@@ -43,7 +43,7 @@ class LoginManagerTests: XCTestCase, ViewControllerCompatibleTest {
4343    } 
4444
4545    override func  tearDown( )  async  throws  { 
46-         LoginManager . shared. reset ( ) 
46+         LoginManager . shared. resetForTesting ( ) 
4747        resetViewController ( ) 
4848    } 
4949
@@ -54,7 +54,147 @@ class LoginManagerTests: XCTestCase, ViewControllerCompatibleTest {
5454
5555        XCTAssertTrue ( LoginManager . shared. isSetupFinished) 
5656    } 
57-     
57+ 
58+     func  testResetLoginManager( )  { 
59+         // Ensure LoginManager is properly set up first
60+         XCTAssertTrue ( LoginManager . shared. isSetupFinished) 
61+         XCTAssertNotNil ( Session . shared) 
62+         XCTAssertNotNil ( AccessTokenStore . shared) 
63+         XCTAssertNotNil ( LoginConfiguration . shared) 
64+ 
65+         // Test resetting without active login process
66+         LoginManager . shared. reset ( ) 
67+ 
68+         // After reset, all shared instances should be nil and setup should be false
69+         XCTAssertFalse ( LoginManager . shared. isSetupFinished) 
70+         XCTAssertNil ( Session . _shared) 
71+         XCTAssertNil ( AccessTokenStore . _shared) 
72+         XCTAssertNil ( LoginConfiguration . _shared) 
73+ 
74+         // Test that we can reconfigure after reset
75+         let  newURL  =  URL ( string:  " https://newexample.com/auth " ) 
76+         LoginManager . shared. setup ( channelID:  " 456 " ,  universalLinkURL:  newURL) 
77+ 
78+         // After reconfiguration, instances should exist again
79+         XCTAssertTrue ( LoginManager . shared. isSetupFinished) 
80+         XCTAssertNotNil ( Session . shared) 
81+         XCTAssertNotNil ( AccessTokenStore . shared) 
82+         XCTAssertNotNil ( LoginConfiguration . shared) 
83+         XCTAssertEqual ( LoginConfiguration . shared. channelID,  " 456 " ) 
84+         XCTAssertEqual ( LoginConfiguration . shared. universalLinkURL,  newURL) 
85+     } 
86+ 
87+     func  testResetLoginManagerWithActiveProcess( )  { 
88+         let  expect  =  expectation ( description:  " \( #file) _ \( #line) " ) 
89+ 
90+         // Mock a session that will never respond (to keep login process active)
91+         let  delegateStub  =  SessionDelegateStub ( stubs:  [ ] ) 
92+         Session . _shared =  Session ( 
93+             configuration:  LoginConfiguration . shared, 
94+             delegate:  delegateStub
95+         ) 
96+ 
97+         // Start a login process but don't complete it
98+         var  process :  LoginProcess ! 
99+         process =  LoginManager . shared. login ( permissions:  [ . profile] ,  in:  setupViewController ( ) )  {  loginResult in 
100+             // This callback should receive a loginManagerReset error
101+             XCTAssertNotNil ( loginResult. error) 
102+             if  let  error =  loginResult. error { 
103+                 if  case . generalError( let  reason)  =  error { 
104+                     if  case . loginManagerReset =  reason { 
105+                         // Expected error when reset is called during login
106+                         expect. fulfill ( ) 
107+                     }  else  { 
108+                         XCTFail ( " Expected loginManagerReset error, got:  \( reason) " ) 
109+                     } 
110+                 }  else  { 
111+                     XCTFail ( " Expected generalError with loginManagerReset, got:  \( error) " ) 
112+                 } 
113+             } 
114+         } 
115+ 
116+         // Verify process is active
117+         XCTAssertNotNil ( process) 
118+         XCTAssertTrue ( LoginManager . shared. isAuthorizing) 
119+ 
120+         // Reset the login manager while process is active
121+         LoginManager . shared. reset ( ) 
122+ 
123+         // After reset, no process should be active and setup should be false
124+         XCTAssertFalse ( LoginManager . shared. isSetupFinished) 
125+         XCTAssertFalse ( LoginManager . shared. isAuthorizing) 
126+ 
127+         waitForExpectations ( timeout:  1 ,  handler:  nil ) 
128+ 
129+         // Re-setup after reset to avoid tearDown issues
130+         let  url  =  URL ( string:  " https://example.com/auth " ) 
131+         LoginManager . shared. setup ( channelID:  " 123 " ,  universalLinkURL:  url) 
132+     } 
133+ 
134+     func  testResetKeepsTokenScopedByChannel( )  { 
135+         let  loginExpectation  =  expectation ( description:  " \( #file) _ \( #line) _login " ) 
136+ 
137+         let  delegateStub  =  SessionDelegateStub ( stubs:  [ 
138+             . init( data:  PostExchangeTokenRequest . successData,  responseCode:  200 ) , 
139+             . init( data:  GetUserProfileRequest . successData,  responseCode:  200 ) 
140+         ] ) 
141+         Session . _shared =  Session ( 
142+             configuration:  LoginConfiguration . shared, 
143+             delegate:  delegateStub
144+         ) 
145+ 
146+         let  viewController  =  setupViewController ( ) 
147+         var  process :  LoginProcess ! 
148+         var  capturedToken :  AccessToken ? 
149+         process =  LoginManager . shared. login ( permissions:  [ . profile] ,  in:  viewController)  {  result in 
150+             switch  result { 
151+             case  . success( let  loginResult) : 
152+                 capturedToken =  loginResult. accessToken
153+                 XCTAssertEqual ( loginResult. accessToken. value,  PostExchangeTokenRequest . successToken) 
154+                 XCTAssertEqual ( AccessTokenStore . shared. current? . value,  PostExchangeTokenRequest . successToken) 
155+             case  . failure( let  error) : 
156+                 XCTFail ( " Unexpected failure:  \( error) " ) 
157+             } 
158+ 
159+             loginExpectation. fulfill ( ) 
160+         } !
161+ 
162+         process. appUniversalLinkFlow =  AppUniversalLinkFlow ( parameter:  sampleFlowParameters) 
163+ 
164+         DispatchQueue . main. asyncAfter ( deadline:  . now( )  +  0.1 )  { 
165+             let  urlString  =  " \( Constant . thirdPartyAppReturnURL) ?code=123&state= \( process. processID) " 
166+             let  handled  =  process. resumeOpenURL ( url:  URL ( string:  urlString) !) 
167+             XCTAssertTrue ( handled) 
168+         } 
169+ 
170+         waitForExpectations ( timeout:  2 ,  handler:  nil ) 
171+ 
172+         guard  let  token =  capturedToken else  { 
173+             XCTFail ( " Token should be captured after login " ) 
174+             return 
175+         } 
176+ 
177+         // After reset, in-memory singletons are cleared but the keychain token remains.
178+         LoginManager . shared. reset ( ) 
179+         XCTAssertFalse ( LoginManager . shared. isSetupFinished) 
180+         XCTAssertNil ( LoginConfiguration . _shared) 
181+         XCTAssertNil ( Session . _shared) 
182+         XCTAssertNil ( AccessTokenStore . _shared) 
183+ 
184+         // Setup with a different channel should not see the previous token.
185+         let  secondaryURL  =  URL ( string:  " https://alternate.example.com/auth " ) 
186+         LoginManager . shared. setup ( channelID:  " 456 " ,  universalLinkURL:  secondaryURL) 
187+         XCTAssertTrue ( LoginManager . shared. isSetupFinished) 
188+         XCTAssertNil ( AccessTokenStore . shared. current) 
189+ 
190+         // Reset again to switch back to the original channel.
191+         LoginManager . shared. reset ( ) 
192+ 
193+         let  primaryURL  =  URL ( string:  " https://example.com/auth " ) 
194+         LoginManager . shared. setup ( channelID:  " 123 " ,  universalLinkURL:  primaryURL) 
195+         XCTAssertEqual ( AccessTokenStore . shared. current? . value,  token. value) 
196+     } 
197+ 
58198    func  testLoginAction( )  { 
59199        let  expect  =  expectation ( description:  " \( #file) _ \( #line) " ) 
60200
@@ -349,7 +489,7 @@ class LoginManagerTests: XCTestCase, ViewControllerCompatibleTest {
349489        let  mockAccessToken  =  try ! JSONDecoder ( ) . decode ( AccessToken . self,  from:  PostExchangeTokenRequest . successData) 
350490
351491        // Create JWK from test RSA public key that matches the test JWT token
352-         let  testRSAPublicKeyPEM  =  """ 
492+         /*  let testRSAPublicKeyPEM */ _  =  """ 
353493        -----BEGIN PUBLIC KEY----- 
354494        MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdlatRjRjogo3WojgGHFHYLugd 
355495        UWAY9iR3fy4arWNA1KoS8kVw33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQs 
@@ -823,4 +963,3 @@ class LoginManagerTests: XCTestCase, ViewControllerCompatibleTest {
823963    } 
824964
825965} 
826- 
0 commit comments