Coverage for tests/model_tests/test_user.py: 99%
327 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"""Tests for the User model."""
3import os
4import sys
5from dotenv import load_dotenv
6import pytest
7from passlib.hash import pbkdf2_sha512
9from flask import session
12# flake8: noqa: F811
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)
18from core import shared
19from core.database_mongo_manager import DatabaseMongoManager
21os.environ["IS_TEST"] = "True"
23load_dotenv()
26@pytest.fixture()
27def app():
28 """Fixture to create a test client."""
29 from ...app import app # pylint: disable=import-outside-toplevel
31 app.config["TESTING"] = True
32 return app
35@pytest.fixture()
36def user_model():
37 """Fixture to create a user model."""
38 from user.models import User
40 return User()
43@pytest.fixture()
44def database():
45 """Fixture to create a test database."""
47 database = DatabaseMongoManager(
48 shared.getenv("MONGO_URI"), shared.getenv("MONGO_DB_TEST", "cs3528_testing")
49 )
51 yield database
53 tables = [
54 "users",
55 "students",
56 "employers",
57 ]
59 for table in tables:
60 database.delete_all_by_field(table, "email", "dummy@dummy.com")
62 # Cleanup code
63 database.connection.close()
66def test_start_session(app, user_model):
67 """Tests the start_session method of the User model."""
68 user = {
69 "_id": "123",
70 "name": "Test User",
71 "email": "dummy@dummy.com",
72 "password": "password",
73 }
75 with app.app_context():
76 with app.test_request_context(): # Add this line
77 response = user_model.start_session(user)
78 json_data = response[0].get_json()
79 assert response[1] == 200
80 assert json_data["message"] == "/user/home"
81 assert "password" not in json_data
84def test_register_success(app, database, user_model):
85 """Tests the register method of the User model."""
86 database.delete_all_by_field("users", "email", "dummy@dummy.com")
87 user = {
88 "_id": "124",
89 "name": "New User",
90 "email": "dummy@dummy.com",
91 "password": "password",
92 }
94 with app.app_context():
95 with app.test_request_context():
96 session["superuser"] = True
97 response = user_model.register(user)
98 json_data = response[0].get_json()
99 assert response[1] == 201
100 assert json_data["message"] == "User registered successfully"
101 session.clear()
103 # Delete the user from the database
104 database.delete_all_by_field("users", "email", "dummy@dummy.com")
107def test_register_email_in_use(app, database, user_model):
108 """Tests the register method of the User model when the email is already in use."""
109 database.delete_all_by_field("users", "email", "dummy@dummy.com")
110 user = {
111 "_id": "125",
112 "name": "Existing User",
113 "email": "dummy@dummy.com",
114 "password": "password",
115 }
117 database.insert("users", user)
119 with app.app_context():
120 with app.test_request_context():
121 response = user_model.register(user)
122 json_data = response[0].get_json()
123 assert response[1] == 400
124 assert json_data["error"] == "Email address already in use"
126 database.delete_all_by_field("users", "email", "dummy@dummy.com")
129def test_register_failure(app, user_model):
130 """Tests the register method of the User model when
131 the request is missing the email or password."""
133 with app.app_context():
134 with app.test_request_context():
135 response = user_model.register({})
136 json_data = response[0].get_json()
137 assert response[1] == 400
138 assert json_data["error"] == "Missing email or password"
141def test_login_success(app, database, user_model):
142 """Tests the login method of the User model."""
143 database.delete_all_by_field("users", "email", "dummy@dummy.com")
144 user = {
145 "_id": "126",
146 "name": "Login User",
147 "email": "dummy@dummy.com",
148 "password": pbkdf2_sha512.hash("dummy"),
149 }
151 # Insert the user into the database
152 database.insert("users", user)
154 attempt_user = {
155 "email": "dummy@dummy.com",
156 "password": "dummy",
157 }
159 with app.app_context():
160 with app.test_request_context():
161 response = user_model.login(attempt_user)
162 json_data = response[0].get_json()
163 assert "logged_in" in session
164 assert response[1] == 200
165 assert json_data["message"] == "/user/home"
166 assert "password" not in json_data
167 session.clear()
169 database.delete_all_by_field("users", "email", "dummy@dummy.com")
172def test_login_invalid_credentials(app, database, user_model):
173 """Tests the login method of the User model when the credentials are invalid."""
174 database.delete_all_by_field("users", "email", "dummy@dummy.com")
175 user = {
176 "_id": "127",
177 "name": "Invalid User",
178 "email": "dummy@dummy.com",
179 "password": pbkdf2_sha512.hash("password"),
180 }
182 # Insert the user into the database
183 database.insert("users", user)
185 attempt_user = {
186 "email": "dummy@dummy.com",
187 "password": "wrongpassword",
188 }
190 with app.app_context():
191 with app.test_request_context():
192 response = user_model.login(attempt_user)
193 json_data = response[0].get_json()
194 assert response[1] == 401
195 assert json_data["error"] == "Invalid login credentials"
197 database.delete_all_by_field("users", "email", "dummy@dummy.com")
200def test_login_user_not_found(app, database, user_model):
201 """Tests the login method of the User model when the user is not found."""
202 database.delete_all_by_field("users", "email", "dummy@dummy.com")
204 attempt_user = {
205 "email": "dummy@dummy.com",
206 "password": "password",
207 }
209 with app.app_context():
210 with app.test_request_context():
211 response = user_model.login(attempt_user)
212 json_data = response[0].get_json()
213 assert response[1] == 401
214 assert json_data["error"] == "Invalid login credentials"
217def test_update_deadlines_success(app, database, user_model):
218 """Tests the change_deadline method of the User model."""
219 deadlines = database.get_all("deadline")
220 if deadlines:
221 database.delete_all("deadline")
223 database.insert("deadline", {"type": 0, "deadline": "2022-10-10"})
224 database.insert("deadline", {"type": 1, "deadline": "2022-10-12"})
225 database.insert("deadline", {"type": 2, "deadline": "2022-10-15"})
227 with app.app_context():
228 with app.test_request_context():
229 response = user_model.change_deadline(
230 "2023-12-31", "2024-01-15", "2024-01-31"
231 )
232 json_data = response[0].get_json()
233 assert response[1] == 200
234 assert json_data["message"] == "All deadlines updated successfully"
235 assert (
236 database.get_one_by_field("deadline", "type", 0)["deadline"]
237 == "2023-12-31"
238 )
239 assert (
240 database.get_one_by_field("deadline", "type", 1)["deadline"]
241 == "2024-01-15"
242 )
243 assert (
244 database.get_one_by_field("deadline", "type", 2)["deadline"]
245 == "2024-01-31"
246 )
248 database.delete_all("deadline")
249 for deadline in deadlines:
250 database.insert("deadline", deadline)
253def test_update_deadlines_invalid_format(app, database, user_model):
254 """Tests the change_deadline method of the User model with an invalid date format."""
255 deadlines = database.get_all("deadline")
256 if deadlines:
257 database.delete_all("deadline")
259 database.insert("deadline", {"type": 0, "deadline": "2022-10-10"})
260 database.insert("deadline", {"type": 1, "deadline": "2022-10-12"})
261 database.insert("deadline", {"type": 2, "deadline": "2022-10-15"})
263 with app.app_context():
264 with app.test_request_context():
265 response = user_model.change_deadline(
266 "invalid-date", "2024-01-15", "2024-01-31"
267 )
268 json_data = response[0].get_json()
269 assert response[1] == 400
270 assert json_data["error"] == "Invalid deadline format. Use YYYY-MM-DD."
272 database.delete_all("deadline")
273 for deadline in deadlines:
274 database.insert("deadline", deadline)
277def test_update_deadlines_details_later_than_student_ranking(app, database, user_model):
278 """Tests the change_deadline method of the User model
279 with the details deadline later than the student ranking deadline."""
280 deadlines = database.get_all("deadline")
281 if deadlines:
282 database.delete_all("deadline")
284 database.insert("deadline", {"type": 0, "deadline": "2022-10-10"})
285 database.insert("deadline", {"type": 1, "deadline": "2022-10-12"})
286 database.insert("deadline", {"type": 2, "deadline": "2022-10-15"})
288 with app.app_context():
289 with app.test_request_context():
290 response = user_model.change_deadline(
291 "2024-01-16", "2024-01-15", "2024-01-31"
292 )
293 json_data = response[0].get_json()
294 assert response[1] == 400
295 assert (
296 json_data["error"]
297 == "Details deadline cannot be later than Student Ranking deadline."
298 )
300 database.delete_all("deadline")
301 for deadline in deadlines:
302 database.insert("deadline", deadline)
305def test_update_deadlines_student_ranking_later_than_opportunities_ranking(
306 app, database, user_model
307):
308 """Tests the change_deadline method of the User model
309 with the student ranking deadline later than the opportunities ranking deadline."""
310 deadlines = database.get_all("deadline")
311 if deadlines:
312 database.delete_all("deadline")
314 database.insert("deadline", {"type": 0, "deadline": "2022-10-10"})
315 database.insert("deadline", {"type": 1, "deadline": "2022-10-12"})
316 database.insert("deadline", {"type": 2, "deadline": "2022-10-15"})
318 with app.app_context():
319 with app.test_request_context():
320 response = user_model.change_deadline(
321 "2024-01-15", "2024-01-31", "2024-01-30"
322 )
323 json_data = response[0].get_json()
324 assert response[1] == 400
325 assert (
326 json_data["error"]
327 == "Student Ranking deadline cannot be later than Opportunities Ranking deadline."
328 )
330 database.delete_all("deadline")
331 for deadline in deadlines:
332 database.insert("deadline", deadline)
335def test_send_match_email(app, database, user_model):
336 """Tests the send_match_email method of the User model."""
337 database.delete_all_by_field("students", "email", "dummy@dummy.com")
338 database.delete_all_by_field("employers", "email", "dummy@dummy.com")
339 database.delete_all_by_field("opportunities", "employer_id", "employer-uuid")
341 student_uuid = "student-uuid"
342 student = {
343 "_id": "student-uuid",
344 "first_name": "Student",
345 "last_name": "User",
346 "email": "dummy@dummy.com",
347 }
348 database.insert("students", student)
349 opportunity_uuid = "opportunity-uuid"
350 opportunity = {
351 "_id": "opportunity-uuid",
352 "title": "Software Developer",
353 "employer_id": "employer-uuid",
354 }
355 database.insert("opportunities", opportunity)
357 employer = {
358 "_id": "employer-uuid",
359 "company_name": "Employer",
360 "email": "dummy@dummy.com",
361 }
362 database.insert("employers", employer)
364 with app.app_context():
365 with app.test_request_context():
366 response = user_model.send_match_email(student_uuid, opportunity_uuid)
367 json_data = response[0].get_json()
368 assert response[1] == 200
369 assert json_data["message"] == "Email Sent"
371 database.delete_all_by_field("students", "email", "dummy@dummy.com")
372 database.delete_all_by_field("employers", "email", "dummy@dummy.com")
373 database.delete_all_by_field("opportunities", "employer_id", "employer-uuid")
376def test_delete_user_success(app, database, user_model):
377 """Tests the delete_user_by_uuid method of the User model."""
378 database.delete_all_by_field("users", "email", "delete@dummy.com")
380 user_uuid = "delete-success-uuid"
381 user = {
382 "_id": user_uuid,
383 "name": "Delete User",
384 "email": "delete@dummy.com",
385 "password": "password",
386 }
388 database.insert("users", user)
390 with app.app_context():
391 with app.test_request_context():
392 response = user_model.delete_user_by_uuid(user_uuid)
393 json_data = response[0].get_json()
394 assert response[1] == 200
395 assert json_data["message"] == "User deleted successfully"
396 assert database.get_one_by_id("users", user_uuid) is None
398 database.delete_all_by_field("users", "email", "delete@dummy.com")
401def test_delete_user_not_found(app, user_model):
402 """Tests the delete_user_by_uuid method of the User model when the user is not found."""
403 user_uuid = "non-existent-uuid"
405 with app.app_context():
406 with app.test_request_context():
407 response = user_model.delete_user_by_uuid(user_uuid)
408 json_data = response[0].get_json()
409 assert response[1] == 404
410 assert json_data["error"] == "User not found"
413def test_get_user_by_uuid_success(app, database, user_model):
414 """Tests the get_user_by_uuid method of the User model."""
415 database.delete_all_by_field("users", "email", "get@dummy.com")
417 user_uuid = "get-success-uuid"
418 user = {
419 "_id": user_uuid,
420 "name": "Get User",
421 "email": "get@dummy.com",
422 "password": "password",
423 }
425 # Insert the user into the database
426 database.insert("users", user)
428 with app.app_context():
429 with app.test_request_context():
430 retrieved_user = user_model.get_user_by_uuid(user_uuid)
431 assert retrieved_user is not None
432 assert retrieved_user["_id"] == user_uuid
433 assert retrieved_user["email"] == "get@dummy.com"
435 database.delete_all_by_field("users", "email", "get@dummy.com")
438def test_get_user_by_uuid_not_found(app, user_model):
439 """Tests the get_user_by_uuid method of the User model when the user is not found."""
440 user_uuid = "non-existent-uuid"
442 with app.app_context():
443 with app.test_request_context():
444 retrieved_user = user_model.get_user_by_uuid(user_uuid)
445 assert retrieved_user is None
448def test_get_users_without_passwords(app, database, user_model):
449 """Tests the get_users_without_passwords method of the User model."""
450 database.delete_all_by_field("users", "email", "nopassword1@dummy.com")
451 database.delete_all_by_field("users", "email", "nopassword2@dummy.com")
452 existing_users = database.get_all("users")
453 database.delete_all("users")
455 user1 = {
456 "_id": "user1-uuid",
457 "name": "User One",
458 "email": "nopassword1@dummy.com",
459 "password": "password1",
460 }
461 user2 = {
462 "_id": "user2-uuid",
463 "name": "User Two",
464 "email": "nopassword2@dummy.com",
465 "password": "password2",
466 }
468 database.insert("users", user1)
469 database.insert("users", user2)
471 with app.app_context():
472 with app.test_request_context():
473 users = user_model.get_users_without_passwords()
474 assert len(users) == 2
475 for user in users:
476 assert "password" not in user
478 database.delete_all_by_field("users", "email", "nopassword1@dummy.com")
479 database.delete_all_by_field("users", "email", "nopassword2@dummy.com")
481 for user in existing_users:
482 database.insert("users", user)
485def test_update_user_success(app, database, user_model):
486 """Tests the update_user method of the User model."""
487 database.delete_all_by_field("users", "email", "update@dummy.com")
488 database.delete_all_by_field("users", "email", "updated@dummy.com")
490 user_uuid = "update-success-uuid"
491 user = {
492 "_id": user_uuid,
493 "name": "Update User",
494 "email": "update@dummy.com",
495 "password": "password",
496 }
498 database.insert("users", user)
500 with app.app_context():
501 with app.test_request_context():
502 response = user_model.update_user(
503 user_uuid, "Updated Name", "updated@dummy.com"
504 )
505 json_data = response[0].get_json()
506 assert response[1] == 200
507 assert json_data["message"] == "User updated successfully"
508 updated_user = database.get_one_by_id("users", user_uuid)
509 assert updated_user["name"] == "Updated Name"
510 assert updated_user["email"] == "updated@dummy.com"
512 database.delete_all_by_field("users", "email", "update@dummy.com")
513 database.delete_all_by_field("users", "email", "updated@dummy.com")
516def test_update_user_email_in_use(app, database, user_model):
517 """Tests the update_user method of the User model when the email is already in use."""
518 database.delete_all_by_field("users", "email", "update@dummy.com")
519 database.delete_all_by_field("users", "email", "existing@dummy.com")
521 user_uuid = "update-email-in-use-uuid"
522 user = {
523 "_id": user_uuid,
524 "name": "Update User",
525 "email": "update@dummy.com",
526 "password": "password",
527 }
529 existing_user = {
530 "_id": "existing-uuid",
531 "name": "Existing User",
532 "email": "existing@dummy.com",
533 "password": "password",
534 }
536 database.insert("users", user)
537 database.insert("users", existing_user)
539 with app.app_context():
540 with app.test_request_context():
541 response = user_model.update_user(
542 user_uuid, "Updated Name", "existing@dummy.com"
543 )
544 json_data = response[0].get_json()
545 assert response[1] == 400
546 assert json_data["error"] == "Email address already in use"
548 database.delete_all_by_field("users", "email", "update@dummy.com")
549 database.delete_all_by_field("users", "email", "existing@dummy.com")
552def test_update_user_not_found(app, database, user_model):
553 """Tests the update_user method of the User model when the user is not found."""
554 database.delete_all_by_field("users", "email", "update@dummy.com")
556 user_uuid = "non-existent-uuid"
558 with app.app_context():
559 with app.test_request_context():
560 response = user_model.update_user(
561 user_uuid, "Updated Name", "update@dummy.com"
562 )
563 json_data = response[0].get_json()
564 assert response[1] == 404
565 assert json_data["error"] == "User not found"
568def test_change_password_success(app, database, user_model):
569 """Tests the change_password method of the User model."""
570 database.delete_all_by_field("users", "email", "changepassword@dummy.com")
572 user_uuid = "change-password-uuid"
573 user = {
574 "_id": user_uuid,
575 "name": "Change Password User",
576 "email": "changepassword@dummy.com",
577 "password": pbkdf2_sha512.hash("oldpassword"),
578 }
580 database.insert("users", user)
582 with app.app_context():
583 with app.test_request_context():
584 response = user_model.change_password(
585 user_uuid, "newpassword", "newpassword"
586 )
587 json_data = response[0].get_json()
588 assert response[1] == 200
589 assert json_data["message"] == "Password updated successfully"
590 updated_user = database.get_one_by_id("users", user_uuid)
591 assert pbkdf2_sha512.verify("newpassword", updated_user["password"])
593 database.delete_all_by_field("users", "email", "changepassword@dummy.com")
596def test_change_password_mismatch(app, database, user_model):
597 """Tests the change_password method of the User model when passwords don't match."""
598 database.delete_all_by_field("users", "email", "changepassword@dummy.com")
600 user_uuid = "change-password-uuid"
601 user = {
602 "_id": user_uuid,
603 "name": "Change Password User",
604 "email": "changepassword@dummy.com",
605 "password": pbkdf2_sha512.hash("oldpassword"),
606 }
608 database.insert("users", user)
610 with app.app_context():
611 with app.test_request_context():
612 response = user_model.change_password(
613 user_uuid, "newpassword", "differentpassword"
614 )
615 json_data = response[0].get_json()
616 assert response[1] == 400
617 assert json_data["error"] == "Passwords don't match"
619 database.delete_all_by_field("users", "email", "changepassword@dummy.com")
622def test_register_missing_name(app, database, user_model):
623 """Tests the register method of the User model when the request is missing the name."""
624 database.delete_all_by_field("users", "email", "dummy@dummy.com")
625 user = {
626 "_id": "128",
627 "email": "dummy@dummy.com",
628 "password": "password",
629 }
631 with app.app_context():
632 with app.test_request_context():
633 response = user_model.register(user)
634 json_data = response[0].get_json()
635 assert response[1] == 400
636 assert json_data["error"] == "Missing name"
638 database.delete_all_by_field("users", "email", "dummy@dummy.com")