Files
Ten31-Portal/backend/tests/test_stakes.py
T
Jonathan Kirkwood f0f8fd15c6 Release 0.2.22: capital chart, Investor View, GP stakes, doc folders
Snapshot commit bringing the uncommitted phase-2 work into version control
together with four new features and the 0.2.22 version bump.

New features:
- Investor capital-over-time chart (value, paid-in, distributions per
  quarter), rendered from existing capital-account history.
- Admin Investor View: read-only reconstruction of an investor's portal
  (GET /api/users/{id}/investor-view), reusing the investor portal UI.
- Document upload scoped to the selected fund's own investors, with an
  explicit upload-target confirmation to prevent mis-attaching.
- GP/mgmt entities gain an Assets tab listing their stakes in the funds
  they manage (new entity_stakes table + /api/entities/{id}/stakes).
- Edit-entity form (change type/status/etc.), so GP entities can be
  categorized correctly.

Verified: 11/11 backend tests pass; alembic upgrades to head b8c9d0e1f2a3;
frontend tsc + vite build clean; s9pk packs at 0.2.22:0 (x86_64).
Also: ignore .DS_Store and *.s9pk artifacts.
2026-07-01 14:25:50 -05:00

42 lines
1.4 KiB
Python

"""Entity stakes: a GP entity's interest in the funds it manages."""
from ten31portal.models import Entity, EntityType
def test_stake_crud(auth_client, session):
gp = Entity(name="Ten31 LLC", type=EntityType.gp)
fund = Entity(name="LTPF I", type=EntityType.fund)
session.add(gp)
session.add(fund)
session.commit()
session.refresh(gp)
session.refresh(fund)
created = auth_client.post(
f"/api/entities/{gp.id}/stakes",
json={"fund_entity_id": fund.id, "ownership_pct": 20, "value_dollars": 1000},
)
assert created.status_code == 201, created.text
body = created.json()
assert body["fund_name"] == "LTPF I"
assert body["fund_type"] == "fund"
assert body["value_cents"] == 100_000 # dollars -> cents
stake_id = body["id"]
listed = auth_client.get(f"/api/entities/{gp.id}/stakes")
assert listed.status_code == 200
assert len(listed.json()) == 1
# An entity cannot hold a stake in itself.
assert auth_client.post(
f"/api/entities/{gp.id}/stakes", json={"fund_entity_id": gp.id}
).status_code == 400
# Duplicate stake rejected.
assert auth_client.post(
f"/api/entities/{gp.id}/stakes", json={"fund_entity_id": fund.id}
).status_code == 409
assert auth_client.delete(f"/api/entities/{gp.id}/stakes/{stake_id}").status_code == 200
assert auth_client.get(f"/api/entities/{gp.id}/stakes").json() == []