@labdigital/commercetools-mock 2.3.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@labdigital/commercetools-mock",
3
3
  "author": "Michael van Tellingen",
4
- "version": "2.3.0",
4
+ "version": "2.4.0",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.cjs",
7
7
  "module": "dist/index.js",
@@ -4,6 +4,8 @@ import type {
4
4
  Category,
5
5
  CategoryAddAssetAction,
6
6
  CategoryChangeAssetNameAction,
7
+ CategoryChangeNameAction,
8
+ CategoryChangeParentAction,
7
9
  CategoryChangeSlugAction,
8
10
  CategoryDraft,
9
11
  CategoryRemoveAssetAction,
@@ -98,6 +100,30 @@ export class CategoryRepository extends AbstractResourceRepository<'category'> {
98
100
  ) => {
99
101
  resource.slug = slug
100
102
  },
103
+ changeName: (
104
+ context: RepositoryContext,
105
+ resource: Writable<Category>,
106
+ { name }: CategoryChangeNameAction
107
+ ) => {
108
+ resource.name = name
109
+ },
110
+ changeParent: (
111
+ context: RepositoryContext,
112
+ resource: Writable<Category>,
113
+ { parent }: CategoryChangeParentAction
114
+ ) => {
115
+ const category = this._storage.getByResourceIdentifier(
116
+ context.projectKey,
117
+ parent
118
+ )
119
+ if (!category) {
120
+ throw new Error('No category found for reference')
121
+ }
122
+ resource.parent = {
123
+ typeId: 'category',
124
+ id: category.id,
125
+ }
126
+ },
101
127
  setKey: (
102
128
  context: RepositoryContext,
103
129
  resource: Writable<Category>,
@@ -6,6 +6,7 @@ import type {
6
6
  ProductDraft,
7
7
  ProductPublishAction,
8
8
  ProductSetAttributeAction,
9
+ ProductSetAttributeInAllVariantsAction,
9
10
  ProductSetDescriptionAction,
10
11
  ProductAddExternalImageAction,
11
12
  ProductRemoveImageAction,
@@ -238,6 +239,65 @@ export class ProductRepository extends AbstractResourceRepository<'product'> {
238
239
 
239
240
  return resource
240
241
  },
242
+ setAttributeInAllVariants: (
243
+ context: RepositoryContext,
244
+ resource: Writable<Product>,
245
+ { name, value, staged }: ProductSetAttributeInAllVariantsAction
246
+ ) => {
247
+ const setAttrInAllVariants = (data: Writable<ProductData>) => {
248
+ if (!data.masterVariant.attributes) {
249
+ data.masterVariant.attributes = []
250
+ }
251
+
252
+ const existingAttr = data.masterVariant.attributes?.find(
253
+ (attr) => attr.name === name
254
+ )
255
+
256
+ if (existingAttr) {
257
+ existingAttr.value = value
258
+ } else {
259
+ data.masterVariant.attributes.push({
260
+ name,
261
+ value,
262
+ })
263
+ }
264
+
265
+ data.variants.forEach((variant) => {
266
+ if (!variant.attributes) {
267
+ variant.attributes = []
268
+ }
269
+
270
+ const existingAttr = variant.attributes.find(
271
+ (attr) => attr.name === name
272
+ )
273
+ if (existingAttr) {
274
+ existingAttr.value = value
275
+ } else {
276
+ variant.attributes.push({
277
+ name,
278
+ value,
279
+ })
280
+ }
281
+ })
282
+ }
283
+
284
+ // If true, only the staged Attribute is set. If false, both current and
285
+ // staged Attribute is set. Default is true
286
+ const onlyStaged = staged !== undefined ? staged : true
287
+
288
+ // Write the attribute to the staged data
289
+ setAttrInAllVariants(resource.masterData.staged)
290
+
291
+ // Also write to published data is isStaged = false
292
+ // if isStaged is false we set the attribute on both the staged and
293
+ // published data.
294
+ if (!onlyStaged) {
295
+ setAttrInAllVariants(resource.masterData.current)
296
+ }
297
+ checkForStagedChanges(resource)
298
+
299
+ return resource
300
+ },
241
301
  setDescription: (
242
302
  context: RepositoryContext,
243
303
  resource: Writable<Product>,
@@ -48,6 +48,105 @@ describe('Categories Query', () => {
48
48
  })
49
49
  })
50
50
 
51
+ describe('categories changeName', () => {
52
+ const ctMock = new CommercetoolsMock()
53
+ let category: Category | undefined
54
+
55
+ beforeEach(async () => {
56
+ const response = await supertest(ctMock.app)
57
+ .post('/dummy/categories')
58
+ .send({
59
+ name: {
60
+ en: 'Top hat',
61
+ },
62
+ slug: {
63
+ en: 'top-hat',
64
+ },
65
+ orderHint: '0.1',
66
+ })
67
+ expect(response.status).toBe(201)
68
+ category = response.body as Category
69
+ })
70
+
71
+ test('changeName', async () => {
72
+ const changeNameResponse = await supertest(ctMock.app)
73
+ .post(`/dummy/categories/${category?.id}`)
74
+ .send({
75
+ version: 1,
76
+ actions: [
77
+ {
78
+ action: 'changeName',
79
+ name: {
80
+ en: 'Top hat - new name',
81
+ },
82
+ },
83
+ ],
84
+ })
85
+
86
+ expect(changeNameResponse.status).toBe(200)
87
+ expect(changeNameResponse.body.name.en).toBe('Top hat - new name')
88
+ })
89
+ })
90
+
91
+ describe('categories changeParent', () => {
92
+ const ctMock = new CommercetoolsMock()
93
+ let category1: Category | undefined
94
+ let category2: Category | undefined
95
+
96
+ beforeEach(async () => {
97
+ const response1 = await supertest(ctMock.app)
98
+ .post('/dummy/categories')
99
+ .send({
100
+ name: {
101
+ en: 'Top hat',
102
+ },
103
+ slug: {
104
+ en: 'top-hat',
105
+ },
106
+ orderHint: '0.1',
107
+ })
108
+ expect(response1.status).toBe(201)
109
+ category1 = response1.body as Category
110
+
111
+ const response2 = await supertest(ctMock.app)
112
+ .post('/dummy/categories')
113
+ .send({
114
+ name: {
115
+ en: 'Top hat',
116
+ },
117
+ slug: {
118
+ en: 'top-hat',
119
+ },
120
+ orderHint: '0.1',
121
+ })
122
+ expect(response2.status).toBe(201)
123
+ category2 = response2.body as Category
124
+ })
125
+
126
+ test('changeParent', async () => {
127
+ const changeNameResponse = await supertest(ctMock.app)
128
+ .post(`/dummy/categories/${category2?.id}`)
129
+ .send({
130
+ version: 1,
131
+ actions: [
132
+ {
133
+ action: 'changeParent',
134
+ parent: {
135
+ typeId: 'category',
136
+ id: category1?.id,
137
+ },
138
+ },
139
+ ],
140
+ })
141
+
142
+ expect(changeNameResponse.status).toBe(200)
143
+ expect(changeNameResponse.body.parent).toEqual({
144
+ typeId: 'category',
145
+ id: category1?.id,
146
+ })
147
+ })
148
+ })
149
+
51
150
  describe('Categories add asset', () => {
52
151
  const ctMock = new CommercetoolsMock()
53
152
  let category: Category | undefined
@@ -594,6 +594,106 @@ describe('Product update actions', () => {
594
594
  expect(attr).toEqual({ name: 'test', value: 'foo' })
595
595
  })
596
596
 
597
+ test('setAttributeInAllVariants overwrite', async () => {
598
+ assert(productPublished, 'product not created')
599
+ const response = await supertest(ctMock.app)
600
+ .post(`/dummy/products/${productPublished.id}`)
601
+ .send({
602
+ version: 1,
603
+ actions: [
604
+ {
605
+ action: 'setAttributeInAllVariants',
606
+ name: 'test',
607
+ value: 'foo',
608
+ },
609
+ ],
610
+ })
611
+ expect(response.status).toBe(200)
612
+ expect(response.body.version).toBe(2)
613
+ expect(
614
+ response.body.masterData.staged.masterVariant.attributes
615
+ ).toHaveLength(1)
616
+
617
+ const masterVariantAttr1 =
618
+ response.body.masterData.staged.masterVariant.attributes[0]
619
+ expect(masterVariantAttr1).toEqual({ name: 'test', value: 'foo' })
620
+
621
+ response.body.masterData.staged.variants.forEach((variant) => {
622
+ expect(variant.attributes).toHaveLength(2)
623
+ expect(variant.attributes[1]).toEqual({
624
+ name: 'test',
625
+ value: 'foo',
626
+ })
627
+ })
628
+ })
629
+
630
+ test('setAttributeInAllVariants product staged', async () => {
631
+ assert(productPublished, 'product not created')
632
+ const response = await supertest(ctMock.app)
633
+ .post(`/dummy/products/${productPublished.id}`)
634
+ .send({
635
+ version: 1,
636
+ actions: [
637
+ {
638
+ action: 'setAttributeInAllVariants',
639
+ name: 'foo',
640
+ value: 'bar',
641
+ },
642
+ ],
643
+ })
644
+ expect(response.status).toBe(200)
645
+ expect(response.body.version).toBe(2)
646
+ expect(
647
+ response.body.masterData.staged.masterVariant.attributes
648
+ ).toHaveLength(2)
649
+ const masterVariantAttr1 =
650
+ response.body.masterData.staged.masterVariant.attributes[0]
651
+ expect(masterVariantAttr1).toEqual({ name: 'test', value: 'test' })
652
+
653
+ const masterVariantAttr2 =
654
+ response.body.masterData.staged.masterVariant.attributes[1]
655
+ expect(masterVariantAttr2).toEqual({
656
+ name: 'foo',
657
+ value: 'bar',
658
+ })
659
+ response.body.masterData.staged.variants.forEach((variant) => {
660
+ expect(variant.attributes).toHaveLength(2)
661
+ expect(variant.attributes[1]).toEqual({
662
+ name: 'foo',
663
+ value: 'bar',
664
+ })
665
+ })
666
+ })
667
+
668
+ test('setAttributeInAllVariants and publish', async () => {
669
+ assert(productPublished, 'product not created')
670
+
671
+ const response = await supertest(ctMock.app)
672
+ .post(`/dummy/products/${productPublished.id}`)
673
+ .send({
674
+ version: 1,
675
+ actions: [
676
+ { action: 'setAttributeInAllVariants', name: 'foo', value: 'bar' },
677
+ { action: 'publish' },
678
+ ],
679
+ })
680
+ expect(response.status).toBe(200)
681
+ expect(response.body.version).toBe(3)
682
+ expect(
683
+ response.body.masterData.current.masterVariant.attributes
684
+ ).toHaveLength(2)
685
+ const attr = response.body.masterData.current.masterVariant.attributes[1]
686
+ expect(attr).toEqual({ name: 'foo', value: 'bar' })
687
+
688
+ response.body.masterData.current.variants.forEach((variant) => {
689
+ expect(variant.attributes).toHaveLength(2)
690
+ expect(variant.attributes[1]).toEqual({
691
+ name: 'foo',
692
+ value: 'bar',
693
+ })
694
+ })
695
+ })
696
+
597
697
  test('addExternalImage variant', async () => {
598
698
  assert(productPublished, 'product not created')
599
699