test_api.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. # coding: utf-8
  2. import json
  3. from urllib.parse import urljoin
  4. import aiohttp
  5. import pytest
  6. from echo.utils import decode_json
  7. content_type = 'application/json; charset=utf-8'
  8. payload = {
  9. 'name': 'Joaozinho',
  10. 'age': 9,
  11. }
  12. str_payload = {
  13. 'name': 'Joaozinho',
  14. 'age': '9',
  15. }
  16. DEFAULT_HEADER = {
  17. 'Content-Length': '31',
  18. 'Content-Type': '',
  19. 'Host': 'localhost'
  20. }
  21. ZERO_LENGTH_HEADER = {
  22. 'Content-Length': '0',
  23. 'Content-Type': '',
  24. 'Host': 'localhost'
  25. }
  26. # Mock tests
  27. @pytest.mark.asyncio
  28. def test_get_mock(api_server):
  29. url = urljoin(api_server, '/mocks/')
  30. response = yield from aiohttp.request('GET', url)
  31. assert response.status == 200
  32. assert response.reason == 'OK'
  33. assert response.headers['content-type'] == content_type
  34. response_json = yield from response.json()
  35. assert response_json == {'mocks': {}}
  36. @pytest.mark.asyncio
  37. def test_put_mock(api_server):
  38. response_must_contain = {
  39. 'status_code': 201,
  40. 'body': {
  41. 'name': 'John Doe',
  42. 'email': 'john@doe.com',
  43. },
  44. 'headers': {
  45. 'content_type': 'application/json',
  46. },
  47. }
  48. request_headers = {
  49. 'content_type': 'application/json',
  50. 'accept': 'application/json',
  51. }
  52. request_must_contain = {
  53. 'body': {
  54. 'name': 'John Doe',
  55. 'email': 'john@doe.com',
  56. 'password': 'secret',
  57. },
  58. 'headers': request_headers,
  59. }
  60. expectation = {
  61. 'method': 'POST',
  62. 'path': '/v1/users/',
  63. 'request': request_must_contain,
  64. 'response': response_must_contain,
  65. }
  66. url = urljoin(api_server, '/mocks/')
  67. # Configure the mock
  68. response = yield from aiohttp.request('PUT', url,
  69. data=json.dumps(expectation),
  70. headers=request_headers)
  71. assert response.status == 201
  72. assert response.reason == 'Created'
  73. assert response.headers['content-type'] == content_type
  74. response_json = yield from response.json()
  75. assert 'path' in response_json.keys()
  76. # Use the mock
  77. post_url = urljoin(api_server, response_json['path'])
  78. post_body = json.dumps(request_must_contain['body'])
  79. response = yield from aiohttp.request('POST', post_url,
  80. data=post_body,
  81. headers=request_headers)
  82. assert response.status == 201
  83. assert response.reason == 'Created'
  84. assert response.headers['content-type'] == content_type
  85. response_json = yield from response.json()
  86. assert 'email' in response_json.keys()
  87. assert 'name' in response_json.keys()
  88. # Health
  89. @pytest.mark.asyncio
  90. def test_health(api_server):
  91. url = urljoin(api_server, '/health/')
  92. response = yield from aiohttp.request('GET', url)
  93. assert response.status == 200
  94. assert response.reason == 'OK'
  95. assert response.headers['content-type'] == content_type
  96. response_json = yield from response.json()
  97. assert response_json == {'status': 'ok'}
  98. # Callback tests
  99. @pytest.mark.asyncio
  100. def test_queue_request_return_status_200(api_server):
  101. response = yield from aiohttp.request('POST',
  102. urljoin(api_server, urljoin(api_server, '/callbacks/app/queue/')),
  103. data=json.dumps(payload))
  104. assert response.status == 200
  105. @pytest.mark.asyncio
  106. def test_queue_request_return_json(api_server):
  107. response = yield from aiohttp.request('POST',
  108. urljoin(api_server, urljoin(api_server, '/callbacks/app/queue/')),
  109. data=json.dumps(payload))
  110. response_json = yield from response.json()
  111. assert response_json['request']['method'] == 'POST'
  112. assert response_json['request']['data'] == payload
  113. @pytest.mark.asyncio
  114. def test_queue_request_store_request(api_server, redis):
  115. yield from aiohttp.request('POST', urljoin(api_server, '/callbacks/app/queue/'), data=json.dumps(payload))
  116. assert redis.llen('app-queue') == 1
  117. @pytest.mark.asyncio
  118. def test_queue_request_store_json(api_server, redis):
  119. url = urljoin(api_server, '/callbacks/app/queue/')
  120. yield from aiohttp.request('POST', url, data=json.dumps(payload),
  121. headers={'X-Region': 'Sao_Paulo'})
  122. db_json = decode_json(redis.rpop('app-queue'))
  123. assert db_json['header']['X-REGION'] == 'Sao_Paulo'
  124. assert db_json['method'] == 'POST'
  125. assert db_json['data'] == payload
  126. """
  127. @pytest.mark.asyncio
  128. def test_queue_request_with_additional_url_return_status_200(api_server):
  129. response = yield from aiohttp.request('POST', '/callbacks/app/queue/some/more/url/here', data=json.dumps(payload))
  130. assert response.status == 200
  131. @pytest.mark.asyncio
  132. def test_queue_request_with_additional_url_json(api_server, redis):
  133. yield from aiohttp.request('POST', '/callbacks/app/queue/some/more/url/here', data=json.dumps(payload))
  134. expected_data = {
  135. 'method': 'POST',
  136. 'data': payload,
  137. 'additional_url': 'some/more/url/here',
  138. 'header': DEFAULT_HEADER,
  139. }
  140. assert decode_json(redis.rpop('app-queue')) == expected_data
  141. """
  142. @pytest.mark.asyncio
  143. def test_queue_request_store_multiple_requests(api_server, redis):
  144. yield from aiohttp.request('POST', urljoin(api_server, '/callbacks/app/queue/'), data=json.dumps(payload))
  145. yield from aiohttp.request('POST', urljoin(api_server, '/callbacks/app/queue/'), data=json.dumps(payload))
  146. yield from aiohttp.request('POST', urljoin(api_server, '/callbacks/app/queue/'), data=json.dumps(payload))
  147. assert redis.llen('app-queue') == 3
  148. @pytest.mark.asyncio
  149. def test_queue_request_store_request_different_apps(api_server, redis):
  150. yield from aiohttp.request('POST', urljoin(api_server, '/callbacks/app1/queue/'), data=json.dumps(payload))
  151. yield from aiohttp.request('POST', urljoin(api_server, '/callbacks/app2/queue/'), data=json.dumps(payload))
  152. assert redis.llen('app1-queue') == 1
  153. assert redis.llen('app2-queue') == 1
  154. @pytest.mark.asyncio
  155. def test_queue_request_store_request_different_queues(api_server, redis):
  156. yield from aiohttp.request('POST', urljoin(api_server, '/callbacks/app/queue1/'), data=json.dumps(payload))
  157. yield from aiohttp.request('POST', urljoin(api_server, '/callbacks/app/queue2/'), data=json.dumps(payload))
  158. assert redis.llen('app-queue1') == 1
  159. assert redis.llen('app-queue2') == 1
  160. @pytest.mark.asyncio
  161. def test_get_requests_return_status_200(api_server):
  162. response = yield from aiohttp.request('GET', urljoin(api_server, '/callbacks/_all/app/queue/'))
  163. assert response.status == 200
  164. @pytest.mark.asyncio
  165. def test_get_requests_empty(api_server):
  166. response = yield from aiohttp.request('GET', urljoin(api_server, '/callbacks/_all/app/queue/'))
  167. response_json = yield from response.json()
  168. assert response_json == {'requests': []}
  169. @pytest.mark.asyncio
  170. def test_get_requests_one_request(api_server):
  171. yield from aiohttp.request('POST', urljoin(api_server, '/callbacks/app/queue/'), data=json.dumps(payload))
  172. response = yield from aiohttp.request('GET', urljoin(api_server, '/callbacks/_all/app/queue/'))
  173. response_json = yield from response.json()
  174. assert response_json['requests'][0]['method'] == 'POST'
  175. assert response_json['requests'][0]['data'] == payload
  176. # TODO: Make it work
  177. """
  178. @pytest.mark.asyncio
  179. def test_get_requests_multiple_request(api_server):
  180. yield from aiohttp.request('POST', urljoin(api_server, '/callbacks/app/queue/'), data=json.dumps(payload))
  181. yield from aiohttp.request('PUT', urljoin(api_server, '/callbacks/app/queue/'), data=json.dumps(payload))
  182. yield from aiohttp.request('PATCH', urljoin(api_server, '/callbacks/app/queue/'), data=json.dumps(payload))
  183. # TODO: Make it work
  184. # yield from aiohttp.request('GET', urljoin(api_server, '/callbacks/app/queue/'), query_string=payload)
  185. yield from aiohttp.request('DELETE', urljoin(api_server, '/callbacks/app/queue/'))
  186. response = yield from aiohttp.request('GET', urljoin(api_server, '/callbacks/_all/app/queue/'))
  187. expected_data = [
  188. {'method': 'POST', 'data': payload, 'header': DEFAULT_HEADER, 'additional_url': ''},
  189. {'method': 'PUT', 'data': payload, 'header': DEFAULT_HEADER, 'additional_url': ''},
  190. {'method': 'PATCH', 'data': payload, 'header': DEFAULT_HEADER, 'additional_url': ''},
  191. {'method': 'GET', 'data': str_payload, 'header': ZERO_LENGTH_HEADER, 'additional_url': ''},
  192. {'method': 'DELETE', 'data': {}, 'header': ZERO_LENGTH_HEADER, 'additional_url': ''},
  193. ]
  194. response_json = yield from response.json()
  195. assert response_json == {'requests': expected_data}
  196. """
  197. @pytest.mark.asyncio
  198. def test_get_requests_remove_key(api_server, redis):
  199. yield from aiohttp.request('POST', urljoin(api_server, '/callbacks/app/queue/'), data=json.dumps(payload))
  200. yield from aiohttp.request('GET', urljoin(api_server, '/callbacks/_all/app/queue/'))
  201. assert not redis.exists('app-queue')
  202. @pytest.mark.asyncio
  203. def test_first_request_return_status_200(api_server):
  204. response = yield from aiohttp.request('GET', urljoin(api_server, '/callbacks/_first/app/queue/'))
  205. assert response.status == 200
  206. @pytest.mark.asyncio
  207. def test_first_request_empty(api_server):
  208. response = yield from aiohttp.request('GET', urljoin(api_server, '/callbacks/_first/app/queue/'))
  209. response_json = yield from response.json()
  210. assert response_json == {'request': {}}
  211. @pytest.mark.asyncio
  212. def test_first_request_one_request(api_server):
  213. yield from aiohttp.request('POST', urljoin(api_server, '/callbacks/app/queue/'), data=json.dumps(payload))
  214. response = yield from aiohttp.request('GET', urljoin(api_server, '/callbacks/_first/app/queue/'))
  215. expected_data = {
  216. 'request': {
  217. 'method': 'POST',
  218. 'data': payload,
  219. 'additional_url': '',
  220. 'header': DEFAULT_HEADER,
  221. }
  222. }
  223. response_json = yield from response.json()
  224. assert response_json['request']['method'] == 'POST'
  225. assert response_json['request']['data'] == payload
  226. @pytest.mark.asyncio
  227. def test_first_request_multiple_request(api_server):
  228. yield from aiohttp.request('POST', urljoin(api_server, '/callbacks/app/queue/'), data=json.dumps(payload))
  229. yield from aiohttp.request('PUT', urljoin(api_server, '/callbacks/app/queue/'), data=json.dumps(payload))
  230. yield from aiohttp.request('PATCH', urljoin(api_server, '/callbacks/app/queue/'), data=json.dumps(payload))
  231. # yield from aiohttp.request('GET', urljoin(api_server, '/callbacks/app/queue/'), query_string=payload)
  232. yield from aiohttp.request('DELETE', urljoin(api_server, '/callbacks/app/queue/'))
  233. response = yield from aiohttp.request('GET', urljoin(api_server, '/callbacks/_first/app/queue/'))
  234. expected_data = {'method': 'POST', 'data': payload, 'header': DEFAULT_HEADER, 'additional_url': ''}
  235. response_json = yield from response.json()
  236. assert response_json['request']['method'] == 'POST'
  237. assert response_json['request']['data'] == payload
  238. @pytest.mark.asyncio
  239. def test_last_request_return_status_200(api_server):
  240. response = yield from aiohttp.request('GET', urljoin(api_server, '/callbacks/_last/app/queue/'))
  241. assert response.status == 200
  242. @pytest.mark.asyncio
  243. def test_last_request_empty(api_server):
  244. response = yield from aiohttp.request('GET', urljoin(api_server, '/callbacks/_last/app/queue/'))
  245. response_json = yield from response.json()
  246. assert response_json == {'request': {}}
  247. @pytest.mark.asyncio
  248. def test_last_request_one_request(api_server):
  249. url = urljoin(api_server, '/callbacks/app/queue/')
  250. yield from aiohttp.request('POST', url, data=json.dumps(payload))
  251. url_last = urljoin(api_server, '/callbacks/_last/app/queue/')
  252. response = yield from aiohttp.request('GET', url_last)
  253. response_json = yield from response.json()
  254. assert response_json['request']['method'] == 'POST'
  255. assert response_json['request']['data'] == payload
  256. """
  257. @pytest.mark.asyncio
  258. def test_last_request_multiple_request(api_server):
  259. yield from aiohttp.request('POST', urljoin(api_server, '/callbacks/app/que
  260. yield from aiohttp.request('PUT', urljoin(api_server, '/callbacks/app/queu
  261. yield from aiohttp.request('PATCH', urljoin(api_server, '/callbacks/app/qu
  262. yield from aiohttp.request('GET', urljoin(api_server, '/callbacks/app/queu
  263. yield from aiohttp.request('DELETE', urljoin(api_server, '/callbacks/app/q
  264. response = yield from aiohttp.request('GET', urljoin(api_server, '/callbac
  265. expected_data = {'method': 'DELETE', 'data': {}, 'additional_url': '', 'he
  266. assert decode_json(response.data) == {'request': expected_data}
  267. """
  268. @pytest.mark.asyncio
  269. def test_clean_requests_none_request(api_server, redis):
  270. url = urljoin(api_server, '/callbacks/_clean/app/queue/')
  271. yield from aiohttp.request('GET', url)
  272. assert not redis.exists('app-queue')
  273. @pytest.mark.asyncio
  274. def test_clean_requests_none_request_return_status_200(api_server):
  275. url = urljoin(api_server, '/callbacks/_clean/app/queue/')
  276. response = yield from aiohttp.request('GET', url)
  277. assert response.status == 200
  278. @pytest.mark.asyncio
  279. def test_clean_requests_none_request_return_empty_json(api_server):
  280. url = urljoin(api_server, '/callbacks/_clean/app/queue/')
  281. response = yield from aiohttp.request('GET', url)
  282. response_json = yield from response.json()
  283. assert response_json == {}
  284. @pytest.mark.asyncio
  285. def test_clean_requests_multiple_requests(api_server, redis):
  286. url = urljoin(api_server, '/callbacks/app/queue/')
  287. yield from aiohttp.request('POST', url, data=json.dumps(payload))
  288. yield from aiohttp.request('PUT', url, data=json.dumps(payload))
  289. yield from aiohttp.request('PATCH', url, data=json.dumps(payload))
  290. yield from aiohttp.request('DELETE', url)
  291. yield from aiohttp.request('GET', urljoin(api_server, '/callbacks/_clean/app/queue/'))
  292. assert not redis.exists('app-queue')