Skip to content

Commit 0cde835

Browse files
committed
Add test script and sample output for contributor profile fix (#3694)
Signed-off-by: antcybersec <anant1234466@gmail.com>
1 parent 56718c1 commit 0cde835

File tree

2 files changed

+144
-0
lines changed

2 files changed

+144
-0
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Test script to demonstrate the contributor profile fix (#3694).
4+
5+
Run from repo root: uv run python scripts/test_contributor_profile_fix.py
6+
7+
Shows that without the fix, a GitHub user response with no 'email' key
8+
causes NameError (canonical_email never set). With the fix, we build
9+
the cntrb dict successfully with email/canonical_email as None.
10+
"""
11+
from augur.tasks.util.AugurUUID import GithubUUID
12+
13+
# Minimal mock of a GitHub /users/:username response when email is NOT public
14+
CONTRIBUTOR_NO_EMAIL = {
15+
"id": 12345,
16+
"login": "testuser",
17+
"node_id": "MDQ6VXNlcjEyMzQ1",
18+
"avatar_url": "https://avatars.githubusercontent.com/u/12345",
19+
"url": "https://api.github.com/users/testuser",
20+
"html_url": "https://github.com/testuser",
21+
"type": "User",
22+
"site_admin": False,
23+
"name": "Test User",
24+
"company": "Acme",
25+
"location": "Earth",
26+
"created_at": "2020-01-01T00:00:00Z",
27+
"updated_at": "2024-01-01T00:00:00Z",
28+
# NO 'email' key - user keeps email private
29+
}
30+
31+
CONTRIBUTOR_WITH_EMAIL = {**CONTRIBUTOR_NO_EMAIL, "email": "test@example.com"}
32+
33+
34+
def old_logic(contributor):
35+
"""Simulates the old code path: canonical_email only set when 'email' in contributor."""
36+
company = None
37+
location = None
38+
email = None
39+
if "company" in contributor:
40+
company = contributor["company"]
41+
if "location" in contributor:
42+
location = contributor["location"]
43+
if "email" in contributor:
44+
email = contributor["email"]
45+
canonical_email = contributor["email"]
46+
# Build cntrb dict - BUG: canonical_email undefined when email missing
47+
return {
48+
"cntrb_email": email,
49+
"cntrb_canonical": canonical_email, # NameError if email was missing
50+
"cntrb_company": company,
51+
"cntrb_location": location,
52+
}
53+
54+
55+
def new_logic(contributor):
56+
"""Current fix: always set canonical_email from email (both can be None)."""
57+
email = contributor.get("email")
58+
canonical_email = email
59+
company = contributor.get("company")
60+
location = contributor.get("location")
61+
full_name = contributor.get("name")
62+
created_at = contributor.get("created_at")
63+
updated_at = contributor.get("updated_at")
64+
return {
65+
"cntrb_email": email,
66+
"cntrb_canonical": canonical_email,
67+
"cntrb_company": company,
68+
"cntrb_location": location,
69+
"cntrb_full_name": full_name,
70+
"cntrb_created_at": created_at,
71+
"cntrb_last_used": updated_at,
72+
}
73+
74+
75+
def main():
76+
print("=== Demonstrating contributor profile fix (#3694) ===\n")
77+
78+
# 1) Old logic with response that HAS email -> works
79+
print("1) OLD logic, contributor WITH email:")
80+
try:
81+
result = old_logic(CONTRIBUTOR_WITH_EMAIL)
82+
print(f" OK: cntrb_canonical = {result['cntrb_canonical']!r}\n")
83+
except Exception as e:
84+
print(f" FAIL: {e}\n")
85+
86+
# 2) Old logic with response that has NO email -> NameError
87+
print("2) OLD logic, contributor WITHOUT email (e.g. private):")
88+
try:
89+
result = old_logic(CONTRIBUTOR_NO_EMAIL)
90+
print(f" OK: cntrb_canonical = {result['cntrb_canonical']!r}\n")
91+
except NameError as e:
92+
print(f" NameError (bug): {e}\n")
93+
except Exception as e:
94+
print(f" FAIL: {type(e).__name__}: {e}\n")
95+
96+
# 3) New logic with no email -> works
97+
print("3) NEW logic, contributor WITHOUT email:")
98+
try:
99+
result = new_logic(CONTRIBUTOR_NO_EMAIL)
100+
print(f" OK: cntrb_email={result['cntrb_email']!r}, cntrb_canonical={result['cntrb_canonical']!r}")
101+
print(f" cntrb_full_name={result['cntrb_full_name']!r}, cntrb_company={result['cntrb_company']!r}\n")
102+
except Exception as e:
103+
print(f" FAIL: {e}\n")
104+
105+
# 4) New logic with email -> still works
106+
print("4) NEW logic, contributor WITH email:")
107+
try:
108+
result = new_logic(CONTRIBUTOR_WITH_EMAIL)
109+
print(f" OK: cntrb_canonical = {result['cntrb_canonical']!r}\n")
110+
except Exception as e:
111+
print(f" FAIL: {e}\n")
112+
113+
print("=== Summary: Without fix, any user with private email causes NameError and failed insert. With fix, all profile fields (including email when present) are stored. ===")
114+
115+
116+
if __name__ == "__main__":
117+
main()
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Test run: contributor profile fix (#3694)
2+
3+
Script: `scripts/test_contributor_profile_fix.py`
4+
Run from repo root: `uv run python scripts/test_contributor_profile_fix.py`
5+
6+
## Output (demonstrates bug without fix, and fix)
7+
8+
```
9+
=== Demonstrating contributor profile fix (#3694) ===
10+
11+
1) OLD logic, contributor WITH email:
12+
OK: cntrb_canonical = 'test@example.com'
13+
14+
2) OLD logic, contributor WITHOUT email (e.g. private):
15+
NameError (bug): cannot access local variable 'canonical_email' where it is not associated with a value
16+
17+
3) NEW logic, contributor WITHOUT email:
18+
OK: cntrb_email=None, cntrb_canonical=None
19+
cntrb_full_name='Test User', cntrb_company='Acme'
20+
21+
4) NEW logic, contributor WITH email:
22+
OK: cntrb_canonical = 'test@example.com'
23+
24+
=== Summary: Without fix, any user with private email causes NameError and failed insert. With fix, all profile fields (including email when present) are stored. ===
25+
```
26+
27+
So: when the GitHub user API omits `email` (e.g. private), the old code raised `NameError` and the contributor was never inserted. The new code handles it and still stores name, company, location, etc.

0 commit comments

Comments
 (0)