Files
full-stack-fastapi/backend/tests/api/routes/test_mqtt_raw.py
魏风 ff971e2cea
All checks were successful
Deploy to Production / deploy (push) Successful in 1m19s
feat: add mqtt raw data management with UTC+8 range UI
2026-03-20 17:46:37 +08:00

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