c2cgeoportal-admin 2.5.0.100__py3-none-any.whl → 2.9rc44__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- c2cgeoportal_admin/__init__.py +44 -14
- c2cgeoportal_admin/lib/__init__.py +0 -0
- c2cgeoportal_admin/lib/lingva_extractor.py +77 -0
- c2cgeoportal_admin/lib/ogcserver_synchronizer.py +410 -0
- c2cgeoportal_admin/py.typed +0 -0
- c2cgeoportal_admin/routes.py +30 -11
- c2cgeoportal_admin/schemas/dimensions.py +17 -11
- c2cgeoportal_admin/schemas/functionalities.py +60 -22
- c2cgeoportal_admin/schemas/interfaces.py +27 -19
- c2cgeoportal_admin/schemas/metadata.py +122 -48
- c2cgeoportal_admin/schemas/restriction_areas.py +26 -20
- c2cgeoportal_admin/schemas/roles.py +13 -7
- c2cgeoportal_admin/schemas/treegroup.py +90 -20
- c2cgeoportal_admin/schemas/treeitem.py +3 -4
- c2cgeoportal_admin/static/layertree.css +26 -4
- c2cgeoportal_admin/static/navbar.css +59 -36
- c2cgeoportal_admin/static/theme.css +51 -11
- c2cgeoportal_admin/subscribers.py +3 -3
- c2cgeoportal_admin/templates/404.jinja2 +41 -2
- c2cgeoportal_admin/templates/edit.jinja2 +23 -0
- c2cgeoportal_admin/templates/home.jinja2 +23 -0
- c2cgeoportal_admin/templates/index.jinja2 +23 -0
- c2cgeoportal_admin/templates/layertree.jinja2 +55 -11
- c2cgeoportal_admin/templates/layout.jinja2 +23 -0
- c2cgeoportal_admin/templates/navigation_navbar.jinja2 +56 -0
- c2cgeoportal_admin/templates/ogcserver_synchronize.jinja2 +90 -0
- c2cgeoportal_admin/templates/widgets/child.pt +35 -3
- c2cgeoportal_admin/templates/widgets/children.pt +121 -92
- c2cgeoportal_admin/templates/widgets/dimension.pt +23 -0
- c2cgeoportal_admin/templates/widgets/dimensions.pt +23 -0
- c2cgeoportal_admin/templates/widgets/functionality_fields.pt +51 -0
- c2cgeoportal_admin/templates/widgets/layer_fields.pt +23 -0
- c2cgeoportal_admin/templates/widgets/layer_group_fields.pt +23 -0
- c2cgeoportal_admin/templates/widgets/layer_v1_fields.pt +23 -0
- c2cgeoportal_admin/templates/widgets/metadata.pt +30 -1
- c2cgeoportal_admin/templates/widgets/metadatas.pt +23 -0
- c2cgeoportal_admin/templates/widgets/ogcserver_fields.pt +23 -0
- c2cgeoportal_admin/templates/widgets/restriction_area_fields.pt +25 -9
- c2cgeoportal_admin/templates/widgets/role_fields.pt +52 -25
- c2cgeoportal_admin/templates/widgets/theme_fields.pt +23 -0
- c2cgeoportal_admin/templates/widgets/user_fields.pt +23 -0
- c2cgeoportal_admin/views/__init__.py +29 -0
- c2cgeoportal_admin/views/dimension_layers.py +14 -9
- c2cgeoportal_admin/views/functionalities.py +52 -18
- c2cgeoportal_admin/views/home.py +5 -5
- c2cgeoportal_admin/views/interfaces.py +29 -21
- c2cgeoportal_admin/views/layer_groups.py +36 -25
- c2cgeoportal_admin/views/layers.py +17 -13
- c2cgeoportal_admin/views/layers_cog.py +135 -0
- c2cgeoportal_admin/views/layers_vectortiles.py +62 -27
- c2cgeoportal_admin/views/layers_wms.py +61 -36
- c2cgeoportal_admin/views/layers_wmts.py +54 -32
- c2cgeoportal_admin/views/layertree.py +37 -28
- c2cgeoportal_admin/views/logged_views.py +83 -0
- c2cgeoportal_admin/views/logs.py +91 -0
- c2cgeoportal_admin/views/oauth2_clients.py +96 -0
- c2cgeoportal_admin/views/ogc_servers.py +192 -21
- c2cgeoportal_admin/views/restriction_areas.py +78 -25
- c2cgeoportal_admin/views/roles.py +88 -25
- c2cgeoportal_admin/views/themes.py +47 -35
- c2cgeoportal_admin/views/themes_ordering.py +44 -24
- c2cgeoportal_admin/views/treeitems.py +21 -17
- c2cgeoportal_admin/views/users.py +46 -26
- c2cgeoportal_admin/widgets.py +79 -28
- {c2cgeoportal_admin-2.5.0.100.dist-info → c2cgeoportal_admin-2.9rc44.dist-info}/METADATA +15 -13
- c2cgeoportal_admin-2.9rc44.dist-info/RECORD +97 -0
- {c2cgeoportal_admin-2.5.0.100.dist-info → c2cgeoportal_admin-2.9rc44.dist-info}/WHEEL +1 -1
- c2cgeoportal_admin-2.9rc44.dist-info/entry_points.txt +5 -0
- tests/__init__.py +36 -27
- tests/conftest.py +23 -24
- tests/test_edit_url.py +16 -19
- tests/test_functionalities.py +52 -14
- tests/test_home.py +0 -1
- tests/test_interface.py +35 -12
- tests/test_layer_groups.py +58 -32
- tests/test_layers_cog.py +243 -0
- tests/test_layers_vectortiles.py +46 -30
- tests/test_layers_wms.py +77 -82
- tests/test_layers_wmts.py +51 -30
- tests/test_layertree.py +107 -101
- tests/test_learn.py +1 -1
- tests/test_left_menu.py +0 -1
- tests/test_lingva_extractor_config.py +64 -0
- tests/test_logs.py +102 -0
- tests/test_main.py +4 -2
- tests/test_metadatas.py +79 -71
- tests/test_oauth2_clients.py +186 -0
- tests/test_ogc_servers.py +110 -28
- tests/test_restriction_areas.py +109 -20
- tests/test_role.py +142 -82
- tests/test_themes.py +75 -41
- tests/test_themes_ordering.py +1 -2
- tests/test_treegroup.py +2 -2
- tests/test_user.py +72 -70
- tests/themes_ordering.py +1 -2
- c2cgeoportal_admin/templates/navigation_vertical.jinja2 +0 -10
- c2cgeoportal_admin-2.5.0.100.dist-info/RECORD +0 -84
- c2cgeoportal_admin-2.5.0.100.dist-info/entry_points.txt +0 -3
- {c2cgeoportal_admin-2.5.0.100.dist-info → c2cgeoportal_admin-2.9rc44.dist-info}/top_level.txt +0 -0
tests/test_metadatas.py
CHANGED
@@ -2,8 +2,7 @@
|
|
2
2
|
|
3
3
|
import pytest
|
4
4
|
|
5
|
-
from . import AbstractViewsTests
|
6
|
-
from .selenium.page import IndexPage
|
5
|
+
from . import AbstractViewsTests
|
7
6
|
|
8
7
|
|
9
8
|
@pytest.fixture(scope="function")
|
@@ -11,7 +10,7 @@ from .selenium.page import IndexPage
|
|
11
10
|
def metadatas_test_data(dbsession, transact):
|
12
11
|
del transact
|
13
12
|
|
14
|
-
from c2cgeoportal_commons.models.main import LayerWMS, LayerWMTS,
|
13
|
+
from c2cgeoportal_commons.models.main import LayerGroup, LayerWMS, LayerWMTS, Metadata, OGCServer, Theme
|
15
14
|
|
16
15
|
ogc_server = OGCServer(name="ogc_server")
|
17
16
|
|
@@ -60,7 +59,6 @@ def metadatas_test_data(dbsession, transact):
|
|
60
59
|
|
61
60
|
@pytest.mark.usefixtures("metadatas_test_data", "test_app")
|
62
61
|
class TestMetadatasView(AbstractViewsTests):
|
63
|
-
|
64
62
|
_prefix = "/admin/"
|
65
63
|
|
66
64
|
def __metadata_ui_types(self):
|
@@ -77,7 +75,18 @@ class TestMetadatasView(AbstractViewsTests):
|
|
77
75
|
"string",
|
78
76
|
)
|
79
77
|
|
80
|
-
def
|
78
|
+
def expected_value(self, test_app, metadata):
|
79
|
+
if self.__metadata_ui_type(test_app, metadata.name) == "boolean":
|
80
|
+
if metadata.value == "true":
|
81
|
+
return True
|
82
|
+
if metadata.value == "false":
|
83
|
+
return False
|
84
|
+
return None
|
85
|
+
return metadata.value
|
86
|
+
|
87
|
+
def _check_metadatas(self, test_app, item, metadatas, model):
|
88
|
+
from c2cgeoportal_admin.schemas.metadata import metadata_definitions
|
89
|
+
|
81
90
|
settings = test_app.app.registry.settings
|
82
91
|
self._check_sequence(
|
83
92
|
item,
|
@@ -88,13 +97,14 @@ class TestMetadatasView(AbstractViewsTests):
|
|
88
97
|
"name": "name",
|
89
98
|
"value": [
|
90
99
|
{"text": s_m["name"], "value": s_m["name"], "selected": s_m["name"] == m.name}
|
91
|
-
for s_m in sorted(
|
92
|
-
settings["admin_interface"]["available_metadata"], key=lambda m: m["name"]
|
93
|
-
)
|
100
|
+
for s_m in sorted(metadata_definitions(settings, model), key=lambda m: m["name"])
|
94
101
|
],
|
95
102
|
"label": "Name",
|
96
103
|
},
|
97
|
-
{
|
104
|
+
{
|
105
|
+
"name": self.__metadata_ui_type(test_app, m.name),
|
106
|
+
"value": self.expected_value(test_app, m),
|
107
|
+
},
|
98
108
|
{"name": "description", "value": m.description, "label": "Description"},
|
99
109
|
]
|
100
110
|
for m in metadatas
|
@@ -120,7 +130,7 @@ class TestMetadatasView(AbstractViewsTests):
|
|
120
130
|
resp = self._post_metadata(test_app, url, base_mapping, name, value, 200)
|
121
131
|
assert (
|
122
132
|
error_msg
|
123
|
-
== resp.html.select_one(".item-{
|
133
|
+
== resp.html.select_one(f".item-{self.__metadata_ui_type(test_app, name)} .help-block")
|
124
134
|
.getText()
|
125
135
|
.strip()
|
126
136
|
)
|
@@ -144,6 +154,46 @@ class TestMetadatasView(AbstractViewsTests):
|
|
144
154
|
'"number" is not a number',
|
145
155
|
)
|
146
156
|
|
157
|
+
def test_get_true_boolean_metadata(self, metadatas_test_data, test_app):
|
158
|
+
from c2cgeoportal_commons.models.main import LayerWMS
|
159
|
+
|
160
|
+
metadatas_test_data["layer_wms"].get_metadata("_boolean")[0].value = "true"
|
161
|
+
self._test_edit_treeitem("layers_wms", metadatas_test_data["layer_wms"], test_app, LayerWMS)
|
162
|
+
|
163
|
+
def test_get_false_boolean_metadata(self, metadatas_test_data, test_app):
|
164
|
+
from c2cgeoportal_commons.models.main import LayerWMS
|
165
|
+
|
166
|
+
metadatas_test_data["layer_wms"].get_metadata("_boolean")[0].value = "false"
|
167
|
+
self._test_edit_treeitem("layers_wms", metadatas_test_data["layer_wms"], test_app, LayerWMS)
|
168
|
+
|
169
|
+
def test_post_true_boolean_metadata(self, test_app, metadatas_test_data, dbsession):
|
170
|
+
from c2cgeoportal_commons.models.main import LayerWMS
|
171
|
+
|
172
|
+
self._post_metadata(
|
173
|
+
test_app,
|
174
|
+
"/admin/layers_wms/new",
|
175
|
+
self._base_metadata_params(metadatas_test_data),
|
176
|
+
"_boolean",
|
177
|
+
"true",
|
178
|
+
302,
|
179
|
+
)
|
180
|
+
layer = dbsession.query(LayerWMS).filter(LayerWMS.name == "new_name").one()
|
181
|
+
assert layer.get_metadata("_boolean")[0].value == "true"
|
182
|
+
|
183
|
+
def test_post_false_boolean_metadata(self, test_app, metadatas_test_data, dbsession):
|
184
|
+
from c2cgeoportal_commons.models.main import LayerWMS
|
185
|
+
|
186
|
+
self._post_metadata(
|
187
|
+
test_app,
|
188
|
+
"/admin/layers_wms/new",
|
189
|
+
self._base_metadata_params(metadatas_test_data),
|
190
|
+
"_boolean",
|
191
|
+
"false",
|
192
|
+
302,
|
193
|
+
)
|
194
|
+
layer = dbsession.query(LayerWMS).filter(LayerWMS.name == "new_name").one()
|
195
|
+
assert layer.get_metadata("_boolean")[0].value == "false"
|
196
|
+
|
147
197
|
def test_valid_float_metadata(self, test_app, metadatas_test_data):
|
148
198
|
self._post_metadata(
|
149
199
|
test_app,
|
@@ -257,85 +307,43 @@ class TestMetadatasView(AbstractViewsTests):
|
|
257
307
|
302,
|
258
308
|
)
|
259
309
|
|
260
|
-
def _test_edit_treeitem(self, prefix, item, test_app):
|
261
|
-
resp = self.get(test_app, "{}/{
|
262
|
-
self._check_metadatas(test_app, resp.html.select_one(".item-metadatas"), item.metadatas)
|
310
|
+
def _test_edit_treeitem(self, prefix, item, test_app, model):
|
311
|
+
resp = self.get(test_app, f"{prefix}/{item.id}")
|
312
|
+
self._check_metadatas(test_app, resp.html.select_one(".item-metadatas"), item.metadatas, model)
|
263
313
|
resp.form.submit("submit", status=302)
|
264
314
|
|
265
315
|
def test_layer_wms_metadatas(self, metadatas_test_data, test_app):
|
266
|
-
|
316
|
+
from c2cgeoportal_commons.models.main import LayerWMS
|
317
|
+
|
318
|
+
self._test_edit_treeitem("layers_wms", metadatas_test_data["layer_wms"], test_app, LayerWMS)
|
267
319
|
|
268
320
|
def test_layer_wmts_metadatas(self, metadatas_test_data, test_app):
|
269
|
-
|
321
|
+
from c2cgeoportal_commons.models.main import LayerWMTS
|
322
|
+
|
323
|
+
self._test_edit_treeitem("layers_wmts", metadatas_test_data["layer_wmts"], test_app, LayerWMTS)
|
270
324
|
|
271
325
|
def test_theme_metadatas(self, metadatas_test_data, test_app):
|
272
|
-
|
326
|
+
from c2cgeoportal_commons.models.main import Theme
|
327
|
+
|
328
|
+
self._test_edit_treeitem("themes", metadatas_test_data["theme"], test_app, Theme)
|
273
329
|
|
274
330
|
def test_group_metadatas(self, metadatas_test_data, test_app):
|
275
|
-
|
331
|
+
from c2cgeoportal_commons.models.main import LayerGroup
|
332
|
+
|
333
|
+
self._test_edit_treeitem("layer_groups", metadatas_test_data["group"], test_app, LayerGroup)
|
276
334
|
|
277
335
|
def test_undefined_metadata(self, metadatas_test_data, test_app):
|
278
|
-
"""
|
336
|
+
"""
|
337
|
+
Undefined metadata must be kept intact across submissions.
|
338
|
+
"""
|
279
339
|
from c2cgeoportal_commons.models.main import Metadata
|
280
340
|
|
281
341
|
layer = metadatas_test_data["layer_wms"]
|
282
342
|
layer.metadatas = [Metadata("_undefined", "This is an undefined metadata")]
|
283
343
|
|
284
|
-
resp = self.get(test_app, "layers_wms/{
|
344
|
+
resp = self.get(test_app, f"layers_wms/{layer.id}")
|
285
345
|
resp.form.submit("submit", status=302)
|
286
346
|
|
287
347
|
metadata = layer.metadatas[0]
|
288
348
|
assert metadata.name == "_undefined"
|
289
349
|
assert metadata.value == "This is an undefined metadata"
|
290
|
-
|
291
|
-
|
292
|
-
@skip_if_ci
|
293
|
-
@pytest.mark.selenium
|
294
|
-
@pytest.mark.usefixtures("selenium", "selenium_app", "metadatas_test_data")
|
295
|
-
class TestMetadatasSelenium:
|
296
|
-
def test_hidden_type_validator_does_not_take_precedence_over_visible(
|
297
|
-
self, selenium, selenium_app, metadatas_test_data
|
298
|
-
):
|
299
|
-
layer = metadatas_test_data["layer_wms"]
|
300
|
-
selenium.get(selenium_app + "/admin/layers_wms/{}".format(layer.id))
|
301
|
-
selenium.execute_script("window.scrollBy(0,3000)", "")
|
302
|
-
selenium.find_element_by_xpath(
|
303
|
-
"""//div[contains(., "Metadatas")]
|
304
|
-
/following-sibling::div[@class="panel-footer"]/a[@href="#"]"""
|
305
|
-
).click()
|
306
|
-
selenium.execute_script("window.scrollBy(0,3000)", "")
|
307
|
-
selenium.find_elements_by_xpath(
|
308
|
-
"""//div[contains(., "Metadatas")]//label[contains(., "Name")]
|
309
|
-
/following-sibling::select/option[contains(.,"_int")]"""
|
310
|
-
)[9].click()
|
311
|
-
selenium.find_elements_by_xpath('//div[contains(., "Metadatas")]//input[@name="int"]')[9].send_keys(
|
312
|
-
"AAA"
|
313
|
-
)
|
314
|
-
|
315
|
-
selenium.find_element_by_id("deformformsubmit").click()
|
316
|
-
|
317
|
-
assert '"AAA" is not a number' == selenium.find_element_by_xpath('//p[@class="help-block"]').text
|
318
|
-
|
319
|
-
selenium.find_elements_by_xpath(
|
320
|
-
"""//div[contains(., "Metadatas")]//label[contains(., "Name")]
|
321
|
-
/following-sibling::select/option[contains(.,"_color")]"""
|
322
|
-
)[9].click()
|
323
|
-
selenium.find_elements_by_xpath('//div[contains(., "Metadatas")]//input[@name="string"]')[
|
324
|
-
9
|
325
|
-
].send_keys("BBB")
|
326
|
-
|
327
|
-
selenium.find_element_by_id("deformformsubmit").click()
|
328
|
-
|
329
|
-
assert (
|
330
|
-
"Expecting hex format for color, e.g. #007DCD"
|
331
|
-
== selenium.find_element_by_xpath('//p[@class="help-block"]').text
|
332
|
-
)
|
333
|
-
|
334
|
-
# have to check there are no side effects, especially that modifications held at template side
|
335
|
-
# don't trigger "are you sure you want to leave alert"
|
336
|
-
layer = metadatas_test_data["layer_wms"]
|
337
|
-
IndexPage(selenium)
|
338
|
-
selenium.get(selenium_app + "/admin/layers_wms/{}".format(layer.id))
|
339
|
-
|
340
|
-
selenium.find_element_by_xpath('//a[contains(@href, "roles")]').click()
|
341
|
-
assert selenium.current_url.endswith("/roles")
|
@@ -0,0 +1,186 @@
|
|
1
|
+
# pylint: disable=no-self-use,unsubscriptable-object
|
2
|
+
|
3
|
+
import re
|
4
|
+
from uuid import uuid4
|
5
|
+
|
6
|
+
import pyramid.httpexceptions
|
7
|
+
import pytest
|
8
|
+
from pyramid.testing import DummyRequest
|
9
|
+
|
10
|
+
from .test_treegroup import TestTreeGroup
|
11
|
+
|
12
|
+
|
13
|
+
@pytest.fixture(scope="function")
|
14
|
+
@pytest.mark.usefixtures("dbsession", "transact")
|
15
|
+
def oauth2_clients_test_data(dbsession, transact):
|
16
|
+
del transact
|
17
|
+
|
18
|
+
from c2cgeoportal_commons.models.static import OAuth2Client
|
19
|
+
|
20
|
+
clients = []
|
21
|
+
for i in range(23):
|
22
|
+
client = OAuth2Client()
|
23
|
+
client.client_id = str(uuid4())
|
24
|
+
client.secret = "1234"
|
25
|
+
client.redirect_uri = "http://127.0.0.1:7070/"
|
26
|
+
|
27
|
+
dbsession.add(client)
|
28
|
+
clients.append(client)
|
29
|
+
|
30
|
+
dbsession.flush()
|
31
|
+
|
32
|
+
yield {
|
33
|
+
"oauth2_clients": clients,
|
34
|
+
}
|
35
|
+
|
36
|
+
|
37
|
+
@pytest.mark.usefixtures("oauth2_clients_test_data", "test_app")
|
38
|
+
class TestOAuth2Client(TestTreeGroup):
|
39
|
+
_prefix = "/admin/oauth2_clients"
|
40
|
+
|
41
|
+
def test_index_rendering(self, test_app):
|
42
|
+
resp = self.get(test_app)
|
43
|
+
|
44
|
+
self.check_left_menu(resp, "OAuth2 Clients")
|
45
|
+
|
46
|
+
expected = [
|
47
|
+
("actions", "", "false"),
|
48
|
+
("id", "id", "true"),
|
49
|
+
("client_id", "Client ID"),
|
50
|
+
("secret", "Secret"),
|
51
|
+
("redirect_uri", "Redirect URI"),
|
52
|
+
]
|
53
|
+
self.check_grid_headers(resp, expected)
|
54
|
+
|
55
|
+
def test_grid_search(self, test_app, oauth2_clients_test_data):
|
56
|
+
self.check_search(test_app, "", total=23)
|
57
|
+
|
58
|
+
client = oauth2_clients_test_data["oauth2_clients"][0]
|
59
|
+
self.check_search(test_app, client.client_id, total=1)
|
60
|
+
|
61
|
+
def test_submit_new(self, dbsession, test_app, oauth2_clients_test_data):
|
62
|
+
from c2cgeoportal_commons.models.main import LogAction
|
63
|
+
from c2cgeoportal_commons.models.static import Log, OAuth2Client
|
64
|
+
|
65
|
+
resp = test_app.post(
|
66
|
+
"/admin/oauth2_clients/new",
|
67
|
+
(
|
68
|
+
("_charset_", "UTF-8"),
|
69
|
+
("__formid__", "deform"),
|
70
|
+
("id", ""),
|
71
|
+
("client_id", "qgis2"),
|
72
|
+
("secret", "12345"),
|
73
|
+
("redirect_uri", "http://127.0.0.1:7070/bis"),
|
74
|
+
("formsubmit", "formsubmit"),
|
75
|
+
),
|
76
|
+
status=302,
|
77
|
+
)
|
78
|
+
|
79
|
+
oauth2_client = dbsession.query(OAuth2Client).filter(OAuth2Client.client_id == "qgis2").one()
|
80
|
+
assert str(oauth2_client.id) == re.match(
|
81
|
+
r"http://localhost/admin/oauth2_clients/(.*)\?msg_col=submit_ok", resp.location
|
82
|
+
).group(1)
|
83
|
+
|
84
|
+
assert oauth2_client.client_id == "qgis2"
|
85
|
+
assert oauth2_client.secret == "12345"
|
86
|
+
assert oauth2_client.redirect_uri == "http://127.0.0.1:7070/bis"
|
87
|
+
|
88
|
+
log = dbsession.query(Log).one()
|
89
|
+
assert log.date != None
|
90
|
+
assert log.action == LogAction.INSERT
|
91
|
+
assert log.element_type == "oauth2_client"
|
92
|
+
assert log.element_id == oauth2_client.id
|
93
|
+
assert log.element_name == oauth2_client.client_id
|
94
|
+
assert log.username == "test_user"
|
95
|
+
|
96
|
+
def test_edit_then_save(self, dbsession, test_app, oauth2_clients_test_data):
|
97
|
+
from c2cgeoportal_commons.models.main import LogAction
|
98
|
+
from c2cgeoportal_commons.models.static import Log
|
99
|
+
|
100
|
+
oauth2_client = oauth2_clients_test_data["oauth2_clients"][10]
|
101
|
+
|
102
|
+
dbsession.expire(oauth2_client)
|
103
|
+
|
104
|
+
form = self.get_item(test_app, oauth2_client.id).form
|
105
|
+
|
106
|
+
assert str(oauth2_client.id) == form["id"].value
|
107
|
+
assert oauth2_client.client_id == form["client_id"].value
|
108
|
+
assert oauth2_client.secret == form["secret"].value
|
109
|
+
assert oauth2_client.redirect_uri == form["redirect_uri"].value
|
110
|
+
|
111
|
+
form["client_id"] = "New client ID"
|
112
|
+
form["secret"] = "New secret"
|
113
|
+
form["redirect_uri"] = "New redirect URI"
|
114
|
+
|
115
|
+
resp = form.submit("submit")
|
116
|
+
|
117
|
+
assert str(oauth2_client.id) == re.match(
|
118
|
+
r"http://localhost/admin/oauth2_clients/(.*)\?msg_col=submit_ok", resp.location
|
119
|
+
).group(1)
|
120
|
+
|
121
|
+
dbsession.expire(oauth2_client)
|
122
|
+
|
123
|
+
assert "New client ID" == oauth2_client.client_id
|
124
|
+
assert "New secret" == oauth2_client.secret
|
125
|
+
assert "New redirect URI" == oauth2_client.redirect_uri
|
126
|
+
|
127
|
+
log = dbsession.query(Log).one()
|
128
|
+
assert log.date != None
|
129
|
+
assert log.action == LogAction.UPDATE
|
130
|
+
assert log.element_type == "oauth2_client"
|
131
|
+
assert log.element_id == oauth2_client.id
|
132
|
+
assert log.element_name == oauth2_client.client_id
|
133
|
+
assert log.username == "test_user"
|
134
|
+
|
135
|
+
def test_duplicate(self, oauth2_clients_test_data, test_app, dbsession):
|
136
|
+
from c2cgeoportal_commons.models.static import OAuth2Client
|
137
|
+
|
138
|
+
oauth2_client_proto = oauth2_clients_test_data["oauth2_clients"][7]
|
139
|
+
|
140
|
+
resp = test_app.get(f"/admin/oauth2_clients/{oauth2_client_proto.id}/duplicate", status=200)
|
141
|
+
form = resp.form
|
142
|
+
|
143
|
+
assert "" == self.get_first_field_named(form, "id").value
|
144
|
+
assert oauth2_client_proto.client_id == form["client_id"].value
|
145
|
+
assert oauth2_client_proto.secret == form["secret"].value
|
146
|
+
assert oauth2_client_proto.redirect_uri == form["redirect_uri"].value
|
147
|
+
form["client_id"].value = "clone"
|
148
|
+
resp = form.submit("submit")
|
149
|
+
|
150
|
+
oauth2_client = dbsession.query(OAuth2Client).filter(OAuth2Client.client_id == "clone").one()
|
151
|
+
assert str(oauth2_client.id) == re.match(
|
152
|
+
r"http://localhost/admin/oauth2_clients/(.*)\?msg_col=submit_ok", resp.location
|
153
|
+
).group(1)
|
154
|
+
assert oauth2_client_proto.id != oauth2_client.id
|
155
|
+
|
156
|
+
def test_delete(self, test_app, dbsession):
|
157
|
+
from c2cgeoportal_commons.models.main import LogAction
|
158
|
+
from c2cgeoportal_commons.models.static import Log, OAuth2Client
|
159
|
+
|
160
|
+
oauth2_client = dbsession.query(OAuth2Client).first()
|
161
|
+
test_app.delete(f"/admin/oauth2_clients/{oauth2_client.id}", status=200)
|
162
|
+
assert dbsession.query(OAuth2Client).get(oauth2_client.id) is None
|
163
|
+
|
164
|
+
log = dbsession.query(Log).one()
|
165
|
+
assert log.date != None
|
166
|
+
assert log.action == LogAction.DELETE
|
167
|
+
assert log.element_type == "oauth2_client"
|
168
|
+
assert log.element_id == oauth2_client.id
|
169
|
+
assert log.element_name == oauth2_client.client_id
|
170
|
+
assert log.username == "test_user"
|
171
|
+
|
172
|
+
def test_unicity_validator(self, oauth2_clients_test_data, test_app):
|
173
|
+
oauth2_client_proto = oauth2_clients_test_data["oauth2_clients"][7]
|
174
|
+
resp = test_app.get(f"/admin/oauth2_clients/{oauth2_client_proto.id}/duplicate", status=200)
|
175
|
+
|
176
|
+
resp = resp.form.submit("submit")
|
177
|
+
|
178
|
+
self._check_submission_problem(resp, f"{oauth2_client_proto.client_id} is already used.")
|
179
|
+
|
180
|
+
@pytest.mark.usefixtures("raise_db_error_on_query")
|
181
|
+
def test_grid_dberror(self, dbsession):
|
182
|
+
from c2cgeoportal_admin.views.oauth2_clients import OAuth2ClientViews
|
183
|
+
|
184
|
+
request = DummyRequest(dbsession=dbsession, params={"offset": 0, "limit": 10})
|
185
|
+
with pytest.raises(pyramid.httpexceptions.HTTPInternalServerError):
|
186
|
+
OAuth2ClientViews(request).grid()
|
tests/test_ogc_servers.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# pylint: disable=no-self-use
|
2
2
|
|
3
3
|
import re
|
4
|
+
from unittest.mock import patch
|
4
5
|
|
5
6
|
import pytest
|
6
7
|
|
@@ -17,8 +18,8 @@ def ogc_server_test_data(dbsession, transact):
|
|
17
18
|
auth = ["No auth", "Standard auth", "Geoserver auth", "Proxy"]
|
18
19
|
servers = []
|
19
20
|
for i in range(0, 8):
|
20
|
-
server = OGCServer(name="server_{}"
|
21
|
-
server.url = "https://somebasicurl_{}.com"
|
21
|
+
server = OGCServer(name=f"server_{i}", description=f"description_{i}")
|
22
|
+
server.url = f"https://somebasicurl_{i}.com"
|
22
23
|
server.image_type = "image/jpeg" if i % 2 == 0 else "image/png"
|
23
24
|
server.auth = auth[i % 4]
|
24
25
|
dbsession.add(server)
|
@@ -31,7 +32,6 @@ def ogc_server_test_data(dbsession, transact):
|
|
31
32
|
|
32
33
|
@pytest.mark.usefixtures("ogc_server_test_data", "test_app")
|
33
34
|
class TestOGCServer(AbstractViewsTests):
|
34
|
-
|
35
35
|
_prefix = "/admin/ogc_servers"
|
36
36
|
|
37
37
|
def test_index_rendering(self, test_app):
|
@@ -59,54 +59,82 @@ class TestOGCServer(AbstractViewsTests):
|
|
59
59
|
self.check_search(test_app, "server_0", total=1)
|
60
60
|
|
61
61
|
def test_submit_new(self, dbsession, test_app):
|
62
|
-
from c2cgeoportal_commons.models.main import OGCServer
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
62
|
+
from c2cgeoportal_commons.models.main import Log, LogAction, OGCServer
|
63
|
+
|
64
|
+
with patch("c2cgeoportal_admin.views.ogc_servers.OGCServerViews._update_cache"):
|
65
|
+
resp = test_app.post(
|
66
|
+
"/admin/ogc_servers/new",
|
67
|
+
{
|
68
|
+
"name": "new_name",
|
69
|
+
"description": "new description",
|
70
|
+
"url": "www.randomurl.com",
|
71
|
+
"type": "mapserver",
|
72
|
+
"auth": "No auth",
|
73
|
+
"image_type": "image/png",
|
74
|
+
},
|
75
|
+
status=302,
|
76
|
+
)
|
76
77
|
ogc_server = dbsession.query(OGCServer).filter(OGCServer.name == "new_name").one()
|
77
78
|
assert str(ogc_server.id) == re.match(
|
78
79
|
r"http://localhost/admin/ogc_servers/(.*)\?msg_col=submit_ok", resp.location
|
79
80
|
).group(1)
|
80
81
|
assert ogc_server.name == "new_name"
|
81
82
|
|
82
|
-
|
83
|
+
log = dbsession.query(Log).one()
|
84
|
+
assert log.date != None
|
85
|
+
assert log.action == LogAction.INSERT
|
86
|
+
assert log.element_type == "ogc_server"
|
87
|
+
assert log.element_id == ogc_server.id
|
88
|
+
assert log.element_name == ogc_server.name
|
89
|
+
assert log.username == "test_user"
|
90
|
+
|
91
|
+
def test_edit(self, test_app, ogc_server_test_data, dbsession):
|
92
|
+
from c2cgeoportal_commons.models.main import Log, LogAction
|
93
|
+
|
83
94
|
ogc_server = ogc_server_test_data["ogc_servers"][0]
|
84
|
-
resp = test_app.get("/admin/ogc_servers/{
|
95
|
+
resp = test_app.get(f"/admin/ogc_servers/{ogc_server.id}", status=200)
|
85
96
|
form = resp.form
|
86
97
|
assert str(ogc_server.id) == self.get_first_field_named(form, "id").value
|
87
98
|
assert "hidden" == self.get_first_field_named(form, "id").attrs["type"]
|
88
99
|
assert ogc_server.name == form["name"].value
|
89
100
|
form["description"] = "new_description"
|
90
|
-
|
101
|
+
with patch("c2cgeoportal_admin.views.ogc_servers.OGCServerViews._update_cache"):
|
102
|
+
assert form.submit().status_int == 302
|
91
103
|
assert ogc_server.description == "new_description"
|
92
104
|
|
105
|
+
log = dbsession.query(Log).one()
|
106
|
+
assert log.date != None
|
107
|
+
assert log.action == LogAction.UPDATE
|
108
|
+
assert log.element_type == "ogc_server"
|
109
|
+
assert log.element_id == ogc_server.id
|
110
|
+
assert log.element_name == ogc_server.name
|
111
|
+
assert log.username == "test_user"
|
112
|
+
|
93
113
|
def test_delete(self, test_app, ogc_server_test_data, dbsession):
|
94
|
-
from c2cgeoportal_commons.models.main import OGCServer
|
114
|
+
from c2cgeoportal_commons.models.main import Log, LogAction, OGCServer
|
95
115
|
|
96
116
|
ogc_server = ogc_server_test_data["ogc_servers"][0]
|
97
|
-
|
98
|
-
|
99
|
-
|
117
|
+
test_app.delete(f"/admin/ogc_servers/{ogc_server.id}", status=200)
|
118
|
+
assert dbsession.query(OGCServer).get(ogc_server.id) is None
|
119
|
+
|
120
|
+
log = dbsession.query(Log).one()
|
121
|
+
assert log.date != None
|
122
|
+
assert log.action == LogAction.DELETE
|
123
|
+
assert log.element_type == "ogc_server"
|
124
|
+
assert log.element_id == ogc_server.id
|
125
|
+
assert log.element_name == ogc_server.name
|
126
|
+
assert log.username == "test_user"
|
100
127
|
|
101
128
|
def test_duplicate(self, ogc_server_test_data, test_app, dbsession):
|
102
129
|
from c2cgeoportal_commons.models.main import OGCServer
|
103
130
|
|
104
131
|
ogc_server = ogc_server_test_data["ogc_servers"][3]
|
105
|
-
resp = test_app.get("/admin/ogc_servers/{}/duplicate"
|
132
|
+
resp = test_app.get(f"/admin/ogc_servers/{ogc_server.id}/duplicate", status=200)
|
106
133
|
form = resp.form
|
107
134
|
assert "" == self.get_first_field_named(form, "id").value
|
108
135
|
self.set_first_field_named(form, "name", "clone")
|
109
|
-
|
136
|
+
with patch("c2cgeoportal_admin.views.ogc_servers.OGCServerViews._update_cache"):
|
137
|
+
resp = form.submit("submit")
|
110
138
|
assert resp.status_int == 302
|
111
139
|
server = dbsession.query(OGCServer).filter(OGCServer.name == "clone").one()
|
112
140
|
assert str(server.id) == re.match(
|
@@ -115,8 +143,62 @@ class TestOGCServer(AbstractViewsTests):
|
|
115
143
|
|
116
144
|
def test_unicity_validator(self, ogc_server_test_data, test_app):
|
117
145
|
ogc_server = ogc_server_test_data["ogc_servers"][3]
|
118
|
-
resp = test_app.get("/admin/ogc_servers/{}/duplicate"
|
146
|
+
resp = test_app.get(f"/admin/ogc_servers/{ogc_server.id}/duplicate", status=200)
|
119
147
|
|
120
148
|
resp = resp.form.submit("submit")
|
121
149
|
|
122
|
-
self._check_submission_problem(resp, "{} is already used."
|
150
|
+
self._check_submission_problem(resp, f"{ogc_server.name} is already used.")
|
151
|
+
|
152
|
+
def test_check_success(self, ogc_server_test_data, test_app):
|
153
|
+
ogc_server = ogc_server_test_data["ogc_servers"][3]
|
154
|
+
ogc_server.url = "config://mapserver"
|
155
|
+
resp = test_app.get(f"/admin/ogc_servers/{ogc_server.id}/synchronize", status=200)
|
156
|
+
|
157
|
+
resp = resp.forms["form-check"].submit("check")
|
158
|
+
|
159
|
+
assert list(resp.html.find("div", class_="alert-success").stripped_strings) == [
|
160
|
+
"OGC Server has been successfully synchronized."
|
161
|
+
]
|
162
|
+
|
163
|
+
def test_dry_run_success(self, ogc_server_test_data, test_app):
|
164
|
+
ogc_server = ogc_server_test_data["ogc_servers"][3]
|
165
|
+
ogc_server.url = "config://mapserver"
|
166
|
+
resp = test_app.get(f"/admin/ogc_servers/{ogc_server.id}/synchronize", status=200)
|
167
|
+
|
168
|
+
resp = resp.forms["form-dry-run"].submit("dry-run")
|
169
|
+
|
170
|
+
assert list(resp.html.find("div", class_="alert-success").stripped_strings) == [
|
171
|
+
"OGC Server has been successfully synchronized."
|
172
|
+
]
|
173
|
+
|
174
|
+
def test_synchronize_success(self, ogc_server_test_data, test_app, dbsession):
|
175
|
+
from c2cgeoportal_commons.models.main import Log, LogAction
|
176
|
+
|
177
|
+
ogc_server = ogc_server_test_data["ogc_servers"][3]
|
178
|
+
ogc_server.url = "config://mapserver"
|
179
|
+
resp = test_app.get(f"/admin/ogc_servers/{ogc_server.id}/synchronize", status=200)
|
180
|
+
|
181
|
+
resp = resp.forms["form-synchronize"].submit("synchronize")
|
182
|
+
|
183
|
+
log = dbsession.query(Log).one()
|
184
|
+
assert log.date != None
|
185
|
+
assert log.action == LogAction.SYNCHRONIZE
|
186
|
+
assert log.element_type == "ogc_server"
|
187
|
+
assert log.element_id == ogc_server.id
|
188
|
+
assert log.element_name == ogc_server.name
|
189
|
+
assert log.username == "test_user"
|
190
|
+
|
191
|
+
assert list(resp.html.find("div", class_="alert-success").stripped_strings) == [
|
192
|
+
"OGC Server has been successfully synchronized."
|
193
|
+
]
|
194
|
+
|
195
|
+
form = resp.forms["form-synchronize"]
|
196
|
+
form["force-parents"].checked = True
|
197
|
+
form["force-ordering"].checked = True
|
198
|
+
form["clean"].checked = True
|
199
|
+
|
200
|
+
resp = form.submit("synchronize")
|
201
|
+
|
202
|
+
assert list(resp.html.find("div", class_="alert-success").stripped_strings) == [
|
203
|
+
"OGC Server has been successfully synchronized."
|
204
|
+
]
|