import { helper, relaxedSnapshot } from "@grouparoo/spec-helper"; import { GrouparooRecord, Group, Destination, GrouparooPlugin, Source, } from "../../src"; import { api } from "actionhero"; describe("test grouparoo records", () => { helper.grouparooTestServer({ truncate: true, enableTestPlugin: true }); describe("within a mock environment", () => { let record: GrouparooRecord; let group: Group; let destination: Destination; beforeAll(async () => { // we need to ensure that we have static results for the import to snapshot const testPlugin: GrouparooPlugin = api.plugins.plugins.find( (a) => a.name === "@grouparoo/test-plugin" ); const testPluginConnection = testPlugin.connections.find( (c) => c.name === "test-plugin-import" ); testPluginConnection.methods.recordProperty = async ({ property }) => { const data = { userId: [100], isVIP: [true], email: [`example@example.com`], firstName: ["Mario"], lastName: ["Mario"], ltv: [100.0], lastLoginAt: [new Date(0)], purchases: ["hat", "mushroom"], purchaseAmounts: [100, 200], }; return data[property.key as keyof typeof data]; }; }); beforeAll(async () => { // make properties await helper.factories.properties(); const source = await Source.findOne(); // make a group group = await helper.factories.group(); await group.update({ name: "test group" }); await group.setRules([ { key: "email", match: "%@example.com", operation: { op: "like" } }, ]); // make a destination destination = await helper.factories.destination(); await destination.update({ name: "test destination" }); await destination.setOptions({ table: "users" }); await destination.setMapping({ "primary-id": "userId", email: "email", ltv: "ltv", isVIP: "isVIP", }); await destination.setDestinationGroupMemberships({ [group.id]: "remote_group_name", }); await destination.updateTracking("group", group.id); // make ready await group.update({ state: "ready" }); await destination.update({ state: "ready" }); // make the record const response = await GrouparooRecord.findOrCreateByUniqueRecordProperties( { userId: ["person1@example.com"] }, source ); record = response.record; // import & export the record await record.sync(); }); test("record properties match the snapshot", async () => { const properties = await record.simplifiedProperties(); expect(properties).toMatchSnapshot(); }); test("groups match the snapshot", async () => { const groups = await record.$get("groups"); const groupApiData = await Promise.all(groups.map((g) => g.apiData())); expect(groupApiData.length).toEqual(1); expect(groupApiData[0]).toMatchSnapshot({ id: expect.stringMatching(/^grp_/), createdAt: expect.any(Number), updatedAt: expect.any(Number), nextCalculatedAt: null, }); }); test("potential exports match the snapshot", async () => { const _exports = await record.export(true, [], false); const exportApiData = await Promise.all( _exports.map((e) => e.apiData(false)) ); expect(exportApiData.length).toEqual(1); expect(exportApiData[0]).toMatchSnapshot({ recordId: expect.stringMatching(/^rec_/), state: "pending", startedAt: expect.any(Number), sendAt: expect.any(Number), newRecordProperties: expect.objectContaining({ email: expect.stringMatching(/@example.com/), "primary-id": expect.any(Number), isVIP: true, ltv: 100, }), oldRecordProperties: expect.objectContaining({ email: expect.stringMatching(/@example.com/), "primary-id": expect.any(Number), isVIP: true, ltv: 100, }), }); }); test("the record can be snapshot-ed", async () => { const snapshot = await record.snapshot(); expect(snapshot).toMatchSnapshot(relaxedSnapshot(snapshot)); }); }); });