File: test_http_custom_method_routing.py

package info (click to toggle)
python-falcon 4.0.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,172 kB
  • sloc: python: 33,608; javascript: 92; sh: 50; makefile: 50
file content (128 lines) | stat: -rw-r--r-- 3,514 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import importlib
import os
import wsgiref.validate

import pytest

import falcon
from falcon import testing
import falcon.constants
from falcon.routing import util

FALCON_CUSTOM_HTTP_METHODS = ['FOO', 'BAR']


@pytest.fixture
def resource_things():
    return ThingsResource()


@pytest.fixture
def cleanup_constants():
    # Forcing reload to make sure we used a module import and didn't import
    # the list directly.
    importlib.reload(falcon.constants)
    orig = list(falcon.constants.COMBINED_METHODS)
    yield
    falcon.constants.COMBINED_METHODS = orig

    if 'FALCON_CUSTOM_HTTP_METHODS' in os.environ:
        del os.environ['FALCON_CUSTOM_HTTP_METHODS']


@pytest.fixture
def custom_http_client(asgi, util, request, cleanup_constants, resource_things):
    falcon.constants.COMBINED_METHODS += FALCON_CUSTOM_HTTP_METHODS

    app = util.create_app(asgi)
    app.add_route('/things', resource_things)
    return testing.TestClient(app)


class ThingsResource:
    def __init__(self):
        self.called = False

        # Test non-callable attribute
        self.on_patch = {}

    # Field names ordered differently than in uri template
    def on_foo(self, req, resp):
        self.called = True
        self.req, self.resp = req, resp
        resp.status = falcon.HTTP_204


def test_map_http_methods(custom_http_client, resource_things):
    method_map = util.map_http_methods(resource_things)

    assert 'FOO' in method_map
    assert 'BAR' not in method_map


@pytest.mark.parametrize(
    'env_str,expected',
    [
        ('foo', ['FOO']),
        ('FOO', ['FOO']),
        ('FOO,', ['FOO']),
        ('FOO,BAR', ['FOO', 'BAR']),
        ('FOO, BAR', ['FOO', 'BAR']),
        (' foo , BAR ', ['FOO', 'BAR']),
    ],
)
def test_environment_override(
    util, cleanup_constants, resource_things, env_str, expected
):
    if util.HAS_CYTHON:
        pytest.skip(reason='Reloading modules on Cython does not work')

    # Make sure we don't have anything in there
    for method in expected:
        assert method not in falcon.constants.COMBINED_METHODS

    os.environ['FALCON_CUSTOM_HTTP_METHODS'] = env_str

    # Reload module to pick up environment variable methods
    importlib.reload(falcon.constants)

    # Now it should be there
    for method in expected:
        assert method in falcon.constants.COMBINED_METHODS


def test_foo(custom_http_client, resource_things):
    """FOO is a supported method, so returns HTTP_204"""
    custom_http_client.app.add_route('/things', resource_things)

    def s():
        return custom_http_client.simulate_request(path='/things', method='FOO')

    if not custom_http_client.app._ASGI:
        with pytest.warns(wsgiref.validate.WSGIWarning):
            response = s()
    else:
        response = s()

    assert 'FOO' in falcon.constants.COMBINED_METHODS
    assert response.status == falcon.HTTP_204
    assert response.status_code == 204
    assert resource_things.called


def test_bar(custom_http_client, resource_things):
    """BAR is not supported by ResourceThing"""
    custom_http_client.app.add_route('/things', resource_things)

    def s():
        return custom_http_client.simulate_request(path='/things', method='BAR')

    if not custom_http_client.app._ASGI:
        with pytest.warns(wsgiref.validate.WSGIWarning):
            response = s()
    else:
        response = s()

    assert 'BAR' in falcon.constants.COMBINED_METHODS
    assert response.status == falcon.HTTP_405
    assert response.status_code == 405