Coverage for tests/route_tests/test_employer.py: 100%
155 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-05-05 14:02 +0000
« prev ^ index » next coverage.py v7.8.0, created at 2025-05-05 14:02 +0000
1"""Test for the employer routes."""
3# pylint: disable=redefined-outer-name
4# flake8: noqa: F811
6import os
7import sys
8import uuid
9from unittest.mock import patch
10from itsdangerous import URLSafeSerializer
11import pytest
12from dotenv import load_dotenv
14# Add the root directory to the Python path
15sys.path.append(
16 os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
17)
19from core import shared
20from core.database_mongo_manager import DatabaseMongoManager
22os.environ["IS_TEST"] = "True"
24load_dotenv()
27@pytest.fixture()
28def client():
29 """Fixture to create a test client."""
30 from ...app import app # pylint: disable=import-outside-toplevel
32 app.config["TESTING"] = True
33 return app.test_client()
36@pytest.fixture()
37def database():
38 """Fixture to create a test database."""
40 database = DatabaseMongoManager(
41 shared.getenv("MONGO_URI"), shared.getenv("MONGO_DB_TEST", "cs3528_testing")
42 )
43 deadlines = database.get_all("deadline")
44 database.delete_all("deadline")
45 yield database
47 database.delete_all("deadline")
48 for deadline in deadlines:
49 database.insert("deadline", deadline)
51 # Cleanup code
52 database.connection.close()
55@pytest.fixture()
56def employer_logged_in_client(client, database: DatabaseMongoManager):
57 """Fixture to login an employer."""
58 database.add_table("employers")
59 database.delete_all_by_field("employers", "email", "dummy@dummy.com")
61 employer = {
62 "_id": uuid.uuid4().hex,
63 "company_name": "dummy",
64 "email": "dummy@dummy.com",
65 }
67 database.insert("employers", employer)
69 url = "/employers/login"
70 client.post(
71 url,
72 data={"email": "dummy@dummy.com"},
73 content_type="application/x-www-form-urlencoded",
74 )
75 otp_serializer = URLSafeSerializer(str(shared.getenv("SECRET_KEY", "secret")))
76 with client.session_transaction() as session:
77 otp = otp_serializer.loads(session["OTP"])
79 url = "/employers/otp"
80 client.post(
81 url,
82 data={"otp": otp},
83 content_type="application/x-www-form-urlencoded",
84 )
86 yield client
88 database.delete_all_by_field("employers", "email", "dummy@dummy.com")
90 with client.session_transaction() as session:
91 session.clear()
94def test_employer_otp_no_login(client):
95 """Test OTP endpoint when employer is not logged in."""
96 response = client.post("/employers/otp", data={"otp": "123456"})
97 assert response.status_code == 400
98 assert response.json == {"error": "Employer not logged in."}
101def test_employer_otp_no_otp(client):
102 """Test OTP endpoint when OTP is not in session."""
103 with client.session_transaction() as session:
104 session["employer"] = {"_id": "123"}
106 response = client.post("/employers/otp", data={"otp": "123456"})
107 assert response.status_code == 400
108 assert response.json == {"error": "OTP not sent."}
111def test_employer_login_page(client):
112 """Test the employer login page."""
113 url = "/employers/login"
115 response = client.get(url)
116 assert response.status_code == 200
119def test_employer_home_page(employer_logged_in_client):
120 """Test the employer home page."""
121 url = "/employers/home"
123 response = employer_logged_in_client.get(url)
124 assert response.status_code == 200
127def test_search_opportunities_page(employer_logged_in_client):
128 """Test the search_opportunities page."""
129 url = "/opportunities/search"
131 response = employer_logged_in_client.get(url)
132 assert response.status_code == 200
135def test_employer_delete_opportunity_page_no_opportunity_id(employer_logged_in_client):
136 """Test the employer_delete_opportunity page."""
137 url = "/opportunities/employer_delete_opportunity"
139 response = employer_logged_in_client.get(url)
140 assert response.status_code == 302
143def test_employers_rank_students_no_opportunity_id(employer_logged_in_client):
144 """Test the rank_students page without providing an opportunity ID."""
146 url = "/employers/rank_students" # No opportunity_id in the request
148 with patch(
149 "app.DEADLINE_MANAGER.is_past_opportunities_ranking_deadline",
150 return_value=False,
151 ):
152 response = employer_logged_in_client.get(url) # GET request
154 assert response.status_code == 400
155 assert response.json == {"error": "Need opportunity ID."}
158def test_employers_rank_students_past_opportunities_deadline(
159 employer_logged_in_client, database
160):
161 """Test the rank_students page."""
162 url = "/employers/rank_students"
164 database.insert("deadline", {"type": 0, "deadline": "2022-10-10"})
165 database.insert("deadline", {"type": 1, "deadline": "2022-10-12"})
166 database.insert("deadline", {"type": 2, "deadline": "2022-10-15"})
168 response = employer_logged_in_client.get(url)
169 assert response.status_code == 200
170 assert b"Ranking deadline has passed as of 2022-10-15" in response.data
173def test_employers_rank_students_wrong_opportunity_id(
174 employer_logged_in_client, database
175):
176 """Test the rank_students page with an incorrect opportunity_id."""
178 url = "/employers/rank_students?opportunity_id=123" # Pass opportunity_id in query string
179 database.delete_all_by_field("opportunities", "_id", "123")
180 database.insert("opportunities", {"_id": "123", "employer_id": "23424"})
182 with patch(
183 "app.DEADLINE_MANAGER.is_past_opportunities_ranking_deadline",
184 return_value=False,
185 ):
186 response = employer_logged_in_client.get(url) # GET request
188 assert response.status_code == 400
189 assert response.json == {"error": "Employer does not own this opportunity."}
191 database.delete_all_by_field("opportunities", "_id", "123")
194def test_employers_rank_students_past_student_ranking_deadline(
195 employer_logged_in_client, database
196):
197 """Test that employers cannot rank students before the student ranking deadline has passed."""
199 url = "/employers/rank_students?opportunity_id=123"
200 database.delete_all_by_field("opportunities", "_id", "123")
201 database.insert("opportunities", {"_id": "123", "employer_id": "test_employer_id"})
203 with employer_logged_in_client.session_transaction() as session:
204 session["employer"] = {"_id": "test_employer_id"}
206 # Use patch directly
207 with patch(
208 "app.DEADLINE_MANAGER.is_past_opportunities_ranking_deadline",
209 return_value=False,
210 ), patch(
211 "app.DEADLINE_MANAGER.is_past_student_ranking_deadline", return_value=False
212 ), patch(
213 "app.DEADLINE_MANAGER.get_student_ranking_deadline", return_value="2025-10-15"
214 ):
216 response = employer_logged_in_client.get(url)
218 assert response.status_code == 200
219 assert (
220 b"Student ranking deadline must have passed before you can start, wait till 2025-10-15"
221 in response.data
222 )
224 database.delete_all_by_field("opportunities", "_id", "123")
227def test_employer_update_opportunity(employer_logged_in_client):
228 """Test the employer_update_opportunity page."""
229 url = "/opportunities/employer_add_update_opportunity"
231 with patch("app.DEADLINE_MANAGER.is_past_details_deadline", return_value=True):
232 response = employer_logged_in_client.get(url)
234 assert response.status_code == 200
235 assert b"Adding/Updating details deadline has passed as of " in response.data
238def test_employer_add_opportunity_post(employer_logged_in_client, database):
239 """Test the employer_update_opportunity page."""
240 url = "/opportunities/employer_add_update_opportunity"
242 database.delete_all_by_field("opportunities", "_id", "123")
243 database.delete_all_by_field("opportunities", "_id", "1234")
244 opportunity = {
245 "_id": "1234",
246 "title": "Software Internship",
247 "description": "A great opportunity to learn.",
248 "url": "https://example.com",
249 "location": "Remote",
250 "modules_required": '["CS101", "CS102"]', # Matches how the request expects it
251 "courses_required": '["Computer_Science"]',
252 "spots_available": 3,
253 "duration": "6_months",
254 }
256 with patch("app.DEADLINE_MANAGER.is_past_details_deadline", return_value=False):
257 response = employer_logged_in_client.post(
258 url, data=opportunity, content_type="application/x-www-form-urlencoded"
259 )
261 assert response.status_code == 200 # Adjust based on actual expected behaviour
262 database.delete_by_id("opportunities", "1234")
263 database.delete_all_by_field("employers", "email", "dummy@dummy,com")
266def test_employer_add_opportunity_post_different_employer_id(
267 employer_logged_in_client, database
268):
269 """Test the employer_update_opportunity page."""
270 url = "/opportunities/employer_add_update_opportunity"
272 database.delete_all_by_field("opportunities", "_id", "123")
273 database.delete_all_by_field("opportunities", "_id", "1234")
274 opportunity = {
275 "_id": "123",
276 "title": "Software Internship",
277 "description": "A great opportunity to learn.",
278 "url": "https://example.com",
279 "location": "Remote",
280 "modules_required": '["CS101", "CS102"]', # Matches how the request expects it
281 "courses_required": '["Computer_Science"]',
282 "spots_available": 3,
283 "duration": "6_months",
284 }
285 database.insert("opportunities", {"_id": "123", "employer_id": "test_employer_id"})
287 with patch("app.DEADLINE_MANAGER.is_past_details_deadline", return_value=False):
288 response = employer_logged_in_client.post(
289 url, data=opportunity, content_type="application/x-www-form-urlencoded"
290 )
292 assert response.status_code == 401
293 assert response.json == {"error": "Unauthorized Access."}
294 database.delete_by_id("opportunities", "123")
295 database.delete_all_by_field("employers", "email", "dummy@dummy,com")
298def test_get_opportunity_page_no_id(employer_logged_in_client):
299 """Test retrieving an opportunity without an ID, ensuring UUID is generated."""
300 url = "/opportunities/employer_add_update_opportunity" # No opportunity_id
302 with patch("app.DEADLINE_MANAGER.is_past_details_deadline", return_value=False):
303 response = employer_logged_in_client.get(url)
305 assert response.status_code == 200
308def test_get_opportunity_page_with_id(employer_logged_in_client, database):
309 """Test retrieving an opportunity with an ID."""
310 url = "/opportunities/employer_add_update_opportunity?opportunity_id=123" # Pass opportunity
312 database.delete_all_by_field("opportunities", "_id", "123")
313 database.insert(
314 "opportunities",
315 {"_id": "123", "employer_id": "test_employer_id", "spots_available": 1},
316 )
318 with patch("app.DEADLINE_MANAGER.is_past_details_deadline", return_value=False):
319 response = employer_logged_in_client.get(url)
321 assert response.status_code == 200
324def test_employers_rank_students_success(employer_logged_in_client, database):
325 """Test the rank_students page."""
326 url = "/employers/rank_students?opportunity_id=123"
327 database.delete_all_by_field("opportunities", "_id", "123")
328 database.insert("opportunities", {"_id": "123", "employer_id": "test_employer_id"})
330 with employer_logged_in_client.session_transaction() as session:
331 session["employer"] = {"_id": "test_employer_id"}
333 with patch(
334 "app.DEADLINE_MANAGER.is_past_opportunities_ranking_deadline",
335 return_value=False,
336 ), patch(
337 "app.DEADLINE_MANAGER.is_past_student_ranking_deadline", return_value=True
338 ):
340 response = employer_logged_in_client.get(url)
342 assert response.status_code == 200
344 database.delete_all_by_field("opportunities", "_id", "123")
345 database.delete_all_by_field("employers", "_id", "test_employer_id")