11import type { IncomingMessage , ServerResponse } from 'http'
22import { Injector } from '@furystack/inject'
3- import { StoreManager } from '@furystack/core'
43import { RequestError } from '@furystack/rest'
54import { HttpUserContext } from '@furystack/rest-service'
6- import { PasswordAuthenticator , PasswordCredential } from '@furystack/security'
5+ import { PasswordAuthenticator } from '@furystack/security'
76import { usingAsync } from '@furystack/utils'
87import { describe , expect , it , vi } from 'vitest'
9- import { User } from 'common'
108import { RegisterAction } from './register-action.js'
119
12- // Mock getLogger
1310vi . mock ( '@furystack/logging' , ( ) => ( {
1411 getLogger : ( ) => ( {
1512 withScope : ( ) => ( {
@@ -20,27 +17,32 @@ vi.mock('@furystack/logging', () => ({
2017 } ) ,
2118} ) )
2219
23- describe ( 'RegisterAction' , ( ) => {
24- const createTestInjector = ( ) => {
25- const injector = new Injector ( )
20+ const mockUserDataSet = {
21+ get : vi . fn ( ) ,
22+ add : vi . fn ( ) ,
23+ remove : vi . fn ( ) ,
24+ }
2625
27- const mockUserStore = {
28- get : vi . fn ( ) ,
29- add : vi . fn ( ) ,
30- remove : vi . fn ( ) ,
31- }
26+ const mockCredentialDataSet = {
27+ add : vi . fn ( ) ,
28+ }
3229
33- const mockCredentialStore = {
34- add : vi . fn ( ) ,
35- }
30+ vi . mock ( '@furystack/core' , ( ) => ( {
31+ useSystemIdentityContext : ( { injector } : { injector : unknown } ) => injector ,
32+ } ) )
3633
37- const mockStoreManager = {
38- getStoreFor : vi . fn ( ( model : { name : string } ) => {
39- if ( model === User || model . name === 'User' ) return mockUserStore
40- if ( model === PasswordCredential || model . name === 'PasswordCredential' ) return mockCredentialStore
41- throw new Error ( `Unknown model: ${ model . name } ` )
42- } ) ,
43- }
34+ vi . mock ( '@furystack/repository' , ( ) => ( {
35+ getDataSetFor : ( _injector : unknown , model : { name ?: string } | ( ( ...args : unknown [ ] ) => unknown ) ) => {
36+ const name = typeof model === 'function' ? model . name : ''
37+ if ( name === 'User' ) return mockUserDataSet
38+ if ( name === 'PasswordCredential' ) return mockCredentialDataSet
39+ throw new Error ( `Unknown model: ${ name } ` )
40+ } ,
41+ } ) )
42+
43+ describe ( 'RegisterAction' , ( ) => {
44+ const createTestInjector = ( ) => {
45+ const injector = new Injector ( )
4446
4547 const mockHasher = {
4648 createCredential : vi . fn ( ) . mockResolvedValue ( {
@@ -59,19 +61,18 @@ describe('RegisterAction', () => {
5961 cookieLogin : vi . fn ( ) . mockResolvedValue ( undefined ) ,
6062 }
6163
62- injector . setExplicitInstance ( mockStoreManager as unknown as StoreManager , StoreManager )
6364 injector . setExplicitInstance ( mockAuthenticator as unknown as PasswordAuthenticator , PasswordAuthenticator )
6465 injector . setExplicitInstance ( mockUserContext as unknown as HttpUserContext , HttpUserContext )
6566
66- return { injector, mockUserStore , mockCredentialStore , mockHasher, mockUserContext }
67+ return { injector, mockHasher, mockUserContext }
6768 }
6869
6970 it ( 'should register a new user successfully' , async ( ) => {
70- const { injector, mockUserStore , mockCredentialStore , mockUserContext } = createTestInjector ( )
71+ const { injector, mockUserContext } = createTestInjector ( )
7172
72- mockUserStore . get . mockResolvedValue ( null ) // User doesn't exist
73- mockUserStore . add . mockResolvedValue ( undefined )
74- mockCredentialStore . add . mockResolvedValue ( undefined )
73+ mockUserDataSet . get . mockResolvedValue ( null )
74+ mockUserDataSet . add . mockResolvedValue ( undefined )
75+ mockCredentialDataSet . add . mockResolvedValue ( undefined )
7576
7677 await usingAsync ( injector , async ( i ) => {
7778 const result = await RegisterAction ( {
@@ -81,24 +82,25 @@ describe('RegisterAction', () => {
8182 request : { } as IncomingMessage ,
8283 } )
8384
84- expect ( mockUserStore . get ) . toHaveBeenCalledWith ( 'newuser' )
85- expect ( mockUserStore . add ) . toHaveBeenCalledWith (
85+ expect ( mockUserDataSet . get ) . toHaveBeenCalledWith ( i , 'newuser' )
86+ expect ( mockUserDataSet . add ) . toHaveBeenCalledWith (
87+ i ,
8688 expect . objectContaining ( {
8789 username : 'newuser' ,
8890 roles : [ ] ,
8991 } ) ,
9092 )
91- expect ( mockCredentialStore . add ) . toHaveBeenCalled ( )
93+ expect ( mockCredentialDataSet . add ) . toHaveBeenCalled ( )
9294 expect ( mockUserContext . authenticateUser ) . toHaveBeenCalledWith ( 'newuser' , 'password123' )
9395 expect ( mockUserContext . cookieLogin ) . toHaveBeenCalled ( )
9496 expect ( result . chunk ) . toEqual ( { username : 'newuser' , roles : [ ] } )
9597 } )
9698 } )
9799
98100 it ( 'should throw 409 when user already exists' , async ( ) => {
99- const { injector, mockUserStore } = createTestInjector ( )
101+ const { injector } = createTestInjector ( )
100102
101- mockUserStore . get . mockResolvedValue ( { username : 'existinguser' , roles : [ ] } )
103+ mockUserDataSet . get . mockResolvedValue ( { username : 'existinguser' , roles : [ ] } )
102104
103105 await usingAsync ( injector , async ( i ) => {
104106 try {
@@ -118,9 +120,9 @@ describe('RegisterAction', () => {
118120 } )
119121
120122 it ( 'should throw 400 when credential creation fails' , async ( ) => {
121- const { injector, mockUserStore , mockHasher } = createTestInjector ( )
123+ const { injector, mockHasher } = createTestInjector ( )
122124
123- mockUserStore . get . mockResolvedValue ( null )
125+ mockUserDataSet . get . mockResolvedValue ( null )
124126 mockHasher . createCredential . mockRejectedValue ( new Error ( 'Invalid password' ) )
125127
126128 await usingAsync ( injector , async ( i ) => {
@@ -141,12 +143,12 @@ describe('RegisterAction', () => {
141143 } )
142144
143145 it ( 'should cleanup user when registration fails after user creation' , async ( ) => {
144- const { injector, mockUserStore , mockCredentialStore } = createTestInjector ( )
146+ const { injector } = createTestInjector ( )
145147
146- mockUserStore . get . mockResolvedValue ( null )
147- mockUserStore . add . mockResolvedValue ( undefined )
148- mockCredentialStore . add . mockRejectedValue ( new Error ( 'Credential store error' ) )
149- mockUserStore . remove . mockResolvedValue ( undefined )
148+ mockUserDataSet . get . mockResolvedValue ( null )
149+ mockUserDataSet . add . mockResolvedValue ( undefined )
150+ mockCredentialDataSet . add . mockRejectedValue ( new Error ( 'Credential store error' ) )
151+ mockUserDataSet . remove . mockResolvedValue ( undefined )
150152
151153 await usingAsync ( injector , async ( i ) => {
152154 try {
@@ -159,19 +161,18 @@ describe('RegisterAction', () => {
159161 expect . fail ( 'Expected RequestError to be thrown' )
160162 } catch ( error ) {
161163 expect ( error ) . toBeInstanceOf ( RequestError )
162- // Verify cleanup was attempted
163- expect ( mockUserStore . remove ) . toHaveBeenCalledWith ( 'newuser' )
164+ expect ( mockUserDataSet . remove ) . toHaveBeenCalledWith ( i , 'newuser' )
164165 }
165166 } )
166167 } )
167168
168169 it ( 'should not fail if cleanup fails' , async ( ) => {
169- const { injector, mockUserStore , mockCredentialStore } = createTestInjector ( )
170+ const { injector } = createTestInjector ( )
170171
171- mockUserStore . get . mockResolvedValue ( null )
172- mockUserStore . add . mockResolvedValue ( undefined )
173- mockCredentialStore . add . mockRejectedValue ( new Error ( 'Credential store error' ) )
174- mockUserStore . remove . mockRejectedValue ( new Error ( 'Cleanup failed' ) )
172+ mockUserDataSet . get . mockResolvedValue ( null )
173+ mockUserDataSet . add . mockResolvedValue ( undefined )
174+ mockCredentialDataSet . add . mockRejectedValue ( new Error ( 'Credential store error' ) )
175+ mockUserDataSet . remove . mockRejectedValue ( new Error ( 'Cleanup failed' ) )
175176
176177 await usingAsync ( injector , async ( i ) => {
177178 try {
@@ -185,8 +186,7 @@ describe('RegisterAction', () => {
185186 } catch ( error ) {
186187 expect ( error ) . toBeInstanceOf ( RequestError )
187188 expect ( ( error as RequestError ) . responseCode ) . toBe ( 400 )
188- // Cleanup was attempted even though it failed
189- expect ( mockUserStore . remove ) . toHaveBeenCalledWith ( 'newuser' )
189+ expect ( mockUserDataSet . remove ) . toHaveBeenCalledWith ( i , 'newuser' )
190190 }
191191 } )
192192 } )
0 commit comments