c2cgeoportal-admin 2.5.0.100__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.
Files changed (91) hide show
  1. c2cgeoportal_admin/__init__.py +19 -12
  2. c2cgeoportal_admin/lib/__init__.py +0 -0
  3. c2cgeoportal_admin/lib/lingua_extractor.py +77 -0
  4. c2cgeoportal_admin/lib/ogcserver_synchronizer.py +409 -0
  5. c2cgeoportal_admin/py.typed +0 -0
  6. c2cgeoportal_admin/routes.py +18 -10
  7. c2cgeoportal_admin/schemas/dimensions.py +13 -11
  8. c2cgeoportal_admin/schemas/functionalities.py +63 -22
  9. c2cgeoportal_admin/schemas/interfaces.py +23 -19
  10. c2cgeoportal_admin/schemas/metadata.py +121 -47
  11. c2cgeoportal_admin/schemas/restriction_areas.py +22 -20
  12. c2cgeoportal_admin/schemas/roles.py +8 -6
  13. c2cgeoportal_admin/schemas/treegroup.py +84 -18
  14. c2cgeoportal_admin/schemas/treeitem.py +2 -3
  15. c2cgeoportal_admin/static/layertree.css +26 -4
  16. c2cgeoportal_admin/static/navbar.css +59 -36
  17. c2cgeoportal_admin/static/theme.css +48 -11
  18. c2cgeoportal_admin/subscribers.py +3 -3
  19. c2cgeoportal_admin/templates/404.jinja2 +23 -0
  20. c2cgeoportal_admin/templates/edit.jinja2 +23 -0
  21. c2cgeoportal_admin/templates/home.jinja2 +23 -0
  22. c2cgeoportal_admin/templates/index.jinja2 +23 -0
  23. c2cgeoportal_admin/templates/layertree.jinja2 +55 -11
  24. c2cgeoportal_admin/templates/layout.jinja2 +23 -0
  25. c2cgeoportal_admin/templates/navigation_navbar.jinja2 +56 -0
  26. c2cgeoportal_admin/templates/ogcserver_synchronize.jinja2 +90 -0
  27. c2cgeoportal_admin/templates/widgets/child.pt +35 -3
  28. c2cgeoportal_admin/templates/widgets/children.pt +121 -92
  29. c2cgeoportal_admin/templates/widgets/dimension.pt +23 -0
  30. c2cgeoportal_admin/templates/widgets/dimensions.pt +23 -0
  31. c2cgeoportal_admin/templates/widgets/functionality_fields.pt +51 -0
  32. c2cgeoportal_admin/templates/widgets/layer_fields.pt +23 -0
  33. c2cgeoportal_admin/templates/widgets/layer_group_fields.pt +23 -0
  34. c2cgeoportal_admin/templates/widgets/layer_v1_fields.pt +23 -0
  35. c2cgeoportal_admin/templates/widgets/metadata.pt +30 -1
  36. c2cgeoportal_admin/templates/widgets/metadatas.pt +23 -0
  37. c2cgeoportal_admin/templates/widgets/ogcserver_fields.pt +23 -0
  38. c2cgeoportal_admin/templates/widgets/restriction_area_fields.pt +25 -9
  39. c2cgeoportal_admin/templates/widgets/role_fields.pt +52 -25
  40. c2cgeoportal_admin/templates/widgets/theme_fields.pt +23 -0
  41. c2cgeoportal_admin/templates/widgets/user_fields.pt +23 -0
  42. c2cgeoportal_admin/views/dimension_layers.py +7 -6
  43. c2cgeoportal_admin/views/functionalities.py +31 -5
  44. c2cgeoportal_admin/views/home.py +5 -5
  45. c2cgeoportal_admin/views/interfaces.py +8 -8
  46. c2cgeoportal_admin/views/layer_groups.py +9 -11
  47. c2cgeoportal_admin/views/layers.py +8 -7
  48. c2cgeoportal_admin/views/layers_vectortiles.py +30 -10
  49. c2cgeoportal_admin/views/layers_wms.py +45 -37
  50. c2cgeoportal_admin/views/layers_wmts.py +39 -33
  51. c2cgeoportal_admin/views/layertree.py +34 -26
  52. c2cgeoportal_admin/views/oauth2_clients.py +89 -0
  53. c2cgeoportal_admin/views/ogc_servers.py +130 -27
  54. c2cgeoportal_admin/views/restriction_areas.py +50 -8
  55. c2cgeoportal_admin/views/roles.py +60 -8
  56. c2cgeoportal_admin/views/themes.py +15 -14
  57. c2cgeoportal_admin/views/themes_ordering.py +38 -18
  58. c2cgeoportal_admin/views/treeitems.py +12 -11
  59. c2cgeoportal_admin/views/users.py +7 -5
  60. c2cgeoportal_admin/widgets.py +79 -28
  61. {c2cgeoportal_admin-2.5.0.100.dist-info → c2cgeoportal_admin-2.7.1.156.dist-info}/METADATA +16 -11
  62. c2cgeoportal_admin-2.7.1.156.dist-info/RECORD +92 -0
  63. {c2cgeoportal_admin-2.5.0.100.dist-info → c2cgeoportal_admin-2.7.1.156.dist-info}/WHEEL +1 -1
  64. c2cgeoportal_admin-2.7.1.156.dist-info/entry_points.txt +5 -0
  65. tests/__init__.py +23 -18
  66. tests/conftest.py +4 -15
  67. tests/test_edit_url.py +16 -18
  68. tests/test_functionalities.py +23 -10
  69. tests/test_interface.py +8 -8
  70. tests/test_layer_groups.py +15 -23
  71. tests/test_layers_vectortiles.py +16 -20
  72. tests/test_layers_wms.py +37 -75
  73. tests/test_layers_wmts.py +20 -24
  74. tests/test_layertree.py +107 -100
  75. tests/test_learn.py +1 -1
  76. tests/test_lingua_extractor_config.py +66 -0
  77. tests/test_main.py +4 -2
  78. tests/test_metadatas.py +79 -70
  79. tests/test_oauth2_clients.py +157 -0
  80. tests/test_ogc_servers.py +51 -7
  81. tests/test_restriction_areas.py +81 -17
  82. tests/test_role.py +110 -76
  83. tests/test_themes.py +44 -37
  84. tests/test_themes_ordering.py +1 -1
  85. tests/test_treegroup.py +2 -2
  86. tests/test_user.py +31 -64
  87. tests/themes_ordering.py +1 -1
  88. c2cgeoportal_admin/templates/navigation_vertical.jinja2 +0 -10
  89. c2cgeoportal_admin-2.5.0.100.dist-info/RECORD +0 -84
  90. c2cgeoportal_admin-2.5.0.100.dist-info/entry_points.txt +0 -3
  91. {c2cgeoportal_admin-2.5.0.100.dist-info → c2cgeoportal_admin-2.7.1.156.dist-info}/top_level.txt +0 -0
tests/test_layers_wmts.py CHANGED
@@ -19,22 +19,22 @@ 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_{}".format(i)
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".format(i)
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_{}".format(i)
27
+ layer.geo_table = f"geotable_{i}"
28
28
  layer.image_type = "image/jpeg"
29
29
  layer.style = "décontrasté"
30
30
  return layer
31
31
 
32
- datas = factory_build_layers(layer_builder, dbsession)
33
- datas["default"] = get_test_default_layers(dbsession, server)
32
+ data = factory_build_layers(layer_builder, dbsession)
33
+ data["default"] = get_test_default_layers(dbsession, server)
34
34
 
35
35
  dbsession.flush()
36
36
 
37
- yield datas
37
+ yield data
38
38
 
39
39
 
40
40
  @pytest.mark.usefixtures("layer_wmts_test_data", "test_app")
@@ -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 set((interfaces[0].id, interfaces[2].id)) == set(i.id for i in layer.interfaces)
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 set((ras[0].id, ras[2].id)) == set(i.id for i in layer.restrictionareas)
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
- r"http://localhost{}/(.*)\?msg_col=submit_ok".format(self._prefix), resp.location
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 set([interfaces[1].id, interfaces[3].id]) == set(
161
- [interface.id for interface in layer.interfaces]
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".format(layer.id), status=200)
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
@@ -192,11 +190,11 @@ class TestLayerWMTS(AbstractViewsTests):
192
190
  ).group(1)
193
191
 
194
192
  def test_delete(self, test_app, dbsession):
195
- from c2cgeoportal_commons.models.main import LayerWMTS, Layer, TreeItem
193
+ from c2cgeoportal_commons.models.main import Layer, LayerWMTS, TreeItem
196
194
 
197
195
  layer_id = dbsession.query(LayerWMTS.id).first().id
198
196
 
199
- test_app.delete("/admin/layers_wmts/{}".format(layer_id), status=200)
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,24 +202,22 @@ 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".format(layer.id), status=200)
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.".format(layer.name))
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
- from c2cgeoportal_commons.models.main import LayerWMTS, LayerWMS
212
+ from c2cgeoportal_commons.models.main import LayerWMS, LayerWMTS
215
213
 
216
214
  layer = layer_wmts_test_data["layers"][3]
217
215
 
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".format(layer.id), status=200)
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".format(layer.id), status=200)
255
+ test_app.post(f"/admin/layers_wmts/{layer.id}/convert_to_wms", status=200)
tests/test_layertree.py CHANGED
@@ -3,10 +3,8 @@
3
3
  from unittest.mock import patch
4
4
 
5
5
  import pytest
6
- from selenium.common.exceptions import NoSuchElementException
7
6
 
8
- from . import AbstractViewsTests, skip_if_ci
9
- from .selenium.page import LayertreePage
7
+ from . import AbstractViewsTests
10
8
 
11
9
 
12
10
  @pytest.fixture(scope="function")
@@ -15,6 +13,7 @@ def layertree_test_data(dbsession, transact):
15
13
  del transact
16
14
 
17
15
  from c2cgeoportal_commons.models.main import (
16
+ Interface,
18
17
  LayerGroup,
19
18
  LayergroupTreeitem,
20
19
  LayerWMS,
@@ -23,26 +22,39 @@ def layertree_test_data(dbsession, transact):
23
22
  Theme,
24
23
  )
25
24
 
25
+ interface1 = Interface("interface1")
26
+ dbsession.add(interface1)
27
+ interface2 = Interface("interface2")
28
+ dbsession.add(interface2)
29
+
26
30
  layers_wms = []
27
31
  ogc_server = OGCServer(name="ogc_server")
28
32
  dbsession.add(ogc_server)
29
- for i in range(0, 10):
30
- layer_wms = LayerWMS(name="layer_wms_{}".format(i))
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]
31
39
  layer_wms.ogc_server = ogc_server
32
40
  layers_wms.append(layer_wms)
33
41
  dbsession.add(layer_wms)
34
42
 
35
43
  layers_wmts = []
36
- for i in range(0, 10):
37
- layer_wmts = LayerWMTS(name="layer_wmts_{}".format(i))
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]
38
50
  layer_wmts.url = "http://localhost/wmts"
39
51
  layer_wmts.layer = layer_wmts.name
40
52
  layers_wmts.append(layer_wmts)
41
53
  dbsession.add(layer_wmts)
42
54
 
43
55
  groups = []
44
- for i in range(0, 10):
45
- group = LayerGroup(name="layer_group_{}".format(i))
56
+ for i in range(10):
57
+ group = LayerGroup(name=f"layer_group_{i}")
46
58
  groups.append(group)
47
59
  dbsession.add(group)
48
60
 
@@ -53,10 +65,14 @@ def layertree_test_data(dbsession, transact):
53
65
  dbsession.add(LayergroupTreeitem(group=groups[9], item=groups[8], ordering=3))
54
66
 
55
67
  themes = []
56
- for i in range(0, 5):
57
- theme = Theme(name="theme_{}".format(i))
68
+ for i in range(5):
69
+ theme = Theme(name=f"theme_{i}")
58
70
  themes.append(theme)
59
71
  dbsession.add(theme)
72
+ if i == 1:
73
+ theme.interfaces = [interface1]
74
+ elif i > 1:
75
+ theme.interfaces = [interface1, interface2]
60
76
 
61
77
  dbsession.add(LayergroupTreeitem(group=theme, item=groups[i], ordering=0))
62
78
  dbsession.add(LayergroupTreeitem(group=theme, item=groups[i + 5], ordering=1))
@@ -76,6 +92,7 @@ def layertree_test_data(dbsession, transact):
76
92
  "layers_wms": layers_wms,
77
93
  "layers_wmts": layers_wmts,
78
94
  "ogc_servers": [ogc_server],
95
+ "interfaces": [interface1, interface2],
79
96
  }
80
97
  )
81
98
 
@@ -95,13 +112,13 @@ class TestLayerTreeView(AbstractViewsTests):
95
112
  def check_edit_action(self, test_app, nodes, table, item_id):
96
113
  node = next(n for n in nodes if n["id"] == item_id)
97
114
  action = next(a for a in node["actions"] if a["name"] == "edit")
98
- assert "http://localhost/admin/{}/{}".format(table, item_id) == action["url"]
115
+ assert f"http://localhost/admin/{table}/{item_id}" == action["url"]
99
116
  test_app.get(action["url"], status=200)
100
117
 
101
118
  def check_unlink_action(self, test_app, nodes, group_id, item_id):
102
119
  node = next(n for n in nodes if n["id"] == item_id)
103
120
  action = next(a for a in node["actions"] if a["name"] == "unlink")
104
- assert "http://localhost/admin/layertree/unlink/{}/{}".format(group_id, item_id) == action["url"]
121
+ assert f"http://localhost/admin/layertree/unlink/{group_id}/{item_id}" == action["url"]
105
122
  test_app.delete(action["url"], status=200)
106
123
 
107
124
  def check_translation(self, nodes, item):
@@ -113,7 +130,7 @@ class TestLayerTreeView(AbstractViewsTests):
113
130
  node = next(n for n in nodes if n["id"] == parent_id)
114
131
  action = next(a for a in node["actions"] if a["name"] == action_name)
115
132
  assert label == action["label"]
116
- assert "http://localhost/admin/{}/new?parent_id={}".format(route_table, parent_id) == action["url"]
133
+ assert f"http://localhost/admin/{route_table}/new?parent_id={parent_id}" == action["url"]
117
134
 
118
135
  form = test_app.get(action["url"], status=200).form
119
136
  assert form["parent_id"].value == str(parent_id)
@@ -152,12 +169,26 @@ class TestLayerTreeView(AbstractViewsTests):
152
169
  {"name": "new_name_from_layer_group"},
153
170
  )
154
171
 
155
- def test_groups(self, test_app, layertree_test_data):
172
+ def test_groups(self, test_app, layertree_test_data, dbsession):
156
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
+
157
180
  resp = self.get(test_app, "/children?group_id={0}&path=_{0}".format(theme.id), status=200)
158
181
  nodes = resp.json
159
182
  assert 2 == len(nodes)
160
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
+
161
192
  group = layertree_test_data["groups"][0]
162
193
  self.check_edit_action(test_app, nodes, "layer_groups", group.id)
163
194
  self.check_unlink_action(test_app, nodes, theme.id, group.id)
@@ -188,15 +219,29 @@ class TestLayerTreeView(AbstractViewsTests):
188
219
  },
189
220
  )
190
221
 
191
- def test_layers(self, test_app, layertree_test_data):
222
+ def test_layers(self, test_app, layertree_test_data, dbsession):
192
223
  theme = layertree_test_data["themes"][0]
193
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
+
194
231
  resp = self.get(
195
232
  test_app, "/children?group_id={0}&path=_{1}_{0}".format(group.id, theme.id), status=200
196
233
  )
197
234
  nodes = resp.json
198
235
  assert len(nodes) == 2
199
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
+
200
245
  layer_wms = layertree_test_data["layers_wms"][0]
201
246
  layer_wmts = layertree_test_data["layers_wmts"][0]
202
247
 
@@ -212,96 +257,58 @@ class TestLayerTreeView(AbstractViewsTests):
212
257
  def test_unlink(self, test_app, layertree_test_data, dbsession):
213
258
  group = layertree_test_data["groups"][0]
214
259
  item = layertree_test_data["layers_wms"][0]
215
- test_app.delete("/admin/layertree/unlink/{}/{}".format(group.id, item.id), status=200)
260
+ test_app.delete(f"/admin/layertree/unlink/{group.id}/{item.id}", status=200)
216
261
  dbsession.expire_all()
217
262
  assert item not in group.children
218
263
 
264
+ def test_delete(self, test_app, layertree_test_data, dbsession):
265
+ from c2cgeoportal_commons.models.main import LayerGroup, LayerWMS, LayerWMTS
219
266
 
220
- @skip_if_ci
221
- @pytest.mark.selenium
222
- @pytest.mark.usefixtures("selenium", "selenium_app", "layertree_test_data")
223
- class TestLayerTreeSelenium:
224
-
225
- _prefix = "/layertree"
226
-
227
- def test_unlink(self, dbsession, selenium, selenium_app, layertree_test_data):
228
- from c2cgeoportal_commons.models.main import LayergroupTreeitem
229
-
230
- themes = layertree_test_data["themes"]
231
- groups = layertree_test_data["groups"]
232
- layers_wms = layertree_test_data["layers_wms"]
233
- layers_wmts = layertree_test_data["layers_wmts"]
234
-
235
- selenium.get(selenium_app + self._prefix)
236
- page = LayertreePage(selenium)
237
- page.expand()
238
-
239
- for group_id, item_id, path in (
240
- (
241
- groups[0].id,
242
- layers_wmts[0].id,
243
- "_{}_{}_{}".format(themes[0].id, groups[0].id, layers_wmts[0].id),
244
- ),
245
- (
246
- groups[0].id,
247
- layers_wms[0].id,
248
- "_{}_{}_{}".format(themes[0].id, groups[0].id, layers_wms[0].id),
249
- ),
250
- (themes[0].id, groups[0].id, "_{}_{}".format(themes[0].id, groups[0].id)),
251
- ):
252
- action_el = page.find_item_action(path, "unlink", 10)
253
- expected_url = "{}/layertree/unlink/{}/{}".format(selenium_app, group_id, item_id)
254
- assert expected_url == action_el.get_attribute("data-url")
255
- page.click_and_confirm(action_el)
256
-
257
- dbsession.expire_all()
258
- link = (
259
- dbsession.query(LayergroupTreeitem)
260
- .filter(LayergroupTreeitem.treegroup_id == group_id)
261
- .filter(LayergroupTreeitem.treeitem_id == item_id)
262
- .one_or_none()
263
- )
264
- assert link is None
265
-
266
- selenium.refresh()
267
- page.wait_jquery_to_be_active()
268
- page.find_item("_{}_{}_{}".format(themes[0].id, groups[5].id, layers_wmts[5].id), 10)
269
- with pytest.raises(NoSuchElementException):
270
- page.find_item(path)
271
-
272
- @skip_if_ci
273
- @pytest.mark.selenium
274
- @pytest.mark.usefixtures("selenium", "selenium_app")
275
- def test_delete(self, dbsession, selenium, selenium_app, layertree_test_data):
276
- from c2cgeoportal_commons.models.main import LayerWMS, LayerWMTS, LayerGroup
277
-
278
- themes = layertree_test_data["themes"]
279
267
  groups = layertree_test_data["groups"]
280
268
  layers_wms = layertree_test_data["layers_wms"]
281
269
  layers_wmts = layertree_test_data["layers_wmts"]
282
270
 
283
- selenium.get(selenium_app + self._prefix)
284
- page = LayertreePage(selenium)
285
- page.expand()
286
-
287
- for item_id, path, model in (
288
- (layers_wmts[1].id, "_{}_{}_{}".format(themes[1].id, groups[1].id, layers_wmts[1].id), LayerWMTS),
289
- (layers_wms[1].id, "_{}_{}_{}".format(themes[1].id, groups[1].id, layers_wms[1].id), LayerWMS),
290
- (groups[1].id, "_{}_{}".format(themes[1].id, groups[1].id), LayerGroup),
271
+ for item_id, model in (
272
+ (layers_wmts[1].id, LayerWMTS),
273
+ (layers_wms[1].id, LayerWMS),
274
+ (groups[1].id, LayerGroup),
291
275
  ):
292
- action_el = page.find_item_action(path, "delete", 10)
293
- expected_url = "{}/admin/layertree/delete/{}".format(selenium_app, item_id)
294
- assert expected_url == action_el.get_attribute("data-url")
295
- page.click_and_confirm(action_el)
296
- page.wait_jquery_to_be_active()
297
-
298
- deleted = dbsession.query(model).filter(model.id == item_id).one_or_none()
299
- assert deleted is None
300
-
301
- dbsession.expire_all()
302
- selenium.refresh()
303
- page.wait_jquery_to_be_active()
304
-
305
- page.find_item("_{}_{}_{}".format(themes[1].id, groups[6].id, layers_wmts[6].id), 10)
306
- with pytest.raises(NoSuchElementException):
307
- page.find_item(path)
276
+ test_app.delete(f"/admin/layertree/delete/{item_id}", status=200)
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)
tests/test_learn.py CHANGED
@@ -1,7 +1,7 @@
1
1
  # pylint: disable=no-self-use
2
2
 
3
- from pyramid.view import view_config
4
3
  import pytest
4
+ from pyramid.view import view_config
5
5
 
6
6
 
7
7
  @pytest.fixture(scope="class")
@@ -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
@@ -1,11 +1,13 @@
1
- from pyramid import testing
2
1
  import pytest
2
+ from pyramid import testing
3
3
  from webtest import TestApp as WebTestApp
4
4
 
5
5
 
6
6
  @pytest.mark.usefixtures("app_env")
7
7
  def test_main(app_env):
8
- """Test dev environment"""
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)