|
| 1 | +import time |
1 | 2 | from pathlib import Path |
2 | 3 | from unittest.mock import patch |
3 | 4 |
|
|
9 | 10 |
|
10 | 11 | from fastapi_cloud_cli.cli import app |
11 | 12 | from fastapi_cloud_cli.config import Settings |
| 13 | +from tests.utils import create_jwt_token |
12 | 14 |
|
13 | 15 | runner = CliRunner() |
14 | 16 | settings = Settings.get() |
@@ -162,3 +164,54 @@ def test_fetch_access_token_handles_500_error(respx_mock: respx.MockRouter) -> N |
162 | 164 | with APIClient() as client: |
163 | 165 | with pytest.raises(httpx.HTTPStatusError): |
164 | 166 | _fetch_access_token(client, "test_device_code", 5) |
| 167 | + |
| 168 | + |
| 169 | +@pytest.mark.respx(base_url=settings.base_api_url) |
| 170 | +def test_notify_already_logged_in_user( |
| 171 | + respx_mock: respx.MockRouter, logged_in_cli: None |
| 172 | +) -> None: |
| 173 | + result = runner.invoke(app, ["login"]) |
| 174 | + |
| 175 | + assert result.exit_code == 0 |
| 176 | + assert "You are already logged in." in result.output |
| 177 | + assert "Run fastapi logout first if you want to switch accounts." in result.output |
| 178 | + |
| 179 | + |
| 180 | +@pytest.mark.respx(base_url=settings.base_api_url) |
| 181 | +def test_notify_expired_token_user( |
| 182 | + respx_mock: respx.MockRouter, temp_auth_config: Path |
| 183 | +) -> None: |
| 184 | + past_exp = int(time.time()) - 3600 |
| 185 | + expired_token = create_jwt_token({"sub": "test_user_12345", "exp": past_exp}) |
| 186 | + |
| 187 | + temp_auth_config.write_text(f'{{"access_token": "{expired_token}"}}') |
| 188 | + |
| 189 | + with patch("fastapi_cloud_cli.commands.login.typer.launch") as mock_open: |
| 190 | + respx_mock.post( |
| 191 | + "/login/device/authorization", data={"client_id": settings.client_id} |
| 192 | + ).mock( |
| 193 | + return_value=Response( |
| 194 | + 200, |
| 195 | + json={ |
| 196 | + "verification_uri_complete": "http://test.com", |
| 197 | + "verification_uri": "http://test.com", |
| 198 | + "user_code": "1234", |
| 199 | + "device_code": "5678", |
| 200 | + }, |
| 201 | + ) |
| 202 | + ) |
| 203 | + respx_mock.post( |
| 204 | + "/login/device/token", |
| 205 | + data={ |
| 206 | + "device_code": "5678", |
| 207 | + "client_id": settings.client_id, |
| 208 | + "grant_type": "urn:ietf:params:oauth:grant-type:device_code", |
| 209 | + }, |
| 210 | + ).mock(return_value=Response(200, json={"access_token": "new_token_1234"})) |
| 211 | + |
| 212 | + result = runner.invoke(app, ["login"]) |
| 213 | + |
| 214 | + assert result.exit_code == 0 |
| 215 | + assert "Your session has expired. Logging in again..." in result.output |
| 216 | + assert "Now you are logged in!" in result.output |
| 217 | + assert mock_open.called |
0 commit comments