93 lines
3.8 KiB
Python
93 lines
3.8 KiB
Python
# backend/tests/repositories/test_classification.py
|
||
# ------------------------------------------------------------
|
||
# Pytest suite for the ClassificationRepository.
|
||
# ------------------------------------------------------------
|
||
|
||
import pytest
|
||
from backend.models import Classification as ClassificationModel
|
||
from backend.repositories import ClassificationRepository
|
||
|
||
|
||
# ----------------------------------------------------------------------
|
||
# 1️⃣ Basic CRUD – create & get_by_id
|
||
# ----------------------------------------------------------------------
|
||
def test_create_and_get_by_id(classification_repo):
|
||
new = classification_repo.create("Countertenor")
|
||
assert isinstance(new.ClassificationId, int) and new.ClassificationId > 0
|
||
assert new.ClassificationName == "Countertenor"
|
||
|
||
fetched = classification_repo.get_by_id(new.ClassificationId)
|
||
assert fetched is not None
|
||
assert fetched.ClassificationId == new.ClassificationId
|
||
assert fetched.ClassificationName == "Countertenor"
|
||
|
||
|
||
# ----------------------------------------------------------------------
|
||
# 2️⃣ Lookup by name (exact match)
|
||
# ----------------------------------------------------------------------
|
||
def test_find_by_name_existing(classification_repo):
|
||
soprano = classification_repo.find_by_name("Soprano")
|
||
assert soprano is not None
|
||
assert soprano.ClassificationName == "Soprano"
|
||
|
||
|
||
def test_find_by_name_missing(classification_repo):
|
||
missing = classification_repo.find_by_name("Bass")
|
||
assert missing is None
|
||
|
||
|
||
# ----------------------------------------------------------------------
|
||
# 3️⃣ List all classifications (ordered alphabetically)
|
||
# ----------------------------------------------------------------------
|
||
def test_list_all(classification_repo):
|
||
all_rows: list[ClassificationModel] = classification_repo.list_all()
|
||
assert len(all_rows) == 4 # the four seeded rows
|
||
names = [row.ClassificationName for row in all_rows]
|
||
assert names == sorted(names)
|
||
|
||
|
||
# ----------------------------------------------------------------------
|
||
# 4️⃣ Idempotent helper – ensure_exists
|
||
# ----------------------------------------------------------------------
|
||
def test_ensure_exists_creates_when_missing(classification_repo):
|
||
before = classification_repo.find_by_name("Bass")
|
||
assert before is None
|
||
|
||
bass = classification_repo.ensure_exists("Bass")
|
||
assert isinstance(bass, ClassificationModel)
|
||
assert bass.ClassificationName == "Bass"
|
||
|
||
# second call returns the same row
|
||
again = classification_repo.ensure_exists("Bass")
|
||
assert again.ClassificationId == bass.ClassificationId
|
||
|
||
# total rows = 4 seeded + the new “Bass”
|
||
all_rows = classification_repo.list_all()
|
||
assert len(all_rows) == 5
|
||
|
||
|
||
def test_ensure_exists_returns_existing(classification_repo):
|
||
existing = classification_repo.ensure_exists("Alto / Mezzo")
|
||
assert existing is not None
|
||
assert existing.ClassificationName == "Alto / Mezzo"
|
||
|
||
# no extra rows added
|
||
all_rows = classification_repo.list_all()
|
||
assert len(all_rows) == 4
|
||
|
||
|
||
# ----------------------------------------------------------------------
|
||
# 5️⃣ Delete (optional – demonstrates that the method works)
|
||
# ----------------------------------------------------------------------
|
||
def test_delete(classification_repo):
|
||
temp = classification_repo.create("TempVoice")
|
||
assert classification_repo.find_by_name("TempVoice") is not None
|
||
|
||
classification_repo.delete(temp.ClassificationId)
|
||
assert classification_repo.find_by_name("TempVoice") is None
|
||
|
||
remaining = classification_repo.list_all()
|
||
remaining_names = {r.ClassificationName for r in remaining}
|
||
assert "TempVoice" not in remaining_names
|
||
# the original four seeded names must still be present
|
||
assert {"Soprano", "Alto / Mezzo", "Tenor", "Baritone"} <= remaining_names |