# Run from /backend with: python manage.py test matching
import unittest
from unittest.mock import Mock
[docs]
def make_user(
hobbies="", goals="", clubs="",
major=None, minor=None, year="1",
international=False, commuter=False, firstgen=False,
outofstate=False, transfer=False,
):
u = Mock()
u.hobbies = hobbies
u.goals = goals
u.clubs = clubs
u.major = major or []
u.minor = minor or []
u.year = year
u.international = international
u.commuter = commuter
u.firstgen = firstgen
u.outofstate = outofstate
u.transfer = transfer
return u
[docs]
class TestYearCompatibility(unittest.TestCase):
[docs]
def setUp(self):
from matching.scoring import calculate_year_compatibility
self.calculate_year_compatibility = calculate_year_compatibility
[docs]
def test_optimal_pairing_1st_3rd(self):
self.assertEqual(self.calculate_year_compatibility('1', '3'), 10.0)
[docs]
def test_strong_pairing_1st_4th(self):
self.assertEqual(self.calculate_year_compatibility('1', '4'), 9.0)
[docs]
def test_large_gap_pairing(self):
self.assertEqual(self.calculate_year_compatibility('1', '5+'), 9.0)
self.assertEqual(self.calculate_year_compatibility('2', '5+'), 9.0)
[docs]
def test_two_year_gap(self):
self.assertEqual(self.calculate_year_compatibility('1', '3'), 10.0)
self.assertEqual(self.calculate_year_compatibility('2', '4'), 8.0)
[docs]
def test_one_year_gap(self):
self.assertEqual(self.calculate_year_compatibility('1', '2'), 6.0)
self.assertEqual(self.calculate_year_compatibility('3', '4'), 6.0)
[docs]
def test_same_year(self):
self.assertEqual(self.calculate_year_compatibility('2', '2'), 3.0)
self.assertEqual(self.calculate_year_compatibility('4', '4'), 3.0)
[docs]
def test_negative_gap(self):
self.assertEqual(self.calculate_year_compatibility('4', '2'), 1.0)
self.assertEqual(self.calculate_year_compatibility('3', '1'), 1.0)
[docs]
def test_5_plus_year_parsing(self):
self.assertEqual(self.calculate_year_compatibility('1', '5+'), 9.0)
[docs]
def test_missing_year_data(self):
self.assertEqual(self.calculate_year_compatibility(None, '3'), 5.0)
self.assertEqual(self.calculate_year_compatibility('2', None), 5.0)
self.assertEqual(self.calculate_year_compatibility('', ''), 5.0)
[docs]
def test_invalid_year_strings(self):
self.assertEqual(self.calculate_year_compatibility('invalid', '3'), 5.0)
self.assertEqual(self.calculate_year_compatibility('2', 'invalid'), 5.0)
[docs]
class TestMatchScoring(unittest.TestCase):
[docs]
def setUp(self):
from matching.scoring import calculate_match_score
self.calculate_match_score = calculate_match_score
self.mentee = make_user(
hobbies="coding, AI, robotics projects",
goals="I want to break into machine learning and software engineering",
clubs="AI club, robotics team",
major=["Computer Science"],
year="1",
international=True,
firstgen=True,
)
self.mentor = make_user(
hobbies="programming and machine learning side projects",
goals="I want to help students get into software engineering and AI careers",
clubs="CS mentorship club, AI research group",
major=["Computer Science"],
year="3",
international=True,
)
[docs]
def test_high_similarity_cs_match(self):
score = self.calculate_match_score(self.mentee, self.mentor)
print(f"\nCS Match Score: {score}")
self.assertGreaterEqual(score, 65.0)
self.assertLessEqual(score, 100.0)
[docs]
def test_cross_discipline_mismatch(self):
mentee = make_user(
hobbies="painting, visiting museums, sculpture",
goals="I want to become an art curator",
major=["Art History"], year="1",
)
mentor = make_user(
hobbies="quantum physics experiments, reading math papers",
goals="I want to get a physics PhD",
major=["Physics"], year="3",
)
score = self.calculate_match_score(mentee, mentor)
print(f"\nCross-discipline Mismatch Score: {score}")
self.assertLessEqual(score, 45.0)
[docs]
def test_same_field_different_focus(self):
mentee = make_user(
hobbies="HTML, CSS, JavaScript, UI/UX design",
goals="I want to be a frontend engineer",
major=["Computer Science"], year="1",
)
mentor = make_user(
hobbies="Python, neural networks, statistics",
goals="I want to work in machine learning and data science",
major=["Computer Science"], year="3",
)
score = self.calculate_match_score(mentee, mentor)
print(f"\nSame Field Different Focus Score: {score}")
self.assertGreaterEqual(score, 40.0)
self.assertLessEqual(score, 80.0)
[docs]
def test_interdisciplinary_match(self):
mentee = make_user(
hobbies="bioinformatics, genetics, data analysis",
goals="I want to work in computational biology",
major=["Biology"], year="2",
)
mentor = make_user(
hobbies="bioinformatics, machine learning, genomics",
goals="I do computational biology research",
major=["Computer Science"], year="4",
)
score = self.calculate_match_score(mentee, mentor)
print(f"\nInterdisciplinary Match Score: {score}")
self.assertGreaterEqual(score, 35.0)
self.assertLessEqual(score, 75.0)
[docs]
def test_special_category_boost(self):
mentee = make_user(
hobbies="engineering", goals="engineering career",
major=["Engineering"], year="1",
international=True, firstgen=True, commuter=True, transfer=True,
)
mentor = make_user(
hobbies="engineering", goals="engineering career",
major=["Engineering"], year="3",
international=True, firstgen=True, commuter=True, transfer=True,
)
mentee2 = make_user(hobbies="engineering", goals="engineering career", major=["Engineering"], year="1")
mentor2 = make_user(hobbies="engineering", goals="engineering career", major=["Engineering"], year="3")
score_with = self.calculate_match_score(mentee, mentor)
score_without = self.calculate_match_score(mentee2, mentor2)
print(f"\nWith categories: {score_with}, Without: {score_without}")
# 4 shared categories = 20 point boost (capped)
self.assertAlmostEqual(score_with - score_without, 20.0, places=1)
[docs]
def test_identical_profiles(self):
text = "Passionate computer science student interested in AI and machine learning"
mentee = make_user(hobbies=text, goals=text, clubs="AI club", major=["Computer Science"], year="1", international=True)
mentor = make_user(hobbies=text, goals=text, clubs="AI club", major=["Computer Science"], year="3", international=True)
score = self.calculate_match_score(mentee, mentor)
print(f"\nIdentical Profiles Score: {score}")
self.assertGreaterEqual(score, 80.0)
[docs]
def test_missing_data_handling(self):
mentee = make_user(year="1")
mentor = make_user(year="3")
score = self.calculate_match_score(mentee, mentor)
print(f"\nMissing Data Score: {score}")
# Only year score: 10
self.assertEqual(score, 10.0)
[docs]
def test_empty_strings_handling(self):
mentee = make_user(hobbies="", goals="", clubs="", major=[], year="1")
mentor = make_user(hobbies="", goals="", clubs="", major=[], year="3")
score = self.calculate_match_score(mentee, mentor)
print(f"\nEmpty Strings Score: {score}")
self.assertEqual(score, 10.0)
[docs]
def test_score_range_validation(self):
score = self.calculate_match_score(self.mentee, self.mentor)
self.assertGreaterEqual(score, 0.0)
self.assertLessEqual(score, 100.0)
[docs]
def test_generic_vs_specific(self):
mentee = make_user(
hobbies="technology, computers, internet",
goals="I want to work in tech",
major=["Computer Science"], year="1",
)
mentor = make_user(
hobbies="Kubernetes, AWS, microservices, Docker",
goals="I build distributed cloud systems",
major=["Computer Science"], year="3",
)
score = self.calculate_match_score(mentee, mentor)
print(f"\nGeneric vs Specific Score: {score}")
self.assertGreaterEqual(score, 35.0)
self.assertLessEqual(score, 75.0)
[docs]
class TestEdgeCases(unittest.TestCase):
[docs]
def setUp(self):
from matching.scoring import (build_profile_text,
calculate_match_score,
calculate_year_compatibility)
self.calculate_match_score = calculate_match_score
self.calculate_year_compatibility = calculate_year_compatibility
self.build_profile_text = build_profile_text
[docs]
def test_year_boundary_values(self):
self.assertEqual(self.calculate_year_compatibility('1', '1'), 3.0)
self.assertEqual(self.calculate_year_compatibility('5+', '5+'), 3.0)
self.assertEqual(self.calculate_year_compatibility('1', '5+'), 9.0)
[docs]
def test_build_profile_text_empty(self):
user = make_user()
self.assertEqual(self.build_profile_text(user), "")
[docs]
def test_build_profile_text_full(self):
user = make_user(
hobbies="coding", goals="become an engineer",
clubs="CS club", major=["Computer Science"], minor=["Math"],
)
text = self.build_profile_text(user)
self.assertIn("Computer Science", text)
self.assertIn("coding", text)
self.assertIn("become an engineer", text)
[docs]
def test_single_word_vs_paragraph(self):
mentee = make_user(hobbies="AI", goals="AI", major=["CS"], year="1")
mentor = make_user(
hobbies="artificial intelligence and machine learning projects",
goals="advance AI research in neural networks and NLP",
major=["Computer Science"], year="3",
)
score = self.calculate_match_score(mentee, mentor)
print(f"\nSingle Word vs Paragraph Score: {score}")
self.assertGreaterEqual(score, 30.0)
[docs]
def test_similar_meaning_different_words(self):
mentee = make_user(
hobbies="programming and coding",
goals="I want to become a software engineer",
major=["Computer Science"], year="1",
)
mentor = make_user(
hobbies="software development and writing code",
goals="I aspire to be a developer",
major=["CS"], year="3",
)
score = self.calculate_match_score(mentee, mentor)
print(f"\nSimilar Meaning Different Words Score: {score}")
self.assertGreaterEqual(score, 60.0)
[docs]
def test_unicode_and_special_characters(self):
mentee = make_user(
hobbies="I love 机器学习 (machine learning) and AI 🤖",
goals="プログラミング and 数学",
major=["Computer Science"], year="1",
)
mentor = make_user(
hobbies="machine learning and statistics",
goals="データサイエンス (data science) and Python",
major=["CS"], year="3",
)
score = self.calculate_match_score(mentee, mentor)
print(f"\nUnicode Score: {score}")
self.assertIsInstance(score, float)
self.assertGreaterEqual(score, 0.0)
self.assertLessEqual(score, 100.0)
if __name__ == '__main__':
unittest.main(verbosity=2)