tests.http.test_receive_server.build_request()   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
nop 4
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
"""
2
:Copyright: 2007-2025 Jochen Kupperschmidt
3
:License: MIT, see LICENSE for details.
4
"""
5
6
import json
7
from urllib.error import HTTPError
8
from urllib.request import Request, urlopen
9
10
import pytest
11
12
13
@pytest.fixture
14
def server(make_server):
15
    return make_server()
16
17
18
@pytest.fixture
19
def restricted_server(make_server):
20
    api_tokens = {
21
        'gAT3KHqpb94YQ7IMhR-qMH5tRquwLnHoyik_lZItTQY',
22
        'qeV4Jf_PYxAySktCODORTKSH1gs117qJXwoqg5YoDBU',
23
    }
24
    return make_server(api_tokens=api_tokens)
25
26
27
# unrestricted access
28
29
30
def test_receive_server_with_valid_request(server):
31
    data = {
32
        'channel': '#party',
33
        'text': 'Limbo!',
34
    }
35
    request = build_request(server, data)
36
37
    response = urlopen(request)
38
39
    assert response.code == 202
40
41
42
def test_receive_server_without_channel(server):
43
    data = {
44
        'text': 'Which channel is this?!',
45
    }
46
    request = build_request(server, data)
47
48
    with pytest.raises(HTTPError) as excinfo:
49
        urlopen(request)
50
51
    assert excinfo.value.code == 400
52
53
54
def test_receive_server_without_text(server):
55
    data = {
56
        'channel': '#silence',
57
    }
58
    request = build_request(server, data)
59
60
    with pytest.raises(HTTPError) as excinfo:
61
        urlopen(request)
62
63
    assert excinfo.value.code == 400
64
65
66
# restricted access
67
68
69
def test_restricted_access_without_api_token(restricted_server):
70
    data = {
71
        'channel': '#internal',
72
        'text': 'I lost my wallet.',
73
    }
74
    request = build_request(restricted_server, data, api_token=None)
75
76
    with pytest.raises(HTTPError) as excinfo:
77
        urlopen(request)
78
79
    assert excinfo.value.code == 401
80
81
82
def test_restricted_access_with_invalid_api_token(restricted_server):
83
    data = {
84
        'channel': '#internal',
85
        'text': 'I can has access?!',
86
    }
87
    request = build_request(
88
        restricted_server,
89
        data,
90
        api_token='dwNlg-iDnDwx9lPr_DGaZzn2hjHx7_AK2UwUfqsrKr0',
91
    )
92
93
    with pytest.raises(HTTPError) as excinfo:
94
        urlopen(request)
95
96
    assert excinfo.value.code == 403
97
98
99
def test_restricted_access_with_valid_api_token(restricted_server):
100
    data = {
101
        'channel': '#internal',
102
        'text': 'Welcome to the club!',
103
    }
104
    request = build_request(
105
        restricted_server,
106
        data,
107
        api_token='qeV4Jf_PYxAySktCODORTKSH1gs117qJXwoqg5YoDBU',
108
    )
109
110
    response = urlopen(request)
111
112
    assert response.code == 202
113
114
115
# unknown URL path
116
117
118
def test_unsupported_url_path(server):
119
    url = get_server_url(server) + 'foo'
120
    request = Request(url, method='POST')
121
122
    with pytest.raises(HTTPError) as excinfo:
123
        urlopen(request)
124
125
    assert excinfo.value.code == 404
126
127
128
# response headers
129
130
131
def test_server_response_header(server):
132
    data = {
133
        'channel': '#curiosity',
134
        'text': 'Show me your web server version!',
135
    }
136
    request = build_request(server, data)
137
138
    response = urlopen(request)
139
140
    assert response.headers['Server'] == 'Weitersager'
141
142
143
# helpers
144
145
146
def build_request(server, data, *, api_token=None):
147
    url = get_server_url(server)
148
149
    data = json.dumps(data).encode('utf-8')
150
151
    headers = {'Content-Type': 'application/json'}
152
    if api_token:
153
        headers['Authorization'] = f'Bearer {api_token}'
154
155
    return Request(url, data=data, headers=headers, method='POST')
156
157
158
def get_server_url(server):
159
    server_host, server_port = server.server_address
160
    return f'http://{server_host}:{server_port}/'
161