Skip to content

Commit 1e8cf69

Browse files
committed
rankings: basically done - some minor fixes and test changes. still need to add logic for having some sort of status taht determines when to show the intake form, when to show the intake thank you form, when to show ranking form, and when to show ranking thank you form after login as well as gating certain pages when not authed or wrong status
1 parent d271125 commit 1e8cf69

File tree

5 files changed

+67
-26
lines changed

5 files changed

+67
-26
lines changed

.github/workflows/backend-ci.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
test:
1717
runs-on: ubuntu-latest
1818
env:
19-
POSTGRES_DATABASE_URL: postgresql://testuser:testpassword@localhost:5432/llsc_test
19+
POSTGRES_TEST_DATABASE_URL: postgresql://testuser:testpassword@localhost:5432/llsc_test
2020

2121
strategy:
2222
matrix:
@@ -65,13 +65,14 @@ jobs:
6565
- name: Set up environment variables
6666
working-directory: ./backend
6767
run: |
68-
echo "POSTGRES_DATABASE_URL=postgresql://testuser:testpassword@localhost:5432/llsc_test" >> .env
68+
echo "POSTGRES_TEST_DATABASE_URL=postgresql://testuser:testpassword@localhost:5432/llsc_test" >> .env
6969
echo "SECRET_KEY=test-secret-key-for-ci" >> .env
7070
echo "ENVIRONMENT=test" >> .env
7171
7272
- name: Run database migrations
7373
working-directory: ./backend
7474
run: |
75+
export POSTGRES_DATABASE_URL="$POSTGRES_TEST_DATABASE_URL"
7576
pdm run alembic upgrade heads
7677
7778
- name: Run linting
@@ -118,7 +119,7 @@ jobs:
118119
runs-on: ubuntu-latest
119120
needs: test
120121
env:
121-
POSTGRES_DATABASE_URL: postgresql://testuser:testpassword@localhost:5432/llsc_test
122+
POSTGRES_TEST_DATABASE_URL: postgresql://testuser:testpassword@localhost:5432/llsc_test
122123

123124
services:
124125
postgres:
@@ -155,7 +156,7 @@ jobs:
155156
- name: Set up environment variables
156157
working-directory: ./backend
157158
run: |
158-
echo "POSTGRES_DATABASE_URL=postgresql://testuser:testpassword@localhost:5432/llsc_test" >> .env
159+
echo "POSTGRES_TEST_DATABASE_URL=postgresql://testuser:testpassword@localhost:5432/llsc_test" >> .env
159160
echo "SECRET_KEY=test-secret-key-for-ci" >> .env
160161
echo "ENVIRONMENT=test" >> .env
161162
echo "TEST_SCRIPT_BACKEND_URL=http://localhost:8000" >> .env
@@ -165,6 +166,7 @@ jobs:
165166
- name: Run database migrations
166167
working-directory: ./backend
167168
run: |
169+
export POSTGRES_DATABASE_URL="$POSTGRES_TEST_DATABASE_URL"
168170
pdm run alembic upgrade heads
169171
170172
- name: Start backend server

backend/tests/unit/test_ranking_service.py

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,19 @@
33

44
import pytest
55
from sqlalchemy import create_engine, text
6+
from sqlalchemy.exc import IntegrityError
67
from sqlalchemy.orm import Session, sessionmaker
78

89
from app.models import Experience, Quality, Role, Treatment, User, UserData
910
from app.schemas.user import UserRole
1011
from app.services.implementations.ranking_service import RankingService
1112

1213
# Postgres-only configuration (migrations assumed to be applied)
13-
POSTGRES_DATABASE_URL = os.getenv("POSTGRES_DATABASE_URL")
14+
POSTGRES_DATABASE_URL = os.getenv("POSTGRES_TEST_DATABASE_URL")
1415
if not POSTGRES_DATABASE_URL:
1516
raise RuntimeError(
1617
"POSTGRES_DATABASE_URL is not set. Please export a Postgres URL, e.g. "
17-
"postgresql+psycopg2://postgres:postgres@localhost:5432/llsc"
18+
"postgresql+psycopg2://postgres:postgres@db:5432/llsc_test"
1819
)
1920
engine = create_engine(POSTGRES_DATABASE_URL)
2021
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
@@ -48,6 +49,19 @@ def db_session() -> Session:
4849
# Qualities should have been seeded by migrations; assert presence
4950
assert session.query(Quality).count() >= 6
5051

52+
# Ensure sequences are aligned after seeding (avoid PK collisions when inserting)
53+
session.execute(
54+
text(
55+
"SELECT setval(pg_get_serial_sequence('treatments','id'), COALESCE((SELECT MAX(id) FROM treatments), 0))"
56+
)
57+
)
58+
session.execute(
59+
text(
60+
"SELECT setval(pg_get_serial_sequence('experiences','id'), COALESCE((SELECT MAX(id) FROM experiences), 0))"
61+
)
62+
)
63+
session.commit()
64+
5165
yield session
5266
finally:
5367
session.rollback()
@@ -84,19 +98,39 @@ def _add_user_data(
8498

8599
def get_or_create_treatment(name: str) -> Treatment:
86100
t = session.query(Treatment).filter(Treatment.name == name).first()
87-
if not t:
88-
t = Treatment(name=name)
89-
session.add(t)
90-
session.flush()
91-
return t
101+
if t:
102+
return t
103+
for _ in range(2):
104+
try:
105+
t = Treatment(name=name)
106+
session.add(t)
107+
session.flush()
108+
return t
109+
except IntegrityError:
110+
session.rollback()
111+
# Sequence collision consumed an id; retry insert
112+
t = session.query(Treatment).filter(Treatment.name == name).first()
113+
if t:
114+
return t
115+
# Final attempt to read existing
116+
return session.query(Treatment).filter(Treatment.name == name).first()
92117

93118
def get_or_create_experience(name: str) -> Experience:
94119
e = session.query(Experience).filter(Experience.name == name).first()
95-
if not e:
96-
e = Experience(name=name)
97-
session.add(e)
98-
session.flush()
99-
return e
120+
if e:
121+
return e
122+
for _ in range(2):
123+
try:
124+
e = Experience(name=name)
125+
session.add(e)
126+
session.flush()
127+
return e
128+
except IntegrityError:
129+
session.rollback()
130+
e = session.query(Experience).filter(Experience.name == name).first()
131+
if e:
132+
return e
133+
return session.query(Experience).filter(Experience.name == name).first()
100134

101135
for n in self_treatments or []:
102136
data.treatments.append(get_or_create_treatment(n))
@@ -142,7 +176,7 @@ async def test_options_caregiver_without_cancer(db_session: Session):
142176
auth_id="auth_cg_no_cancer",
143177
has_blood_cancer="no",
144178
caring_for_someone="yes",
145-
self_treatments=["Chemo Pills"],
179+
self_treatments=["Oral Chemotherapy"],
146180
self_experiences=["Caregiver Fatigue"],
147181
loved_one_diagnosis="CLL",
148182
loved_treatments=["Immunotherapy"],
@@ -172,7 +206,7 @@ async def test_options_caregiver_with_cancer(db_session: Session):
172206
caring_for_someone="yes",
173207
diagnosis="MDS",
174208
loved_one_diagnosis="MM",
175-
self_treatments=["Radiation"],
209+
self_treatments=["Radiation Therapy"],
176210
self_experiences=["PTSD"],
177211
loved_treatments=["Watch and Wait / Active Surveillance"],
178212
loved_experiences=["Communication Challenges"],

backend/tests/unit/test_user.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@
1919
from app.services.implementations.user_service import UserService
2020

2121
# Test DB Configuration - Always require Postgres for full parity
22-
POSTGRES_DATABASE_URL = os.getenv("POSTGRES_DATABASE_URL")
22+
POSTGRES_DATABASE_URL = os.getenv("POSTGRES_TEST_DATABASE_URL")
2323
if not POSTGRES_DATABASE_URL:
2424
raise RuntimeError(
2525
"POSTGRES_DATABASE_URL is not set. Please export a Postgres URL, e.g. "
26-
"postgresql+psycopg2://postgres:postgres@localhost:5432/llsc"
26+
"postgresql+psycopg2://postgres:postgres@db:5432/llsc_test"
2727
)
2828
engine = create_engine(POSTGRES_DATABASE_URL)
2929
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
@@ -533,11 +533,10 @@ async def test_update_user_by_id(db_session):
533533
db_session.rollback()
534534
raise
535535

536-
537536
# Error case tests
538537
@pytest.mark.asyncio
539538
async def test_delete_nonexistent_user_by_email(db_session):
540-
"""Test deleting a non-existent user by email"""
539+
"""Test deleting a non-existent user"""
541540
user_service = UserService(db_session)
542541
with pytest.raises(HTTPException) as exc_info:
543542
await user_service.delete_user_by_email("[email protected]")
@@ -546,7 +545,7 @@ async def test_delete_nonexistent_user_by_email(db_session):
546545

547546
@pytest.mark.asyncio
548547
async def test_delete_nonexistent_user_by_id(db_session):
549-
"""Test deleting a non-existent user by ID"""
548+
"""Test deleting a non-existent user"""
550549
user_service = UserService(db_session)
551550
with pytest.raises(HTTPException) as exc_info:
552551
await user_service.delete_user_by_id("00000000-0000-0000-0000-000000000000")
@@ -563,7 +562,7 @@ async def test_get_nonexistent_user_by_id(db_session):
563562

564563

565564
def test_get_nonexistent_user_by_email(db_session):
566-
"""Test getting a non-existent user by email"""
565+
"""Test getting user by email"""
567566
user_service = UserService(db_session)
568567
with pytest.raises(ValueError) as exc_info:
569568
user_service.get_user_by_email("[email protected]")

frontend/src/components/ranking/caregiver-ranking-form.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,12 @@ export function CaregiverRankingForm({
2525
const kind = itemKinds?.[index];
2626
const scope = itemScopes?.[index];
2727
const isLovedOneQuality = kind === 'quality' && scope === 'loved_one';
28+
const isLovedOneDynamic = (kind === 'treatment' || kind === 'experience') && scope === 'loved_one';
2829
const prefix = isLovedOneQuality
2930
? 'I would prefer a volunteer whose loved one is '
30-
: 'I would prefer a volunteer with ';
31+
: isLovedOneDynamic
32+
? 'I would prefer a volunteer whose loved one has '
33+
: 'I would prefer a volunteer with ';
3134
return (
3235
<>
3336
{prefix}

frontend/src/components/ranking/volunteer-ranking-form.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,12 @@ export function VolunteerRankingForm({
2525
const kind = itemKinds?.[index];
2626
const scope = itemScopes?.[index];
2727
const isLovedOneQuality = kind === 'quality' && scope === 'loved_one';
28+
const isLovedOneDynamic = (kind === 'treatment' || kind === 'experience') && scope === 'loved_one';
2829
const prefix = isLovedOneQuality
2930
? 'I would prefer a volunteer whose loved one is '
30-
: 'I would prefer a volunteer with ';
31+
: isLovedOneDynamic
32+
? 'I would prefer a volunteer whose loved one has '
33+
: 'I would prefer a volunteer with ';
3134
return (
3235
<>
3336
{prefix}

0 commit comments

Comments
 (0)