Merge pull request 'feat: Add badge earned info to user profile badges API response' (#159) from typosaurus/157-add-badge-earned-info-to-user-profile-badges-api-response into master
Reviewed-on: #159
This commit is contained in:
commit
e02919a1db
@ -203,7 +203,9 @@ async def profile_page(
|
||||
|
||||
badges = list(get_table("badges").find(user_uid=profile_user["uid"]))
|
||||
for b in badges:
|
||||
b["icon"] = get_badge(b["badge_name"]).get("icon")
|
||||
badge_meta = get_badge(b["badge_name"])
|
||||
b["icon"] = badge_meta.get("icon")
|
||||
b["description"] = badge_meta.get("description")
|
||||
achievements = build_achievements({b["badge_name"] for b in badges})
|
||||
badge_total = sum(group["total"] for group in achievements)
|
||||
badge_earned = sum(group["earned"] for group in achievements)
|
||||
|
||||
@ -68,6 +68,7 @@ class PollOut(_Out):
|
||||
class BadgeOut(_Out):
|
||||
name: Optional[str] = Field(None, alias="badge_name")
|
||||
icon: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
created_at: Optional[str] = None
|
||||
model_config = ConfigDict(populate_by_name=True)
|
||||
|
||||
|
||||
@ -499,3 +499,76 @@ def test_profile_json_xp_fields_boundary_xp(app_server):
|
||||
)
|
||||
|
||||
|
||||
def _signup_badge_user():
|
||||
import time
|
||||
|
||||
name = f"bdgi{int(time.time() * 1000)}"
|
||||
session = requests.Session()
|
||||
session.post(
|
||||
f"{BASE_URL}/auth/signup",
|
||||
data={
|
||||
"username": name,
|
||||
"email": f"{name}@t.dev",
|
||||
"password": "secret123",
|
||||
"confirm_password": "secret123",
|
||||
},
|
||||
allow_redirects=True,
|
||||
)
|
||||
return session, name
|
||||
|
||||
|
||||
def test_profile_badges_json_description_matches_catalog(app_server):
|
||||
from devplacepy.database import get_table, refresh_snapshot
|
||||
from devplacepy.utils import BADGE_CATALOG, award_badge
|
||||
|
||||
session, name = _signup_badge_user()
|
||||
refresh_snapshot()
|
||||
user = get_table("users").find_one(username=name)
|
||||
assert user, f"user {name} not found after signup"
|
||||
award_badge(user["uid"], "First Post")
|
||||
award_badge(user["uid"], "Member")
|
||||
refresh_snapshot()
|
||||
|
||||
r = session.get(
|
||||
f"{BASE_URL}/profile/{name}", headers={"Accept": "application/json"}
|
||||
)
|
||||
assert r.status_code == 200
|
||||
body = r.json()
|
||||
assert "badges" in body, "badges key missing from profile JSON"
|
||||
assert isinstance(body["badges"], list), "badges is not a list"
|
||||
assert body["badges"], "expected at least one badge"
|
||||
for badge in body["badges"]:
|
||||
assert "description" in badge, f"badge missing description key: {badge}"
|
||||
assert badge["description"] is not None, f"badge description is null: {badge}"
|
||||
assert isinstance(badge["description"], str), (
|
||||
f"badge description is not a string: {badge}"
|
||||
)
|
||||
assert badge["description"] == BADGE_CATALOG[badge["name"]]["description"], (
|
||||
f"badge description mismatch: {badge['name']}"
|
||||
)
|
||||
|
||||
|
||||
def test_profile_badge_description_exact_string(app_server):
|
||||
from devplacepy.database import get_table, refresh_snapshot
|
||||
from devplacepy.utils import award_badge
|
||||
|
||||
session, name = _signup_badge_user()
|
||||
refresh_snapshot()
|
||||
user = get_table("users").find_one(username=name)
|
||||
assert user, f"user {name} not found after signup"
|
||||
award_badge(user["uid"], "Cheerleader")
|
||||
refresh_snapshot()
|
||||
|
||||
r = session.get(
|
||||
f"{BASE_URL}/profile/{name}", headers={"Accept": "application/json"}
|
||||
)
|
||||
assert r.status_code == 200
|
||||
badges = r.json()["badges"]
|
||||
cheerleader = [b for b in badges if b["name"] == "Cheerleader"]
|
||||
assert cheerleader, f"Cheerleader badge missing from profile JSON: {badges}"
|
||||
assert cheerleader[0]["description"] == "Reacted 50 times", (
|
||||
f"expected 'Reacted 50 times', got {cheerleader[0]['description']!r}"
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
@ -276,7 +276,7 @@ def test_profile_renders_heatmap_and_streak(app_server):
|
||||
def test_profile_badges_json_has_non_null_names(app_server):
|
||||
import time
|
||||
from devplacepy.database import get_table, refresh_snapshot
|
||||
from devplacepy.utils import award_badge
|
||||
from devplacepy.utils import BADGE_CATALOG, award_badge
|
||||
|
||||
name = f"bdg{int(time.time() * 1000)}"
|
||||
session = requests.Session()
|
||||
@ -309,5 +309,14 @@ def test_profile_badges_json_has_non_null_names(app_server):
|
||||
assert badge["name"] is not None, f"badge name is null: {badge}"
|
||||
assert isinstance(badge["name"], str), f"badge name is not a string: {badge}"
|
||||
assert len(badge["name"]) > 0, f"badge name is empty: {badge}"
|
||||
assert "description" in badge, f"badge missing description key: {badge}"
|
||||
assert badge["description"] is not None, f"badge description is null: {badge}"
|
||||
assert isinstance(badge["description"], str), f"badge description is not a string: {badge}"
|
||||
assert len(badge["description"]) > 0, f"badge description is empty: {badge}"
|
||||
assert badge["description"] == BADGE_CATALOG[badge["name"]]["description"], (
|
||||
f"badge description mismatch: {badge['name']}"
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user