Completed
Push — master ( 7e3034...798a9f )
by Ali-Akber
27s
created

RegressionTests.test_invalid_ratelimit_key()   B

Complexity

Conditions 5

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 5
c 2
b 0
f 0
dl 0
loc 21
rs 8.439
1
"""
2
3
"""
4
import time
5
import logging
6
import unittest
7
8
from flask import Flask
9
import hiro
10
import mock
11
import redis
12
13
from flask_limiter.extension import C, Limiter
14
from flask_limiter.util import get_ipaddr
15
16
17
class RegressionTests(unittest.TestCase):
18
    def setUp(self):
19
        redis.Redis().flushall()
20
21
    def build_app(self, config={}, **limiter_args):
22
        app = Flask(__name__)
23
        for k, v in config.items():
24
            app.config.setdefault(k, v)
25
        limiter = Limiter(app, key_func=get_ipaddr, **limiter_args)
26
        mock_handler = mock.Mock()
27
        mock_handler.level = logging.INFO
28
        limiter.logger.addHandler(mock_handler)
29
        return app, limiter
30
31
    def test_redis_request_slower_than_fixed_window(self):
32
        app, limiter = self.build_app({
33
            C.GLOBAL_LIMITS: "5 per second",
34
            C.STORAGE_URL: "redis://localhost:6379",
35
            C.STRATEGY: "fixed-window",
36
            C.HEADERS_ENABLED: True
37
        })
38
39
        @app.route("/t1")
40
        def t1():
41
            time.sleep(1.1)
42
            return "t1"
43
44
        with app.test_client() as cli:
45
            resp = cli.get("/t1")
46
            self.assertEqual(
47
                    resp.headers["X-RateLimit-Remaining"],
48
                    '5'
49
            )
50
51
    def test_redis_request_slower_than_moving_window(self):
52
        app, limiter = self.build_app({
53
            C.GLOBAL_LIMITS: "5 per second",
54
            C.STORAGE_URL: "redis://localhost:6379",
55
            C.STRATEGY: "moving-window",
56
            C.HEADERS_ENABLED: True
57
        })
58
59
        @app.route("/t1")
60
        def t1():
61
            time.sleep(1.1)
62
            return "t1"
63
64
        with app.test_client() as cli:
65
            resp = cli.get("/t1")
66
            self.assertEqual(
67
                    resp.headers["X-RateLimit-Remaining"],
68
                    '5'
69
            )
70
71
    def test_dynamic_limits(self):
72 View Code Duplication
        app, limiter = self.build_app({
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
73
            C.STRATEGY: "moving-window",
74
            C.HEADERS_ENABLED: True
75
        })
76
77
        def func(*a):
78
            return "1/second; 2/minute"
79
80
        @app.route("/t1")
81
        @limiter.limit(func)
82
        def t1():
83
            return "t1"
84
85
        with hiro.Timeline().freeze() as timeline:
86
            with app.test_client() as cli:
87
                self.assertEqual(cli.get("/t1").status_code, 200)
88
                self.assertEqual(cli.get("/t1").status_code, 429)
89
                timeline.forward(2)
90
                self.assertEqual(cli.get("/t1").status_code, 200)
91
                self.assertEqual(cli.get("/t1").status_code, 429)
92
93
    def test_invalid_ratelimit_key(self):
94
        app, limiter = self.build_app(
95
            {C.HEADERS_ENABLED: True}
96
        )
97
98
        def func(*a):
99
            return None
100
101
        @app.route("/t1")
102
        @limiter.limit("2/second", key_func=func)
103
        def t1():
104
            return "t1"
105
106
        with app.test_client() as cli:
107
            cli.get("/t1")
108
            cli.get("/t1")
109
            cli.get("/t1")
110
            self.assertEqual(cli.get("/t1").status_code, 200)
111
            limiter.limit("1/second", key_func=lambda: "key")(t1)
112
            cli.get("/t1")
113
            self.assertEqual(cli.get("/t1").status_code, 429)
114