test(fixtures): add mileage, payment, expense, credit_note, recurring_invoice, quote

Sixteen tests in tests/test_routes/test_api_v1_*_refactored.py and
test_api_v1_recurring_invoices_credit_notes.py reference fixtures
(mileage, payment, expense, credit_note, recurring_invoice, quote) that
were never defined anywhere — not in conftest.py, not in the test files
themselves. Every affected test fails as ERROR (fixture-setup failure)
with pytest's "fixture not found" message.

Add the missing fixtures to tests/conftest.py, mirroring the existing
patterns used for the `invoice` / `project` / `test_client` fixtures:

- mileage: bound to user + project, populated with minimal valid trip
- expense: bound to user + project, "travel" category, today's date
- payment: bound to the test invoice, completed bank_transfer
- credit_note: bound to invoice + user, unique credit_number derived
  from invoice.id to avoid collisions
- recurring_invoice: monthly retainer template tied to project + client
- quote: draft quote tied to test_client and user

Each fixture commits via the function-scoped app fixture (so it ties
into the per-test sqlite isolation), refreshes the ORM instance, and
returns it. No models touched. No tests touched.

Test plan
- pytest tests/test_routes/test_api_v1_mileage_refactored.py
- pytest tests/test_routes/test_api_v1_payments_refactored.py
- pytest tests/test_routes/test_api_v1_recurring_invoices_credit_notes.py
- pytest tests/test_routes/test_api_v1_invoices_tasks_expenses_refactored.py
- pytest tests/test_routes/test_api_v1_quotes_refactored.py
- All previously-erroring tests should now reach their assertions
This commit is contained in:
MacJediWizard
2026-05-14 17:27:22 -04:00
parent 8f18d3b624
commit 6af9c5ba1a
+127
View File
@@ -801,6 +801,133 @@ def invoice_with_items(app, invoice):
# ============================================================================
@pytest.fixture
def mileage(app, user, project):
"""Create a mileage entry tied to user + project."""
from datetime import date
from decimal import Decimal
from app.models import Mileage
entry = Mileage(
user_id=user.id,
trip_date=date.today(),
purpose="Client visit",
start_location="Office",
end_location="Client Site",
distance_km=Decimal("25.00"),
rate_per_km=Decimal("0.50"),
project_id=project.id,
)
entry.calculated_amount = entry.distance_km * entry.rate_per_km
db.session.add(entry)
db.session.commit()
db.session.refresh(entry)
return entry
@pytest.fixture
def expense(app, user, project):
"""Create an expense tied to user + project."""
from datetime import date
from decimal import Decimal
from app.models import Expense
item = Expense(
user_id=user.id,
title="Test expense",
category="travel",
amount=Decimal("42.50"),
expense_date=date.today(),
project_id=project.id,
)
db.session.add(item)
db.session.commit()
db.session.refresh(item)
return item
@pytest.fixture
def payment(app, invoice):
"""Create a payment recorded against the test invoice."""
from datetime import date
from decimal import Decimal
from app.models import Payment
p = Payment(
invoice_id=invoice.id,
amount=Decimal("100.00"),
payment_date=date.today(),
method="bank_transfer",
status="completed",
)
db.session.add(p)
db.session.commit()
db.session.refresh(p)
return p
@pytest.fixture
def credit_note(app, invoice, user):
"""Create a credit note against the test invoice."""
from decimal import Decimal
from app.models import CreditNote
cn = CreditNote(
invoice_id=invoice.id,
credit_number=f"CN-{invoice.id}-1",
amount=Decimal("25.00"),
reason="Test credit note",
created_by=user.id,
)
db.session.add(cn)
db.session.commit()
db.session.refresh(cn)
return cn
@pytest.fixture
def recurring_invoice(app, project, test_client):
"""Create a recurring invoice template tied to project + client."""
from datetime import date, timedelta
from app.models import RecurringInvoice
ri = RecurringInvoice(
name="Monthly retainer",
project_id=project.id,
client_id=test_client.id,
client_name=test_client.name,
frequency="monthly",
interval=1,
next_run_date=date.today() + timedelta(days=30),
)
db.session.add(ri)
db.session.commit()
db.session.refresh(ri)
return ri
@pytest.fixture
def quote(app, test_client, user):
"""Create a quote tied to the test client."""
from app.models import Quote
q = Quote(
quote_number=f"Q-{test_client.id}-1",
client_id=test_client.id,
title="Test quote",
created_by=user.id,
)
db.session.add(q)
db.session.commit()
db.session.refresh(q)
return q
@pytest.fixture
def authenticated_client(client, user):
"""Create an authenticated test client."""