views.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. # -*- coding: utf-8 -*-
  2. """
  3. flask.testsuite.views
  4. ~~~~~~~~~~~~~~~~~~~~~
  5. Pluggable views.
  6. :copyright: (c) 2011 by Armin Ronacher.
  7. :license: BSD, see LICENSE for more details.
  8. """
  9. import flask
  10. import flask.views
  11. import unittest
  12. from flask.testsuite import FlaskTestCase
  13. from werkzeug.http import parse_set_header
  14. class ViewTestCase(FlaskTestCase):
  15. def common_test(self, app):
  16. c = app.test_client()
  17. self.assert_equal(c.get('/').data, b'GET')
  18. self.assert_equal(c.post('/').data, b'POST')
  19. self.assert_equal(c.put('/').status_code, 405)
  20. meths = parse_set_header(c.open('/', method='OPTIONS').headers['Allow'])
  21. self.assert_equal(sorted(meths), ['GET', 'HEAD', 'OPTIONS', 'POST'])
  22. def test_basic_view(self):
  23. app = flask.Flask(__name__)
  24. class Index(flask.views.View):
  25. methods = ['GET', 'POST']
  26. def dispatch_request(self):
  27. return flask.request.method
  28. app.add_url_rule('/', view_func=Index.as_view('index'))
  29. self.common_test(app)
  30. def test_method_based_view(self):
  31. app = flask.Flask(__name__)
  32. class Index(flask.views.MethodView):
  33. def get(self):
  34. return 'GET'
  35. def post(self):
  36. return 'POST'
  37. app.add_url_rule('/', view_func=Index.as_view('index'))
  38. self.common_test(app)
  39. def test_view_patching(self):
  40. app = flask.Flask(__name__)
  41. class Index(flask.views.MethodView):
  42. def get(self):
  43. 1 // 0
  44. def post(self):
  45. 1 // 0
  46. class Other(Index):
  47. def get(self):
  48. return 'GET'
  49. def post(self):
  50. return 'POST'
  51. view = Index.as_view('index')
  52. view.view_class = Other
  53. app.add_url_rule('/', view_func=view)
  54. self.common_test(app)
  55. def test_view_inheritance(self):
  56. app = flask.Flask(__name__)
  57. class Index(flask.views.MethodView):
  58. def get(self):
  59. return 'GET'
  60. def post(self):
  61. return 'POST'
  62. class BetterIndex(Index):
  63. def delete(self):
  64. return 'DELETE'
  65. app.add_url_rule('/', view_func=BetterIndex.as_view('index'))
  66. c = app.test_client()
  67. meths = parse_set_header(c.open('/', method='OPTIONS').headers['Allow'])
  68. self.assert_equal(sorted(meths), ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST'])
  69. def test_view_decorators(self):
  70. app = flask.Flask(__name__)
  71. def add_x_parachute(f):
  72. def new_function(*args, **kwargs):
  73. resp = flask.make_response(f(*args, **kwargs))
  74. resp.headers['X-Parachute'] = 'awesome'
  75. return resp
  76. return new_function
  77. class Index(flask.views.View):
  78. decorators = [add_x_parachute]
  79. def dispatch_request(self):
  80. return 'Awesome'
  81. app.add_url_rule('/', view_func=Index.as_view('index'))
  82. c = app.test_client()
  83. rv = c.get('/')
  84. self.assert_equal(rv.headers['X-Parachute'], 'awesome')
  85. self.assert_equal(rv.data, b'Awesome')
  86. def test_implicit_head(self):
  87. app = flask.Flask(__name__)
  88. class Index(flask.views.MethodView):
  89. def get(self):
  90. return flask.Response('Blub', headers={
  91. 'X-Method': flask.request.method
  92. })
  93. app.add_url_rule('/', view_func=Index.as_view('index'))
  94. c = app.test_client()
  95. rv = c.get('/')
  96. self.assert_equal(rv.data, b'Blub')
  97. self.assert_equal(rv.headers['X-Method'], 'GET')
  98. rv = c.head('/')
  99. self.assert_equal(rv.data, b'')
  100. self.assert_equal(rv.headers['X-Method'], 'HEAD')
  101. def test_explicit_head(self):
  102. app = flask.Flask(__name__)
  103. class Index(flask.views.MethodView):
  104. def get(self):
  105. return 'GET'
  106. def head(self):
  107. return flask.Response('', headers={'X-Method': 'HEAD'})
  108. app.add_url_rule('/', view_func=Index.as_view('index'))
  109. c = app.test_client()
  110. rv = c.get('/')
  111. self.assert_equal(rv.data, b'GET')
  112. rv = c.head('/')
  113. self.assert_equal(rv.data, b'')
  114. self.assert_equal(rv.headers['X-Method'], 'HEAD')
  115. def test_endpoint_override(self):
  116. app = flask.Flask(__name__)
  117. app.debug = True
  118. class Index(flask.views.View):
  119. methods = ['GET', 'POST']
  120. def dispatch_request(self):
  121. return flask.request.method
  122. app.add_url_rule('/', view_func=Index.as_view('index'))
  123. with self.assert_raises(AssertionError):
  124. app.add_url_rule('/', view_func=Index.as_view('index'))
  125. # But these tests should still pass. We just log a warning.
  126. self.common_test(app)
  127. def suite():
  128. suite = unittest.TestSuite()
  129. suite.addTest(unittest.makeSuite(ViewTestCase))
  130. return suite