@@ -31,16 +31,16 @@ describe("API Client - callISBAPI", () => {
3131 "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlRlc3QgVXNlciIsImlhdCI6MTUxNjIzOTAyMn0.test"
3232
3333 beforeEach ( ( ) => {
34- // Clear mocks and sessionStorage before each test
34+ // Clear mocks and localStorage before each test
3535 mockFetch . mockReset ( )
3636 mockFetch . mockResolvedValue ( createMockResponse ( ) )
37- sessionStorage . clear ( )
37+ localStorage . clear ( )
3838 } )
3939
4040 describe ( "AC #1: Authorization Header Injection" , ( ) => {
41- it ( "should add Authorization header when JWT token exists in sessionStorage " , async ( ) => {
42- // Arrange: Set token in sessionStorage
43- sessionStorage . setItem ( _internal . JWT_TOKEN_KEY , TEST_TOKEN )
41+ it ( "should add Authorization header when JWT token exists in localStorage " , async ( ) => {
42+ // Arrange: Set token in localStorage
43+ localStorage . setItem ( _internal . JWT_TOKEN_KEY , TEST_TOKEN )
4444
4545 // Act: Make API call
4646 await callISBAPI ( "/api/leases" )
@@ -53,7 +53,7 @@ describe("API Client - callISBAPI", () => {
5353
5454 it ( "should use correct Bearer token format" , async ( ) => {
5555 // Arrange
56- sessionStorage . setItem ( _internal . JWT_TOKEN_KEY , TEST_TOKEN )
56+ localStorage . setItem ( _internal . JWT_TOKEN_KEY , TEST_TOKEN )
5757
5858 // Act
5959 await callISBAPI ( "/api/test" )
@@ -68,7 +68,7 @@ describe("API Client - callISBAPI", () => {
6868 describe ( "AC #2: Conditional Header Behavior" , ( ) => {
6969 it ( "should preserve custom headers alongside Authorization header" , async ( ) => {
7070 // Arrange
71- sessionStorage . setItem ( _internal . JWT_TOKEN_KEY , TEST_TOKEN )
71+ localStorage . setItem ( _internal . JWT_TOKEN_KEY , TEST_TOKEN )
7272 const customHeaders = {
7373 "X-Custom-Header" : "custom-value" ,
7474 "X-Another-Header" : "another-value" ,
@@ -86,7 +86,7 @@ describe("API Client - callISBAPI", () => {
8686
8787 it ( "should include default Content-Type header" , async ( ) => {
8888 // Arrange
89- sessionStorage . setItem ( _internal . JWT_TOKEN_KEY , TEST_TOKEN )
89+ localStorage . setItem ( _internal . JWT_TOKEN_KEY , TEST_TOKEN )
9090
9191 // Act
9292 await callISBAPI ( "/api/test" )
@@ -98,7 +98,7 @@ describe("API Client - callISBAPI", () => {
9898
9999 it ( "should allow custom Content-Type to override default" , async ( ) => {
100100 // Arrange
101- sessionStorage . setItem ( _internal . JWT_TOKEN_KEY , TEST_TOKEN )
101+ localStorage . setItem ( _internal . JWT_TOKEN_KEY , TEST_TOKEN )
102102
103103 // Act
104104 await callISBAPI ( "/api/test" , {
@@ -112,7 +112,7 @@ describe("API Client - callISBAPI", () => {
112112
113113 it ( "should preserve other fetch options (method, body, etc.)" , async ( ) => {
114114 // Arrange
115- sessionStorage . setItem ( _internal . JWT_TOKEN_KEY , TEST_TOKEN )
115+ localStorage . setItem ( _internal . JWT_TOKEN_KEY , TEST_TOKEN )
116116 const requestBody = JSON . stringify ( { productId : "123" } )
117117
118118 // Act
@@ -131,8 +131,8 @@ describe("API Client - callISBAPI", () => {
131131
132132 describe ( "AC #3: No Token Behavior" , ( ) => {
133133 it ( "should NOT add Authorization header when token is missing" , async ( ) => {
134- // Arrange: No token in sessionStorage
135- sessionStorage . clear ( )
134+ // Arrange: No token in localStorage
135+ localStorage . clear ( )
136136
137137 // Act
138138 await callISBAPI ( "/api/public" )
@@ -145,7 +145,7 @@ describe("API Client - callISBAPI", () => {
145145
146146 it ( "should NOT add Authorization header when token is empty string" , async ( ) => {
147147 // Arrange: Empty string token
148- sessionStorage . setItem ( _internal . JWT_TOKEN_KEY , "" )
148+ localStorage . setItem ( _internal . JWT_TOKEN_KEY , "" )
149149
150150 // Act
151151 await callISBAPI ( "/api/test" )
@@ -157,15 +157,15 @@ describe("API Client - callISBAPI", () => {
157157
158158 it ( "should not throw error when token is missing" , async ( ) => {
159159 // Arrange
160- sessionStorage . clear ( )
160+ localStorage . clear ( )
161161
162162 // Act & Assert: Should not throw
163163 await expect ( callISBAPI ( "/api/test" ) ) . resolves . toBeDefined ( )
164164 } )
165165
166166 it ( "should still include Content-Type when unauthenticated" , async ( ) => {
167167 // Arrange
168- sessionStorage . clear ( )
168+ localStorage . clear ( )
169169
170170 // Act
171171 await callISBAPI ( "/api/test" )
@@ -202,7 +202,7 @@ describe("API Client - callISBAPI", () => {
202202 describe ( "Headers extraction" , ( ) => {
203203 it ( "should handle Headers object input" , async ( ) => {
204204 // Arrange
205- sessionStorage . setItem ( _internal . JWT_TOKEN_KEY , TEST_TOKEN )
205+ localStorage . setItem ( _internal . JWT_TOKEN_KEY , TEST_TOKEN )
206206 const headers = new Headers ( )
207207 headers . set ( "X-Custom" , "value" )
208208
@@ -216,7 +216,7 @@ describe("API Client - callISBAPI", () => {
216216
217217 it ( "should handle array of header pairs" , async ( ) => {
218218 // Arrange
219- sessionStorage . setItem ( _internal . JWT_TOKEN_KEY , TEST_TOKEN )
219+ localStorage . setItem ( _internal . JWT_TOKEN_KEY , TEST_TOKEN )
220220 const headers : [ string , string ] [ ] = [
221221 [ "X-First" , "first-value" ] ,
222222 [ "X-Second" , "second-value" ] ,
@@ -236,11 +236,11 @@ describe("API Client - callISBAPI", () => {
236236describe ( "Internal helpers" , ( ) => {
237237 describe ( "getToken" , ( ) => {
238238 beforeEach ( ( ) => {
239- sessionStorage . clear ( )
239+ localStorage . clear ( )
240240 } )
241241
242242 it ( "should return token when present" , ( ) => {
243- sessionStorage . setItem ( _internal . JWT_TOKEN_KEY , "test-token" )
243+ localStorage . setItem ( _internal . JWT_TOKEN_KEY , "test-token" )
244244 expect ( _internal . getToken ( ) ) . toBe ( "test-token" )
245245 } )
246246
@@ -249,7 +249,7 @@ describe("Internal helpers", () => {
249249 } )
250250
251251 it ( "should return null for empty string token" , ( ) => {
252- sessionStorage . setItem ( _internal . JWT_TOKEN_KEY , "" )
252+ localStorage . setItem ( _internal . JWT_TOKEN_KEY , "" )
253253 expect ( _internal . getToken ( ) ) . toBeNull ( )
254254 } )
255255 } )
@@ -294,9 +294,9 @@ describe("API Client - checkAuthStatus", () => {
294294
295295 beforeEach ( ( ) => {
296296 mockFetch . mockReset ( )
297- sessionStorage . clear ( )
297+ localStorage . clear ( )
298298 // Set token for authenticated requests
299- sessionStorage . setItem ( _internal . JWT_TOKEN_KEY , TEST_TOKEN )
299+ localStorage . setItem ( _internal . JWT_TOKEN_KEY , TEST_TOKEN )
300300 // Suppress console.error for cleaner test output
301301 jest . spyOn ( console , "error" ) . mockImplementation ( ( ) => { } )
302302 } )
@@ -464,9 +464,9 @@ describe("API Client - checkAuthStatus", () => {
464464 } )
465465
466466 describe ( "Edge cases" , ( ) => {
467- it ( "should work when sessionStorage has no token" , async ( ) => {
467+ it ( "should work when localStorage has no token" , async ( ) => {
468468 // Arrange: Clear token
469- sessionStorage . clear ( )
469+ localStorage . clear ( )
470470 mockFetch . mockResolvedValueOnce ( createMockResponse ( '{"error": "Unauthorized"}' , 401 ) )
471471
472472 // Act
@@ -529,8 +529,8 @@ describe("API Client - 401 Handling (Story 5.8)", () => {
529529 beforeEach ( ( ) => {
530530 mockFetch . mockReset ( )
531531 mockFetch . mockResolvedValue ( createMockResponse ( ) )
532- sessionStorage . clear ( )
533- sessionStorage . setItem ( _internal . JWT_TOKEN_KEY , TEST_TOKEN )
532+ localStorage . clear ( )
533+ localStorage . setItem ( _internal . JWT_TOKEN_KEY , TEST_TOKEN )
534534
535535 // Set up location href spy using our custom jsdom environment helper
536536 locationSpy = setupLocationHrefSpy ( )
@@ -542,7 +542,7 @@ describe("API Client - 401 Handling (Story 5.8)", () => {
542542 } )
543543
544544 describe ( "AC #1: Automatic 401 Detection" , ( ) => {
545- it ( "should clear sessionStorage token when 401 received" , async ( ) => {
545+ it ( "should clear localStorage token when 401 received" , async ( ) => {
546546 // Arrange
547547 mockFetch . mockResolvedValueOnce ( createMockResponse ( '{"error": "Unauthorized"}' , 401 ) )
548548
@@ -554,7 +554,7 @@ describe("API Client - 401 Handling (Story 5.8)", () => {
554554 }
555555
556556 // Assert: Token should be cleared
557- expect ( sessionStorage . getItem ( _internal . JWT_TOKEN_KEY ) ) . toBeNull ( )
557+ expect ( localStorage . getItem ( _internal . JWT_TOKEN_KEY ) ) . toBeNull ( )
558558 } )
559559
560560 it ( "should detect 401 status code" , async ( ) => {
@@ -601,7 +601,7 @@ describe("API Client - 401 Handling (Story 5.8)", () => {
601601 describe ( "AC #4: No Infinite Loops" , ( ) => {
602602 it ( "should clear token before redirect (order verification)" , async ( ) => {
603603 // This test verifies the implementation order by checking the code flow:
604- // 1. Token is cleared first (via sessionStorage .removeItem)
604+ // 1. Token is cleared first (via localStorage .removeItem)
605605 // 2. Then redirect happens (via window.location.href)
606606 // We verify both happen, and since the code is sequential, clear happens first
607607
@@ -617,7 +617,7 @@ describe("API Client - 401 Handling (Story 5.8)", () => {
617617
618618 // Assert: Both actions happened
619619 // Token is cleared
620- expect ( sessionStorage . getItem ( _internal . JWT_TOKEN_KEY ) ) . toBeNull ( )
620+ expect ( localStorage . getItem ( _internal . JWT_TOKEN_KEY ) ) . toBeNull ( )
621621 // Redirect happened
622622 expect ( locationSpy ?. getRedirectUrl ( ) ) . toBe ( "/api/auth/login" )
623623 // The implementation clears before redirect (verified by code review)
@@ -635,7 +635,7 @@ describe("API Client - 401 Handling (Story 5.8)", () => {
635635 }
636636
637637 // Assert: Token cleared before redirect
638- expect ( sessionStorage . getItem ( _internal . JWT_TOKEN_KEY ) ) . toBeNull ( )
638+ expect ( localStorage . getItem ( _internal . JWT_TOKEN_KEY ) ) . toBeNull ( )
639639 expect ( locationSpy ?. getRedirectUrl ( ) ) . toBe ( "/api/auth/login" )
640640 } )
641641 } )
@@ -651,7 +651,7 @@ describe("API Client - 401 Handling (Story 5.8)", () => {
651651
652652 // Assert: Returns response normally
653653 expect ( response ) . toBe ( successResponse )
654- expect ( sessionStorage . getItem ( _internal . JWT_TOKEN_KEY ) ) . toBe ( TEST_TOKEN ) // Token not cleared
654+ expect ( localStorage . getItem ( _internal . JWT_TOKEN_KEY ) ) . toBe ( TEST_TOKEN ) // Token not cleared
655655 } )
656656
657657 it ( "should preserve existing behavior for 500 errors" , async ( ) => {
@@ -677,7 +677,7 @@ describe("API Client - 401 Handling (Story 5.8)", () => {
677677 // Assert: Should NOT redirect, should return response
678678 expect ( response . status ) . toBe ( 401 )
679679 expect ( locationSpy ?. getRedirectUrl ( ) ) . toBe ( "" ) // No redirect
680- expect ( sessionStorage . getItem ( _internal . JWT_TOKEN_KEY ) ) . toBe ( TEST_TOKEN ) // Token not cleared
680+ expect ( localStorage . getItem ( _internal . JWT_TOKEN_KEY ) ) . toBe ( TEST_TOKEN ) // Token not cleared
681681 } )
682682 } )
683683
@@ -702,7 +702,7 @@ describe("API Client - 401 Handling (Story 5.8)", () => {
702702 await checkAuthStatus ( )
703703
704704 // Assert: Token still present (checkAuthStatus uses skipAuthRedirect)
705- expect ( sessionStorage . getItem ( _internal . JWT_TOKEN_KEY ) ) . toBe ( TEST_TOKEN )
705+ expect ( localStorage . getItem ( _internal . JWT_TOKEN_KEY ) ) . toBe ( TEST_TOKEN )
706706 } )
707707 } )
708708} )
0 commit comments