1
1
import '@testing-library/jest-dom' ;
2
2
import { render , waitFor } from '@testing-library/react' ;
3
3
import React from 'react' ;
4
- import { getAccessTokenAction } from '../src/actions.js' ;
5
4
import { useAuth } from '../src/components/authkit-provider.js' ;
6
- import { useCustomClaims } from '../src/components/useCustomClaims.js' ;
7
5
8
6
jest . mock ( '../src/actions.js' , ( ) => ( {
9
7
getAccessTokenAction : jest . fn ( ) ,
@@ -18,20 +16,31 @@ jest.mock('../src/components/authkit-provider.js', () => {
18
16
} ;
19
17
} ) ;
20
18
19
+ jest . mock ( '../src/components/useAccessToken.js' , ( ) => ( {
20
+ useAccessToken : jest . fn ( ( ) => ( { accessToken : undefined } ) ) ,
21
+ } ) ) ;
22
+
21
23
jest . mock ( 'jose' , ( ) => ( {
22
24
decodeJwt : jest . fn ( ( token : string ) => {
25
+ if ( token === 'malformed-token' || token === 'throw-error-token' ) {
26
+ throw new Error ( 'Invalid JWT' ) ;
27
+ }
23
28
try {
24
29
const parts = token . split ( '.' ) ;
25
- if ( parts . length !== 3 ) return null ;
30
+ if ( parts . length !== 3 ) throw new Error ( 'Invalid JWT' ) ;
26
31
const payload = JSON . parse ( atob ( parts [ 1 ] ) ) ;
27
32
return payload ;
28
33
} catch {
29
- return null ;
34
+ throw new Error ( 'Invalid JWT' ) ;
30
35
}
31
36
} ) ,
32
37
} ) ) ;
33
38
34
- describe ( 'useCustomClaims' , ( ) => {
39
+ // Import after mocks are set up
40
+ import { useAccessToken } from '../src/components/useAccessToken.js' ;
41
+ import { useTokenClaims } from '../src/components/useTokenClaims.js' ;
42
+
43
+ describe ( 'useTokenClaims' , ( ) => {
35
44
beforeEach ( ( ) => {
36
45
jest . clearAllMocks ( ) ;
37
46
jest . useFakeTimers ( ) ;
@@ -41,32 +50,35 @@ describe('useCustomClaims', () => {
41
50
sessionId : 'session_123' ,
42
51
refreshAuth : jest . fn ( ) . mockResolvedValue ( { } ) ,
43
52
} ) ) ;
53
+
54
+ // Reset useAccessToken mock to default
55
+ ( useAccessToken as jest . Mock ) . mockReturnValue ( { accessToken : undefined } ) ;
44
56
} ) ;
45
57
46
58
afterEach ( ( ) => {
47
59
jest . useRealTimers ( ) ;
48
60
} ) ;
49
61
50
- const CustomClaimsTestComponent = ( ) => {
51
- const customClaims = useCustomClaims ( ) ;
62
+ const TokenClaimsTestComponent = ( ) => {
63
+ const tokenClaims = useTokenClaims ( ) ;
52
64
return (
53
65
< div >
54
- < div data-testid = "claims" > { JSON . stringify ( customClaims ) } </ div >
66
+ < div data-testid = "claims" > { JSON . stringify ( tokenClaims ) } </ div >
55
67
</ div >
56
68
) ;
57
69
} ;
58
70
59
- it ( 'should return null when no access token is available' , async ( ) => {
60
- ( getAccessTokenAction as jest . Mock ) . mockResolvedValue ( undefined ) ;
71
+ it ( 'should return empty object when no access token is available' , async ( ) => {
72
+ ( useAccessToken as jest . Mock ) . mockReturnValue ( { accessToken : undefined } ) ;
61
73
62
- const { getByTestId } = render ( < CustomClaimsTestComponent /> ) ;
74
+ const { getByTestId } = render ( < TokenClaimsTestComponent /> ) ;
63
75
64
76
await waitFor ( ( ) => {
65
- expect ( getByTestId ( 'claims' ) ) . toHaveTextContent ( 'null ' ) ;
77
+ expect ( getByTestId ( 'claims' ) ) . toHaveTextContent ( '{} ' ) ;
66
78
} ) ;
67
79
} ) ;
68
80
69
- it ( 'should return custom claims when access token is available' , async ( ) => {
81
+ it ( 'should return all token claims when access token is available' , async ( ) => {
70
82
const payload = {
71
83
aud : 'audience' ,
72
84
exp : 9999999999 ,
@@ -87,21 +99,16 @@ describe('useCustomClaims', () => {
87
99
} ;
88
100
const token = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.${ btoa ( JSON . stringify ( payload ) ) } .mock-signature` ;
89
101
90
- ( getAccessTokenAction as jest . Mock ) . mockResolvedValue ( token ) ;
102
+ ( useAccessToken as jest . Mock ) . mockReturnValue ( { accessToken : token } ) ;
91
103
92
- const { getByTestId } = render ( < CustomClaimsTestComponent /> ) ;
104
+ const { getByTestId } = render ( < TokenClaimsTestComponent /> ) ;
93
105
94
106
await waitFor ( ( ) => {
95
- const expectedCustomClaims = {
96
- customField1 : 'value1' ,
97
- customField2 : 42 ,
98
- customObject : { nested : 'data' } ,
99
- } ;
100
- expect ( getByTestId ( 'claims' ) ) . toHaveTextContent ( JSON . stringify ( expectedCustomClaims ) ) ;
107
+ expect ( getByTestId ( 'claims' ) ) . toHaveTextContent ( JSON . stringify ( payload ) ) ;
101
108
} ) ;
102
109
} ) ;
103
110
104
- it ( 'should return empty object when token has no custom claims' , async ( ) => {
111
+ it ( 'should return all standard claims when token has only standard claims' , async ( ) => {
105
112
const payload = {
106
113
aud : 'audience' ,
107
114
exp : 9999999999 ,
@@ -118,16 +125,16 @@ describe('useCustomClaims', () => {
118
125
} ;
119
126
const token = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.${ btoa ( JSON . stringify ( payload ) ) } .mock-signature` ;
120
127
121
- ( getAccessTokenAction as jest . Mock ) . mockResolvedValue ( token ) ;
128
+ ( useAccessToken as jest . Mock ) . mockReturnValue ( { accessToken : token } ) ;
122
129
123
- const { getByTestId } = render ( < CustomClaimsTestComponent /> ) ;
130
+ const { getByTestId } = render ( < TokenClaimsTestComponent /> ) ;
124
131
125
132
await waitFor ( ( ) => {
126
- expect ( getByTestId ( 'claims' ) ) . toHaveTextContent ( '{}' ) ;
133
+ expect ( getByTestId ( 'claims' ) ) . toHaveTextContent ( JSON . stringify ( payload ) ) ;
127
134
} ) ;
128
135
} ) ;
129
136
130
- it ( 'should handle partial standard claims' , async ( ) => {
137
+ it ( 'should handle partial claims' , async ( ) => {
131
138
const payload = {
132
139
sub : 'user_123' ,
133
140
exp : 9999999999 ,
@@ -136,20 +143,16 @@ describe('useCustomClaims', () => {
136
143
} ;
137
144
const token = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.${ btoa ( JSON . stringify ( payload ) ) } .mock-signature` ;
138
145
139
- ( getAccessTokenAction as jest . Mock ) . mockResolvedValue ( token ) ;
146
+ ( useAccessToken as jest . Mock ) . mockReturnValue ( { accessToken : token } ) ;
140
147
141
- const { getByTestId } = render ( < CustomClaimsTestComponent /> ) ;
148
+ const { getByTestId } = render ( < TokenClaimsTestComponent /> ) ;
142
149
143
150
await waitFor ( ( ) => {
144
- const expectedCustomClaims = {
145
- customField : 'value' ,
146
- anotherCustom : true ,
147
- } ;
148
- expect ( getByTestId ( 'claims' ) ) . toHaveTextContent ( JSON . stringify ( expectedCustomClaims ) ) ;
151
+ expect ( getByTestId ( 'claims' ) ) . toHaveTextContent ( JSON . stringify ( payload ) ) ;
149
152
} ) ;
150
153
} ) ;
151
154
152
- it ( 'should handle complex nested custom claims' , async ( ) => {
155
+ it ( 'should handle complex nested claims' , async ( ) => {
153
156
const payload = {
154
157
sub : 'user_123' ,
155
158
exp : 9999999999 ,
@@ -168,26 +171,22 @@ describe('useCustomClaims', () => {
168
171
} ;
169
172
const token = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.${ btoa ( JSON . stringify ( payload ) ) } .mock-signature` ;
170
173
171
- ( getAccessTokenAction as jest . Mock ) . mockResolvedValue ( token ) ;
174
+ ( useAccessToken as jest . Mock ) . mockReturnValue ( { accessToken : token } ) ;
172
175
173
- const { getByTestId } = render ( < CustomClaimsTestComponent /> ) ;
176
+ const { getByTestId } = render ( < TokenClaimsTestComponent /> ) ;
174
177
175
178
await waitFor ( ( ) => {
176
- const expectedCustomClaims = {
177
- metadata : {
178
- preferences : {
179
- theme : 'dark' ,
180
- language : 'en' ,
181
- } ,
182
- settings : [ 'setting1' , 'setting2' ] ,
183
- } ,
184
- tags : [ 'tag1' , 'tag2' ] ,
185
- permissions_custom : {
186
- read : true ,
187
- write : false ,
188
- } ,
189
- } ;
190
- expect ( getByTestId ( 'claims' ) ) . toHaveTextContent ( JSON . stringify ( expectedCustomClaims ) ) ;
179
+ expect ( getByTestId ( 'claims' ) ) . toHaveTextContent ( JSON . stringify ( payload ) ) ;
180
+ } ) ;
181
+ } ) ;
182
+
183
+ it ( 'should return empty object when decodeJwt throws an error' , async ( ) => {
184
+ ( useAccessToken as jest . Mock ) . mockReturnValue ( { accessToken : 'malformed-token' } ) ;
185
+
186
+ const { getByTestId } = render ( < TokenClaimsTestComponent /> ) ;
187
+
188
+ await waitFor ( ( ) => {
189
+ expect ( getByTestId ( 'claims' ) ) . toHaveTextContent ( '{}' ) ;
191
190
} ) ;
192
191
} ) ;
193
192
} ) ;
0 commit comments