@htlkg/data 0.0.21 → 0.0.23
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/dist/hooks/index.d.ts +702 -94
- package/dist/hooks/index.js +793 -56
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +802 -65
- package/dist/index.js.map +1 -1
- package/dist/mutations/index.js +4 -4
- package/dist/mutations/index.js.map +1 -1
- package/dist/queries/index.js +5 -5
- package/dist/queries/index.js.map +1 -1
- package/package.json +11 -12
- package/src/hooks/accounts/index.ts +2 -0
- package/src/hooks/{useAccounts.ts → accounts/useAccounts.ts} +48 -5
- package/src/hooks/accounts/usePaginatedAccounts.ts +166 -0
- package/src/hooks/brands/index.ts +2 -0
- package/src/hooks/{useBrands.ts → brands/useBrands.ts} +1 -1
- package/src/hooks/brands/usePaginatedBrands.ts +206 -0
- package/src/hooks/contacts/index.ts +2 -0
- package/src/hooks/contacts/useContacts.ts +176 -0
- package/src/hooks/contacts/usePaginatedContacts.ts +268 -0
- package/src/hooks/createPaginatedDataHook.ts +359 -0
- package/src/hooks/data-hook-errors.property.test.ts +4 -4
- package/src/hooks/data-hook-filters.property.test.ts +4 -4
- package/src/hooks/data-hooks.property.test.ts +4 -4
- package/src/hooks/index.ts +101 -8
- package/src/hooks/productInstances/index.ts +1 -0
- package/src/hooks/{useProductInstances.ts → productInstances/useProductInstances.ts} +9 -6
- package/src/hooks/products/index.ts +1 -0
- package/src/hooks/{useProducts.ts → products/useProducts.ts} +4 -5
- package/src/hooks/reservations/index.ts +2 -0
- package/src/hooks/reservations/usePaginatedReservations.ts +258 -0
- package/src/hooks/{useReservations.ts → reservations/useReservations.ts} +65 -10
- package/src/hooks/users/index.ts +2 -0
- package/src/hooks/users/usePaginatedUsers.ts +213 -0
- package/src/hooks/{useUsers.ts → users/useUsers.ts} +1 -1
- package/src/mutations/accounts/accounts.test.ts +287 -0
- package/src/mutations/{accounts.ts → accounts/accounts.ts} +2 -2
- package/src/mutations/accounts/index.ts +1 -0
- package/src/mutations/brands/brands.test.ts +292 -0
- package/src/mutations/{brands.ts → brands/brands.ts} +2 -2
- package/src/mutations/brands/index.ts +1 -0
- package/src/mutations/reservations/index.ts +1 -0
- package/src/mutations/{reservations.test.ts → reservations/reservations.test.ts} +1 -1
- package/src/mutations/{reservations.ts → reservations/reservations.ts} +2 -2
- package/src/mutations/users/index.ts +1 -0
- package/src/mutations/users/users.test.ts +289 -0
- package/src/mutations/{users.ts → users/users.ts} +2 -2
- package/src/queries/accounts/accounts.test.ts +228 -0
- package/src/queries/accounts/index.ts +1 -0
- package/src/queries/brands/brands.test.ts +288 -0
- package/src/queries/brands/index.ts +1 -0
- package/src/queries/products/index.ts +1 -0
- package/src/queries/products/products.test.ts +347 -0
- package/src/queries/reservations/index.ts +1 -0
- package/src/queries/users/index.ts +1 -0
- package/src/queries/users/users.test.ts +301 -0
- /package/src/queries/{accounts.ts → accounts/accounts.ts} +0 -0
- /package/src/queries/{brands.ts → brands/brands.ts} +0 -0
- /package/src/queries/{products.ts → products/products.ts} +0 -0
- /package/src/queries/{reservations.test.ts → reservations/reservations.test.ts} +0 -0
- /package/src/queries/{reservations.ts → reservations/reservations.ts} +0 -0
- /package/src/queries/{users.ts → users/users.ts} +0 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Brand Query Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests for brand query functions including filtering and pagination.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { describe, it, expect, vi } from "vitest";
|
|
8
|
+
import {
|
|
9
|
+
getBrand,
|
|
10
|
+
listBrands,
|
|
11
|
+
getBrandWithProducts,
|
|
12
|
+
listBrandsByAccount,
|
|
13
|
+
listActiveBrands,
|
|
14
|
+
} from "./brands";
|
|
15
|
+
|
|
16
|
+
describe("Brand Queries", () => {
|
|
17
|
+
const mockBrand = {
|
|
18
|
+
id: "brand-001",
|
|
19
|
+
name: "Test Brand",
|
|
20
|
+
accountId: "account-123",
|
|
21
|
+
logo: "logo.png",
|
|
22
|
+
timezone: "America/New_York",
|
|
23
|
+
status: "active",
|
|
24
|
+
settings: {},
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
describe("getBrand", () => {
|
|
28
|
+
it("should return a brand by ID", async () => {
|
|
29
|
+
const mockGet = vi.fn().mockResolvedValue({
|
|
30
|
+
data: mockBrand,
|
|
31
|
+
errors: null,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const mockClient = {
|
|
35
|
+
models: {
|
|
36
|
+
Brand: { get: mockGet },
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const result = await getBrand(mockClient, "brand-001");
|
|
41
|
+
|
|
42
|
+
expect(result).toEqual(mockBrand);
|
|
43
|
+
expect(mockGet).toHaveBeenCalledWith({ id: "brand-001" });
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("should return null when brand not found", async () => {
|
|
47
|
+
const mockGet = vi.fn().mockResolvedValue({
|
|
48
|
+
data: null,
|
|
49
|
+
errors: [{ message: "Not found" }],
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const mockClient = {
|
|
53
|
+
models: {
|
|
54
|
+
Brand: { get: mockGet },
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const result = await getBrand(mockClient, "nonexistent");
|
|
59
|
+
|
|
60
|
+
expect(result).toBeNull();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("should throw on unexpected error", async () => {
|
|
64
|
+
const mockGet = vi.fn().mockRejectedValue(new Error("Network error"));
|
|
65
|
+
|
|
66
|
+
const mockClient = {
|
|
67
|
+
models: {
|
|
68
|
+
Brand: { get: mockGet },
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
await expect(getBrand(mockClient, "brand-001")).rejects.toThrow("Network error");
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
describe("listBrands", () => {
|
|
77
|
+
const mockBrands = [
|
|
78
|
+
mockBrand,
|
|
79
|
+
{ ...mockBrand, id: "brand-002", name: "Second Brand" },
|
|
80
|
+
];
|
|
81
|
+
|
|
82
|
+
it("should return a list of brands", async () => {
|
|
83
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
84
|
+
data: mockBrands,
|
|
85
|
+
errors: null,
|
|
86
|
+
nextToken: null,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const mockClient = {
|
|
90
|
+
models: {
|
|
91
|
+
Brand: { list: mockList },
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const result = await listBrands(mockClient);
|
|
96
|
+
|
|
97
|
+
expect(result.items).toHaveLength(2);
|
|
98
|
+
expect(result.items[0].id).toBe("brand-001");
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("should pass filter options to the query", async () => {
|
|
102
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
103
|
+
data: [mockBrand],
|
|
104
|
+
errors: null,
|
|
105
|
+
nextToken: null,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const mockClient = {
|
|
109
|
+
models: {
|
|
110
|
+
Brand: { list: mockList },
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const filter = { status: { eq: "active" } };
|
|
115
|
+
await listBrands(mockClient, { filter, limit: 50 });
|
|
116
|
+
|
|
117
|
+
expect(mockList).toHaveBeenCalledWith({
|
|
118
|
+
filter,
|
|
119
|
+
limit: 50,
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it("should return nextToken for pagination", async () => {
|
|
124
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
125
|
+
data: [mockBrand],
|
|
126
|
+
errors: null,
|
|
127
|
+
nextToken: "token-123",
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const mockClient = {
|
|
131
|
+
models: {
|
|
132
|
+
Brand: { list: mockList },
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const result = await listBrands(mockClient, { limit: 1 });
|
|
137
|
+
|
|
138
|
+
expect(result.nextToken).toBe("token-123");
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("should return empty array on GraphQL error", async () => {
|
|
142
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
143
|
+
data: null,
|
|
144
|
+
errors: [{ message: "Query failed" }],
|
|
145
|
+
nextToken: undefined,
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const mockClient = {
|
|
149
|
+
models: {
|
|
150
|
+
Brand: { list: mockList },
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const result = await listBrands(mockClient);
|
|
155
|
+
|
|
156
|
+
expect(result.items).toHaveLength(0);
|
|
157
|
+
expect(result.nextToken).toBeUndefined();
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
describe("getBrandWithProducts", () => {
|
|
162
|
+
it("should return brand with product instances", async () => {
|
|
163
|
+
const brandWithProducts = {
|
|
164
|
+
...mockBrand,
|
|
165
|
+
productInstances: [
|
|
166
|
+
{ id: "pi-001", productId: "prod-001", enabled: true },
|
|
167
|
+
],
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const mockGet = vi.fn().mockResolvedValue({
|
|
171
|
+
data: brandWithProducts,
|
|
172
|
+
errors: null,
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
const mockClient = {
|
|
176
|
+
models: {
|
|
177
|
+
Brand: { get: mockGet },
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
const result = await getBrandWithProducts(mockClient, "brand-001");
|
|
182
|
+
|
|
183
|
+
expect(result).toEqual(brandWithProducts);
|
|
184
|
+
expect(mockGet).toHaveBeenCalledWith(
|
|
185
|
+
{ id: "brand-001" },
|
|
186
|
+
{
|
|
187
|
+
selectionSet: [
|
|
188
|
+
"id",
|
|
189
|
+
"name",
|
|
190
|
+
"accountId",
|
|
191
|
+
"logo",
|
|
192
|
+
"timezone",
|
|
193
|
+
"status",
|
|
194
|
+
"settings",
|
|
195
|
+
"productInstances.*",
|
|
196
|
+
],
|
|
197
|
+
}
|
|
198
|
+
);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it("should return null on error", async () => {
|
|
202
|
+
const mockGet = vi.fn().mockResolvedValue({
|
|
203
|
+
data: null,
|
|
204
|
+
errors: [{ message: "Not found" }],
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
const mockClient = {
|
|
208
|
+
models: {
|
|
209
|
+
Brand: { get: mockGet },
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
const result = await getBrandWithProducts(mockClient, "nonexistent");
|
|
214
|
+
|
|
215
|
+
expect(result).toBeNull();
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
describe("listBrandsByAccount", () => {
|
|
220
|
+
it("should filter brands by account ID", async () => {
|
|
221
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
222
|
+
data: [mockBrand],
|
|
223
|
+
errors: null,
|
|
224
|
+
nextToken: null,
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
const mockClient = {
|
|
228
|
+
models: {
|
|
229
|
+
Brand: { list: mockList },
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
await listBrandsByAccount(mockClient, "account-123");
|
|
234
|
+
|
|
235
|
+
expect(mockList).toHaveBeenCalledWith({
|
|
236
|
+
filter: { accountId: { eq: "account-123" } },
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
it("should support pagination options", async () => {
|
|
241
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
242
|
+
data: [mockBrand],
|
|
243
|
+
errors: null,
|
|
244
|
+
nextToken: "next-page",
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
const mockClient = {
|
|
248
|
+
models: {
|
|
249
|
+
Brand: { list: mockList },
|
|
250
|
+
},
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
const result = await listBrandsByAccount(mockClient, "account-123", {
|
|
254
|
+
limit: 10,
|
|
255
|
+
nextToken: "current-token",
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
expect(mockList).toHaveBeenCalledWith({
|
|
259
|
+
filter: { accountId: { eq: "account-123" } },
|
|
260
|
+
limit: 10,
|
|
261
|
+
nextToken: "current-token",
|
|
262
|
+
});
|
|
263
|
+
expect(result.nextToken).toBe("next-page");
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
describe("listActiveBrands", () => {
|
|
268
|
+
it("should filter brands by active status", async () => {
|
|
269
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
270
|
+
data: [mockBrand],
|
|
271
|
+
errors: null,
|
|
272
|
+
nextToken: null,
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
const mockClient = {
|
|
276
|
+
models: {
|
|
277
|
+
Brand: { list: mockList },
|
|
278
|
+
},
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
await listActiveBrands(mockClient);
|
|
282
|
+
|
|
283
|
+
expect(mockList).toHaveBeenCalledWith({
|
|
284
|
+
filter: { status: { eq: "active" } },
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./brands";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./products";
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Product Query Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests for product and product instance query functions.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { describe, it, expect, vi } from "vitest";
|
|
8
|
+
import {
|
|
9
|
+
getProduct,
|
|
10
|
+
listProducts,
|
|
11
|
+
listActiveProducts,
|
|
12
|
+
getProductInstance,
|
|
13
|
+
listProductInstancesByBrand,
|
|
14
|
+
listProductInstancesByAccount,
|
|
15
|
+
listEnabledProductInstancesByBrand,
|
|
16
|
+
} from "./products";
|
|
17
|
+
|
|
18
|
+
describe("Product Queries", () => {
|
|
19
|
+
const mockProduct = {
|
|
20
|
+
id: "product-001",
|
|
21
|
+
name: "WiFi Portal",
|
|
22
|
+
version: "1.0.0",
|
|
23
|
+
isActive: true,
|
|
24
|
+
schema: {},
|
|
25
|
+
uiSchema: {},
|
|
26
|
+
defaultConfig: {},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const mockProductInstance = {
|
|
30
|
+
id: "instance-001",
|
|
31
|
+
productId: "product-001",
|
|
32
|
+
brandId: "brand-001",
|
|
33
|
+
accountId: "account-001",
|
|
34
|
+
enabled: true,
|
|
35
|
+
config: {},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
describe("getProduct", () => {
|
|
39
|
+
it("should return a product by ID", async () => {
|
|
40
|
+
const mockGet = vi.fn().mockResolvedValue({
|
|
41
|
+
data: mockProduct,
|
|
42
|
+
errors: null,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const mockClient = {
|
|
46
|
+
models: {
|
|
47
|
+
Product: { get: mockGet },
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const result = await getProduct(mockClient, "product-001");
|
|
52
|
+
|
|
53
|
+
expect(result).toEqual(mockProduct);
|
|
54
|
+
expect(mockGet).toHaveBeenCalledWith({ id: "product-001" });
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("should return null when product not found", async () => {
|
|
58
|
+
const mockGet = vi.fn().mockResolvedValue({
|
|
59
|
+
data: null,
|
|
60
|
+
errors: [{ message: "Not found" }],
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const mockClient = {
|
|
64
|
+
models: {
|
|
65
|
+
Product: { get: mockGet },
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const result = await getProduct(mockClient, "nonexistent");
|
|
70
|
+
|
|
71
|
+
expect(result).toBeNull();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("should throw on unexpected error", async () => {
|
|
75
|
+
const mockGet = vi.fn().mockRejectedValue(new Error("Network error"));
|
|
76
|
+
|
|
77
|
+
const mockClient = {
|
|
78
|
+
models: {
|
|
79
|
+
Product: { get: mockGet },
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
await expect(getProduct(mockClient, "product-001")).rejects.toThrow("Network error");
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
describe("listProducts", () => {
|
|
88
|
+
const mockProducts = [
|
|
89
|
+
mockProduct,
|
|
90
|
+
{ ...mockProduct, id: "product-002", name: "WhatsApp CRM" },
|
|
91
|
+
];
|
|
92
|
+
|
|
93
|
+
it("should return a list of products", async () => {
|
|
94
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
95
|
+
data: mockProducts,
|
|
96
|
+
errors: null,
|
|
97
|
+
nextToken: null,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
const mockClient = {
|
|
101
|
+
models: {
|
|
102
|
+
Product: { list: mockList },
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const result = await listProducts(mockClient);
|
|
107
|
+
|
|
108
|
+
expect(result.items).toHaveLength(2);
|
|
109
|
+
expect(result.items[0].id).toBe("product-001");
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("should pass filter options to the query", async () => {
|
|
113
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
114
|
+
data: [mockProduct],
|
|
115
|
+
errors: null,
|
|
116
|
+
nextToken: null,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const mockClient = {
|
|
120
|
+
models: {
|
|
121
|
+
Product: { list: mockList },
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const filter = { isActive: { eq: true } };
|
|
126
|
+
await listProducts(mockClient, { filter, limit: 50 });
|
|
127
|
+
|
|
128
|
+
expect(mockList).toHaveBeenCalledWith({
|
|
129
|
+
filter,
|
|
130
|
+
limit: 50,
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it("should return empty array on GraphQL error", async () => {
|
|
135
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
136
|
+
data: null,
|
|
137
|
+
errors: [{ message: "Query failed" }],
|
|
138
|
+
nextToken: undefined,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
const mockClient = {
|
|
142
|
+
models: {
|
|
143
|
+
Product: { list: mockList },
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const result = await listProducts(mockClient);
|
|
148
|
+
|
|
149
|
+
expect(result.items).toHaveLength(0);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
describe("listActiveProducts", () => {
|
|
154
|
+
it("should filter products by active status", async () => {
|
|
155
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
156
|
+
data: [mockProduct],
|
|
157
|
+
errors: null,
|
|
158
|
+
nextToken: null,
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
const mockClient = {
|
|
162
|
+
models: {
|
|
163
|
+
Product: { list: mockList },
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
await listActiveProducts(mockClient);
|
|
168
|
+
|
|
169
|
+
expect(mockList).toHaveBeenCalledWith({
|
|
170
|
+
filter: { isActive: { eq: true } },
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
describe("getProductInstance", () => {
|
|
176
|
+
it("should return a product instance by ID", async () => {
|
|
177
|
+
const mockGet = vi.fn().mockResolvedValue({
|
|
178
|
+
data: mockProductInstance,
|
|
179
|
+
errors: null,
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
const mockClient = {
|
|
183
|
+
models: {
|
|
184
|
+
ProductInstance: { get: mockGet },
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
const result = await getProductInstance(mockClient, "instance-001");
|
|
189
|
+
|
|
190
|
+
expect(result).toEqual(mockProductInstance);
|
|
191
|
+
expect(mockGet).toHaveBeenCalledWith({ id: "instance-001" });
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
it("should return null when not found", async () => {
|
|
195
|
+
const mockGet = vi.fn().mockResolvedValue({
|
|
196
|
+
data: null,
|
|
197
|
+
errors: [{ message: "Not found" }],
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
const mockClient = {
|
|
201
|
+
models: {
|
|
202
|
+
ProductInstance: { get: mockGet },
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
const result = await getProductInstance(mockClient, "nonexistent");
|
|
207
|
+
|
|
208
|
+
expect(result).toBeNull();
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
describe("listProductInstancesByBrand", () => {
|
|
213
|
+
it("should filter instances by brand ID", async () => {
|
|
214
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
215
|
+
data: [mockProductInstance],
|
|
216
|
+
errors: null,
|
|
217
|
+
nextToken: null,
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
const mockClient = {
|
|
221
|
+
models: {
|
|
222
|
+
ProductInstance: { list: mockList },
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
await listProductInstancesByBrand(mockClient, "brand-001");
|
|
227
|
+
|
|
228
|
+
expect(mockList).toHaveBeenCalledWith({
|
|
229
|
+
filter: { brandId: { eq: "brand-001" } },
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
it("should support pagination", async () => {
|
|
234
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
235
|
+
data: [mockProductInstance],
|
|
236
|
+
errors: null,
|
|
237
|
+
nextToken: "next-page",
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
const mockClient = {
|
|
241
|
+
models: {
|
|
242
|
+
ProductInstance: { list: mockList },
|
|
243
|
+
},
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
const result = await listProductInstancesByBrand(mockClient, "brand-001", {
|
|
247
|
+
limit: 10,
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
expect(result.nextToken).toBe("next-page");
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it("should return empty array on error", async () => {
|
|
254
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
255
|
+
data: null,
|
|
256
|
+
errors: [{ message: "Error" }],
|
|
257
|
+
nextToken: undefined,
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
const mockClient = {
|
|
261
|
+
models: {
|
|
262
|
+
ProductInstance: { list: mockList },
|
|
263
|
+
},
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
const result = await listProductInstancesByBrand(mockClient, "brand-001");
|
|
267
|
+
|
|
268
|
+
expect(result.items).toHaveLength(0);
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
describe("listProductInstancesByAccount", () => {
|
|
273
|
+
it("should filter instances by account ID", async () => {
|
|
274
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
275
|
+
data: [mockProductInstance],
|
|
276
|
+
errors: null,
|
|
277
|
+
nextToken: null,
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
const mockClient = {
|
|
281
|
+
models: {
|
|
282
|
+
ProductInstance: { list: mockList },
|
|
283
|
+
},
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
await listProductInstancesByAccount(mockClient, "account-001");
|
|
287
|
+
|
|
288
|
+
expect(mockList).toHaveBeenCalledWith({
|
|
289
|
+
filter: { accountId: { eq: "account-001" } },
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
describe("listEnabledProductInstancesByBrand", () => {
|
|
295
|
+
it("should filter by brand ID and enabled status", async () => {
|
|
296
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
297
|
+
data: [mockProductInstance],
|
|
298
|
+
errors: null,
|
|
299
|
+
nextToken: null,
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
const mockClient = {
|
|
303
|
+
models: {
|
|
304
|
+
ProductInstance: { list: mockList },
|
|
305
|
+
},
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
await listEnabledProductInstancesByBrand(mockClient, "brand-001");
|
|
309
|
+
|
|
310
|
+
expect(mockList).toHaveBeenCalledWith({
|
|
311
|
+
filter: {
|
|
312
|
+
brandId: { eq: "brand-001" },
|
|
313
|
+
enabled: { eq: true },
|
|
314
|
+
},
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
it("should support pagination options", async () => {
|
|
319
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
320
|
+
data: [mockProductInstance],
|
|
321
|
+
errors: null,
|
|
322
|
+
nextToken: "token-123",
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
const mockClient = {
|
|
326
|
+
models: {
|
|
327
|
+
ProductInstance: { list: mockList },
|
|
328
|
+
},
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
const result = await listEnabledProductInstancesByBrand(mockClient, "brand-001", {
|
|
332
|
+
limit: 5,
|
|
333
|
+
nextToken: "prev-token",
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
expect(mockList).toHaveBeenCalledWith({
|
|
337
|
+
filter: {
|
|
338
|
+
brandId: { eq: "brand-001" },
|
|
339
|
+
enabled: { eq: true },
|
|
340
|
+
},
|
|
341
|
+
limit: 5,
|
|
342
|
+
nextToken: "prev-token",
|
|
343
|
+
});
|
|
344
|
+
expect(result.nextToken).toBe("token-123");
|
|
345
|
+
});
|
|
346
|
+
});
|
|
347
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./reservations";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./users";
|