@@ -59,51 +59,71 @@ describe('State', () => {
5959 expect ( signUpResourceSignal ( ) . resource ?. id ) . toBe ( 'signup_123' ) ;
6060 } ) ;
6161
62- it ( 'should allow null resource update when previous resource exists and canBeDiscarded is true' , ( ) => {
63- // Arrange: Set up a SignUp with id
62+ it ( 'should allow null resource update when previous resource exists and canBeDiscarded is true' , async ( ) => {
63+ // Arrange: Set up a SignUp with id and mock setActive
64+ const mockSetActive = vi . fn ( ) . mockResolvedValue ( { } ) ;
65+ SignUp . clerk = { setActive : mockSetActive } as any ;
66+
6467 const existingSignUp = new SignUp ( {
6568 id : 'signup_123' ,
6669 status : 'complete' ,
6770 created_session_id : 'session_123' ,
6871 } as any ) ;
6972 expect ( signUpResourceSignal ( ) . resource ) . toBe ( existingSignUp ) ;
73+ expect ( existingSignUp . __internal_future . canBeDiscarded ) . toBe ( false ) ;
7074
71- // Simulate finalize() being called - which sets canBeDiscarded to true
72- // We need to access the private field, so we'll use a workaround
73- // by calling the internal method that sets it
74- const mockSetActive = vi . fn ( ) . mockResolvedValue ( { } ) ;
75- SignUp . clerk = { setActive : mockSetActive } as any ;
75+ // Act: Call finalize() which sets canBeDiscarded to true
76+ await existingSignUp . __internal_future . finalize ( ) ;
77+
78+ // Verify canBeDiscarded is now true
79+ expect ( existingSignUp . __internal_future . canBeDiscarded ) . toBe ( true ) ;
80+ expect ( mockSetActive ) . toHaveBeenCalledWith ( { session : 'session_123' , navigate : undefined } ) ;
7681
77- // Note: We can't easily call finalize() here because it's async and calls setActive
78- // Instead, let's directly test the scenario by creating a new SignUp and checking behavior
82+ // Now emit a null resource update (simulating client refresh with null sign_up)
83+ const nullSignUp = new SignUp ( null ) ;
7984
80- // For this test, we'll verify the opposite case is working
81- // The null update should be blocked when canBeDiscarded is false
85+ // Assert: The null update SHOULD be allowed because canBeDiscarded is true
86+ // shouldIgnoreNullUpdate returns false when canBeDiscarded is true
87+ expect ( signUpResourceSignal ( ) . resource ) . toBe ( nullSignUp ) ;
88+ expect ( signUpResourceSignal ( ) . resource ?. id ) . toBeUndefined ( ) ;
8289 } ) ;
8390
8491 it ( 'should allow null resource update after reset() is called' , async ( ) => {
85- // Arrange: Set up mock client
92+ // Arrange: Set up mock client that tracks the new SignUp created during reset
93+ let newSignUpFromReset : SignUp | null = null ;
8694 const mockClient = {
8795 signUp : new SignUp ( null ) ,
8896 resetSignUp : vi . fn ( ) . mockImplementation ( function ( this : typeof mockClient ) {
89- const newSignUp = new SignUp ( null ) ;
90- this . signUp = newSignUp ;
91- eventBus . emit ( 'resource:error' , { resource : newSignUp , error : null } ) ;
97+ newSignUpFromReset = new SignUp ( null ) ;
98+ this . signUp = newSignUpFromReset ;
99+ // reset() emits resource:error to clear errors, but the signal update
100+ // happens via resource:update when the new SignUp is created
101+ eventBus . emit ( 'resource:error' , { resource : newSignUpFromReset , error : null } ) ;
102+ // Emit resource:update to update the signal (simulating what happens in real flow)
103+ eventBus . emit ( 'resource:update' , { resource : newSignUpFromReset } ) ;
92104 } ) ,
93105 } ;
94106 SignUp . clerk = { client : mockClient } as any ;
95107
96108 // Create a SignUp with id
97109 const existingSignUp = new SignUp ( { id : 'signup_123' , status : 'missing_requirements' } as any ) ;
98110 expect ( signUpResourceSignal ( ) . resource ?. id ) . toBe ( 'signup_123' ) ;
111+ expect ( existingSignUp . __internal_future . canBeDiscarded ) . toBe ( false ) ;
99112
100113 // Act: Call reset() - this sets canBeDiscarded to true before resetting
101114 await existingSignUp . __internal_future . reset ( ) ;
102115
103- // Assert: After reset, the signal should have a new null SignUp
104- // Note: reset() calls client.resetSignUp() which emits resource:error, not resource:update
105- // So the signal update happens through a different path
116+ // Assert: Verify reset was called
106117 expect ( mockClient . resetSignUp ) . toHaveBeenCalled ( ) ;
118+
119+ // Assert: Verify canBeDiscarded was set to true on the original SignUp
120+ expect ( existingSignUp . __internal_future . canBeDiscarded ) . toBe ( true ) ;
121+
122+ // Assert: Verify the signal was updated with a new SignUp that has no id
123+ // The previous id 'signup_123' should be gone
124+ expect ( signUpResourceSignal ( ) . resource ) . toBe ( newSignUpFromReset ) ;
125+ expect ( signUpResourceSignal ( ) . resource ?. id ) . toBeUndefined ( ) ;
126+ expect ( signUpResourceSignal ( ) . resource ) . not . toBe ( existingSignUp ) ;
107127 } ) ;
108128
109129 it ( 'should allow resource update when new resource has an id (not a null update)' , ( ) => {
0 commit comments