Download backend/tests/test_api.py from Jessedbrown/schedule-manager: direct link, hf CLI and curl.
- Browser
- Download file 7.7 kB
-
https://huggingface.co/Jessedbrown/schedule-manager/resolve/main/backend/tests/test_api.py
- Command line
-
hf download hf://Jessedbrown/schedule-manager/backend/tests/test_api.py
-
curl -L -o test_api.py https://huggingface.co/Jessedbrown/schedule-manager/resolve/main/backend/tests/test_api.py
7.7 kB
| """Tests for API endpoints.""" | |
| from datetime import date, time | |
| import pytest | |
| class TestHealthEndpoints: | |
| """Test health check endpoints.""" | |
| def test_root_endpoint(self, client): | |
| """Root endpoint should return OK status.""" | |
| response = client.get("/") | |
| assert response.status_code == 200 | |
| assert response.json()["status"] == "ok" | |
| def test_health_endpoint(self, client): | |
| """Health endpoint should return healthy status.""" | |
| response = client.get("/health") | |
| assert response.status_code == 200 | |
| assert response.json()["status"] == "healthy" | |
| class TestLookupEndpoints: | |
| """Test lookup API endpoints.""" | |
| def test_get_rooms(self, client, seed_data): | |
| """Should return all rooms.""" | |
| response = client.get("/rooms") | |
| assert response.status_code == 200 | |
| rooms = response.json() | |
| assert len(rooms) == 3 | |
| assert all("name" in r and "capacity" in r for r in rooms) | |
| def test_get_instructors(self, client, seed_data): | |
| """Should return all instructors.""" | |
| response = client.get("/instructors") | |
| assert response.status_code == 200 | |
| instructors = response.json() | |
| assert len(instructors) == 2 | |
| def test_get_students(self, client, seed_data): | |
| """Should return all students.""" | |
| response = client.get("/students") | |
| assert response.status_code == 200 | |
| students = response.json() | |
| assert len(students) == 10 | |
| class TestClassCRUD: | |
| """Test class CRUD operations.""" | |
| def test_create_class(self, client, seed_data): | |
| """Should create a new class.""" | |
| response = client.post("/classes", json={ | |
| "course_name": "Test Course", | |
| "chapter_topic": "Test Topic", | |
| "date": "2024-01-15", | |
| "start_time": "10:00:00", | |
| "end_time": "11:30:00", | |
| "room_id": 1, | |
| "instructor_id": 1, | |
| "student_ids": [1, 2, 3], | |
| }) | |
| assert response.status_code == 201 | |
| data = response.json() | |
| assert data["course_name"] == "Test Course" | |
| assert len(data["students"]) == 3 | |
| def test_get_classes_by_date(self, client, seed_data): | |
| """Should return classes for a specific date.""" | |
| # First create a class | |
| client.post("/classes", json={ | |
| "course_name": "Test Course", | |
| "chapter_topic": "Test Topic", | |
| "date": "2024-01-15", | |
| "start_time": "10:00:00", | |
| "end_time": "11:30:00", | |
| "room_id": 1, | |
| "instructor_id": 1, | |
| "student_ids": [], | |
| }) | |
| response = client.get("/classes?date=2024-01-15") | |
| assert response.status_code == 200 | |
| classes = response.json() | |
| assert len(classes) == 1 | |
| def test_update_class(self, client, seed_data): | |
| """Should update an existing class.""" | |
| # Create | |
| create_response = client.post("/classes", json={ | |
| "course_name": "Original Name", | |
| "chapter_topic": "Original Topic", | |
| "date": "2024-01-15", | |
| "start_time": "10:00:00", | |
| "end_time": "11:30:00", | |
| "room_id": 1, | |
| "instructor_id": 1, | |
| "student_ids": [], | |
| }) | |
| class_id = create_response.json()["id"] | |
| # Update | |
| update_response = client.put(f"/classes/{class_id}", json={ | |
| "course_name": "Updated Name", | |
| "chapter_topic": "Updated Topic", | |
| "date": "2024-01-15", | |
| "start_time": "10:00:00", | |
| "end_time": "11:30:00", | |
| "room_id": 1, | |
| "instructor_id": 1, | |
| "student_ids": [1], | |
| }) | |
| assert update_response.status_code == 200 | |
| assert update_response.json()["course_name"] == "Updated Name" | |
| assert len(update_response.json()["students"]) == 1 | |
| def test_delete_class(self, client, seed_data): | |
| """Should delete a class.""" | |
| # Create | |
| create_response = client.post("/classes", json={ | |
| "course_name": "To Delete", | |
| "chapter_topic": "Topic", | |
| "date": "2024-01-15", | |
| "start_time": "10:00:00", | |
| "end_time": "11:30:00", | |
| "room_id": 1, | |
| "instructor_id": 1, | |
| "student_ids": [], | |
| }) | |
| class_id = create_response.json()["id"] | |
| # Delete | |
| delete_response = client.delete(f"/classes/{class_id}") | |
| assert delete_response.status_code == 204 | |
| # Verify deleted | |
| get_response = client.get(f"/classes/{class_id}") | |
| assert get_response.status_code == 404 | |
| class TestConflictAPI: | |
| """Test conflict detection via API.""" | |
| def test_room_conflict_returns_409(self, client, seed_data): | |
| """Creating a class with room conflict should return 409.""" | |
| # Create first class | |
| client.post("/classes", json={ | |
| "course_name": "First Class", | |
| "chapter_topic": "Topic", | |
| "date": "2024-01-15", | |
| "start_time": "10:00:00", | |
| "end_time": "11:30:00", | |
| "room_id": 1, | |
| "instructor_id": 1, | |
| "student_ids": [], | |
| }) | |
| # Try to create conflicting class | |
| response = client.post("/classes", json={ | |
| "course_name": "Conflicting Class", | |
| "chapter_topic": "Topic", | |
| "date": "2024-01-15", | |
| "start_time": "11:00:00", # Overlaps | |
| "end_time": "12:30:00", | |
| "room_id": 1, # Same room | |
| "instructor_id": 2, # Different instructor | |
| "student_ids": [], | |
| }) | |
| assert response.status_code == 409 | |
| detail = response.json()["detail"] | |
| assert detail["error"] == "conflict" | |
| assert any(c["type"] == "room" for c in detail["conflicts"]) | |
| def test_adjacent_times_no_conflict(self, client, seed_data): | |
| """Adjacent times should not conflict.""" | |
| # Create first class | |
| client.post("/classes", json={ | |
| "course_name": "First Class", | |
| "chapter_topic": "Topic", | |
| "date": "2024-01-15", | |
| "start_time": "10:00:00", | |
| "end_time": "11:00:00", | |
| "room_id": 1, | |
| "instructor_id": 1, | |
| "student_ids": [], | |
| }) | |
| # Create adjacent class (should succeed) | |
| response = client.post("/classes", json={ | |
| "course_name": "Adjacent Class", | |
| "chapter_topic": "Topic", | |
| "date": "2024-01-15", | |
| "start_time": "11:00:00", # Starts exactly when first ends | |
| "end_time": "12:00:00", | |
| "room_id": 1, # Same room | |
| "instructor_id": 1, # Same instructor | |
| "student_ids": [], | |
| }) | |
| assert response.status_code == 201 | |
| def test_capacity_conflict_returns_409(self, client, seed_data): | |
| """Creating a class with too many students should return 409.""" | |
| response = client.post("/classes", json={ | |
| "course_name": "Overcrowded Class", | |
| "chapter_topic": "Topic", | |
| "date": "2024-01-15", | |
| "start_time": "10:00:00", | |
| "end_time": "11:30:00", | |
| "room_id": 3, # Small Room with capacity=5 | |
| "instructor_id": 1, | |
| "student_ids": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], # 10 students | |
| }) | |
| assert response.status_code == 409 | |
| detail = response.json()["detail"] | |
| assert any(c["type"] == "capacity" for c in detail["conflicts"]) | |