@rebasepro/server-postgresql 0.0.1-canary.4d4fb3e → 0.0.1-canary.ca2cb6e
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/common/src/collections/CollectionRegistry.d.ts +8 -0
- package/dist/common/src/util/entities.d.ts +22 -0
- package/dist/common/src/util/relations.d.ts +14 -4
- package/dist/common/src/util/resolutions.d.ts +1 -1
- package/dist/index.es.js +1254 -591
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +1254 -591
- package/dist/index.umd.js.map +1 -1
- package/dist/server-postgresql/src/PostgresBackendDriver.d.ts +17 -29
- package/dist/server-postgresql/src/auth/services.d.ts +7 -3
- package/dist/server-postgresql/src/collections/PostgresCollectionRegistry.d.ts +1 -1
- package/dist/server-postgresql/src/connection.d.ts +34 -1
- package/dist/server-postgresql/src/data-transformer.d.ts +26 -4
- package/dist/server-postgresql/src/databasePoolManager.d.ts +2 -2
- package/dist/server-postgresql/src/schema/auth-schema.d.ts +139 -38
- package/dist/server-postgresql/src/schema/doctor-cli.d.ts +2 -0
- package/dist/server-postgresql/src/schema/doctor.d.ts +43 -0
- package/dist/server-postgresql/src/schema/generate-drizzle-schema-logic.d.ts +1 -1
- package/dist/server-postgresql/src/schema/test-schema.d.ts +24 -0
- package/dist/server-postgresql/src/services/EntityFetchService.d.ts +22 -8
- package/dist/server-postgresql/src/services/EntityPersistService.d.ts +1 -1
- package/dist/server-postgresql/src/services/RelationService.d.ts +11 -5
- package/dist/server-postgresql/src/services/entity-helpers.d.ts +16 -2
- package/dist/server-postgresql/src/services/entityService.d.ts +8 -6
- package/dist/server-postgresql/src/services/realtimeService.d.ts +2 -0
- package/dist/server-postgresql/src/utils/drizzle-conditions.d.ts +2 -2
- package/dist/types/src/controllers/auth.d.ts +2 -0
- package/dist/types/src/controllers/client.d.ts +119 -7
- package/dist/types/src/controllers/collection_registry.d.ts +4 -3
- package/dist/types/src/controllers/customization_controller.d.ts +7 -1
- package/dist/types/src/controllers/data.d.ts +34 -7
- package/dist/types/src/controllers/data_driver.d.ts +20 -28
- package/dist/types/src/controllers/database_admin.d.ts +2 -2
- package/dist/types/src/controllers/email.d.ts +34 -0
- package/dist/types/src/controllers/index.d.ts +1 -0
- package/dist/types/src/controllers/local_config_persistence.d.ts +4 -4
- package/dist/types/src/controllers/navigation.d.ts +5 -5
- package/dist/types/src/controllers/registry.d.ts +6 -3
- package/dist/types/src/controllers/side_entity_controller.d.ts +7 -6
- package/dist/types/src/controllers/storage.d.ts +24 -26
- package/dist/types/src/rebase_context.d.ts +8 -4
- package/dist/types/src/types/backend.d.ts +4 -1
- package/dist/types/src/types/builders.d.ts +5 -4
- package/dist/types/src/types/chips.d.ts +1 -1
- package/dist/types/src/types/collections.d.ts +169 -125
- package/dist/types/src/types/cron.d.ts +102 -0
- package/dist/types/src/types/data_source.d.ts +1 -1
- package/dist/types/src/types/entity_actions.d.ts +8 -8
- package/dist/types/src/types/entity_callbacks.d.ts +15 -15
- package/dist/types/src/types/entity_link_builder.d.ts +1 -1
- package/dist/types/src/types/entity_overrides.d.ts +2 -1
- package/dist/types/src/types/entity_views.d.ts +8 -8
- package/dist/types/src/types/export_import.d.ts +3 -3
- package/dist/types/src/types/index.d.ts +1 -0
- package/dist/types/src/types/plugins.d.ts +72 -18
- package/dist/types/src/types/properties.d.ts +118 -33
- package/dist/types/src/types/relations.d.ts +1 -1
- package/dist/types/src/types/slots.d.ts +30 -6
- package/dist/types/src/types/translations.d.ts +44 -0
- package/dist/types/src/types/user_management_delegate.d.ts +1 -0
- package/drizzle-test/0000_woozy_junta.sql +6 -0
- package/drizzle-test/0001_youthful_arachne.sql +1 -0
- package/drizzle-test/0002_lively_dragon_lord.sql +2 -0
- package/drizzle-test/0003_mean_king_cobra.sql +2 -0
- package/drizzle-test/meta/0000_snapshot.json +47 -0
- package/drizzle-test/meta/0001_snapshot.json +48 -0
- package/drizzle-test/meta/0002_snapshot.json +38 -0
- package/drizzle-test/meta/0003_snapshot.json +48 -0
- package/drizzle-test/meta/_journal.json +34 -0
- package/drizzle-test-out/0000_tan_trauma.sql +6 -0
- package/drizzle-test-out/0001_rapid_drax.sql +1 -0
- package/drizzle-test-out/meta/0000_snapshot.json +44 -0
- package/drizzle-test-out/meta/0001_snapshot.json +54 -0
- package/drizzle-test-out/meta/_journal.json +20 -0
- package/drizzle.test.config.ts +10 -0
- package/package.json +88 -89
- package/scratch.ts +41 -0
- package/src/PostgresBackendDriver.ts +63 -79
- package/src/PostgresBootstrapper.ts +7 -8
- package/src/auth/ensure-tables.ts +158 -86
- package/src/auth/services.ts +109 -50
- package/src/cli.ts +259 -16
- package/src/collections/PostgresCollectionRegistry.ts +6 -6
- package/src/connection.ts +70 -48
- package/src/data-transformer.ts +155 -116
- package/src/databasePoolManager.ts +6 -5
- package/src/history/HistoryService.ts +3 -12
- package/src/interfaces.ts +3 -3
- package/src/schema/auth-schema.ts +26 -3
- package/src/schema/doctor-cli.ts +47 -0
- package/src/schema/doctor.ts +595 -0
- package/src/schema/generate-drizzle-schema-logic.ts +204 -57
- package/src/schema/generate-drizzle-schema.ts +6 -6
- package/src/schema/test-schema.ts +11 -0
- package/src/services/BranchService.ts +5 -5
- package/src/services/EntityFetchService.ts +317 -188
- package/src/services/EntityPersistService.ts +15 -17
- package/src/services/RelationService.ts +299 -37
- package/src/services/entity-helpers.ts +39 -13
- package/src/services/entityService.ts +11 -9
- package/src/services/realtimeService.ts +58 -29
- package/src/utils/drizzle-conditions.ts +25 -24
- package/src/websocket.ts +52 -21
- package/test/auth-services.test.ts +131 -39
- package/test/batch-many-to-many-regression.test.ts +573 -0
- package/test/branchService.test.ts +22 -12
- package/test/data-transformer-hardening.test.ts +417 -0
- package/test/data-transformer.test.ts +175 -0
- package/test/doctor.test.ts +182 -0
- package/test/entityService.errors.test.ts +31 -16
- package/test/entityService.relations.test.ts +155 -59
- package/test/entityService.subcollection-search.test.ts +107 -57
- package/test/entityService.test.ts +105 -47
- package/test/generate-drizzle-schema.test.ts +262 -69
- package/test/historyService.test.ts +31 -16
- package/test/n-plus-one-regression.test.ts +314 -0
- package/test/postgresDataDriver.test.ts +260 -168
- package/test/realtimeService.test.ts +70 -39
- package/test/relation-pipeline-gaps.test.ts +637 -0
- package/test/relations.test.ts +492 -39
- package/test-drizzle-bug.ts +18 -0
- package/test-drizzle-out/0000_cultured_freak.sql +7 -0
- package/test-drizzle-out/0001_tiresome_professor_monster.sql +1 -0
- package/test-drizzle-out/meta/0000_snapshot.json +55 -0
- package/test-drizzle-out/meta/0001_snapshot.json +63 -0
- package/test-drizzle-out/meta/_journal.json +20 -0
- package/test-drizzle-prompt.sh +2 -0
- package/test-policy-prompt.sh +3 -0
- package/test-programmatic.ts +30 -0
- package/test-programmatic2.ts +59 -0
- package/test-schema-no-policies.ts +12 -0
- package/test_drizzle_mock.js +2 -2
- package/test_find_changed.mjs +3 -1
- package/test_hash.js +14 -0
- package/tsconfig.json +1 -1
- package/vite.config.ts +5 -5
|
@@ -4,8 +4,10 @@ import { users, refreshTokens, passwordResetTokens, User } from "../src/schema/a
|
|
|
4
4
|
|
|
5
5
|
// Mock the drizzle-orm functions
|
|
6
6
|
jest.mock("drizzle-orm", () => ({
|
|
7
|
-
eq: jest.fn((field, value) => ({ field,
|
|
8
|
-
|
|
7
|
+
eq: jest.fn((field, value) => ({ field,
|
|
8
|
+
value,
|
|
9
|
+
type: "eq" })),
|
|
10
|
+
sql: jest.fn((strings: TemplateStringsArray, ...values: unknown[]) => ({
|
|
9
11
|
strings,
|
|
10
12
|
values,
|
|
11
13
|
type: "sql"
|
|
@@ -14,7 +16,7 @@ jest.mock("drizzle-orm", () => ({
|
|
|
14
16
|
}));
|
|
15
17
|
|
|
16
18
|
describe("Auth Services", () => {
|
|
17
|
-
let db: jest.Mocked<NodePgDatabase<
|
|
19
|
+
let db: jest.Mocked<NodePgDatabase<Record<string, unknown>>>;
|
|
18
20
|
let mockInsertValues: jest.Mock;
|
|
19
21
|
let mockInsertReturning: jest.Mock;
|
|
20
22
|
let mockSelectFrom: jest.Mock;
|
|
@@ -28,9 +30,10 @@ describe("Auth Services", () => {
|
|
|
28
30
|
beforeEach(() => {
|
|
29
31
|
// Create chainable mocks
|
|
30
32
|
mockInsertReturning = jest.fn().mockResolvedValue([]);
|
|
31
|
-
mockInsertValues = jest.fn().mockReturnValue({
|
|
33
|
+
mockInsertValues = jest.fn().mockReturnValue({
|
|
32
34
|
returning: mockInsertReturning,
|
|
33
|
-
onConflictDoUpdate: jest.fn().mockReturnValue({ returning: mockInsertReturning })
|
|
35
|
+
onConflictDoUpdate: jest.fn().mockReturnValue({ returning: mockInsertReturning }),
|
|
36
|
+
onConflictDoNothing: jest.fn().mockReturnValue({ returning: mockInsertReturning })
|
|
34
37
|
});
|
|
35
38
|
|
|
36
39
|
mockSelectWhere = jest.fn().mockResolvedValue([]);
|
|
@@ -52,7 +55,7 @@ describe("Auth Services", () => {
|
|
|
52
55
|
update: jest.fn().mockReturnValue({ set: mockUpdateSet }),
|
|
53
56
|
delete: jest.fn().mockReturnValue({ where: mockDeleteWhere }),
|
|
54
57
|
execute: mockExecute
|
|
55
|
-
} as
|
|
58
|
+
} as unknown as jest.Mocked<NodePgDatabase<Record<string, unknown>>>;
|
|
56
59
|
});
|
|
57
60
|
|
|
58
61
|
describe("UserService", () => {
|
|
@@ -66,10 +69,12 @@ describe("Auth Services", () => {
|
|
|
66
69
|
it("should create a user and return it", async () => {
|
|
67
70
|
const newUser = {
|
|
68
71
|
email: "test@example.com",
|
|
69
|
-
displayName: "Test User"
|
|
70
|
-
provider: "email"
|
|
72
|
+
displayName: "Test User"
|
|
71
73
|
};
|
|
72
|
-
const createdUser = { id: "user-123",
|
|
74
|
+
const createdUser = { id: "user-123",
|
|
75
|
+
...newUser,
|
|
76
|
+
createdAt: new Date(),
|
|
77
|
+
updatedAt: new Date() };
|
|
73
78
|
mockInsertReturning.mockResolvedValueOnce([createdUser]);
|
|
74
79
|
|
|
75
80
|
const result = await userService.createUser(newUser);
|
|
@@ -82,7 +87,8 @@ describe("Auth Services", () => {
|
|
|
82
87
|
|
|
83
88
|
describe("getUserById", () => {
|
|
84
89
|
it("should return user when found", async () => {
|
|
85
|
-
const mockUser = { id: "user-123",
|
|
90
|
+
const mockUser = { id: "user-123",
|
|
91
|
+
email: "test@example.com" };
|
|
86
92
|
mockSelectWhere.mockResolvedValueOnce([mockUser]);
|
|
87
93
|
|
|
88
94
|
const result = await userService.getUserById("user-123");
|
|
@@ -102,7 +108,8 @@ describe("Auth Services", () => {
|
|
|
102
108
|
|
|
103
109
|
describe("getUserByEmail", () => {
|
|
104
110
|
it("should return user when found by email", async () => {
|
|
105
|
-
const mockUser = { id: "user-123",
|
|
111
|
+
const mockUser = { id: "user-123",
|
|
112
|
+
email: "test@example.com" };
|
|
106
113
|
mockSelectWhere.mockResolvedValueOnce([mockUser]);
|
|
107
114
|
|
|
108
115
|
const result = await userService.getUserByEmail("test@example.com");
|
|
@@ -120,20 +127,40 @@ describe("Auth Services", () => {
|
|
|
120
127
|
});
|
|
121
128
|
});
|
|
122
129
|
|
|
123
|
-
describe("
|
|
124
|
-
it("should
|
|
125
|
-
const mockUser = { id: "user-123"
|
|
126
|
-
|
|
130
|
+
describe("getUserByIdentity", () => {
|
|
131
|
+
it("should execute sql for identity lookup", async () => {
|
|
132
|
+
const mockUser = { id: "user-123" };
|
|
133
|
+
// execute mock instead of select
|
|
134
|
+
mockExecute.mockResolvedValueOnce({ rows: [mockUser] });
|
|
127
135
|
|
|
128
|
-
const result = await userService.
|
|
136
|
+
const result = await userService.getUserByIdentity("google", "google-abc");
|
|
129
137
|
|
|
130
|
-
expect(
|
|
138
|
+
expect(mockExecute).toHaveBeenCalled();
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
describe("getUserIdentities", () => {
|
|
143
|
+
it("should fetch user identities", async () => {
|
|
144
|
+
mockExecute.mockResolvedValueOnce({ rows: [] });
|
|
145
|
+
|
|
146
|
+
const result = await userService.getUserIdentities("user-123");
|
|
147
|
+
|
|
148
|
+
expect(mockExecute).toHaveBeenCalled();
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
describe("linkUserIdentity", () => {
|
|
153
|
+
it("should insert user identity", async () => {
|
|
154
|
+
await userService.linkUserIdentity("user-123", "google", "123", { email: "test@test.com" });
|
|
155
|
+
expect(db.insert).toHaveBeenCalled();
|
|
131
156
|
});
|
|
132
157
|
});
|
|
133
158
|
|
|
134
159
|
describe("updateUser", () => {
|
|
135
160
|
it("should update user and return updated record", async () => {
|
|
136
|
-
const updatedUser = { id: "user-123",
|
|
161
|
+
const updatedUser = { id: "user-123",
|
|
162
|
+
email: "test@example.com",
|
|
163
|
+
displayName: "Updated Name" };
|
|
137
164
|
mockUpdateReturning.mockResolvedValueOnce([updatedUser]);
|
|
138
165
|
|
|
139
166
|
const result = await userService.updateUser("user-123", { displayName: "Updated Name" });
|
|
@@ -167,8 +194,10 @@ describe("Auth Services", () => {
|
|
|
167
194
|
describe("listUsers", () => {
|
|
168
195
|
it("should return all users", async () => {
|
|
169
196
|
const mockUsers = [
|
|
170
|
-
{ id: "user-1",
|
|
171
|
-
|
|
197
|
+
{ id: "user-1",
|
|
198
|
+
email: "user1@example.com" },
|
|
199
|
+
{ id: "user-2",
|
|
200
|
+
email: "user2@example.com" }
|
|
172
201
|
];
|
|
173
202
|
mockSelectFrom.mockReturnValueOnce(Promise.resolve(mockUsers));
|
|
174
203
|
|
|
@@ -235,7 +264,8 @@ describe("Auth Services", () => {
|
|
|
235
264
|
|
|
236
265
|
describe("getUserByVerificationToken", () => {
|
|
237
266
|
it("should find user by verification token", async () => {
|
|
238
|
-
const mockUser = { id: "user-123",
|
|
267
|
+
const mockUser = { id: "user-123",
|
|
268
|
+
email: "test@example.com" };
|
|
239
269
|
mockSelectWhere.mockResolvedValueOnce([mockUser]);
|
|
240
270
|
|
|
241
271
|
const result = await userService.getUserByVerificationToken("token-abc");
|
|
@@ -248,8 +278,18 @@ describe("Auth Services", () => {
|
|
|
248
278
|
it("should return roles for user", async () => {
|
|
249
279
|
mockExecute.mockResolvedValueOnce({
|
|
250
280
|
rows: [
|
|
251
|
-
{ id: "admin",
|
|
252
|
-
|
|
281
|
+
{ id: "admin",
|
|
282
|
+
name: "Admin",
|
|
283
|
+
is_admin: true,
|
|
284
|
+
default_permissions: null,
|
|
285
|
+
collection_permissions: null,
|
|
286
|
+
config: null },
|
|
287
|
+
{ id: "editor",
|
|
288
|
+
name: "Editor",
|
|
289
|
+
is_admin: false,
|
|
290
|
+
default_permissions: { edit: true },
|
|
291
|
+
collection_permissions: null,
|
|
292
|
+
config: null }
|
|
253
293
|
]
|
|
254
294
|
});
|
|
255
295
|
|
|
@@ -271,7 +311,12 @@ describe("Auth Services", () => {
|
|
|
271
311
|
it("should return role IDs for user", async () => {
|
|
272
312
|
mockExecute.mockResolvedValueOnce({
|
|
273
313
|
rows: [
|
|
274
|
-
{ id: "admin",
|
|
314
|
+
{ id: "admin",
|
|
315
|
+
name: "Admin",
|
|
316
|
+
is_admin: true,
|
|
317
|
+
default_permissions: null,
|
|
318
|
+
collection_permissions: null,
|
|
319
|
+
config: null }
|
|
275
320
|
]
|
|
276
321
|
});
|
|
277
322
|
|
|
@@ -308,17 +353,28 @@ describe("Auth Services", () => {
|
|
|
308
353
|
|
|
309
354
|
describe("getUserWithRoles", () => {
|
|
310
355
|
it("should return user with roles", async () => {
|
|
311
|
-
const mockUser = { id: "user-123",
|
|
356
|
+
const mockUser = { id: "user-123",
|
|
357
|
+
email: "test@example.com" };
|
|
312
358
|
mockSelectWhere.mockResolvedValueOnce([mockUser]);
|
|
313
359
|
mockExecute.mockResolvedValueOnce({
|
|
314
|
-
rows: [{ id: "admin",
|
|
360
|
+
rows: [{ id: "admin",
|
|
361
|
+
name: "Admin",
|
|
362
|
+
is_admin: true,
|
|
363
|
+
default_permissions: null,
|
|
364
|
+
collection_permissions: null,
|
|
365
|
+
config: null }]
|
|
315
366
|
});
|
|
316
367
|
|
|
317
368
|
const result = await userService.getUserWithRoles("user-123");
|
|
318
369
|
|
|
319
370
|
expect(result).toEqual({
|
|
320
371
|
user: mockUser,
|
|
321
|
-
roles: [{ id: "admin",
|
|
372
|
+
roles: [{ id: "admin",
|
|
373
|
+
name: "Admin",
|
|
374
|
+
isAdmin: true,
|
|
375
|
+
defaultPermissions: null,
|
|
376
|
+
collectionPermissions: null,
|
|
377
|
+
config: null }]
|
|
322
378
|
});
|
|
323
379
|
});
|
|
324
380
|
|
|
@@ -342,7 +398,12 @@ describe("Auth Services", () => {
|
|
|
342
398
|
describe("getRoleById", () => {
|
|
343
399
|
it("should return role when found", async () => {
|
|
344
400
|
mockExecute.mockResolvedValueOnce({
|
|
345
|
-
rows: [{ id: "admin",
|
|
401
|
+
rows: [{ id: "admin",
|
|
402
|
+
name: "Admin",
|
|
403
|
+
is_admin: true,
|
|
404
|
+
default_permissions: null,
|
|
405
|
+
collection_permissions: null,
|
|
406
|
+
config: null }]
|
|
346
407
|
});
|
|
347
408
|
|
|
348
409
|
const result = await roleService.getRoleById("admin");
|
|
@@ -370,8 +431,18 @@ describe("Auth Services", () => {
|
|
|
370
431
|
it("should return all roles", async () => {
|
|
371
432
|
mockExecute.mockResolvedValueOnce({
|
|
372
433
|
rows: [
|
|
373
|
-
{ id: "admin",
|
|
374
|
-
|
|
434
|
+
{ id: "admin",
|
|
435
|
+
name: "Admin",
|
|
436
|
+
is_admin: true,
|
|
437
|
+
default_permissions: null,
|
|
438
|
+
collection_permissions: null,
|
|
439
|
+
config: null },
|
|
440
|
+
{ id: "editor",
|
|
441
|
+
name: "Editor",
|
|
442
|
+
is_admin: false,
|
|
443
|
+
default_permissions: null,
|
|
444
|
+
collection_permissions: null,
|
|
445
|
+
config: null }
|
|
375
446
|
]
|
|
376
447
|
});
|
|
377
448
|
|
|
@@ -384,7 +455,12 @@ describe("Auth Services", () => {
|
|
|
384
455
|
describe("createRole", () => {
|
|
385
456
|
it("should create a role", async () => {
|
|
386
457
|
mockExecute.mockResolvedValueOnce({
|
|
387
|
-
rows: [{ id: "custom",
|
|
458
|
+
rows: [{ id: "custom",
|
|
459
|
+
name: "Custom Role",
|
|
460
|
+
is_admin: false,
|
|
461
|
+
default_permissions: null,
|
|
462
|
+
collection_permissions: null,
|
|
463
|
+
config: null }]
|
|
388
464
|
});
|
|
389
465
|
|
|
390
466
|
const role = await roleService.createRole({
|
|
@@ -402,9 +478,19 @@ describe("Auth Services", () => {
|
|
|
402
478
|
describe("updateRole", () => {
|
|
403
479
|
it("should update a role", async () => {
|
|
404
480
|
mockExecute
|
|
405
|
-
.mockResolvedValueOnce({ rows: [{ id: "admin",
|
|
481
|
+
.mockResolvedValueOnce({ rows: [{ id: "admin",
|
|
482
|
+
name: "Admin",
|
|
483
|
+
is_admin: true,
|
|
484
|
+
default_permissions: null,
|
|
485
|
+
collection_permissions: null,
|
|
486
|
+
config: null }] })
|
|
406
487
|
.mockResolvedValueOnce({ rows: [] })
|
|
407
|
-
.mockResolvedValueOnce({ rows: [{ id: "admin",
|
|
488
|
+
.mockResolvedValueOnce({ rows: [{ id: "admin",
|
|
489
|
+
name: "Super Admin",
|
|
490
|
+
is_admin: true,
|
|
491
|
+
default_permissions: null,
|
|
492
|
+
collection_permissions: null,
|
|
493
|
+
config: null }] });
|
|
408
494
|
|
|
409
495
|
const result = await roleService.updateRole("admin", { name: "Super Admin" });
|
|
410
496
|
|
|
@@ -456,11 +542,13 @@ describe("Auth Services", () => {
|
|
|
456
542
|
describe("findByHash", () => {
|
|
457
543
|
it("should find token by hash", async () => {
|
|
458
544
|
const expiresAt = new Date();
|
|
459
|
-
mockSelectWhere.mockResolvedValueOnce([{ userId: "user-123",
|
|
545
|
+
mockSelectWhere.mockResolvedValueOnce([{ userId: "user-123",
|
|
546
|
+
expiresAt }]);
|
|
460
547
|
|
|
461
548
|
const result = await refreshTokenService.findByHash("token-hash");
|
|
462
549
|
|
|
463
|
-
expect(result).toEqual({ userId: "user-123",
|
|
550
|
+
expect(result).toEqual({ userId: "user-123",
|
|
551
|
+
expiresAt });
|
|
464
552
|
});
|
|
465
553
|
|
|
466
554
|
it("should return null when token not found", async () => {
|
|
@@ -512,14 +600,17 @@ describe("Auth Services", () => {
|
|
|
512
600
|
describe("findValidByHash", () => {
|
|
513
601
|
it("should find valid token", async () => {
|
|
514
602
|
const expiresAt = new Date(Date.now() + 60 * 60 * 1000);
|
|
515
|
-
mockSelectWhere.mockResolvedValueOnce([{ userId: "user-123",
|
|
603
|
+
mockSelectWhere.mockResolvedValueOnce([{ userId: "user-123",
|
|
604
|
+
expiresAt }]);
|
|
516
605
|
mockExecute.mockResolvedValueOnce({
|
|
517
|
-
rows: [{ user_id: "user-123",
|
|
606
|
+
rows: [{ user_id: "user-123",
|
|
607
|
+
expires_at: expiresAt }]
|
|
518
608
|
});
|
|
519
609
|
|
|
520
610
|
const result = await passwordResetTokenService.findValidByHash("token-hash");
|
|
521
611
|
|
|
522
|
-
expect(result).toEqual({ userId: "user-123",
|
|
612
|
+
expect(result).toEqual({ userId: "user-123",
|
|
613
|
+
expiresAt });
|
|
523
614
|
});
|
|
524
615
|
|
|
525
616
|
it("should return null when token not found", async () => {
|
|
@@ -532,7 +623,8 @@ describe("Auth Services", () => {
|
|
|
532
623
|
|
|
533
624
|
it("should return null when token is expired or used", async () => {
|
|
534
625
|
const expiresAt = new Date(Date.now() + 60 * 60 * 1000);
|
|
535
|
-
mockSelectWhere.mockResolvedValueOnce([{ userId: "user-123",
|
|
626
|
+
mockSelectWhere.mockResolvedValueOnce([{ userId: "user-123",
|
|
627
|
+
expiresAt }]);
|
|
536
628
|
mockExecute.mockResolvedValueOnce({ rows: [] }); // No valid token found
|
|
537
629
|
|
|
538
630
|
const result = await passwordResetTokenService.findValidByHash("token-hash");
|