cli-anything-transcode-api-v2 0.1.0__tar.gz → 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cli_anything_transcode_api_v2-0.1.0 → cli_anything_transcode_api_v2-0.1.1}/PKG-INFO +1 -1
- {cli_anything_transcode_api_v2-0.1.0 → cli_anything_transcode_api_v2-0.1.1}/cli_anything_transcode_api_v2.egg-info/PKG-INFO +1 -1
- {cli_anything_transcode_api_v2-0.1.0 → cli_anything_transcode_api_v2-0.1.1}/cli_anything_transcode_api_v2.egg-info/SOURCES.txt +0 -3
- {cli_anything_transcode_api_v2-0.1.0 → cli_anything_transcode_api_v2-0.1.1}/setup.py +5 -2
- cli_anything_transcode_api_v2-0.1.0/cli_anything/transcode_api_v2/tests/__init__.py +0 -0
- cli_anything_transcode_api_v2-0.1.0/cli_anything/transcode_api_v2/tests/test_core.py +0 -237
- cli_anything_transcode_api_v2-0.1.0/cli_anything/transcode_api_v2/tests/test_full_e2e.py +0 -218
- {cli_anything_transcode_api_v2-0.1.0 → cli_anything_transcode_api_v2-0.1.1}/cli_anything/transcode_api_v2/__init__.py +0 -0
- {cli_anything_transcode_api_v2-0.1.0 → cli_anything_transcode_api_v2-0.1.1}/cli_anything/transcode_api_v2/__main__.py +0 -0
- {cli_anything_transcode_api_v2-0.1.0 → cli_anything_transcode_api_v2-0.1.1}/cli_anything/transcode_api_v2/core/__init__.py +0 -0
- {cli_anything_transcode_api_v2-0.1.0 → cli_anything_transcode_api_v2-0.1.1}/cli_anything/transcode_api_v2/core/client.py +0 -0
- {cli_anything_transcode_api_v2-0.1.0 → cli_anything_transcode_api_v2-0.1.1}/cli_anything/transcode_api_v2/core/session.py +0 -0
- {cli_anything_transcode_api_v2-0.1.0 → cli_anything_transcode_api_v2-0.1.1}/cli_anything/transcode_api_v2/skills/SKILL.md +0 -0
- {cli_anything_transcode_api_v2-0.1.0 → cli_anything_transcode_api_v2-0.1.1}/cli_anything/transcode_api_v2/transcode_api_v2_cli.py +0 -0
- {cli_anything_transcode_api_v2-0.1.0 → cli_anything_transcode_api_v2-0.1.1}/cli_anything/transcode_api_v2/utils/__init__.py +0 -0
- {cli_anything_transcode_api_v2-0.1.0 → cli_anything_transcode_api_v2-0.1.1}/cli_anything/transcode_api_v2/utils/formatting.py +0 -0
- {cli_anything_transcode_api_v2-0.1.0 → cli_anything_transcode_api_v2-0.1.1}/cli_anything_transcode_api_v2.egg-info/dependency_links.txt +0 -0
- {cli_anything_transcode_api_v2-0.1.0 → cli_anything_transcode_api_v2-0.1.1}/cli_anything_transcode_api_v2.egg-info/entry_points.txt +0 -0
- {cli_anything_transcode_api_v2-0.1.0 → cli_anything_transcode_api_v2-0.1.1}/cli_anything_transcode_api_v2.egg-info/requires.txt +0 -0
- {cli_anything_transcode_api_v2-0.1.0 → cli_anything_transcode_api_v2-0.1.1}/cli_anything_transcode_api_v2.egg-info/top_level.txt +0 -0
- {cli_anything_transcode_api_v2-0.1.0 → cli_anything_transcode_api_v2-0.1.1}/setup.cfg +0 -0
|
@@ -6,9 +6,6 @@ cli_anything/transcode_api_v2/core/__init__.py
|
|
|
6
6
|
cli_anything/transcode_api_v2/core/client.py
|
|
7
7
|
cli_anything/transcode_api_v2/core/session.py
|
|
8
8
|
cli_anything/transcode_api_v2/skills/SKILL.md
|
|
9
|
-
cli_anything/transcode_api_v2/tests/__init__.py
|
|
10
|
-
cli_anything/transcode_api_v2/tests/test_core.py
|
|
11
|
-
cli_anything/transcode_api_v2/tests/test_full_e2e.py
|
|
12
9
|
cli_anything/transcode_api_v2/utils/__init__.py
|
|
13
10
|
cli_anything/transcode_api_v2/utils/formatting.py
|
|
14
11
|
cli_anything_transcode_api_v2.egg-info/PKG-INFO
|
|
@@ -2,9 +2,12 @@ from setuptools import setup, find_namespace_packages
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name="cli-anything-transcode-api-v2",
|
|
5
|
-
version="0.1.
|
|
5
|
+
version="0.1.1",
|
|
6
6
|
description="CLI harness for transcode_api_v2 — video/audio transcoding orchestration API",
|
|
7
|
-
packages=find_namespace_packages(
|
|
7
|
+
packages=find_namespace_packages(
|
|
8
|
+
include=["cli_anything.*"],
|
|
9
|
+
exclude=["cli_anything.transcode_api_v2.tests*"],
|
|
10
|
+
),
|
|
8
11
|
package_data={
|
|
9
12
|
"cli_anything.transcode_api_v2": ["skills/*.md"],
|
|
10
13
|
},
|
|
File without changes
|
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
"""Unit tests for ApiClient, Session, and Formatting modules.
|
|
2
|
-
|
|
3
|
-
Run without installing the package:
|
|
4
|
-
cd /Users/a1/Desktop/transcode_api_v2/agent-harness
|
|
5
|
-
python -m pytest cli_anything/transcode_api_v2/tests/test_core.py -v
|
|
6
|
-
|
|
7
|
-
Or after pip install -e .:
|
|
8
|
-
pytest cli_anything/transcode_api_v2/tests/test_core.py -v
|
|
9
|
-
"""
|
|
10
|
-
from __future__ import annotations
|
|
11
|
-
|
|
12
|
-
import hashlib
|
|
13
|
-
import json
|
|
14
|
-
import os
|
|
15
|
-
import sys
|
|
16
|
-
|
|
17
|
-
# Allow running without install
|
|
18
|
-
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", "..", ".."))
|
|
19
|
-
|
|
20
|
-
import pytest
|
|
21
|
-
|
|
22
|
-
from cli_anything.transcode_api_v2.core.client import ApiClient, ApiError
|
|
23
|
-
from cli_anything.transcode_api_v2.core.session import Session
|
|
24
|
-
from cli_anything.transcode_api_v2.utils.formatting import (
|
|
25
|
-
STATUS_LABELS,
|
|
26
|
-
format_error,
|
|
27
|
-
format_result,
|
|
28
|
-
format_task_table,
|
|
29
|
-
status_label,
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
# ── ApiClient unit tests ──────────────────────────────────────────────────────
|
|
34
|
-
|
|
35
|
-
class TestApiClient:
|
|
36
|
-
"""Tests for ApiClient (all run in mock mode via env var)."""
|
|
37
|
-
|
|
38
|
-
def setup_method(self):
|
|
39
|
-
os.environ["TRANSCODE_API_MOCK"] = "1"
|
|
40
|
-
|
|
41
|
-
def teardown_method(self):
|
|
42
|
-
os.environ.pop("TRANSCODE_API_MOCK", None)
|
|
43
|
-
|
|
44
|
-
def test_client_defaults_from_env(self):
|
|
45
|
-
os.environ["TRANSCODE_API_BASE_URL"] = "http://myserver:9090"
|
|
46
|
-
os.environ["TRANSCODE_API_SNAME"] = "myns"
|
|
47
|
-
os.environ["TRANSCODE_API_AK"] = "aabbcc"
|
|
48
|
-
os.environ["TRANSCODE_API_SK"] = "mysecret"
|
|
49
|
-
try:
|
|
50
|
-
c = ApiClient()
|
|
51
|
-
assert c.base_url == "http://myserver:9090"
|
|
52
|
-
assert c.sname == "myns"
|
|
53
|
-
assert c.ak == "aabbcc"
|
|
54
|
-
assert c.sk == "mysecret"
|
|
55
|
-
finally:
|
|
56
|
-
os.environ.pop("TRANSCODE_API_BASE_URL", None)
|
|
57
|
-
os.environ.pop("TRANSCODE_API_SNAME", None)
|
|
58
|
-
os.environ.pop("TRANSCODE_API_AK", None)
|
|
59
|
-
os.environ.pop("TRANSCODE_API_SK", None)
|
|
60
|
-
|
|
61
|
-
def test_client_sign_empty_params(self):
|
|
62
|
-
import hmac as hmac_mod, hashlib, base64
|
|
63
|
-
c = ApiClient(ak="myak", sk="mysk")
|
|
64
|
-
sig = hmac_mod.new("mysk".encode(), "myak\n123\n456".encode(), hashlib.sha1).digest()
|
|
65
|
-
expected = "myak:" + base64.b64encode(sig).decode()
|
|
66
|
-
headers = c._standard_auth_headers("123", "456")
|
|
67
|
-
assert headers["Authorization"] == expected
|
|
68
|
-
|
|
69
|
-
def test_client_sign_sorted_params(self):
|
|
70
|
-
# _standard_auth_headers always produces AK:base64(...) format
|
|
71
|
-
c = ApiClient(ak="ak1234", sk="sk5678")
|
|
72
|
-
headers = c._standard_auth_headers("111", "222")
|
|
73
|
-
assert headers["Authorization"].startswith("ak1234:")
|
|
74
|
-
|
|
75
|
-
def test_client_mock_task_add(self):
|
|
76
|
-
c = ApiClient()
|
|
77
|
-
result = c.task_add(service="transcode", args={"input": "s3://bucket/vid.mp4"})
|
|
78
|
-
assert "tid" in result
|
|
79
|
-
assert result["tid"] == 42
|
|
80
|
-
|
|
81
|
-
def test_client_mock_task_get(self):
|
|
82
|
-
c = ApiClient()
|
|
83
|
-
result = c.task_get(12345)
|
|
84
|
-
assert result.get("tid") == 1
|
|
85
|
-
assert result.get("status") == 1
|
|
86
|
-
|
|
87
|
-
def test_client_mock_task_get_many(self):
|
|
88
|
-
c = ApiClient()
|
|
89
|
-
result = c.task_get_many([1, 2, 3])
|
|
90
|
-
# Falls through to default mock → {"tid": 42}
|
|
91
|
-
assert isinstance(result, dict)
|
|
92
|
-
|
|
93
|
-
def test_client_mock_media_call(self):
|
|
94
|
-
c = ApiClient()
|
|
95
|
-
result = c.media_call("VideoClip", {"sname": "ns", "args": {}})
|
|
96
|
-
assert isinstance(result, dict)
|
|
97
|
-
|
|
98
|
-
def test_client_mock_health(self):
|
|
99
|
-
c = ApiClient()
|
|
100
|
-
result = c.health()
|
|
101
|
-
assert result.get("status") == "ok"
|
|
102
|
-
|
|
103
|
-
def test_client_mock_template_list(self):
|
|
104
|
-
c = ApiClient()
|
|
105
|
-
result = c.template_list(eqid="eq001")
|
|
106
|
-
assert "list" in result
|
|
107
|
-
assert isinstance(result["list"], list)
|
|
108
|
-
|
|
109
|
-
def test_api_error_message(self):
|
|
110
|
-
err = ApiError(errno=403, errmsg="Forbidden", raw={"errno": 403})
|
|
111
|
-
assert "403" in str(err)
|
|
112
|
-
assert "Forbidden" in str(err)
|
|
113
|
-
assert err.errno == 403
|
|
114
|
-
assert err.errmsg == "Forbidden"
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
# ── Session unit tests ────────────────────────────────────────────────────────
|
|
118
|
-
|
|
119
|
-
class TestSession:
|
|
120
|
-
"""Tests for the in-memory Session store."""
|
|
121
|
-
|
|
122
|
-
def test_session_store_and_get(self):
|
|
123
|
-
s = Session()
|
|
124
|
-
s.store("job1", {"tid": 100, "status": 0})
|
|
125
|
-
assert s.get("job1") == {"tid": 100, "status": 0}
|
|
126
|
-
|
|
127
|
-
def test_session_get_missing_raises(self):
|
|
128
|
-
s = Session()
|
|
129
|
-
with pytest.raises(KeyError, match="job_missing"):
|
|
130
|
-
s.get("job_missing")
|
|
131
|
-
|
|
132
|
-
def test_session_get_tid(self):
|
|
133
|
-
s = Session()
|
|
134
|
-
s.store("job1", {"tid": 99, "status": 1})
|
|
135
|
-
assert s.get_tid("job1") == 99
|
|
136
|
-
|
|
137
|
-
def test_session_get_tid_missing_raises(self):
|
|
138
|
-
s = Session()
|
|
139
|
-
s.store("notask", {"status": 1})
|
|
140
|
-
with pytest.raises(ValueError, match="no tid"):
|
|
141
|
-
s.get_tid("notask")
|
|
142
|
-
|
|
143
|
-
def test_session_list_aliases_empty(self):
|
|
144
|
-
s = Session()
|
|
145
|
-
assert s.list_aliases() == []
|
|
146
|
-
|
|
147
|
-
def test_session_list_aliases_nonempty(self):
|
|
148
|
-
s = Session()
|
|
149
|
-
s.store("a", {"tid": 1})
|
|
150
|
-
s.store("b", {"tid": 2})
|
|
151
|
-
assert set(s.list_aliases()) == {"a", "b"}
|
|
152
|
-
|
|
153
|
-
def test_session_history(self):
|
|
154
|
-
s = Session()
|
|
155
|
-
s.store("a", {"tid": 1})
|
|
156
|
-
s.store("b", {"tid": 2})
|
|
157
|
-
hist = s.history()
|
|
158
|
-
assert len(hist) == 2
|
|
159
|
-
assert hist[0]["alias"] == "a"
|
|
160
|
-
assert hist[1]["alias"] == "b"
|
|
161
|
-
|
|
162
|
-
def test_session_clear(self):
|
|
163
|
-
s = Session()
|
|
164
|
-
s.store("a", {"tid": 1})
|
|
165
|
-
s.clear()
|
|
166
|
-
assert s.list_aliases() == []
|
|
167
|
-
assert s.history() == []
|
|
168
|
-
|
|
169
|
-
def test_session_summary_empty(self):
|
|
170
|
-
s = Session()
|
|
171
|
-
assert "(empty session)" in s.summary()
|
|
172
|
-
|
|
173
|
-
def test_session_summary_nonempty(self):
|
|
174
|
-
s = Session()
|
|
175
|
-
s.store("myjob", {"tid": 55, "status": 6})
|
|
176
|
-
summary = s.summary()
|
|
177
|
-
assert "myjob" in summary
|
|
178
|
-
assert "55" in summary
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
# ── Formatting unit tests ─────────────────────────────────────────────────────
|
|
182
|
-
|
|
183
|
-
class TestFormatting:
|
|
184
|
-
"""Tests for formatting helpers."""
|
|
185
|
-
|
|
186
|
-
def test_status_label_known(self):
|
|
187
|
-
assert status_label(0) == "queued"
|
|
188
|
-
assert status_label(1) == "done"
|
|
189
|
-
assert status_label(2) == "failed"
|
|
190
|
-
assert status_label(3) == "sending"
|
|
191
|
-
assert status_label(6) == "processing"
|
|
192
|
-
|
|
193
|
-
def test_status_label_unknown(self):
|
|
194
|
-
assert status_label(99) == "99"
|
|
195
|
-
|
|
196
|
-
def test_status_label_none(self):
|
|
197
|
-
assert status_label(None) == "?"
|
|
198
|
-
|
|
199
|
-
def test_format_result_dict(self):
|
|
200
|
-
out = format_result({"tid": 42, "status": 1})
|
|
201
|
-
assert "42" in out
|
|
202
|
-
# status should include human-readable label
|
|
203
|
-
assert "done" in out
|
|
204
|
-
|
|
205
|
-
def test_format_result_as_json(self):
|
|
206
|
-
data = {"tid": 42}
|
|
207
|
-
out = format_result(data, as_json=True)
|
|
208
|
-
parsed = json.loads(out)
|
|
209
|
-
assert parsed == data
|
|
210
|
-
|
|
211
|
-
def test_format_result_string(self):
|
|
212
|
-
assert format_result("hello") == "hello"
|
|
213
|
-
|
|
214
|
-
def test_format_error_text(self):
|
|
215
|
-
out = format_error("something went wrong")
|
|
216
|
-
assert "ERR" in out
|
|
217
|
-
assert "something went wrong" in out
|
|
218
|
-
|
|
219
|
-
def test_format_error_json(self):
|
|
220
|
-
out = format_error("boom", as_json=True)
|
|
221
|
-
parsed = json.loads(out)
|
|
222
|
-
assert parsed["errno"] == -1
|
|
223
|
-
assert "boom" in parsed["errmsg"]
|
|
224
|
-
|
|
225
|
-
def test_format_task_table_empty(self):
|
|
226
|
-
assert "(no tasks)" in format_task_table([])
|
|
227
|
-
|
|
228
|
-
def test_format_task_table_rows(self):
|
|
229
|
-
tasks = [
|
|
230
|
-
{"tid": 1, "status": 1, "progress": 100, "service": "transcode"},
|
|
231
|
-
{"tid": 2, "status": 6, "progress": 50, "service": "clip"},
|
|
232
|
-
]
|
|
233
|
-
out = format_task_table(tasks)
|
|
234
|
-
assert "done" in out
|
|
235
|
-
assert "processing" in out
|
|
236
|
-
assert "transcode" in out
|
|
237
|
-
assert "clip" in out
|
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
"""Subprocess / E2E tests for cli-anything-transcode-api-v2.
|
|
2
|
-
|
|
3
|
-
All tests use TRANSCODE_API_MOCK=1 — no live server required.
|
|
4
|
-
The _resolve_cli() helper finds the installed entry-point or skips when
|
|
5
|
-
CLI_ANYTHING_FORCE_INSTALLED=1 is set and the binary isn't on PATH.
|
|
6
|
-
|
|
7
|
-
Run:
|
|
8
|
-
cd /Users/a1/Desktop/transcode_api_v2/agent-harness
|
|
9
|
-
pip install -e . && pytest cli_anything/transcode_api_v2/tests/test_full_e2e.py -v
|
|
10
|
-
"""
|
|
11
|
-
from __future__ import annotations
|
|
12
|
-
|
|
13
|
-
import json
|
|
14
|
-
import os
|
|
15
|
-
import shutil
|
|
16
|
-
import subprocess
|
|
17
|
-
import sys
|
|
18
|
-
from typing import Optional
|
|
19
|
-
|
|
20
|
-
import pytest
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
# ── Helper: locate installed CLI ──────────────────────────────────────────────
|
|
24
|
-
|
|
25
|
-
def _resolve_cli(name: str) -> Optional[str]:
|
|
26
|
-
"""Return absolute path to named CLI, or None/skip depending on env."""
|
|
27
|
-
path = shutil.which(name)
|
|
28
|
-
if path:
|
|
29
|
-
return path
|
|
30
|
-
if os.environ.get("CLI_ANYTHING_FORCE_INSTALLED", "").strip() == "1":
|
|
31
|
-
pytest.fail(f"CLI_ANYTHING_FORCE_INSTALLED=1 but '{name}' not found on PATH")
|
|
32
|
-
pytest.skip(f"'{name}' not installed; run `pip install -e .` first")
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
CLI_NAME = "cli-anything-transcode-api-v2"
|
|
36
|
-
MOCK_ENV = {**os.environ, "TRANSCODE_API_MOCK": "1"}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def _run(*args: str, env=None, input: str | None = None) -> subprocess.CompletedProcess:
|
|
40
|
-
cli = _resolve_cli(CLI_NAME)
|
|
41
|
-
return subprocess.run(
|
|
42
|
-
[cli] + list(args),
|
|
43
|
-
capture_output=True,
|
|
44
|
-
text=True,
|
|
45
|
-
env=env or MOCK_ENV,
|
|
46
|
-
input=input,
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
# ── Top-level CLI ─────────────────────────────────────────────────────────────
|
|
51
|
-
|
|
52
|
-
class TestTopLevel:
|
|
53
|
-
def test_help(self):
|
|
54
|
-
r = _run("--help")
|
|
55
|
-
assert r.returncode == 0
|
|
56
|
-
assert "task" in r.stdout
|
|
57
|
-
assert "media" in r.stdout
|
|
58
|
-
assert "monitor" in r.stdout
|
|
59
|
-
|
|
60
|
-
def test_version_flag_absent_no_crash(self):
|
|
61
|
-
"""CLI should show help without crashing even without --version."""
|
|
62
|
-
r = _run("--help")
|
|
63
|
-
assert r.returncode == 0
|
|
64
|
-
|
|
65
|
-
def test_json_flag_preserved_for_subcommand(self):
|
|
66
|
-
r = _run("--json", "monitor", "health")
|
|
67
|
-
assert r.returncode == 0
|
|
68
|
-
parsed = json.loads(r.stdout.strip())
|
|
69
|
-
assert isinstance(parsed, dict)
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
# ── task group ────────────────────────────────────────────────────────────────
|
|
73
|
-
|
|
74
|
-
class TestTaskGroup:
|
|
75
|
-
def test_task_help(self):
|
|
76
|
-
r = _run("task", "--help")
|
|
77
|
-
assert r.returncode == 0
|
|
78
|
-
assert "add" in r.stdout
|
|
79
|
-
|
|
80
|
-
def test_task_add_mock(self):
|
|
81
|
-
r = _run("task", "add",
|
|
82
|
-
"--service", "transcode",
|
|
83
|
-
"--args", '{"input":"s3://bucket/video.mp4"}')
|
|
84
|
-
assert r.returncode == 0
|
|
85
|
-
assert "42" in r.stdout # mock returns tid=42
|
|
86
|
-
|
|
87
|
-
def test_task_add_json_output(self):
|
|
88
|
-
r = _run("--json", "task", "add",
|
|
89
|
-
"--service", "transcode",
|
|
90
|
-
"--args", '{"input":"s3://bucket/video.mp4"}')
|
|
91
|
-
assert r.returncode == 0
|
|
92
|
-
data = json.loads(r.stdout.strip())
|
|
93
|
-
assert "tid" in data
|
|
94
|
-
assert data["tid"] == 42
|
|
95
|
-
|
|
96
|
-
def test_task_get_mock(self):
|
|
97
|
-
r = _run("task", "get", "12345")
|
|
98
|
-
assert r.returncode == 0
|
|
99
|
-
assert "1" in r.stdout # tid=1 from mock
|
|
100
|
-
|
|
101
|
-
def test_task_get_json(self):
|
|
102
|
-
r = _run("--json", "task", "get", "12345")
|
|
103
|
-
assert r.returncode == 0
|
|
104
|
-
data = json.loads(r.stdout.strip())
|
|
105
|
-
assert data["tid"] == 1
|
|
106
|
-
assert data["status"] == 1
|
|
107
|
-
|
|
108
|
-
def test_task_stop_mock(self):
|
|
109
|
-
r = _run("task", "stop", "12345")
|
|
110
|
-
assert r.returncode == 0
|
|
111
|
-
|
|
112
|
-
def test_task_get_many_mock(self):
|
|
113
|
-
r = _run("task", "get-many", "1", "2", "3")
|
|
114
|
-
assert r.returncode == 0
|
|
115
|
-
|
|
116
|
-
def test_task_add_invalid_args_json(self):
|
|
117
|
-
r = _run("task", "add",
|
|
118
|
-
"--service", "transcode",
|
|
119
|
-
"--args", "not-json")
|
|
120
|
-
assert r.returncode != 0
|
|
121
|
-
assert "ERR" in r.stderr or "Invalid" in r.stderr
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
# ── media group ───────────────────────────────────────────────────────────────
|
|
125
|
-
|
|
126
|
-
class TestMediaGroup:
|
|
127
|
-
def test_media_actions_list(self):
|
|
128
|
-
r = _run("media", "actions")
|
|
129
|
-
assert r.returncode == 0
|
|
130
|
-
assert "VideoClip" in r.stdout
|
|
131
|
-
assert "Snapshot" in r.stdout
|
|
132
|
-
|
|
133
|
-
def test_media_actions_json(self):
|
|
134
|
-
r = _run("--json", "media", "actions")
|
|
135
|
-
assert r.returncode == 0
|
|
136
|
-
data = json.loads(r.stdout.strip())
|
|
137
|
-
assert isinstance(data, list)
|
|
138
|
-
assert "VideoClip" in data
|
|
139
|
-
|
|
140
|
-
def test_media_call_mock(self):
|
|
141
|
-
r = _run("media", "call", "VideoClip", '{"sname":"ns"}')
|
|
142
|
-
assert r.returncode == 0
|
|
143
|
-
|
|
144
|
-
def test_media_call_default_empty_body(self):
|
|
145
|
-
r = _run("media", "call", "Snapshot")
|
|
146
|
-
assert r.returncode == 0
|
|
147
|
-
|
|
148
|
-
def test_media_get_mock(self):
|
|
149
|
-
r = _run("media", "get", "99")
|
|
150
|
-
assert r.returncode == 0
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
# ── monitor group ─────────────────────────────────────────────────────────────
|
|
154
|
-
|
|
155
|
-
class TestMonitorGroup:
|
|
156
|
-
def test_monitor_health(self):
|
|
157
|
-
r = _run("monitor", "health")
|
|
158
|
-
assert r.returncode == 0
|
|
159
|
-
assert "ok" in r.stdout
|
|
160
|
-
|
|
161
|
-
def test_monitor_health_json(self):
|
|
162
|
-
r = _run("--json", "monitor", "health")
|
|
163
|
-
assert r.returncode == 0
|
|
164
|
-
data = json.loads(r.stdout.strip())
|
|
165
|
-
assert data.get("status") == "ok"
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
# ── template group ────────────────────────────────────────────────────────────
|
|
169
|
-
|
|
170
|
-
class TestTemplateGroup:
|
|
171
|
-
def test_template_list_mock(self):
|
|
172
|
-
r = _run("template", "list", "--eqid", "eq001")
|
|
173
|
-
assert r.returncode == 0
|
|
174
|
-
|
|
175
|
-
def test_template_get_mock(self):
|
|
176
|
-
r = _run("template", "get", "--eqid", "eq001", "1")
|
|
177
|
-
assert r.returncode == 0
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
# ── session group ─────────────────────────────────────────────────────────────
|
|
181
|
-
|
|
182
|
-
class TestSessionGroup:
|
|
183
|
-
def test_session_list_empty(self):
|
|
184
|
-
r = _run("session", "list")
|
|
185
|
-
assert r.returncode == 0
|
|
186
|
-
assert "(empty session)" in r.stdout
|
|
187
|
-
|
|
188
|
-
def test_session_clear(self):
|
|
189
|
-
r = _run("session", "clear")
|
|
190
|
-
assert r.returncode == 0
|
|
191
|
-
assert "cleared" in r.stdout.lower()
|
|
192
|
-
|
|
193
|
-
def test_session_get_missing_alias(self):
|
|
194
|
-
r = _run("session", "get", "nonexistent_alias_xyz")
|
|
195
|
-
assert r.returncode != 0
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
# ── REPL tests ────────────────────────────────────────────────────────────────
|
|
199
|
-
|
|
200
|
-
class TestRepl:
|
|
201
|
-
def test_repl_exit(self):
|
|
202
|
-
r = _run(input="exit\n")
|
|
203
|
-
assert r.returncode == 0
|
|
204
|
-
assert "Bye" in r.stdout
|
|
205
|
-
|
|
206
|
-
def test_repl_quit(self):
|
|
207
|
-
r = _run(input="quit\n")
|
|
208
|
-
assert r.returncode == 0
|
|
209
|
-
assert "Bye" in r.stdout
|
|
210
|
-
|
|
211
|
-
def test_repl_monitor_health(self):
|
|
212
|
-
r = _run(input="monitor health\nexit\n")
|
|
213
|
-
assert r.returncode == 0
|
|
214
|
-
assert "ok" in r.stdout
|
|
215
|
-
|
|
216
|
-
def test_repl_empty_line(self):
|
|
217
|
-
r = _run(input="\nexit\n")
|
|
218
|
-
assert r.returncode == 0
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|