@reactionary/source 0.0.37 → 0.0.39

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 (93) hide show
  1. package/.env-template +10 -0
  2. package/.github/workflows/pull-request.yml +5 -3
  3. package/core/package.json +1 -2
  4. package/core/src/client/client.ts +4 -2
  5. package/core/src/index.ts +3 -9
  6. package/core/src/providers/analytics.provider.ts +6 -1
  7. package/core/src/providers/base.provider.ts +33 -3
  8. package/core/src/providers/cart.provider.ts +7 -1
  9. package/core/src/providers/category.provider.ts +91 -0
  10. package/core/src/providers/identity.provider.ts +5 -1
  11. package/core/src/providers/inventory.provider.ts +4 -0
  12. package/core/src/providers/price.provider.ts +54 -0
  13. package/core/src/providers/product.provider.ts +4 -0
  14. package/core/src/providers/search.provider.ts +6 -0
  15. package/core/src/schemas/capabilities.schema.ts +3 -2
  16. package/core/src/schemas/models/base.model.ts +42 -1
  17. package/core/src/schemas/models/cart.model.ts +27 -3
  18. package/core/src/schemas/models/category.model.ts +23 -0
  19. package/core/src/schemas/models/identifiers.model.ts +29 -1
  20. package/core/src/schemas/models/inventory.model.ts +6 -2
  21. package/core/src/schemas/models/price.model.ts +11 -3
  22. package/core/src/schemas/models/search.model.ts +4 -2
  23. package/core/src/schemas/queries/category.query.ts +32 -0
  24. package/core/src/schemas/queries/index.ts +9 -0
  25. package/core/src/schemas/queries/inventory.query.ts +18 -3
  26. package/core/src/schemas/session.schema.ts +13 -2
  27. package/examples/next/.swcrc +30 -0
  28. package/examples/next/eslint.config.mjs +21 -0
  29. package/examples/next/index.d.ts +6 -0
  30. package/examples/next/next-env.d.ts +5 -0
  31. package/examples/next/next.config.js +20 -0
  32. package/examples/next/project.json +9 -0
  33. package/examples/next/public/.gitkeep +0 -0
  34. package/examples/next/public/favicon.ico +0 -0
  35. package/examples/next/src/app/global.css +0 -0
  36. package/examples/next/src/app/layout.tsx +18 -0
  37. package/examples/next/src/app/page.module.scss +2 -0
  38. package/examples/next/src/app/page.tsx +51 -0
  39. package/examples/next/src/instrumentation.ts +9 -0
  40. package/examples/next/tsconfig.json +44 -0
  41. package/examples/node/src/basic/basic-node-provider-model-extension.spec.ts +0 -1
  42. package/examples/node/src/basic/basic-node-setup.spec.ts +0 -1
  43. package/otel/README.md +152 -172
  44. package/otel/package.json +0 -1
  45. package/otel/src/index.ts +15 -5
  46. package/otel/src/metrics.ts +3 -3
  47. package/otel/src/test/otel.spec.ts +8 -0
  48. package/otel/src/trace-decorator.ts +87 -108
  49. package/otel/src/tracer.ts +3 -3
  50. package/package.json +2 -1
  51. package/providers/commercetools/package.json +1 -0
  52. package/providers/commercetools/src/core/initialize.ts +7 -3
  53. package/providers/commercetools/src/providers/cart.provider.ts +84 -8
  54. package/providers/commercetools/src/providers/category.provider.ts +244 -0
  55. package/providers/commercetools/src/providers/index.ts +7 -0
  56. package/providers/commercetools/src/providers/inventory.provider.ts +31 -14
  57. package/providers/commercetools/src/providers/price.provider.ts +74 -18
  58. package/providers/commercetools/src/providers/product.provider.ts +19 -15
  59. package/providers/commercetools/src/providers/search.provider.ts +9 -7
  60. package/providers/commercetools/src/schema/capabilities.schema.ts +2 -1
  61. package/providers/commercetools/src/schema/configuration.schema.ts +1 -1
  62. package/providers/commercetools/src/test/cart.provider.spec.ts +119 -0
  63. package/providers/commercetools/src/test/category.provider.spec.ts +180 -0
  64. package/providers/commercetools/src/test/price.provider.spec.ts +80 -0
  65. package/providers/commercetools/src/test/product.provider.spec.ts +29 -14
  66. package/providers/commercetools/src/test/search.provider.spec.ts +51 -9
  67. package/providers/commercetools/src/test/test-utils.ts +35 -0
  68. package/providers/commercetools/tsconfig.lib.json +1 -1
  69. package/providers/fake/jest.config.ts +10 -0
  70. package/providers/fake/src/core/initialize.ts +15 -1
  71. package/providers/fake/src/index.ts +2 -9
  72. package/providers/fake/src/providers/cart.provider.ts +74 -15
  73. package/providers/fake/src/providers/category.provider.ts +152 -0
  74. package/providers/fake/src/providers/index.ts +8 -0
  75. package/providers/fake/src/providers/inventory.provider.ts +23 -9
  76. package/providers/fake/src/providers/price.provider.ts +46 -6
  77. package/providers/fake/src/providers/search.provider.ts +13 -4
  78. package/providers/fake/src/schema/capabilities.schema.ts +4 -2
  79. package/providers/fake/src/schema/configuration.schema.ts +5 -0
  80. package/providers/fake/src/test/cart.provider.spec.ts +126 -0
  81. package/providers/fake/src/test/category.provider.spec.ts +134 -0
  82. package/providers/fake/src/test/price.provider.spec.ts +80 -0
  83. package/providers/fake/src/test/test-utils.ts +42 -0
  84. package/providers/fake/tsconfig.json +4 -0
  85. package/providers/fake/tsconfig.lib.json +3 -1
  86. package/providers/fake/tsconfig.spec.json +16 -0
  87. package/trpc/package.json +1 -2
  88. package/trpc/src/client.ts +1 -3
  89. package/trpc/src/integration.spec.ts +16 -10
  90. package/trpc/src/transparent-client.spec.ts +23 -17
  91. package/tsconfig.base.json +2 -0
  92. package/core/src/decorators/trpc.decorators.ts +0 -144
  93. package/otel/src/sdk.ts +0 -57
@@ -0,0 +1,119 @@
1
+ import 'dotenv/config';
2
+ import { CartSchema, CategorySchema, IdentitySchema, NoOpCache, ProductSchema, Session } from '@reactionary/core';
3
+ import { createAnonymousTestSession, getCommercetoolsTestConfiguration } from './test-utils';
4
+ import { CommercetoolsCartProvider } from '../providers/cart.provider';
5
+ import { CommercetoolsIdentityProvider } from '../providers/identity.provider';
6
+ describe('Commercetools Cart Provider', () => {
7
+ let provider: CommercetoolsCartProvider;
8
+ let identityProvider: CommercetoolsIdentityProvider;
9
+ let session: Session;
10
+
11
+ beforeAll( () => {
12
+ provider = new CommercetoolsCartProvider(getCommercetoolsTestConfiguration(), CartSchema, new NoOpCache());
13
+ identityProvider = new CommercetoolsIdentityProvider(getCommercetoolsTestConfiguration(), IdentitySchema, new NoOpCache());
14
+ });
15
+
16
+ beforeEach( () => {
17
+ session = createAnonymousTestSession()
18
+ });
19
+
20
+ describe('anonymous sessions', () => {
21
+ it('should be able to get an empty cart', async () => {
22
+ const cart = await provider.getById({
23
+ cart: { key: '' },
24
+ }, session);
25
+
26
+ expect(cart.identifier.key).toBeFalsy();
27
+ expect(cart.items.length).toBe(0);
28
+ expect(cart.meta?.placeholder).toBe(true);
29
+
30
+ });
31
+
32
+ it('should be able to add an item to a cart', async () => {
33
+ const cart = await provider.add({
34
+ cart: { key: '' },
35
+ product: {
36
+ key: '4d28f98d-c446-446e-b59a-d9f718e5b98a',
37
+ },
38
+ quantity: 1
39
+ }, session);
40
+
41
+ expect(cart.identifier.key).toBeDefined();
42
+ expect(cart.items.length).toBe(1);
43
+ expect(cart.items[0].product.key).toBe('4d28f98d-c446-446e-b59a-d9f718e5b98a');
44
+ expect(cart.items[0].quantity).toBe(1);
45
+
46
+ expect(cart.items[0].price.totalPrice.value).toBeGreaterThan(0);
47
+ expect(cart.items[0].price.totalPrice.currency).toBe(session.languageContext.currencyCode);
48
+
49
+ expect(cart.price.grandTotal.value).toBeGreaterThan(0);
50
+ expect(cart.price.grandTotal.currency).toBe(session.languageContext.currencyCode);
51
+
52
+ expect(cart.price.grandTotal.value).toBe(cart.items[0].price.totalPrice.value);
53
+
54
+
55
+ expect(cart.meta?.placeholder).toBeFalsy();
56
+
57
+ });
58
+
59
+
60
+ it('should be able to change quantity of an item in a cart', async () => {
61
+
62
+ const cart = await provider.add({
63
+ cart: { key: '' },
64
+ product: {
65
+ key: '4d28f98d-c446-446e-b59a-d9f718e5b98a',
66
+ },
67
+ quantity: 1
68
+ }, session);
69
+
70
+ const updatedCart = await provider.changeQuantity({
71
+ cart: cart.identifier,
72
+ item: cart.items[0].identifier,
73
+ quantity: 3
74
+ }, session);
75
+
76
+ expect(updatedCart.identifier.key).toBe(cart.identifier.key);
77
+ expect(updatedCart.items.length).toBe(1);
78
+ expect(updatedCart.items[0].product.key).toBe('4d28f98d-c446-446e-b59a-d9f718e5b98a');
79
+ expect(updatedCart.items[0].quantity).toBe(3);
80
+
81
+ expect(updatedCart.items[0].price.totalPrice.value).toBe(cart.items[0].price.totalPrice.value * 3);
82
+ expect(updatedCart.items[0].price.unitPrice.value).toBe(cart.items[0].price.unitPrice.value);
83
+
84
+
85
+ });
86
+
87
+ it('should be able to remove an item from a cart', async () => {
88
+
89
+ const cart = await provider.add({
90
+ cart: { key: '' },
91
+ product: {
92
+ key: '4d28f98d-c446-446e-b59a-d9f718e5b98a',
93
+ },
94
+ quantity: 1
95
+ }, session);
96
+
97
+ const updatedCart = await provider.remove({
98
+ cart: cart.identifier,
99
+ item: cart.items[0].identifier,
100
+ }, session);
101
+ expect(updatedCart.identifier.key).toBe(cart.identifier.key);
102
+ expect(updatedCart.items.length).toBe(0);
103
+ });
104
+
105
+ /**
106
+ it('should be able to create a cart for an anonymous user, then login and merge the cart', async () => {
107
+ });
108
+
109
+ it('should be able to create a cart for an anonymous user, then register and merge the cart', async () => {
110
+ });
111
+
112
+ it('should be able to clear the cart', async () => { });
113
+
114
+ it('should be able to check out the cart', async () => { });
115
+ */
116
+
117
+ });
118
+
119
+ });
@@ -0,0 +1,180 @@
1
+ import 'dotenv/config'
2
+
3
+ import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api';
4
+
5
+ import { CategorySchema, NoOpCache, ProductSchema, Session } from '@reactionary/core';
6
+ import { CommercetoolsCategoryProvider } from '../providers/category.provider';
7
+ import { createAnonymousTestSession, getCommercetoolsTestConfiguration } from './test-utils';
8
+ import { getTracer, shutdownOtel } from '@reactionary/otel';
9
+
10
+ const testData = {
11
+ topCategories: [
12
+ {
13
+ key: 'home-decor', name: 'Home Decor', slug: 'home-decor'
14
+ },
15
+ {
16
+ key: 'furniture', name: 'Furniture'
17
+ }
18
+ ],
19
+
20
+ childCategoriesOfFirstTopcategory: [
21
+ { key: 'bedding', name: 'Bedding' },
22
+ { key: 'room-decor', name: 'Room Decor' }
23
+ ],
24
+
25
+ breadCrumb: [ 'home-decor', 'room-decor', 'home-accents' ],
26
+ }
27
+
28
+
29
+ describe('Commercetools Category Provider', () => {
30
+ let provider: CommercetoolsCategoryProvider;
31
+ let session: Session;
32
+
33
+ beforeAll( () => {
34
+ provider = new CommercetoolsCategoryProvider(getCommercetoolsTestConfiguration(), CategorySchema, new NoOpCache());
35
+ });
36
+
37
+ beforeEach( () => {
38
+ session = createAnonymousTestSession()
39
+ })
40
+
41
+ it('should be able to get top-categories', async () => {
42
+ const result = await provider.findTopCategories({ paginationOptions: { pageSize: 10, pageNumber: 1 }}, session);
43
+
44
+ expect(result.items.length).toBeGreaterThan(0);
45
+ expect(result.items[0].identifier.key).toBe(testData.topCategories[0].key);
46
+ expect(result.items[0].name).toBe(testData.topCategories[0].name);
47
+
48
+ expect(result.items[1].identifier.key).toBe(testData.topCategories[1].key);
49
+ expect(result.items[1].name).toBe(testData.topCategories[1].name);
50
+ });
51
+
52
+ it('should be able to get child categories for a category', async () => {
53
+ const result = await provider.findChildCategories({ parentId: { key: testData.topCategories[0].key }, paginationOptions: { pageSize: 10, pageNumber: 1 }}, session);
54
+
55
+ expect(result.items.length).toBeGreaterThan(0);
56
+ expect(result.items[0].identifier.key).toBe(testData.childCategoriesOfFirstTopcategory[0].key);
57
+ expect(result.items[0].name).toBe(testData.childCategoriesOfFirstTopcategory[0].name);
58
+
59
+ expect(result.items[1].identifier.key).toBe(testData.childCategoriesOfFirstTopcategory[1].key);
60
+ expect(result.items[1].name).toBe(testData.childCategoriesOfFirstTopcategory[1].name);
61
+
62
+ });
63
+
64
+
65
+ it('should be able to get child categories for a category, paged', async () => {
66
+ let result = await provider.findChildCategories({ parentId: { key: testData.topCategories[0].key }, paginationOptions: { pageSize: 1, pageNumber: 1 }}, session);
67
+
68
+ expect(result.items.length).toBeGreaterThan(0);
69
+ expect(result.items[0].identifier.key).toBe(testData.childCategoriesOfFirstTopcategory[0].key);
70
+ expect(result.items[0].name).toBe(testData.childCategoriesOfFirstTopcategory[0].name);
71
+ expect(result.totalCount).toBe(2);
72
+ expect(result.totalPages).toBe(2);
73
+ expect(result.pageSize).toBe(1);
74
+ expect(result.pageNumber).toBe(1);
75
+
76
+ result = await provider.findChildCategories({ parentId: { key: testData.topCategories[0].key }, paginationOptions: { pageSize: 1, pageNumber: 2 }}, session);
77
+
78
+ expect(result.items.length).toBeGreaterThan(0);
79
+ expect(result.items[0].identifier.key).toBe(testData.childCategoriesOfFirstTopcategory[1].key);
80
+ expect(result.items[0].name).toBe(testData.childCategoriesOfFirstTopcategory[1].name);
81
+ expect(result.totalCount).toBe(2);
82
+ expect(result.totalPages).toBe(2);
83
+ expect(result.pageSize).toBe(1);
84
+ expect(result.pageNumber).toBe(2);
85
+ });
86
+
87
+
88
+ it('can load all breadcrumbs for a category', async () => {
89
+ const leaf = testData.breadCrumb[testData.breadCrumb.length -1];
90
+ const result = await provider.getBreadcrumbPathToCategory({ id: { key: leaf! } }, session);
91
+
92
+ expect(result.length).toBe(testData.breadCrumb.length);
93
+ for(let i = 0 ; i < testData.breadCrumb.length; i++) {
94
+ expect(result[i].identifier.key).toBe(testData.breadCrumb[i]);
95
+ }
96
+ });
97
+
98
+
99
+ it('should be able to get a category by slug', async () => {
100
+
101
+ const result = await provider.getBySlug({ slug: testData.topCategories[0].slug! }, session);
102
+ expect(result).toBeTruthy();
103
+ if (result) {
104
+ expect(result.identifier.key).toBe(testData.topCategories[0].key);
105
+ expect(result.name).toBe(testData.topCategories[0].name);
106
+ expect(result.slug).toBe(testData.topCategories[0].slug);
107
+ expect(result.parentCategory).toBeUndefined();
108
+ expect(result.text).not.toBe("");
109
+ expect(result.meta.placeholder).toBe(false);
110
+ }
111
+ });
112
+
113
+ it('returns null if looking for slug that does not exist', async () => {
114
+ const result = await provider.getBySlug({ slug: 'non-existent-slug' }, session);
115
+ expect(result).toBeNull();
116
+ });
117
+
118
+
119
+
120
+ it('should be able to get a category by id', async () => {
121
+ const result = await provider.getById({ id: { key: 'home-decor'}}, session);
122
+
123
+ expect(result.identifier.key).toBe('home-decor');
124
+ expect(result.name).toBe('Home Decor');
125
+ expect(result.slug).toBe('home-decor');
126
+ expect(result.parentCategory).toBeUndefined();
127
+
128
+ expect(result.text).toBe('A test description');
129
+ expect(result.meta.placeholder).toBe(false);
130
+
131
+ });
132
+
133
+ it('should be able to get a category by id in alternate language', async () => {
134
+
135
+ session.languageContext.locale = 'de-DE';
136
+ const result = await provider.getById({ id: { key: 'home-decor'}}, session);
137
+
138
+ expect(result.identifier.key).toBe('home-decor');
139
+ expect(result.name).toBe('Dekoration');
140
+ expect(result.slug).toBe('home-decor');
141
+ expect(result.parentCategory).toBeUndefined();
142
+
143
+ expect(result.text).toBe('Eine Testbeschreibung');
144
+ expect(result.meta.placeholder).toBe(false);
145
+
146
+ });
147
+
148
+
149
+ it('returns empty values if you choose a language that is not available', async () => {
150
+
151
+ session.languageContext.locale = 'fr-FR';
152
+ const result = await provider.getById({ id: { key: 'home-decor'}}, session);
153
+
154
+ expect(result.identifier.key).toBe('home-decor');
155
+ expect(result.name).toBe('No Name');
156
+ expect(result.slug).toBe('');
157
+ expect(result.parentCategory).toBeUndefined();
158
+
159
+ expect(result.meta.placeholder).toBe(false);
160
+
161
+ });
162
+
163
+
164
+
165
+ it('returns a placeholder if you search for a category that does not exist', async () => {
166
+ const result = await provider.getById({ id: { key: 'non-existent-category'}}, session);
167
+ expect(result.identifier.key).toBe('non-existent-category');
168
+ expect(result.meta.placeholder).toBe(true);
169
+
170
+ });
171
+
172
+ it('traces execution of getById', async () => {
173
+ const tracer = getTracer();
174
+ const span = tracer.startSpan('test-span');
175
+ const result = await provider.getById({ id: { key: 'home-decor'}}, session);
176
+ span.end();
177
+ await shutdownOtel();
178
+ });
179
+
180
+ });
@@ -0,0 +1,80 @@
1
+ import 'dotenv/config';
2
+
3
+
4
+ import { NoOpCache, PriceSchema, Session } from '@reactionary/core';
5
+ import { createAnonymousTestSession, getCommercetoolsTestConfiguration } from './test-utils';
6
+
7
+ import { CommercetoolsPriceProvider } from '../providers/price.provider';
8
+
9
+ const testData = {
10
+ skuWithoutTiers: 'SGB-01',
11
+ skuWithTiers: 'GMCT-01'
12
+ }
13
+
14
+
15
+ describe('Commercetools Price Provider', () => {
16
+ let provider: CommercetoolsPriceProvider;
17
+ let session: Session;
18
+
19
+
20
+
21
+ beforeAll( () => {
22
+ provider = new CommercetoolsPriceProvider(getCommercetoolsTestConfiguration(), PriceSchema, new NoOpCache());
23
+ });
24
+
25
+ beforeEach( () => {
26
+ session = createAnonymousTestSession()
27
+ })
28
+
29
+ it('should be able to get prices for a product without tiers', async () => {
30
+ const result = await provider.getBySKU({ sku: { key: testData.skuWithoutTiers }}, session);
31
+
32
+ expect(result).toBeTruthy();
33
+ if (result) {
34
+ expect(result.identifier.sku.key).toBe(testData.skuWithoutTiers);
35
+ expect(result.unitPrice.value).toBeGreaterThan(0);
36
+ expect(result.unitPrice.currency).toBe('USD');
37
+ expect(result.tieredPrices.length).toBe(0);
38
+ }
39
+ });
40
+
41
+ it('should be able to get prices for a product with tiers', async () => {
42
+ const result = await provider.getBySKU({ sku: { key: testData.skuWithTiers }}, session);
43
+
44
+ expect(result).toBeTruthy();
45
+ if (result) {
46
+ expect(result.identifier.sku.key).toBe(testData.skuWithTiers);
47
+ expect(result.unitPrice.value).toBeGreaterThan(0);
48
+ expect(result.unitPrice.currency).toBe('USD');
49
+ expect(result.tieredPrices.length).toBeGreaterThan(0);
50
+
51
+ expect(result.tieredPrices[0].minimumQuantity).toBeGreaterThan(0);
52
+ expect(result.tieredPrices[0].price.value).toBeLessThanOrEqual(result.unitPrice.value);
53
+ expect(result.tieredPrices[0].price.currency).toBe('USD');
54
+
55
+ }
56
+ });
57
+
58
+ it('should return a placeholder price for an unknown SKU', async () => {
59
+ const result = await provider.getBySKU({ sku: { key: 'unknown-sku' }}, session);
60
+
61
+ expect(result).toBeTruthy();
62
+ if (result) {
63
+ expect(result.identifier.sku.key).toBe('unknown-sku');
64
+ expect(result.unitPrice.value).toBe(-1);
65
+ expect(result.unitPrice.currency).toBe('USD');
66
+ expect(result.tieredPrices.length).toBe(0);
67
+ expect(result.meta?.placeholder).toBe(true);
68
+ }
69
+ });
70
+
71
+ it('can look up multiple prices at once', async () => {
72
+ const skus = [testData.skuWithTiers, testData.skuWithoutTiers, 'unknown-sku'];
73
+ const results = await Promise.all(skus.map( sku => provider.getBySKU({ sku: { key: sku }}, session)));
74
+
75
+ expect(results).toHaveLength(skus.length);
76
+ expect(results[0].identifier.sku.key).toBe(testData.skuWithTiers);
77
+ expect(results[1].identifier.sku.key).toBe(testData.skuWithoutTiers);
78
+ expect(results[2].identifier.sku.key).toBe('unknown-sku');
79
+ });
80
+ });
@@ -1,20 +1,35 @@
1
- import { ProductSchema } from '@reactionary/core';
1
+ import 'dotenv/config';
2
+ import { NoOpCache, ProductSchema, Session } from '@reactionary/core';
2
3
  import { CommercetoolsProductProvider } from '../providers/product.provider';
4
+ import { createAnonymousTestSession, getCommercetoolsTestConfiguration } from './test-utils';
5
+
6
+ const testData = {
7
+ product : {
8
+ id: '4d28f98d-c446-446e-b59a-d9f718e5b98a',
9
+ name: 'Sunnai Glass Bowl',
10
+ image: 'https://storage.googleapis.com/merchant-center-europe/sample-data/goodstore/Sunnai_Glass_Bowl-1.1.jpeg'
11
+ }
12
+ }
3
13
 
4
14
  describe('Commercetools Product Provider', () => {
15
+
16
+ let provider: CommercetoolsProductProvider;
17
+ let session: Session;
18
+
19
+ beforeAll( () => {
20
+ provider = new CommercetoolsProductProvider(getCommercetoolsTestConfiguration(), ProductSchema, new NoOpCache());
21
+ });
22
+
23
+ beforeEach( () => {
24
+ session = createAnonymousTestSession()
25
+ })
26
+
27
+
5
28
  it('should be able to get a product by id', async () => {
6
- const provider = new CommercetoolsProductProvider({
7
- apiUrl: process.env['COMMERCETOOLS_API_URL'] || '',
8
- authUrl: process.env['COMMERCETOOLS_AUTH_URL'] || '',
9
- clientId: process.env['COMMERCETOOLS_CLIENT_ID'] || '',
10
- clientSecret: process.env['COMMERCETOOLS_CLIENT_SECRET'] || '',
11
- projectKey: process.env['COMMERCETOOLS_PROJECT_KEY'] || ''
12
- }, ProductSchema);
13
-
14
- const result = await provider.get({ id: '4d28f98d-c446-446e-b59a-d9f718e5b98a'});
15
-
16
- expect(result.identifier.key).toBe('4d28f98d-c446-446e-b59a-d9f718e5b98a');
17
- expect(result.name).toBe('Sunnai Glass Bowl');
18
- expect(result.image).toBe('https://storage.googleapis.com/merchant-center-europe/sample-data/goodstore/Sunnai_Glass_Bowl-1.1.jpeg');
29
+ const result = await provider.getById( { id: testData.product.id }, session);
30
+
31
+ expect(result.identifier.key).toBe(testData.product.id);
32
+ expect(result.name).toBe(testData.product.name);
33
+ expect(result.image).toBe(testData.product.image);
19
34
  });
20
35
  });
@@ -1,18 +1,60 @@
1
- import { SearchResultSchema } from '@reactionary/core';
1
+ import 'dotenv/config';
2
+ import { NoOpCache, SearchResultSchema, Session } from '@reactionary/core';
2
3
  import { CommercetoolsSearchProvider } from '../providers/search.provider';
4
+ import { getCommercetoolsTestConfiguration, createAnonymousTestSession } from './test-utils';
5
+
6
+ const testData = {
7
+ searchTerm: 'bowl'
8
+ }
3
9
 
4
10
  describe('Commercetools Search Provider', () => {
11
+
12
+ let provider: CommercetoolsSearchProvider;
13
+ let session: Session;
14
+
15
+ beforeAll( () => {
16
+ provider = new CommercetoolsSearchProvider(getCommercetoolsTestConfiguration(), SearchResultSchema, new NoOpCache());
17
+ });
18
+
19
+ beforeEach( () => {
20
+ session = createAnonymousTestSession()
21
+ })
22
+
5
23
  it('should be able to get a result by term', async () => {
6
- const provider = new CommercetoolsSearchProvider({
7
- apiUrl: process.env['COMMERCETOOLS_API_URL'] || '',
8
- authUrl: process.env['COMMERCETOOLS_AUTH_URL'] || '',
9
- clientId: process.env['COMMERCETOOLS_CLIENT_ID'] || '',
10
- clientSecret: process.env['COMMERCETOOLS_CLIENT_SECRET'] || '',
11
- projectKey: process.env['COMMERCETOOLS_PROJECT_KEY'] || '',
12
- }, SearchResultSchema);
24
+ const result = await provider.queryByTerm( {
25
+ search: {
26
+ term: testData.searchTerm,
27
+ facets: [],
28
+ page: 1,
29
+ pageSize: 10,
30
+ }}, session);
31
+
32
+ expect(result.products.length).toBeGreaterThan(0);
33
+ });
13
34
 
14
- const result = await provider.get({ term: 'glass', page: 0, pageSize: 20, facets: [] });
35
+
36
+ it('should be able to get a result by term, paged', async () => {
37
+ const result = await provider.queryByTerm( {
38
+ search: {
39
+ term: testData.searchTerm,
40
+ facets: [],
41
+ page: 1,
42
+ pageSize: 1,
43
+ }}, session);
15
44
 
16
45
  expect(result.products.length).toBeGreaterThan(0);
46
+ expect(result.pages).toBeGreaterThan(1);
47
+
48
+ const result2 = await provider.queryByTerm( {
49
+ search: {
50
+ term: testData.searchTerm,
51
+ facets: [],
52
+ page: 2,
53
+ pageSize: 1,
54
+ }}, session);
55
+
56
+ expect(result2.products.length).toBeGreaterThan(0);
57
+ expect(result2.pages).toBeGreaterThan(2);
58
+ expect(result2.products[0].identifier.key).not.toBe(result.products[0].identifier.key);
17
59
  });
18
60
  });
@@ -0,0 +1,35 @@
1
+ import { Session } from "@reactionary/core";
2
+
3
+ export function getCommercetoolsTestConfiguration() {
4
+ return {
5
+ apiUrl: process.env['COMMERCETOOLS_API_URL'] || '',
6
+ authUrl: process.env['COMMERCETOOLS_AUTH_URL'] || '',
7
+ clientId: process.env['COMMERCETOOLS_CLIENT_ID'] || '',
8
+ clientSecret: process.env['COMMERCETOOLS_CLIENT_SECRET'] || '',
9
+ projectKey: process.env['COMMERCETOOLS_PROJECT_KEY'] || ''
10
+ }
11
+ }
12
+ export function createAnonymousTestSession(): Session {
13
+ return {
14
+ id: 'test-session-id',
15
+ identity: {
16
+ type: 'Anonymous',
17
+ meta: {
18
+ cache: { hit: false, key: '' },
19
+ placeholder: false,
20
+ },
21
+ id: '',
22
+ token: undefined,
23
+ issued: new Date(),
24
+ expiry: new Date(new Date().getTime() + 3600 * 1000), // 1 hour from now
25
+ },
26
+ languageContext: {
27
+ locale: 'en-US',
28
+ currencyCode: 'USD',
29
+ countryCode: 'US',
30
+ },
31
+ storeIdentifier: {
32
+ key: 'the-good-store',
33
+ },
34
+ };
35
+ }
@@ -6,5 +6,5 @@
6
6
  "types": ["node"]
7
7
  },
8
8
  "include": ["src/**/*.ts"],
9
- "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]
9
+ "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts", "src/**/test-utils.ts"]
10
10
  }
@@ -0,0 +1,10 @@
1
+ export default {
2
+ displayName: 'provider-faker',
3
+ preset: '../../jest.preset.js',
4
+ testEnvironment: 'node',
5
+ transform: {
6
+ '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
7
+ },
8
+ moduleFileExtensions: ['ts', 'js', 'html'],
9
+ coverageDirectory: '../../coverage/providers/fake',
10
+ };
@@ -1,13 +1,17 @@
1
- import { ProductSchema, SearchResultSchema, Cache as ReactinaryCache, ProductProvider, SearchProvider, IdentityProvider } from "@reactionary/core";
1
+ import { ProductSchema, SearchResultSchema, Cache as ReactinaryCache, ProductProvider, SearchProvider, IdentityProvider, CategorySchema, CategoryProvider, CartSchema, CartProvider } from "@reactionary/core";
2
2
  import { FakeProductProvider } from "../providers/product.provider";
3
3
  import { FakeSearchProvider } from "../providers/search.provider";
4
4
  import { FakeConfiguration } from "../schema/configuration.schema";
5
5
  import { FakeCapabilities } from "../schema/capabilities.schema";
6
+ import { FakeCategoryProvider } from "../providers/category.provider";
7
+ import { FakeCartProvider } from "../providers";
6
8
 
7
9
  type FakeClient<T extends FakeCapabilities> = Partial<{
10
+ cart: T['cart'] extends true ? CartProvider : never;
8
11
  product: T['product'] extends true ? ProductProvider : never;
9
12
  search: T['search'] extends true ? SearchProvider : never;
10
13
  identity: T['identity'] extends true ? IdentityProvider : never;
14
+ category: T['category'] extends true ? CategoryProvider : never;
11
15
  }>;
12
16
 
13
17
  export function withFakeCapabilities<T extends FakeCapabilities>(configuration: FakeConfiguration, capabilities: T) {
@@ -22,6 +26,16 @@ export function withFakeCapabilities<T extends FakeCapabilities>(configuration:
22
26
  client.search = new FakeSearchProvider(configuration, SearchResultSchema, cache);
23
27
  }
24
28
 
29
+ if (capabilities.category) {
30
+ client.category = new FakeCategoryProvider(configuration, CategorySchema, cache);
31
+ }
32
+
33
+
34
+ if (capabilities.cart) {
35
+ client.cart = new FakeCartProvider(configuration, CartSchema, cache);
36
+ }
37
+
38
+
25
39
  return client;
26
40
  };
27
41
  }
@@ -1,12 +1,5 @@
1
1
  export * from './core/initialize';
2
2
 
3
- export * from './providers/analytics.provider';
4
- export * from './providers/cart.provider';
5
- export * from './providers/identity.provider';
6
- export * from './providers/inventory.provider';
7
- export * from './providers/price.provider';
8
- export * from './providers/product.provider';
9
- export * from './providers/search.provider';
10
-
3
+ export * from './providers/'
11
4
  export * from './schema/capabilities.schema';
12
- export * from './schema/configuration.schema';
5
+ export * from './schema/configuration.schema';