@htlkg/data 0.0.21 → 0.0.22
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 +601 -94
- package/dist/hooks/index.js +682 -73
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +691 -82
- 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/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 +96 -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,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";
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User Query Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests for user query functions including filtering and pagination.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { describe, it, expect, vi } from "vitest";
|
|
8
|
+
import {
|
|
9
|
+
getUser,
|
|
10
|
+
getUserByCognitoId,
|
|
11
|
+
getUserByEmail,
|
|
12
|
+
listUsers,
|
|
13
|
+
listUsersByAccount,
|
|
14
|
+
listActiveUsers,
|
|
15
|
+
} from "./users";
|
|
16
|
+
|
|
17
|
+
describe("User Queries", () => {
|
|
18
|
+
const mockUser = {
|
|
19
|
+
id: "user-001",
|
|
20
|
+
cognitoId: "cognito-123",
|
|
21
|
+
email: "user@example.com",
|
|
22
|
+
accountId: "account-123",
|
|
23
|
+
brandIds: ["brand-001"],
|
|
24
|
+
roles: ["BRAND_ADMIN"],
|
|
25
|
+
status: "active",
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
describe("getUser", () => {
|
|
29
|
+
it("should return a user by ID", async () => {
|
|
30
|
+
const mockGet = vi.fn().mockResolvedValue({
|
|
31
|
+
data: mockUser,
|
|
32
|
+
errors: null,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const mockClient = {
|
|
36
|
+
models: {
|
|
37
|
+
User: { get: mockGet },
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const result = await getUser(mockClient, "user-001");
|
|
42
|
+
|
|
43
|
+
expect(result).toEqual(mockUser);
|
|
44
|
+
expect(mockGet).toHaveBeenCalledWith({ id: "user-001" });
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("should return null when user not found", async () => {
|
|
48
|
+
const mockGet = vi.fn().mockResolvedValue({
|
|
49
|
+
data: null,
|
|
50
|
+
errors: [{ message: "Not found" }],
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const mockClient = {
|
|
54
|
+
models: {
|
|
55
|
+
User: { get: mockGet },
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const result = await getUser(mockClient, "nonexistent");
|
|
60
|
+
|
|
61
|
+
expect(result).toBeNull();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("should throw on unexpected error", async () => {
|
|
65
|
+
const mockGet = vi.fn().mockRejectedValue(new Error("Network error"));
|
|
66
|
+
|
|
67
|
+
const mockClient = {
|
|
68
|
+
models: {
|
|
69
|
+
User: { get: mockGet },
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
await expect(getUser(mockClient, "user-001")).rejects.toThrow("Network error");
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
describe("getUserByCognitoId", () => {
|
|
78
|
+
it("should return user by Cognito ID", async () => {
|
|
79
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
80
|
+
data: [mockUser],
|
|
81
|
+
errors: null,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const mockClient = {
|
|
85
|
+
models: {
|
|
86
|
+
User: { list: mockList },
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const result = await getUserByCognitoId(mockClient, "cognito-123");
|
|
91
|
+
|
|
92
|
+
expect(result).toEqual(mockUser);
|
|
93
|
+
expect(mockList).toHaveBeenCalledWith({
|
|
94
|
+
filter: { cognitoId: { eq: "cognito-123" } },
|
|
95
|
+
limit: 1,
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it("should return undefined when no user found", async () => {
|
|
100
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
101
|
+
data: [],
|
|
102
|
+
errors: null,
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
const mockClient = {
|
|
106
|
+
models: {
|
|
107
|
+
User: { list: mockList },
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const result = await getUserByCognitoId(mockClient, "nonexistent");
|
|
112
|
+
|
|
113
|
+
expect(result).toBeUndefined();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it("should return null on GraphQL error", async () => {
|
|
117
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
118
|
+
data: null,
|
|
119
|
+
errors: [{ message: "Query failed" }],
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
const mockClient = {
|
|
123
|
+
models: {
|
|
124
|
+
User: { list: mockList },
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const result = await getUserByCognitoId(mockClient, "cognito-123");
|
|
129
|
+
|
|
130
|
+
expect(result).toBeNull();
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe("getUserByEmail", () => {
|
|
135
|
+
it("should return user by email", async () => {
|
|
136
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
137
|
+
data: [mockUser],
|
|
138
|
+
errors: null,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
const mockClient = {
|
|
142
|
+
models: {
|
|
143
|
+
User: { list: mockList },
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const result = await getUserByEmail(mockClient, "user@example.com");
|
|
148
|
+
|
|
149
|
+
expect(result).toEqual(mockUser);
|
|
150
|
+
expect(mockList).toHaveBeenCalledWith({
|
|
151
|
+
filter: { email: { eq: "user@example.com" } },
|
|
152
|
+
limit: 1,
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it("should return undefined when no user found", async () => {
|
|
157
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
158
|
+
data: [],
|
|
159
|
+
errors: null,
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
const mockClient = {
|
|
163
|
+
models: {
|
|
164
|
+
User: { list: mockList },
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
const result = await getUserByEmail(mockClient, "notfound@example.com");
|
|
169
|
+
|
|
170
|
+
expect(result).toBeUndefined();
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
describe("listUsers", () => {
|
|
175
|
+
const mockUsers = [
|
|
176
|
+
mockUser,
|
|
177
|
+
{ ...mockUser, id: "user-002", email: "user2@example.com" },
|
|
178
|
+
];
|
|
179
|
+
|
|
180
|
+
it("should return a list of users", async () => {
|
|
181
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
182
|
+
data: mockUsers,
|
|
183
|
+
errors: null,
|
|
184
|
+
nextToken: null,
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
const mockClient = {
|
|
188
|
+
models: {
|
|
189
|
+
User: { list: mockList },
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const result = await listUsers(mockClient);
|
|
194
|
+
|
|
195
|
+
expect(result.items).toHaveLength(2);
|
|
196
|
+
expect(result.items[0].id).toBe("user-001");
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it("should pass filter options to the query", async () => {
|
|
200
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
201
|
+
data: [mockUser],
|
|
202
|
+
errors: null,
|
|
203
|
+
nextToken: null,
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
const mockClient = {
|
|
207
|
+
models: {
|
|
208
|
+
User: { list: mockList },
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
const filter = { status: { eq: "active" } };
|
|
213
|
+
await listUsers(mockClient, { filter, limit: 50 });
|
|
214
|
+
|
|
215
|
+
expect(mockList).toHaveBeenCalledWith({
|
|
216
|
+
filter,
|
|
217
|
+
limit: 50,
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it("should return nextToken for pagination", async () => {
|
|
222
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
223
|
+
data: [mockUser],
|
|
224
|
+
errors: null,
|
|
225
|
+
nextToken: "token-123",
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
const mockClient = {
|
|
229
|
+
models: {
|
|
230
|
+
User: { list: mockList },
|
|
231
|
+
},
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
const result = await listUsers(mockClient, { limit: 1 });
|
|
235
|
+
|
|
236
|
+
expect(result.nextToken).toBe("token-123");
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
it("should return empty array on GraphQL error", async () => {
|
|
240
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
241
|
+
data: null,
|
|
242
|
+
errors: [{ message: "Query failed" }],
|
|
243
|
+
nextToken: undefined,
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
const mockClient = {
|
|
247
|
+
models: {
|
|
248
|
+
User: { list: mockList },
|
|
249
|
+
},
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
const result = await listUsers(mockClient);
|
|
253
|
+
|
|
254
|
+
expect(result.items).toHaveLength(0);
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
describe("listUsersByAccount", () => {
|
|
259
|
+
it("should filter users by account ID", async () => {
|
|
260
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
261
|
+
data: [mockUser],
|
|
262
|
+
errors: null,
|
|
263
|
+
nextToken: null,
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
const mockClient = {
|
|
267
|
+
models: {
|
|
268
|
+
User: { list: mockList },
|
|
269
|
+
},
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
await listUsersByAccount(mockClient, "account-123");
|
|
273
|
+
|
|
274
|
+
expect(mockList).toHaveBeenCalledWith({
|
|
275
|
+
filter: { accountId: { eq: "account-123" } },
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
describe("listActiveUsers", () => {
|
|
281
|
+
it("should filter users by active status", async () => {
|
|
282
|
+
const mockList = vi.fn().mockResolvedValue({
|
|
283
|
+
data: [mockUser],
|
|
284
|
+
errors: null,
|
|
285
|
+
nextToken: null,
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
const mockClient = {
|
|
289
|
+
models: {
|
|
290
|
+
User: { list: mockList },
|
|
291
|
+
},
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
await listActiveUsers(mockClient);
|
|
295
|
+
|
|
296
|
+
expect(mockList).toHaveBeenCalledWith({
|
|
297
|
+
filter: { status: { eq: "active" } },
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|