c2cgeoportal-admin 2.7.1.156__py3-none-any.whl → 2.8.1.180__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 (52) hide show
  1. c2cgeoportal_admin/__init__.py +16 -1
  2. c2cgeoportal_admin/lib/ogcserver_synchronizer.py +4 -4
  3. c2cgeoportal_admin/routes.py +3 -1
  4. c2cgeoportal_admin/schemas/metadata.py +1 -1
  5. c2cgeoportal_admin/schemas/treegroup.py +2 -2
  6. c2cgeoportal_admin/templates/404.jinja2 +18 -2
  7. c2cgeoportal_admin/templates/widgets/metadata.pt +1 -1
  8. c2cgeoportal_admin/views/__init__.py +29 -0
  9. c2cgeoportal_admin/views/functionalities.py +4 -3
  10. c2cgeoportal_admin/views/interfaces.py +4 -3
  11. c2cgeoportal_admin/views/layer_groups.py +1 -1
  12. c2cgeoportal_admin/views/layers_wms.py +5 -3
  13. c2cgeoportal_admin/views/layers_wmts.py +5 -3
  14. c2cgeoportal_admin/views/layertree.py +2 -2
  15. c2cgeoportal_admin/views/logged_views.py +80 -0
  16. c2cgeoportal_admin/views/logs.py +90 -0
  17. c2cgeoportal_admin/views/oauth2_clients.py +9 -6
  18. c2cgeoportal_admin/views/ogc_servers.py +66 -12
  19. c2cgeoportal_admin/views/restriction_areas.py +4 -3
  20. c2cgeoportal_admin/views/roles.py +4 -3
  21. c2cgeoportal_admin/views/themes.py +1 -1
  22. c2cgeoportal_admin/views/treeitems.py +4 -3
  23. c2cgeoportal_admin/views/users.py +7 -4
  24. c2cgeoportal_admin/widgets.py +2 -2
  25. {c2cgeoportal_admin-2.7.1.156.dist-info → c2cgeoportal_admin-2.8.1.180.dist-info}/METADATA +13 -7
  26. c2cgeoportal_admin-2.8.1.180.dist-info/RECORD +95 -0
  27. {c2cgeoportal_admin-2.7.1.156.dist-info → c2cgeoportal_admin-2.8.1.180.dist-info}/entry_points.txt +1 -0
  28. tests/__init__.py +2 -3
  29. tests/test_edit_url.py +0 -1
  30. tests/test_functionalities.py +29 -4
  31. tests/test_home.py +0 -1
  32. tests/test_interface.py +27 -4
  33. tests/test_layer_groups.py +45 -11
  34. tests/test_layers_vectortiles.py +33 -8
  35. tests/test_layers_wms.py +43 -10
  36. tests/test_layers_wmts.py +33 -8
  37. tests/test_layertree.py +0 -1
  38. tests/test_left_menu.py +0 -1
  39. tests/test_lingua_extractor_config.py +1 -3
  40. tests/test_logs.py +103 -0
  41. tests/test_metadatas.py +0 -1
  42. tests/test_oauth2_clients.py +35 -7
  43. tests/test_ogc_servers.py +65 -27
  44. tests/test_restriction_areas.py +28 -3
  45. tests/test_role.py +33 -8
  46. tests/test_themes.py +33 -6
  47. tests/test_themes_ordering.py +0 -1
  48. tests/test_user.py +33 -4
  49. tests/themes_ordering.py +0 -1
  50. c2cgeoportal_admin-2.7.1.156.dist-info/RECORD +0 -92
  51. {c2cgeoportal_admin-2.7.1.156.dist-info → c2cgeoportal_admin-2.8.1.180.dist-info}/WHEEL +0 -0
  52. {c2cgeoportal_admin-2.7.1.156.dist-info → c2cgeoportal_admin-2.8.1.180.dist-info}/top_level.txt +0 -0
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
 
@@ -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,27 +59,38 @@ 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
- resp = test_app.post(
65
- "/admin/ogc_servers/new",
66
- {
67
- "name": "new_name",
68
- "description": "new description",
69
- "url": "www.randomurl.com",
70
- "type": "mapserver",
71
- "auth": "No auth",
72
- "image_type": "image/png",
73
- },
74
- status=302,
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
- def test_edit(self, test_app, ogc_server_test_data):
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
95
  resp = test_app.get(f"/admin/ogc_servers/{ogc_server.id}", status=200)
85
96
  form = resp.form
@@ -87,16 +98,32 @@ class TestOGCServer(AbstractViewsTests):
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
- assert form.submit().status_int == 302
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
- deleted_id = ogc_server.id
98
- test_app.delete(f"/admin/ogc_servers/{deleted_id}", status=200)
99
- assert dbsession.query(OGCServer).get(deleted_id) is None
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
@@ -106,7 +133,8 @@ class TestOGCServer(AbstractViewsTests):
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
- resp = form.submit("submit")
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(
@@ -126,7 +154,7 @@ class TestOGCServer(AbstractViewsTests):
126
154
  ogc_server.url = "config://mapserver"
127
155
  resp = test_app.get(f"/admin/ogc_servers/{ogc_server.id}/synchronize", status=200)
128
156
 
129
- resp = resp.forms["form-check"].submit("submit")
157
+ resp = resp.forms["form-check"].submit("check")
130
158
 
131
159
  assert list(resp.html.find("div", class_="alert-success").stripped_strings) == [
132
160
  "OGC Server has been successfully synchronized."
@@ -137,18 +165,28 @@ class TestOGCServer(AbstractViewsTests):
137
165
  ogc_server.url = "config://mapserver"
138
166
  resp = test_app.get(f"/admin/ogc_servers/{ogc_server.id}/synchronize", status=200)
139
167
 
140
- resp = resp.forms["form-dry-run"].submit("submit")
168
+ resp = resp.forms["form-dry-run"].submit("dry-run")
141
169
 
142
170
  assert list(resp.html.find("div", class_="alert-success").stripped_strings) == [
143
171
  "OGC Server has been successfully synchronized."
144
172
  ]
145
173
 
146
- def test_synchronize_success(self, ogc_server_test_data, test_app):
174
+ def test_synchronize_success(self, ogc_server_test_data, test_app, dbsession):
175
+ from c2cgeoportal_commons.models.main import Log, LogAction
176
+
147
177
  ogc_server = ogc_server_test_data["ogc_servers"][3]
148
178
  ogc_server.url = "config://mapserver"
149
179
  resp = test_app.get(f"/admin/ogc_servers/{ogc_server.id}/synchronize", status=200)
150
180
 
151
- resp = resp.forms["form-synchronize"].submit("submit")
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"
152
190
 
153
191
  assert list(resp.html.find("div", class_="alert-success").stripped_strings) == [
154
192
  "OGC Server has been successfully synchronized."
@@ -159,7 +197,7 @@ class TestOGCServer(AbstractViewsTests):
159
197
  form["force-ordering"].checked = True
160
198
  form["clean"].checked = True
161
199
 
162
- resp = form.submit("submit")
200
+ resp = form.submit("synchronize")
163
201
 
164
202
  assert list(resp.html.find("div", class_="alert-success").stripped_strings) == [
165
203
  "OGC Server has been successfully synchronized."
@@ -50,7 +50,6 @@ def restriction_area_test_data(dbsession, transact):
50
50
 
51
51
  @pytest.mark.usefixtures("restriction_area_test_data", "test_app")
52
52
  class TestRestrictionAreaViews(TestTreeGroup):
53
-
54
53
  _prefix = "/admin/restriction_areas"
55
54
 
56
55
  def test_index_rendering(self, test_app):
@@ -73,7 +72,7 @@ class TestRestrictionAreaViews(TestTreeGroup):
73
72
  self.check_search(test_app, "restrictionarea_1", total=1)
74
73
 
75
74
  def test_submit_new(self, dbsession, test_app, restriction_area_test_data):
76
- from c2cgeoportal_commons.models.main import RestrictionArea
75
+ from c2cgeoportal_commons.models.main import Log, LogAction, RestrictionArea
77
76
 
78
77
  roles = restriction_area_test_data["roles"]
79
78
  layers = restriction_area_test_data["layers"]
@@ -116,6 +115,14 @@ class TestRestrictionAreaViews(TestTreeGroup):
116
115
  assert set(restriction_area.roles) == {roles[0], roles[1]}
117
116
  assert set(restriction_area.layers) == {layers[0], layers[1]}
118
117
 
118
+ log = dbsession.query(Log).one()
119
+ assert log.date != None
120
+ assert log.action == LogAction.INSERT
121
+ assert log.element_type == "restrictionarea"
122
+ assert log.element_id == restriction_area.id
123
+ assert log.element_name == restriction_area.name
124
+ assert log.username == "test_user"
125
+
119
126
  def test_unicity_validator(self, restriction_area_test_data, test_app):
120
127
  restriction_area = restriction_area_test_data["restriction_areas"][2]
121
128
 
@@ -125,6 +132,8 @@ class TestRestrictionAreaViews(TestTreeGroup):
125
132
  self._check_submission_problem(resp, f"{restriction_area.name} is already used.")
126
133
 
127
134
  def test_edit(self, test_app, restriction_area_test_data, dbsession):
135
+ from c2cgeoportal_commons.models.main import Log, LogAction
136
+
128
137
  restriction_area = restriction_area_test_data["restriction_areas"][0]
129
138
  roles = restriction_area_test_data["roles"]
130
139
 
@@ -164,14 +173,30 @@ class TestRestrictionAreaViews(TestTreeGroup):
164
173
  assert restriction_area.description == "new_description"
165
174
  assert set(restriction_area.roles) == {roles[i] for i in range(0, 3)}
166
175
 
176
+ log = dbsession.query(Log).one()
177
+ assert log.date != None
178
+ assert log.action == LogAction.UPDATE
179
+ assert log.element_type == "restrictionarea"
180
+ assert log.element_id == restriction_area.id
181
+ assert log.element_name == restriction_area.name
182
+ assert log.username == "test_user"
183
+
167
184
  def test_delete(self, test_app, restriction_area_test_data, dbsession):
168
- from c2cgeoportal_commons.models.main import RestrictionArea
185
+ from c2cgeoportal_commons.models.main import Log, LogAction, RestrictionArea
169
186
 
170
187
  restriction_area = restriction_area_test_data["restriction_areas"][0]
171
188
  deleted_id = restriction_area.id
172
189
  test_app.delete(f"/admin/restriction_areas/{deleted_id}", status=200)
173
190
  assert dbsession.query(RestrictionArea).get(deleted_id) is None
174
191
 
192
+ log = dbsession.query(Log).one()
193
+ assert log.date != None
194
+ assert log.action == LogAction.DELETE
195
+ assert log.element_type == "restrictionarea"
196
+ assert log.element_id == restriction_area.id
197
+ assert log.element_name == restriction_area.name
198
+ assert log.username == "test_user"
199
+
175
200
  def test_duplicate(self, restriction_area_test_data, test_app, dbsession):
176
201
  from c2cgeoportal_commons.models.main import RestrictionArea
177
202
 
tests/test_role.py CHANGED
@@ -68,7 +68,6 @@ def roles_test_data(dbsession, transact):
68
68
 
69
69
  @pytest.mark.usefixtures("roles_test_data", "test_app")
70
70
  class TestRole(TestTreeGroup):
71
-
72
71
  _prefix = "/admin/roles"
73
72
 
74
73
  def test_index_rendering(self, test_app):
@@ -103,9 +102,9 @@ class TestRole(TestTreeGroup):
103
102
  self.check_grid_headers(resp, expected, new="Nouveau")
104
103
 
105
104
  def test_submit_new(self, dbsession, test_app, roles_test_data):
106
- from c2cgeoportal_commons.models.main import Role
105
+ from c2cgeoportal_commons.models.main import Log, LogAction, Role
107
106
 
108
- roles = roles_test_data["roles"]
107
+ roles_test_data["roles"]
109
108
  functionalities = roles_test_data["functionalities"]
110
109
  restrictionareas = roles_test_data["restrictionareas"]
111
110
  users = roles_test_data["users"]
@@ -154,7 +153,17 @@ class TestRole(TestTreeGroup):
154
153
  assert set(role.restrictionareas) == {restrictionareas[0], restrictionareas[1]}
155
154
  assert set(role.users) == {users[0], users[1]}
156
155
 
156
+ log = dbsession.query(Log).one()
157
+ assert log.date != None
158
+ assert log.action == LogAction.INSERT
159
+ assert log.element_type == "role"
160
+ assert log.element_id == role.id
161
+ assert log.element_name == role.name
162
+ assert log.username == "test_user"
163
+
157
164
  def test_edit(self, dbsession, test_app, roles_test_data):
165
+ from c2cgeoportal_commons.models.main import Log, LogAction
166
+
158
167
  role = roles_test_data["roles"][10]
159
168
 
160
169
  # Ensure role.users is loaded with relationship "order_by"
@@ -273,6 +282,14 @@ class TestRole(TestTreeGroup):
273
282
  assert set(functionality_ids) == {f.id for f in role.functionalities}
274
283
  assert set(ra_ids) == {f.id for f in role.restrictionareas}
275
284
 
285
+ log = dbsession.query(Log).one()
286
+ assert log.date != None
287
+ assert log.action == LogAction.UPDATE
288
+ assert log.element_type == "role"
289
+ assert log.element_id == role.id
290
+ assert log.element_name == role.name
291
+ assert log.username == "test_user"
292
+
276
293
  def test_duplicate(self, roles_test_data, test_app, dbsession):
277
294
  from c2cgeoportal_commons.models.main import Role
278
295
 
@@ -297,11 +314,19 @@ class TestRole(TestTreeGroup):
297
314
  assert set(role_proto.users) == set(role.users)
298
315
 
299
316
  def test_delete(self, test_app, dbsession):
300
- from c2cgeoportal_commons.models.main import Role
301
-
302
- role_id = dbsession.query(Role.id).first().id
303
- test_app.delete(f"/admin/roles/{role_id}", status=200)
304
- assert dbsession.query(Role).get(role_id) is None
317
+ from c2cgeoportal_commons.models.main import Log, LogAction, Role
318
+
319
+ role = dbsession.query(Role).first()
320
+ test_app.delete(f"/admin/roles/{role.id}", status=200)
321
+ assert dbsession.query(Role).get(role.id) is None
322
+
323
+ log = dbsession.query(Log).one()
324
+ assert log.date != None
325
+ assert log.action == LogAction.DELETE
326
+ assert log.element_type == "role"
327
+ assert log.element_id == role.id
328
+ assert log.element_name == role.name
329
+ assert log.username == "test_user"
305
330
 
306
331
  def test_unicity_validator(self, roles_test_data, test_app):
307
332
  role_proto = roles_test_data["roles"][7]
tests/test_themes.py CHANGED
@@ -91,7 +91,6 @@ def theme_test_data(dbsession, transact):
91
91
 
92
92
  @pytest.mark.usefixtures("theme_test_data", "test_app")
93
93
  class TestTheme(TestTreeGroup):
94
-
95
94
  _prefix = "/admin/themes"
96
95
 
97
96
  def test_index_rendering(self, test_app):
@@ -158,6 +157,8 @@ class TestTheme(TestTreeGroup):
158
157
  assert form11["public"].checked
159
158
 
160
159
  def test_edit(self, test_app, theme_test_data, dbsession):
160
+ from c2cgeoportal_commons.models.main import Log, LogAction
161
+
161
162
  theme = theme_test_data["themes"][0]
162
163
 
163
164
  resp = test_app.get(f"/admin/themes/{theme.id}", status=200)
@@ -232,6 +233,14 @@ class TestTheme(TestTreeGroup):
232
233
  assert {functionalities[2].id} == {functionality.id for functionality in theme.functionalities}
233
234
  assert 0 == len(theme.restricted_roles)
234
235
 
236
+ log = dbsession.query(Log).one()
237
+ assert log.date != None
238
+ assert log.action == LogAction.UPDATE
239
+ assert log.element_type == "theme"
240
+ assert log.element_id == theme.id
241
+ assert log.element_name == theme.name
242
+ assert log.username == "test_user"
243
+
235
244
  def test_post_new_with_children_invalid(self, test_app, theme_test_data):
236
245
  """
237
246
  Check there is no rendering error when validation fails.
@@ -258,6 +267,8 @@ class TestTheme(TestTreeGroup):
258
267
  self._check_submission_problem(resp, "Required")
259
268
 
260
269
  def test_post_new_with_children_success(self, test_app, dbsession, theme_test_data):
270
+ from c2cgeoportal_commons.models.main import Log, LogAction
271
+
261
272
  groups = theme_test_data["groups"]
262
273
  resp = test_app.post(
263
274
  f"{self._prefix}/new",
@@ -302,6 +313,14 @@ class TestTheme(TestTreeGroup):
302
313
  rel.treeitem_id for rel in theme.children_relation
303
314
  ]
304
315
 
316
+ log = dbsession.query(Log).one()
317
+ assert log.date != None
318
+ assert log.action == LogAction.INSERT
319
+ assert log.element_type == "theme"
320
+ assert log.element_id == theme.id
321
+ assert log.element_name == theme.name
322
+ assert log.username == "test_user"
323
+
305
324
  def test_post_new_with_child_layer(self, theme_test_data, test_app):
306
325
  """
307
326
  Check layers are rejected by the validator (also means that they are not proposed to the user).
@@ -395,11 +414,19 @@ class TestTheme(TestTreeGroup):
395
414
  assert duplicated.children_relation[0].treeitem.id == theme.children_relation[0].treeitem.id
396
415
 
397
416
  def test_delete(self, test_app, dbsession):
398
- from c2cgeoportal_commons.models.main import Theme
399
-
400
- theme_id = dbsession.query(Theme.id).first().id
401
- test_app.delete(f"/admin/themes/{theme_id}", status=200)
402
- assert dbsession.query(Theme).get(theme_id) is None
417
+ from c2cgeoportal_commons.models.main import Log, LogAction, Theme
418
+
419
+ theme = dbsession.query(Theme).first()
420
+ test_app.delete(f"/admin/themes/{theme.id}", status=200)
421
+ assert dbsession.query(Theme).get(theme.id) is None
422
+
423
+ log = dbsession.query(Log).one()
424
+ assert log.date != None
425
+ assert log.action == LogAction.DELETE
426
+ assert log.element_type == "theme"
427
+ assert log.element_id == theme.id
428
+ assert log.element_name == theme.name
429
+ assert log.username == "test_user"
403
430
 
404
431
  def test_unicity_validator(self, theme_test_data, test_app):
405
432
  theme = theme_test_data["themes"][1]
@@ -28,7 +28,6 @@ def theme_test_data(dbsession, transact):
28
28
 
29
29
  @pytest.mark.usefixtures("theme_test_data", "test_app")
30
30
  class TestThemeOrdering(TestTreeGroup):
31
-
32
31
  _prefix = "/admin/layertree/ordering"
33
32
 
34
33
  def test_edit(self, test_app, theme_test_data, dbsession):
tests/test_user.py CHANGED
@@ -48,7 +48,6 @@ EXPECTED_WELCOME_MAIL = (
48
48
 
49
49
  @pytest.mark.usefixtures("users_test_data", "test_app")
50
50
  class TestUser(AbstractViewsTests):
51
-
52
51
  _prefix = "/admin/users"
53
52
 
54
53
  def test_index_rendering(self, test_app):
@@ -89,7 +88,10 @@ class TestUser(AbstractViewsTests):
89
88
  ]
90
89
  self.check_grid_headers(resp, expected, new="Nouveau")
91
90
 
92
- def test_view_edit(self, test_app, users_test_data):
91
+ def test_view_edit(self, test_app, users_test_data, dbsession):
92
+ from c2cgeoportal_commons.models.main import LogAction
93
+ from c2cgeoportal_commons.models.static import Log
94
+
93
95
  user = users_test_data["users"][9]
94
96
  roles = users_test_data["roles"]
95
97
 
@@ -122,8 +124,17 @@ class TestUser(AbstractViewsTests):
122
124
  assert str(value or "") == str(getattr(user, key) or "")
123
125
  assert {roles[2].id, roles[3].id} == {role.id for role in user.roles}
124
126
 
127
+ log = dbsession.query(Log).one()
128
+ assert log.date != None
129
+ assert log.action == LogAction.UPDATE
130
+ assert log.element_type == "user"
131
+ assert log.element_id == user.id
132
+ assert log.element_name == user.username
133
+ assert log.username == "test_user"
134
+
125
135
  def test_delete(self, test_app, users_test_data, dbsession):
126
- from c2cgeoportal_commons.models.static import User, user_role
136
+ from c2cgeoportal_commons.models.main import LogAction
137
+ from c2cgeoportal_commons.models.static import Log, User, user_role
127
138
 
128
139
  user = users_test_data["users"][9]
129
140
  deleted_id = user.id
@@ -131,6 +142,14 @@ class TestUser(AbstractViewsTests):
131
142
  assert dbsession.query(User).get(deleted_id) is None
132
143
  assert dbsession.query(user_role).filter(user_role.c.user_id == user.id).count() == 0
133
144
 
145
+ log = dbsession.query(Log).one()
146
+ assert log.date != None
147
+ assert log.action == LogAction.DELETE
148
+ assert log.element_type == "user"
149
+ assert log.element_id == user.id
150
+ assert log.element_name == user.username
151
+ assert log.username == "test_user"
152
+
134
153
  @patch("c2cgeoportal_commons.lib.email_.smtplib.SMTP")
135
154
  @patch("c2cgeoportal_admin.views.users.pwgenerator.generate")
136
155
  def test_submit_update(self, pw_gen_mock, smtp_mock, dbsession, test_app, users_test_data):
@@ -233,10 +252,12 @@ class TestUser(AbstractViewsTests):
233
252
  @patch("c2cgeoportal_admin.views.users.pwgenerator.generate")
234
253
  @pytest.mark.usefixtures("test_app")
235
254
  def test_submit_new(self, pw_gen_mock, smtp_mock, dbsession, test_app, users_test_data):
255
+ from c2cgeoportal_commons.models.main import LogAction
256
+ from c2cgeoportal_commons.models.static import Log, User
257
+
236
258
  sender_mock = MagicMock()
237
259
  smtp_mock.return_value = sender_mock
238
260
  pw_gen_mock.return_value = "basile"
239
- from c2cgeoportal_commons.models.static import User
240
261
 
241
262
  roles = users_test_data["roles"]
242
263
 
@@ -275,6 +296,14 @@ class TestUser(AbstractViewsTests):
275
296
  ).decode("utf8")
276
297
  assert "valid@email.net" == parts[0].items()[3][1]
277
298
 
299
+ log = dbsession.query(Log).one()
300
+ assert log.date != None
301
+ assert log.action == LogAction.INSERT
302
+ assert log.element_type == "user"
303
+ assert log.element_id == user.id
304
+ assert log.element_name == user.username
305
+ assert log.username == "test_user"
306
+
278
307
  def test_invalid_email(self, test_app):
279
308
  resp = test_app.post(
280
309
  "/admin/users/new",
tests/themes_ordering.py CHANGED
@@ -25,7 +25,6 @@ def themes_ordering_test_data(dbsession, transact):
25
25
 
26
26
  @pytest.mark.usefixtures("themes_ordering_test_data", "test_app")
27
27
  class TestThemesOrdering(TestTreeGroup):
28
-
29
28
  _prefix = "/admin/layertree/ordering"
30
29
 
31
30
  def test_edit(self, test_app, themes_ordering_test_data):
@@ -1,92 +0,0 @@
1
- c2cgeoportal_admin/__init__.py,sha256=4UYLGCcfxd8mfHojIalTFmaYNgD67WFbgVhw2sl5yok,4959
2
- c2cgeoportal_admin/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- c2cgeoportal_admin/routes.py,sha256=So17Lj2v8UigkxVwfYJrK_piDejRkvekPiFibyr3qiw,4676
4
- c2cgeoportal_admin/subscribers.py,sha256=P1CaccDTpuxrWak_gMN2qBurz3OrAZ6aZ1LA7P3avu8,2430
5
- c2cgeoportal_admin/widgets.py,sha256=tW6brDW-95LuRnSsRd_8xVRKNAkwkYtdi8zQ44TBj18,6132
6
- c2cgeoportal_admin/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- c2cgeoportal_admin/lib/lingua_extractor.py,sha256=Dw4vo46TcUnJ7vvxgFezPYidfEdL2pHJUM0qxAaJ1KE,3380
8
- c2cgeoportal_admin/lib/ogcserver_synchronizer.py,sha256=NuCV8EpUso01to2PYbh6NpXPcD702pQOSslah__Bzus,15421
9
- c2cgeoportal_admin/schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- c2cgeoportal_admin/schemas/dimensions.py,sha256=rPMEuIdGiVGS5e0xqXUu-COVKlrWg9rpp-xe-8aHbOQ,2290
11
- c2cgeoportal_admin/schemas/functionalities.py,sha256=AptqKn2oyy74qivzihNfeNvmaDILsl36bSoJdSNXh9Y,3941
12
- c2cgeoportal_admin/schemas/interfaces.py,sha256=0NCRDZOqbw7Bwj-l3GNsVwYDHck4F0q1fCSo1kTYoOY,2578
13
- c2cgeoportal_admin/schemas/metadata.py,sha256=px0Teh0vtyimQfzL7zXHXIEkWtBbD00OsadfDDeqSkY,8991
14
- c2cgeoportal_admin/schemas/restriction_areas.py,sha256=48hFUgFznl_1bYsl490YSXLbXfjCY_f6gURQtB_7eIk,2598
15
- c2cgeoportal_admin/schemas/roles.py,sha256=4JJrgZNKsj_wru_YGOWxZTEXGVm0hahbAkYf2aePGzI,2507
16
- c2cgeoportal_admin/schemas/treegroup.py,sha256=-s_aKAzwYwS9zVsuqQAp_7M_-c00LVq-R6dC8BiUWk0,7039
17
- c2cgeoportal_admin/schemas/treeitem.py,sha256=qnjrLd2LD7NCBjXqzw7aRn83cw_hYZbepJdLzOz0rBk,2117
18
- c2cgeoportal_admin/static/layertree.css,sha256=tk54KGW0yRRmdrY35gOCZG3qTsqWtGNEwvBYPQKhaVs,3177
19
- c2cgeoportal_admin/static/navbar.css,sha256=QIaAQsb4n17OfwdKEQdmNDVPCP23Yu-oGW4xsSaHyW0,2307
20
- c2cgeoportal_admin/static/theme.css,sha256=eHtBEJcBtDhyZJvCKNxE5hgril0VpLtcDKfNFdgCSVw,2025
21
- c2cgeoportal_admin/templates/404.jinja2,sha256=F05OZUzJljcieoCFMP7Oz1F6Jb-VZ06hTOSc9mrb87g,1420
22
- c2cgeoportal_admin/templates/edit.jinja2,sha256=rkBQiz0JZdL7VDq8XrhRLTv6JaiFt_QB8CwP3NMHWQY,1302
23
- c2cgeoportal_admin/templates/home.jinja2,sha256=WDQwmBGMZxsiOLw9YeYPLuca_mjjntjrTh529euzd1o,1516
24
- c2cgeoportal_admin/templates/index.jinja2,sha256=HPgilbqh5dv-yc_T_bc1hV2DEtV2wD617_aAERC2VSk,2005
25
- c2cgeoportal_admin/templates/layertree.jinja2,sha256=1ys5XDY3nb4gAu8JazkwSFeJUdGRadT7WaBuvin_hYg,9830
26
- c2cgeoportal_admin/templates/layout.jinja2,sha256=KCDwATUYBu-ZXv7ijo0S0PlTmKtU-JxW8gMhvPA_kAE,4105
27
- c2cgeoportal_admin/templates/navigation_navbar.jinja2,sha256=XzVQDpo3ClIiRxWf5eDULHZi9u-veYOmndiE_Twqxog,4166
28
- c2cgeoportal_admin/templates/ogcserver_synchronize.jinja2,sha256=rdQfbHBzrV5VUq5TC97QR7pv8bRvrdKaUUZpnQyldoE,4327
29
- c2cgeoportal_admin/templates/widgets/child.pt,sha256=JjxI0oVADhS3SoFgg0iN8P4ca1I_UGr7fWRp3wpZXsE,2159
30
- c2cgeoportal_admin/templates/widgets/children.pt,sha256=0TPpatvmZcU2TxbcZMjDz8VQcLGtoHkuDJ-eAGvjXho,6625
31
- c2cgeoportal_admin/templates/widgets/dimension.pt,sha256=1BXmE7s9JpzaJSHAQEtZk0DHB11pQ4FNQPaG_4c8CYo,2627
32
- c2cgeoportal_admin/templates/widgets/dimensions.pt,sha256=LjWjsgdcFYZxpB_30-3NOfvq5KYkKTu49F-P-r9d5Jg,1211
33
- c2cgeoportal_admin/templates/widgets/functionality_fields.pt,sha256=8TvwXCmQOtYFkiqsa4AHFUYsWk92LLnthz8bDrLmMBc,1969
34
- c2cgeoportal_admin/templates/widgets/layer_fields.pt,sha256=RJBYt8ji6YQp9ZaNZJD-caLgy856a6rzlKSMnuZWphw,3223
35
- c2cgeoportal_admin/templates/widgets/layer_group_fields.pt,sha256=xnqIqFjPPan81OqLwKeDnvNtlhEvYss6h2J9txH5neE,2459
36
- c2cgeoportal_admin/templates/widgets/layer_v1_fields.pt,sha256=w-MujUevHWmnOkOTbbvES6alDoL_UO1eiMj8SCxcQEY,3956
37
- c2cgeoportal_admin/templates/widgets/metadata.pt,sha256=jWiLmS0J-cwFkqUxxZwKnkPNX9ShTG2zj0tUCq4TMjQ,3735
38
- c2cgeoportal_admin/templates/widgets/metadatas.pt,sha256=ErgAH0DA94MO7gqEJ2iZdQ9LRptP2YKH78yze-jdl2Q,1476
39
- c2cgeoportal_admin/templates/widgets/ogcserver_fields.pt,sha256=x0bDmgrnj9SA6RCVpg3k2lTkkXPkuBFPKMScDgDeyGU,1724
40
- c2cgeoportal_admin/templates/widgets/restriction_area_fields.pt,sha256=pZVE0KcitAF7HXc3ZlniLr0QwSD05TOhlgieLUR1i7Q,1731
41
- c2cgeoportal_admin/templates/widgets/role_fields.pt,sha256=gVd9eRYaqw8fGmZauqEUS_Igmyxaa71qcmdC1KUx5nY,2623
42
- c2cgeoportal_admin/templates/widgets/theme_fields.pt,sha256=68G1Ya8-Dc6pCeP-taQ0ofCIpnY_v0rouazkFhfQflU,3083
43
- c2cgeoportal_admin/templates/widgets/user_fields.pt,sha256=twmajhUYL1xa47Eu-iATKifNPA5lu3SGpqdKajH6gL8,1753
44
- c2cgeoportal_admin/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
- c2cgeoportal_admin/views/dimension_layers.py,sha256=jupwqX_kO37ukcWE-SsO290JdKENEmfoYxk4sRWb25Y,2598
46
- c2cgeoportal_admin/views/functionalities.py,sha256=U51DvRd6Jg40VQm66kyVy363cDGGEol0WwaQC8b2ZKM,4002
47
- c2cgeoportal_admin/views/home.py,sha256=h_hJWIKpzJeSmXl58J0nvZdEg7avSYOOVUEEnlV-r0k,1943
48
- c2cgeoportal_admin/views/interfaces.py,sha256=3Sl-57PchMlUw_RrvL7F4KTpa57ifpNjOxk-nWqMXpk,3465
49
- c2cgeoportal_admin/views/layer_groups.py,sha256=CbuURDXMcRXnWbW9aEhXP9nSiSiFq4m3JdtgQS6agxs,3956
50
- c2cgeoportal_admin/views/layers.py,sha256=xjvcRvKVpeD-LRuVwE8PGkDT-Kih9ADX0beEDcOP1bE,3039
51
- c2cgeoportal_admin/views/layers_vectortiles.py,sha256=lREdMc7bo2TVqdf-s6MzNXZoauReqFS_K-Hng49NUT4,4932
52
- c2cgeoportal_admin/views/layers_wms.py,sha256=p3g2zc2waMBBrlFQjgTUn9YTg3WcXQofx5Yw1b3ozAg,7954
53
- c2cgeoportal_admin/views/layers_wmts.py,sha256=IxvF_knk3HYsa8gKhIaZsyi5Uhmv_Qrmd50gU8BPla8,7731
54
- c2cgeoportal_admin/views/layertree.py,sha256=x1nTVwyf-ZK7M0gIDpsDdySMZm3XmE6yGEE9j8VYQ4Y,8589
55
- c2cgeoportal_admin/views/oauth2_clients.py,sha256=hovhxGKK3et_Lny7UuXsterP_OUSZ1HW7YqhawEXrOw,3740
56
- c2cgeoportal_admin/views/ogc_servers.py,sha256=rK0dIS2XLTc5EDeGrnDf_mpHlNXJsCEyUpci_lIexR8,7476
57
- c2cgeoportal_admin/views/restriction_areas.py,sha256=0Zpo8p5Zsw3JdPCH8kqWr020boBpNiKMhARKcgCsOVU,5549
58
- c2cgeoportal_admin/views/roles.py,sha256=7BjQ0zLcsf6JW8OgBKJukaMRksUB-VKTeILfhP9bLG0,5858
59
- c2cgeoportal_admin/views/themes.py,sha256=Qv6sZ7op90JEd7ASGuTU68rjTdsRrGlf0clYqqumuFI,5710
60
- c2cgeoportal_admin/views/themes_ordering.py,sha256=NYN3I2tDwLW5E4G-695DwV0dCbHUAObWVFYZ8Bir1-o,5590
61
- c2cgeoportal_admin/views/treeitems.py,sha256=p-Ba_v3UFtUZEmlct4MZmkwv7jzMoxNKnCVa_FX2hxg,3860
62
- c2cgeoportal_admin/views/users.py,sha256=YzyKYDDTVn69NQPkrlkmbpgrtsIkK_cxqlcWa6utAVA,5355
63
- tests/__init__.py,sha256=JbVMbOZgS0u5_MhWBnyzT1gdv3cXwhkXyLQgDqpZAik,9525
64
- tests/conftest.py,sha256=ah7JmR2epDZul2rmMH5wuUzkSpXIjm8dd-cgGjK6_k0,2119
65
- tests/test_edit_url.py,sha256=00Q9E3QOtsEEB0YJQehllFr1ztQCU3wc9OyayXCHYI4,4495
66
- tests/test_functionalities.py,sha256=CPHxBueoCt8W76VJN2sCouxQyc7LD7ccusRah5UK2ys,4126
67
- tests/test_home.py,sha256=oA4i-V9jJQQgHD9Gz79mgIEMUCRw3tmIQVqdhM9Q2Fo,426
68
- tests/test_interface.py,sha256=ml1yM4t1o6jIQEHZRwMywjt7mjkUhP-34VKBgHOmWes,4704
69
- tests/test_layer_groups.py,sha256=Bb1Rsy8QkzGee6edY4UQY8hcxvp54PE7gXUcHoi__JA,11062
70
- tests/test_layers_vectortiles.py,sha256=DjOLkm3o8nPJJbd010Xi_pwHTK5roiHoQBYAuNaZW5c,9395
71
- tests/test_layers_wms.py,sha256=MISvkAjEZ4oSD1xg7Zah_GKiBHNu60D8kT03f241wuc,18175
72
- tests/test_layers_wmts.py,sha256=jjO3AbOQgHgC2yXdYke339W11Ygz1b8DpuAn4OXLnxE,11185
73
- tests/test_layertree.py,sha256=uu-2AzVtqr87eqq9w_5EWPR_KIXFFjEipEA0_ImnkCU,11336
74
- tests/test_learn.py,sha256=gQwe-Bim0eihZH0rbBWDn6_rIBxvQD_lyu9MlOljupM,2307
75
- tests/test_left_menu.py,sha256=-K_429ZcW5Hsz317StIRVz8VtU7GDMH7UCTzZDfckUo,920
76
- tests/test_lingua_extractor_config.py,sha256=3dqgIdCB1M3YPzXrgDCFQ74t0t4QRXwdQZSy6AMqKp8,2515
77
- tests/test_main.py,sha256=_gUdMrMMAEzvGIf1QwkoHQkd0eBACz05ycTidCHP5Ao,365
78
- tests/test_metadatas.py,sha256=dawAKLxyWy4Ok3TWAR5zsB_IN_Ci_VJdjNE9fU5NVjE,12089
79
- tests/test_oauth2_clients.py,sha256=UaTz7jE0-V2JJ4VkjA3W0FlzgkfacI1jchiynXNNYbc,5782
80
- tests/test_ogc_servers.py,sha256=qPrbLFw8zaPOpk-fbydJUtfgLl9nxA81jOUNd1l8EUI,6436
81
- tests/test_restriction_areas.py,sha256=S97lbxHghyhz9h8Sv78jYt2EOQEgwlUp8zCfOtmV-OU,7925
82
- tests/test_role.py,sha256=99Rk4PCTtoVzbiTP3cR3cVkuIArdLywBl2Hx8Pk5lnE,11820
83
- tests/test_themes.py,sha256=e-OGon6beHfY4q8xOGsYjW-_pm0-wTA18DPBOz6F9iM,15181
84
- tests/test_themes_ordering.py,sha256=qIEgLgIjSYpWqMVXBAhOk6BKBUAPXkiXsxWB_A1Dy4s,2244
85
- tests/test_treegroup.py,sha256=Plv119G4TWlurWLE7Z1mWGeHHPScK_fWKcDmDzMUlIU,576
86
- tests/test_user.py,sha256=pW2Fsbw8wIP2H3BxAMUojSonhMMyr63jsWFmEteaogk,11659
87
- tests/themes_ordering.py,sha256=mbjTJHl63UVdv5SsfgDrjOx-1z6C5L4wDSCzIh7LPAE,1343
88
- c2cgeoportal_admin-2.7.1.156.dist-info/METADATA,sha256=cRegyrlS02-K1HNMG99ohp7l0WSyWQpqnPMJC7zInU4,1492
89
- c2cgeoportal_admin-2.7.1.156.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
90
- c2cgeoportal_admin-2.7.1.156.dist-info/entry_points.txt,sha256=ZF-xnP-Q_zr7y6yRmVqjIGVZ1L2iKi5uaOxjxJQBuG4,164
91
- c2cgeoportal_admin-2.7.1.156.dist-info/top_level.txt,sha256=DgcTJgTvpJUB8HqwYB14PdLBPAOAFk0B8oqnSTFoAU4,25
92
- c2cgeoportal_admin-2.7.1.156.dist-info/RECORD,,