diff --git a/routes/main_routes.py b/routes/main_routes.py index 5cb3459..281cd51 100644 --- a/routes/main_routes.py +++ b/routes/main_routes.py @@ -10,6 +10,19 @@ from utils.file_server import read_starter_code, resolve_starter_file, get_starter_code_dir import os +# Interest categories that currently have no project recommendations available +NO_PROJECT_INTERESTS = { + "machine learning/ai", + "devops", + "mobile", + "artificial intelligence", + "cloud computing", + "mobile app development", +} + +def interest_has_no_projects(interest): + return interest and interest.strip().lower() in NO_PROJECT_INTERESTS + # Create the Blueprint that app.py will register main = Blueprint("main", __name__) @@ -58,6 +71,12 @@ def recommend(): # Return only the first error to keep the UI message clean return jsonify({"error": errors[0]}), 400 + if interest_has_no_projects(interest): + return jsonify({ + "projects": [], + "message": "No projects are currently available for this interest area. Please check back later." + }), 200 + results = get_recommendations(skills, level, interest, time_availability) if not results: diff --git a/static/script.js b/static/script.js index 9d96ab9..bb0f30e 100644 --- a/static/script.js +++ b/static/script.js @@ -615,9 +615,19 @@ if (clearFiltersBtn) { resultsEmptyEl.style.display = "block"; if (message && emptyMessageEl) emptyMessageEl.textContent = message; if (!projects || projects.length === 0) { //if no projects returned from api, show the "no results" message and hide the grid - resultsGrid.style.display = "none"; - resultsEmptyEl.style.display = "block"; - if (message && emptyMessageEl) emptyMessageEl.textContent = message; //if api sent back a message (e.g. "no projects found matching your criteria"), show that + resultsGrid.style.display = "none"; + resultsEmptyEl.style.display = "block"; + + // Show a friendly custom message when the user selected an interest + var selectedInterest = document.getElementById("interest")?.value; + if (selectedInterest) { + emptyMessageEl.textContent = "No projects are currently available for this interest. Please check back later or try a different area."; + } else if (message) { + emptyMessageEl.textContent = message; + } else { + emptyMessageEl.textContent = "Try adjusting your skills or choosing a different interest area."; + } + resultsSection.scrollIntoView({ behavior: "smooth" }); return; } @@ -654,8 +664,8 @@ if (clearFiltersBtn) { var tagsRow = document.createElement("div"); tagsRow.className = "project-card-tags"; - // Show the first two skills as tags - (project.skills || []).slice(0, 2).forEach(function (skill) { + // Show all project skills as tags so users can see the full match + (project.skills || []).forEach(function (skill) { tagsRow.appendChild(createTag(skill, "skill")); }); diff --git a/templates/index.html b/templates/index.html index 18537b9..959c697 100644 --- a/templates/index.html +++ b/templates/index.html @@ -413,7 +413,6 @@

Find Your Next Project

- Find Your Next Project + + + +
diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..c133ad5 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,19 @@ +# tests/conftest.py +# Pytest configuration and shared fixtures for DevPath tests. + +import sys +import os + +# Allow imports from the project root when running tests +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) + +import pytest +from app import app + + +@pytest.fixture +def client(): + """Provide a Flask test client for testing the application.""" + app.config['TESTING'] = True + with app.test_client() as client: + yield client diff --git a/tests/test_basic.py b/tests/test_basic.py index fc41aa7..c6cf061 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -221,6 +221,22 @@ def test_recommend_api_valid(): assert len(data["projects"]) > 0 +def test_recommend_api_interest_not_available(): + """The API should return no projects for blocked interest categories.""" + client = get_client() + response = client.post("/api/recommend", json={ + "skills": "Python, JavaScript", + "level": "Beginner", + "interest": "Machine Learning/AI", + "time": "Low" + }) + assert response.status_code == 200 + data = response.get_json() + assert data["projects"] == [] + assert "message" in data + assert "no projects are currently available" in data["message"].lower() + + def test_recommend_api_missing_field(): """The API should return 400 when a required field is missing.""" client = get_client()