def test_rules_match_hit(rules): req = Request(environ={ 'REQUEST_METHOD': 'PATCH', 'REMOTE_ADDR': '1.2.3.4', }) rules = Rules(rules) assert str(rules.match(req)) == 'http://me,1' rules.compile = True assert str(rules.match(req)) == 'http://me,1' rules.compile = False assert str(rules.match(req)) == 'http://me,1'
def test_rules_match_miss(rules): req = Request(environ={ 'REQUEST_METHOD': 'PATCH', 'REMOTE_ADDR': '11.22.33.44', }) rules = Rules(rules) assert rules.match(req) is None rules.compile = True assert rules.match(req) is None rules.compile = False assert rules.match(req) is None
def test_invalid_basic_authorization(): environ = { 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/abc/123', 'QUERY_STRING': 'a=b&c=d', 'HTTP_AUTHORIZATION': '@!#!@#!#$', } req = Request(environ) assert req.authenticated assert req.basic_authorization is None assert req.username is None assert req.password is None
def test_rules_match_error_disable(rules): req = Request(environ={ 'REQUEST_METHOD': 'PATCH', 'REMOTE_ADDR': '1.2.3.4', }) rs = Rules(rules, compile=False) with mock.patch('rump.Rule.match') as patch: patch.side_effect = Exception('boom') rs.match(req, error='disable') assert all(rule in rs.disabled for rule in rs) rs = Rules(rules, compile=True) with mock.patch('rump.rule.CompiledRule.match_context') as patch: patch.side_effect = Exception('boom') rs.match(req, error='disable') assert all(rule in rs.disabled for rule in rs)
def test_basic_authorization(): username, password = '******', 'there' value = 'Basic {0}'.format( base64.encodestring('{0}:{1}'.format(username, password))) environ = { 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/abc/123', 'QUERY_STRING': 'a=b&c=d', 'HTTP_AUTHORIZATION': value, } req = Request(environ) assert req.authenticated assert req.basic_authorization == { 'username': username, 'password': password } assert req.username == username assert req.password == password
def test_headers(): environ = { 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/abc/123', 'QUERY_STRING': 'a=b&c=d', 'HTTP_X_1': '1', 'HTTP_X_2': '22', 'HTTP_X_3': '333', 'HTTP_X_4': '4444', } req = Request(environ) assert req.headers == { 'http_x_1': '1', 'http_x_2': '22', 'http_x_3': '333', 'http_x_4': '4444', } assert not req.has_content
def test_rules_match_error_propagate(rules): req = Request(environ={ 'REQUEST_METHOD': 'PATCH', 'REMOTE_ADDR': '1.2.3.4', }) rs = Rules(rules, compile=False) with mock.patch('rump.Rule.match') as patch: patch.side_effect = Exception('boom') with pytest.raises(Exception): rs.match(req, error='raise') assert all(rule not in rs.disabled for rule in rs) rs = Rules(rules, compile=True) with mock.patch('rump.Rule.compiled_type.match') as patch: patch.side_effect = Exception('boom') rs.match(req, error='disable') assert all(rule not in rs.disabled for rule in rs)
def test_request_ctx(): content = json.dumps({'hi': 'there'}) environ = { 'REQUEST_METHOD': 'POST', 'PATH_INFO': '/abc/123', 'QUERY_STRING': 'a=b&c=d', 'CONTENT_TYPE': 'application/json', 'CONTENT_LENGTH': str(len(content)), 'REMOTE_ADDR': '1.2.3.4', 'wsgi.input': StringIO.StringIO(content), } ctx = Request(environ).context(exp.Symbols()) assert ctx['request'][Request.method] == 'POST' assert ctx['request'][Request.path] == '/abc/123' assert ctx['request'][Request.query_string] == 'a=b&c=d' assert ctx['request'][Request.query] == {'a': 'b', 'c': 'd'} assert ctx['request'][Request.has_content] assert ctx['request'][Request.content_length] == len(content) assert ctx['request'][Request.content] == content assert not ctx['request'][Request.authenticated] assert ctx['request'][Request.client_ip4] == types.IPAddress('1.2.3.4')
def test_map(): content = json.dumps({'hi': 'there'}) environ = { 'REQUEST_METHOD': 'POST', 'PATH_INFO': '/abc/123', 'QUERY_STRING': 'a=b&c=d', 'CONTENT_TYPE': 'application/json', 'CONTENT_LENGTH': str(len(content)), 'REMOTE_ADDR': '1.2.3.4', 'wsgi.input': StringIO.StringIO(content), } req = Request(environ) assert req.method == 'POST' assert req.path == '/abc/123' assert req.query_string == 'a=b&c=d' assert req.query == {'a': 'b', 'c': 'd'} assert req.has_content assert req.content_length == len(content) assert req.content == content assert not req.authenticated assert req.client_ip4 == types.IPAddress('1.2.3.4')
def test_rule_match(parse_rule): content = json.dumps({'hi': 'there'}) req = Request( environ={ 'METHOD': 'PATCH', 'REMOTE_ADDR': '1.2.3.4', 'PATH_INFO': '/a/b/c/123', 'HTTP_X_1': '5', 'CONTENT_TYPE': 'application/json', 'CONTENT_LENGTH': str(len(content)), 'wsgi.input': StringIO.StringIO(content), }) cases = [ ('client_ip4 in 1.2.3.4/32 => prod', True), ('headers.x_1 in [1, 2, 4] => prod', False), ('headers.x_1 !in [1, 2, 4] => prod', True), ('headers.x_2 = 3 => prod', False), ('content_length >= 10 => prod', True), ('content_length > 10 => prod', True), ('content_length < 10 => prod', False), ('content_length <= 10 => prod', False), ('content_length = 15 => prod', True), ('content_length != 15 => prod', False), ('has_content => prod', True), ('!has_content => prod', False), ('"a/b" in path => prod', True), ('"b/a" in path => prod', False), ('"b/a" !in path => prod', True), ('path startswith "/a/b/c" => prod', True), ('path endswith 123 => prod', True), ('"/b/" in path => prod', True), ('"/veep/" in path => prod', False), ('path ~ "/(\w/){3}123" => prod', True), ('path !~ "/(\w/){3}123" => prod', False), ] for case, expected in cases: r = parse_rule(case) assert r.expression(req) == expected