@reactionary/examples-node 0.1.5
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/README.md +11 -0
- package/eslint.config.mjs +19 -0
- package/package.json +13 -0
- package/project.json +23 -0
- package/src/basic/basic-node-provider-model-extension.spec.ts +104 -0
- package/src/basic/basic-node-provider-query-extension.spec.ts +99 -0
- package/src/basic/basic-node-setup.spec.ts +54 -0
- package/src/basic/client-creation.spec.ts +53 -0
- package/src/capabilities/cart.spec.ts +211 -0
- package/src/capabilities/category.spec.ts +158 -0
- package/src/capabilities/checkout.spec.ts +272 -0
- package/src/capabilities/identity.spec.ts +67 -0
- package/src/capabilities/inventory.spec.ts +66 -0
- package/src/capabilities/price.spec.ts +41 -0
- package/src/capabilities/product-search.spec.ts +149 -0
- package/src/capabilities/product.spec.ts +108 -0
- package/src/capabilities/profile.spec.ts +25 -0
- package/src/capabilities/store.spec.ts +22 -0
- package/src/index.ts +2 -0
- package/src/utils.ts +102 -0
- package/tsconfig.json +21 -0
- package/tsconfig.lib.json +9 -0
- package/tsconfig.spec.json +4 -0
- package/vitest.config.ts +14 -0
package/README.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# examples-node
|
|
2
|
+
|
|
3
|
+
This library was generated with [Nx](https://nx.dev).
|
|
4
|
+
|
|
5
|
+
## Building
|
|
6
|
+
|
|
7
|
+
Run `nx build examples-node` to build the library.
|
|
8
|
+
|
|
9
|
+
## Running unit tests
|
|
10
|
+
|
|
11
|
+
Run `nx test examples-node` to execute the unit tests via [Jest](https://jestjs.io).
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import baseConfig from '../../eslint.config.mjs';
|
|
2
|
+
|
|
3
|
+
export default [
|
|
4
|
+
...baseConfig,
|
|
5
|
+
{
|
|
6
|
+
files: ['**/*.json'],
|
|
7
|
+
rules: {
|
|
8
|
+
'@nx/dependency-checks': [
|
|
9
|
+
'error',
|
|
10
|
+
{
|
|
11
|
+
ignoredFiles: ['{projectRoot}/eslint.config.{js,cjs,mjs}'],
|
|
12
|
+
},
|
|
13
|
+
],
|
|
14
|
+
},
|
|
15
|
+
languageOptions: {
|
|
16
|
+
parser: await import('jsonc-eslint-parser'),
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
];
|
package/package.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@reactionary/examples-node",
|
|
3
|
+
"version": "0.1.5",
|
|
4
|
+
"main": "index.js",
|
|
5
|
+
"types": "src/index.d.ts",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"@reactionary/core": "0.1.5",
|
|
8
|
+
"@reactionary/provider-commercetools": "0.1.5",
|
|
9
|
+
"@reactionary/provider-algolia": "0.1.5",
|
|
10
|
+
"@reactionary/provider-medusa": "0.1.5"
|
|
11
|
+
},
|
|
12
|
+
"type": "module"
|
|
13
|
+
}
|
package/project.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "examples-node",
|
|
3
|
+
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
+
"sourceRoot": "examples/node/src",
|
|
5
|
+
"projectType": "library",
|
|
6
|
+
"tags": [],
|
|
7
|
+
"targets": {
|
|
8
|
+
|
|
9
|
+
"build": {
|
|
10
|
+
"executor": "@nx/esbuild:esbuild",
|
|
11
|
+
"outputs": ["{options.outputPath}"],
|
|
12
|
+
"options": {
|
|
13
|
+
"outputPath": "dist/examples/node",
|
|
14
|
+
"main": "examples/node/src/index.ts",
|
|
15
|
+
"tsConfig": "examples/node/tsconfig.lib.json",
|
|
16
|
+
"assets": ["examples/node/*.md"],
|
|
17
|
+
"format": ["esm"],
|
|
18
|
+
"bundle": false
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Cache,
|
|
3
|
+
ProductQueryById,
|
|
4
|
+
ProductQueryBySlug,
|
|
5
|
+
RequestContext} from '@reactionary/core';
|
|
6
|
+
import {
|
|
7
|
+
ClientBuilder,
|
|
8
|
+
NoOpCache,
|
|
9
|
+
ProductSchema
|
|
10
|
+
} from '@reactionary/core';
|
|
11
|
+
import {
|
|
12
|
+
FakeProductProvider,
|
|
13
|
+
withFakeCapabilities,
|
|
14
|
+
} from '@reactionary/provider-fake';
|
|
15
|
+
import { createInitialRequestContext } from '@reactionary/core'
|
|
16
|
+
import { z } from 'zod';
|
|
17
|
+
import { describe, expect, it } from 'vitest';
|
|
18
|
+
|
|
19
|
+
describe('basic node provider extension (models)', () => {
|
|
20
|
+
const reqCtx = createInitialRequestContext();
|
|
21
|
+
|
|
22
|
+
const ExtendedProductModel = ProductSchema.extend({
|
|
23
|
+
gtin: z.string().default('gtin-default'),
|
|
24
|
+
});
|
|
25
|
+
type ExtendedProduct = z.infer<typeof ExtendedProductModel>;
|
|
26
|
+
|
|
27
|
+
class ExtendedProductProvider extends FakeProductProvider {
|
|
28
|
+
protected override parseSingle(body: string): ExtendedProduct {
|
|
29
|
+
const result = {
|
|
30
|
+
...super.parseSingle(body),
|
|
31
|
+
gtin: 'gtin-1234'
|
|
32
|
+
} satisfies ExtendedProduct;
|
|
33
|
+
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function withExtendedCapabilities() {
|
|
39
|
+
return (cache: Cache, context: RequestContext) => {
|
|
40
|
+
const client = {
|
|
41
|
+
product: new ExtendedProductProvider(
|
|
42
|
+
{ jitter: { mean: 0, deviation: 0 },
|
|
43
|
+
seeds: {
|
|
44
|
+
category: 1,
|
|
45
|
+
product: 1,
|
|
46
|
+
search: 1
|
|
47
|
+
} },
|
|
48
|
+
cache,
|
|
49
|
+
context
|
|
50
|
+
),
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
return client;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const client = new ClientBuilder(reqCtx)
|
|
58
|
+
.withCapability(
|
|
59
|
+
withFakeCapabilities(
|
|
60
|
+
{
|
|
61
|
+
jitter: {
|
|
62
|
+
mean: 0,
|
|
63
|
+
deviation: 0,
|
|
64
|
+
},
|
|
65
|
+
seeds: {
|
|
66
|
+
category: 1,
|
|
67
|
+
product: 1,
|
|
68
|
+
search: 1
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
{ productSearch: true, product: false, identity: false }
|
|
72
|
+
)
|
|
73
|
+
)
|
|
74
|
+
.withCapability(withExtendedCapabilities())
|
|
75
|
+
.withCache(new NoOpCache())
|
|
76
|
+
.build();
|
|
77
|
+
|
|
78
|
+
it('should get the enabled set of capabilities across providers', async () => {
|
|
79
|
+
expect(client.product).toBeDefined();
|
|
80
|
+
expect(client.productSearch).toBeDefined();
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('should be able to call the regular methods and get the default value', async () => {
|
|
84
|
+
const product = await client.product.getBySlug(
|
|
85
|
+
{
|
|
86
|
+
slug: '1234',
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
expect(product).toBeDefined();
|
|
91
|
+
// FIXME: expect(product.gtin).toBe('gtin-1234');
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should be able to get serialized value from the extended provider', async () => {
|
|
95
|
+
const product = await client.product.getById(
|
|
96
|
+
{
|
|
97
|
+
identifier: { key: '1234' },
|
|
98
|
+
}
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
expect(product).toBeDefined();
|
|
102
|
+
// FIXME: expect(product.gtin).toBe('gtin-1234');
|
|
103
|
+
});
|
|
104
|
+
});
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Cache,
|
|
3
|
+
Product,
|
|
4
|
+
RequestContext} from '@reactionary/core';
|
|
5
|
+
import {
|
|
6
|
+
ClientBuilder,
|
|
7
|
+
createInitialRequestContext,
|
|
8
|
+
NoOpCache,
|
|
9
|
+
ProductSchema
|
|
10
|
+
} from '@reactionary/core';
|
|
11
|
+
import {
|
|
12
|
+
FakeProductProvider,
|
|
13
|
+
withFakeCapabilities,
|
|
14
|
+
} from '@reactionary/provider-fake';
|
|
15
|
+
import { z } from 'zod';
|
|
16
|
+
import { describe, expect, it } from 'vitest';
|
|
17
|
+
|
|
18
|
+
describe('basic node provider extension (models)', () => {
|
|
19
|
+
const ExtendedProductModel = ProductSchema.extend({
|
|
20
|
+
gtin: z.string().default('gtin-default'),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
class ExtendedProductProvider extends FakeProductProvider {
|
|
24
|
+
|
|
25
|
+
public async getByCustom(_custom: string): Promise<Product> {
|
|
26
|
+
// Lets say we called somewhere...
|
|
27
|
+
const data = {
|
|
28
|
+
id: 'foo',
|
|
29
|
+
name: 'bar'
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const model = this.parseItem(data);
|
|
33
|
+
|
|
34
|
+
return model;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
protected parseItem(data: unknown): Product {
|
|
38
|
+
// In the real world, call super
|
|
39
|
+
// super.parseItem(data);
|
|
40
|
+
// Which would start by doing
|
|
41
|
+
const item = { } as any;
|
|
42
|
+
|
|
43
|
+
if (data) {
|
|
44
|
+
item.name = (data as { name: string }).name;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
return item;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function withExtendedCapabilities() {
|
|
53
|
+
return (cache: Cache, context: RequestContext) => {
|
|
54
|
+
const client = {
|
|
55
|
+
product: new ExtendedProductProvider(
|
|
56
|
+
{ jitter: { mean: 0, deviation: 0 },
|
|
57
|
+
seeds: {
|
|
58
|
+
category: 1,
|
|
59
|
+
product: 1,
|
|
60
|
+
search: 1
|
|
61
|
+
}},
|
|
62
|
+
cache,
|
|
63
|
+
context
|
|
64
|
+
),
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
return client;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const reqCtx = createInitialRequestContext();
|
|
72
|
+
const client = new ClientBuilder(reqCtx)
|
|
73
|
+
.withCapability(
|
|
74
|
+
withFakeCapabilities(
|
|
75
|
+
{
|
|
76
|
+
jitter: {
|
|
77
|
+
mean: 0,
|
|
78
|
+
deviation: 0,
|
|
79
|
+
},
|
|
80
|
+
seeds: {
|
|
81
|
+
category: 1,
|
|
82
|
+
product: 1,
|
|
83
|
+
search: 1
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
{ productSearch: true, product: false, identity: false }
|
|
87
|
+
)
|
|
88
|
+
)
|
|
89
|
+
.withCapability(withExtendedCapabilities())
|
|
90
|
+
.withCache(new NoOpCache())
|
|
91
|
+
.build();
|
|
92
|
+
|
|
93
|
+
it('should be able to call a custom query method on the provider', async () => {
|
|
94
|
+
const product = await client.product.getByCustom('1234');
|
|
95
|
+
|
|
96
|
+
expect(product.name).toBe('bar');
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import {
|
|
3
|
+
ClientBuilder,
|
|
4
|
+
createInitialRequestContext,
|
|
5
|
+
NoOpCache,
|
|
6
|
+
type Client,
|
|
7
|
+
type RequestContext,
|
|
8
|
+
} from '@reactionary/core';
|
|
9
|
+
import { withFakeCapabilities } from '@reactionary/provider-fake';
|
|
10
|
+
import { beforeAll, beforeEach, describe, expect, it } from 'vitest';
|
|
11
|
+
|
|
12
|
+
describe('basic node setup', () => {
|
|
13
|
+
let client: Partial<Client>;
|
|
14
|
+
let reqCtx: RequestContext;
|
|
15
|
+
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
reqCtx = createInitialRequestContext();
|
|
18
|
+
client = new ClientBuilder(reqCtx)
|
|
19
|
+
.withCapability(
|
|
20
|
+
withFakeCapabilities(
|
|
21
|
+
{
|
|
22
|
+
jitter: {
|
|
23
|
+
mean: 0,
|
|
24
|
+
deviation: 0,
|
|
25
|
+
},
|
|
26
|
+
seeds: {
|
|
27
|
+
category: 1,
|
|
28
|
+
product: 1,
|
|
29
|
+
search: 1,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
{ productSearch: true, product: true, identity: false }
|
|
33
|
+
)
|
|
34
|
+
)
|
|
35
|
+
.withCache(new NoOpCache())
|
|
36
|
+
.build();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should only get back the enabled capabilities', async () => {
|
|
40
|
+
expect(client.product).toBeDefined();
|
|
41
|
+
expect(client.productSearch).toBeDefined();
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should be able to call the enabled capabilities', async () => {
|
|
45
|
+
const product = await client.product!.getBySlug(
|
|
46
|
+
{
|
|
47
|
+
slug: '1234',
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
expect(product).toBeDefined();
|
|
52
|
+
expect(product!.slug).toBe('1234');
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { ClientBuilder, createInitialRequestContext, NoOpCache } from '@reactionary/core';
|
|
3
|
+
import { FakeProductProvider, withFakeCapabilities } from '@reactionary/provider-fake';
|
|
4
|
+
import { CommercetoolsCartProvider, withCommercetoolsCapabilities } from '@reactionary/provider-commercetools';
|
|
5
|
+
import { AlgoliaSearchProvider, withAlgoliaCapabilities } from '@reactionary/provider-algolia';
|
|
6
|
+
|
|
7
|
+
describe('client creation', () => {
|
|
8
|
+
it('should be able to mix providers and get a valid, typed client', async () => {
|
|
9
|
+
const reqCtx = createInitialRequestContext();
|
|
10
|
+
const client = new ClientBuilder(reqCtx)
|
|
11
|
+
.withCapability(
|
|
12
|
+
withFakeCapabilities(
|
|
13
|
+
{
|
|
14
|
+
jitter: {
|
|
15
|
+
mean: 0,
|
|
16
|
+
deviation: 0,
|
|
17
|
+
},
|
|
18
|
+
seeds: {
|
|
19
|
+
category: 1,
|
|
20
|
+
product: 1,
|
|
21
|
+
search: 1,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
{ product: true }
|
|
25
|
+
)
|
|
26
|
+
)
|
|
27
|
+
.withCapability(
|
|
28
|
+
withCommercetoolsCapabilities({
|
|
29
|
+
apiUrl: '',
|
|
30
|
+
authUrl: '',
|
|
31
|
+
clientId: '',
|
|
32
|
+
clientSecret: '',
|
|
33
|
+
paymentMethods: [],
|
|
34
|
+
projectKey: '',
|
|
35
|
+
scopes: [],
|
|
36
|
+
facetFieldsForSearch: []
|
|
37
|
+
}, { cart: true })
|
|
38
|
+
)
|
|
39
|
+
.withCapability(
|
|
40
|
+
withAlgoliaCapabilities({
|
|
41
|
+
apiKey: '',
|
|
42
|
+
appId: '',
|
|
43
|
+
indexName: ''
|
|
44
|
+
}, { productSearch: true })
|
|
45
|
+
)
|
|
46
|
+
.withCache(new NoOpCache())
|
|
47
|
+
.build();
|
|
48
|
+
|
|
49
|
+
expect(client.cart).toBeInstanceOf(CommercetoolsCartProvider);
|
|
50
|
+
expect(client.product).toBeInstanceOf(FakeProductProvider);
|
|
51
|
+
expect(client.productSearch).toBeInstanceOf(AlgoliaSearchProvider);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import { createClient, PrimaryProvider } from '../utils.js';
|
|
3
|
+
import { describe, expect, it, beforeEach } from 'vitest';
|
|
4
|
+
import { ProductSearchQueryByTermSchema, type ProductSearchQueryByTerm } from '@reactionary/core';
|
|
5
|
+
|
|
6
|
+
const testData = {
|
|
7
|
+
skuWithoutTiers: '0766623301831',
|
|
8
|
+
skuWithTiers: '0766623360203',
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
describe.each([PrimaryProvider.COMMERCETOOLS])('Cart Capability - %s', (provider) => {
|
|
12
|
+
let client: ReturnType<typeof createClient>;
|
|
13
|
+
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
client = createClient(provider);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
describe('anonymous sessions', () => {
|
|
19
|
+
it('should be able to get an empty cart', async () => {
|
|
20
|
+
const cart = await client.cart.getById({
|
|
21
|
+
cart: { key: '' },
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
expect(cart.identifier.key).toBeFalsy();
|
|
25
|
+
expect(cart.items.length).toBe(0);
|
|
26
|
+
expect(cart.meta?.placeholder).toBe(true);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('should be able to add an item to a cart', async () => {
|
|
30
|
+
const cart = await client.cart.add({
|
|
31
|
+
cart: { key: '' },
|
|
32
|
+
variant: {
|
|
33
|
+
sku: testData.skuWithoutTiers,
|
|
34
|
+
},
|
|
35
|
+
quantity: 1,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
expect(cart.identifier.key).toBeDefined();
|
|
39
|
+
expect(cart.items.length).toBe(1);
|
|
40
|
+
expect(cart.items[0].variant.sku).toBe(testData.skuWithoutTiers);
|
|
41
|
+
expect(cart.items[0].quantity).toBe(1);
|
|
42
|
+
|
|
43
|
+
expect(cart.items[0].price.totalPrice.value).toBeGreaterThan(0);
|
|
44
|
+
|
|
45
|
+
expect(cart.price.grandTotal.value).toBeGreaterThan(0);
|
|
46
|
+
|
|
47
|
+
expect(cart.price.grandTotal.value).toBe(
|
|
48
|
+
cart.items[0].price.totalPrice.value
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
expect(cart.meta?.placeholder).toBeFalsy();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('can add multiple different items to a cart', async () => {
|
|
55
|
+
const cart = await client.cart.add({
|
|
56
|
+
cart: { key: '' },
|
|
57
|
+
variant: {
|
|
58
|
+
sku: testData.skuWithoutTiers,
|
|
59
|
+
},
|
|
60
|
+
quantity: 1,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const updatedCart = await client.cart.add({
|
|
64
|
+
cart: cart.identifier,
|
|
65
|
+
variant: {
|
|
66
|
+
sku: testData.skuWithTiers,
|
|
67
|
+
},
|
|
68
|
+
quantity: 2,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
expect(updatedCart.items.length).toBe(2);
|
|
72
|
+
expect(updatedCart.items[0].variant.sku).toBe(testData.skuWithoutTiers);
|
|
73
|
+
expect(updatedCart.items[0].quantity).toBe(1);
|
|
74
|
+
expect(updatedCart.items[1].variant.sku).toBe(testData.skuWithTiers);
|
|
75
|
+
expect(updatedCart.items[1].quantity).toBe(2);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('should be able to change quantity of an item in a cart', async () => {
|
|
79
|
+
const cart = await client.cart.add({
|
|
80
|
+
cart: { key: '' },
|
|
81
|
+
variant: {
|
|
82
|
+
sku: testData.skuWithoutTiers,
|
|
83
|
+
},
|
|
84
|
+
quantity: 1,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const updatedCart = await client.cart.changeQuantity({
|
|
88
|
+
cart: cart.identifier,
|
|
89
|
+
item: cart.items[0].identifier,
|
|
90
|
+
quantity: 3,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
expect(updatedCart.items.length).toBe(1);
|
|
94
|
+
expect(updatedCart.items[0].variant.sku).toBe(testData.skuWithoutTiers);
|
|
95
|
+
expect(updatedCart.items[0].quantity).toBe(3);
|
|
96
|
+
|
|
97
|
+
expect(updatedCart.items[0].price.totalPrice.value).toBeGreaterThan(
|
|
98
|
+
cart.items[0].price.totalPrice.value
|
|
99
|
+
);
|
|
100
|
+
expect(updatedCart.items[0].price.unitPrice.value).toBe(
|
|
101
|
+
cart.items[0].price.unitPrice.value
|
|
102
|
+
);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('should be able to remove an item from a cart', async () => {
|
|
106
|
+
const cart = await client.cart.add({
|
|
107
|
+
cart: { key: '' },
|
|
108
|
+
variant: {
|
|
109
|
+
sku: testData.skuWithoutTiers,
|
|
110
|
+
},
|
|
111
|
+
quantity: 1,
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const updatedCart = await client.cart.remove({
|
|
115
|
+
cart: cart.identifier,
|
|
116
|
+
item: cart.items[0].identifier,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
expect(updatedCart.items.length).toBe(0);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('should be able to delete a cart', async () => {
|
|
123
|
+
const cart = await client.cart.add({
|
|
124
|
+
cart: { key: '' },
|
|
125
|
+
variant: {
|
|
126
|
+
sku: testData.skuWithoutTiers,
|
|
127
|
+
},
|
|
128
|
+
quantity: 1,
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
expect(cart.items.length).toBe(1);
|
|
132
|
+
expect(cart.identifier.key).toBeTruthy();
|
|
133
|
+
|
|
134
|
+
const deletedCart = await client.cart.deleteCart({
|
|
135
|
+
cart: cart.identifier,
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
expect(deletedCart.items.length).toBe(0);
|
|
139
|
+
expect(deletedCart.identifier.key).toBe('');
|
|
140
|
+
|
|
141
|
+
const originalCart = await client.cart.getById({
|
|
142
|
+
cart: cart.identifier,
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
expect(originalCart.items.length).toBe(0);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('can load the product information for cart items', async () => {
|
|
149
|
+
const cart = await client.cart.add({
|
|
150
|
+
cart: { key: '' },
|
|
151
|
+
variant: {
|
|
152
|
+
sku: testData.skuWithoutTiers,
|
|
153
|
+
},
|
|
154
|
+
quantity: 1,
|
|
155
|
+
});
|
|
156
|
+
expect(cart.items[0].variant).toBeDefined();
|
|
157
|
+
|
|
158
|
+
const product = await client.product.getBySKU({
|
|
159
|
+
variant: cart.items[0].variant,
|
|
160
|
+
});
|
|
161
|
+
expect(product).toBeTruthy();
|
|
162
|
+
if (product) {
|
|
163
|
+
expect(product.mainVariant.identifier.sku).toEqual(
|
|
164
|
+
cart.items[0].variant.sku
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('should be able to add an 50 items to a cart in less than 30 seconds', async () => {
|
|
170
|
+
let cart = await client.cart.getById({
|
|
171
|
+
cart: { key: '' },
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
const searchResult = await client.productSearch.queryByTerm(
|
|
175
|
+
ProductSearchQueryByTermSchema.parse({
|
|
176
|
+
search: {
|
|
177
|
+
term: 'cable',
|
|
178
|
+
paginationOptions: {
|
|
179
|
+
pageNumber: 1,
|
|
180
|
+
pageSize: 8,
|
|
181
|
+
},
|
|
182
|
+
filters: [],
|
|
183
|
+
facets: [],
|
|
184
|
+
},
|
|
185
|
+
} satisfies ProductSearchQueryByTerm)
|
|
186
|
+
);
|
|
187
|
+
expect(searchResult.items.length).toBeGreaterThanOrEqual(8);
|
|
188
|
+
|
|
189
|
+
for (const product of searchResult.items) {
|
|
190
|
+
cart = await client.cart.add({
|
|
191
|
+
cart: cart.identifier,
|
|
192
|
+
variant: {
|
|
193
|
+
sku: product.variants[0].variant.sku,
|
|
194
|
+
},
|
|
195
|
+
quantity: 1,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (cart) {
|
|
200
|
+
expect(cart.identifier.key).toBeDefined();
|
|
201
|
+
expect(cart.items.length).toBe(8);
|
|
202
|
+
|
|
203
|
+
expect(cart.items[0].price.totalPrice.value).toBeGreaterThan(0);
|
|
204
|
+
expect(cart.price.grandTotal.value).toBeGreaterThan(0);
|
|
205
|
+
expect(cart.meta?.placeholder).toBeFalsy();
|
|
206
|
+
} else {
|
|
207
|
+
throw new Error('Cart is undefined');
|
|
208
|
+
}
|
|
209
|
+
}, 30000);
|
|
210
|
+
});
|
|
211
|
+
});
|