Initial production analytics foundation
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
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")
|
||||
Reference in New Issue
Block a user