diff --git a/requirements.txt b/requirements.txt index 0687ae5..ccda4ca 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,8 +5,8 @@ SQLAlchemy==2.0.36 psycopg2-binary==2.9.9 redis==5.0.8 rq==1.16.2 -python-jose[cryptography]==3.3.0 -python-multipart==0.0.9 +python-jose[cryptography]>=3.4.0 +python-multipart>=0.0.18 python-dotenv==1.0.0 bcrypt==4.1.2 # Testing Dependencies diff --git a/tests/test_api_photos.py b/tests/test_api_photos.py index b719f2b..b1f8802 100644 --- a/tests/test_api_photos.py +++ b/tests/test_api_photos.py @@ -29,6 +29,11 @@ class TestPhotoSearch: # Link face to person test_face.person_id = test_person.id test_db_session.commit() + test_db_session.refresh(test_face) + + # Verify the link was created + assert test_face.person_id == test_person.id + assert test_face.photo_id == test_photo.id response = test_client.get( "/api/v1/photos", @@ -40,8 +45,11 @@ class TestPhotoSearch: data = response.json() assert "items" in data assert "total" in data - # Search may return results if person name matches - # Note: search does partial matching on first_name, last_name, etc. + # With test_person.first_name="John" and face linked, we should find results + assert len(data["items"]) > 0 + # Verify the photo is in the results + photo_ids = [item["id"] for item in data["items"]] + assert test_photo.id in photo_ids def test_search_photos_by_name_without_person_name( self, @@ -306,15 +314,15 @@ class TestPhotoFavorites: ): """Verify bulk add operation.""" response = test_client.post( - "/api/v1/photos/favorites/bulk-add", + "/api/v1/photos/bulk-add-favorites", headers=auth_headers, json={"photo_ids": [test_photo.id, test_photo_2.id]}, ) assert response.status_code == 200 data = response.json() - assert data["added"] >= 0 - assert data["already_favorites"] >= 0 + assert data["added_count"] >= 0 + assert data["already_favorite_count"] >= 0 def test_bulk_remove_favorites_success( self, @@ -333,14 +341,14 @@ class TestPhotoFavorites: test_db_session.commit() response = test_client.post( - "/api/v1/photos/favorites/bulk-remove", + "/api/v1/photos/bulk-remove-favorites", headers=auth_headers, json={"photo_ids": [test_photo.id]}, ) assert response.status_code == 200 data = response.json() - assert data["removed"] >= 0 + assert data["removed_count"] >= 0 class TestPhotoRetrieval: @@ -403,6 +411,7 @@ class TestPhotoDeletion: test_client: TestClient, regular_auth_headers: dict, test_photo: "Photo", + admin_user, # Ensure an admin exists to prevent bootstrap ): """Verify 403 for non-admin users.""" response = test_client.post( diff --git a/tests/test_api_tags.py b/tests/test_api_tags.py index eb2009f..dae7f25 100644 --- a/tests/test_api_tags.py +++ b/tests/test_api_tags.py @@ -63,7 +63,7 @@ class TestTagCRUD: assert response.status_code == 200 data = response.json() - assert data["tag"] == "new-tag" + assert data["tag_name"] == "new-tag" assert "id" in data def test_create_tag_duplicate( @@ -89,7 +89,7 @@ class TestTagCRUD: assert response.status_code == 200 data = response.json() assert data["id"] == tag.id - assert data["tag"] == "duplicate-tag" + assert data["tag_name"] == "duplicate-tag" def test_create_tag_strips_whitespace( self, @@ -104,7 +104,7 @@ class TestTagCRUD: assert response.status_code == 200 data = response.json() # Tag should be trimmed - assert "whitespace-tag" in data["tag"] + assert "whitespace-tag" in data["tag_name"] def test_update_tag_success( self, @@ -126,7 +126,7 @@ class TestTagCRUD: assert response.status_code == 200 data = response.json() - assert data["tag"] == "new-name" + assert data["tag_name"] == "new-name" def test_update_tag_not_found( self, diff --git a/tests/test_api_users.py b/tests/test_api_users.py index de90de8..3d30b8e 100644 --- a/tests/test_api_users.py +++ b/tests/test_api_users.py @@ -36,6 +36,7 @@ class TestUserListing: self, test_client: TestClient, regular_auth_headers: dict, + admin_user, # Ensure an admin exists to prevent bootstrap ): """Verify 403 for non-admin users.""" response = test_client.get( @@ -168,6 +169,7 @@ class TestUserCRUD: f"/api/v1/users/{admin_user.id}", headers=auth_headers, json={ + "email": admin_user.email, "full_name": "Updated Name", }, ) @@ -233,9 +235,14 @@ class TestUserActivation: inactive_user: "User", ): """Verify user activation.""" - response = test_client.post( - f"/api/v1/users/{inactive_user.id}/activate", + response = test_client.put( + f"/api/v1/users/{inactive_user.id}", headers=auth_headers, + json={ + "email": inactive_user.email, + "full_name": inactive_user.full_name or inactive_user.username, + "is_active": True, + }, ) assert response.status_code == 200 @@ -249,9 +256,14 @@ class TestUserActivation: regular_user: "User", ): """Verify user deactivation.""" - response = test_client.post( - f"/api/v1/users/{regular_user.id}/deactivate", + response = test_client.put( + f"/api/v1/users/{regular_user.id}", headers=auth_headers, + json={ + "email": regular_user.email, + "full_name": regular_user.full_name or regular_user.username, + "is_active": False, + }, ) assert response.status_code == 200 @@ -264,9 +276,14 @@ class TestUserActivation: auth_headers: dict, ): """Verify 404 handling.""" - response = test_client.post( - "/api/v1/users/99999/activate", + response = test_client.put( + "/api/v1/users/99999", headers=auth_headers, + json={ + "email": "nonexistent@example.com", + "full_name": "Nonexistent User", + "is_active": True, + }, ) assert response.status_code == 404