@labdigital/commercetools-mock 0.10.1 → 0.12.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": "0.10.1",
4
+ "version": "0.12.0",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/commercetools--mock.esm.js",
@@ -7,11 +7,14 @@ import {
7
7
  ProductPublishAction,
8
8
  ProductSetAttributeAction,
9
9
  ProductSetDescriptionAction,
10
+ ProductAddExternalImageAction,
11
+ ProductRemoveImageAction,
10
12
  ProductSetKeyAction,
11
13
  ProductTypeReference,
12
14
  ProductUpdateAction,
13
15
  ProductVariant,
14
16
  ProductVariantDraft,
17
+ ProductMoveImageToPositionAction,
15
18
  } from '@commercetools/platform-sdk'
16
19
  import { v4 as uuidv4 } from 'uuid'
17
20
  import { Writable } from '../types'
@@ -183,6 +186,181 @@ export class ProductRepository extends AbstractResourceRepository<'product'> {
183
186
  resource.key = key
184
187
  return resource
185
188
  },
189
+ addExternalImage: (
190
+ context: RepositoryContext,
191
+ resource: Writable<Product>,
192
+ { variantId, sku, image, staged }: ProductAddExternalImageAction
193
+ ) => {
194
+ const addImg = (data: Writable<ProductData>) => {
195
+ const { variant, isMasterVariant, variantIndex } = getVariant(
196
+ data,
197
+ variantId,
198
+ sku
199
+ )
200
+ if (!variant) {
201
+ throw new Error(
202
+ `Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`
203
+ )
204
+ }
205
+
206
+ if (!variant.images) {
207
+ variant.images = []
208
+ } else {
209
+ const existingImage = variant.images.find((x) => x.url === image.url)
210
+ if (existingImage) {
211
+ throw new Error(
212
+ `Cannot add image '${image.url}' because product '${resource.id}' already has that image.`
213
+ )
214
+ }
215
+ }
216
+
217
+ // Add image
218
+ variant.images.push(image)
219
+
220
+ if (isMasterVariant) {
221
+ data.masterVariant = variant
222
+ } else {
223
+ data.variants[variantIndex] = variant
224
+ }
225
+ }
226
+
227
+ // If true, only the staged Attribute is set. If false, both current and
228
+ // staged Attribute is set. Default is true
229
+ const onlyStaged = staged !== undefined ? staged : true
230
+
231
+ // Write the attribute to the staged data
232
+ addImg(resource.masterData.staged)
233
+
234
+ // Also write to published data is isStaged = false
235
+ // if isStaged is false we set the attribute on both the staged and
236
+ // published data.
237
+ if (!onlyStaged) {
238
+ addImg(resource.masterData.current)
239
+ }
240
+ checkForStagedChanges(resource)
241
+
242
+ return resource
243
+ },
244
+ removeImage: (
245
+ context: RepositoryContext,
246
+ resource: Writable<Product>,
247
+ { variantId, sku, imageUrl, staged }: ProductRemoveImageAction
248
+ ) => {
249
+ const removeImg = (data: Writable<ProductData>) => {
250
+ const { variant, isMasterVariant, variantIndex } = getVariant(
251
+ data,
252
+ variantId,
253
+ sku
254
+ )
255
+ if (!variant) {
256
+ throw new Error(
257
+ `Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`
258
+ )
259
+ }
260
+
261
+ const variantImages = variant.images ?? []
262
+ const existingImage = variantImages.find((x) => x.url === imageUrl)
263
+ if (!existingImage) {
264
+ throw new Error(
265
+ `Cannot remove image '${imageUrl}' because product '${resource.id}' does not have that image.`
266
+ )
267
+ }
268
+
269
+ // Remove image
270
+ variant.images = variantImages.filter((image) => image.url !== imageUrl)
271
+
272
+ if (isMasterVariant) {
273
+ data.masterVariant = variant
274
+ } else {
275
+ data.variants[variantIndex] = variant
276
+ }
277
+ }
278
+
279
+ // If true, only the staged Attribute is set. If false, both current and
280
+ // staged Attribute is set. Default is true
281
+ const onlyStaged = staged !== undefined ? staged : true
282
+
283
+ // Write the attribute to the staged data
284
+ removeImg(resource.masterData.staged)
285
+
286
+ // Also write to published data is isStaged = false
287
+ // if isStaged is false we set the attribute on both the staged and
288
+ // published data.
289
+ if (!onlyStaged) {
290
+ removeImg(resource.masterData.current)
291
+ }
292
+ checkForStagedChanges(resource)
293
+
294
+ return resource
295
+ },
296
+ moveImageToPosition: (
297
+ context: RepositoryContext,
298
+ resource: Writable<Product>,
299
+ {
300
+ variantId,
301
+ sku,
302
+ imageUrl,
303
+ position,
304
+ staged,
305
+ }: ProductMoveImageToPositionAction
306
+ ) => {
307
+ const moveImg = (data: Writable<ProductData>) => {
308
+ const { variant, isMasterVariant, variantIndex } = getVariant(
309
+ data,
310
+ variantId,
311
+ sku
312
+ )
313
+ if (!variant) {
314
+ throw new Error(
315
+ `Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`
316
+ )
317
+ }
318
+
319
+ const variantImages = variant.images ?? []
320
+ const existingImage = variantImages.find((x) => x.url === imageUrl)
321
+ if (!existingImage) {
322
+ throw new Error(
323
+ `Cannot move image '${imageUrl}' because product '${resource.id}' does not have that image.`
324
+ )
325
+ }
326
+
327
+ if (position >= variantImages.length) {
328
+ throw new Error(
329
+ `Invalid position given. Position in images where the image should be moved. Must be between 0 and the total number of images minus 1.`
330
+ )
331
+ }
332
+
333
+ // Remove image
334
+ variant.images = variantImages.filter((image) => image.url !== imageUrl)
335
+
336
+ // Re-add image to the correct position
337
+ variant.images.splice(position, 0, existingImage)
338
+
339
+ if (isMasterVariant) {
340
+ data.masterVariant = variant
341
+ } else {
342
+ data.variants[variantIndex] = variant
343
+ }
344
+ }
345
+
346
+ // If true, only the staged Attribute is set. If false, both current and
347
+ // staged Attribute is set. Default is true
348
+ const onlyStaged = staged !== undefined ? staged : true
349
+
350
+ // Write the attribute to the staged data
351
+ moveImg(resource.masterData.staged)
352
+
353
+ // Also write to published data is isStaged = false
354
+ // if isStaged is false we set the attribute on both the staged and
355
+ // published data.
356
+ if (!onlyStaged) {
357
+ moveImg(resource.masterData.current)
358
+ }
359
+ checkForStagedChanges(resource)
360
+
361
+ return resource
362
+ },
363
+
186
364
  // 'changeName': () => {},
187
365
  // 'changeSlug': () => {},
188
366
  // 'addVariant': () => {},
@@ -202,9 +380,6 @@ export class ProductRepository extends AbstractResourceRepository<'product'> {
202
380
  // 'setTaxCategory': () => {},
203
381
  // 'setSku': () => {},
204
382
  // 'setProductVariantKey': () => {},
205
- // 'addExternalImage': () => {},
206
- // 'moveImageToPosition': () => {},
207
- // 'removeImage': () => {},
208
383
  // 'setImageLabel': () => {},
209
384
  // 'addAsset': () => {},
210
385
  // 'removeAsset': () => {},
@@ -83,6 +83,7 @@ export class ProjectRepository extends AbstractRepository<Project> {
83
83
  { messagesConfiguration }: ProjectChangeMessagesConfigurationAction
84
84
  ) => {
85
85
  resource.messages.enabled = messagesConfiguration.enabled
86
+ resource.messages.deleteDaysAfterCreation = messagesConfiguration.deleteDaysAfterCreation
86
87
  },
87
88
  changeProductSearchIndexingEnabled: (
88
89
  context: RepositoryContext,
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  State,
3
+ StateChangeInitialAction,
3
4
  StateChangeKeyAction,
4
5
  StateDraft,
5
6
  StateReference,
@@ -51,6 +52,13 @@ export class StateRepository extends AbstractResourceRepository<'state'> {
51
52
  ) => {
52
53
  resource.key = key
53
54
  },
55
+ changeInitial: (
56
+ context: RepositoryContext,
57
+ resource: Writable<State>,
58
+ {initial }: StateChangeInitialAction
59
+ ) => {
60
+ resource.initial = initial
61
+ },
54
62
  setDescription: (
55
63
  context: RepositoryContext,
56
64
  resource: Writable<State>,
@@ -1,4 +1,9 @@
1
- import { Product, ProductData, ProductDraft } from '@commercetools/platform-sdk'
1
+ import {
2
+ Image,
3
+ Product,
4
+ ProductData,
5
+ ProductDraft,
6
+ } from '@commercetools/platform-sdk'
2
7
  import assert from 'assert'
3
8
  import supertest from 'supertest'
4
9
  import { CommercetoolsMock } from '../index'
@@ -294,4 +299,107 @@ describe('Product update actions', () => {
294
299
  const attr = response.body.masterData.staged.masterVariant.attributes[0]
295
300
  expect(attr).toEqual({ name: 'test', value: 'foo' })
296
301
  })
302
+
303
+ test('addExternalImage variant', async () => {
304
+ assert(productPublished, 'product not created')
305
+
306
+ const image: Image = {
307
+ url: 'http://example.com/image',
308
+ dimensions: { w: 100, h: 100 },
309
+ }
310
+ const response = await supertest(ctMock.app)
311
+ .post(`/dummy/products/${productPublished.id}`)
312
+ .send({
313
+ version: 1,
314
+ actions: [{ action: 'addExternalImage', sku: '1338', image }],
315
+ })
316
+ expect(response.status).toBe(200)
317
+ expect(response.body.version).toBe(2)
318
+ expect(response.body.masterData.staged.variants[0].images).toHaveLength(1)
319
+ const attr = response.body.masterData.staged.variants[0].images[0]
320
+ expect(attr).toEqual(image)
321
+ })
322
+
323
+ test('removeImage variant', async () => {
324
+ assert(productPublished, 'product not created')
325
+
326
+ const image: Image = {
327
+ url: 'http://example.com/image',
328
+ dimensions: { w: 100, h: 100 },
329
+ }
330
+
331
+ {
332
+ const response = await supertest(ctMock.app)
333
+ .post(`/dummy/products/${productPublished.id}`)
334
+ .send({
335
+ version: 1,
336
+ actions: [{ action: 'addExternalImage', sku: '1338', image }],
337
+ })
338
+ expect(response.status).toBe(200)
339
+ expect(response.body.version).toBe(2)
340
+ }
341
+
342
+ const response = await supertest(ctMock.app)
343
+ .post(`/dummy/products/${productPublished.id}`)
344
+ .send({
345
+ version: 2,
346
+ actions: [
347
+ {
348
+ action: 'removeImage',
349
+ sku: '1338',
350
+ imageUrl: image.url,
351
+ },
352
+ ],
353
+ })
354
+ expect(response.status).toBe(200)
355
+ expect(response.body.version).toBe(3)
356
+ expect(response.body.masterData.staged.variants[0].images).toHaveLength(0)
357
+ })
358
+
359
+ test('moveImageToPosition variant', async () => {
360
+ assert(productPublished, 'product not created')
361
+
362
+ const image1: Image = {
363
+ url: 'http://example.com/image1',
364
+ dimensions: { w: 100, h: 100 },
365
+ }
366
+ const image2: Image = {
367
+ url: 'http://example.com/image2',
368
+ dimensions: { w: 100, h: 100 },
369
+ }
370
+
371
+ {
372
+ const response = await supertest(ctMock.app)
373
+ .post(`/dummy/products/${productPublished.id}`)
374
+ .send({
375
+ version: 1,
376
+ actions: [
377
+ { action: 'addExternalImage', sku: '1338', image: image1 },
378
+ { action: 'addExternalImage', sku: '1338', image: image2 },
379
+ ],
380
+ })
381
+ expect(response.status).toBe(200)
382
+ expect(response.body.version).toBe(3)
383
+ }
384
+
385
+ const response = await supertest(ctMock.app)
386
+ .post(`/dummy/products/${productPublished.id}`)
387
+ .send({
388
+ version: 3,
389
+ actions: [
390
+ {
391
+ action: 'moveImageToPosition',
392
+ sku: '1338',
393
+ imageUrl: image2.url,
394
+ position: 0,
395
+ },
396
+ ],
397
+ })
398
+ expect(response.status).toBe(200)
399
+ expect(response.body.version).toBe(4)
400
+ expect(response.body.masterData.staged.variants[0].images).toEqual([
401
+ { url: 'http://example.com/image2', dimensions: { w: 100, h: 100 } },
402
+ { url: 'http://example.com/image1', dimensions: { w: 100, h: 100 } },
403
+ ])
404
+ })
297
405
  })
@@ -29,13 +29,13 @@ export class ProjectService {
29
29
  return response.status(404).send({})
30
30
  }
31
31
 
32
- this.repository.processUpdateActions(
32
+ const updatedResource = this.repository.processUpdateActions(
33
33
  getRepositoryContext(request),
34
34
  project,
35
35
  updateRequest.version,
36
36
  updateRequest.actions
37
37
  )
38
38
 
39
- return response.status(200).send({})
39
+ return response.status(200).send(updatedResource)
40
40
  }
41
41
  }