@labdigital/commercetools-mock 0.6.4 → 0.7.1

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.
Files changed (118) hide show
  1. package/dist/index.d.ts +385 -3
  2. package/dist/index.global.js +49770 -0
  3. package/dist/index.global.js.map +1 -0
  4. package/dist/index.js +4622 -6
  5. package/dist/index.js.map +1 -0
  6. package/dist/index.mjs +4590 -0
  7. package/dist/index.mjs.map +1 -0
  8. package/package.json +30 -17
  9. package/src/ctMock.ts +5 -0
  10. package/src/helpers.ts +15 -0
  11. package/src/lib/projectionSearchFilter.test.ts +177 -0
  12. package/src/lib/projectionSearchFilter.ts +248 -0
  13. package/src/priceSelector.test.ts +96 -0
  14. package/src/priceSelector.ts +109 -0
  15. package/src/product-projection-search.ts +149 -0
  16. package/src/projectAPI.ts +19 -20
  17. package/src/repositories/category.ts +36 -0
  18. package/src/repositories/channel.ts +104 -0
  19. package/src/repositories/customer-group.ts +37 -0
  20. package/src/repositories/discount-code.ts +37 -0
  21. package/src/repositories/helpers.ts +46 -4
  22. package/src/repositories/product-discount.ts +181 -0
  23. package/src/repositories/product-projection.ts +29 -55
  24. package/src/repositories/product-type.ts +88 -6
  25. package/src/repositories/product.ts +49 -9
  26. package/src/repositories/shipping-method.ts +31 -0
  27. package/src/repositories/store.ts +43 -3
  28. package/src/repositories/type.ts +19 -0
  29. package/src/services/custom-object.test.ts +2 -2
  30. package/src/services/product-discount.ts +33 -0
  31. package/src/services/product-projection.test.ts +171 -116
  32. package/src/services/product.test.ts +12 -0
  33. package/src/storage.ts +116 -58
  34. package/src/types.ts +9 -2
  35. package/dist/commercetools-mock.cjs.development.js +0 -4380
  36. package/dist/commercetools-mock.cjs.development.js.map +0 -1
  37. package/dist/commercetools-mock.cjs.production.min.js +0 -2
  38. package/dist/commercetools-mock.cjs.production.min.js.map +0 -1
  39. package/dist/commercetools-mock.esm.js +0 -4372
  40. package/dist/commercetools-mock.esm.js.map +0 -1
  41. package/dist/constants.d.ts +0 -2
  42. package/dist/ctMock.d.ts +0 -32
  43. package/dist/exceptions.d.ts +0 -12
  44. package/dist/helpers.d.ts +0 -6
  45. package/dist/lib/expandParser.d.ts +0 -15
  46. package/dist/lib/filterParser.d.ts +0 -1
  47. package/dist/lib/haversine.d.ts +0 -8
  48. package/dist/lib/masking.d.ts +0 -1
  49. package/dist/lib/predicateParser.d.ts +0 -11
  50. package/dist/lib/proxy.d.ts +0 -1
  51. package/dist/oauth/errors.d.ts +0 -8
  52. package/dist/oauth/helpers.d.ts +0 -2
  53. package/dist/oauth/server.d.ts +0 -12
  54. package/dist/oauth/store.d.ts +0 -14
  55. package/dist/projectAPI.d.ts +0 -12
  56. package/dist/repositories/abstract.d.ts +0 -33
  57. package/dist/repositories/cart-discount.d.ts +0 -9
  58. package/dist/repositories/cart.d.ts +0 -21
  59. package/dist/repositories/category.d.ts +0 -18
  60. package/dist/repositories/channel.d.ts +0 -6
  61. package/dist/repositories/custom-object.d.ts +0 -8
  62. package/dist/repositories/customer-group.d.ts +0 -11
  63. package/dist/repositories/customer.d.ts +0 -11
  64. package/dist/repositories/discount-code.d.ts +0 -8
  65. package/dist/repositories/errors.d.ts +0 -2
  66. package/dist/repositories/extension.d.ts +0 -8
  67. package/dist/repositories/helpers.d.ts +0 -10
  68. package/dist/repositories/inventory-entry.d.ts +0 -14
  69. package/dist/repositories/my-order.d.ts +0 -6
  70. package/dist/repositories/order.d.ts +0 -26
  71. package/dist/repositories/payment.d.ts +0 -23
  72. package/dist/repositories/product-projection.d.ts +0 -10
  73. package/dist/repositories/product-type.d.ts +0 -10
  74. package/dist/repositories/product.d.ts +0 -11
  75. package/dist/repositories/project.d.ts +0 -8
  76. package/dist/repositories/shipping-method.d.ts +0 -10
  77. package/dist/repositories/shopping-list.d.ts +0 -6
  78. package/dist/repositories/state.d.ts +0 -8
  79. package/dist/repositories/store.d.ts +0 -10
  80. package/dist/repositories/subscription.d.ts +0 -6
  81. package/dist/repositories/tax-category.d.ts +0 -10
  82. package/dist/repositories/type.d.ts +0 -8
  83. package/dist/repositories/zone.d.ts +0 -8
  84. package/dist/server.d.ts +0 -1
  85. package/dist/services/abstract.d.ts +0 -20
  86. package/dist/services/cart-discount.d.ts +0 -9
  87. package/dist/services/cart.d.ts +0 -12
  88. package/dist/services/category.d.ts +0 -9
  89. package/dist/services/channel.d.ts +0 -9
  90. package/dist/services/custom-object.d.ts +0 -13
  91. package/dist/services/customer-group.d.ts +0 -9
  92. package/dist/services/customer.d.ts +0 -10
  93. package/dist/services/discount-code.d.ts +0 -9
  94. package/dist/services/extension.d.ts +0 -9
  95. package/dist/services/inventory-entry.d.ts +0 -9
  96. package/dist/services/my-cart.d.ts +0 -11
  97. package/dist/services/my-customer.d.ts +0 -13
  98. package/dist/services/my-order.d.ts +0 -10
  99. package/dist/services/my-payment.d.ts +0 -9
  100. package/dist/services/order.d.ts +0 -12
  101. package/dist/services/payment.d.ts +0 -9
  102. package/dist/services/product-projection.d.ts +0 -11
  103. package/dist/services/product-type.d.ts +0 -11
  104. package/dist/services/product.d.ts +0 -9
  105. package/dist/services/project.d.ts +0 -11
  106. package/dist/services/shipping-method.d.ts +0 -10
  107. package/dist/services/shopping-list.d.ts +0 -9
  108. package/dist/services/state.d.ts +0 -9
  109. package/dist/services/store.d.ts +0 -11
  110. package/dist/services/subscription.d.ts +0 -9
  111. package/dist/services/tax-category.d.ts +0 -11
  112. package/dist/services/type.d.ts +0 -9
  113. package/dist/services/zone.d.ts +0 -9
  114. package/dist/storage.d.ts +0 -56
  115. package/dist/types.d.ts +0 -89
  116. package/dist/validate.d.ts +0 -7482
  117. package/src/lib/filterParser.test.ts +0 -15
  118. package/src/lib/filterParser.ts +0 -17
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  Type,
3
3
  TypeDraft,
4
+ InvalidOperationError,
4
5
  ReferenceTypeId,
5
6
  TypeUpdateAction,
6
7
  FieldDefinition,
@@ -12,6 +13,8 @@ import {
12
13
  TypeChangeFieldDefinitionOrderAction,
13
14
  TypeRemoveFieldDefinitionAction,
14
15
  } from '@commercetools/platform-sdk'
16
+ import { CommercetoolsError } from '../exceptions'
17
+ import { isEqual } from 'lodash'
15
18
  import { Writable } from 'types'
16
19
  import { getBaseResourceProperties } from '../helpers'
17
20
  import { AbstractResourceRepository, RepositoryContext } from './abstract'
@@ -97,6 +100,22 @@ export class TypeRepository extends AbstractResourceRepository {
97
100
  })
98
101
  })
99
102
 
103
+ if (
104
+ isEqual(
105
+ fieldNames,
106
+ resource.fieldDefinitions.map(item => item.name)
107
+ )
108
+ ) {
109
+ throw new CommercetoolsError<InvalidOperationError>({
110
+ code: 'InvalidOperation',
111
+ message: "'fieldDefinitions' has no changes.",
112
+ action: {
113
+ action: 'changeFieldDefinitionOrder',
114
+ fieldNames: fieldNames,
115
+ },
116
+ })
117
+ }
118
+
100
119
  resource.fieldDefinitions = result
101
120
  // Add fields which were not specified in the order as last items. Not
102
121
  // sure if this follows commercetools
@@ -118,7 +118,7 @@ describe('CustomObject retrieve', () => {
118
118
  })
119
119
 
120
120
  test('can use the add function with the custom object name', async () => {
121
- ctMock.project('dummy').add('custom-object', {
121
+ ctMock.project('dummy').add('key-value-document', {
122
122
  ...getBaseResourceProperties(),
123
123
  container: 'my-container',
124
124
  key: 'my-key',
@@ -143,7 +143,7 @@ describe('CustomObject retrieve', () => {
143
143
  })
144
144
 
145
145
  test('update with container and key', async () => {
146
- ctMock.project('dummy').add('custom-object', {
146
+ ctMock.project('dummy').add('key-value-document', {
147
147
  ...getBaseResourceProperties(),
148
148
  container: 'my-container',
149
149
  key: 'my-key',
@@ -0,0 +1,33 @@
1
+ import { ProductDiscountRepository } from '../repositories/product-discount'
2
+ import AbstractService from './abstract'
3
+ import { Request, Response, Router } from 'express'
4
+ import { AbstractStorage } from '../storage'
5
+ import { getRepositoryContext } from '../repositories/helpers'
6
+
7
+ export class ProductDiscountService extends AbstractService {
8
+ public repository: ProductDiscountRepository
9
+
10
+ constructor(parent: Router, storage: AbstractStorage) {
11
+ super(parent)
12
+ this.repository = new ProductDiscountRepository(storage)
13
+ }
14
+
15
+ getBasePath() {
16
+ return 'product-discounts'
17
+ }
18
+
19
+ extraRoutes(router: Router) {
20
+ router.get('/key=:key', this.getWithKey.bind(this))
21
+ }
22
+
23
+ getWithKey(request: Request, response: Response) {
24
+ const resource = this.repository.getWithKey(
25
+ getRepositoryContext(request),
26
+ request.params.key
27
+ )
28
+ if (resource) {
29
+ return response.status(200).send(resource)
30
+ }
31
+ return response.status(404).send('Not found')
32
+ }
33
+ }
@@ -1,167 +1,222 @@
1
- import { ProductDraft, ProductProjection } from '@commercetools/platform-sdk'
1
+ import {
2
+ ProductDraft,
3
+ ProductProjection,
4
+ ProductProjectionPagedSearchResponse,
5
+ ProductType,
6
+ ProductTypeDraft,
7
+ } from '@commercetools/platform-sdk'
2
8
  import supertest from 'supertest'
9
+ import * as timekeeper from 'timekeeper'
3
10
  import { CommercetoolsMock } from '../index'
4
- import * as qs from 'querystring'
11
+ import { Writable } from 'types'
5
12
 
6
13
  const ctMock = new CommercetoolsMock()
7
14
 
8
- describe('Product Projection', () => {
9
- afterEach(() => {
10
- ctMock.clear()
11
- })
15
+ let productType: ProductType
16
+ let productProjection: ProductProjection
17
+
18
+ beforeEach(async () => {
19
+ timekeeper.freeze(new Date('2022-07-22T13:31:49.840Z'))
20
+
21
+ // Create the product type
22
+ {
23
+ const draft: ProductTypeDraft = {
24
+ name: 'Default Product Type',
25
+ description: 'Product type for testing',
26
+ }
27
+ const response = await supertest(ctMock.app)
28
+ .post('/dummy/product-types')
29
+ .send(draft)
12
30
 
13
- test('Create product projection', async () => {
14
- const draft: ProductDraft = {
15
- key: '1337357',
31
+ expect(response.ok).toBe(true)
32
+ productType = response.body
33
+ }
34
+
35
+ // Create the product
36
+ {
37
+ const productDraft: Writable<ProductDraft> = {
38
+ publish: true,
39
+ key: 'my-product-key',
16
40
  masterVariant: {
17
- sku: '1337',
41
+ sku: 'my-sku',
42
+ prices: [
43
+ {
44
+ value: {
45
+ currencyCode: 'EUR',
46
+ centAmount: 1789,
47
+ },
48
+ },
49
+ ],
50
+ attributes: [
51
+ {
52
+ name: 'number',
53
+ value: '1' as any,
54
+ },
55
+ ],
18
56
  },
19
57
  name: {
20
58
  'nl-NL': 'test product',
21
59
  },
22
60
  productType: {
23
61
  typeId: 'product-type',
24
- id: 'some-uuid',
62
+ id: productType.id,
25
63
  },
26
64
  slug: {
27
65
  'nl-NL': 'test-product',
28
66
  },
29
67
  }
68
+
30
69
  const response = await supertest(ctMock.app)
31
- .post('/dummy/product-projections')
32
- .send(draft)
70
+ .post('/dummy/products')
71
+ .send(productDraft)
72
+ expect(response.ok).toBe(true)
73
+ const product = response.body
33
74
 
34
- const projection: ProductProjection = response.body
35
- expect(projection).toEqual({
36
- createdAt: expect.anything(),
37
- id: expect.anything(),
38
- lastModifiedAt: expect.anything(),
39
- name: {
40
- 'nl-NL': 'test product',
41
- },
42
- slug: {
43
- 'nl-NL': 'test-product',
44
- },
45
- categories: [],
75
+ // Create the expected ProductProjection object
76
+ productProjection = {
77
+ id: product.id,
78
+ createdAt: '2022-07-22T13:31:49.840Z',
79
+ lastModifiedAt: '2022-07-22T13:31:49.840Z',
46
80
  version: 1,
47
81
  masterVariant: {
48
- id: 0,
49
- sku: '1337',
82
+ id: 1,
83
+ sku: 'my-sku',
84
+ prices: [
85
+ {
86
+ id: product.masterData.current.masterVariant.prices[0].id,
87
+ value: {
88
+ type: 'centPrecision',
89
+ currencyCode: 'EUR',
90
+ centAmount: 1789,
91
+ fractionDigits: 2,
92
+ },
93
+ },
94
+ ],
95
+ assets: [],
96
+ images: [],
97
+ attributes: productDraft.masterVariant?.attributes,
50
98
  },
99
+ variants: [],
100
+ name: productDraft.name,
101
+ slug: productDraft.slug,
102
+ categories: [],
51
103
  productType: {
52
- id: 'some-uuid',
53
104
  typeId: 'product-type',
105
+ id: productType.id,
54
106
  },
55
- variants: [],
56
- })
57
- })
107
+ }
108
+ }
109
+ })
110
+
111
+ afterEach(async () => {
112
+ timekeeper.reset()
58
113
 
59
- test('Get product projection by 404 when not found by key with expand', async () => {
60
- const response = await supertest(ctMock.app).get(
61
- '/dummy/product-projections/key=DOESNOTEXIST?' +
62
- qs.stringify({
63
- expand: ['categories[*]'],
114
+ const response = await supertest(ctMock.app)
115
+ .delete(`/dummy/products/${productProjection.id}`)
116
+ .send()
117
+ expect(response.ok).toBe(true)
118
+ const product = response.body
119
+ })
120
+
121
+ // Test the general product projection implementation
122
+ describe('Product Projection Search - Generic', () => {
123
+ test('Pagination', async () => {
124
+ {
125
+ const response = await supertest(ctMock.app)
126
+ .get('/dummy/product-projections/search')
127
+ .query({
128
+ limit: 50,
64
129
  })
65
- )
66
130
 
67
- expect(response.status).toBe(404)
131
+ const result: ProductProjectionPagedSearchResponse = response.body
132
+ expect(result).toEqual({
133
+ count: 1,
134
+ limit: 50,
135
+ offset: 0,
136
+ total: 1,
137
+ facets: {},
138
+ results: [productProjection],
139
+ })
140
+ }
141
+ {
142
+ const response = await supertest(ctMock.app)
143
+ .get('/dummy/product-projections/search')
144
+ .query({
145
+ limit: 50,
146
+ offset: 50,
147
+ })
148
+
149
+ const projection: ProductProjection = response.body
150
+ expect(projection).toEqual({
151
+ count: 1,
152
+ limit: 50,
153
+ offset: 50,
154
+ total: 0,
155
+ facets: {},
156
+ results: [],
157
+ })
158
+ }
68
159
  })
69
- })
70
160
 
71
- describe('Product Projection Search', () => {
72
- beforeAll(() => {
73
- ctMock.project('dummy').add('product-projection', {
74
- id: '',
75
- version: 1,
76
- productType: {
77
- id: 'fake',
78
- typeId: 'product-type',
79
- },
80
- name: { 'nl-NL': 'test-prod' },
81
- slug: {},
82
- variants: [],
83
- masterVariant: { id: 1, sku: '1337' },
84
- createdAt: '',
85
- lastModifiedAt: '',
86
- categories: [],
87
- })
161
+ test('Get 404 when not found by key with expand', async () => {
162
+ const response = await supertest(ctMock.app)
163
+ .get('/dummy/product-projections/key=DOESNOTEXIST')
164
+ .query({
165
+ expand: ['categories[*]'],
166
+ })
167
+
168
+ expect(response.status).toBe(404)
88
169
  })
170
+ })
89
171
 
90
- test('Search product projection', async () => {
91
- const response = await supertest(ctMock.app).get(
92
- '/dummy/product-projections/search?' +
93
- qs.stringify({
94
- filter: ['masterVariant.sku:"1337"'],
95
- })
96
- )
172
+ describe('Product Projection Search - Filters', () => {
173
+ test('variants.sku', async () => {
174
+ const response = await supertest(ctMock.app)
175
+ .get('/dummy/product-projections/search')
176
+ .query({
177
+ filter: ['variants.sku:"my-sku"'],
178
+ })
97
179
 
98
- const projection: ProductProjection = response.body
99
- expect(projection).toEqual({
180
+ const result: ProductProjectionPagedSearchResponse = response.body
181
+ expect(result).toMatchObject({
100
182
  count: 1,
101
- limit: 20,
102
- offset: 0,
103
- total: 1,
104
183
  results: [
105
184
  {
106
- categories: [],
107
- createdAt: '',
108
- id: '',
109
- lastModifiedAt: '',
110
- masterVariant: { id: 1, sku: '1337' },
111
- name: { 'nl-NL': 'test-prod' },
112
- productType: { id: 'fake', typeId: 'product-type' },
113
- slug: {},
114
- variants: [],
115
- version: 1,
185
+ masterVariant: { sku: 'my-sku' },
116
186
  },
117
187
  ],
118
188
  })
119
189
  })
120
190
 
121
- test('Search product projection page 2', async () => {
122
- const response = await supertest(ctMock.app).get(
123
- '/dummy/product-projections/search?' +
124
- qs.stringify({
125
- filter: ['masterVariant.sku:"1337"'],
126
- limit: 50,
127
- offset: 100,
128
- })
129
- )
130
-
131
- const projection: ProductProjection = response.body
132
- expect(projection).toEqual({
133
- count: 1,
134
- limit: 50,
135
- offset: 100,
136
- total: 0,
137
- results: [],
138
- })
139
- })
140
-
141
- test('Search product projection with query.filter', async () => {
142
- const response = await supertest(ctMock.app).get(
143
- '/dummy/product-projections/search?' +
144
- qs.stringify({
145
- 'query.filter': ['masterVariant.sku:"1337"'],
146
- })
147
- )
191
+ test('variants.attributes.range - match', async () => {
192
+ const response = await supertest(ctMock.app)
193
+ .get('/dummy/product-projections/search')
194
+ .query({
195
+ filter: ['variants.attributes.number:range(0 TO 10)'],
196
+ })
148
197
 
149
- const projection: ProductProjection = response.body
150
- expect(projection).toMatchObject({
198
+ const result: ProductProjectionPagedSearchResponse = response.body
199
+ expect(result).toMatchObject({
151
200
  count: 1,
152
- results: [{ masterVariant: { id: 1, sku: '1337' } }],
201
+ results: [
202
+ {
203
+ masterVariant: { sku: 'my-sku' },
204
+ },
205
+ ],
153
206
  })
154
207
  })
155
208
 
156
- test('Search product projection without filter', async () => {
157
- const response = await supertest(ctMock.app).get(
158
- '/dummy/product-projections/search'
159
- )
209
+ test('variants.attributes.range - mismatch', async () => {
210
+ const response = await supertest(ctMock.app)
211
+ .get('/dummy/product-projections/search')
212
+ .query({
213
+ filter: ['variants.attributes.number:range(2 TO 10)'],
214
+ })
160
215
 
161
- const projection: ProductProjection = response.body
162
- expect(projection).toMatchObject({
163
- count: 1,
164
- results: [{ masterVariant: { id: 1, sku: '1337' } }],
216
+ const result: ProductProjectionPagedSearchResponse = response.body
217
+ expect(result).toMatchObject({
218
+ count: 0,
219
+ results: [],
165
220
  })
166
221
  })
167
222
  })
@@ -18,6 +18,7 @@ describe('Product', () => {
18
18
  slug: {
19
19
  'nl-NL': 'test-product',
20
20
  },
21
+ masterVariant: {},
21
22
  }
22
23
 
23
24
  const response = await supertest(ctMock.app)
@@ -37,10 +38,21 @@ describe('Product', () => {
37
38
  'nl-NL': 'test-product',
38
39
  },
39
40
  categories: [],
41
+ masterVariant: {
42
+ assets: [],
43
+ attributes: [],
44
+ id: 1,
45
+ images: [],
46
+ },
47
+ variants: [],
40
48
  },
41
49
  hasStagedChanges: true,
42
50
  published: false,
43
51
  },
52
+ productType: {
53
+ typeId: 'product-type',
54
+ id: 'some-uuid',
55
+ },
44
56
  version: 1,
45
57
  })
46
58
  })