Fuel UI
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_handlers.py 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. # -*- coding: utf-8 -*-
  2. # Copyright 2013 Mirantis, Inc.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  5. # not use this file except in compliance with the License. You may obtain
  6. # a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. # License for the specific language governing permissions and limitations
  14. # under the License.
  15. import json
  16. import urllib
  17. import web
  18. from nailgun.api.v1.handlers.base import BaseHandler
  19. from nailgun.api.v1.handlers.base import handle_errors
  20. from nailgun.api.v1.handlers.base import serialize
  21. from nailgun.test.base import BaseIntegrationTest
  22. from nailgun.utils import reverse
  23. class TestHandlers(BaseIntegrationTest):
  24. def test_all_api_urls_404_or_405(self):
  25. urls = {
  26. 'ClusterHandler': {'obj_id': 1},
  27. 'NodeHandler': {'obj_id': 1},
  28. 'ReleaseHandler': {'obj_id': 1},
  29. }
  30. for handler in urls:
  31. test_url = reverse(handler, urls[handler])
  32. resp = self.app.get(test_url, expect_errors=True)
  33. self.assertIn(resp.status_code, [404, 405])
  34. resp = self.app.delete(test_url, expect_errors=True)
  35. self.assertIn(resp.status_code, [404, 405])
  36. resp = self.app.put(
  37. test_url,
  38. json.dumps({}),
  39. expect_errors=True
  40. )
  41. self.assertIn(resp.status_code, [404, 405])
  42. resp = self.app.post(
  43. test_url,
  44. json.dumps({}),
  45. expect_errors=True
  46. )
  47. self.assertIn(resp.status_code, [404, 405])
  48. def test_http_response(self):
  49. web.ctx.headers = []
  50. http_codes = (
  51. (200, 'ok'),
  52. (201, 'created'),
  53. (202, 'accepted'),
  54. (204, 'no content'),
  55. (400, 'bad request :('),
  56. (401, 'unauthorized'),
  57. (403, 'forbidden'),
  58. (404, 'not found, try again'),
  59. (405, 'no method'),
  60. (406, 'unacceptable'),
  61. (409, 'ooops, conflict'),
  62. (415, 'unsupported media type'),
  63. (500, 'internal problems'),
  64. )
  65. headers = {
  66. 'Content-Type': 'application/json',
  67. 'ETag': '737060cd8c284d8af7ad3082f209582d',
  68. }
  69. # test response status code and message
  70. for code, message in http_codes:
  71. with self.assertRaises(web.HTTPError) as cm:
  72. raise BaseHandler.http(
  73. status_code=code,
  74. msg=message,
  75. headers=headers
  76. )
  77. self.assertTrue(web.ctx.status.startswith(str(code)))
  78. self.assertTrue(cm.exception.data, message)
  79. for header, value in headers.items():
  80. self.assertIn((header, value), web.ctx.headers)
  81. def test_content_decorator(self):
  82. class FakeHandler(BaseHandler):
  83. @serialize
  84. def GET(self):
  85. return {}
  86. @serialize
  87. def POST(self):
  88. return {}
  89. web.ctx.headers = []
  90. web.ctx.env = {"HTTP_ACCEPT": "text/html"}
  91. fake_handler = FakeHandler()
  92. self.assertRaises(
  93. web.webapi.UnsupportedMediaType,
  94. fake_handler.GET
  95. )
  96. web.ctx.env = {"HTTP_ACCEPT": "*/*"}
  97. web.ctx.headers = []
  98. fake_handler.GET()
  99. self.assertIn(
  100. ('Content-Type', 'application/json'),
  101. web.ctx.headers
  102. )
  103. web.ctx.headers = []
  104. web.ctx.env = {"HTTP_ACCEPT": "application/json"}
  105. fake_handler.POST()
  106. self.assertIn(
  107. # we don't have plain/text serializer right now
  108. ('Content-Type', 'application/json'),
  109. web.ctx.headers
  110. )
  111. def test_invalid_handler_output(self):
  112. class FakeHandler(object):
  113. @handle_errors
  114. @serialize
  115. def GET(self):
  116. return {set([1, 2, 3])}
  117. fake_handler = FakeHandler()
  118. web.ctx.env = {"HTTP_ACCEPT": "*/*"}
  119. web.ctx.headers = []
  120. self.assertRaises(web.HTTPError, fake_handler.GET)
  121. def test_get_param_as_set(self):
  122. urls = ("/hello", "hello")
  123. class hello(object):
  124. def GET(self_inner):
  125. web.header('Content-Type', 'application/json')
  126. data = BaseHandler.get_param_as_set('test_param',
  127. delimiter=';')
  128. return json.dumps(list(data))
  129. app = web.application(urls, {'hello': hello})
  130. url = '/hello?test_param=' + urllib.quote('1;4 ; 777; 4;x ')
  131. resp = app.request(url)
  132. self.assertEqual(set(json.loads(resp.data)),
  133. set(['1', '4', '777', 'x']))
  134. def check_get_requested_mime(self, headers, expected_mime):
  135. urls = ("/hello", "hello")
  136. class hello(object):
  137. def GET(self_inner):
  138. web.header('Content-Type', 'text/plain')
  139. return BaseHandler.get_requested_mime()
  140. app = web.application(urls, {'hello': hello})
  141. resp = app.request('/hello', headers=headers)
  142. self.assertEqual(resp.data, expected_mime)
  143. def test_get_requested_mime1(self):
  144. self.check_get_requested_mime({'ACCEPT': 'text/html'}, 'text/html')
  145. def test_get_requested_mime2(self):
  146. self.check_get_requested_mime(
  147. {'ACCEPT': 'text/plain;q=0.7, text/html;level=1,'}, 'text/plain')
  148. def test_get_requested_default(self):
  149. self.check_get_requested_mime({}, 'application/json')