Newer
Older
import unittest
import pytest
import mwclient
from mwclient.listing import List, NestedList, GeneratorList
if __name__ == "__main__":
print()
print("Note: Running in stand-alone mode. Consult the README")
print(" (section 'Contributing') for advice on running tests.")
print()
class TestList(unittest.TestCase):
def setUp(self):
pass
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
def setupDummyResponsesOne(self, mock_site, result_member, ns=None):
if ns is None:
ns = [0, 0, 0]
mock_site.get.side_effect = [
{
'continue': {
'apcontinue': 'Kre_Mbaye',
'continue': '-||'
},
'query': {
result_member: [
{
"pageid": 19839654,
"ns": ns[0],
"title": "Kre'fey",
},
]
}
},
{
'continue': {
'apcontinue': 'Kre_Blip',
'continue': '-||'
},
'query': {
result_member: [
{
"pageid": 19839654,
"ns": ns[1],
"title": "Kre-O",
}
]
}
},
{
'query': {
result_member: [
{
"pageid": 30955295,
"ns": ns[2],
"title": "Kre-O Transformers",
}
]
}
},
]
def setupDummyResponsesTwo(self, mock_site, result_member, ns=None):
if ns is None:
ns = [0, 0, 0]
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
{
'continue': {
'apcontinue': 'Kre_Mbaye',
'continue': '-||'
},
'query': {
result_member: [
{
"pageid": 19839654,
"ns": ns[0],
"title": "Kre'fey",
},
{
"pageid": 19839654,
"ns": ns[1],
"title": "Kre-O",
}
]
}
},
{
'query': {
result_member: [
{
"pageid": 30955295,
"ns": ns[2],
"title": "Kre-O Transformers",
}
]
}
},
]
@mock.patch('mwclient.client.Site')
def test_list_continuation(self, mock_site):
# Test that the list fetches all three responses
# and yields dicts when return_values not set
lst = List(mock_site, 'allpages', 'ap', api_chunk_size=2)
self.setupDummyResponsesTwo(mock_site, 'allpages')
vals = [x for x in lst]
assert len(vals) == 3
assert type(vals[0]) == dict
assert lst.args["aplimit"] == "2"
assert mock_site.get.call_count == 2
@mock.patch('mwclient.client.Site')
def test_list_limit_deprecated(self, mock_site):
# Test that the limit arg acts as api_chunk_size but generates
# DeprecationWarning
with pytest.deprecated_call():
lst = List(mock_site, 'allpages', 'ap', limit=2)
self.setupDummyResponsesTwo(mock_site, 'allpages')
vals = [x for x in lst]
assert len(vals) == 3
assert type(vals[0]) == dict
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
assert lst.args["aplimit"] == "2"
assert mock_site.get.call_count == 2
@mock.patch('mwclient.client.Site')
def test_list_max_items(self, mock_site):
# Test that max_items properly caps the list
# iterations
mock_site.api_limit = 500
lst = List(mock_site, 'allpages', 'ap', max_items=2)
self.setupDummyResponsesTwo(mock_site, 'allpages')
vals = [x for x in lst]
assert len(vals) == 2
assert type(vals[0]) == dict
assert lst.args["aplimit"] == "2"
assert mock_site.get.call_count == 1
@mock.patch('mwclient.client.Site')
def test_list_max_items_continuation(self, mock_site):
# Test that max_items and api_chunk_size work together
mock_site.api_limit = 500
lst = List(mock_site, 'allpages', 'ap', max_items=2, api_chunk_size=1)
self.setupDummyResponsesOne(mock_site, 'allpages')
vals = [x for x in lst]
assert len(vals) == 2
assert type(vals[0]) == dict
assert lst.args["aplimit"] == "1"
assert mock_site.get.call_count == 2
@mock.patch('mwclient.client.Site')
def test_list_with_str_return_value(self, mock_site):
# Test that the List yields strings when return_values is string
lst = List(mock_site, 'allpages', 'ap', limit=2, return_values='title')
self.setupDummyResponsesTwo(mock_site, 'allpages')
vals = [x for x in lst]
assert len(vals) == 3
assert type(vals[0]) == str
@mock.patch('mwclient.client.Site')
def test_list_with_tuple_return_value(self, mock_site):
# Test that the List yields tuples when return_values is tuple
lst = List(mock_site, 'allpages', 'ap', limit=2,
return_values=('title', 'ns'))
self.setupDummyResponsesTwo(mock_site, 'allpages')
vals = [x for x in lst]
assert len(vals) == 3
assert type(vals[0]) == tuple
@mock.patch('mwclient.client.Site')
def test_list_empty(self, mock_site):
# Test that we handle an empty response from get correctly
# (stop iterating)
lst = List(mock_site, 'allpages', 'ap', limit=2,
return_values=('title', 'ns'))
mock_site.get.side_effect = [{}]
vals = [x for x in lst]
assert len(vals) == 0
@mock.patch('mwclient.client.Site')
def test_list_invalid(self, mock_site):
# Test that we handle the response for a list that doesn't
# exist correctly (set an empty iterator, then stop
# iterating)
mock_site.api_limit = 500
lst = List(mock_site, 'allpagess', 'ap')
mock_site.get.side_effect = [
{
'batchcomplete': '',
'warnings': {
'main': {'*': 'Unrecognized parameter: aplimit.'},
'query': {'*': 'Unrecognized value for parameter "list": allpagess'}
},
'query': {
'userinfo': {
'id': 0,
'name': 'DEAD:BEEF:CAFE',
'anon': ''
}
}
}
]
vals = [x for x in lst]
assert len(vals) == 0
@mock.patch('mwclient.client.Site')
def test_list_repr(self, mock_site):
# Test __repr__ of a List is as expected
mock_site.__str__.return_value = "some wiki"
lst = List(mock_site, 'allpages', 'ap', limit=2,
return_values=('title', 'ns'))
assert repr(lst) == "<List object 'allpages' for some wiki>"
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
@mock.patch('mwclient.client.Site')
def test_get_list(self, mock_site):
# Test get_list behaves as expected
lst = List.get_list()(mock_site, 'allpages', 'ap', limit=2,
return_values=('title', 'ns'))
genlst = List.get_list(True)(mock_site, 'allpages', 'ap', limit=2,
return_values=('title', 'ns'))
assert isinstance(lst, List)
assert not isinstance(lst, GeneratorList)
assert isinstance(genlst, GeneratorList)
@mock.patch('mwclient.client.Site')
def test_nested_list(self, mock_site):
# Test NestedList class works as expected
mock_site.api_limit = 500
nested = NestedList('entries', mock_site, 'checkuserlog', 'cul')
mock_site.get.side_effect = [
# this is made-up because I do not have permissions on any
# wiki with this extension installed and the extension doc
# does not show a sample API response
{
'query': {
'checkuserlog': {
'entries': [
{
'user': 'Dreamyjazz',
'action': 'users',
'ip': '172.18.0.1',
'message': 'suspected sockpuppet',
'time': 1662328680
},
{
'user': 'Dreamyjazz',
'action': 'ip',
'targetuser': 'JohnDoe124',
'message': 'suspected sockpuppet',
'time': 1662328380
},
]
}
}
}
]
vals = [x for x in nested]
assert len(vals) == 2
assert vals[0]['action'] == 'users'
assert vals[1]['action'] == 'ip'
@mock.patch('mwclient.client.Site')
def test_generator_list(self, mock_site):
# Test that the GeneratorList yields Page objects
mock_site.api_limit = 500
lst = GeneratorList(mock_site, 'pages', 'p')
self.setupDummyResponsesTwo(mock_site, 'pages', ns=[0, 6, 14])
vals = [x for x in lst]
assert len(vals) == 3
assert type(vals[0]) == mwclient.page.Page
assert type(vals[1]) == mwclient.image.Image
assert type(vals[2]) == mwclient.listing.Category
if __name__ == '__main__':
unittest.main()