text: from typing import Any, AsyncGenerator, Dict, cast
  
  import httpx
  import pytest
  from fastapi import FastAPI, status
  
  from fastapi_users.manager import (
      InvalidPasswordException,
      InvalidResetPasswordToken,
      UserInactive,
      UserNotExists,
  )
  from fastapi_users.router import ErrorCode, get_reset_password_router
  from tests.conftest import AsyncMethodMocker, UserManagerMock
  
  
  @pytest.fixture
  @pytest.mark.asyncio
  async def test_app_client(
      get_user_manager, get_test_client
  ) -> AsyncGenerator[httpx.AsyncClient, None]:
      reset_router = get_reset_password_router(get_user_manager)
  
      app = FastAPI()
      app.include_router(reset_router)
  
      async for client in get_test_client(app):
          yield client
  
  
  @pytest.mark.router
  @pytest.mark.asyncio
  class TestForgotPassword:
      async def test_empty_body(
          self, test_app_client: httpx.AsyncClient, user_manager: UserManagerMock
      ):
          response = await test_app_client.post("/forgot-password", json={})
          assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
          assert user_manager.forgot_password.called is False
  
      async def test_not_existing_user(
          self, test_app_client: httpx.AsyncClient, user_manager: UserManagerMock
      ):
          user_manager.get_by_email.side_effect = UserNotExists()
          json = {"email": "lancelot@camelot.bt"}
          response = await test_app_client.post("/forgot-password", json=json)
          assert response.status_code == status.HTTP_202_ACCEPTED
          assert user_manager.forgot_password.called is False
  
      async def test_inactive_user(
          self, test_app_client: httpx.AsyncClient, user_manager: UserManagerMock
      ):
          user_manager.forgot_password.side_effect = UserInactive()
          json = {"email": "percival@camelot.bt"}
          response = await test_app_client.post("/forgot-password", json=json)
          assert response.status_code == status.HTTP_202_ACCEPTED
  
      async def test_existing_user(
          self,
          async_method_mocker: AsyncMethodMocker,
          test_app_client: httpx.AsyncClient,
          user_manager: UserManagerMock,
      ):
          async_method_mocker(user_manager, "forgot_password", return_value=None)
          json = {"email": "king.arthur@camelot.bt"}
          response = await test_app_client.post("/forgot-password", json=json)
          assert response.status_code == status.HTTP_202_ACCEPTED
  
  
  @pytest.mark.router
  @pytest.mark.asyncio
  class TestResetPassword:
      async def test_empty_body(
          self,
          test_app_client: httpx.AsyncClient,
          user_manager: UserManagerMock,
      ):
          response = await test_app_client.post("/reset-password", json={})
          assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
          assert user_manager.reset_password.called is False
  
      async def test_missing_token(
          self, test_app_client: httpx.AsyncClient, user_manager: UserManagerMock
      ):
          json = {"password": "guinevere"}
          response = await test_app_client.post("/reset-password", json=json)
          assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
          assert user_manager.reset_password.called is False
  
      async def test_missing_password(
          self,
          test_app_client: httpx.AsyncClient,
          user_manager: UserManagerMock,
      ):
          json = {"token": "foo"}
          response = await test_app_client.post("/reset-password", json=json)
          assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
          assert user_manager.reset_password.called is False
  
      async def test_invalid_token(
          self,
          test_app_client: httpx.AsyncClient,
          user_manager: UserManagerMock,
      ):
          user_manager.reset_password.side_effect = InvalidResetPasswordToken()
          json = {"token": "foo", "password": "guinevere"}
          response = await test_app_client.post("/reset-password", json=json)
          assert response.status_code == status.HTTP_400_BAD_REQUEST
          data = cast(Dict[str, Any], response.json())
          assert data["detail"] == ErrorCode.RESET_PASSWORD_BAD_TOKEN
  
      async def test_inactive_user(
          self,
          test_app_client: httpx.AsyncClient,
          user_manager: UserManagerMock,
      ):
          user_manager.reset_password.side_effect = UserInactive()
          json = {"token": "foo", "password": "guinevere"}
          response = await test_app_client.post("/reset-password", json=json)
          assert response.status_code == status.HTTP_400_BAD_REQUEST
          data = cast(Dict[str, Any], response.json())
          assert data["detail"] == ErrorCode.RESET_PASSWORD_BAD_TOKEN
  
      async def test_invalid_password(
          self,
          test_app_client: httpx.AsyncClient,
          user_manager: UserManagerMock,
      ):
          user_manager.reset_password.side_effect = InvalidPasswordException(
              reason="Invalid"
          )
          json = {"token": "foo", "password": "guinevere"}
          response = await test_app_client.post("/reset-password", json=json)
          assert response.status_code == status.HTTP_400_BAD_REQUEST
          data = cast(Dict[str, Any], response.json())
          assert data["detail"] == {
              "code": ErrorCode.RESET_PASSWORD_INVALID_PASSWORD,
              "reason": "Invalid",
          }
  
      async def test_valid_user_password(
          self,
          async_method_mocker: AsyncMethodMocker,
          test_app_client: httpx.AsyncClient,
          user_manager: UserManagerMock,
      ):
          async_method_mocker(user_manager, "reset_password", return_value=None)
          json = {"token": "foo", "password": "guinevere"}
          response = await test_app_client.post("/reset-password", json=json)
          assert response.status_code == status.HTTP_200_OK
  
  
  @pytest.mark.asyncio
  async def test_forgot_password_namespace(get_user_manager):
      app = FastAPI()
      app.include_router(get_reset_password_router(get_user_manager))
      assert app.url_path_for("forgot_password") == "/forgot-password"
  
  
  @pytest.mark.asyncio
  async def test_reset_password_namespace(get_user_manager):
      app = FastAPI()
      app.include_router(get_reset_password_router(get_user_manager))
      assert app.url_path_for("reset_password") == "/reset-password"
  