diff --git a/setup.cfg b/setup.cfg index 03c3f561..87069a2b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -20,3 +20,9 @@ multi_line_output = 5 known_standard_library = types known_third_party = pytest,_pytest +[tool:pytest] +markers = + authentication + db + fastapi_users + router diff --git a/tests/test_authentication_base.py b/tests/test_authentication_base.py index 692add1c..05dec909 100644 --- a/tests/test_authentication_base.py +++ b/tests/test_authentication_base.py @@ -5,6 +5,7 @@ from fastapi_users.authentication import BaseAuthentication @pytest.mark.asyncio +@pytest.mark.authentication async def test_not_implemented_methods(user, mock_user_db): response = Response() base_authentication = BaseAuthentication() diff --git a/tests/test_authentication_jwt.py b/tests/test_authentication_jwt.py index b4f3f700..391ad522 100644 --- a/tests/test_authentication_jwt.py +++ b/tests/test_authentication_jwt.py @@ -44,6 +44,7 @@ async def test_get_login_response(jwt_authentication, user): assert decoded["user_id"] == user.id +@pytest.mark.authentication class TestGetCurrentUser: def test_missing_token(self, test_auth_client): response = test_auth_client.get("/test-current-user") @@ -81,6 +82,7 @@ class TestGetCurrentUser: assert response_json["id"] == user.id +@pytest.mark.authentication class TestGetCurrentActiveUser: def test_missing_token(self, test_auth_client): response = test_auth_client.get("/test-current-active-user") @@ -110,6 +112,7 @@ class TestGetCurrentActiveUser: assert response_json["id"] == user.id +@pytest.mark.authentication class TestGetCurrentSuperuser: def test_missing_token(self, test_auth_client): response = test_auth_client.get("/test-current-superuser") diff --git a/tests/test_db_base.py b/tests/test_db_base.py index 24c0bf2b..894ef693 100644 --- a/tests/test_db_base.py +++ b/tests/test_db_base.py @@ -13,6 +13,7 @@ def create_oauth2_password_request_form(): @pytest.mark.asyncio +@pytest.mark.db async def test_not_implemented_methods(user): base_user_db = BaseUserDatabase() @@ -35,6 +36,7 @@ async def test_not_implemented_methods(user): await base_user_db.delete(user) +@pytest.mark.db class TestAuthenticate: @pytest.mark.asyncio async def test_unknown_user( diff --git a/tests/test_db_mongodb.py b/tests/test_db_mongodb.py index ce933006..cc6be13b 100644 --- a/tests/test_db_mongodb.py +++ b/tests/test_db_mongodb.py @@ -11,7 +11,16 @@ from fastapi_users.password import get_password_hash @pytest.fixture async def mongodb_user_db() -> AsyncGenerator[MongoDBUserDatabase, None]: - client = motor.motor_asyncio.AsyncIOMotorClient("mongodb://localhost:27017") + client = motor.motor_asyncio.AsyncIOMotorClient( + "mongodb://localhost:27017", serverSelectionTimeoutMS=100 + ) + + try: + await client.server_info() + except pymongo.errors.ServerSelectionTimeoutError: + pytest.skip("MongoDB not available", allow_module_level=True) + return + db = client["test_database"] collection = db["users"] @@ -21,6 +30,7 @@ async def mongodb_user_db() -> AsyncGenerator[MongoDBUserDatabase, None]: @pytest.mark.asyncio +@pytest.mark.db async def test_queries(mongodb_user_db): user = BaseUserDB( id="111", diff --git a/tests/test_db_sqlalchemy.py b/tests/test_db_sqlalchemy.py index cd8fee22..2eba8006 100644 --- a/tests/test_db_sqlalchemy.py +++ b/tests/test_db_sqlalchemy.py @@ -34,6 +34,7 @@ async def sqlalchemy_user_db() -> AsyncGenerator[SQLAlchemyUserDatabase, None]: @pytest.mark.asyncio +@pytest.mark.db async def test_queries(sqlalchemy_user_db): user = BaseUserDB( id="111", diff --git a/tests/test_fastapi_users.py b/tests/test_fastapi_users.py index 6edb031f..0e3e4b85 100644 --- a/tests/test_fastapi_users.py +++ b/tests/test_fastapi_users.py @@ -35,6 +35,7 @@ def fastapi_users(request, mock_user_db, mock_authentication) -> FastAPIUsers: @pytest.fixture() +@pytest.mark.fastapi_users def test_app_client(fastapi_users) -> TestClient: app = FastAPI() app.include_router(fastapi_users.router, prefix="/users") @@ -54,6 +55,7 @@ def test_app_client(fastapi_users) -> TestClient: return TestClient(app) +@pytest.mark.fastapi_users class TestFastAPIUsers: def test_event_handlers(self, fastapi_users): event_handlers = fastapi_users.router.event_handlers @@ -61,6 +63,7 @@ class TestFastAPIUsers: assert len(event_handlers[Event.ON_AFTER_FORGOT_PASSWORD]) == 1 +@pytest.mark.fastapi_users class TestRouter: def test_routes_exist(self, test_app_client: TestClient): response = test_app_client.post("/users/register") @@ -85,6 +88,7 @@ class TestRouter: assert response.status_code != status.HTTP_404_NOT_FOUND +@pytest.mark.fastapi_users class TestGetCurrentUser: def test_missing_token(self, test_app_client: TestClient): response = test_app_client.get("/current-user") @@ -103,6 +107,7 @@ class TestGetCurrentUser: assert response.status_code == status.HTTP_200_OK +@pytest.mark.fastapi_users class TestGetCurrentActiveUser: def test_missing_token(self, test_app_client: TestClient): response = test_app_client.get("/current-active-user") @@ -130,6 +135,7 @@ class TestGetCurrentActiveUser: assert response.status_code == status.HTTP_200_OK +@pytest.mark.fastapi_users class TestGetCurrentSuperuser: def test_missing_token(self, test_app_client: TestClient): response = test_app_client.get("/current-superuser") diff --git a/tests/test_router.py b/tests/test_router.py index ed9220be..f2a038f7 100644 --- a/tests/test_router.py +++ b/tests/test_router.py @@ -57,6 +57,7 @@ def test_app_client(mock_user_db, mock_authentication, event_handler) -> TestCli return TestClient(app) +@pytest.mark.router class TestRegister: def test_empty_body(self, test_app_client: TestClient, event_handler): response = test_app_client.post("/register", json={}) @@ -123,6 +124,7 @@ class TestRegister: assert response_json["is_active"] is True +@pytest.mark.router class TestLogin: def test_empty_body(self, test_app_client: TestClient): response = test_app_client.post("/login", data={}) @@ -163,6 +165,7 @@ class TestLogin: assert response.json()["detail"] == ErrorCode.LOGIN_BAD_CREDENTIALS +@pytest.mark.router class TestForgotPassword: def test_empty_body(self, test_app_client: TestClient, event_handler): response = test_app_client.post("/forgot-password", json={}) @@ -199,6 +202,7 @@ class TestForgotPassword: assert decoded_token["user_id"] == user.id +@pytest.mark.router class TestResetPassword: def test_empty_body(self, test_app_client: TestClient): response = test_app_client.post("/reset-password", json={}) @@ -270,6 +274,7 @@ class TestResetPassword: assert updated_user.hashed_password != current_hashed_passord +@pytest.mark.router class TestMe: def test_missing_token(self, test_app_client: TestClient): response = test_app_client.get("/me") @@ -294,6 +299,7 @@ class TestMe: assert response_json["email"] == user.email +@pytest.mark.router class TestUpdateMe: def test_missing_token(self, test_app_client: TestClient): response = test_app_client.patch("/me") @@ -365,6 +371,7 @@ class TestUpdateMe: assert updated_user.hashed_password != current_hashed_passord +@pytest.mark.router class TestListUsers: def test_missing_token(self, test_app_client: TestClient): response = test_app_client.get("/") @@ -389,6 +396,7 @@ class TestListUsers: assert "hashed_password" not in user +@pytest.mark.router class TestGetUser: def test_missing_token(self, test_app_client: TestClient): response = test_app_client.get("/000") @@ -421,6 +429,7 @@ class TestGetUser: assert "hashed_password" not in response_json +@pytest.mark.router class TestUpdateUser: def test_missing_token(self, test_app_client: TestClient): response = test_app_client.patch("/000") @@ -517,6 +526,7 @@ class TestUpdateUser: assert updated_user.hashed_password != current_hashed_passord +@pytest.mark.router class TestDeleteUser: def test_missing_token(self, test_app_client: TestClient): response = test_app_client.delete("/000")