From 72b57a0c538f2551aec8802b184874df9a8a3a3a Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Thu, 12 Nov 2026 11:23:21 +0400 Subject: [PATCH] =?UTF-8?q?test(vsp):=20=D0=BA=D1=80=D0=B0=D1=81=D0=BD?= =?UTF-8?q?=D1=8B=D0=B5=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D0=B2=D0=BE?= =?UTF-8?q?=D0=B7=D0=B2=D1=80=D0=B0=D1=82=D0=B0=20=D0=92=D0=A1=D0=9F=20?= =?UTF-8?q?=D0=B2=20=D0=B4=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D1=83=D1=8E=D1=89?= =?UTF-8?q?=D0=B8=D0=B5=20(AURORA-1886,=20#329)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- api/tests/integration/test_vsp.py | 79 +++++++++++++++++++ api/tests/unit/test_vsp_service_close_date.py | 16 +++- 2 files changed, 93 insertions(+), 2 deletions(-) diff --git a/api/tests/integration/test_vsp.py b/api/tests/integration/test_vsp.py index 4ea505c..5b3670c 100644 --- a/api/tests/integration/test_vsp.py +++ b/api/tests/integration/test_vsp.py @@ -353,3 +353,82 @@ def test_vsp_update_past_close_date_deactivates(client, admin_tokens, auth_heade listing = client.get("/api/v1/dict/info", headers=auth_headers(admin_tokens)) assert listing.status_code == 200 assert vsp_id not in [item["id"] for item in listing.json()["result"]] + + +def _put_vsp(client, admin_tokens, auth_headers, vsp_id, **body): + response = client.put( + f"/api/v1/dict/info/{vsp_id}", json=body, headers=auth_headers(admin_tokens), + ) + assert response.status_code == 200, response.text + return response.json()["result"] + + +def _closed_vsp(client, admin_tokens, auth_headers) -> int: + from datetime import date, timedelta + + vsp_id = _create_vsp(client, admin_tokens, auth_headers, open_date="2020-01-01") + result = _put_vsp( + client, admin_tokens, auth_headers, vsp_id, + close_date=(date.today() - timedelta(days=1)).isoformat(), + ) + assert result["is_active"] is False + return vsp_id + + +def test_vsp_update_clear_close_date_reopens(client, admin_tokens, auth_headers): + vsp_id = _closed_vsp(client, admin_tokens, auth_headers) + + result = _put_vsp(client, admin_tokens, auth_headers, vsp_id, close_date=None) + + assert result["close_date"] is None + assert result["is_active"] is True + listing = client.get("/api/v1/dict/info", headers=auth_headers(admin_tokens)) + assert vsp_id in [item["id"] for item in listing.json()["result"]] + + +def test_vsp_update_future_close_date_reopens(client, admin_tokens, auth_headers): + from datetime import date, timedelta + + vsp_id = _closed_vsp(client, admin_tokens, auth_headers) + future = (date.today() + timedelta(days=30)).isoformat() + + result = _put_vsp(client, admin_tokens, auth_headers, vsp_id, close_date=future) + + assert result["close_date"] == future + assert result["is_active"] is True + + +def test_vsp_update_without_close_date_keeps_it(client, admin_tokens, auth_headers): + from datetime import date, timedelta + + vsp_id = _closed_vsp(client, admin_tokens, auth_headers) + yesterday = (date.today() - timedelta(days=1)).isoformat() + + result = _put_vsp(client, admin_tokens, auth_headers, vsp_id, address="AURORA-1886 new") + + assert result["close_date"] == yesterday + assert result["is_active"] is False + + +def test_vsp_clear_close_date_is_audited(client, admin_tokens, auth_headers, db_session): + from sqlalchemy import text + + vsp_id = _closed_vsp(client, admin_tokens, auth_headers) + _put_vsp(client, admin_tokens, auth_headers, vsp_id, close_date=None) + + async def _last_changes(): + row = ( + await db_session.execute( + text( + "SELECT event_data->'changes' FROM v3.audit_log " + "WHERE event = 'VSP_UPDATE' AND (event_data->>'vsp_id')::int = :id " + "ORDER BY id DESC LIMIT 1" + ), + {"id": vsp_id}, + ) + ).first() + return row[0] + + changes = client.portal.call(_last_changes) + assert changes["closed_at"]["before"] is not None + assert changes["closed_at"]["after"] is None diff --git a/api/tests/unit/test_vsp_service_close_date.py b/api/tests/unit/test_vsp_service_close_date.py index e29814b..1de3674 100644 --- a/api/tests/unit/test_vsp_service_close_date.py +++ b/api/tests/unit/test_vsp_service_close_date.py @@ -34,7 +34,7 @@ async def test_update_past_close_date_sets_inactive(): assert data["is_active"] is False -async def test_update_future_close_date_keeps_active_key_absent(): +async def test_update_future_close_date_sets_active(): vsp = MagicMock(closed_at=None) service = _service(vsp) payload = VSPUpdate(close_date=date.today() + timedelta(days=30)) @@ -42,4 +42,16 @@ async def test_update_future_close_date_keeps_active_key_absent(): await service.update(vsp_id=1, payload=payload, user=_admin()) data = service.vsp_repo.update.await_args.kwargs["data"] - assert "is_active" not in data + assert data["is_active"] is True + + +async def test_update_null_close_date_sets_active(): + vsp = MagicMock(closed_at=date.today() - timedelta(days=1)) + service = _service(vsp) + payload = VSPUpdate(close_date=None) + + await service.update(vsp_id=1, payload=payload, user=_admin()) + + data = service.vsp_repo.update.await_args.kwargs["data"] + assert data["closed_at"] is None + assert data["is_active"] is True