33from datetime import date , timedelta
44
55import pytest
6+ from httpx import AsyncClient
67
78from src import load_test_db
89from src .officers .constants import OfficerPositionEnum
1112# TODO: setup a database on the CI machine & run this as a unit test then (since
1213# this isn't really an integration test)
1314
14- # TODO: switch to mark.anyio
15- @pytest .mark .asyncio
16- async def test__read_execs (database_setup ):
17- async with database_setup .session () as db_session :
18- # test that reads from the database succeeded as expected
19- print (type (db_session ))
20- assert (await get_active_officer_terms (db_session , "blarg" )) == []
21- assert (await get_active_officer_terms (db_session , "abc22" )) != []
22-
23- abc11_officer_terms = await get_active_officer_terms (db_session , "abc11" )
24- assert len (abc11_officer_terms ) == 1
25- assert abc11_officer_terms [0 ].computing_id == "abc11"
26- assert abc11_officer_terms [0 ].position == OfficerPositionEnum .EXECUTIVE_AT_LARGE
27- assert abc11_officer_terms [0 ].start_date is not None
28- assert abc11_officer_terms [0 ].nickname == "the holy A"
29- assert abc11_officer_terms [0 ].favourite_course_0 == "CMPT 361"
30- assert abc11_officer_terms [0 ].biography == "Hi! I'm person A and I want school to be over ; _ ;"
31-
32- current_exec_team = await current_officers (db_session )
33- assert current_exec_team is not None
34- assert len (current_exec_team ) == 3
35- # assert next(iter(current_exec_team)) == OfficerPositionEnum.EXECUTIVE_AT_LARGE
36- # assert next(iter(current_exec_team))["favourite_course_0"] == "CMPT 361"
37- # assert next(iter(current_exec_team.values()))[0].csss_email == OfficerPosition.to_email(OfficerPositionEnum.EXECUTIVE_AT_LARGE)
38- # assert next(iter(current_exec_team.values()))[0].private_data is None
39-
40- current_exec_team = await current_officers (db_session )
41- assert current_exec_team is not None
42- assert len (current_exec_team ) == 3
43- # assert next(iter(current_exec_team.keys())) == OfficerPositionEnum.EXECUTIVE_AT_LARGE
44- # assert next(iter(current_exec_team.values()))[0].favourite_course_0 == "CMPT 361"
45- # assert next(iter(current_exec_team.values()))[0].csss_email == OfficerPosition.to_email(OfficerPositionEnum.EXECUTIVE_AT_LARGE)
46- # assert next(iter(current_exec_team.values()))[0].private_data is not None
47- # assert next(iter(current_exec_team.values()))[0].private_data.computing_id == "abc11"
48-
49- all_terms = await all_officers (db_session , include_future_terms = False )
50- assert len (all_terms ) == 8
15+ pytestmark = pytest .mark .asyncio (loop_scope = "session" )
16+
17+ async def test__read_execs (db_session ):
18+ # test that reads from the database succeeded as expected
19+ print (type (db_session ))
20+ assert (await get_active_officer_terms (db_session , "blarg" )) == []
21+ assert (await get_active_officer_terms (db_session , "abc22" )) != []
22+
23+ abc11_officer_terms = await get_active_officer_terms (db_session , "abc11" )
24+ assert len (abc11_officer_terms ) == 1
25+ assert abc11_officer_terms [0 ].computing_id == "abc11"
26+ assert abc11_officer_terms [0 ].position == OfficerPositionEnum .EXECUTIVE_AT_LARGE
27+ assert abc11_officer_terms [0 ].start_date is not None
28+ assert abc11_officer_terms [0 ].nickname == "the holy A"
29+ assert abc11_officer_terms [0 ].favourite_course_0 == "CMPT 361"
30+ assert abc11_officer_terms [0 ].biography == "Hi! I'm person A and I want school to be over ; _ ;"
31+
32+ current_exec_team = await current_officers (db_session )
33+ assert current_exec_team is not None
34+ assert len (current_exec_team ) == 3
35+ # assert next(iter(current_exec_team)) == OfficerPositionEnum.EXECUTIVE_AT_LARGE
36+ # assert next(iter(current_exec_team))["favourite_course_0"] == "CMPT 361"
37+ # assert next(iter(current_exec_team.values()))[0].csss_email == OfficerPosition.to_email(OfficerPositionEnum.EXECUTIVE_AT_LARGE)
38+ # assert next(iter(current_exec_team.values()))[0].private_data is None
39+
40+ current_exec_team = await current_officers (db_session )
41+ assert current_exec_team is not None
42+ assert len (current_exec_team ) == 3
43+ # assert next(iter(current_exec_team.keys())) == OfficerPositionEnum.EXECUTIVE_AT_LARGE
44+ # assert next(iter(current_exec_team.values()))[0].favourite_course_0 == "CMPT 361"
45+ # assert next(iter(current_exec_team.values()))[0].csss_email == OfficerPosition.to_email(OfficerPositionEnum.EXECUTIVE_AT_LARGE)
46+ # assert next(iter(current_exec_team.values()))[0].private_data is not None
47+ # assert next(iter(current_exec_team.values()))[0].private_data.computing_id == "abc11"
48+
49+ all_terms = await all_officers (db_session , include_future_terms = False )
50+ assert len (all_terms ) == 8
5151
5252
5353#async def test__update_execs(database_setup):
5454# # TODO: the second time an update_officer_info call occurs, the user should be updated with info
5555# pass
5656
57- @pytest .mark .asyncio
58- async def test__endpoints (client ):
57+ async def test__get_officers (client ):
58+ # private data shoudn't be leaked
59+ print (f"[DEBUG] Loop ID in { __name__ } : { id (asyncio .get_running_loop ())} " )
5960 response = await client .get ("/officers/current" )
6061 assert response .status_code == 200
6162 assert response .json () != {}
6263 assert len (response .json ().values ()) == 3
63- assert not response .json ()["executive at large" ]["computing_id" ]
64+ assert "computing_id" not in response .json ()[OfficerPositionEnum .EXECUTIVE_AT_LARGE ]
65+ assert "discord_id" not in response .json ()[OfficerPositionEnum .EXECUTIVE_AT_LARGE ]
66+ assert "discord_name" not in response .json ()[OfficerPositionEnum .EXECUTIVE_AT_LARGE ]
67+ assert "discord_nickname" not in response .json ()[OfficerPositionEnum .EXECUTIVE_AT_LARGE ]
68+ assert "phone_number" not in response .json ()[OfficerPositionEnum .EXECUTIVE_AT_LARGE ]
69+ assert "github_username" not in response .json ()[OfficerPositionEnum .EXECUTIVE_AT_LARGE ]
70+ assert "google_drive_email" not in response .json ()[OfficerPositionEnum .EXECUTIVE_AT_LARGE ]
71+ assert "photo_url" not in response .json ()[OfficerPositionEnum .EXECUTIVE_AT_LARGE ]
72+
73+ assert "computing_id" not in response .json ()[OfficerPositionEnum .DIRECTOR_OF_ARCHIVES ]
74+ assert "discord_id" not in response .json ()[OfficerPositionEnum .DIRECTOR_OF_ARCHIVES ]
75+ assert "discord_name" not in response .json ()[OfficerPositionEnum .DIRECTOR_OF_ARCHIVES ]
76+ assert "discord_nickname" not in response .json ()[OfficerPositionEnum .DIRECTOR_OF_ARCHIVES ]
77+ assert "phone_number" not in response .json ()[OfficerPositionEnum .DIRECTOR_OF_ARCHIVES ]
78+ assert "github_username" not in response .json ()[OfficerPositionEnum .DIRECTOR_OF_ARCHIVES ]
79+ assert "google_drive_email" not in response .json ()[OfficerPositionEnum .DIRECTOR_OF_ARCHIVES ]
80+ assert "photo_url" not in response .json ()[OfficerPositionEnum .DIRECTOR_OF_ARCHIVES ]
81+
82+ assert "computing_id" not in response .json ()[OfficerPositionEnum .PRESIDENT ]
83+ assert "discord_id" not in response .json ()[OfficerPositionEnum .PRESIDENT ]
84+ assert "discord_name" not in response .json ()[OfficerPositionEnum .PRESIDENT ]
85+ assert "discord_nickname" not in response .json ()[OfficerPositionEnum .PRESIDENT ]
86+ assert "phone_number" not in response .json ()[OfficerPositionEnum .PRESIDENT ]
87+ assert "github_username" not in response .json ()[OfficerPositionEnum .PRESIDENT ]
88+ assert "google_drive_email" not in response .json ()[OfficerPositionEnum .PRESIDENT ]
89+ assert "photo_url" not in response .json ()[OfficerPositionEnum .PRESIDENT ]
6490
6591 response = await client .get ("/officers/all?include_future_terms=false" )
6692 assert response .status_code == 200
6793 assert response .json () != []
68- assert len (response .json ()) == 6
69- assert response .json ()[0 ]["private_data" ] is None
94+ assert len (response .json ()) == 8
95+ assert "computing_id" not in response .json ()[0 ]
96+ assert "discord_id" not in response .json ()[0 ]
97+ assert "discord_name" not in response .json ()[0 ]
98+ assert "discord_nickname" not in response .json ()[0 ]
99+ assert "phone_number" not in response .json ()[0 ]
100+ assert "github_username" not in response .json ()[0 ]
101+ assert "google_drive_email" not in response .json ()[0 ]
102+ assert "photo_url" not in response .json ()[0 ]
70103
71104 response = await client .get ("/officers/all?include_future_terms=true" )
72105 assert response .status_code == 401
73106
107+ async def test__get_officer_terms (client : AsyncClient ):
74108 response = await client .get (f"/officers/terms/{ load_test_db .SYSADMIN_COMPUTING_ID } ?include_future_terms=false" )
75109 assert response .status_code == 200
76- assert response .json () != []
77110 assert len (response .json ()) == 2
78111 assert response .json ()[0 ]["nickname" ] == "G2"
79112 assert response .json ()[1 ]["nickname" ] == "G1"
80113
81114 response = await client .get ("/officers/terms/balargho?include_future_terms=false" )
82115 assert response .status_code == 200
83- assert response .json () == []
116+ assert len ( response .json ()) == 0
84117
85118 response = await client .get ("/officers/terms/abc11?include_future_terms=true" )
86119 assert response .status_code == 401
@@ -90,28 +123,35 @@ async def test__endpoints(client):
90123 response = await client .get (f"/officers/info/{ load_test_db .SYSADMIN_COMPUTING_ID } " )
91124 assert response .status_code == 401
92125
93- response = await client .post ("officers/term" , content = json .dumps ([{
126+ async def test__post_officer_terms (client : AsyncClient ):
127+ # Only admins can create new terms
128+ response = await client .post ("officers/term" , json = [{
94129 "computing_id" : "ehbc12" ,
95130 "position" : OfficerPositionEnum .DIRECTOR_OF_MULTIMEDIA ,
96- "start_date" : "2025-12-29"
97- }]))
131+ "start_date" : "2025-12-29" ,
132+ "legal_name" : "Eh Bc"
133+ }])
98134 assert response .status_code == 401
99135
100- response = await client .post ("officers/term" , content = json .dumps ([{
136+ # Position must be one of the enum positions
137+ response = await client .post ("officers/term" , json = [{
101138 "computing_id" : "ehbc12" ,
102139 "position" : "balargho" ,
103- "start_date" : "2025-12-29"
104- }]))
105- assert response .status_code == 400
140+ "start_date" : "2025-12-29" ,
141+ "legal_name" : "Eh Bc"
142+ }])
143+ assert response .status_code == 422
106144
107- response = await client .patch ("officers/info/abc11" , content = json .dumps ({
145+ async def test__patch_officer_terms (client : AsyncClient ):
146+ # Only admins can update new terms
147+ response = await client .patch ("officers/info/abc11" , json = {
108148 "legal_name" : "fancy name" ,
109149 "phone_number" : None ,
110150 "discord_name" : None ,
111151 "github_username" : None ,
112152 "google_drive_email" : None ,
113- }))
114- assert response .status_code == 401
153+ })
154+ assert response .status_code == 403
115155
116156 response = await client .patch ("officers/term/1" , content = json .dumps ({
117157 "computing_id" : "abc11" ,
@@ -127,12 +167,12 @@ async def test__endpoints(client):
127167 "favourite_pl_1" : "5" ,
128168 "biography" : "hello"
129169 }))
130- assert response .status_code == 401
170+ assert response .status_code == 403
131171
132172 response = await client .delete ("officers/term/1" )
133173 assert response .status_code == 401
134174
135- @pytest .mark .asyncio
175+ @pytest .mark .skip
136176async def test__endpoints_admin (client , database_setup , admin_session ):
137177 # login as website admin
138178 session_id = "temp_id_" + load_test_db .SYSADMIN_COMPUTING_ID
0 commit comments