Skip to content

Commit fffb34d

Browse files
Improve coverage
1 parent aeafcf1 commit fffb34d

1 file changed

Lines changed: 52 additions & 0 deletions

File tree

tests/test_logs.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
from unittest.mock import patch
23

34
import httpx
45
import pytest
@@ -7,6 +8,7 @@
78

89
from fastapi_cloud_cli.cli import cloud_app as app
910
from fastapi_cloud_cli.config import Settings
11+
from fastapi_cloud_cli.utils.api import TooManyRetriesError
1012
from tests.conftest import ConfiguredApp
1113
from tests.utils import changing_dir
1214

@@ -270,3 +272,53 @@ def test_skips_invalid_json_lines(
270272

271273
assert result.exit_code == 0
272274
assert "Valid log message" in result.output
275+
276+
277+
@pytest.mark.respx(base_url=settings.base_api_url)
278+
def test_skips_heartbeat_messages(
279+
logged_in_cli: None, respx_mock: respx.MockRouter, configured_app: ConfiguredApp
280+
) -> None:
281+
log_lines = [
282+
json.dumps({"type": "heartbeat"}),
283+
json.dumps(
284+
{
285+
"timestamp": "2025-12-05T14:32:01.123000Z",
286+
"message": "Real log message",
287+
"level": "info",
288+
}
289+
),
290+
]
291+
response_content = "\n".join(log_lines)
292+
293+
respx_mock.get(url__regex=rf"/apps/{configured_app.app_id}/logs/stream.*").mock(
294+
return_value=httpx.Response(200, content=response_content)
295+
)
296+
297+
with changing_dir(configured_app.path):
298+
result = runner.invoke(app, ["logs", "--no-follow"])
299+
300+
assert result.exit_code == 0
301+
assert "Real log message" in result.output
302+
assert "heartbeat" not in result.output.lower()
303+
304+
305+
@pytest.mark.parametrize(
306+
"error",
307+
[TooManyRetriesError, TimeoutError],
308+
)
309+
def test_handles_connection_loss(
310+
logged_in_cli: None,
311+
configured_app: ConfiguredApp,
312+
error: type[Exception],
313+
) -> None:
314+
with (
315+
changing_dir(configured_app.path),
316+
patch(
317+
"fastapi_cloud_cli.utils.api.APIClient.stream_app_logs",
318+
side_effect=error("Connection lost"),
319+
),
320+
):
321+
result = runner.invoke(app, ["logs", "--no-follow"])
322+
323+
assert result.exit_code == 1
324+
assert "Lost connection to log stream" in result.output

0 commit comments

Comments
 (0)