c2cgeoportal-admin 2.6.0__py3-none-any.whl → 2.7.1.156__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 +17 -10
- c2cgeoportal_admin/lib/lingua_extractor.py +77 -0
- c2cgeoportal_admin/lib/ogcserver_synchronizer.py +166 -54
- c2cgeoportal_admin/py.typed +0 -0
- c2cgeoportal_admin/routes.py +4 -3
- c2cgeoportal_admin/schemas/dimensions.py +12 -10
- c2cgeoportal_admin/schemas/functionalities.py +62 -21
- c2cgeoportal_admin/schemas/interfaces.py +22 -18
- c2cgeoportal_admin/schemas/metadata.py +99 -46
- c2cgeoportal_admin/schemas/restriction_areas.py +21 -19
- c2cgeoportal_admin/schemas/roles.py +7 -5
- c2cgeoportal_admin/schemas/treegroup.py +37 -16
- c2cgeoportal_admin/schemas/treeitem.py +2 -3
- c2cgeoportal_admin/static/layertree.css +3 -4
- c2cgeoportal_admin/static/navbar.css +36 -35
- c2cgeoportal_admin/static/theme.css +16 -9
- c2cgeoportal_admin/subscribers.py +3 -3
- c2cgeoportal_admin/templates/layertree.jinja2 +31 -9
- c2cgeoportal_admin/templates/navigation_navbar.jinja2 +33 -0
- c2cgeoportal_admin/templates/ogcserver_synchronize.jinja2 +12 -0
- c2cgeoportal_admin/templates/widgets/functionality_fields.pt +51 -0
- c2cgeoportal_admin/templates/widgets/metadata.pt +7 -1
- c2cgeoportal_admin/views/dimension_layers.py +7 -6
- c2cgeoportal_admin/views/functionalities.py +31 -5
- c2cgeoportal_admin/views/home.py +5 -5
- c2cgeoportal_admin/views/interfaces.py +5 -7
- c2cgeoportal_admin/views/layer_groups.py +9 -11
- c2cgeoportal_admin/views/layers.py +8 -7
- c2cgeoportal_admin/views/layers_vectortiles.py +30 -10
- c2cgeoportal_admin/views/layers_wms.py +39 -35
- c2cgeoportal_admin/views/layers_wmts.py +39 -35
- c2cgeoportal_admin/views/layertree.py +35 -27
- c2cgeoportal_admin/views/oauth2_clients.py +26 -21
- c2cgeoportal_admin/views/ogc_servers.py +57 -29
- c2cgeoportal_admin/views/restriction_areas.py +11 -10
- c2cgeoportal_admin/views/roles.py +14 -11
- c2cgeoportal_admin/views/themes.py +15 -14
- c2cgeoportal_admin/views/themes_ordering.py +13 -8
- c2cgeoportal_admin/views/treeitems.py +12 -11
- c2cgeoportal_admin/views/users.py +7 -5
- c2cgeoportal_admin/widgets.py +17 -14
- {c2cgeoportal_admin-2.6.0.dist-info → c2cgeoportal_admin-2.7.1.156.dist-info}/METADATA +15 -12
- c2cgeoportal_admin-2.7.1.156.dist-info/RECORD +92 -0
- {c2cgeoportal_admin-2.6.0.dist-info → c2cgeoportal_admin-2.7.1.156.dist-info}/WHEEL +1 -1
- c2cgeoportal_admin-2.7.1.156.dist-info/entry_points.txt +5 -0
- tests/__init__.py +9 -9
- tests/conftest.py +2 -1
- tests/test_edit_url.py +11 -13
- tests/test_functionalities.py +23 -10
- tests/test_interface.py +7 -7
- tests/test_layer_groups.py +13 -17
- tests/test_layers_vectortiles.py +11 -13
- tests/test_layers_wms.py +25 -36
- tests/test_layers_wmts.py +15 -19
- tests/test_layertree.py +99 -15
- tests/test_lingua_extractor_config.py +66 -0
- tests/test_main.py +3 -1
- tests/test_metadatas.py +34 -20
- tests/test_oauth2_clients.py +4 -4
- tests/test_ogc_servers.py +21 -10
- tests/test_restriction_areas.py +10 -12
- tests/test_role.py +37 -35
- tests/test_themes.py +40 -33
- tests/test_themes_ordering.py +1 -1
- tests/test_treegroup.py +2 -2
- tests/test_user.py +15 -13
- tests/themes_ordering.py +1 -1
- c2cgeoportal_admin/templates/navigation_vertical.jinja2 +0 -33
- c2cgeoportal_admin-2.6.0.dist-info/RECORD +0 -89
- c2cgeoportal_admin-2.6.0.dist-info/entry_points.txt +0 -3
- {c2cgeoportal_admin-2.6.0.dist-info → c2cgeoportal_admin-2.7.1.156.dist-info}/top_level.txt +0 -0
tests/test_layers_wms.py
CHANGED
@@ -14,16 +14,16 @@ def layer_wms_test_data(dbsession, transact):
|
|
14
14
|
|
15
15
|
from c2cgeoportal_commons.models.main import LayerWMS, OGCServer
|
16
16
|
|
17
|
-
servers = [OGCServer(name="server_{}"
|
17
|
+
servers = [OGCServer(name=f"server_{i}") for i in range(0, 4)]
|
18
18
|
for i, server in enumerate(servers):
|
19
|
-
server.url = "http://wms.geo.admin.ch_{}"
|
19
|
+
server.url = f"http://wms.geo.admin.ch_{i}"
|
20
20
|
server.image_type = "image/jpeg" if i % 2 == 0 else "image/png"
|
21
21
|
|
22
22
|
def layer_builder(i):
|
23
|
-
layer = LayerWMS(name="layer_wms_{}"
|
24
|
-
layer.layer = "layer_{}"
|
23
|
+
layer = LayerWMS(name=f"layer_wms_{i}")
|
24
|
+
layer.layer = f"layer_{i}"
|
25
25
|
layer.public = 1 == i % 2
|
26
|
-
layer.geo_table = "geotable_{}"
|
26
|
+
layer.geo_table = f"geotable_{i}"
|
27
27
|
layer.ogc_server = servers[i % 4]
|
28
28
|
layer.style = "décontrasté"
|
29
29
|
return layer
|
@@ -173,11 +173,11 @@ class TestLayerWMSViews(AbstractViewsTests):
|
|
173
173
|
assert str(layer.time_widget) == form["time_widget"].value
|
174
174
|
|
175
175
|
interfaces = layer_wms_test_data["interfaces"]
|
176
|
-
assert
|
176
|
+
assert {interfaces[0].id, interfaces[2].id} == {i.id for i in layer.interfaces}
|
177
177
|
self._check_interfaces(form, interfaces, layer)
|
178
178
|
|
179
179
|
ras = layer_wms_test_data["restrictionareas"]
|
180
|
-
assert
|
180
|
+
assert {ras[0].id, ras[2].id} == {i.id for i in layer.restrictionareas}
|
181
181
|
self._check_restrictionsareas(form, ras, layer)
|
182
182
|
|
183
183
|
new_values = {
|
@@ -200,7 +200,7 @@ class TestLayerWMSViews(AbstractViewsTests):
|
|
200
200
|
|
201
201
|
resp = form.submit("submit")
|
202
202
|
assert str(layer.id) == re.match(
|
203
|
-
|
203
|
+
rf"http://localhost{self._prefix}/(.*)\?msg_col=submit_ok", resp.location
|
204
204
|
).group(1)
|
205
205
|
|
206
206
|
dbsession.expire(layer)
|
@@ -209,10 +209,8 @@ class TestLayerWMSViews(AbstractViewsTests):
|
|
209
209
|
assert value == getattr(layer, key)
|
210
210
|
else:
|
211
211
|
assert str(value or "") == str(getattr(layer, key) or "")
|
212
|
-
assert
|
213
|
-
|
214
|
-
)
|
215
|
-
assert set([ras[1].id, ras[3].id]) == set([ra.id for ra in layer.restrictionareas])
|
212
|
+
assert {interfaces[1].id, interfaces[3].id} == {interface.id for interface in layer.interfaces}
|
213
|
+
assert {ras[1].id, ras[3].id} == {ra.id for ra in layer.restrictionareas}
|
216
214
|
|
217
215
|
def test_submit_new(self, dbsession, test_app, layer_wms_test_data):
|
218
216
|
from c2cgeoportal_commons.models.main import LayerWMS
|
@@ -244,7 +242,7 @@ class TestLayerWMSViews(AbstractViewsTests):
|
|
244
242
|
|
245
243
|
layer = layer_wms_test_data["layers"][3]
|
246
244
|
|
247
|
-
resp = test_app.get("/admin/layers_wms/{}/duplicate"
|
245
|
+
resp = test_app.get(f"/admin/layers_wms/{layer.id}/duplicate", status=200)
|
248
246
|
form = resp.form
|
249
247
|
|
250
248
|
assert "" == self.get_first_field_named(form, "id").value
|
@@ -260,11 +258,11 @@ class TestLayerWMSViews(AbstractViewsTests):
|
|
260
258
|
assert str(layer.time_mode) == form["time_mode"].value
|
261
259
|
assert str(layer.time_widget) == form["time_widget"].value
|
262
260
|
interfaces = layer_wms_test_data["interfaces"]
|
263
|
-
assert
|
261
|
+
assert {interfaces[3].id, interfaces[1].id} == {i.id for i in layer.interfaces}
|
264
262
|
self._check_interfaces(form, interfaces, layer)
|
265
263
|
|
266
264
|
ras = layer_wms_test_data["restrictionareas"]
|
267
|
-
assert
|
265
|
+
assert {ras[3].id, ras[0].id} == {i.id for i in layer.restrictionareas}
|
268
266
|
self._check_restrictionsareas(form, ras, layer)
|
269
267
|
|
270
268
|
self._check_dimensions(resp.html, layer.dimensions, duplicated=True)
|
@@ -289,12 +287,9 @@ class TestLayerWMSViews(AbstractViewsTests):
|
|
289
287
|
assert 0 == dbsession.query(LayerWMTS).filter(LayerWMTS.name == layer.name).count()
|
290
288
|
assert 1 == dbsession.query(LayerWMS).filter(LayerWMS.name == layer.name).count()
|
291
289
|
|
292
|
-
resp = test_app.post("/admin/layers_wms/{}/convert_to_wmts"
|
290
|
+
resp = test_app.post(f"/admin/layers_wms/{layer.id}/convert_to_wmts", status=200)
|
293
291
|
assert resp.json["success"]
|
294
|
-
assert
|
295
|
-
"http://localhost/admin/layers_wmts/{}?msg_col=submit_ok".format(layer.id)
|
296
|
-
== resp.json["redirect"]
|
297
|
-
)
|
292
|
+
assert f"http://localhost/admin/layers_wmts/{layer.id}?msg_col=submit_ok" == resp.json["redirect"]
|
298
293
|
|
299
294
|
assert 1 == dbsession.query(LayerWMTS).filter(LayerWMTS.name == layer.name).count()
|
300
295
|
assert 0 == dbsession.query(LayerWMS).filter(LayerWMS.name == layer.name).count()
|
@@ -328,23 +323,17 @@ class TestLayerWMSViews(AbstractViewsTests):
|
|
328
323
|
def test_convert_image_type_from_ogcserver(self, layer_wms_test_data, test_app):
|
329
324
|
layer = layer_wms_test_data["layers"][3]
|
330
325
|
|
331
|
-
resp = test_app.post("/admin/layers_wms/{}/convert_to_wmts"
|
326
|
+
resp = test_app.post(f"/admin/layers_wms/{layer.id}/convert_to_wmts", status=200)
|
332
327
|
assert resp.json["success"]
|
333
|
-
assert
|
334
|
-
"http://localhost/admin/layers_wmts/{}?msg_col=submit_ok".format(layer.id)
|
335
|
-
== resp.json["redirect"]
|
336
|
-
)
|
328
|
+
assert f"http://localhost/admin/layers_wmts/{layer.id}?msg_col=submit_ok" == resp.json["redirect"]
|
337
329
|
|
338
330
|
resp = test_app.get(resp.json["redirect"], status=200)
|
339
331
|
assert "image/png" == resp.form["image_type"].value
|
340
332
|
|
341
333
|
layer = layer_wms_test_data["layers"][2]
|
342
|
-
resp = test_app.post("/admin/layers_wms/{}/convert_to_wmts"
|
334
|
+
resp = test_app.post(f"/admin/layers_wms/{layer.id}/convert_to_wmts", status=200)
|
343
335
|
assert resp.json["success"]
|
344
|
-
assert
|
345
|
-
"http://localhost/admin/layers_wmts/{}?msg_col=submit_ok".format(layer.id)
|
346
|
-
== resp.json["redirect"]
|
347
|
-
)
|
336
|
+
assert f"http://localhost/admin/layers_wmts/{layer.id}?msg_col=submit_ok" == resp.json["redirect"]
|
348
337
|
|
349
338
|
resp = test_app.get(resp.json["redirect"], status=200)
|
350
339
|
assert "image/jpeg" == resp.form["image_type"].value
|
@@ -354,15 +343,15 @@ class TestLayerWMSViews(AbstractViewsTests):
|
|
354
343
|
|
355
344
|
dbsession.delete(LayerWMTS.get_default(dbsession))
|
356
345
|
layer = layer_wms_test_data["layers"][3]
|
357
|
-
test_app.post("/admin/layers_wms/{}/convert_to_wmts"
|
346
|
+
test_app.post(f"/admin/layers_wms/{layer.id}/convert_to_wmts", status=200)
|
358
347
|
|
359
348
|
def test_unicity_validator(self, layer_wms_test_data, test_app):
|
360
349
|
layer = layer_wms_test_data["layers"][2]
|
361
|
-
resp = test_app.get("/admin/layers_wms/{}/duplicate"
|
350
|
+
resp = test_app.get(f"/admin/layers_wms/{layer.id}/duplicate", status=200)
|
362
351
|
|
363
352
|
resp = resp.form.submit("submit")
|
364
353
|
|
365
|
-
self._check_submission_problem(resp, "{} is already used."
|
354
|
+
self._check_submission_problem(resp, f"{layer.name} is already used.")
|
366
355
|
|
367
356
|
def test_unicity_validator_does_not_matter_amongst_cousin(self, layer_wms_test_data, test_app, dbsession):
|
368
357
|
from c2cgeoportal_commons.models.main import LayerGroup, LayerWMS
|
@@ -372,7 +361,7 @@ class TestLayerWMSViews(AbstractViewsTests):
|
|
372
361
|
assert dbsession.query(LayerWMS).filter(LayerWMS.name == "layer_group_0").one_or_none() is None
|
373
362
|
|
374
363
|
layer = layer_wms_test_data["layers"][2]
|
375
|
-
resp = test_app.get("/admin/layers_wms/{}/duplicate"
|
364
|
+
resp = test_app.get(f"/admin/layers_wms/{layer.id}/duplicate", status=200)
|
376
365
|
self.set_first_field_named(resp.form, "name", "layer_group_0")
|
377
366
|
resp = resp.form.submit("submit")
|
378
367
|
|
@@ -386,7 +375,7 @@ class TestLayerWMSViews(AbstractViewsTests):
|
|
386
375
|
|
387
376
|
layer_id = dbsession.query(LayerWMS.id).first().id
|
388
377
|
|
389
|
-
test_app.delete("/admin/layers_wms/{}"
|
378
|
+
test_app.delete(f"/admin/layers_wms/{layer_id}", status=200)
|
390
379
|
|
391
380
|
assert dbsession.query(LayerWMS).get(layer_id) is None
|
392
381
|
assert dbsession.query(Layer).get(layer_id) is None
|
@@ -417,5 +406,5 @@ class TestLayerWMSViews(AbstractViewsTests):
|
|
417
406
|
"Errors have been highlighted below" == resp.html.select_one('div[class="error-msg-detail"]').text
|
418
407
|
)
|
419
408
|
assert ["WMS layer name"] == sorted(
|
420
|
-
|
409
|
+
(x.select_one("label").text.strip()) for x in resp.html.select("[class~='has-error']")
|
421
410
|
)
|
tests/test_layers_wmts.py
CHANGED
@@ -19,12 +19,12 @@ def layer_wmts_test_data(dbsession, transact):
|
|
19
19
|
server.image_type = "image/png"
|
20
20
|
|
21
21
|
def layer_builder(i):
|
22
|
-
name = "layer_wmts_{}"
|
22
|
+
name = f"layer_wmts_{i}"
|
23
23
|
layer = LayerWMTS(name=name)
|
24
24
|
layer.layer = name
|
25
|
-
layer.url = "https:///wms.geo.admin.ch_{}.org?service=wms&request=GetCapabilities"
|
25
|
+
layer.url = f"https:///wms.geo.admin.ch_{i}.org?service=wms&request=GetCapabilities"
|
26
26
|
layer.public = 1 == i % 2
|
27
|
-
layer.geo_table = "geotable_{}"
|
27
|
+
layer.geo_table = f"geotable_{i}"
|
28
28
|
layer.image_type = "image/jpeg"
|
29
29
|
layer.style = "décontrasté"
|
30
30
|
return layer
|
@@ -121,11 +121,11 @@ class TestLayerWMTS(AbstractViewsTests):
|
|
121
121
|
assert str(layer.image_type or "") == form["image_type"].value
|
122
122
|
|
123
123
|
interfaces = layer_wmts_test_data["interfaces"]
|
124
|
-
assert
|
124
|
+
assert {interfaces[0].id, interfaces[2].id} == {i.id for i in layer.interfaces}
|
125
125
|
self._check_interfaces(form, interfaces, layer)
|
126
126
|
|
127
127
|
ras = layer_wmts_test_data["restrictionareas"]
|
128
|
-
assert
|
128
|
+
assert {ras[0].id, ras[2].id} == {i.id for i in layer.restrictionareas}
|
129
129
|
self._check_restrictionsareas(form, ras, layer)
|
130
130
|
|
131
131
|
new_values = {
|
@@ -148,7 +148,7 @@ class TestLayerWMTS(AbstractViewsTests):
|
|
148
148
|
|
149
149
|
resp = form.submit("submit")
|
150
150
|
assert str(layer.id) == re.match(
|
151
|
-
|
151
|
+
rf"http://localhost{self._prefix}/(.*)\?msg_col=submit_ok", resp.location
|
152
152
|
).group(1)
|
153
153
|
|
154
154
|
dbsession.expire(layer)
|
@@ -157,17 +157,15 @@ class TestLayerWMTS(AbstractViewsTests):
|
|
157
157
|
assert value == getattr(layer, key)
|
158
158
|
else:
|
159
159
|
assert str(value or "") == str(getattr(layer, key) or "")
|
160
|
-
assert
|
161
|
-
|
162
|
-
)
|
163
|
-
assert set([ras[1].id, ras[3].id]) == set([ra.id for ra in layer.restrictionareas])
|
160
|
+
assert {interfaces[1].id, interfaces[3].id} == {interface.id for interface in layer.interfaces}
|
161
|
+
assert {ras[1].id, ras[3].id} == {ra.id for ra in layer.restrictionareas}
|
164
162
|
|
165
163
|
def test_duplicate(self, layer_wmts_test_data, test_app, dbsession):
|
166
164
|
from c2cgeoportal_commons.models.main import LayerWMTS
|
167
165
|
|
168
166
|
layer = layer_wmts_test_data["layers"][3]
|
169
167
|
|
170
|
-
resp = test_app.get("/admin/layers_wmts/{}/duplicate"
|
168
|
+
resp = test_app.get(f"/admin/layers_wmts/{layer.id}/duplicate", status=200)
|
171
169
|
form = resp.form
|
172
170
|
|
173
171
|
assert "" == self.get_first_field_named(form, "id").value
|
@@ -196,7 +194,7 @@ class TestLayerWMTS(AbstractViewsTests):
|
|
196
194
|
|
197
195
|
layer_id = dbsession.query(LayerWMTS.id).first().id
|
198
196
|
|
199
|
-
test_app.delete("/admin/layers_wmts/{}"
|
197
|
+
test_app.delete(f"/admin/layers_wmts/{layer_id}", status=200)
|
200
198
|
|
201
199
|
assert dbsession.query(LayerWMTS).get(layer_id) is None
|
202
200
|
assert dbsession.query(Layer).get(layer_id) is None
|
@@ -204,11 +202,11 @@ class TestLayerWMTS(AbstractViewsTests):
|
|
204
202
|
|
205
203
|
def test_unicity_validator(self, layer_wmts_test_data, test_app):
|
206
204
|
layer = layer_wmts_test_data["layers"][2]
|
207
|
-
resp = test_app.get("/admin/layers_wmts/{}/duplicate"
|
205
|
+
resp = test_app.get(f"/admin/layers_wmts/{layer.id}/duplicate", status=200)
|
208
206
|
|
209
207
|
resp = resp.form.submit("submit")
|
210
208
|
|
211
|
-
self._check_submission_problem(resp, "{} is already used."
|
209
|
+
self._check_submission_problem(resp, f"{layer.name} is already used.")
|
212
210
|
|
213
211
|
def test_convert_common_fields_copied(self, layer_wmts_test_data, test_app, dbsession):
|
214
212
|
from c2cgeoportal_commons.models.main import LayerWMS, LayerWMTS
|
@@ -218,10 +216,8 @@ class TestLayerWMTS(AbstractViewsTests):
|
|
218
216
|
assert 0 == dbsession.query(LayerWMS).filter(LayerWMS.name == layer.name).count()
|
219
217
|
assert 1 == dbsession.query(LayerWMTS).filter(LayerWMTS.name == layer.name).count()
|
220
218
|
|
221
|
-
resp = test_app.post("/admin/layers_wmts/{}/convert_to_wms"
|
222
|
-
assert
|
223
|
-
"http://localhost/admin/layers_wms/{}?msg_col=submit_ok".format(layer.id) == resp.json["redirect"]
|
224
|
-
)
|
219
|
+
resp = test_app.post(f"/admin/layers_wmts/{layer.id}/convert_to_wms", status=200)
|
220
|
+
assert f"http://localhost/admin/layers_wms/{layer.id}?msg_col=submit_ok" == resp.json["redirect"]
|
225
221
|
|
226
222
|
assert 1 == dbsession.query(LayerWMS).filter(LayerWMS.name == layer.name).count()
|
227
223
|
assert 0 == dbsession.query(LayerWMTS).filter(LayerWMTS.name == layer.name).count()
|
@@ -256,4 +252,4 @@ class TestLayerWMTS(AbstractViewsTests):
|
|
256
252
|
|
257
253
|
dbsession.delete(LayerWMS.get_default(dbsession))
|
258
254
|
layer = layer_wmts_test_data["layers"][3]
|
259
|
-
test_app.post("/admin/layers_wmts/{}/convert_to_wms"
|
255
|
+
test_app.post(f"/admin/layers_wmts/{layer.id}/convert_to_wms", status=200)
|
tests/test_layertree.py
CHANGED
@@ -13,6 +13,7 @@ def layertree_test_data(dbsession, transact):
|
|
13
13
|
del transact
|
14
14
|
|
15
15
|
from c2cgeoportal_commons.models.main import (
|
16
|
+
Interface,
|
16
17
|
LayerGroup,
|
17
18
|
LayergroupTreeitem,
|
18
19
|
LayerWMS,
|
@@ -21,26 +22,39 @@ def layertree_test_data(dbsession, transact):
|
|
21
22
|
Theme,
|
22
23
|
)
|
23
24
|
|
25
|
+
interface1 = Interface("interface1")
|
26
|
+
dbsession.add(interface1)
|
27
|
+
interface2 = Interface("interface2")
|
28
|
+
dbsession.add(interface2)
|
29
|
+
|
24
30
|
layers_wms = []
|
25
31
|
ogc_server = OGCServer(name="ogc_server")
|
26
32
|
dbsession.add(ogc_server)
|
27
|
-
for i in range(
|
28
|
-
layer_wms = LayerWMS(name="layer_wms_{}"
|
33
|
+
for i in range(10):
|
34
|
+
layer_wms = LayerWMS(name=f"layer_wms_{i}")
|
35
|
+
if i == 1:
|
36
|
+
layer_wms.interfaces = [interface1]
|
37
|
+
elif i > 1:
|
38
|
+
layer_wms.interfaces = [interface1, interface2]
|
29
39
|
layer_wms.ogc_server = ogc_server
|
30
40
|
layers_wms.append(layer_wms)
|
31
41
|
dbsession.add(layer_wms)
|
32
42
|
|
33
43
|
layers_wmts = []
|
34
|
-
for i in range(
|
35
|
-
layer_wmts = LayerWMTS(name="layer_wmts_{}"
|
44
|
+
for i in range(10):
|
45
|
+
layer_wmts = LayerWMTS(name=f"layer_wmts_{i}")
|
46
|
+
if i == 1:
|
47
|
+
layer_wmts.interfaces = [interface1]
|
48
|
+
elif i > 1:
|
49
|
+
layer_wmts.interfaces = [interface1, interface2]
|
36
50
|
layer_wmts.url = "http://localhost/wmts"
|
37
51
|
layer_wmts.layer = layer_wmts.name
|
38
52
|
layers_wmts.append(layer_wmts)
|
39
53
|
dbsession.add(layer_wmts)
|
40
54
|
|
41
55
|
groups = []
|
42
|
-
for i in range(
|
43
|
-
group = LayerGroup(name="layer_group_{}"
|
56
|
+
for i in range(10):
|
57
|
+
group = LayerGroup(name=f"layer_group_{i}")
|
44
58
|
groups.append(group)
|
45
59
|
dbsession.add(group)
|
46
60
|
|
@@ -51,10 +65,14 @@ def layertree_test_data(dbsession, transact):
|
|
51
65
|
dbsession.add(LayergroupTreeitem(group=groups[9], item=groups[8], ordering=3))
|
52
66
|
|
53
67
|
themes = []
|
54
|
-
for i in range(
|
55
|
-
theme = Theme(name="theme_{}"
|
68
|
+
for i in range(5):
|
69
|
+
theme = Theme(name=f"theme_{i}")
|
56
70
|
themes.append(theme)
|
57
71
|
dbsession.add(theme)
|
72
|
+
if i == 1:
|
73
|
+
theme.interfaces = [interface1]
|
74
|
+
elif i > 1:
|
75
|
+
theme.interfaces = [interface1, interface2]
|
58
76
|
|
59
77
|
dbsession.add(LayergroupTreeitem(group=theme, item=groups[i], ordering=0))
|
60
78
|
dbsession.add(LayergroupTreeitem(group=theme, item=groups[i + 5], ordering=1))
|
@@ -74,6 +92,7 @@ def layertree_test_data(dbsession, transact):
|
|
74
92
|
"layers_wms": layers_wms,
|
75
93
|
"layers_wmts": layers_wmts,
|
76
94
|
"ogc_servers": [ogc_server],
|
95
|
+
"interfaces": [interface1, interface2],
|
77
96
|
}
|
78
97
|
)
|
79
98
|
|
@@ -93,13 +112,13 @@ class TestLayerTreeView(AbstractViewsTests):
|
|
93
112
|
def check_edit_action(self, test_app, nodes, table, item_id):
|
94
113
|
node = next(n for n in nodes if n["id"] == item_id)
|
95
114
|
action = next(a for a in node["actions"] if a["name"] == "edit")
|
96
|
-
assert "http://localhost/admin/{}/{}"
|
115
|
+
assert f"http://localhost/admin/{table}/{item_id}" == action["url"]
|
97
116
|
test_app.get(action["url"], status=200)
|
98
117
|
|
99
118
|
def check_unlink_action(self, test_app, nodes, group_id, item_id):
|
100
119
|
node = next(n for n in nodes if n["id"] == item_id)
|
101
120
|
action = next(a for a in node["actions"] if a["name"] == "unlink")
|
102
|
-
assert "http://localhost/admin/layertree/unlink/{}/{}"
|
121
|
+
assert f"http://localhost/admin/layertree/unlink/{group_id}/{item_id}" == action["url"]
|
103
122
|
test_app.delete(action["url"], status=200)
|
104
123
|
|
105
124
|
def check_translation(self, nodes, item):
|
@@ -111,7 +130,7 @@ class TestLayerTreeView(AbstractViewsTests):
|
|
111
130
|
node = next(n for n in nodes if n["id"] == parent_id)
|
112
131
|
action = next(a for a in node["actions"] if a["name"] == action_name)
|
113
132
|
assert label == action["label"]
|
114
|
-
assert "http://localhost/admin/{}/new?parent_id={}"
|
133
|
+
assert f"http://localhost/admin/{route_table}/new?parent_id={parent_id}" == action["url"]
|
115
134
|
|
116
135
|
form = test_app.get(action["url"], status=200).form
|
117
136
|
assert form["parent_id"].value == str(parent_id)
|
@@ -150,12 +169,26 @@ class TestLayerTreeView(AbstractViewsTests):
|
|
150
169
|
{"name": "new_name_from_layer_group"},
|
151
170
|
)
|
152
171
|
|
153
|
-
def test_groups(self, test_app, layertree_test_data):
|
172
|
+
def test_groups(self, test_app, layertree_test_data, dbsession):
|
154
173
|
theme = layertree_test_data["themes"][0]
|
174
|
+
|
175
|
+
# Invert children order (to test ordering)
|
176
|
+
theme.children_relation[0].ordering = 1
|
177
|
+
theme.children_relation[1].ordering = 0
|
178
|
+
dbsession.flush()
|
179
|
+
|
155
180
|
resp = self.get(test_app, "/children?group_id={0}&path=_{0}".format(theme.id), status=200)
|
156
181
|
nodes = resp.json
|
157
182
|
assert 2 == len(nodes)
|
158
183
|
|
184
|
+
# check groups are sorted by ordering
|
185
|
+
expected = [
|
186
|
+
relation.treeitem.name
|
187
|
+
for relation in sorted(theme.children_relation, key=lambda relation: relation.ordering)
|
188
|
+
]
|
189
|
+
group_names = [node["name"] for node in nodes]
|
190
|
+
assert expected == group_names
|
191
|
+
|
159
192
|
group = layertree_test_data["groups"][0]
|
160
193
|
self.check_edit_action(test_app, nodes, "layer_groups", group.id)
|
161
194
|
self.check_unlink_action(test_app, nodes, theme.id, group.id)
|
@@ -186,15 +219,29 @@ class TestLayerTreeView(AbstractViewsTests):
|
|
186
219
|
},
|
187
220
|
)
|
188
221
|
|
189
|
-
def test_layers(self, test_app, layertree_test_data):
|
222
|
+
def test_layers(self, test_app, layertree_test_data, dbsession):
|
190
223
|
theme = layertree_test_data["themes"][0]
|
191
224
|
group = layertree_test_data["groups"][0]
|
225
|
+
|
226
|
+
# Invert children order (to test ordering)
|
227
|
+
group.children_relation[0].ordering = 1
|
228
|
+
group.children_relation[1].ordering = 0
|
229
|
+
dbsession.flush()
|
230
|
+
|
192
231
|
resp = self.get(
|
193
232
|
test_app, "/children?group_id={0}&path=_{1}_{0}".format(group.id, theme.id), status=200
|
194
233
|
)
|
195
234
|
nodes = resp.json
|
196
235
|
assert len(nodes) == 2
|
197
236
|
|
237
|
+
# check layers are sorted by ordering
|
238
|
+
expected = [
|
239
|
+
relation.treeitem.name
|
240
|
+
for relation in sorted(group.children_relation, key=lambda relation: relation.ordering)
|
241
|
+
]
|
242
|
+
layer_names = [node["name"] for node in nodes]
|
243
|
+
assert expected == layer_names
|
244
|
+
|
198
245
|
layer_wms = layertree_test_data["layers_wms"][0]
|
199
246
|
layer_wmts = layertree_test_data["layers_wmts"][0]
|
200
247
|
|
@@ -210,7 +257,7 @@ class TestLayerTreeView(AbstractViewsTests):
|
|
210
257
|
def test_unlink(self, test_app, layertree_test_data, dbsession):
|
211
258
|
group = layertree_test_data["groups"][0]
|
212
259
|
item = layertree_test_data["layers_wms"][0]
|
213
|
-
test_app.delete("/admin/layertree/unlink/{}/{
|
260
|
+
test_app.delete(f"/admin/layertree/unlink/{group.id}/{item.id}", status=200)
|
214
261
|
dbsession.expire_all()
|
215
262
|
assert item not in group.children
|
216
263
|
|
@@ -226,5 +273,42 @@ class TestLayerTreeView(AbstractViewsTests):
|
|
226
273
|
(layers_wms[1].id, LayerWMS),
|
227
274
|
(groups[1].id, LayerGroup),
|
228
275
|
):
|
229
|
-
test_app.delete("/admin/layertree/delete/{}"
|
276
|
+
test_app.delete(f"/admin/layertree/delete/{item_id}", status=200)
|
230
277
|
assert dbsession.query(model).get(item_id) is None
|
278
|
+
|
279
|
+
@pytest.mark.parametrize(
|
280
|
+
"params,expected",
|
281
|
+
[
|
282
|
+
({}, ["theme_0", "theme_3", "theme_1", "theme_2", "theme_4"]),
|
283
|
+
({"interface": "interface1"}, ["theme_3", "theme_1", "theme_2", "theme_4"]),
|
284
|
+
({"interface": "interface2"}, ["theme_3", "theme_2", "theme_4"]),
|
285
|
+
],
|
286
|
+
)
|
287
|
+
def test_themes_interfaces(self, test_app, layertree_test_data, params, expected):
|
288
|
+
resp = self.get(test_app, "/children", status=200, params=params)
|
289
|
+
nodes = resp.json
|
290
|
+
assert expected == [node["name"] for node in nodes if node["item_type"] == "theme"]
|
291
|
+
|
292
|
+
@pytest.mark.parametrize(
|
293
|
+
"interface,index,length",
|
294
|
+
[
|
295
|
+
(None, 0, 2),
|
296
|
+
(None, 1, 2),
|
297
|
+
(None, 2, 2),
|
298
|
+
("interface1", 0, 0),
|
299
|
+
("interface1", 1, 2),
|
300
|
+
("interface1", 2, 2),
|
301
|
+
("interface2", 0, 0),
|
302
|
+
("interface2", 1, 0),
|
303
|
+
("interface2", 2, 2),
|
304
|
+
],
|
305
|
+
)
|
306
|
+
def test_layers_interface(self, test_app, layertree_test_data, interface, index, length):
|
307
|
+
theme = layertree_test_data["themes"][index]
|
308
|
+
group = layertree_test_data["groups"][index]
|
309
|
+
params = {"group_id": group.id, "path": f"_{theme.id}_{group.id}"}
|
310
|
+
if interface:
|
311
|
+
params["interface"] = interface
|
312
|
+
resp = self.get(test_app, "/children", status=200, params=params)
|
313
|
+
nodes = resp.json
|
314
|
+
assert length == len(nodes)
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
# Copyright (c) 2022, Camptocamp SA
|
4
|
+
# All rights reserved.
|
5
|
+
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
8
|
+
|
9
|
+
# 1. Redistributions of source code must retain the above copyright notice, this
|
10
|
+
# list of conditions and the following disclaimer.
|
11
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer in the documentation
|
13
|
+
# and/or other materials provided with the distribution.
|
14
|
+
|
15
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
16
|
+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
17
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
19
|
+
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
20
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
21
|
+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
22
|
+
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
23
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
24
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
25
|
+
|
26
|
+
# The views and conclusions contained in the software and documentation are those
|
27
|
+
# of the authors and should not be interpreted as representing official policies,
|
28
|
+
# either expressed or implied, of the FreeBSD Project.
|
29
|
+
|
30
|
+
# pylint: disable=missing-docstring
|
31
|
+
|
32
|
+
from unittest.mock import Mock, mock_open, patch
|
33
|
+
|
34
|
+
import pytest
|
35
|
+
import yaml
|
36
|
+
from c2c.template.config import config as configuration
|
37
|
+
|
38
|
+
from c2cgeoportal_admin.lib.lingua_extractor import GeomapfishConfigExtractor
|
39
|
+
|
40
|
+
GMF_CONFIG = """
|
41
|
+
vars:
|
42
|
+
admin_interface:
|
43
|
+
available_metadata:
|
44
|
+
- name: metadata1
|
45
|
+
description: description1
|
46
|
+
translate: true
|
47
|
+
available_functionalities:
|
48
|
+
- name: functionality1
|
49
|
+
description: description2
|
50
|
+
"""
|
51
|
+
|
52
|
+
|
53
|
+
class TestGeomapfishConfigExtractor:
|
54
|
+
@patch(
|
55
|
+
"c2cgeoportal_admin.lib.lingua_extractor.open",
|
56
|
+
mock_open(read_data=GMF_CONFIG),
|
57
|
+
)
|
58
|
+
def test_extract_config(self):
|
59
|
+
extractor = GeomapfishConfigExtractor()
|
60
|
+
|
61
|
+
options = Mock()
|
62
|
+
options.keywords = []
|
63
|
+
|
64
|
+
messages = list(extractor("config.yaml", options))
|
65
|
+
|
66
|
+
assert {msg.msgid for msg in messages} == {"description1", "description2"}
|
tests/test_main.py
CHANGED
@@ -5,7 +5,9 @@ from webtest import TestApp as WebTestApp
|
|
5
5
|
|
6
6
|
@pytest.mark.usefixtures("app_env")
|
7
7
|
def test_main(app_env):
|
8
|
-
"""
|
8
|
+
"""
|
9
|
+
Test dev environment.
|
10
|
+
"""
|
9
11
|
config = testing.setUp(registry=app_env["registry"])
|
10
12
|
app = config.make_wsgi_app()
|
11
13
|
testapp = WebTestApp(app)
|