Files
nimbusflow/backend/tests/conftest.py

173 lines
5.9 KiB
Python
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.
# tests/conftest.py
import os
import pytest
# ----------------------------------------------------------------------
# Import the concrete classes from your backend package.
# Adjust the import path if your package layout differs.
# ----------------------------------------------------------------------
from backend.db import DatabaseConnection
from backend.repositories import (
MemberRepository,
ClassificationRepository,
ServiceRepository,
ServiceTypeRepository,
ServiceAvailabilityRepository,
)
# ----------------------------------------------------------------------
# Path to the full schema (DDL) that creates every table, including
# ServiceAvailability.
# ----------------------------------------------------------------------
@pytest.fixture(scope="session")
def schema_path() -> str:
"""Absolute path to the SQL file that creates the test schema."""
return os.path.abspath(
os.path.join(os.path.dirname(__file__), "..", "schema.sql")
)
# ----------------------------------------------------------------------
# Fresh inmemory SQLite DB with the full schema applied.
# ----------------------------------------------------------------------
@pytest.fixture
def db_connection(schema_path: str) -> DatabaseConnection:
conn = DatabaseConnection(":memory:")
# Load the DDL.
with open(schema_path, "r", encoding="utf-8") as f:
ddl = f.read()
conn._conn.executescript(ddl) # apply the whole schema
conn._conn.commit()
yield conn
conn.close()
# ----------------------------------------------------------------------
# Seed lookup tables that have foreignkey relationships.
# ----------------------------------------------------------------------
@pytest.fixture
def seed_lookup_tables(db_connection: DatabaseConnection):
"""
Insert rows into lookup tables that other tables reference.
Currently we need:
• Classifications for Member tests
• ServiceTypes for ServiceTypeRepository tests
• ServiceAvailability for the repo we are testing now
"""
# ---- Classifications -------------------------------------------------
classifications = [
("Soprano",), # ClassificationId = 1
("Alto / Mezzo",), # ClassificationId = 2
("Tenor",), # ClassificationId = 3
("Baritone",), # ClassificationId = 4
]
for name in classifications:
db_connection.execute(
"INSERT INTO Classifications (ClassificationName) VALUES (?)",
name,
)
# ---- ServiceTypes ----------------------------------------------------
# These are the three timeslot examples you asked for.
service_types = [("9AM",), ("11AM",), ("6PM",)]
for name in service_types:
db_connection.execute(
"INSERT INTO ServiceTypes (TypeName) VALUES (?)",
name,
)
# ---- ServiceAvailability ---------------------------------------------
# We need a couple of members first, otherwise the FK constraints will
# reject the inserts. We'll create two dummy members (Alice = 1,
# Bob = 2) and then map them to the three slots.
#
# NOTE: In a real test suite you would probably use the MemberRepository
# to create these rows, but inserting directly keeps the fixture fast and
# independent of the Member repo implementation.
dummy_members = [
("Alice", "Smith", "alice@example.com", None, None, 1, None, 1),
("Bob", "Jones", "bob@example.com", None, None, 2, None, 1),
]
for (
fn, ln, email, phone, notes,
classification_id, is_active, member_id_placeholder,
) in dummy_members:
# The MemberId column is AUTOINCREMENT, so we omit it.
db_connection.execute(
"""
INSERT INTO Members
(FirstName, LastName, Email, PhoneNumber, Notes,
ClassificationId, IsActive)
VALUES (?, ?, ?, ?, ?, ?, ?)
""",
(fn, ln, email, phone, notes, classification_id, is_active),
)
# At this point SQLite has assigned MemberIds 1 and 2.
# Map them to the three servicetype slots:
# Alice → 9AM (id=1) and 6PM (id=3)
# Bob → 11AM (id=2) and 6PM (id=3)
availability = [
(1, 1), # Alice 9AM
(1, 3), # Alice 6PM
(2, 2), # Bob 11AM
(2, 3), # Bob 6PM
]
for member_id, service_type_id in availability:
db_connection.execute(
"""
INSERT INTO ServiceAvailability (MemberId, ServiceTypeId)
VALUES (?, ?)
""",
(member_id, service_type_id),
)
# Commit everything so downstream fixtures see the data.
db_connection._conn.commit()
# ----------------------------------------------------------------------
# Repository factories each receives the same fresh DB that already has
# the lookup data seeded.
# ----------------------------------------------------------------------
@pytest.fixture
def member_repo(
db_connection: DatabaseConnection,
seed_lookup_tables,
) -> MemberRepository:
return MemberRepository(db_connection)
@pytest.fixture
def classification_repo(
db_connection: DatabaseConnection,
seed_lookup_tables,
) -> ClassificationRepository:
return ClassificationRepository(db_connection)
@pytest.fixture
def service_type_repo(
db_connection: DatabaseConnection,
seed_lookup_tables,
) -> ServiceTypeRepository:
return ServiceTypeRepository(db_connection)
@pytest.fixture
def service_repo(
db_connection: DatabaseConnection,
seed_lookup_tables,
) -> ServiceRepository:
return ServiceRepository(db_connection)
@pytest.fixture
def service_availability_repo(
db_connection: DatabaseConnection,
seed_lookup_tables,
) -> ServiceAvailabilityRepository:
return ServiceAvailabilityRepository(db_connection)