224 lines
6.2 KiB
Python
224 lines
6.2 KiB
Python
from datetime import date, datetime, timezone
|
|
|
|
from fastapi.testclient import TestClient
|
|
from sqlmodel import Session, delete, func, select
|
|
|
|
from app.core.config import settings
|
|
from app.models import TerminalMessageRaw
|
|
from app.mqtt.repository import insert_raw_message
|
|
|
|
|
|
def _reset_raw_data(db: Session) -> None:
|
|
db.execute(delete(TerminalMessageRaw))
|
|
db.commit()
|
|
|
|
|
|
def _count_raw_rows(db: Session) -> int:
|
|
statement = select(func.count()).select_from(TerminalMessageRaw)
|
|
return int(db.exec(statement).one())
|
|
|
|
|
|
def test_list_mqtt_raw_days(
|
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
|
) -> None:
|
|
_reset_raw_data(db)
|
|
|
|
insert_raw_message(
|
|
session=db,
|
|
device_id="device-a",
|
|
topic="terminal/device-a/raw",
|
|
payload=b"A1",
|
|
qos=1,
|
|
retain=False,
|
|
received_at=datetime(2026, 3, 10, 8, 0, tzinfo=timezone.utc),
|
|
)
|
|
insert_raw_message(
|
|
session=db,
|
|
device_id="device-a",
|
|
topic="terminal/device-a/raw",
|
|
payload=b"A2",
|
|
qos=1,
|
|
retain=False,
|
|
received_at=datetime(2026, 3, 10, 21, 0, tzinfo=timezone.utc),
|
|
)
|
|
insert_raw_message(
|
|
session=db,
|
|
device_id="device-b",
|
|
topic="terminal/device-b/raw",
|
|
payload=b"B1",
|
|
qos=1,
|
|
retain=False,
|
|
received_at=datetime(2026, 3, 11, 9, 0, tzinfo=timezone.utc),
|
|
)
|
|
|
|
response = client.get(
|
|
f"{settings.API_V1_STR}/mqtt-raw/days?skip=0&limit=10",
|
|
headers=superuser_token_headers,
|
|
)
|
|
|
|
assert response.status_code == 200
|
|
content = response.json()
|
|
assert content["count"] == 2
|
|
assert content["data"][0]["day"] == "2026-03-11"
|
|
assert content["data"][0]["message_count"] == 2
|
|
assert content["data"][1]["day"] == "2026-03-10"
|
|
assert content["data"][1]["message_count"] == 1
|
|
|
|
|
|
def test_download_mqtt_raw_by_day_or_time_range(
|
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
|
) -> None:
|
|
_reset_raw_data(db)
|
|
|
|
target_day = date(2026, 3, 12)
|
|
insert_raw_message(
|
|
session=db,
|
|
device_id="device-a",
|
|
topic="terminal/device-a/raw",
|
|
payload=b"EARLY\n",
|
|
qos=1,
|
|
retain=False,
|
|
received_at=datetime(2026, 3, 11, 20, 0, tzinfo=timezone.utc),
|
|
)
|
|
insert_raw_message(
|
|
session=db,
|
|
device_id="device-a",
|
|
topic="terminal/device-a/raw",
|
|
payload=b"MID\n",
|
|
qos=1,
|
|
retain=False,
|
|
received_at=datetime(2026, 3, 12, 3, 0, tzinfo=timezone.utc),
|
|
)
|
|
insert_raw_message(
|
|
session=db,
|
|
device_id="device-a",
|
|
topic="terminal/device-a/raw",
|
|
payload=b"LATE\n",
|
|
qos=1,
|
|
retain=False,
|
|
received_at=datetime(2026, 3, 12, 12, 0, tzinfo=timezone.utc),
|
|
)
|
|
insert_raw_message(
|
|
session=db,
|
|
device_id="device-a",
|
|
topic="terminal/device-a/raw",
|
|
payload=b"NEXT_DAY\n",
|
|
qos=1,
|
|
retain=False,
|
|
received_at=datetime(2026, 3, 12, 18, 0, tzinfo=timezone.utc),
|
|
)
|
|
|
|
full_day_response = client.get(
|
|
f"{settings.API_V1_STR}/mqtt-raw/download",
|
|
headers=superuser_token_headers,
|
|
params={"day": target_day.isoformat()},
|
|
)
|
|
assert full_day_response.status_code == 200
|
|
assert full_day_response.content == b"EARLY\nMID\nLATE\n"
|
|
|
|
range_response = client.get(
|
|
f"{settings.API_V1_STR}/mqtt-raw/download",
|
|
headers=superuser_token_headers,
|
|
params={
|
|
"day": target_day.isoformat(),
|
|
"start_seconds": 10 * 3600,
|
|
"end_seconds": 14 * 3600,
|
|
},
|
|
)
|
|
assert range_response.status_code == 200
|
|
assert range_response.content == b"MID\n"
|
|
|
|
|
|
def test_delete_mqtt_raw_by_day(
|
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
|
) -> None:
|
|
_reset_raw_data(db)
|
|
|
|
insert_raw_message(
|
|
session=db,
|
|
device_id="device-x",
|
|
topic="terminal/device-x/raw",
|
|
payload=b"X",
|
|
qos=1,
|
|
retain=False,
|
|
received_at=datetime(2026, 3, 14, 20, 30, tzinfo=timezone.utc),
|
|
)
|
|
insert_raw_message(
|
|
session=db,
|
|
device_id="device-a",
|
|
topic="terminal/device-a/raw",
|
|
payload=b"A",
|
|
qos=1,
|
|
retain=False,
|
|
received_at=datetime(2026, 3, 15, 1, 0, tzinfo=timezone.utc),
|
|
)
|
|
insert_raw_message(
|
|
session=db,
|
|
device_id="device-b",
|
|
topic="terminal/device-b/raw",
|
|
payload=b"B",
|
|
qos=1,
|
|
retain=False,
|
|
received_at=datetime(2026, 3, 15, 12, 0, tzinfo=timezone.utc),
|
|
)
|
|
insert_raw_message(
|
|
session=db,
|
|
device_id="device-c",
|
|
topic="terminal/device-c/raw",
|
|
payload=b"C",
|
|
qos=1,
|
|
retain=False,
|
|
received_at=datetime(2026, 3, 15, 16, 30, tzinfo=timezone.utc),
|
|
)
|
|
|
|
response = client.delete(
|
|
f"{settings.API_V1_STR}/mqtt-raw/day/2026-03-15",
|
|
headers=superuser_token_headers,
|
|
)
|
|
|
|
assert response.status_code == 200
|
|
content = response.json()
|
|
assert content["deleted_count"] == 3
|
|
assert _count_raw_rows(db) == 1
|
|
|
|
|
|
def test_delete_all_mqtt_raw_requires_confirmation(
|
|
client: TestClient, superuser_token_headers: dict[str, str], db: Session
|
|
) -> None:
|
|
_reset_raw_data(db)
|
|
|
|
insert_raw_message(
|
|
session=db,
|
|
device_id="device-a",
|
|
topic="terminal/device-a/raw",
|
|
payload=b"A",
|
|
qos=1,
|
|
retain=False,
|
|
received_at=datetime(2026, 3, 15, 1, 0, tzinfo=timezone.utc),
|
|
)
|
|
insert_raw_message(
|
|
session=db,
|
|
device_id="device-b",
|
|
topic="terminal/device-b/raw",
|
|
payload=b"B",
|
|
qos=1,
|
|
retain=False,
|
|
received_at=datetime(2026, 3, 16, 1, 0, tzinfo=timezone.utc),
|
|
)
|
|
|
|
reject_response = client.delete(
|
|
f"{settings.API_V1_STR}/mqtt-raw/all",
|
|
headers=superuser_token_headers,
|
|
)
|
|
assert reject_response.status_code == 400
|
|
assert _count_raw_rows(db) == 2
|
|
|
|
confirmed_response = client.delete(
|
|
f"{settings.API_V1_STR}/mqtt-raw/all?confirm=true",
|
|
headers=superuser_token_headers,
|
|
)
|
|
assert confirmed_response.status_code == 200
|
|
content = confirmed_response.json()
|
|
assert content["deleted_count"] == 2
|
|
assert _count_raw_rows(db) == 0
|