diff --git a/.changeset/great-grapes-sneeze.md b/.changeset/great-grapes-sneeze.md new file mode 100644 index 000000000..11c9e1a4d --- /dev/null +++ b/.changeset/great-grapes-sneeze.md @@ -0,0 +1,5 @@ +--- +'@commercetools/sync-actions': minor +--- + +Added support for extensions, business-units and subscriptions diff --git a/packages/sync-actions/src/api-extensions-actions.js b/packages/sync-actions/src/api-extensions-actions.js new file mode 100644 index 000000000..d0d153e36 --- /dev/null +++ b/packages/sync-actions/src/api-extensions-actions.js @@ -0,0 +1,18 @@ +import { buildBaseAttributesActions } from './utils/common-actions' + +export const baseActionsList = [ + { action: 'setKey', key: 'key' }, + { action: 'changeTriggers', key: 'triggers' }, + { action: 'setTimeoutInMs', key: 'timeoutInMs' }, + { action: 'changeDestination', key: 'destination' }, +] + +export const actionsMapBase = (diff, oldObj, newObj, config) => { + return buildBaseAttributesActions({ + actions: baseActionsList, + diff, + oldObj, + newObj, + shouldOmitEmptyString: config?.shouldOmitEmptyString, + }) +} diff --git a/packages/sync-actions/src/api-extensions.js b/packages/sync-actions/src/api-extensions.js new file mode 100644 index 000000000..f2d5885bb --- /dev/null +++ b/packages/sync-actions/src/api-extensions.js @@ -0,0 +1,35 @@ +import flatten from 'lodash.flatten' +import type { SyncAction, ActionGroup, SyncActionConfig } from 'types/sdk' +import createBuildActions from './utils/create-build-actions' +import createMapActionGroup from './utils/create-map-action-group' +import { actionsMapBase } from './api-extensions-actions' +import * as diffpatcher from './utils/diffpatcher' + +export const actionGroups = ['base'] + +const createApiExtensionsMapActions = (mapActionGroup, syncActionConfig) => { + return function doMapActions(diff, newObj, oldObj) { + const allActions = [] + + allActions.push( + mapActionGroup('base', () => + actionsMapBase(diff, oldObj, newObj, syncActionConfig) + ) + ) + + return flatten(allActions) + } +} + +export default ( + actionGroupList: Array, + syncActionConfig: SyncActionConfig +): SyncAction => { + const mapActionGroup = createMapActionGroup(actionGroupList) + const doMapActions = createApiExtensionsMapActions( + mapActionGroup, + syncActionConfig + ) + const buildActions = createBuildActions(diffpatcher.diff, doMapActions) + return { buildActions } +} diff --git a/packages/sync-actions/src/business-units-actions.js b/packages/sync-actions/src/business-units-actions.js new file mode 100644 index 000000000..5ee9f3bd3 --- /dev/null +++ b/packages/sync-actions/src/business-units-actions.js @@ -0,0 +1,55 @@ +import createBuildArrayActions, { + ADD_ACTIONS, + CHANGE_ACTIONS, + REMOVE_ACTIONS, +} from './utils/create-build-array-actions' +import { buildBaseAttributesActions } from './utils/common-actions' + +export const baseActionsList = [ + { + action: 'setStores', + key: 'stores', + }, + { action: 'changeAssociateMode', key: 'associateMode' }, + { action: 'changeApprovalRuleMode', key: 'approvalRuleMode' }, + { + action: 'changeName', + key: 'name', + }, + { action: 'changeParentUnit', key: 'parentUnit' }, + { action: 'changeStatus', key: 'status' }, + { action: 'setContactEmail', key: 'contactEmail' }, + { action: 'setStoreMode', key: 'storeMode' }, +] + +export const actionsMapAssociates = (diff, oldObj, newObj) => { + const handler = createBuildArrayActions('associates', { + [ADD_ACTIONS]: (newObject) => ({ + action: 'addAssociate', + associate: newObject, + }), + [REMOVE_ACTIONS]: (objectToRemove) => ({ + action: 'removeAssociate', + customer: { + typeId: 'customer', + id: objectToRemove.customer.id, + }, + }), + [CHANGE_ACTIONS]: (oldObject, updatedObject) => ({ + action: 'changeAssociate', + associate: updatedObject, + }), + }) + + return handler(diff, oldObj, newObj) +} + +export const actionsMapBase = (diff, oldObj, newObj, config) => { + return buildBaseAttributesActions({ + actions: baseActionsList, + diff, + oldObj, + newObj, + shouldOmitEmptyString: config?.shouldOmitEmptyString, + }) +} diff --git a/packages/sync-actions/src/business-units.js b/packages/sync-actions/src/business-units.js new file mode 100644 index 000000000..f5a693b1b --- /dev/null +++ b/packages/sync-actions/src/business-units.js @@ -0,0 +1,79 @@ +import flatten from 'lodash.flatten' +import type { SyncAction, ActionGroup, SyncActionConfig } from 'types/sdk' +import createMapActionGroup from './utils/create-map-action-group' +import createBuildActions from './utils/create-build-actions' +import * as customerActions from './customer-actions' +import actionsMapCustom from './utils/action-map-custom' +import * as businessUnitActions from './business-units-actions' +import * as diffpatcher from './utils/diffpatcher' + +const createCustomerMapActions = (mapActionGroup, syncActionConfig) => { + return function doMapActions(diff, newObj, oldObj) { + const allActions = [] + + allActions.push( + mapActionGroup('base', () => + businessUnitActions.actionsMapBase( + diff, + oldObj, + newObj, + syncActionConfig + ) + ) + ) + + allActions.push( + mapActionGroup('addresses', () => + customerActions.actionsMapAddresses(diff, oldObj, newObj) + ) + ) + + allActions.push( + mapActionGroup('base', () => + customerActions.actionsMapSetDefaultBase( + diff, + oldObj, + newObj, + syncActionConfig + ) + ) + ) + + allActions.push( + mapActionGroup('billingAddressIds', () => + customerActions.actionsMapBillingAddresses(diff, oldObj, newObj) + ) + ) + + allActions.push( + mapActionGroup('shippingAddressIds', () => + customerActions.actionsMapShippingAddresses(diff, oldObj, newObj) + ) + ) + + allActions.push( + mapActionGroup('associates', () => + businessUnitActions.actionsMapAssociates(diff, oldObj, newObj) + ) + ) + + allActions.push( + mapActionGroup('custom', () => actionsMapCustom(diff, newObj, oldObj)) + ) + + return flatten(allActions) + } +} + +export default ( + actionGroupList: Array, + syncActionConfig: SyncActionConfig +): SyncAction => { + const mapActionGroup = createMapActionGroup(actionGroupList) + const doMapActions = createCustomerMapActions( + mapActionGroup, + syncActionConfig + ) + const buildActions = createBuildActions(diffpatcher.diff, doMapActions) + return { buildActions } +} diff --git a/packages/sync-actions/src/index.js b/packages/sync-actions/src/index.js index 348e1d398..2f4ba7b46 100644 --- a/packages/sync-actions/src/index.js +++ b/packages/sync-actions/src/index.js @@ -19,3 +19,6 @@ export { default as createSyncStores } from './stores' export { default as createSyncProductSelections } from './product-selections' export { default as createSyncStandalonePrices } from './prices' export { default as createSyncAttributeGroups } from './attribute-groups' +export { default as createSyncApiExtensions } from './api-extensions' +export { default as createSyncBusinessUnits } from './business-units' +export { default as createSyncSubscriptions } from './subscriptions' diff --git a/packages/sync-actions/src/subscriptions-actions.js b/packages/sync-actions/src/subscriptions-actions.js new file mode 100644 index 000000000..1d52b6b39 --- /dev/null +++ b/packages/sync-actions/src/subscriptions-actions.js @@ -0,0 +1,18 @@ +import { buildBaseAttributesActions } from './utils/common-actions' + +export const baseActionsList = [ + { action: 'setKey', key: 'key' }, + { action: 'setMessages', key: 'messages' }, + { action: 'setChanges', key: 'changes' }, + { action: 'changeDestination', key: 'destination' }, +] + +export const actionsMapBase = (diff, oldObj, newObj, config) => { + return buildBaseAttributesActions({ + actions: baseActionsList, + diff, + oldObj, + newObj, + shouldOmitEmptyString: config?.shouldOmitEmptyString, + }) +} diff --git a/packages/sync-actions/src/subscriptions.js b/packages/sync-actions/src/subscriptions.js new file mode 100644 index 000000000..bfaff32ce --- /dev/null +++ b/packages/sync-actions/src/subscriptions.js @@ -0,0 +1,44 @@ +import type { SyncAction, ActionGroup, SyncActionConfig } from 'types/sdk' +import createBuildActions from './utils/create-build-actions' +import createMapActionGroup from './utils/create-map-action-group' +import actionsMapCustom from './utils/action-map-custom' +import * as subscriptionsActions from './subscriptions-actions' +import * as diffpatcher from './utils/diffpatcher' + +export const actionGroups = ['base'] + +const createSubscriptionsMapActions = (mapActionGroup, syncActionConfig) => { + return function doMapActions(diff, newObj, oldObj) { + const allActions = [] + + allActions.push( + mapActionGroup('base', () => + subscriptionsActions.actionsMapBase( + diff, + oldObj, + newObj, + syncActionConfig + ) + ) + ) + + allActions.push( + mapActionGroup('custom', () => actionsMapCustom(diff, newObj, oldObj)) + ) + + return allActions.flat() + } +} + +export default ( + actionGroupList: Array, + syncActionConfig: SyncActionConfig +): SyncAction => { + const mapActionGroup = createMapActionGroup(actionGroupList) + const doMapActions = createSubscriptionsMapActions( + mapActionGroup, + syncActionConfig + ) + const buildActions = createBuildActions(diffpatcher.diff, doMapActions) + return { buildActions } +} diff --git a/packages/sync-actions/test/api-extensions-sync.spec.js b/packages/sync-actions/test/api-extensions-sync.spec.js new file mode 100644 index 000000000..093b86226 --- /dev/null +++ b/packages/sync-actions/test/api-extensions-sync.spec.js @@ -0,0 +1,118 @@ +import apiExtensionsSyncFn, { actionGroups } from '../src/api-extensions' +import { baseActionsList } from '../src/api-extensions-actions' + +describe('Exports', () => { + test('action group list', () => { + expect(actionGroups).toEqual(['base']) + }) + + describe('action list', () => { + test('should contain `setKey` action', () => { + expect(baseActionsList).toEqual( + expect.arrayContaining([{ action: 'setKey', key: 'key' }]) + ) + }) + test('should contain `changeTriggers` action', () => { + expect(baseActionsList).toEqual( + expect.arrayContaining([{ action: 'changeTriggers', key: 'triggers' }]) + ) + }) + test('should contain `setTimeoutInMs` action', () => { + expect(baseActionsList).toEqual( + expect.arrayContaining([ + { action: 'setTimeoutInMs', key: 'timeoutInMs' }, + ]) + ) + }) + test('should contain `changeDestination` action', () => { + expect(baseActionsList).toEqual( + expect.arrayContaining([ + { action: 'changeDestination', key: 'destination' }, + ]) + ) + }) + }) +}) + +describe('Actions', () => { + let apiExtensionsSync = apiExtensionsSyncFn() + beforeEach(() => { + apiExtensionsSync = apiExtensionsSyncFn() + }) + + test('should build `setKey` action', () => { + const before = { key: 'keyBefore' } + const now = { key: 'keyAfter' } + const actual = apiExtensionsSync.buildActions(now, before) + const expected = [ + { + action: 'setKey', + ...now, + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build `changeDestination` action', () => { + const before = {} + const now = { + destination: { + type: 'GoogleCloudFunction', + url: 'url', + }, + } + const actual = apiExtensionsSync.buildActions(now, before) + const expected = [ + { + action: 'changeDestination', + destination: { + type: 'GoogleCloudFunction', + url: 'url', + }, + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build `setTimeoutInMs` action', () => { + const before = { timeoutInMs: 5 } + const now = { + timeoutInMs: 10, + } + const actual = apiExtensionsSync.buildActions(now, before) + const expected = [ + { + action: 'setTimeoutInMs', + timeoutInMs: 10, + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build `changeTriggers` action', () => { + const before = {} + const now = { + triggers: [ + { + resourceTypeId: 'cart', + actions: ['Create', 'Update'], + condition: 'field is defined and field has changed', + }, + ], + } + const actual = apiExtensionsSync.buildActions(now, before) + const expected = [ + { + action: 'changeTriggers', + triggers: [ + { + resourceTypeId: 'cart', + actions: ['Create', 'Update'], + condition: 'field is defined and field has changed', + }, + ], + }, + ] + expect(actual).toEqual(expected) + }) +}) diff --git a/packages/sync-actions/test/business-units-sync.spec.js b/packages/sync-actions/test/business-units-sync.spec.js new file mode 100644 index 000000000..0944c5ae2 --- /dev/null +++ b/packages/sync-actions/test/business-units-sync.spec.js @@ -0,0 +1,713 @@ +import businessUnitsSyncFn from '../src/business-units' +import { baseActionsList } from '../src/business-units-actions' + +describe('Exports', () => { + test('correctly define base actions list', () => { + expect(baseActionsList).toEqual([ + { + action: 'setStores', + key: 'stores', + }, + { + action: 'changeAssociateMode', + key: 'associateMode', + }, + { + action: 'changeApprovalRuleMode', + key: 'approvalRuleMode', + }, + { + action: 'changeName', + key: 'name', + }, + { action: 'changeParentUnit', key: 'parentUnit' }, + { action: 'changeStatus', key: 'status' }, + { action: 'setContactEmail', key: 'contactEmail' }, + { action: 'setStoreMode', key: 'storeMode' }, + ]) + }) +}) + +describe('Actions', () => { + let businessUnitsSync = businessUnitsSyncFn() + beforeEach(() => { + businessUnitsSync = businessUnitsSyncFn() + }) + + test('should build `setDefaultBillingAddress` action', () => { + const before = { + defaultBillingAddressId: 'abc123', + } + const now = { + defaultBillingAddressId: 'def456', + } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [ + { + action: 'setDefaultBillingAddress', + addressId: now.defaultBillingAddressId, + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build `setDefaultShippingAddress` action', () => { + const before = { + defaultShippingAddressId: 'abc123', + } + const now = { + defaultShippingAddressId: 'def456', + } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [ + { + action: 'setDefaultShippingAddress', + addressId: now.defaultShippingAddressId, + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build `addAddress` action', () => { + const before = { addresses: [] } + const now = { + addresses: [{ streetName: 'some name', streetNumber: '5' }], + } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [{ action: 'addAddress', address: now.addresses[0] }] + expect(actual).toEqual(expected) + }) + + test('should build `addAddress` action before `setDefaultShippingAddress`', () => { + const before = { addresses: [] } + const now = { + addresses: [{ streetName: 'some name', streetNumber: '5' }], + defaultShippingAddressId: 'def456', + } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [ + { action: 'addAddress', address: now.addresses[0] }, + { + action: 'setDefaultShippingAddress', + addressId: now.defaultShippingAddressId, + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build `changeAddress` action', () => { + const before = { + addresses: [ + { + id: 'somelongidgoeshere199191', + streetName: 'some name', + streetNumber: '5', + }, + ], + } + const now = { + addresses: [ + { + id: 'somelongidgoeshere199191', + streetName: 'some different name', + streetNumber: '5', + }, + ], + } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [ + { + action: 'changeAddress', + addressId: before.addresses[0].id, + address: now.addresses[0], + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build `removeAddress` action', () => { + const before = { + addresses: [{ id: 'somelongidgoeshere199191' }], + } + const now = { addresses: [] } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [ + { + action: 'removeAddress', + addressId: before.addresses[0].id, + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build complex mixed actions', () => { + const before = { + addresses: [ + { + id: 'addressId1', + title: 'mr', + streetName: 'address 1 street', + postalCode: 'postal code 1', + }, + { + id: 'addressId2', + title: 'mr', + streetName: 'address 2 street', + postalCode: 'postal code 2', + }, + { + id: 'addressId4', + title: 'mr', + streetName: 'address 4 street', + postalCode: 'postal code 4', + }, + ], + } + const now = { + addresses: [ + { + id: 'addressId1', + title: 'mr', + streetName: 'address 1 street changed', // CHANGED + postalCode: 'postal code 1', + }, + // REMOVED ADDRESS 2 + { + // UNCHANGED ADDRESS 4 + id: 'addressId4', + title: 'mr', + streetName: 'address 4 street', + postalCode: 'postal code 4', + }, + { + // ADD NEW ADDRESS + id: 'addressId3', + title: 'mr', + streetName: 'address 3 street', + postalCode: 'postal code 3', + }, + ], + } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [ + { + // CHANGE ACTIONS FIRST + action: 'changeAddress', + addressId: 'addressId1', + address: now.addresses[0], + }, + { + // REMOVE ACTIONS NEXT + action: 'removeAddress', + addressId: 'addressId2', + }, + { + // CREATE ACTIONS LAST + action: 'addAddress', + address: now.addresses[2], + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build `addBillingAddressId` action', () => { + const addressId = 'addressId' + const before = { billingAddressIds: [] } + const now = { + billingAddressIds: [addressId], + } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [{ action: 'addBillingAddressId', addressId }] + expect(actual).toEqual(expected) + }) + + test('should build `removeBillingAddressId` action', () => { + const addressId = 'addressId' + const before = { + billingAddressIds: [addressId], + } + const now = { billingAddressIds: [] } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [{ action: 'removeBillingAddressId', addressId }] + expect(actual).toEqual(expected) + }) + + test('should build both `add-` and `removeBillingAddressId` actions', () => { + const before = { + billingAddressIds: ['remove', 'keep', 'remove2'], + } + const now = { + billingAddressIds: ['keep', 'new'], + } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [ + { + action: 'removeBillingAddressId', + addressId: 'remove', + }, + { + action: 'removeBillingAddressId', + addressId: 'remove2', + }, + { + action: 'addBillingAddressId', + addressId: 'new', + }, + ] + expect(actual).toEqual(expected) + }) + test('should build `addShippingAddressId` action', () => { + const addressId = 'addressId' + const before = { shippingAddressIds: [] } + const now = { + shippingAddressIds: [addressId], + } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [{ action: 'addShippingAddressId', addressId }] + expect(actual).toEqual(expected) + }) + + test('should build `removeShippingAddressId` action', () => { + const addressId = 'addressId' + const before = { + shippingAddressIds: [addressId], + } + const now = { shippingAddressIds: [] } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [{ action: 'removeShippingAddressId', addressId }] + expect(actual).toEqual(expected) + }) + + test('should build both `add-` and `removeShippingAddressId` actions', () => { + const before = { + shippingAddressIds: ['remove', 'keep', 'remove2'], + } + const now = { + shippingAddressIds: ['keep', 'new'], + } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [ + { + action: 'removeShippingAddressId', + addressId: 'remove', + }, + { + action: 'removeShippingAddressId', + addressId: 'remove2', + }, + { + action: 'addShippingAddressId', + addressId: 'new', + }, + ] + expect(actual).toEqual(expected) + }) + + describe('custom fields', () => { + test('should build `setCustomType` action', () => { + const before = { + custom: { + type: { + typeId: 'type', + id: 'customType1', + }, + fields: { + customField1: true, + }, + }, + } + const now = { + custom: { + type: { + typeId: 'type', + id: 'customType2', + }, + fields: { + customField1: true, + }, + }, + } + const actual = businessUnitsSync.buildActions(now, before) + const expected = [{ action: 'setCustomType', ...now.custom }] + expect(actual).toEqual(expected) + }) + }) + + test('should build `setCustomField` action', () => { + const before = { + custom: { + type: { + typeId: 'type', + id: 'customType1', + }, + fields: { + customField1: false, + }, + }, + } + const now = { + custom: { + type: { + typeId: 'type', + id: 'customType1', + }, + fields: { + customField1: true, + }, + }, + } + const actual = businessUnitsSync.buildActions(now, before) + const expected = [ + { + action: 'setCustomField', + name: 'customField1', + value: true, + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build `addStore` action', () => { + const before = { + stores: [], + } + const now = { + stores: [ + { + typeId: 'store', + key: 'canada', + }, + ], + } + const actual = businessUnitsSync.buildActions(now, before) + expect(actual).toEqual([ + { + action: 'setStores', + stores: [ + { + typeId: 'store', + key: 'canada', + }, + ], + }, + ]) + }) + + test('should build `setStores` action', () => { + const before = { + stores: [ + { + typeId: 'store', + key: 'canada', + }, + ], + } + const now = { + stores: [ + { + typeId: 'store', + key: 'canada', + }, + { + typeId: 'store', + key: 'usa', + }, + ], + } + const actual = businessUnitsSync.buildActions(now, before) + expect(actual).toEqual([ + { + action: 'setStores', + stores: [ + { + typeId: 'store', + key: 'canada', + }, + { + typeId: 'store', + key: 'usa', + }, + ], + }, + ]) + }) + test('should build `setStores` action but empty', () => { + const before = { + stores: [ + { + typeId: 'store', + key: 'canada', + }, + { + typeId: 'store', + key: 'usa', + }, + ], + } + + const now = { stores: [] } + + const actual = businessUnitsSync.buildActions(now, before) + expect(actual).toEqual([ + { + action: 'setStores', + stores: [], + }, + ]) + }) + + test('should build `addAssociate` action', () => { + const before = { associates: [] } + const now = { + associates: [ + { + customer: { + typeId: 'customer', + id: 'some-customer-id', + }, + }, + ], + } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [ + { + action: 'addAssociate', + associate: { + customer: { + typeId: 'customer', + id: 'some-customer-id', + }, + }, + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build `removeAssociate` action', () => { + const before = { + associates: [ + { + customer: { + typeId: 'customer', + id: 'some-customer-id', + }, + associateRoleAssignments: [ + { + associateRole: { + typeId: 'associate-role', + key: 'admin', + }, + inheritance: 'Enabled', + }, + ], + }, + ], + } + const now = { associates: [] } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [ + { + action: 'removeAssociate', + customer: { + typeId: 'customer', + id: 'some-customer-id', + }, + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build both `change-` and `removeAssociate` actions', () => { + const before = { + associates: [ + { + customer: { + typeId: 'customer', + id: 'remove', + }, + }, + { + customer: { + typeId: 'customer', + id: 'keep', + }, + }, + { + customer: { + typeId: 'customer', + id: 'remove2', + }, + }, + ], + } + const now = { + associates: [ + { + customer: { + typeId: 'customer', + id: 'new', + }, + }, + { + customer: { + typeId: 'customer', + id: 'keep', + }, + }, + ], + } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [ + { + action: 'changeAssociate', + associate: { customer: { id: 'new', typeId: 'customer' } }, + }, + { + action: 'removeAssociate', + customer: { id: 'remove2', typeId: 'customer' }, + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build `changeAssociateMode` action', () => { + const before = { + associateMode: 'ExplicitAndFromParent', + } + const now = { associateMode: 'Explicit' } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [ + { + action: 'changeAssociateMode', + associateMode: 'Explicit', + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build `changeApprovalRuleMode` action', () => { + const before = { + approvalRuleMode: 'ExplicitAndFromParent', + } + const now = { approvalRuleMode: 'Explicit' } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [ + { + action: 'changeApprovalRuleMode', + approvalRuleMode: 'Explicit', + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build `changeName` action', () => { + const before = { + name: 'old', + } + const now = { name: 'new' } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [ + { + action: 'changeName', + name: 'new', + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build `changeParentUnit` action', () => { + const before = { + parentUnit: { + typeId: 'business-unit', + key: 'old', + }, + } + const now = { + parentUnit: { + typeId: 'business-unit', + key: 'new', + }, + } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [ + { + action: 'changeParentUnit', + parentUnit: { + typeId: 'business-unit', + key: 'new', + }, + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build `changeStatus` action', () => { + const before = { + status: 'Inactive', + } + const now = { + status: 'Active', + } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [ + { + action: 'changeStatus', + status: 'Active', + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build `setContactEmail` action', () => { + const before = {} + const now = { + contactEmail: 'contactEmail', + } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [ + { + action: 'setContactEmail', + contactEmail: 'contactEmail', + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build `setStoreMode` action', () => { + const before = { storeMode: 'FromParent' } + const now = { + storeMode: 'Explicit', + } + + const actual = businessUnitsSync.buildActions(now, before) + const expected = [ + { + action: 'setStoreMode', + storeMode: 'Explicit', + }, + ] + expect(actual).toEqual(expected) + }) +}) diff --git a/packages/sync-actions/test/subscriptions-sync.spec.js b/packages/sync-actions/test/subscriptions-sync.spec.js new file mode 100644 index 000000000..e45423c9f --- /dev/null +++ b/packages/sync-actions/test/subscriptions-sync.spec.js @@ -0,0 +1,194 @@ +import subscriptionsSyncFn, { actionGroups } from '../src/subscriptions' +import { baseActionsList } from '../src/subscriptions-actions' + +describe('Exports', () => { + test('action group list', () => { + expect(actionGroups).toEqual(['base']) + }) + + describe('action list', () => { + test('should contain `setKey` action', () => { + expect(baseActionsList).toEqual( + expect.arrayContaining([{ action: 'setKey', key: 'key' }]) + ) + }) + test('should contain `setMessages` action', () => { + expect(baseActionsList).toEqual( + expect.arrayContaining([{ action: 'setMessages', key: 'messages' }]) + ) + }) + test('should contain `setChanges` action', () => { + expect(baseActionsList).toEqual( + expect.arrayContaining([{ action: 'setChanges', key: 'changes' }]) + ) + }) + test('should contain `changeDestination` action', () => { + expect(baseActionsList).toEqual( + expect.arrayContaining([ + { action: 'changeDestination', key: 'destination' }, + ]) + ) + }) + }) +}) + +describe('Actions', () => { + let subscriptionsSync = subscriptionsSyncFn() + beforeEach(() => { + subscriptionsSync = subscriptionsSyncFn() + }) + + test('should build `setKey` action', () => { + const before = { key: 'keyBefore' } + const now = { key: 'keyAfter' } + const actual = subscriptionsSync.buildActions(now, before) + const expected = [ + { + action: 'setKey', + ...now, + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build `setMessages` action', () => { + const before = { + messages: [{ resourceTypeId: 'product', types: ['ProductCreated'] }], + } + const now = { + messages: [{ resourceTypeId: 'product', types: ['ProductUpdated'] }], + } + const actual = subscriptionsSync.buildActions(now, before) + const expected = [ + { + action: 'setMessages', + messages: [ + { + resourceTypeId: 'product', + types: ['ProductUpdated'], + }, + ], + }, + ] + expect(actual).toEqual(expected) + }) + + test('should add additional type', () => { + const before = { + messages: [{ resourceTypeId: 'product', types: ['ProductCreated'] }], + } + const now = { + messages: [ + { + resourceTypeId: 'product', + types: ['ProductCreated', 'ProductUpdated'], + }, + ], + } + const actual = subscriptionsSync.buildActions(now, before) + const expected = [ + { + action: 'setMessages', + messages: [ + { + resourceTypeId: 'product', + types: ['ProductCreated', 'ProductUpdated'], + }, + ], + }, + ] + expect(actual).toEqual(expected) + }) + + test('should set Message', () => { + const before = {} + const now = { + messages: [ + { + resourceTypeId: 'store', + types: ['StoreCreated'], + }, + { + resourceTypeId: 'product', + types: ['ProductCreated', 'ProductUpdated'], + }, + ], + } + const actual = subscriptionsSync.buildActions(now, before) + const expected = [ + { + action: 'setMessages', + messages: [ + { + resourceTypeId: 'store', + types: ['StoreCreated'], + }, + { + resourceTypeId: 'product', + types: ['ProductCreated', 'ProductUpdated'], + }, + ], + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build `setChanges` action', () => { + const before = { + changes: [{ resourceTypeId: 'product' }], + } + const now = { + changes: [{ resourceTypeId: 'store' }], + } + const actual = subscriptionsSync.buildActions(now, before) + const expected = [ + { + action: 'setChanges', + changes: [ + { + resourceTypeId: 'store', + }, + ], + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build remove on `setChanges` action', () => { + const before = { + changes: [{ resourceTypeId: 'product' }], + } + const now = { changes: [] } + const actual = subscriptionsSync.buildActions(now, before) + const expected = [ + { + action: 'setChanges', + changes: [], + }, + ] + expect(actual).toEqual(expected) + }) + + test('should build `changeDestination` action', () => { + const before = {} + const now = { + destination: { + type: 'GoogleCloudPubSub', + projectId: 'projectId', + topic: 'topic', + }, + } + const actual = subscriptionsSync.buildActions(now, before) + const expected = [ + { + action: 'changeDestination', + destination: { + type: 'GoogleCloudPubSub', + projectId: 'projectId', + topic: 'topic', + }, + }, + ] + expect(actual).toEqual(expected) + }) +})