forked from OurHike/OurHike
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_routers_preferences.py
More file actions
132 lines (96 loc) · 4.41 KB
/
Copy pathtest_routers_preferences.py
File metadata and controls
132 lines (96 loc) · 4.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
"""Tests for GET/PUT /preferences/me, via the real FastAPI TestClient.
See ../../../features/IDENTITY_AND_PRIVACY.md for the canonical
UserPreferences model this syncs. `show_closures` is deliberately never part
of it (Map Options: closures are always shown, never hideable) - several
tests below exist specifically to pin that down at the API boundary.
"""
from datetime import datetime, timedelta, timezone
import jwt
from sqlalchemy import select
from app.config import settings
from app.models.preferences import UserPreferences
TEST_SECRET = settings.supabase_jwt_secret
def _make_token(user_id: str) -> str:
payload = {
"sub": user_id,
"exp": datetime.now(timezone.utc) + timedelta(hours=1),
}
return jwt.encode(payload, TEST_SECRET, algorithm="HS256")
def _auth_headers(user_id: str) -> dict[str, str]:
return {"Authorization": f"Bearer {_make_token(user_id)}"}
def _valid_preferences(**overrides) -> dict:
body = {
"trail_name": "Switchback",
"theme": "dark",
"unit_system": "imperial",
"background_source": "usgs_topo_offline",
"max_background_zoom": 12,
"show_roads": False,
"waypoint_types_shown": ["water", "shelter"],
"layer_detail_level": "standard",
"auto_rotate_enabled": False,
"anonymity_window_days": 14,
"onboarding_completed": True,
"download_choice_made": True,
"location_permission_requested": True,
}
body.update(overrides)
return body
def test_get_preferences_me_requires_authentication(client):
response = client.get("/preferences/me")
assert response.status_code == 401
def test_put_preferences_creates_a_row_on_first_call(client):
user_id = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
put_response = client.put("/preferences/me", json=_valid_preferences(), headers=_auth_headers(user_id))
assert put_response.status_code == 200
body = put_response.json()
assert body["trail_name"] == "Switchback"
assert body["theme"] == "dark"
assert body["max_background_zoom"] == 12
assert "updated_at" in body
get_response = client.get("/preferences/me", headers=_auth_headers(user_id))
assert get_response.status_code == 200
assert get_response.json()["trail_name"] == "Switchback"
def test_put_preferences_upserts_on_a_second_call(client, db_session):
user_id = "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
first = client.put("/preferences/me", json=_valid_preferences(theme="light"), headers=_auth_headers(user_id))
assert first.status_code == 200
second = client.put("/preferences/me", json=_valid_preferences(theme="dark"), headers=_auth_headers(user_id))
assert second.status_code == 200
assert second.json()["theme"] == "dark"
get_response = client.get("/preferences/me", headers=_auth_headers(user_id))
assert get_response.status_code == 200
assert get_response.json()["theme"] == "dark"
# Upsert, not a duplicate row - exactly one row exists for this profile.
rows = db_session.execute(select(UserPreferences).where(UserPreferences.profile_id == user_id)).scalars().all()
assert len(rows) == 1
def test_put_preferences_rejects_an_invalid_theme_value(client):
user_id = "cccccccc-cccc-cccc-cccc-cccccccccccc"
response = client.put(
"/preferences/me",
json=_valid_preferences(theme="solarized"),
headers=_auth_headers(user_id),
)
assert response.status_code == 422
def test_put_preferences_rejects_an_out_of_range_max_background_zoom(client):
user_id = "dddddddd-dddd-dddd-dddd-dddddddddddd"
response = client.put(
"/preferences/me",
json=_valid_preferences(max_background_zoom=14),
headers=_auth_headers(user_id),
)
assert response.status_code == 422
def test_put_preferences_does_not_accept_a_show_closures_field(client):
user_id = "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee"
response = client.put(
"/preferences/me",
json=_valid_preferences(show_closures=False),
headers=_auth_headers(user_id),
)
# extra="forbid" means an unknown field is a real validation error (422),
# not the field being silently dropped and the request otherwise
# succeeding (which would be a 200) - assert the real behavior, not just
# "not silently accepted."
assert response.status_code == 422
body = response.json()
assert any("show_closures" in str(error.get("loc")) for error in body["detail"])