Files
production-analytics/tests/test_cli.py
T

82 lines
4.0 KiB
Python

import io
import json
import os
import tempfile
import unittest
from contextlib import redirect_stdout
from pathlib import Path
from unittest.mock import patch
from production_analytics.cli.__main__ import main
from production_analytics.enlyze.exploration import ExplorationResponse
class CliTests(unittest.TestCase):
@patch.dict(os.environ, {"ENLYZE_BASE_URL": "https://enlyze.example"}, clear=True)
@patch("production_analytics.cli.__main__.ExplorationClient.get")
def test_raw_prints_and_saves_sanitized_response(self, get_mock: object) -> None:
get_mock.return_value = ExplorationResponse( # type: ignore[attr-defined]
status_code=200,
path="/verified/path",
headers={"Content-Type": "application/json"},
body={"api_token": "secret", "authorization": "Bearer secret", "value": 4.2},
)
with tempfile.TemporaryDirectory() as temporary_directory:
output = io.StringIO()
with redirect_stdout(output):
result = main(
[
"enlyze",
"raw",
"/verified/path",
"--save-fixture",
"example.json",
"--fixture-dir",
temporary_directory,
"--save-raw",
"raw-example.json",
"--raw-dir",
temporary_directory,
]
)
fixture = json.loads((Path(temporary_directory) / "example.json").read_text())
raw_capture = json.loads((Path(temporary_directory) / "raw-example.json").read_text())
self.assertEqual(result, 0)
self.assertEqual(fixture["response"]["body"]["api_token"], "<redacted-secret>")
self.assertEqual(fixture["response"]["body"]["authorization"], "<redacted-secret>")
self.assertNotIn("Bearer secret", output.getvalue())
self.assertEqual(raw_capture["response"]["body"]["api_token"], "secret")
def test_raw_rejects_unsafe_fixture_name(self) -> None:
with patch.dict(os.environ, {"ENLYZE_BASE_URL": "https://enlyze.example"}, clear=True):
with patch("production_analytics.cli.__main__.ExplorationClient.get") as get_mock:
get_mock.return_value = ExplorationResponse(200, "/path", {}, {})
output = io.StringIO()
with redirect_stdout(output):
result = main(["enlyze", "raw", "/path", "--save-fixture", "../unsafe.json"])
self.assertEqual(result, 1)
self.assertIn("plain filename", output.getvalue())
@patch.dict(os.environ, {"ENLYZE_BASE_URL": "https://enlyze.example"}, clear=True)
@patch("production_analytics.cli.__main__.ExplorationClient.post_json")
def test_timeseries_builds_schema_supported_read_only_post(self, post_mock: object) -> None:
post_mock.return_value = ExplorationResponse( # type: ignore[attr-defined]
200, "/v2/timeseries", {}, {"metadata": {"next_cursor": None}, "data": {"columns": [], "records": []}}
)
with tempfile.TemporaryDirectory() as temporary_directory:
result = main(
[
"enlyze", "timeseries", "--machine", "machine-id", "--start", "2026-01-01T00:00:00+00:00",
"--end", "2026-01-01T00:10:00+00:00", "--variable", "variable-id", "--resampling-interval", "10",
"--resampling-method", "avg", "--save-fixture", "timeseries.json", "--fixture-dir", temporary_directory,
]
)
fixture = json.loads((Path(temporary_directory) / "timeseries.json").read_text())
self.assertEqual(result, 0)
self.assertEqual(post_mock.call_args.args[0], "/v2/timeseries") # type: ignore[attr-defined]
self.assertEqual(post_mock.call_args.args[1]["resampling_interval"], 10) # type: ignore[attr-defined]
self.assertEqual(fixture["request"]["method"], "POST")