@@ -106,6 +106,13 @@ def test_client_explicit_app(self):
106106 client = fpnv .client (app )
107107 assert isinstance (client , fpnv .FpnvClient )
108108
109+ def test_client_illegal_app_argument_wrong_app_type (self ):
110+ cred = testutils .MockCredential ()
111+ app = ""
112+ with pytest .raises (ValueError , match = 'Illegal app argument. Argument must be of type firebase_admin.App, but given '
113+ f'"{ type (app )} ".' ):
114+ client = fpnv .client (app )
115+
109116
110117class TestVerifyToken (TestCommon ):
111118
@@ -198,6 +205,14 @@ def test_verify_token_success(self, mock_header, mock_decode, mock_jwks_cls, cli
198205 issuer = _ISSUER
199206 )
200207
208+ @mock .patch ('jwt.get_unverified_header' )
209+ def test_verify_token_no_name (self , mock_header ):
210+ app = firebase_admin .get_app ()
211+ client = fpnv .client (app )
212+ mock_header .return_value = {'kid' : 'k' , 'typ' : 'JWT' , 'alg' : 'ES256' }
213+ with pytest .raises (ValueError , match = "must be a non-empty string" ):
214+ client .verify_token ('' )
215+
201216 @mock .patch ('jwt.get_unverified_header' )
202217 def test_verify_token_no_kid (self , mock_header ):
203218 app = firebase_admin .get_app ()
@@ -212,6 +227,12 @@ def test_verify_token_wrong_alg(self, mock_header, client):
212227 with pytest .raises (ValueError , match = "incorrect alg" ):
213228 client .verify_token ('token' )
214229
230+ @mock .patch ('jwt.get_unverified_header' )
231+ def test_verify_token_wrong_typ (self , mock_header , client ):
232+ mock_header .return_value = {'kid' : 'k' , 'typ' : 'WRONG' , 'alg' : 'ES256' } # wrong typ
233+ with pytest .raises (ValueError , match = "incorrect type header" ):
234+ client .verify_token ('token' )
235+
215236 def test_verify_token_jwk_error (self , client ):
216237 # Access the ACTUAL client instance used by the verifier
217238 # (Assuming internal structure: client -> _verifier -> _jwks_client)
@@ -243,6 +264,21 @@ def test_verify_token_expired(self, mock_header, mock_decode, mock_jwks_cls, cli
243264 with pytest .raises (ValueError , match = "token has expired" ):
244265 client .verify_token ('token' )
245266
267+ @mock .patch ('jwt.PyJWKClient' )
268+ @mock .patch ('jwt.decode' )
269+ @mock .patch ('jwt.get_unverified_header' )
270+ def test_verify_token_invalid_signature (self , mock_header , mock_decode , mock_jwks_cls , client ):
271+ mock_header .return_value = {'kid' : 'k' , 'typ' : 'JWT' , 'alg' : 'ES256' }
272+ mock_jwks_instance = mock_jwks_cls .return_value
273+ mock_jwks_instance .get_signing_key_from_jwt .return_value .key = _PUBLIC_KEY
274+ client ._verifier ._jwks_client = mock_jwks_instance
275+
276+ # Simulate InvalidSignatureError
277+ mock_decode .side_effect = jwt .InvalidSignatureError ("Wrong Signature" )
278+
279+ with pytest .raises (ValueError , match = "invalid signature" ):
280+ client .verify_token ('token' )
281+
246282 @mock .patch ('jwt.PyJWKClient' )
247283 @mock .patch ('jwt.decode' )
248284 @mock .patch ('jwt.get_unverified_header' )
@@ -272,3 +308,18 @@ def test_verify_token_invalid_issuer(self, mock_header, mock_decode, mock_jwks_c
272308
273309 with pytest .raises (ValueError , match = "incorrect \" iss\" " ):
274310 client .verify_token ('token' )
311+
312+ @mock .patch ('jwt.PyJWKClient' )
313+ @mock .patch ('jwt.decode' )
314+ @mock .patch ('jwt.get_unverified_header' )
315+ def test_verify_token_invalid_token (self , mock_header , mock_decode , mock_jwks_cls , client ):
316+ mock_header .return_value = {'kid' : 'k' , 'typ' : 'JWT' , 'alg' : 'ES256' }
317+ mock_jwks_instance = mock_jwks_cls .return_value
318+ mock_jwks_instance .get_signing_key_from_jwt .return_value .key = _PUBLIC_KEY
319+ client ._verifier ._jwks_client = mock_jwks_instance
320+
321+ # Simulate InvalidTokenError
322+ mock_decode .side_effect = jwt .InvalidTokenError ("Decoding FPNV token failed" )
323+
324+ with pytest .raises (ValueError , match = "incorrect \" iss\" " ):
325+ client .verify_token ('token' )
0 commit comments