test_get_access_token.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. from unittest.mock import Mock, patch
  2. import pytest
  3. from requests.exceptions import Timeout
  4. from ...conf.test import override_dynamic_settings
  5. from .. import exceptions
  6. from ..client import REQUESTS_TIMEOUT, get_access_token
  7. ACCESS_TOKEN = "acc3ss-t0k3n"
  8. CODE_GRANT = "valid-code"
  9. @pytest.fixture
  10. def mock_request(dynamic_settings):
  11. return Mock(
  12. settings=dynamic_settings,
  13. build_absolute_uri=lambda url: f"http://mysite.com{url or ''}",
  14. )
  15. @override_dynamic_settings(
  16. oauth2_client_id="clientid123",
  17. oauth2_client_secret="secr3t",
  18. oauth2_token_url="https://example.com/oauth2/token",
  19. )
  20. def test_access_token_is_retrieved_using_post_request(mock_request):
  21. post_mock = Mock(
  22. return_value=Mock(
  23. status_code=200,
  24. json=Mock(
  25. return_value={
  26. "access_token": ACCESS_TOKEN,
  27. },
  28. ),
  29. ),
  30. )
  31. with patch("requests.post", post_mock):
  32. assert get_access_token(mock_request, CODE_GRANT) == ACCESS_TOKEN
  33. post_mock.assert_called_once_with(
  34. "https://example.com/oauth2/token",
  35. data={
  36. "grant_type": "authorization_code",
  37. "client_id": "clientid123",
  38. "client_secret": "secr3t",
  39. "redirect_uri": "http://mysite.com/oauth2/complete/",
  40. "code": CODE_GRANT,
  41. },
  42. headers={},
  43. timeout=REQUESTS_TIMEOUT,
  44. )
  45. @override_dynamic_settings(
  46. oauth2_client_id="clientid123",
  47. oauth2_client_secret="secr3t",
  48. oauth2_token_url="https://example.com/oauth2/token",
  49. oauth2_token_extra_headers="Accept: application/json\nApi-Ver:1234",
  50. )
  51. def test_access_token_is_retrieved_using_extra_headers(mock_request):
  52. post_mock = Mock(
  53. return_value=Mock(
  54. status_code=200,
  55. json=Mock(
  56. return_value={
  57. "access_token": ACCESS_TOKEN,
  58. },
  59. ),
  60. ),
  61. )
  62. with patch("requests.post", post_mock):
  63. assert get_access_token(mock_request, CODE_GRANT) == ACCESS_TOKEN
  64. post_mock.assert_called_once_with(
  65. "https://example.com/oauth2/token",
  66. data={
  67. "grant_type": "authorization_code",
  68. "client_id": "clientid123",
  69. "client_secret": "secr3t",
  70. "redirect_uri": "http://mysite.com/oauth2/complete/",
  71. "code": CODE_GRANT,
  72. },
  73. headers={
  74. "Accept": "application/json",
  75. "Api-Ver": "1234",
  76. },
  77. timeout=REQUESTS_TIMEOUT,
  78. )
  79. @override_dynamic_settings(
  80. oauth2_client_id="clientid123",
  81. oauth2_client_secret="secr3t",
  82. oauth2_token_url="https://example.com/oauth2/token",
  83. oauth2_json_token_path="data.auth.token",
  84. )
  85. def test_access_token_is_extracted_from_json(mock_request):
  86. post_mock = Mock(
  87. return_value=Mock(
  88. status_code=200,
  89. json=Mock(
  90. return_value={
  91. "data": {
  92. "auth": {
  93. "token": ACCESS_TOKEN,
  94. },
  95. },
  96. },
  97. ),
  98. ),
  99. )
  100. with patch("requests.post", post_mock):
  101. assert get_access_token(mock_request, CODE_GRANT) == ACCESS_TOKEN
  102. post_mock.assert_called_once()
  103. @override_dynamic_settings(
  104. oauth2_client_id="clientid123",
  105. oauth2_client_secret="secr3t",
  106. oauth2_token_url="https://example.com/oauth2/token",
  107. )
  108. def test_exception_is_raised_if_access_token_request_times_out(mock_request):
  109. post_mock = Mock(side_effect=Timeout())
  110. with patch("requests.post", post_mock):
  111. with pytest.raises(exceptions.OAuth2AccessTokenRequestError):
  112. get_access_token(mock_request, CODE_GRANT)
  113. post_mock.assert_called_once()
  114. @override_dynamic_settings(
  115. oauth2_client_id="clientid123",
  116. oauth2_client_secret="secr3t",
  117. oauth2_token_url="https://example.com/oauth2/token",
  118. )
  119. def test_exception_is_raised_if_access_token_request_response_is_not_200(mock_request):
  120. post_mock = Mock(
  121. return_value=Mock(
  122. status_code=400,
  123. ),
  124. )
  125. with patch("requests.post", post_mock):
  126. with pytest.raises(exceptions.OAuth2AccessTokenResponseError):
  127. get_access_token(mock_request, CODE_GRANT)
  128. post_mock.assert_called_once()
  129. @override_dynamic_settings(
  130. oauth2_client_id="clientid123",
  131. oauth2_client_secret="secr3t",
  132. oauth2_token_url="https://example.com/oauth2/token",
  133. )
  134. def test_exception_is_raised_if_access_token_request_response_is_not_json(mock_request):
  135. post_mock = Mock(
  136. return_value=Mock(
  137. status_code=200,
  138. json=Mock(
  139. side_effect=ValueError(),
  140. ),
  141. ),
  142. )
  143. with patch("requests.post", post_mock):
  144. with pytest.raises(exceptions.OAuth2AccessTokenJSONError):
  145. get_access_token(mock_request, CODE_GRANT)
  146. post_mock.assert_called_once()
  147. @override_dynamic_settings(
  148. oauth2_client_id="clientid123",
  149. oauth2_client_secret="secr3t",
  150. oauth2_token_url="https://example.com/oauth2/token",
  151. )
  152. def test_exception_is_raised_if_access_token_request_response_json_is_not_object(
  153. mock_request,
  154. ):
  155. post_mock = Mock(
  156. return_value=Mock(
  157. status_code=200,
  158. json=Mock(
  159. return_value=["json", "list"],
  160. ),
  161. ),
  162. )
  163. with patch("requests.post", post_mock):
  164. with pytest.raises(exceptions.OAuth2AccessTokenJSONError):
  165. get_access_token(mock_request, CODE_GRANT)
  166. post_mock.assert_called_once()
  167. @override_dynamic_settings(
  168. oauth2_client_id="clientid123",
  169. oauth2_client_secret="secr3t",
  170. oauth2_token_url="https://example.com/oauth2/token",
  171. )
  172. def test_exception_is_raised_if_access_token_request_response_json_misses_token(
  173. mock_request,
  174. ):
  175. post_mock = Mock(
  176. return_value=Mock(
  177. status_code=200,
  178. json=Mock(
  179. return_value={
  180. "no_token": "nope",
  181. },
  182. ),
  183. ),
  184. )
  185. with patch("requests.post", post_mock):
  186. with pytest.raises(exceptions.OAuth2AccessTokenNotProvidedError):
  187. get_access_token(mock_request, CODE_GRANT)
  188. post_mock.assert_called_once()