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
« 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
5import pytest 1abcdefg
7from fastapi_cloud_cli.utils.auth import ( 1abcdefg
8 AuthConfig,
9 Identity,
10 _is_jwt_expired,
11 write_auth_config,
12)
14from .utils import create_jwt_token 1abcdefg
17def test_is_jwt_expired_with_valid_token() -> None: 1abcdefg
18 future_exp = int(time.time()) + 3600 1CDEFGHI
20 token = create_jwt_token({"exp": future_exp, "sub": "test_user"}) 1CDEFGHI
22 assert not _is_jwt_expired(token) 1CDEFGHI
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
29 assert _is_jwt_expired(token) 1JKLMNOP
32def test_is_jwt_expired_with_no_exp_claim() -> None: 1abcdefg
33 token = create_jwt_token({"sub": "test_user"}) 1456789!
35 # Tokens without exp claim should be considered valid
36 assert not _is_jwt_expired(token) 1456789!
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
53def test_is_jwt_expired_with_invalid_base64() -> None: 1abcdefg
54 token = "header.!!!invalid_signature!!!.signature" 1#$%'()*
55 assert _is_jwt_expired(token) 1#$%'()*
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
64 assert _is_jwt_expired(token) 1hijklmn
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
71 assert _is_jwt_expired(token) 1QRSTUVW
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
78 assert not _is_jwt_expired(token) 1XYZ0123
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+,-./:;
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=?@[]^_
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
95 write_auth_config(AuthConfig(access_token=token)) 1opqrstu
97 assert Identity().is_logged_in() 1opqrstu
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
104 write_auth_config(AuthConfig(access_token=token)) 1vwxyzAB
106 assert not Identity().is_logged_in() 1vwxyzAB
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
112 assert not Identity().is_logged_in() 2` { | } ~ abbb