fuel-web/nailgun/nailgun/test/unit/test_handlers.py

188 lines
5.8 KiB
Python

# -*- coding: utf-8 -*-
# Copyright 2013 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import json
import urllib
import web
from nailgun.api.v1.handlers.base import BaseHandler
from nailgun.api.v1.handlers.base import handle_errors
from nailgun.api.v1.handlers.base import serialize
from nailgun.test.base import BaseIntegrationTest
from nailgun.utils import reverse
class TestHandlers(BaseIntegrationTest):
def test_all_api_urls_404_or_405(self):
urls = {
'ClusterHandler': {'obj_id': 1},
'NodeHandler': {'obj_id': 1},
'ReleaseHandler': {'obj_id': 1},
}
for handler in urls:
test_url = reverse(handler, urls[handler])
resp = self.app.get(test_url, expect_errors=True)
self.assertIn(resp.status_code, [404, 405])
resp = self.app.delete(test_url, expect_errors=True)
self.assertIn(resp.status_code, [404, 405])
resp = self.app.put(
test_url,
json.dumps({}),
expect_errors=True
)
self.assertIn(resp.status_code, [404, 405])
resp = self.app.post(
test_url,
json.dumps({}),
expect_errors=True
)
self.assertIn(resp.status_code, [404, 405])
def test_http_response(self):
web.ctx.headers = []
http_codes = (
(200, 'ok'),
(201, 'created'),
(202, 'accepted'),
(204, 'no content'),
(400, 'bad request :('),
(401, 'unauthorized'),
(403, 'forbidden'),
(404, 'not found, try again'),
(405, 'no method'),
(406, 'unacceptable'),
(409, 'ooops, conflict'),
(415, 'unsupported media type'),
(500, 'internal problems'),
)
headers = {
'Content-Type': 'application/json',
'ETag': '737060cd8c284d8af7ad3082f209582d',
}
# test response status code and message
for code, message in http_codes:
with self.assertRaises(web.HTTPError) as cm:
raise BaseHandler.http(
status_code=code,
msg=message,
headers=headers
)
self.assertTrue(web.ctx.status.startswith(str(code)))
self.assertTrue(cm.exception.data, message)
for header, value in headers.items():
self.assertIn((header, value), web.ctx.headers)
def test_content_decorator(self):
class FakeHandler(BaseHandler):
@serialize
def GET(self):
return {}
@serialize
def POST(self):
return {}
web.ctx.headers = []
web.ctx.env = {"HTTP_ACCEPT": "text/html"}
fake_handler = FakeHandler()
self.assertRaises(
web.webapi.UnsupportedMediaType,
fake_handler.GET
)
web.ctx.env = {"HTTP_ACCEPT": "*/*"}
web.ctx.headers = []
fake_handler.GET()
self.assertIn(
('Content-Type', 'application/json'),
web.ctx.headers
)
web.ctx.headers = []
web.ctx.env = {"HTTP_ACCEPT": "application/json"}
fake_handler.POST()
self.assertIn(
# we don't have plain/text serializer right now
('Content-Type', 'application/json'),
web.ctx.headers
)
def test_invalid_handler_output(self):
class FakeHandler(object):
@handle_errors
@serialize
def GET(self):
return {set([1, 2, 3])}
fake_handler = FakeHandler()
web.ctx.env = {"HTTP_ACCEPT": "*/*"}
web.ctx.headers = []
self.assertRaises(web.HTTPError, fake_handler.GET)
def test_get_param_as_set(self):
urls = ("/hello", "hello")
class hello(object):
def GET(self_inner):
web.header('Content-Type', 'application/json')
data = BaseHandler.get_param_as_set('test_param',
delimiter=';')
return json.dumps(list(data))
app = web.application(urls, {'hello': hello})
url = '/hello?test_param=' + urllib.quote('1;4 ; 777; 4;x ')
resp = app.request(url)
self.assertEqual(set(json.loads(resp.data)),
set(['1', '4', '777', 'x']))
def check_get_requested_mime(self, headers, expected_mime):
urls = ("/hello", "hello")
class hello(object):
def GET(self_inner):
web.header('Content-Type', 'text/plain')
return BaseHandler.get_requested_mime()
app = web.application(urls, {'hello': hello})
resp = app.request('/hello', headers=headers)
self.assertEqual(resp.data, expected_mime)
def test_get_requested_mime1(self):
self.check_get_requested_mime({'ACCEPT': 'text/html'}, 'text/html')
def test_get_requested_mime2(self):
self.check_get_requested_mime(
{'ACCEPT': 'text/plain;q=0.7, text/html;level=1,'}, 'text/plain')
def test_get_requested_default(self):
self.check_get_requested_mime({}, 'application/json')