/ fastapi-template-users / tests / utils / test_recaptcha.py
test_recaptcha.py
 1  from contextlib import asynccontextmanager
 2  from typing import Any, AsyncIterator
 3  from unittest.mock import AsyncMock, MagicMock
 4  
 5  import pytest
 6  from _pytest.monkeypatch import MonkeyPatch
 7  from pytest_mock import MockerFixture
 8  
 9  from .._utils import mock_asynccontextmanager
10  from api.settings import settings
11  from api.utils import recaptcha
12  
13  
14  @pytest.mark.parametrize(
15      "secret,sitekey,expected",
16      [("", "", False), (None, None, False), ("foo", "", False), ("", "bar", False), ("foo", "bar", True)],
17  )
18  async def test__recaptcha_enabled(
19      secret: str | None, sitekey: str | None, expected: bool, monkeypatch: MonkeyPatch
20  ) -> None:
21      monkeypatch.setattr(settings, "recaptcha_sitekey", sitekey)
22      monkeypatch.setattr(settings, "recaptcha_secret", secret)
23  
24      assert recaptcha.recaptcha_enabled() == expected
25  
26  
27  async def test__check_recaptcha(mocker: MockerFixture, monkeypatch: MonkeyPatch) -> None:
28      client_patch = mocker.patch("aiohttp.ClientSession")
29  
30      secret = MagicMock()
31      token = MagicMock()
32      expected = MagicMock()
33  
34      session = MagicMock()
35      response = AsyncMock()
36  
37      client_patch.side_effect, func_callbacks, assert_calls = mock_asynccontextmanager(3, session)
38  
39      @asynccontextmanager
40      async def session_context(url: str, data: dict[str, Any]) -> AsyncIterator[AsyncMock]:
41          assert url == "https://www.google.com/recaptcha/api/siteverify"
42          assert data == {"secret": secret, "response": token}
43  
44          func_callbacks[0]()
45          yield response
46          func_callbacks[2]()
47  
48      session.post.side_effect = session_context
49      response.json.side_effect = lambda: func_callbacks[1]() or {"success": expected}
50  
51      monkeypatch.setattr(settings, "recaptcha_secret", secret)
52      assert await recaptcha.check_recaptcha(token) == expected
53  
54      assert_calls()
55      client_patch.assert_called_once()
56      session.post.assert_called_once()
57      response.json.assert_called_once()