Files
sneakyklaus/tests/integration/test_view_exchange_list.py
Phil Skentelbery f2dc3dfccf feat: add comprehensive tests for Story 2.2 View Exchange List
Add integration tests covering all acceptance criteria:
- Dashboard shows list of all exchanges
- Each exchange displays name, state, participant count, exchange date
- Exchanges sorted by exchange date (upcoming first)
- Visual indicator for exchange state
- Summary counts for draft, active, completed
- Empty state handling

Story: 2.2

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-22 12:49:56 -07:00

323 lines
11 KiB
Python

"""Integration tests for Story 2.2: View Exchange List."""
from datetime import datetime, timedelta
from src.models import Exchange
class TestViewExchangeList:
"""Test cases for viewing exchange list (Story 2.2)."""
def test_dashboard_shows_list_of_exchanges(self, client, db, admin): # noqa: ARG002
"""Test that dashboard displays all exchanges.
Acceptance Criteria:
- Dashboard shows list of all exchanges
"""
# Login first
client.post(
"/admin/login",
data={
"email": "admin@example.com",
"password": "testpassword123",
},
follow_redirects=True,
)
# Create multiple exchanges
future_close_date = datetime.utcnow() + timedelta(days=7)
future_exchange_date = datetime.utcnow() + timedelta(days=14)
exchange1 = Exchange(
slug=Exchange.generate_slug(),
name="Family Christmas 2025",
budget="$20-30",
max_participants=20,
registration_close_date=future_close_date,
exchange_date=future_exchange_date,
timezone="America/New_York",
state=Exchange.STATE_REGISTRATION_OPEN,
)
exchange2 = Exchange(
slug=Exchange.generate_slug(),
name="Office Gift Exchange",
budget="$15-25",
max_participants=15,
registration_close_date=future_close_date + timedelta(days=7),
exchange_date=future_exchange_date + timedelta(days=7),
timezone="America/Chicago",
state=Exchange.STATE_DRAFT,
)
db.session.add(exchange1)
db.session.add(exchange2)
db.session.commit()
# View dashboard
response = client.get("/admin/dashboard")
assert response.status_code == 200
# Verify both exchanges appear
assert b"Family Christmas 2025" in response.data
assert b"Office Gift Exchange" in response.data
def test_dashboard_displays_exchange_info(self, client, db, admin): # noqa: ARG002
"""Test that each exchange displays required information.
Acceptance Criteria:
- Each exchange displays: name, state, participant count, exchange date
"""
# Login first
client.post(
"/admin/login",
data={
"email": "admin@example.com",
"password": "testpassword123",
},
follow_redirects=True,
)
# Create an exchange
future_close_date = datetime.utcnow() + timedelta(days=7)
future_exchange_date = datetime.utcnow() + timedelta(days=14)
exchange = Exchange(
slug=Exchange.generate_slug(),
name="Test Exchange",
budget="$20-30",
max_participants=10,
registration_close_date=future_close_date,
exchange_date=future_exchange_date,
timezone="America/New_York",
state=Exchange.STATE_REGISTRATION_OPEN,
)
db.session.add(exchange)
db.session.commit()
# View dashboard
response = client.get("/admin/dashboard")
assert response.status_code == 200
# Verify exchange information is displayed
assert b"Test Exchange" in response.data
assert b"registration_open" in response.data
assert b"0 / 10" in response.data # Participant count
assert future_exchange_date.strftime("%Y-%m-%d").encode() in response.data
def test_dashboard_sorted_by_exchange_date(self, client, db, admin): # noqa: ARG002
"""Test that exchanges are sorted by exchange date (upcoming first).
Acceptance Criteria:
- Exchanges sorted by exchange date (upcoming first)
"""
# Login first
client.post(
"/admin/login",
data={
"email": "admin@example.com",
"password": "testpassword123",
},
follow_redirects=True,
)
# Create exchanges with different dates
base_close_date = datetime.utcnow() + timedelta(days=7)
# Later exchange
exchange1 = Exchange(
slug=Exchange.generate_slug(),
name="Later Exchange",
budget="$20-30",
max_participants=10,
registration_close_date=base_close_date + timedelta(days=30),
exchange_date=base_close_date + timedelta(days=60), # Far in future
timezone="America/New_York",
state=Exchange.STATE_DRAFT,
)
# Earlier exchange
exchange2 = Exchange(
slug=Exchange.generate_slug(),
name="Earlier Exchange",
budget="$20-30",
max_participants=10,
registration_close_date=base_close_date,
exchange_date=base_close_date + timedelta(days=7), # Sooner
timezone="America/New_York",
state=Exchange.STATE_REGISTRATION_OPEN,
)
db.session.add(exchange1)
db.session.add(exchange2)
db.session.commit()
# View dashboard
response = client.get("/admin/dashboard")
assert response.status_code == 200
# Verify earlier exchange appears before later exchange
response_text = response.data.decode()
earlier_pos = response_text.index("Earlier Exchange")
later_pos = response_text.index("Later Exchange")
assert earlier_pos < later_pos
def test_dashboard_shows_state_indicators(self, client, db, admin): # noqa: ARG002
"""Test that visual indicators for exchange state are displayed.
Acceptance Criteria:
- Visual indicator for exchange state
"""
# Login first
client.post(
"/admin/login",
data={
"email": "admin@example.com",
"password": "testpassword123",
},
follow_redirects=True,
)
# Create exchanges in different states
future_close_date = datetime.utcnow() + timedelta(days=7)
future_exchange_date = datetime.utcnow() + timedelta(days=14)
draft_exchange = Exchange(
slug=Exchange.generate_slug(),
name="Draft Exchange",
budget="$20-30",
max_participants=10,
registration_close_date=future_close_date,
exchange_date=future_exchange_date,
timezone="America/New_York",
state=Exchange.STATE_DRAFT,
)
open_exchange = Exchange(
slug=Exchange.generate_slug(),
name="Open Exchange",
budget="$20-30",
max_participants=10,
registration_close_date=future_close_date,
exchange_date=future_exchange_date,
timezone="America/New_York",
state=Exchange.STATE_REGISTRATION_OPEN,
)
db.session.add(draft_exchange)
db.session.add(open_exchange)
db.session.commit()
# View dashboard
response = client.get("/admin/dashboard")
assert response.status_code == 200
# Verify state indicators are present
assert b"draft" in response.data
assert b"registration_open" in response.data
def test_dashboard_shows_summary_counts(self, client, db, admin): # noqa: ARG002
"""Test that dashboard shows summary counts by state.
Acceptance Criteria:
- Dashboard shows counts for draft, active, and completed exchanges
"""
# Login first
client.post(
"/admin/login",
data={
"email": "admin@example.com",
"password": "testpassword123",
},
follow_redirects=True,
)
# Create exchanges in different states
future_close_date = datetime.utcnow() + timedelta(days=7)
future_exchange_date = datetime.utcnow() + timedelta(days=14)
# 2 draft exchanges
for i in range(2):
exchange = Exchange(
slug=Exchange.generate_slug(),
name=f"Draft Exchange {i}",
budget="$20-30",
max_participants=10,
registration_close_date=future_close_date,
exchange_date=future_exchange_date,
timezone="America/New_York",
state=Exchange.STATE_DRAFT,
)
db.session.add(exchange)
# 3 active exchanges (registration_open)
for i in range(3):
exchange = Exchange(
slug=Exchange.generate_slug(),
name=f"Active Exchange {i}",
budget="$20-30",
max_participants=10,
registration_close_date=future_close_date,
exchange_date=future_exchange_date,
timezone="America/New_York",
state=Exchange.STATE_REGISTRATION_OPEN,
)
db.session.add(exchange)
# 1 completed exchange
completed_exchange = Exchange(
slug=Exchange.generate_slug(),
name="Completed Exchange",
budget="$20-30",
max_participants=10,
registration_close_date=future_close_date - timedelta(days=30),
exchange_date=future_exchange_date - timedelta(days=20),
timezone="America/New_York",
state=Exchange.STATE_COMPLETED,
)
db.session.add(completed_exchange)
db.session.commit()
# View dashboard
response = client.get("/admin/dashboard")
assert response.status_code == 200
# Verify counts are displayed
response_text = response.data.decode()
# Look for summary section with counts
assert "2" in response_text # draft_count
assert "3" in response_text # active_count
assert "1" in response_text # completed_count
def test_dashboard_empty_state(self, client, db, admin): # noqa: ARG002
"""Test dashboard when no exchanges exist.
Acceptance Criteria:
- Show helpful message when no exchanges exist
- Link to create first exchange
"""
# Login first
client.post(
"/admin/login",
data={
"email": "admin@example.com",
"password": "testpassword123",
},
follow_redirects=True,
)
# View dashboard with no exchanges
response = client.get("/admin/dashboard")
assert response.status_code == 200
# Verify empty state message
assert (
b"No exchanges yet" in response.data
or b"no exchanges" in response.data.lower()
)
# Verify link to create exchange
assert b"Create" in response.data or b"create" in response.data.lower()