async def send_email(self, request: Request):
        qs = sa.select(User).where(User.email == self.data["email"])
        result = await User.execute(qs)
        user = result.scalars().first()
        if not user:
            return

        context = {
            "request": request,
            "uid": urlsafe_base64_encode(bytes(str(user.id), encoding="utf-8")),
            "user": user,
            "token": token_generator.make_token(user),
        }
        msg = EmailMessage()

        subject_tmpl = templates.get_template("auth/password_reset_subject.txt")
        subject = subject_tmpl.render(context)
        body_tmpl = templates.get_template("auth/password_reset_body.txt")
        body = body_tmpl.render(context)

        msg["To"] = [user.email]
        msg["Subject"] = subject
        msg.set_content(body)

        await send_message(msg)
async def test_get_invalid_uid(client, user):
    uidb64 = "XX"
    token = token_generator.make_token(user)
    url = app.url_path_for("auth:password_reset_confirm",
                           uidb64=uidb64,
                           token=token)

    response = await client.get(url)
    assert response.status_code == 404
async def test_get_200(client, user):
    uidb64 = urlsafe_base64_encode(bytes(str(user.id), encoding="utf-8"))
    token = token_generator.make_token(user)
    url = app.url_path_for("auth:password_reset_confirm",
                           uidb64=uidb64,
                           token=token)

    response = await client.get(url)
    assert response.status_code == 200
async def test_invalid(test_data, client, user):
    uidb64 = urlsafe_base64_encode(bytes(str(user.id), encoding="utf-8"))
    token = token_generator.make_token(user)
    url = app.url_path_for("auth:password_reset_confirm",
                           uidb64=uidb64,
                           token=token)

    response = await client.post(url, data=test_data)
    assert response.status_code == 200
    assert response.url == f"http://test{url}"
async def test_get_user_url_is_invalid_by_logging_in(client, user):
    uidb64 = urlsafe_base64_encode(bytes(str(user.id), encoding="utf-8"))
    token = token_generator.make_token(user)
    url = app.url_path_for("auth:password_reset_confirm",
                           uidb64=uidb64,
                           token=token)

    # here we just update the last_login to simulate the user logging
    # in after the pw request is created
    user.last_login = datetime.utcnow()
    await user.save()

    response = await client.get(url)
    assert response.status_code == 404
async def test_post_changed_password(client, user):
    uidb64 = urlsafe_base64_encode(bytes(str(user.id), encoding="utf-8"))
    token = token_generator.make_token(user)
    url = app.url_path_for("auth:password_reset_confirm",
                           uidb64=uidb64,
                           token=token)

    await client.post(url,
                      data={
                          "new_password": "******",
                          "confirm_new_password": "******"
                      })

    user = await User.get(user.id)
    assert user.check_password("foobar25")
async def test_post_url_is_one_time_use(client, user):
    uidb64 = urlsafe_base64_encode(bytes(str(user.id), encoding="utf-8"))
    token = token_generator.make_token(user)
    url = app.url_path_for("auth:password_reset_confirm",
                           uidb64=uidb64,
                           token=token)

    await client.post(url,
                      data={
                          "new_password": "******",
                          "confirm_new_password": "******"
                      })

    another = await client.get(url)
    assert another.status_code == 404
async def test_post(client, user):
    uidb64 = urlsafe_base64_encode(bytes(str(user.id), encoding="utf-8"))
    token = token_generator.make_token(user)
    url = app.url_path_for("auth:password_reset_confirm",
                           uidb64=uidb64,
                           token=token)

    response = await client.post(url,
                                 data={
                                     "new_password": "******",
                                     "confirm_new_password": "******"
                                 })
    assert response.status_code == 302
    assert response.is_redirect
    url = app.url_path_for("auth:password_reset_complete")
    assert response.next_request.url == f"http://test{url}"