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_role.py CHANGED
@@ -3,14 +3,12 @@
3
3
  import json
4
4
  import re
5
5
 
6
+ import pytest
6
7
  from geoalchemy2.shape import from_shape, to_shape
7
8
  from pyramid.testing import DummyRequest
8
- import pytest
9
- from selenium.webdriver.common.by import By
10
9
  from shapely.geometry import Polygon, box, shape
11
10
 
12
- from . import AbstractViewsTests, skip_if_ci
13
- from .selenium.page import IndexPage
11
+ from .test_treegroup import TestTreeGroup
14
12
 
15
13
 
16
14
  @pytest.fixture(scope="function")
@@ -18,20 +16,21 @@ from .selenium.page import IndexPage
18
16
  def roles_test_data(dbsession, transact):
19
17
  del transact
20
18
 
21
- from c2cgeoportal_commons.models.main import Role, Functionality, RestrictionArea
19
+ from c2cgeoportal_commons.models.main import Functionality, RestrictionArea, Role
22
20
  from c2cgeoportal_commons.models.static import User
23
21
 
22
+ # Note that "default_basemap" is not relevant for roles
24
23
  functionalities = {}
25
- for name in ("default_basemap", "location"):
24
+ for name in ("default_basemap", "default_theme", "print_template"):
26
25
  functionalities[name] = []
27
26
  for v in range(0, 4):
28
- functionality = Functionality(name=name, value="value_{}".format(v))
27
+ functionality = Functionality(name=name, value=f"value_{v}")
29
28
  dbsession.add(functionality)
30
29
  functionalities[name].append(functionality)
31
30
 
32
31
  restrictionareas = []
33
32
  for i in range(0, 5):
34
- restrictionarea = RestrictionArea(name="restrictionarea_{}".format(i))
33
+ restrictionarea = RestrictionArea(name=f"restrictionarea_{i}")
35
34
  dbsession.add(restrictionarea)
36
35
  restrictionareas.append(restrictionarea)
37
36
 
@@ -39,9 +38,9 @@ def roles_test_data(dbsession, transact):
39
38
  for i in range(0, 23):
40
39
  role = Role("secretary_" + str(i))
41
40
  role.functionalities = [
42
- functionalities["default_basemap"][0],
43
- functionalities["location"][0],
44
- functionalities["location"][1],
41
+ functionalities["default_theme"][0],
42
+ functionalities["print_template"][0],
43
+ functionalities["print_template"][1],
45
44
  ]
46
45
  role.restrictionareas = [restrictionareas[0], restrictionareas[1]]
47
46
  role.extent = from_shape(box(485869.5728, 76443.1884, 837076.5648, 299941.7864), srid=21781)
@@ -68,7 +67,7 @@ def roles_test_data(dbsession, transact):
68
67
 
69
68
 
70
69
  @pytest.mark.usefixtures("roles_test_data", "test_app")
71
- class TestRole(AbstractViewsTests):
70
+ class TestRole(TestTreeGroup):
72
71
 
73
72
  _prefix = "/admin/roles"
74
73
 
@@ -87,24 +86,80 @@ class TestRole(AbstractViewsTests):
87
86
  ]
88
87
  self.check_grid_headers(resp, expected)
89
88
 
90
- @pytest.mark.skip(reason="Translation is not finished")
89
+ @pytest.mark.skip(reason="Translation seems not available in tests")
91
90
  def test_index_rendering_fr(self, test_app):
92
91
  resp = self.get(test_app, locale="fr")
93
92
 
94
- self.check_left_menu(resp, "Roles")
93
+ self.check_left_menu(resp, "Rôles")
95
94
 
96
95
  expected = [
97
- ("_id_", "", "false"),
98
- ("name", "Name"),
96
+ ("actions", "", "false"),
97
+ ("id", "id", "true"),
98
+ ("name", "Nom"),
99
99
  ("description", "Description"),
100
- ("functionalities", "Fonctionalités", "false"),
101
- ("restrictionareas", "Aires de restriction", "false"),
100
+ ("functionalities", "Fonctionnalités", "false"),
101
+ ("restrictionareas", "Zones de restriction", "false"),
102
102
  ]
103
- self.check_grid_headers(resp, expected)
103
+ self.check_grid_headers(resp, expected, new="Nouveau")
104
+
105
+ def test_submit_new(self, dbsession, test_app, roles_test_data):
106
+ from c2cgeoportal_commons.models.main import Role
107
+
108
+ roles = roles_test_data["roles"]
109
+ functionalities = roles_test_data["functionalities"]
110
+ restrictionareas = roles_test_data["restrictionareas"]
111
+ users = roles_test_data["users"]
112
+
113
+ resp = test_app.post(
114
+ "/admin/roles/new",
115
+ (
116
+ ("_charset_", "UTF-8"),
117
+ ("__formid__", "deform"),
118
+ ("id", ""),
119
+ ("name", "new_name"),
120
+ ("description", "new_description"),
121
+ ("extent", ""),
122
+ ("__start__", "functionalities:sequence"),
123
+ ("functionalities", str(functionalities["default_basemap"][0].id)),
124
+ ("functionalities", str(functionalities["print_template"][1].id)),
125
+ ("__end__", "functionalities:sequence"),
126
+ ("__start__", "restrictionareas:sequence"),
127
+ ("restrictionareas", str(restrictionareas[0].id)),
128
+ ("restrictionareas", str(restrictionareas[1].id)),
129
+ ("__end__", "restrictionareas:sequence"),
130
+ ("__start__", "users:sequence"),
131
+ ("__start__", "user:mapping"),
132
+ ("id", str(users[0].id)),
133
+ ("__end__", "user:mapping"),
134
+ ("__start__", "user:mapping"),
135
+ ("id", str(users[1].id)),
136
+ ("__end__", "user:mapping"),
137
+ ("__end__", "users:sequence"),
138
+ ("formsubmit", "formsubmit"),
139
+ ),
140
+ status=302,
141
+ )
142
+
143
+ role = dbsession.query(Role).filter(Role.name == "new_name").one()
144
+ assert str(role.id) == re.match(
145
+ r"http://localhost/admin/roles/(.*)\?msg_col=submit_ok", resp.location
146
+ ).group(1)
147
+
148
+ assert role.name == "new_name"
149
+ assert role.description == "new_description"
150
+ assert set(role.functionalities) == {
151
+ functionalities["default_basemap"][0],
152
+ functionalities["print_template"][1],
153
+ }
154
+ assert set(role.restrictionareas) == {restrictionareas[0], restrictionareas[1]}
155
+ assert set(role.users) == {users[0], users[1]}
104
156
 
105
157
  def test_edit(self, dbsession, test_app, roles_test_data):
106
158
  role = roles_test_data["roles"][10]
107
159
 
160
+ # Ensure role.users is loaded with relationship "order_by"
161
+ dbsession.expire(role)
162
+
108
163
  form = self.get_item(test_app, role.id).form
109
164
 
110
165
  assert "secretary_10" == form["name"].value
@@ -121,30 +176,33 @@ class TestRole(AbstractViewsTests):
121
176
  assert expected.almost_equals(shape(json.loads(form["extent"].value)), decimal=0)
122
177
 
123
178
  functionalities = roles_test_data["functionalities"]
124
- assert set(
125
- (
126
- functionalities["default_basemap"][0].id,
127
- functionalities["location"][0].id,
128
- functionalities["location"][1].id,
129
- )
130
- ) == set(f.id for f in role.functionalities)
179
+ assert {
180
+ functionalities["default_theme"][0].id,
181
+ functionalities["print_template"][0].id,
182
+ functionalities["print_template"][1].id,
183
+ } == {f.id for f in role.functionalities}
131
184
  self.check_checkboxes(
132
185
  form,
133
186
  "functionalities",
134
187
  [
135
188
  {
136
- "label": "{}={}".format(f.name, f.value),
189
+ "label": f"{f.name}={f.value}",
137
190
  "value": str(f.id),
138
191
  "checked": f in role.functionalities,
139
192
  }
140
- for f in sum(
141
- [roles_test_data["functionalities"][name] for name in ("default_basemap", "location")], []
193
+ for f in sorted(
194
+ [
195
+ f
196
+ for f in sum(functionalities.values(), [])
197
+ if f.name in ("default_theme", "print_template")
198
+ ],
199
+ key=lambda f: (f.name, f.value),
142
200
  )
143
201
  ],
144
202
  )
145
203
 
146
204
  ras = roles_test_data["restrictionareas"]
147
- assert set((ras[0].id, ras[1].id)) == set(ra.id for ra in role.restrictionareas)
205
+ assert {ras[0].id, ras[1].id} == {ra.id for ra in role.restrictionareas}
148
206
  self.check_checkboxes(
149
207
  form,
150
208
  "restrictionareas",
@@ -154,6 +212,15 @@ class TestRole(AbstractViewsTests):
154
212
  ],
155
213
  )
156
214
 
215
+ self.check_children(
216
+ form,
217
+ "users",
218
+ [
219
+ {"label": user.username, "values": {"id": str(user.id)}}
220
+ for user in sorted(role.users, key=lambda u: u.username)
221
+ ],
222
+ )
223
+
157
224
  form["name"] = "New name"
158
225
  form["description"] = "New description"
159
226
  form["extent"] = json.dumps(
@@ -172,9 +239,9 @@ class TestRole(AbstractViewsTests):
172
239
  )
173
240
 
174
241
  functionality_ids = [
175
- roles_test_data["functionalities"]["default_basemap"][1].id,
176
- roles_test_data["functionalities"]["location"][1].id,
177
- roles_test_data["functionalities"]["default_basemap"][2].id,
242
+ roles_test_data["functionalities"]["default_theme"][1].id,
243
+ roles_test_data["functionalities"]["print_template"][1].id,
244
+ roles_test_data["functionalities"]["print_template"][2].id,
178
245
  ]
179
246
  form["functionalities"] = [str(id) for id in functionality_ids]
180
247
 
@@ -203,18 +270,18 @@ class TestRole(AbstractViewsTests):
203
270
  )
204
271
  assert expected.almost_equals(to_shape(role.extent), decimal=0)
205
272
 
206
- assert set(functionality_ids) == set([f.id for f in role.functionalities])
207
- assert set(ra_ids) == set([f.id for f in role.restrictionareas])
273
+ assert set(functionality_ids) == {f.id for f in role.functionalities}
274
+ assert set(ra_ids) == {f.id for f in role.restrictionareas}
208
275
 
209
276
  def test_duplicate(self, roles_test_data, test_app, dbsession):
210
277
  from c2cgeoportal_commons.models.main import Role
211
278
 
212
279
  role_proto = roles_test_data["roles"][7]
213
280
 
214
- resp = test_app.get("/admin/roles/{}/duplicate".format(role_proto.id), status=200)
281
+ resp = test_app.get(f"/admin/roles/{role_proto.id}/duplicate", status=200)
215
282
  form = resp.form
216
283
 
217
- assert "" == form["id"].value
284
+ assert "" == self.get_first_field_named(form, "id").value
218
285
  assert role_proto.name == form["name"].value
219
286
  assert role_proto.description == form["description"].value
220
287
  form["name"].value = "clone"
@@ -225,26 +292,24 @@ class TestRole(AbstractViewsTests):
225
292
  r"http://localhost/admin/roles/(.*)\?msg_col=submit_ok", resp.location
226
293
  ).group(1)
227
294
  assert role_proto.id != role.id
228
- assert role_proto.functionalities[2].name == role.functionalities[2].name
229
- assert role_proto.functionalities[2].value == role.functionalities[2].value
230
- assert role_proto.functionalities[2].id == role.functionalities[2].id
231
- assert role_proto.restrictionareas[1].name == role.restrictionareas[1].name
232
- assert role_proto.restrictionareas[1].id == role.restrictionareas[1].id
295
+ assert set(role_proto.functionalities) == set(role.functionalities)
296
+ assert set(role_proto.restrictionareas) == set(role.restrictionareas)
297
+ assert set(role_proto.users) == set(role.users)
233
298
 
234
299
  def test_delete(self, test_app, dbsession):
235
300
  from c2cgeoportal_commons.models.main import Role
236
301
 
237
302
  role_id = dbsession.query(Role.id).first().id
238
- test_app.delete("/admin/roles/{}".format(role_id), status=200)
303
+ test_app.delete(f"/admin/roles/{role_id}", status=200)
239
304
  assert dbsession.query(Role).get(role_id) is None
240
305
 
241
306
  def test_unicity_validator(self, roles_test_data, test_app):
242
307
  role_proto = roles_test_data["roles"][7]
243
- resp = test_app.get("/admin/roles/{}/duplicate".format(role_proto.id), status=200)
308
+ resp = test_app.get(f"/admin/roles/{role_proto.id}/duplicate", status=200)
244
309
 
245
310
  resp = resp.form.submit("submit")
246
311
 
247
- self._check_submission_problem(resp, "{} is already used.".format(role_proto.name))
312
+ self._check_submission_problem(resp, f"{role_proto.name} is already used.")
248
313
 
249
314
  @pytest.mark.usefixtures("raise_db_error_on_query")
250
315
  def test_grid_dberror(self, dbsession):
@@ -253,34 +318,3 @@ class TestRole(AbstractViewsTests):
253
318
  request = DummyRequest(dbsession=dbsession, params={"offset": 0, "limit": 10})
254
319
  info = RoleViews(request).grid()
255
320
  assert info.status_int == 500, "Expected 500 status when db error"
256
-
257
-
258
- @skip_if_ci
259
- @pytest.mark.selenium
260
- @pytest.mark.usefixtures("selenium", "selenium_app", "roles_test_data")
261
- class TestRoleSelenium:
262
-
263
- _prefix = "/admin/roles"
264
-
265
- def test_index(self, selenium, selenium_app, roles_test_data, dbsession):
266
- from c2cgeoportal_commons.models.static import Role
267
-
268
- selenium.get(selenium_app + self._prefix)
269
-
270
- index_page = IndexPage(selenium)
271
- index_page.select_language("en")
272
- index_page.check_pagination_info("Showing 1 to 23 of 23 rows", 10)
273
- index_page.select_page_size(10)
274
- index_page.check_pagination_info("Showing 1 to 10 of 23 rows", 10)
275
-
276
- # delete
277
- role = roles_test_data["roles"][3]
278
- deleted_id = role.id
279
- index_page.click_delete(deleted_id)
280
- index_page.check_pagination_info("Showing 1 to 10 of 22 rows", 10)
281
- assert dbsession.query(Role).get(deleted_id) is None
282
-
283
- # edit
284
- role = roles_test_data["roles"][4]
285
- index_page.find_item_action(role.id, "edit").click()
286
- index_page.find_element(By.XPATH, "//canvas", timeout=5)
tests/test_themes.py CHANGED
@@ -13,33 +13,38 @@ def theme_test_data(dbsession, transact):
13
13
  del transact
14
14
 
15
15
  from c2cgeoportal_commons.models.main import (
16
- Theme,
17
- Role,
18
16
  Functionality,
19
- LayergroupTreeitem,
20
17
  Interface,
21
- Metadata,
22
18
  LayerGroup,
19
+ LayergroupTreeitem,
23
20
  LayerWMS,
21
+ Metadata,
24
22
  OGCServer,
23
+ Role,
24
+ Theme,
25
25
  )
26
26
 
27
27
  interfaces = [Interface(name) for name in ["desktop", "mobile", "edit", "routing"]]
28
+ dbsession.add_all(interfaces)
28
29
 
29
- groups = [LayerGroup(name="layer_group_{}".format(i)) for i in range(0, 5)]
30
+ groups = [LayerGroup(name=f"layer_group_{i}") for i in range(0, 5)]
31
+ dbsession.add_all(groups)
30
32
 
31
33
  layer = LayerWMS(name="layer_wms")
32
34
  layer.ogc_server = OGCServer(name="server")
33
- dbsession.add(layer)
34
35
  layers = [layer]
36
+ dbsession.add_all(layers)
35
37
 
38
+ # Note that "default_theme" is not relevant for themes
36
39
  functionalities = [
37
- Functionality(name=name, value="value_{}".format(v))
38
- for name in ("default_basemap", "location")
40
+ Functionality(name=name, value=f"value_{v}")
41
+ for name in ("default_basemap", "default_theme")
39
42
  for v in range(0, 4)
40
43
  ]
44
+ dbsession.add_all(functionalities)
41
45
 
42
46
  roles = [Role("secretary_" + str(i)) for i in range(0, 4)]
47
+ dbsession.add_all(roles)
43
48
 
44
49
  metadatas_protos = [
45
50
  ("copyable", "true"),
@@ -48,7 +53,7 @@ def theme_test_data(dbsession, transact):
48
53
  ]
49
54
  themes = []
50
55
  for i in range(0, 25):
51
- theme = Theme(name="theme_{}".format(i), ordering=1, icon="icon_{}".format(i))
56
+ theme = Theme(name=f"theme_{i}", ordering=1, icon=f"icon_{i}")
52
57
  theme.public = 1 == i % 2
53
58
  theme.interfaces = [interfaces[i % 4], interfaces[(i + 2) % 4]]
54
59
  theme.metadatas = [
@@ -57,7 +62,7 @@ def theme_test_data(dbsession, transact):
57
62
  ]
58
63
  for metadata in theme.metadatas:
59
64
  metadata.item = theme
60
- theme.functionalities = [functionalities[i % 8], functionalities[(i + 3) % 8]]
65
+ theme.functionalities = [functionalities[i % 4]]
61
66
  theme.restricted_roles = [roles[i % 4], roles[(i + 2) % 4]]
62
67
 
63
68
  dbsession.add(
@@ -117,7 +122,7 @@ class TestTheme(TestTreeGroup):
117
122
 
118
123
  assert first_theme.id == int(first_row["_id_"])
119
124
  assert first_theme.name == first_row["name"]
120
- assert "default_basemap=value_0, default_basemap=value_3" == first_row["functionalities"]
125
+ assert "default_basemap=value_0" == first_row["functionalities"]
121
126
  assert "secretary_0, secretary_2" == first_row["restricted_roles"]
122
127
  assert "desktop, edit" == first_row["interfaces"]
123
128
  assert 'copyable: true, snappingConfig: {"tolerance": 50}' == first_row["metadatas"]
@@ -146,16 +151,16 @@ class TestTheme(TestTreeGroup):
146
151
 
147
152
  def test_public_checkbox_edit(self, test_app, theme_test_data):
148
153
  theme = theme_test_data["themes"][10]
149
- form10 = test_app.get("/admin/themes/{}".format(theme.id), status=200).form
154
+ form10 = test_app.get(f"/admin/themes/{theme.id}", status=200).form
150
155
  assert not form10["public"].checked
151
156
  theme = theme_test_data["themes"][11]
152
- form11 = test_app.get("/admin/themes/{}".format(theme.id), status=200).form
157
+ form11 = test_app.get(f"/admin/themes/{theme.id}", status=200).form
153
158
  assert form11["public"].checked
154
159
 
155
160
  def test_edit(self, test_app, theme_test_data, dbsession):
156
161
  theme = theme_test_data["themes"][0]
157
162
 
158
- resp = test_app.get("/admin/themes/{}".format(theme.id), status=200)
163
+ resp = test_app.get(f"/admin/themes/{theme.id}", status=200)
159
164
  form = resp.form
160
165
 
161
166
  assert str(theme.id) == self.get_first_field_named(form, "id").value
@@ -166,21 +171,24 @@ class TestTheme(TestTreeGroup):
166
171
  assert theme.public == form["public"].checked
167
172
 
168
173
  interfaces = theme_test_data["interfaces"]
169
- assert set((interfaces[0].id, interfaces[2].id)) == set(i.id for i in theme.interfaces)
174
+ assert {interfaces[0].id, interfaces[2].id} == {i.id for i in theme.interfaces}
170
175
  self._check_interfaces(form, interfaces, theme)
171
176
 
172
177
  functionalities = theme_test_data["functionalities"]
173
- assert set((functionalities[0].id, functionalities[3].id)) == set(f.id for f in theme.functionalities)
178
+ assert {functionalities[0].id} == {f.id for f in theme.functionalities}
174
179
  self.check_checkboxes(
175
180
  form,
176
181
  "functionalities",
177
182
  [
178
183
  {
179
- "label": "{}={}".format(f.name, f.value),
184
+ "label": f"{f.name}={f.value}",
180
185
  "value": str(f.id),
181
186
  "checked": f in theme.functionalities,
182
187
  }
183
- for f in sorted(functionalities, key=lambda f: (f.name, f.value))
188
+ for f in sorted(
189
+ [f for f in functionalities if f.name in ("default_basemap")],
190
+ key=lambda f: (f.name, f.value),
191
+ )
184
192
  ],
185
193
  )
186
194
 
@@ -220,12 +228,8 @@ class TestTheme(TestTreeGroup):
220
228
  assert value == getattr(theme, key)
221
229
  else:
222
230
  assert str(value or "") == str(getattr(theme, key) or "")
223
- assert set([interfaces[1].id, interfaces[3].id]) == set(
224
- [interface.id for interface in theme.interfaces]
225
- )
226
- assert set([functionalities[2].id]) == set(
227
- [functionality.id for functionality in theme.functionalities]
228
- )
231
+ assert {interfaces[1].id, interfaces[3].id} == {interface.id for interface in theme.interfaces}
232
+ assert {functionalities[2].id} == {functionality.id for functionality in theme.functionalities}
229
233
  assert 0 == len(theme.restricted_roles)
230
234
 
231
235
  def test_post_new_with_children_invalid(self, test_app, theme_test_data):
@@ -234,7 +238,7 @@ class TestTheme(TestTreeGroup):
234
238
  """
235
239
  groups = theme_test_data["groups"]
236
240
  resp = test_app.post(
237
- "{}/new".format(self._prefix),
241
+ f"{self._prefix}/new",
238
242
  (
239
243
  ("_charset_", "UTF-8"),
240
244
  ("__formid__", "deform"),
@@ -256,7 +260,7 @@ class TestTheme(TestTreeGroup):
256
260
  def test_post_new_with_children_success(self, test_app, dbsession, theme_test_data):
257
261
  groups = theme_test_data["groups"]
258
262
  resp = test_app.post(
259
- "{}/new".format(self._prefix),
263
+ f"{self._prefix}/new",
260
264
  (
261
265
  ("_charset_", "UTF-8"),
262
266
  ("__formid__", "deform"),
@@ -304,7 +308,7 @@ class TestTheme(TestTreeGroup):
304
308
  """
305
309
  layers = theme_test_data["layers"]
306
310
  resp = test_app.post(
307
- "{}/new".format(self._prefix),
311
+ f"{self._prefix}/new",
308
312
  (
309
313
  ("_charset_", "UTF-8"),
310
314
  ("__formid__", "deform"),
@@ -324,7 +328,7 @@ class TestTheme(TestTreeGroup):
324
328
  status=200,
325
329
  )
326
330
  assert (
327
- "Value {} does not exist in table treeitem or is not allowed to avoid cycles".format(layers[0].id)
331
+ f"Value {layers[0].id} does not exist in table treeitem or is not allowed to avoid cycles"
328
332
  == resp.html.select_one(".item-children_relation + .help-block").getText().strip()
329
333
  )
330
334
 
@@ -333,7 +337,7 @@ class TestTheme(TestTreeGroup):
333
337
 
334
338
  theme = theme_test_data["themes"][1]
335
339
 
336
- resp = test_app.get("{}/{}/duplicate".format(self._prefix, theme.id), status=200)
340
+ resp = test_app.get(f"{self._prefix}/{theme.id}/duplicate", status=200)
337
341
  form = resp.form
338
342
 
339
343
  assert "" == self.get_first_field_named(form, "id").value
@@ -345,22 +349,25 @@ class TestTheme(TestTreeGroup):
345
349
  assert theme.public == form["public"].checked
346
350
 
347
351
  interfaces = theme_test_data["interfaces"]
348
- assert set((interfaces[1].id, interfaces[3].id)) == set(i.id for i in theme.interfaces)
352
+ assert {interfaces[1].id, interfaces[3].id} == {i.id for i in theme.interfaces}
349
353
 
350
354
  self._check_interfaces(form, interfaces, theme)
351
355
 
352
356
  functionalities = theme_test_data["functionalities"]
353
- assert set((functionalities[1].id, functionalities[4].id)) == set(f.id for f in theme.functionalities)
357
+ assert {functionalities[1].id} == {f.id for f in theme.functionalities}
354
358
  self.check_checkboxes(
355
359
  form,
356
360
  "functionalities",
357
361
  [
358
362
  {
359
- "label": "{}={}".format(f.name, f.value),
363
+ "label": f"{f.name}={f.value}",
360
364
  "value": str(f.id),
361
365
  "checked": f in theme.functionalities,
362
366
  }
363
- for f in sorted(functionalities, key=lambda f: (f.name, f.value))
367
+ for f in sorted(
368
+ [f for f in functionalities if f.name in ("default_basemap")],
369
+ key=lambda f: (f.name, f.value),
370
+ )
364
371
  ],
365
372
  )
366
373
 
@@ -381,7 +388,7 @@ class TestTheme(TestTreeGroup):
381
388
  duplicated = dbsession.query(Theme).filter(Theme.name == "duplicated").one()
382
389
 
383
390
  assert str(duplicated.id) == re.match(
384
- r"http://localhost{}/(.*)\?msg_col=submit_ok".format(self._prefix), resp.location
391
+ rf"http://localhost{self._prefix}/(.*)\?msg_col=submit_ok", resp.location
385
392
  ).group(1)
386
393
  assert duplicated.id != theme.id
387
394
  assert duplicated.children_relation[0].id != theme.children_relation[0].id
@@ -391,13 +398,13 @@ class TestTheme(TestTreeGroup):
391
398
  from c2cgeoportal_commons.models.main import Theme
392
399
 
393
400
  theme_id = dbsession.query(Theme.id).first().id
394
- test_app.delete("/admin/themes/{}".format(theme_id), status=200)
401
+ test_app.delete(f"/admin/themes/{theme_id}", status=200)
395
402
  assert dbsession.query(Theme).get(theme_id) is None
396
403
 
397
404
  def test_unicity_validator(self, theme_test_data, test_app):
398
405
  theme = theme_test_data["themes"][1]
399
- resp = test_app.get("{}/{}/duplicate".format(self._prefix, theme.id), status=200)
406
+ resp = test_app.get(f"{self._prefix}/{theme.id}/duplicate", status=200)
400
407
 
401
408
  resp = resp.form.submit("submit")
402
409
 
403
- self._check_submission_problem(resp, "{} is already used.".format(theme.name))
410
+ self._check_submission_problem(resp, f"{theme.name} is already used.")
@@ -14,7 +14,7 @@ def theme_test_data(dbsession, transact):
14
14
 
15
15
  themes = []
16
16
  for i in range(0, 3):
17
- theme = Theme(name="theme_{}".format(i), ordering=i, icon="icon_{}".format(i))
17
+ theme = Theme(name=f"theme_{i}", ordering=i, icon=f"icon_{i}")
18
18
 
19
19
  dbsession.add(theme)
20
20
  themes.append(theme)
tests/test_treegroup.py CHANGED
@@ -5,10 +5,10 @@ from . import AbstractViewsTests
5
5
 
6
6
  class TestTreeGroup(AbstractViewsTests):
7
7
  def check_children(self, form, group, expected):
8
- form_group = form.html.select_one(".item-{}".format(group))
8
+ form_group = form.html.select_one(f".item-{group}")
9
9
  items = form_group.select(".deform-seq-item")
10
10
  assert len(expected) == len(items)
11
11
  for item, exp in zip(items, expected):
12
12
  assert exp["label"] == item.select_one(".well").getText().strip()
13
13
  for key, value in exp["values"].items():
14
- assert value == item.select_one('input[name="{}"]'.format(key))["value"]
14
+ assert value == item.select_one(f'input[name="{key}"]')["value"]