c2cgeoportal-admin 2.6.0__py3-none-any.whl → 2.9rc44__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. c2cgeoportal_admin/__init__.py +42 -12
  2. c2cgeoportal_admin/lib/lingva_extractor.py +77 -0
  3. c2cgeoportal_admin/lib/ogcserver_synchronizer.py +170 -57
  4. c2cgeoportal_admin/py.typed +0 -0
  5. c2cgeoportal_admin/routes.py +18 -6
  6. c2cgeoportal_admin/schemas/dimensions.py +16 -10
  7. c2cgeoportal_admin/schemas/functionalities.py +59 -21
  8. c2cgeoportal_admin/schemas/interfaces.py +26 -18
  9. c2cgeoportal_admin/schemas/metadata.py +101 -48
  10. c2cgeoportal_admin/schemas/restriction_areas.py +25 -19
  11. c2cgeoportal_admin/schemas/roles.py +12 -6
  12. c2cgeoportal_admin/schemas/treegroup.py +46 -21
  13. c2cgeoportal_admin/schemas/treeitem.py +3 -4
  14. c2cgeoportal_admin/static/layertree.css +3 -4
  15. c2cgeoportal_admin/static/navbar.css +36 -35
  16. c2cgeoportal_admin/static/theme.css +19 -9
  17. c2cgeoportal_admin/subscribers.py +3 -3
  18. c2cgeoportal_admin/templates/404.jinja2 +18 -2
  19. c2cgeoportal_admin/templates/layertree.jinja2 +31 -9
  20. c2cgeoportal_admin/templates/navigation_navbar.jinja2 +33 -0
  21. c2cgeoportal_admin/templates/ogcserver_synchronize.jinja2 +12 -0
  22. c2cgeoportal_admin/templates/widgets/functionality_fields.pt +51 -0
  23. c2cgeoportal_admin/templates/widgets/metadata.pt +7 -1
  24. c2cgeoportal_admin/views/__init__.py +29 -0
  25. c2cgeoportal_admin/views/dimension_layers.py +14 -9
  26. c2cgeoportal_admin/views/functionalities.py +52 -18
  27. c2cgeoportal_admin/views/home.py +5 -5
  28. c2cgeoportal_admin/views/interfaces.py +26 -20
  29. c2cgeoportal_admin/views/layer_groups.py +36 -25
  30. c2cgeoportal_admin/views/layers.py +17 -13
  31. c2cgeoportal_admin/views/layers_cog.py +135 -0
  32. c2cgeoportal_admin/views/layers_vectortiles.py +62 -27
  33. c2cgeoportal_admin/views/layers_wms.py +55 -34
  34. c2cgeoportal_admin/views/layers_wmts.py +54 -34
  35. c2cgeoportal_admin/views/layertree.py +38 -29
  36. c2cgeoportal_admin/views/logged_views.py +83 -0
  37. c2cgeoportal_admin/views/logs.py +91 -0
  38. c2cgeoportal_admin/views/oauth2_clients.py +30 -18
  39. c2cgeoportal_admin/views/ogc_servers.py +132 -36
  40. c2cgeoportal_admin/views/restriction_areas.py +39 -27
  41. c2cgeoportal_admin/views/roles.py +42 -28
  42. c2cgeoportal_admin/views/themes.py +47 -35
  43. c2cgeoportal_admin/views/themes_ordering.py +19 -14
  44. c2cgeoportal_admin/views/treeitems.py +21 -17
  45. c2cgeoportal_admin/views/users.py +46 -26
  46. c2cgeoportal_admin/widgets.py +17 -14
  47. {c2cgeoportal_admin-2.6.0.dist-info → c2cgeoportal_admin-2.9rc44.dist-info}/METADATA +12 -12
  48. c2cgeoportal_admin-2.9rc44.dist-info/RECORD +97 -0
  49. {c2cgeoportal_admin-2.6.0.dist-info → c2cgeoportal_admin-2.9rc44.dist-info}/WHEEL +1 -1
  50. c2cgeoportal_admin-2.9rc44.dist-info/entry_points.txt +5 -0
  51. tests/__init__.py +24 -20
  52. tests/conftest.py +22 -11
  53. tests/test_edit_url.py +11 -14
  54. tests/test_functionalities.py +52 -14
  55. tests/test_home.py +0 -1
  56. tests/test_interface.py +34 -11
  57. tests/test_layer_groups.py +57 -27
  58. tests/test_layers_cog.py +243 -0
  59. tests/test_layers_vectortiles.py +43 -25
  60. tests/test_layers_wms.py +67 -45
  61. tests/test_layers_wmts.py +47 -26
  62. tests/test_layertree.py +99 -16
  63. tests/test_left_menu.py +0 -1
  64. tests/test_lingva_extractor_config.py +64 -0
  65. tests/test_logs.py +102 -0
  66. tests/test_main.py +3 -1
  67. tests/test_metadatas.py +34 -21
  68. tests/test_oauth2_clients.py +40 -11
  69. tests/test_ogc_servers.py +84 -35
  70. tests/test_restriction_areas.py +38 -15
  71. tests/test_role.py +71 -43
  72. tests/test_themes.py +71 -37
  73. tests/test_themes_ordering.py +1 -2
  74. tests/test_treegroup.py +2 -2
  75. tests/test_user.py +56 -19
  76. tests/themes_ordering.py +1 -2
  77. c2cgeoportal_admin/templates/navigation_vertical.jinja2 +0 -33
  78. c2cgeoportal_admin-2.6.0.dist-info/RECORD +0 -89
  79. c2cgeoportal_admin-2.6.0.dist-info/entry_points.txt +0 -3
  80. {c2cgeoportal_admin-2.6.0.dist-info → c2cgeoportal_admin-2.9rc44.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
 
@@ -17,8 +18,8 @@ def ogc_server_test_data(dbsession, transact):
17
18
  auth = ["No auth", "Standard auth", "Geoserver auth", "Proxy"]
18
19
  servers = []
19
20
  for i in range(0, 8):
20
- server = OGCServer(name="server_{}".format(i), description="description_{}".format(i))
21
- server.url = "https://somebasicurl_{}.com".format(i)
21
+ server = OGCServer(name=f"server_{i}", description=f"description_{i}")
22
+ server.url = f"https://somebasicurl_{i}.com"
22
23
  server.image_type = "image/jpeg" if i % 2 == 0 else "image/png"
23
24
  server.auth = auth[i % 4]
24
25
  dbsession.add(server)
@@ -31,7 +32,6 @@ def ogc_server_test_data(dbsession, transact):
31
32
 
32
33
  @pytest.mark.usefixtures("ogc_server_test_data", "test_app")
33
34
  class TestOGCServer(AbstractViewsTests):
34
-
35
35
  _prefix = "/admin/ogc_servers"
36
36
 
37
37
  def test_index_rendering(self, test_app):
@@ -59,54 +59,82 @@ class TestOGCServer(AbstractViewsTests):
59
59
  self.check_search(test_app, "server_0", total=1)
60
60
 
61
61
  def test_submit_new(self, dbsession, test_app):
62
- from c2cgeoportal_commons.models.main import OGCServer
63
-
64
- 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
- resp = test_app.get("/admin/ogc_servers/{}".format(ogc_server.id), status=200)
95
+ resp = test_app.get(f"/admin/ogc_servers/{ogc_server.id}", status=200)
85
96
  form = resp.form
86
97
  assert str(ogc_server.id) == self.get_first_field_named(form, "id").value
87
98
  assert "hidden" == self.get_first_field_named(form, "id").attrs["type"]
88
99
  assert ogc_server.name == form["name"].value
89
100
  form["description"] = "new_description"
90
- 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("/admin/ogc_servers/{}".format(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
103
130
 
104
131
  ogc_server = ogc_server_test_data["ogc_servers"][3]
105
- resp = test_app.get("/admin/ogc_servers/{}/duplicate".format(ogc_server.id), status=200)
132
+ resp = test_app.get(f"/admin/ogc_servers/{ogc_server.id}/duplicate", status=200)
106
133
  form = resp.form
107
134
  assert "" == self.get_first_field_named(form, "id").value
108
135
  self.set_first_field_named(form, "name", "clone")
109
- 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(
@@ -115,18 +143,18 @@ class TestOGCServer(AbstractViewsTests):
115
143
 
116
144
  def test_unicity_validator(self, ogc_server_test_data, test_app):
117
145
  ogc_server = ogc_server_test_data["ogc_servers"][3]
118
- resp = test_app.get("/admin/ogc_servers/{}/duplicate".format(ogc_server.id), status=200)
146
+ resp = test_app.get(f"/admin/ogc_servers/{ogc_server.id}/duplicate", status=200)
119
147
 
120
148
  resp = resp.form.submit("submit")
121
149
 
122
- self._check_submission_problem(resp, "{} is already used.".format(ogc_server.name))
150
+ self._check_submission_problem(resp, f"{ogc_server.name} is already used.")
123
151
 
124
152
  def test_check_success(self, ogc_server_test_data, test_app):
125
153
  ogc_server = ogc_server_test_data["ogc_servers"][3]
126
154
  ogc_server.url = "config://mapserver"
127
- resp = test_app.get("/admin/ogc_servers/{}/synchronize".format(ogc_server.id), status=200)
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."
@@ -135,20 +163,41 @@ class TestOGCServer(AbstractViewsTests):
135
163
  def test_dry_run_success(self, ogc_server_test_data, test_app):
136
164
  ogc_server = ogc_server_test_data["ogc_servers"][3]
137
165
  ogc_server.url = "config://mapserver"
138
- resp = test_app.get("/admin/ogc_servers/{}/synchronize".format(ogc_server.id), status=200)
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
- resp = test_app.get("/admin/ogc_servers/{}/synchronize".format(ogc_server.id), status=200)
179
+ resp = test_app.get(f"/admin/ogc_servers/{ogc_server.id}/synchronize", status=200)
180
+
181
+ resp = resp.forms["form-synchronize"].submit("synchronize")
182
+
183
+ log = dbsession.query(Log).one()
184
+ assert log.date != None
185
+ assert log.action == LogAction.SYNCHRONIZE
186
+ assert log.element_type == "ogc_server"
187
+ assert log.element_id == ogc_server.id
188
+ assert log.element_name == ogc_server.name
189
+ assert log.username == "test_user"
190
+
191
+ assert list(resp.html.find("div", class_="alert-success").stripped_strings) == [
192
+ "OGC Server has been successfully synchronized."
193
+ ]
194
+
195
+ form = resp.forms["form-synchronize"]
196
+ form["force-parents"].checked = True
197
+ form["force-ordering"].checked = True
198
+ form["clean"].checked = True
150
199
 
151
- resp = resp.forms["form-synchronize"].submit("submit")
200
+ resp = form.submit("synchronize")
152
201
 
153
202
  assert list(resp.html.find("div", class_="alert-success").stripped_strings) == [
154
203
  "OGC Server has been successfully synchronized."
@@ -25,16 +25,16 @@ def restriction_area_test_data(dbsession, transact):
25
25
  ogc_server = OGCServer(name="test_server")
26
26
  layers = []
27
27
  for i in range(0, 4):
28
- layer = LayerWMS(name="layer_{}".format(i), layer="layer_{}".format(i), public=False)
28
+ layer = LayerWMS(name=f"layer_{i}", layer=f"layer_{i}", public=False)
29
29
  layer.ogc_server = ogc_server
30
30
  layers.append(layer)
31
31
  dbsession.add_all(layers)
32
32
 
33
33
  restrictionareas = []
34
34
  for i in range(0, 4):
35
- restrictionarea = RestrictionArea(name="restrictionarea_{}".format(i))
35
+ restrictionarea = RestrictionArea(name=f"restrictionarea_{i}")
36
36
  restrictionarea.area = from_shape(box(485869.5728, 76443.1884, 837076.5648, 299941.7864), srid=21781)
37
- restrictionarea.description = "description_{}".format(i)
37
+ restrictionarea.description = f"description_{i}"
38
38
  restrictionarea.roles = [roles[i % 4], roles[(i + 2) % 4]]
39
39
  restrictionarea.layers = [layers[i % 4], layers[(i + 2) % 4]]
40
40
  dbsession.add(restrictionarea)
@@ -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"]
@@ -113,18 +112,28 @@ class TestRestrictionAreaViews(TestTreeGroup):
113
112
  assert restriction_area.name == "new_name"
114
113
  assert restriction_area.description == "new_description"
115
114
  assert restriction_area.readwrite
116
- assert set(restriction_area.roles) == set([roles[0], roles[1]])
117
- assert set(restriction_area.layers) == set([layers[0], layers[1]])
115
+ assert set(restriction_area.roles) == {roles[0], roles[1]}
116
+ assert set(restriction_area.layers) == {layers[0], layers[1]}
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"
118
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
 
122
- resp = test_app.get("/admin/restriction_areas/{}/duplicate".format(restriction_area.id), status=200)
129
+ resp = test_app.get(f"/admin/restriction_areas/{restriction_area.id}/duplicate", status=200)
123
130
  resp = resp.form.submit("submit")
124
131
 
125
- self._check_submission_problem(resp, "{} is already used.".format(restriction_area.name))
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
 
@@ -162,16 +171,32 @@ class TestRestrictionAreaViews(TestTreeGroup):
162
171
 
163
172
  dbsession.expire(restriction_area)
164
173
  assert restriction_area.description == "new_description"
165
- assert set(restriction_area.roles) == set([roles[i] for i in range(0, 3)])
174
+ assert set(restriction_area.roles) == {roles[i] for i in range(0, 3)}
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"
166
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
- test_app.delete("/admin/restriction_areas/{}".format(deleted_id), status=200)
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
 
@@ -181,9 +206,7 @@ class TestRestrictionAreaViews(TestTreeGroup):
181
206
  # Ensure restriction_area.layers is loaded with relationship "order_by"
182
207
  dbsession.expire(restriction_area)
183
208
 
184
- form = test_app.get(
185
- "/admin/restriction_areas/{}/duplicate".format(restriction_area.id), status=200
186
- ).form
209
+ form = test_app.get(f"/admin/restriction_areas/{restriction_area.id}/duplicate", status=200).form
187
210
 
188
211
  assert "" == self.get_first_field_named(form, "id").value
189
212
  self._check_roles(form, roles, restriction_area)
tests/test_role.py CHANGED
@@ -3,6 +3,7 @@
3
3
  import json
4
4
  import re
5
5
 
6
+ import pyramid.httpexceptions
6
7
  import pytest
7
8
  from geoalchemy2.shape import from_shape, to_shape
8
9
  from pyramid.testing import DummyRequest
@@ -19,17 +20,18 @@ def roles_test_data(dbsession, transact):
19
20
  from c2cgeoportal_commons.models.main import Functionality, RestrictionArea, Role
20
21
  from c2cgeoportal_commons.models.static import User
21
22
 
23
+ # Note that "default_basemap" is not relevant for roles
22
24
  functionalities = {}
23
- for name in ("default_basemap", "location"):
25
+ for name in ("default_basemap", "default_theme", "print_template"):
24
26
  functionalities[name] = []
25
27
  for v in range(0, 4):
26
- functionality = Functionality(name=name, value="value_{}".format(v))
28
+ functionality = Functionality(name=name, value=f"value_{v}")
27
29
  dbsession.add(functionality)
28
30
  functionalities[name].append(functionality)
29
31
 
30
32
  restrictionareas = []
31
33
  for i in range(0, 5):
32
- restrictionarea = RestrictionArea(name="restrictionarea_{}".format(i))
34
+ restrictionarea = RestrictionArea(name=f"restrictionarea_{i}")
33
35
  dbsession.add(restrictionarea)
34
36
  restrictionareas.append(restrictionarea)
35
37
 
@@ -37,9 +39,9 @@ def roles_test_data(dbsession, transact):
37
39
  for i in range(0, 23):
38
40
  role = Role("secretary_" + str(i))
39
41
  role.functionalities = [
40
- functionalities["default_basemap"][0],
41
- functionalities["location"][0],
42
- functionalities["location"][1],
42
+ functionalities["default_theme"][0],
43
+ functionalities["print_template"][0],
44
+ functionalities["print_template"][1],
43
45
  ]
44
46
  role.restrictionareas = [restrictionareas[0], restrictionareas[1]]
45
47
  role.extent = from_shape(box(485869.5728, 76443.1884, 837076.5648, 299941.7864), srid=21781)
@@ -67,7 +69,6 @@ def roles_test_data(dbsession, transact):
67
69
 
68
70
  @pytest.mark.usefixtures("roles_test_data", "test_app")
69
71
  class TestRole(TestTreeGroup):
70
-
71
72
  _prefix = "/admin/roles"
72
73
 
73
74
  def test_index_rendering(self, test_app):
@@ -102,9 +103,9 @@ class TestRole(TestTreeGroup):
102
103
  self.check_grid_headers(resp, expected, new="Nouveau")
103
104
 
104
105
  def test_submit_new(self, dbsession, test_app, roles_test_data):
105
- from c2cgeoportal_commons.models.main import Role
106
+ from c2cgeoportal_commons.models.main import Log, LogAction, Role
106
107
 
107
- roles = roles_test_data["roles"]
108
+ roles_test_data["roles"]
108
109
  functionalities = roles_test_data["functionalities"]
109
110
  restrictionareas = roles_test_data["restrictionareas"]
110
111
  users = roles_test_data["users"]
@@ -120,7 +121,7 @@ class TestRole(TestTreeGroup):
120
121
  ("extent", ""),
121
122
  ("__start__", "functionalities:sequence"),
122
123
  ("functionalities", str(functionalities["default_basemap"][0].id)),
123
- ("functionalities", str(functionalities["location"][1].id)),
124
+ ("functionalities", str(functionalities["print_template"][1].id)),
124
125
  ("__end__", "functionalities:sequence"),
125
126
  ("__start__", "restrictionareas:sequence"),
126
127
  ("restrictionareas", str(restrictionareas[0].id)),
@@ -146,13 +147,24 @@ class TestRole(TestTreeGroup):
146
147
 
147
148
  assert role.name == "new_name"
148
149
  assert role.description == "new_description"
149
- assert set(role.functionalities) == set(
150
- [functionalities["default_basemap"][0], functionalities["location"][1]]
151
- )
152
- assert set(role.restrictionareas) == set([restrictionareas[0], restrictionareas[1]])
153
- assert set(role.users) == set([users[0], users[1]])
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]}
156
+
157
+ log = dbsession.query(Log).one()
158
+ assert log.date != None
159
+ assert log.action == LogAction.INSERT
160
+ assert log.element_type == "role"
161
+ assert log.element_id == role.id
162
+ assert log.element_name == role.name
163
+ assert log.username == "test_user"
154
164
 
155
165
  def test_edit(self, dbsession, test_app, roles_test_data):
166
+ from c2cgeoportal_commons.models.main import Log, LogAction
167
+
156
168
  role = roles_test_data["roles"][10]
157
169
 
158
170
  # Ensure role.users is loaded with relationship "order_by"
@@ -174,33 +186,33 @@ class TestRole(TestTreeGroup):
174
186
  assert expected.almost_equals(shape(json.loads(form["extent"].value)), decimal=0)
175
187
 
176
188
  functionalities = roles_test_data["functionalities"]
177
- assert (
178
- set(
179
- (
180
- functionalities["default_basemap"][0].id,
181
- functionalities["location"][0].id,
182
- functionalities["location"][1].id,
183
- )
184
- )
185
- == set(f.id for f in role.functionalities)
186
- )
189
+ assert {
190
+ functionalities["default_theme"][0].id,
191
+ functionalities["print_template"][0].id,
192
+ functionalities["print_template"][1].id,
193
+ } == {f.id for f in role.functionalities}
187
194
  self.check_checkboxes(
188
195
  form,
189
196
  "functionalities",
190
197
  [
191
198
  {
192
- "label": "{}={}".format(f.name, f.value),
199
+ "label": f"{f.name}={f.value}",
193
200
  "value": str(f.id),
194
201
  "checked": f in role.functionalities,
195
202
  }
196
- for f in sum(
197
- [roles_test_data["functionalities"][name] for name in ("default_basemap", "location")], []
203
+ for f in sorted(
204
+ [
205
+ f
206
+ for f in sum(functionalities.values(), [])
207
+ if f.name in ("default_theme", "print_template")
208
+ ],
209
+ key=lambda f: (f.name, f.value),
198
210
  )
199
211
  ],
200
212
  )
201
213
 
202
214
  ras = roles_test_data["restrictionareas"]
203
- assert set((ras[0].id, ras[1].id)) == set(ra.id for ra in role.restrictionareas)
215
+ assert {ras[0].id, ras[1].id} == {ra.id for ra in role.restrictionareas}
204
216
  self.check_checkboxes(
205
217
  form,
206
218
  "restrictionareas",
@@ -237,9 +249,9 @@ class TestRole(TestTreeGroup):
237
249
  )
238
250
 
239
251
  functionality_ids = [
240
- roles_test_data["functionalities"]["default_basemap"][1].id,
241
- roles_test_data["functionalities"]["location"][1].id,
242
- roles_test_data["functionalities"]["default_basemap"][2].id,
252
+ roles_test_data["functionalities"]["default_theme"][1].id,
253
+ roles_test_data["functionalities"]["print_template"][1].id,
254
+ roles_test_data["functionalities"]["print_template"][2].id,
243
255
  ]
244
256
  form["functionalities"] = [str(id) for id in functionality_ids]
245
257
 
@@ -268,15 +280,23 @@ class TestRole(TestTreeGroup):
268
280
  )
269
281
  assert expected.almost_equals(to_shape(role.extent), decimal=0)
270
282
 
271
- assert set(functionality_ids) == set([f.id for f in role.functionalities])
272
- assert set(ra_ids) == set([f.id for f in role.restrictionareas])
283
+ assert set(functionality_ids) == {f.id for f in role.functionalities}
284
+ assert set(ra_ids) == {f.id for f in role.restrictionareas}
285
+
286
+ log = dbsession.query(Log).one()
287
+ assert log.date != None
288
+ assert log.action == LogAction.UPDATE
289
+ assert log.element_type == "role"
290
+ assert log.element_id == role.id
291
+ assert log.element_name == role.name
292
+ assert log.username == "test_user"
273
293
 
274
294
  def test_duplicate(self, roles_test_data, test_app, dbsession):
275
295
  from c2cgeoportal_commons.models.main import Role
276
296
 
277
297
  role_proto = roles_test_data["roles"][7]
278
298
 
279
- resp = test_app.get("/admin/roles/{}/duplicate".format(role_proto.id), status=200)
299
+ resp = test_app.get(f"/admin/roles/{role_proto.id}/duplicate", status=200)
280
300
  form = resp.form
281
301
 
282
302
  assert "" == self.get_first_field_named(form, "id").value
@@ -295,24 +315,32 @@ class TestRole(TestTreeGroup):
295
315
  assert set(role_proto.users) == set(role.users)
296
316
 
297
317
  def test_delete(self, test_app, dbsession):
298
- from c2cgeoportal_commons.models.main import Role
318
+ from c2cgeoportal_commons.models.main import Log, LogAction, Role
319
+
320
+ role = dbsession.query(Role).first()
321
+ test_app.delete(f"/admin/roles/{role.id}", status=200)
322
+ assert dbsession.query(Role).get(role.id) is None
299
323
 
300
- role_id = dbsession.query(Role.id).first().id
301
- test_app.delete("/admin/roles/{}".format(role_id), status=200)
302
- assert dbsession.query(Role).get(role_id) is None
324
+ log = dbsession.query(Log).one()
325
+ assert log.date != None
326
+ assert log.action == LogAction.DELETE
327
+ assert log.element_type == "role"
328
+ assert log.element_id == role.id
329
+ assert log.element_name == role.name
330
+ assert log.username == "test_user"
303
331
 
304
332
  def test_unicity_validator(self, roles_test_data, test_app):
305
333
  role_proto = roles_test_data["roles"][7]
306
- resp = test_app.get("/admin/roles/{}/duplicate".format(role_proto.id), status=200)
334
+ resp = test_app.get(f"/admin/roles/{role_proto.id}/duplicate", status=200)
307
335
 
308
336
  resp = resp.form.submit("submit")
309
337
 
310
- self._check_submission_problem(resp, "{} is already used.".format(role_proto.name))
338
+ self._check_submission_problem(resp, f"{role_proto.name} is already used.")
311
339
 
312
340
  @pytest.mark.usefixtures("raise_db_error_on_query")
313
341
  def test_grid_dberror(self, dbsession):
314
342
  from c2cgeoportal_admin.views.roles import RoleViews
315
343
 
316
344
  request = DummyRequest(dbsession=dbsession, params={"offset": 0, "limit": 10})
317
- info = RoleViews(request).grid()
318
- assert info.status_int == 500, "Expected 500 status when db error"
345
+ with pytest.raises(pyramid.httpexceptions.HTTPInternalServerError):
346
+ RoleViews(request).grid()