1
|
# SPDX-License-Identifier: CC0-1.0
|
2
|
|
3
|
"""
|
4
|
Haketilo unit tests - .............
|
5
|
"""
|
6
|
|
7
|
# This file is part of Haketilo
|
8
|
#
|
9
|
# Copyright (C) 2022 Wojtek Kosior <koszko@koszko.org>
|
10
|
#
|
11
|
# This program is free software: you can redistribute it and/or modify
|
12
|
# it under the terms of the CC0 1.0 Universal License as published by
|
13
|
# the Creative Commons Corporation.
|
14
|
#
|
15
|
# This program is distributed in the hope that it will be useful,
|
16
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
17
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
18
|
# CC0 1.0 Universal License for more details.
|
19
|
|
20
|
import pytest
|
21
|
import json
|
22
|
from selenium.webdriver.support.ui import WebDriverWait
|
23
|
|
24
|
from ..extension_crafting import ExtraHTML
|
25
|
from ..script_loader import load_script
|
26
|
|
27
|
from ..extension_crafting import ExtraHTML
|
28
|
from ..script_loader import load_script
|
29
|
from .utils import *
|
30
|
|
31
|
repo_urls = [f'https://hydril.la/{s}' for s in ('', '1/', '2/', '3/', '4/')]
|
32
|
|
33
|
queried_url = 'https://example_a.com/something'
|
34
|
|
35
|
def setup_view(execute_in_page, repo_urls):
|
36
|
mock_cacher(execute_in_page)
|
37
|
|
38
|
execute_in_page(load_script('html/repo_query.js'))
|
39
|
execute_in_page(
|
40
|
'''
|
41
|
const repo_proms = arguments[0].map(url => haketilodb.set_repo(url));
|
42
|
|
43
|
const cb_calls = [];
|
44
|
const view = new RepoQueryView(0,
|
45
|
() => cb_calls.push("show"),
|
46
|
() => cb_calls.push("hide"));
|
47
|
document.body.append(view.main_div);
|
48
|
const shw = slice => [cb_calls.slice(slice || 0), view.shown];
|
49
|
|
50
|
returnval(Promise.all(repo_proms));
|
51
|
''',
|
52
|
repo_urls)
|
53
|
|
54
|
repo_query_ext_data = {
|
55
|
'background_script': broker_js,
|
56
|
'extra_html': ExtraHTML('html/repo_query.html', {}),
|
57
|
'navigate_to': 'html/repo_query.html'
|
58
|
}
|
59
|
|
60
|
@pytest.mark.ext_data(repo_query_ext_data)
|
61
|
@pytest.mark.usefixtures('webextension')
|
62
|
def test_repo_query_normal_usage(driver, execute_in_page):
|
63
|
"""
|
64
|
Test of using the repo query view to browse results from repository and to
|
65
|
start installation.
|
66
|
"""
|
67
|
setup_view(execute_in_page, repo_urls)
|
68
|
|
69
|
assert execute_in_page('returnval(shw());') == [[], False]
|
70
|
|
71
|
execute_in_page('view.show(arguments[0]);', queried_url)
|
72
|
|
73
|
assert execute_in_page('returnval(shw());') == [['show'], True]
|
74
|
|
75
|
def get_repo_entries(driver):
|
76
|
return execute_in_page(
|
77
|
f'returnval((view.repo_entries || []).map({nodes_props_code}));'
|
78
|
)
|
79
|
|
80
|
repo_entries = WebDriverWait(driver, 10).until(get_repo_entries)
|
81
|
|
82
|
assert len(repo_urls) == len(repo_entries)
|
83
|
|
84
|
for url, entry in reversed(list(zip(repo_urls, repo_entries))):
|
85
|
assert url in entry['main_li'].text
|
86
|
|
87
|
but_ids = ('show_results_but', 'hide_results_but')
|
88
|
for but_idx in (0, 1, 0):
|
89
|
assert bool(but_idx) == entry['list_container'].is_displayed()
|
90
|
|
91
|
assert not entry[but_ids[1 - but_idx]].is_displayed()
|
92
|
|
93
|
entry[but_ids[but_idx]].click()
|
94
|
|
95
|
def get_mapping_entries(driver):
|
96
|
return execute_in_page(
|
97
|
f'''{{
|
98
|
const result_entries = (view.repo_entries[0].result_entries || []);
|
99
|
returnval(result_entries.map({nodes_props_code}));
|
100
|
}}''')
|
101
|
|
102
|
mapping_entries = WebDriverWait(driver, 10).until(get_mapping_entries)
|
103
|
|
104
|
assert len(mapping_entries) == 3
|
105
|
|
106
|
expected_names = ['MAPPING_ABCD', 'MAPPING_ABCD-DEFG-GHIJ', 'MAPPING_A']
|
107
|
|
108
|
for name, entry in zip(expected_names, mapping_entries):
|
109
|
assert entry['mapping_name'].text == name
|
110
|
assert entry['mapping_id'].text == f'{name.lower()}-2022.5.11'
|
111
|
|
112
|
containers = execute_in_page(
|
113
|
'''{
|
114
|
const reductor = (acc, k) => Object.assign(acc, {[k]: view[k]});
|
115
|
returnval(container_ids.reduce(reductor, {}));
|
116
|
}''')
|
117
|
|
118
|
for id, container in containers.items():
|
119
|
assert (id == 'repos_list_container') == container.is_displayed()
|
120
|
|
121
|
entry['install_but'].click()
|
122
|
|
123
|
for id, container in containers.items():
|
124
|
assert (id == 'install_view_container') == container.is_displayed()
|
125
|
|
126
|
execute_in_page('returnval(view.install_view.cancel_but);').click()
|
127
|
|
128
|
for id, container in containers.items():
|
129
|
assert (id == 'repos_list_container') == container.is_displayed()
|
130
|
|
131
|
assert execute_in_page('returnval(shw());') == [['show'], True]
|
132
|
execute_in_page('returnval(view.cancel_but);').click()
|
133
|
assert execute_in_page('returnval(shw());') == [['show', 'hide'], False]
|
134
|
|
135
|
@pytest.mark.ext_data(repo_query_ext_data)
|
136
|
@pytest.mark.usefixtures('webextension')
|
137
|
@pytest.mark.parametrize('message', [
|
138
|
'browsing_for',
|
139
|
'no_repos',
|
140
|
'failure_to_communicate',
|
141
|
'HTTP_code',
|
142
|
'invalid_JSON',
|
143
|
'newer_API_version',
|
144
|
'invalid_API_version',
|
145
|
'querying_repo',
|
146
|
'no_results'
|
147
|
])
|
148
|
def test_repo_query_messages(driver, execute_in_page, message):
|
149
|
"""
|
150
|
Test of loading and error messages shown in parts of the repo query view.
|
151
|
"""
|
152
|
def has_msg(message, elem=None):
|
153
|
def has_msg_and_is_visible(dummy_driver):
|
154
|
if elem:
|
155
|
return elem.is_displayed() and message in elem.text
|
156
|
else:
|
157
|
return message in driver.page_source
|
158
|
return has_msg_and_is_visible
|
159
|
|
160
|
def show_and_wait_for_repo_entry():
|
161
|
execute_in_page('view.show(arguments[0]);', queried_url)
|
162
|
done = lambda d: execute_in_page('returnval(!!view.repo_entries);')
|
163
|
WebDriverWait(driver, 10).until(done)
|
164
|
execute_in_page(
|
165
|
'''
|
166
|
if (view.repo_entries.length > 0)
|
167
|
view.repo_entries[0].show_results_but.click();
|
168
|
''')
|
169
|
|
170
|
if message == 'browsing_for':
|
171
|
setup_view(execute_in_page, [])
|
172
|
show_and_wait_for_repo_entry()
|
173
|
|
174
|
elem = execute_in_page('returnval(view.url_span.parentNode);')
|
175
|
assert has_msg(f'Browsing custom resources for {queried_url}.', elem)(0)
|
176
|
elif message == 'no_repos':
|
177
|
setup_view(execute_in_page, [])
|
178
|
show_and_wait_for_repo_entry()
|
179
|
|
180
|
elem = execute_in_page('returnval(view.repos_list);')
|
181
|
done = has_msg('You have no repositories configured :(', elem)
|
182
|
WebDriverWait(driver, 10).until(done)
|
183
|
elif message == 'failure_to_communicate':
|
184
|
setup_view(execute_in_page, repo_urls)
|
185
|
execute_in_page(
|
186
|
'browser.tabs.sendMessage = () => Promise.resolve({error: "sth"});'
|
187
|
)
|
188
|
show_and_wait_for_repo_entry()
|
189
|
|
190
|
elem = execute_in_page('returnval(view.repo_entries[0].info_span);')
|
191
|
done = has_msg('Failure to communicate with repository :(', elem)
|
192
|
WebDriverWait(driver, 10).until(done)
|
193
|
elif message == 'HTTP_code':
|
194
|
setup_view(execute_in_page, repo_urls)
|
195
|
execute_in_page(
|
196
|
'''
|
197
|
const response = {ok: false, status: 405};
|
198
|
browser.tabs.sendMessage = () => Promise.resolve(response);
|
199
|
''')
|
200
|
show_and_wait_for_repo_entry()
|
201
|
|
202
|
elem = execute_in_page('returnval(view.repo_entries[0].info_span);')
|
203
|
done = has_msg('Repository sent HTTP code 405 :(', elem)
|
204
|
WebDriverWait(driver, 10).until(done)
|
205
|
elif message == 'invalid_JSON':
|
206
|
setup_view(execute_in_page, repo_urls)
|
207
|
execute_in_page(
|
208
|
'''
|
209
|
const response = {ok: true, status: 200, error_json: "sth"};
|
210
|
browser.tabs.sendMessage = () => Promise.resolve(response);
|
211
|
''')
|
212
|
show_and_wait_for_repo_entry()
|
213
|
|
214
|
elem = execute_in_page('returnval(view.repo_entries[0].info_span);')
|
215
|
done = has_msg("Repository's response is not valid JSON :(", elem)
|
216
|
WebDriverWait(driver, 10).until(done)
|
217
|
elif message == 'newer_API_version':
|
218
|
setup_view(execute_in_page, repo_urls)
|
219
|
execute_in_page(
|
220
|
'''
|
221
|
const response = {
|
222
|
ok: true,
|
223
|
status: 200,
|
224
|
json: {api_schema_version: [1234]}
|
225
|
};
|
226
|
browser.tabs.sendMessage = () => Promise.resolve(response);
|
227
|
''')
|
228
|
show_and_wait_for_repo_entry()
|
229
|
|
230
|
elem = execute_in_page('returnval(view.repo_entries[0].info_span);')
|
231
|
msg = 'Results were served using unsupported Hydrilla API version (1234). You might need to update Haketilo.'
|
232
|
WebDriverWait(driver, 10).until(has_msg(msg, elem))
|
233
|
elif message == 'invalid_API_version':
|
234
|
setup_view(execute_in_page, repo_urls)
|
235
|
execute_in_page(
|
236
|
'''
|
237
|
const response = {
|
238
|
ok: true,
|
239
|
status: 200,
|
240
|
json: {api_schema_version: null}
|
241
|
};
|
242
|
browser.tabs.sendMessage = () => Promise.resolve(response);
|
243
|
''')
|
244
|
show_and_wait_for_repo_entry()
|
245
|
|
246
|
elem = execute_in_page('returnval(view.repo_entries[0].info_span);')
|
247
|
msg = 'Results were served using unsupported Hydrilla API version. You might need to update Haketilo.'
|
248
|
WebDriverWait(driver, 10).until(has_msg(msg, elem))
|
249
|
elif message == 'querying_repo':
|
250
|
setup_view(execute_in_page, repo_urls)
|
251
|
execute_in_page(
|
252
|
'browser.tabs.sendMessage = () => new Promise(() => {});'
|
253
|
)
|
254
|
show_and_wait_for_repo_entry()
|
255
|
|
256
|
elem = execute_in_page('returnval(view.repo_entries[0].info_span);')
|
257
|
assert has_msg('Querying repository...', elem)(0)
|
258
|
elif message == 'no_results':
|
259
|
setup_view(execute_in_page, repo_urls)
|
260
|
execute_in_page(
|
261
|
'''
|
262
|
const response = {
|
263
|
ok: true,
|
264
|
status: 200,
|
265
|
json: {
|
266
|
api_schema_version: [1],
|
267
|
api_schema_revision: 1,
|
268
|
mappings: []
|
269
|
}
|
270
|
};
|
271
|
browser.tabs.sendMessage = () => Promise.resolve(response);
|
272
|
''')
|
273
|
show_and_wait_for_repo_entry()
|
274
|
|
275
|
elem = execute_in_page('returnval(view.repo_entries[0].results_list);')
|
276
|
WebDriverWait(driver, 10).until(has_msg('No results :(', elem))
|
277
|
else:
|
278
|
raise Exception('made a typo in test function params?')
|