Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/utils/recommender.py
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,8 @@ def get_recommendations(
for entry in skill_entries
}
all_projects = load_all_projects()
if tech_stack and tech_stack.lower() != "all":
all_projects = [p for p in all_projects if project_matches_tech(p, tech_stack)]
# Load NLP model to determine if we should use semantic search
model = get_nlp_model()

Expand Down
44 changes: 44 additions & 0 deletions tests/test_recommender_tech_stack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# tests/test_recommender_tech_stack.py
# Regression test for issue #1870:
# The technology stack filter must actually narrow the recommendations returned
# by get_recommendations (project_matches_tech was defined but never called).

from utils.recommender import get_recommendations, project_matches_tech


def test_all_returns_everything():
"""With tech_stack='all' the filter must not exclude any project."""
results = get_recommendations("Python", "Beginner", "Data", "Low", tech_stack="all")
assert len(results["recommendations"]) > 0


def test_tech_stack_filter_changes_results():
"""A non-'all' tech stack must produce a different recommendation set."""
base = get_recommendations("Python", "Beginner", "Data", "Low", tech_stack="all")
filtered = get_recommendations("Python", "Beginner", "Data", "Low", tech_stack="java")
base_ids = [p["id"] for p in base["recommendations"]]
filtered_ids = [p["id"] for p in filtered["recommendations"]]
assert filtered_ids != base_ids, (
"tech_stack filter had no effect (issue #1870)"
)


def test_filtered_projects_actually_match_tech():
"""Every project returned for a given tech_stack must match it."""
filtered = get_recommendations("Python", "Beginner", "Data", "Low", tech_stack="java")
assert filtered["recommendations"], "Expected at least one java project to match"
for project in filtered["recommendations"]:
assert project_matches_tech(project, "java"), (
f"Project {project.get('id')} does not match tech_stack='java' (issue #1870)"
)


def test_filtered_results_are_subset_of_all():
"""Filtered results must never include projects the 'all' query excludes."""
base = get_recommendations("Python", "Beginner", "Data", "Low", tech_stack="all")
filtered = get_recommendations("Python", "Beginner", "Data", "Low", tech_stack="flask")
base_ids = {p["id"] for p in base["recommendations"]}
for project in filtered["recommendations"]:
assert project["id"] in base_ids, (
f"Project {project.get('id')} returned by filter but absent from unfiltered query"
)
Loading