AURORA-1885: админ получает ВСП по id включая удалённые; прошедшая дата закрытия сразу закрывает ВСП #328
@ -32,7 +32,9 @@ class VSPRepository:
|
||||
load_org_unit: bool = False,
|
||||
with_deleted: bool = False,
|
||||
) -> Optional[Vsp]:
|
||||
queries = [Vsp.id == vsp_id, Vsp.is_deleted.is_(with_deleted)]
|
||||
queries = [Vsp.id == vsp_id]
|
||||
if not with_deleted:
|
||||
queries.append(Vsp.is_deleted.is_(False))
|
||||
if is_active is not None:
|
||||
queries.append(Vsp.is_active == is_active)
|
||||
if load_org_unit:
|
||||
|
||||
@ -264,7 +264,7 @@ class VSPService:
|
||||
if not set(data.keys()).issubset(self.EXECUTOR_EDITABLE_FIELDS):
|
||||
raise AccessDeniedException()
|
||||
|
||||
effective_close_date = data.get("close_date", vsp.closed_at)
|
||||
effective_close_date = data.get("closed_at", vsp.closed_at)
|
||||
if effective_close_date is not None and effective_close_date <= date.today():
|
||||
data["is_active"] = False
|
||||
|
||||
|
||||
@ -293,3 +293,63 @@ def test_vsp_delete_forbidden_for_executor(client, isp_tokens, auth_headers):
|
||||
def test_vsp_requires_auth(client):
|
||||
response = client.get("/api/v1/dict/info")
|
||||
assert response.status_code == 403
|
||||
|
||||
|
||||
def _create_vsp(client, admin_tokens, auth_headers, **extra) -> int:
|
||||
created = client.post(
|
||||
"/api/v1/dict/info",
|
||||
json={
|
||||
"registration_number": _unique_reg_number(),
|
||||
"address": "AURORA-1885",
|
||||
"ssp_id": 1,
|
||||
**extra,
|
||||
},
|
||||
headers=auth_headers(admin_tokens),
|
||||
)
|
||||
assert created.status_code == 201
|
||||
return created.json()["result"]["id"]
|
||||
|
||||
|
||||
def test_vsp_get_by_id_admin_active(client, admin_tokens, auth_headers):
|
||||
vsp_id = _create_vsp(client, admin_tokens, auth_headers)
|
||||
response = client.get(f"/api/v1/dict/info/{vsp_id}", headers=auth_headers(admin_tokens))
|
||||
assert response.status_code == 200
|
||||
assert response.json()["result"]["id"] == vsp_id
|
||||
assert response.json()["result"]["is_deleted"] is False
|
||||
|
||||
|
||||
def test_vsp_get_by_id_admin_sees_deleted(client, admin_tokens, auth_headers):
|
||||
vsp_id = _create_vsp(client, admin_tokens, auth_headers)
|
||||
deleted = client.delete(f"/api/v1/dict/info/{vsp_id}", headers=auth_headers(admin_tokens))
|
||||
assert deleted.status_code == 200
|
||||
|
||||
response = client.get(f"/api/v1/dict/info/{vsp_id}", headers=auth_headers(admin_tokens))
|
||||
assert response.status_code == 200
|
||||
assert response.json()["result"]["is_deleted"] is True
|
||||
|
||||
|
||||
def test_vsp_get_by_id_executor_deleted_not_found(client, admin_tokens, isp_tokens, auth_headers):
|
||||
vsp_id = _create_vsp(client, admin_tokens, auth_headers)
|
||||
client.delete(f"/api/v1/dict/info/{vsp_id}", headers=auth_headers(admin_tokens))
|
||||
|
||||
response = client.get(f"/api/v1/dict/info/{vsp_id}", headers=auth_headers(isp_tokens))
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
def test_vsp_update_past_close_date_deactivates(client, admin_tokens, auth_headers):
|
||||
from datetime import date, timedelta
|
||||
|
||||
vsp_id = _create_vsp(client, admin_tokens, auth_headers, open_date="2020-01-01")
|
||||
yesterday = (date.today() - timedelta(days=1)).isoformat()
|
||||
|
||||
response = client.put(
|
||||
f"/api/v1/dict/info/{vsp_id}",
|
||||
json={"close_date": yesterday},
|
||||
headers=auth_headers(admin_tokens),
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json()["result"]["is_active"] is False
|
||||
|
||||
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"]]
|
||||
|
||||
45
api/tests/unit/test_vsp_service_close_date.py
Normal file
45
api/tests/unit/test_vsp_service_close_date.py
Normal file
@ -0,0 +1,45 @@
|
||||
from datetime import date, timedelta
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
from src.db.models import UserRoleEnum
|
||||
from src.domain.schemas import VSPUpdate
|
||||
from src.services.vsp_service import VSPService
|
||||
|
||||
|
||||
def _service(vsp) -> VSPService:
|
||||
service = VSPService.__new__(VSPService)
|
||||
service.vsp_repo = MagicMock()
|
||||
service.vsp_repo.get = AsyncMock(return_value=vsp)
|
||||
service.vsp_repo.update = AsyncMock(return_value=vsp)
|
||||
return service
|
||||
|
||||
|
||||
def _admin():
|
||||
user = MagicMock()
|
||||
user.id = 1
|
||||
user.role_id = UserRoleEnum.ADMIN
|
||||
return user
|
||||
|
||||
|
||||
async def test_update_past_close_date_sets_inactive():
|
||||
vsp = MagicMock(closed_at=None)
|
||||
service = _service(vsp)
|
||||
payload = VSPUpdate(close_date=date.today() - timedelta(days=1))
|
||||
|
||||
await service.update(vsp_id=1, payload=payload, user=_admin())
|
||||
|
||||
data = service.vsp_repo.update.await_args.kwargs["data"]
|
||||
assert data["is_active"] is False
|
||||
|
||||
|
||||
async def test_update_future_close_date_keeps_active_key_absent():
|
||||
vsp = MagicMock(closed_at=None)
|
||||
service = _service(vsp)
|
||||
payload = VSPUpdate(close_date=date.today() + timedelta(days=30))
|
||||
|
||||
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
|
||||
Loading…
x
Reference in New Issue
Block a user