Files
fin-tracker/backend/tests/api/test_portfolios_api.py
T
Dmitry f1f336f94f feat(api): портфели, ручные события, правка инструментов и обзор по скоупам
CRUD портфелей (/portfolios), ручные события (POST /events, DELETE только для manual), PATCH /instruments/{id}, GET /analytics/overview — карточка на каждый скоуп одним запросом. Холдинги отдают logo_url и logo_color. openapi.json обновлён.
2026-09-19 22:13:55 +03:00

114 lines
4.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Portfolio CRUD and the account set over HTTP."""
from factories import make_account
URL = "/api/v1/portfolios"
async def test_create_list_and_replace_accounts(client, auth_headers):
a = await make_account(name="Брокер 1")
b = await make_account(name="Брокер 2")
r = await client.post(
URL, json={"name": " Основной ", "account_ids": [b, a]}, headers=auth_headers
)
assert r.status_code == 201, r.text
created = r.json()
assert created["name"] == "Основной"
assert created["base_currency"] == "RUB"
assert created["account_ids"] == sorted([a, b])
r = await client.get(URL, headers=auth_headers)
assert [p["id"] for p in r.json()] == [created["id"]]
r = await client.put(
f"{URL}/{created['id']}/accounts", json={"account_ids": [b]}, headers=auth_headers
)
assert r.status_code == 200, r.text
assert r.json()["account_ids"] == [b]
r = await client.put(
f"{URL}/{created['id']}/accounts", json={"account_ids": []}, headers=auth_headers
)
assert r.json()["account_ids"] == []
async def test_create_without_accounts_is_allowed(client, auth_headers):
r = await client.post(URL, json={"name": "Пустой"}, headers=auth_headers)
assert r.status_code == 201
assert r.json()["account_ids"] == []
async def test_duplicate_name_is_a_conflict(client, auth_headers):
await client.post(URL, json={"name": "Основной"}, headers=auth_headers)
r = await client.post(URL, json={"name": "Основной"}, headers=auth_headers)
assert r.status_code == 409
assert r.headers["content-type"].startswith("application/problem+json")
async def test_rename_and_rename_conflict(client, auth_headers):
first = (await client.post(URL, json={"name": "Один"}, headers=auth_headers)).json()
await client.post(URL, json={"name": "Два"}, headers=auth_headers)
r = await client.patch(
f"{URL}/{first['id']}", json={"name": "Один и один"}, headers=auth_headers
)
assert r.status_code == 200
assert r.json()["name"] == "Один и один"
r = await client.patch(f"{URL}/{first['id']}", json={"name": "Два"}, headers=auth_headers)
assert r.status_code == 409
r = await client.patch(
f"{URL}/{first['id']}", json={"name": "Один и один"}, headers=auth_headers
)
assert r.status_code == 200 # keeping its own name is not a conflict
async def test_blank_name_is_rejected(client, auth_headers):
r = await client.post(URL, json={"name": " "}, headers=auth_headers)
assert r.status_code == 400
async def test_unknown_account_is_rejected_and_nothing_is_saved(client, auth_headers):
real = await make_account(name="Брокер")
r = await client.post(
URL, json={"name": "Х", "account_ids": [real, 99999]}, headers=auth_headers
)
assert r.status_code == 400
assert "99999" in r.json()["detail"]
assert (await client.get(URL, headers=auth_headers)).json() == []
created = (
await client.post(URL, json={"name": "Х", "account_ids": [real]}, headers=auth_headers)
).json()
r = await client.put(
f"{URL}/{created['id']}/accounts", json={"account_ids": [99999]}, headers=auth_headers
)
assert r.status_code == 400
listed = (await client.get(URL, headers=auth_headers)).json()
assert listed[0]["account_ids"] == [real]
async def test_delete_removes_the_portfolio_but_not_its_accounts(client, auth_headers):
a = await make_account(name="Брокер")
created = (
await client.post(URL, json={"name": "Х", "account_ids": [a]}, headers=auth_headers)
).json()
r = await client.delete(f"{URL}/{created['id']}", headers=auth_headers)
assert r.status_code == 204
assert (await client.get(URL, headers=auth_headers)).json() == []
accounts = (await client.get("/api/v1/accounts", headers=auth_headers)).json()
assert [x["id"] for x in accounts] == [a]
async def test_missing_portfolio_is_404(client, auth_headers):
assert (
await client.patch(f"{URL}/999", json={"name": "Х"}, headers=auth_headers)
).status_code == 404
assert (
await client.put(f"{URL}/999/accounts", json={"account_ids": []}, headers=auth_headers)
).status_code == 404
assert (await client.delete(f"{URL}/999", headers=auth_headers)).status_code == 404