Coverage for tests/test_auth.py: 100%

56 statements  

« prev     ^ index     » next       coverage.py v7.16.0, created at 2026-11-09 00:25 +0000

1import base64 1abcdefg

2import time 1abcdefg

3from pathlib import Path 1abcdefg

4 

5import pytest 1abcdefg

6 

7from fastapi_cloud_cli.utils.auth import ( 1abcdefg

8 AuthConfig, 

9 Identity, 

10 _is_jwt_expired, 

11 write_auth_config, 

12) 

13 

14from .utils import create_jwt_token 1abcdefg

15 

16 

17def test_is_jwt_expired_with_valid_token() -> None: 1abcdefg

18 future_exp = int(time.time()) + 3600 1CDEFGHI

19 

20 token = create_jwt_token({"exp": future_exp, "sub": "test_user"}) 1CDEFGHI

21 

22 assert not _is_jwt_expired(token) 1CDEFGHI

23 

24 

25def test_is_jwt_expired_with_expired_token() -> None: 1abcdefg

26 past_exp = int(time.time()) - 3600 1JKLMNOP

27 token = create_jwt_token({"exp": past_exp, "sub": "test_user"}) 1JKLMNOP

28 

29 assert _is_jwt_expired(token) 1JKLMNOP

30 

31 

32def test_is_jwt_expired_with_no_exp_claim() -> None: 1abcdefg

33 token = create_jwt_token({"sub": "test_user"}) 1456789!

34 

35 # Tokens without exp claim should be considered valid 

36 assert not _is_jwt_expired(token) 1456789!

37 

38 

39@pytest.mark.parametrize( 1abcdefg

40 "token", 

41 [ 

42 "not.a.valid.jwt.token", 

43 "only.two", 

44 "invalid", 

45 "", 

46 "...", 

47 ], 

48) 

49def test_is_jwt_expired_with_malformed_token(token: str) -> None: 1abcdefg

50 assert _is_jwt_expired(token) 2cbdbebfbgbhbib

51 

52 

53def test_is_jwt_expired_with_invalid_base64() -> None: 1abcdefg

54 token = "header.!!!invalid_signature!!!.signature" 1#$%'()*

55 assert _is_jwt_expired(token) 1#$%'()*

56 

57 

58def test_is_jwt_expired_with_invalid_json() -> None: 1abcdefg

59 header_encoded = base64.urlsafe_b64encode(b'{"alg":"HS256"}').decode().rstrip("=") 1hijklmn

60 payload_encoded = base64.urlsafe_b64encode(b"{invalid json}").decode().rstrip("=") 1hijklmn

61 signature = base64.urlsafe_b64encode(b"signature").decode().rstrip("=") 1hijklmn

62 token = f"{header_encoded}.{payload_encoded}.{signature}" 1hijklmn

63 

64 assert _is_jwt_expired(token) 1hijklmn

65 

66 

67def test_is_jwt_expired_edge_case_exact_expiration() -> None: 1abcdefg

68 current_time = int(time.time()) 1QRSTUVW

69 token = create_jwt_token({"exp": current_time, "sub": "test_user"}) 1QRSTUVW

70 

71 assert _is_jwt_expired(token) 1QRSTUVW

72 

73 

74def test_is_jwt_expired_edge_case_one_second_before() -> None: 1abcdefg

75 current_time = int(time.time()) 1XYZ0123

76 token = create_jwt_token({"exp": current_time + 1, "sub": "test_user"}) 1XYZ0123

77 

78 assert not _is_jwt_expired(token) 1XYZ0123

79 

80 

81def test_is_user_token_expired_with_no_token(temp_auth_config: Path) -> None: 1abcdefg

82 assert not temp_auth_config.exists() 1+,-./:;

83 assert Identity().is_user_token_expired() 1+,-./:;

84 

85 

86def test_is_logged_in_with_no_token(temp_auth_config: Path) -> None: 1abcdefg

87 assert not temp_auth_config.exists() 1=?@[]^_

88 assert not Identity().is_logged_in() 1=?@[]^_

89 

90 

91def test_is_logged_in_with_valid_token(temp_auth_config: Path) -> None: 1abcdefg

92 future_exp = int(time.time()) + 3600 1opqrstu

93 token = create_jwt_token({"exp": future_exp, "sub": "test_user"}) 1opqrstu

94 

95 write_auth_config(AuthConfig(access_token=token)) 1opqrstu

96 

97 assert Identity().is_logged_in() 1opqrstu

98 

99 

100def test_is_logged_in_with_expired_token(temp_auth_config: Path) -> None: 1abcdefg

101 past_exp = int(time.time()) - 3600 1vwxyzAB

102 token = create_jwt_token({"exp": past_exp, "sub": "test_user"}) 1vwxyzAB

103 

104 write_auth_config(AuthConfig(access_token=token)) 1vwxyzAB

105 

106 assert not Identity().is_logged_in() 1vwxyzAB

107 

108 

109def test_is_logged_in_with_malformed_token(temp_auth_config: Path) -> None: 1abcdefg

110 write_auth_config(AuthConfig(access_token="not.a.valid.token")) 2` { | } ~ abbb

111 

112 assert not Identity().is_logged_in() 2` { | } ~ abbb