data_prestatie traieste in payload_json, nu e coloana SQL: filtrarea se aplica in Python dupa derivarea prezentarii (fetch scope+status fara LIMIT, filtreaza, apoi LIMIT dupa filtrare), acelasi pattern deja folosit de dashboard-ul web (/_fragments/submissions). Extrage helper-ul iso_date_prefix in payload_view.py ca sa fie partajat intre canalul web si cel API (elimina duplicarea). Format invalid pe data_de/data_pana -> 422. Fara parametri, comportamentul raspunsului ramane identic cu inainte.
157 lines
5.3 KiB
Python
157 lines
5.3 KiB
Python
"""Teste API GET /v1/prezentari — filtrare pe perioada (data_de/data_pana) + obs expus.
|
|
|
|
data_prestatie traieste in payload_json (nu e coloana SQL), deci filtrul se aplica
|
|
in Python dupa derivarea prezentarii (vezi app/api/v1/router.py:list_prezentari),
|
|
acelasi pattern ca /_fragments/submissions (dashboard web).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import tempfile
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
|
|
|
|
@pytest.fixture()
|
|
def client(monkeypatch):
|
|
tmp = tempfile.mkdtemp()
|
|
monkeypatch.setenv("AUTOPASS_DB_PATH", os.path.join(tmp, "t.db"))
|
|
from app.config import get_settings
|
|
get_settings.cache_clear()
|
|
from app.main import app
|
|
with TestClient(app) as c:
|
|
yield c
|
|
get_settings.cache_clear()
|
|
|
|
|
|
def _body(**over):
|
|
prez = {
|
|
"vin": "WVWZZZ1KZAW000123",
|
|
"nr_inmatriculare": "B999TST",
|
|
"data_prestatie": "2026-06-15",
|
|
"odometru_final": "123456",
|
|
"prestatii": [{"cod_prestatie": "OE-1"}],
|
|
}
|
|
prez.update(over)
|
|
return {"rar_credentials": {"email": "x@y.ro", "password": "s"}, "prezentari": [prez], "raspuns": "complet"}
|
|
|
|
|
|
def _trimite(client, data_prestatie: str, **over) -> int:
|
|
r = client.post("/v1/prezentari", json=_body(data_prestatie=data_prestatie, **over))
|
|
assert r.status_code == 200, r.text
|
|
return r.json()["results"][0]["submission_id"]
|
|
|
|
|
|
def test_filtrare_ambii_parametri(client):
|
|
id_inainte = _trimite(client, "2026-06-01")
|
|
id_in_interval = _trimite(client, "2026-06-15")
|
|
id_dupa = _trimite(client, "2026-07-01")
|
|
|
|
r = client.get("/v1/prezentari", params={"data_de": "2026-06-10", "data_pana": "2026-06-20"})
|
|
assert r.status_code == 200
|
|
ids = [s["id"] for s in r.json()["submissions"]]
|
|
assert ids == [id_in_interval]
|
|
assert id_inainte not in ids
|
|
assert id_dupa not in ids
|
|
|
|
|
|
def test_filtrare_doar_data_de(client):
|
|
id_vechi = _trimite(client, "2026-06-01")
|
|
id_nou = _trimite(client, "2026-06-20")
|
|
|
|
r = client.get("/v1/prezentari", params={"data_de": "2026-06-10"})
|
|
assert r.status_code == 200
|
|
ids = [s["id"] for s in r.json()["submissions"]]
|
|
assert id_nou in ids
|
|
assert id_vechi not in ids
|
|
|
|
|
|
def test_filtrare_doar_data_pana(client):
|
|
id_vechi = _trimite(client, "2026-06-01")
|
|
id_nou = _trimite(client, "2026-06-20")
|
|
|
|
r = client.get("/v1/prezentari", params={"data_pana": "2026-06-10"})
|
|
assert r.status_code == 200
|
|
ids = [s["id"] for s in r.json()["submissions"]]
|
|
assert id_vechi in ids
|
|
assert id_nou not in ids
|
|
|
|
|
|
def test_fara_parametri_comportament_neschimbat(client):
|
|
"""Fara data_de/data_pana, comportamentul ramane identic (SQL LIMIT, fara filtru Python)."""
|
|
id1 = _trimite(client, "2026-06-01")
|
|
id2 = _trimite(client, "2026-07-01")
|
|
|
|
r = client.get("/v1/prezentari")
|
|
assert r.status_code == 200
|
|
ids = [s["id"] for s in r.json()["submissions"]]
|
|
assert id1 in ids
|
|
assert id2 in ids
|
|
|
|
|
|
@pytest.mark.parametrize("param", ["data_de", "data_pana"])
|
|
def test_format_invalid_422(client, param):
|
|
r = client.get("/v1/prezentari", params={param: "15-06-2026"})
|
|
assert r.status_code == 422
|
|
|
|
|
|
def test_format_invalid_data_nesexistenta_422(client):
|
|
r = client.get("/v1/prezentari", params={"data_de": "2026-02-30"})
|
|
assert r.status_code == 422
|
|
|
|
|
|
def test_interactiune_cu_status(client):
|
|
"""Filtrul de perioada se combina cu status (AND): doar randuri care satisfac AMBELE."""
|
|
id_queued_in_interval = _trimite(client, "2026-06-15")
|
|
# Al doilea rand, status diferit (needs_data via VIN invalid) dar tot in interval.
|
|
r = client.post("/v1/prezentari", json=_body(
|
|
data_prestatie="2026-06-16", vin="WVWZZZ1OZIQ45678",
|
|
))
|
|
assert r.status_code == 200
|
|
id_needs_data = r.json()["results"][0]["submission_id"]
|
|
|
|
lista = client.get("/v1/prezentari", params={
|
|
"status": "queued", "data_de": "2026-06-01", "data_pana": "2026-06-30",
|
|
}).json()["submissions"]
|
|
ids = [s["id"] for s in lista]
|
|
assert id_queued_in_interval in ids
|
|
assert id_needs_data not in ids
|
|
|
|
|
|
def test_interactiune_cu_limit(client):
|
|
"""LIMIT se aplica DUPA filtrarea pe perioada, nu inainte (altfel ar trunchia gresit)."""
|
|
ids_in_interval = [
|
|
_trimite(client, "2026-06-10", vin=f"WVWZZZ1KZAW{i:06d}") for i in range(5)
|
|
]
|
|
# Randuri in afara intervalului, mai recente (ORDER BY id DESC) — daca LIMIT s-ar
|
|
# aplica INAINTE de filtrare, ar "manca" toate randurile din interval.
|
|
for i in range(5):
|
|
_trimite(client, "2026-08-01", vin=f"WVWZZZ1KZBW{i:06d}")
|
|
|
|
r = client.get("/v1/prezentari", params={
|
|
"data_de": "2026-06-01", "data_pana": "2026-06-30", "limit": 3,
|
|
})
|
|
assert r.status_code == 200
|
|
submissions = r.json()["submissions"]
|
|
assert len(submissions) == 3
|
|
ids = [s["id"] for s in submissions]
|
|
assert all(i in ids_in_interval for i in ids)
|
|
|
|
|
|
def test_obs_prezent_in_raspuns(client):
|
|
sid = _trimite(client, "2026-06-15", obs="observatie test")
|
|
|
|
lista = client.get("/v1/prezentari").json()["submissions"]
|
|
rand = next(s for s in lista if s["id"] == sid)
|
|
assert rand["prezentare"]["obs"] == "observatie test"
|
|
|
|
|
|
def test_obs_gol_cand_lipseste(client):
|
|
sid = _trimite(client, "2026-06-15")
|
|
|
|
lista = client.get("/v1/prezentari").json()["submissions"]
|
|
rand = next(s for s in lista if s["id"] == sid)
|
|
assert rand["prezentare"]["obs"] == ""
|