c2cgeoportal-admin 2.5.0.100__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.
- c2cgeoportal_admin/__init__.py +44 -14
- c2cgeoportal_admin/lib/__init__.py +0 -0
- c2cgeoportal_admin/lib/lingva_extractor.py +77 -0
- c2cgeoportal_admin/lib/ogcserver_synchronizer.py +410 -0
- c2cgeoportal_admin/py.typed +0 -0
- c2cgeoportal_admin/routes.py +30 -11
- c2cgeoportal_admin/schemas/dimensions.py +17 -11
- c2cgeoportal_admin/schemas/functionalities.py +60 -22
- c2cgeoportal_admin/schemas/interfaces.py +27 -19
- c2cgeoportal_admin/schemas/metadata.py +122 -48
- c2cgeoportal_admin/schemas/restriction_areas.py +26 -20
- c2cgeoportal_admin/schemas/roles.py +13 -7
- c2cgeoportal_admin/schemas/treegroup.py +90 -20
- c2cgeoportal_admin/schemas/treeitem.py +3 -4
- c2cgeoportal_admin/static/layertree.css +26 -4
- c2cgeoportal_admin/static/navbar.css +59 -36
- c2cgeoportal_admin/static/theme.css +51 -11
- c2cgeoportal_admin/subscribers.py +3 -3
- c2cgeoportal_admin/templates/404.jinja2 +41 -2
- c2cgeoportal_admin/templates/edit.jinja2 +23 -0
- c2cgeoportal_admin/templates/home.jinja2 +23 -0
- c2cgeoportal_admin/templates/index.jinja2 +23 -0
- c2cgeoportal_admin/templates/layertree.jinja2 +55 -11
- c2cgeoportal_admin/templates/layout.jinja2 +23 -0
- c2cgeoportal_admin/templates/navigation_navbar.jinja2 +56 -0
- c2cgeoportal_admin/templates/ogcserver_synchronize.jinja2 +90 -0
- c2cgeoportal_admin/templates/widgets/child.pt +35 -3
- c2cgeoportal_admin/templates/widgets/children.pt +121 -92
- c2cgeoportal_admin/templates/widgets/dimension.pt +23 -0
- c2cgeoportal_admin/templates/widgets/dimensions.pt +23 -0
- c2cgeoportal_admin/templates/widgets/functionality_fields.pt +51 -0
- c2cgeoportal_admin/templates/widgets/layer_fields.pt +23 -0
- c2cgeoportal_admin/templates/widgets/layer_group_fields.pt +23 -0
- c2cgeoportal_admin/templates/widgets/layer_v1_fields.pt +23 -0
- c2cgeoportal_admin/templates/widgets/metadata.pt +30 -1
- c2cgeoportal_admin/templates/widgets/metadatas.pt +23 -0
- c2cgeoportal_admin/templates/widgets/ogcserver_fields.pt +23 -0
- c2cgeoportal_admin/templates/widgets/restriction_area_fields.pt +25 -9
- c2cgeoportal_admin/templates/widgets/role_fields.pt +52 -25
- c2cgeoportal_admin/templates/widgets/theme_fields.pt +23 -0
- c2cgeoportal_admin/templates/widgets/user_fields.pt +23 -0
- c2cgeoportal_admin/views/__init__.py +29 -0
- c2cgeoportal_admin/views/dimension_layers.py +14 -9
- c2cgeoportal_admin/views/functionalities.py +52 -18
- c2cgeoportal_admin/views/home.py +5 -5
- c2cgeoportal_admin/views/interfaces.py +29 -21
- c2cgeoportal_admin/views/layer_groups.py +36 -25
- c2cgeoportal_admin/views/layers.py +17 -13
- c2cgeoportal_admin/views/layers_cog.py +135 -0
- c2cgeoportal_admin/views/layers_vectortiles.py +62 -27
- c2cgeoportal_admin/views/layers_wms.py +61 -36
- c2cgeoportal_admin/views/layers_wmts.py +54 -32
- c2cgeoportal_admin/views/layertree.py +37 -28
- c2cgeoportal_admin/views/logged_views.py +83 -0
- c2cgeoportal_admin/views/logs.py +91 -0
- c2cgeoportal_admin/views/oauth2_clients.py +96 -0
- c2cgeoportal_admin/views/ogc_servers.py +192 -21
- c2cgeoportal_admin/views/restriction_areas.py +78 -25
- c2cgeoportal_admin/views/roles.py +88 -25
- c2cgeoportal_admin/views/themes.py +47 -35
- c2cgeoportal_admin/views/themes_ordering.py +44 -24
- c2cgeoportal_admin/views/treeitems.py +21 -17
- c2cgeoportal_admin/views/users.py +46 -26
- c2cgeoportal_admin/widgets.py +79 -28
- {c2cgeoportal_admin-2.5.0.100.dist-info → c2cgeoportal_admin-2.9rc44.dist-info}/METADATA +15 -13
- c2cgeoportal_admin-2.9rc44.dist-info/RECORD +97 -0
- {c2cgeoportal_admin-2.5.0.100.dist-info → c2cgeoportal_admin-2.9rc44.dist-info}/WHEEL +1 -1
- c2cgeoportal_admin-2.9rc44.dist-info/entry_points.txt +5 -0
- tests/__init__.py +36 -27
- tests/conftest.py +23 -24
- tests/test_edit_url.py +16 -19
- tests/test_functionalities.py +52 -14
- tests/test_home.py +0 -1
- tests/test_interface.py +35 -12
- tests/test_layer_groups.py +58 -32
- tests/test_layers_cog.py +243 -0
- tests/test_layers_vectortiles.py +46 -30
- tests/test_layers_wms.py +77 -82
- tests/test_layers_wmts.py +51 -30
- tests/test_layertree.py +107 -101
- tests/test_learn.py +1 -1
- tests/test_left_menu.py +0 -1
- tests/test_lingva_extractor_config.py +64 -0
- tests/test_logs.py +102 -0
- tests/test_main.py +4 -2
- tests/test_metadatas.py +79 -71
- tests/test_oauth2_clients.py +186 -0
- tests/test_ogc_servers.py +110 -28
- tests/test_restriction_areas.py +109 -20
- tests/test_role.py +142 -82
- tests/test_themes.py +75 -41
- tests/test_themes_ordering.py +1 -2
- tests/test_treegroup.py +2 -2
- tests/test_user.py +72 -70
- tests/themes_ordering.py +1 -2
- c2cgeoportal_admin/templates/navigation_vertical.jinja2 +0 -10
- c2cgeoportal_admin-2.5.0.100.dist-info/RECORD +0 -84
- c2cgeoportal_admin-2.5.0.100.dist-info/entry_points.txt +0 -3
- {c2cgeoportal_admin-2.5.0.100.dist-info → c2cgeoportal_admin-2.9rc44.dist-info}/top_level.txt +0 -0
tests/test_restriction_areas.py
CHANGED
@@ -4,40 +4,52 @@
|
|
4
4
|
import json
|
5
5
|
import re
|
6
6
|
|
7
|
-
from geoalchemy2.shape import from_shape
|
8
7
|
import pytest
|
8
|
+
from geoalchemy2.shape import from_shape
|
9
9
|
from shapely.geometry import Polygon, box, shape
|
10
10
|
|
11
|
-
from . import
|
11
|
+
from .test_treegroup import TestTreeGroup
|
12
12
|
|
13
13
|
|
14
14
|
@pytest.fixture(scope="function")
|
15
15
|
@pytest.mark.usefixtures("dbsession", "transact")
|
16
16
|
def restriction_area_test_data(dbsession, transact):
|
17
17
|
del transact
|
18
|
-
from c2cgeoportal_commons.models.main import RestrictionArea, Role
|
18
|
+
from c2cgeoportal_commons.models.main import LayerWMS, OGCServer, RestrictionArea, Role
|
19
19
|
|
20
20
|
roles = []
|
21
21
|
for i in range(0, 4):
|
22
22
|
roles.append(Role("secretary_" + str(i)))
|
23
|
-
|
23
|
+
dbsession.add_all(roles)
|
24
|
+
|
25
|
+
ogc_server = OGCServer(name="test_server")
|
26
|
+
layers = []
|
27
|
+
for i in range(0, 4):
|
28
|
+
layer = LayerWMS(name=f"layer_{i}", layer=f"layer_{i}", public=False)
|
29
|
+
layer.ogc_server = ogc_server
|
30
|
+
layers.append(layer)
|
31
|
+
dbsession.add_all(layers)
|
24
32
|
|
25
33
|
restrictionareas = []
|
26
34
|
for i in range(0, 4):
|
27
|
-
restrictionarea = RestrictionArea(name="restrictionarea_{}"
|
35
|
+
restrictionarea = RestrictionArea(name=f"restrictionarea_{i}")
|
28
36
|
restrictionarea.area = from_shape(box(485869.5728, 76443.1884, 837076.5648, 299941.7864), srid=21781)
|
29
|
-
restrictionarea.description = "description_{}"
|
37
|
+
restrictionarea.description = f"description_{i}"
|
30
38
|
restrictionarea.roles = [roles[i % 4], roles[(i + 2) % 4]]
|
39
|
+
restrictionarea.layers = [layers[i % 4], layers[(i + 2) % 4]]
|
31
40
|
dbsession.add(restrictionarea)
|
32
41
|
restrictionareas.append(restrictionarea)
|
33
42
|
|
34
43
|
dbsession.flush()
|
35
|
-
yield {
|
44
|
+
yield {
|
45
|
+
"layers": layers,
|
46
|
+
"restriction_areas": restrictionareas,
|
47
|
+
"roles": roles,
|
48
|
+
}
|
36
49
|
|
37
50
|
|
38
51
|
@pytest.mark.usefixtures("restriction_area_test_data", "test_app")
|
39
|
-
class TestRestrictionAreaViews(
|
40
|
-
|
52
|
+
class TestRestrictionAreaViews(TestTreeGroup):
|
41
53
|
_prefix = "/admin/restriction_areas"
|
42
54
|
|
43
55
|
def test_index_rendering(self, test_app):
|
@@ -59,31 +71,75 @@ class TestRestrictionAreaViews(AbstractViewsTests):
|
|
59
71
|
def test_grid_search(self, test_app):
|
60
72
|
self.check_search(test_app, "restrictionarea_1", total=1)
|
61
73
|
|
62
|
-
def test_submit_new(self, dbsession, test_app):
|
63
|
-
from c2cgeoportal_commons.models.main import RestrictionArea
|
74
|
+
def test_submit_new(self, dbsession, test_app, restriction_area_test_data):
|
75
|
+
from c2cgeoportal_commons.models.main import Log, LogAction, RestrictionArea
|
76
|
+
|
77
|
+
roles = restriction_area_test_data["roles"]
|
78
|
+
layers = restriction_area_test_data["layers"]
|
64
79
|
|
65
80
|
resp = test_app.post(
|
66
|
-
"/admin/restriction_areas/new",
|
81
|
+
"/admin/restriction_areas/new",
|
82
|
+
(
|
83
|
+
("_charset_", "UTF-8"),
|
84
|
+
("__formid__", "deform"),
|
85
|
+
("id", ""),
|
86
|
+
("name", "new_name"),
|
87
|
+
("description", "new_description"),
|
88
|
+
("readwrite", "true"),
|
89
|
+
("area", ""),
|
90
|
+
("__start__", "roles:sequence"),
|
91
|
+
("roles", str(roles[0].id)),
|
92
|
+
("roles", str(roles[1].id)),
|
93
|
+
("__end__", "roles:sequence"),
|
94
|
+
("__start__", "layers:sequence"),
|
95
|
+
("__start__", "layer:mapping"),
|
96
|
+
("id", str(layers[0].id)),
|
97
|
+
("__end__", "layer:mapping"),
|
98
|
+
("__start__", "layer:mapping"),
|
99
|
+
("id", str(layers[1].id)),
|
100
|
+
("__end__", "layer:mapping"),
|
101
|
+
("__end__", "layers:sequence"),
|
102
|
+
("formsubmit", "formsubmit"),
|
103
|
+
),
|
104
|
+
status=302,
|
67
105
|
)
|
68
106
|
|
69
107
|
restriction_area = dbsession.query(RestrictionArea).filter(RestrictionArea.name == "new_name").one()
|
70
108
|
assert str(restriction_area.id) == re.match(
|
71
109
|
r"http://localhost/admin/restriction_areas/(.*)\?msg_col=submit_ok", resp.location
|
72
110
|
).group(1)
|
111
|
+
|
73
112
|
assert restriction_area.name == "new_name"
|
113
|
+
assert restriction_area.description == "new_description"
|
114
|
+
assert restriction_area.readwrite
|
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"
|
74
125
|
|
75
126
|
def test_unicity_validator(self, restriction_area_test_data, test_app):
|
76
127
|
restriction_area = restriction_area_test_data["restriction_areas"][2]
|
77
128
|
|
78
|
-
resp = test_app.get("/admin/restriction_areas/{}/duplicate"
|
129
|
+
resp = test_app.get(f"/admin/restriction_areas/{restriction_area.id}/duplicate", status=200)
|
79
130
|
resp = resp.form.submit("submit")
|
80
131
|
|
81
|
-
self._check_submission_problem(resp, "{} is already used."
|
132
|
+
self._check_submission_problem(resp, f"{restriction_area.name} is already used.")
|
82
133
|
|
83
134
|
def test_edit(self, test_app, restriction_area_test_data, dbsession):
|
135
|
+
from c2cgeoportal_commons.models.main import Log, LogAction
|
136
|
+
|
84
137
|
restriction_area = restriction_area_test_data["restriction_areas"][0]
|
85
138
|
roles = restriction_area_test_data["roles"]
|
86
139
|
|
140
|
+
# Ensure restriction_area.layers is loaded with relationship "order_by"
|
141
|
+
dbsession.expire(restriction_area)
|
142
|
+
|
87
143
|
form = self.get_item(test_app, restriction_area.id).form
|
88
144
|
|
89
145
|
assert str(restriction_area.id) == self.get_first_field_named(form, "id").value
|
@@ -100,6 +156,14 @@ class TestRestrictionAreaViews(AbstractViewsTests):
|
|
100
156
|
)
|
101
157
|
assert expected.almost_equals(shape(json.loads(form["area"].value)), decimal=0)
|
102
158
|
self._check_roles(form, roles, restriction_area)
|
159
|
+
self.check_children(
|
160
|
+
form,
|
161
|
+
"layers",
|
162
|
+
[
|
163
|
+
{"label": layer.name, "values": {"id": str(layer.id)}}
|
164
|
+
for layer in sorted(restriction_area.layers, key=lambda l: l.name)
|
165
|
+
],
|
166
|
+
)
|
103
167
|
|
104
168
|
form["description"] = "new_description"
|
105
169
|
form["roles"] = [roles[i].id for i in range(0, 3)]
|
@@ -107,28 +171,53 @@ class TestRestrictionAreaViews(AbstractViewsTests):
|
|
107
171
|
|
108
172
|
dbsession.expire(restriction_area)
|
109
173
|
assert restriction_area.description == "new_description"
|
110
|
-
assert set(restriction_area.roles) ==
|
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"
|
111
183
|
|
112
184
|
def test_delete(self, test_app, restriction_area_test_data, dbsession):
|
113
|
-
from c2cgeoportal_commons.models.main import RestrictionArea
|
185
|
+
from c2cgeoportal_commons.models.main import Log, LogAction, RestrictionArea
|
114
186
|
|
115
187
|
restriction_area = restriction_area_test_data["restriction_areas"][0]
|
116
188
|
deleted_id = restriction_area.id
|
117
|
-
test_app.delete("/admin/restriction_areas/{}"
|
189
|
+
test_app.delete(f"/admin/restriction_areas/{deleted_id}", status=200)
|
118
190
|
assert dbsession.query(RestrictionArea).get(deleted_id) is None
|
119
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
|
+
|
120
200
|
def test_duplicate(self, restriction_area_test_data, test_app, dbsession):
|
121
201
|
from c2cgeoportal_commons.models.main import RestrictionArea
|
122
202
|
|
123
203
|
restriction_area = restriction_area_test_data["restriction_areas"][3]
|
124
204
|
roles = restriction_area_test_data["roles"]
|
125
205
|
|
126
|
-
|
127
|
-
|
128
|
-
|
206
|
+
# Ensure restriction_area.layers is loaded with relationship "order_by"
|
207
|
+
dbsession.expire(restriction_area)
|
208
|
+
|
209
|
+
form = test_app.get(f"/admin/restriction_areas/{restriction_area.id}/duplicate", status=200).form
|
129
210
|
|
130
211
|
assert "" == self.get_first_field_named(form, "id").value
|
131
212
|
self._check_roles(form, roles, restriction_area)
|
213
|
+
self.check_children(
|
214
|
+
form,
|
215
|
+
"layers",
|
216
|
+
[
|
217
|
+
{"label": layer.name, "values": {"id": str(layer.id)}}
|
218
|
+
for layer in sorted(restriction_area.layers, key=lambda l: l.name)
|
219
|
+
],
|
220
|
+
)
|
132
221
|
|
133
222
|
self.set_first_field_named(form, "name", "clone")
|
134
223
|
resp = form.submit("submit")
|
tests/test_role.py
CHANGED
@@ -3,14 +3,13 @@
|
|
3
3
|
import json
|
4
4
|
import re
|
5
5
|
|
6
|
+
import pyramid.httpexceptions
|
7
|
+
import pytest
|
6
8
|
from geoalchemy2.shape import from_shape, to_shape
|
7
9
|
from pyramid.testing import DummyRequest
|
8
|
-
import pytest
|
9
|
-
from selenium.webdriver.common.by import By
|
10
10
|
from shapely.geometry import Polygon, box, shape
|
11
11
|
|
12
|
-
from . import
|
13
|
-
from .selenium.page import IndexPage
|
12
|
+
from .test_treegroup import TestTreeGroup
|
14
13
|
|
15
14
|
|
16
15
|
@pytest.fixture(scope="function")
|
@@ -18,20 +17,21 @@ from .selenium.page import IndexPage
|
|
18
17
|
def roles_test_data(dbsession, transact):
|
19
18
|
del transact
|
20
19
|
|
21
|
-
from c2cgeoportal_commons.models.main import
|
20
|
+
from c2cgeoportal_commons.models.main import Functionality, RestrictionArea, Role
|
22
21
|
from c2cgeoportal_commons.models.static import User
|
23
22
|
|
23
|
+
# Note that "default_basemap" is not relevant for roles
|
24
24
|
functionalities = {}
|
25
|
-
for name in ("default_basemap", "
|
25
|
+
for name in ("default_basemap", "default_theme", "print_template"):
|
26
26
|
functionalities[name] = []
|
27
27
|
for v in range(0, 4):
|
28
|
-
functionality = Functionality(name=name, value="value_{}"
|
28
|
+
functionality = Functionality(name=name, value=f"value_{v}")
|
29
29
|
dbsession.add(functionality)
|
30
30
|
functionalities[name].append(functionality)
|
31
31
|
|
32
32
|
restrictionareas = []
|
33
33
|
for i in range(0, 5):
|
34
|
-
restrictionarea = RestrictionArea(name="restrictionarea_{}"
|
34
|
+
restrictionarea = RestrictionArea(name=f"restrictionarea_{i}")
|
35
35
|
dbsession.add(restrictionarea)
|
36
36
|
restrictionareas.append(restrictionarea)
|
37
37
|
|
@@ -39,9 +39,9 @@ def roles_test_data(dbsession, transact):
|
|
39
39
|
for i in range(0, 23):
|
40
40
|
role = Role("secretary_" + str(i))
|
41
41
|
role.functionalities = [
|
42
|
-
functionalities["
|
43
|
-
functionalities["
|
44
|
-
functionalities["
|
42
|
+
functionalities["default_theme"][0],
|
43
|
+
functionalities["print_template"][0],
|
44
|
+
functionalities["print_template"][1],
|
45
45
|
]
|
46
46
|
role.restrictionareas = [restrictionareas[0], restrictionareas[1]]
|
47
47
|
role.extent = from_shape(box(485869.5728, 76443.1884, 837076.5648, 299941.7864), srid=21781)
|
@@ -68,8 +68,7 @@ def roles_test_data(dbsession, transact):
|
|
68
68
|
|
69
69
|
|
70
70
|
@pytest.mark.usefixtures("roles_test_data", "test_app")
|
71
|
-
class TestRole(
|
72
|
-
|
71
|
+
class TestRole(TestTreeGroup):
|
73
72
|
_prefix = "/admin/roles"
|
74
73
|
|
75
74
|
def test_index_rendering(self, test_app):
|
@@ -87,24 +86,90 @@ class TestRole(AbstractViewsTests):
|
|
87
86
|
]
|
88
87
|
self.check_grid_headers(resp, expected)
|
89
88
|
|
90
|
-
@pytest.mark.skip(reason="Translation
|
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, "
|
93
|
+
self.check_left_menu(resp, "Rôles")
|
95
94
|
|
96
95
|
expected = [
|
97
|
-
("
|
98
|
-
("
|
96
|
+
("actions", "", "false"),
|
97
|
+
("id", "id", "true"),
|
98
|
+
("name", "Nom"),
|
99
99
|
("description", "Description"),
|
100
|
-
("functionalities", "
|
101
|
-
("restrictionareas", "
|
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 Log, LogAction, Role
|
107
|
+
|
108
|
+
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]}
|
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"
|
104
164
|
|
105
165
|
def test_edit(self, dbsession, test_app, roles_test_data):
|
166
|
+
from c2cgeoportal_commons.models.main import Log, LogAction
|
167
|
+
|
106
168
|
role = roles_test_data["roles"][10]
|
107
169
|
|
170
|
+
# Ensure role.users is loaded with relationship "order_by"
|
171
|
+
dbsession.expire(role)
|
172
|
+
|
108
173
|
form = self.get_item(test_app, role.id).form
|
109
174
|
|
110
175
|
assert "secretary_10" == form["name"].value
|
@@ -121,30 +186,33 @@ class TestRole(AbstractViewsTests):
|
|
121
186
|
assert expected.almost_equals(shape(json.loads(form["extent"].value)), decimal=0)
|
122
187
|
|
123
188
|
functionalities = roles_test_data["functionalities"]
|
124
|
-
assert
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
)
|
130
|
-
) == set(f.id for f in role.functionalities)
|
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}
|
131
194
|
self.check_checkboxes(
|
132
195
|
form,
|
133
196
|
"functionalities",
|
134
197
|
[
|
135
198
|
{
|
136
|
-
"label": "{}={
|
199
|
+
"label": f"{f.name}={f.value}",
|
137
200
|
"value": str(f.id),
|
138
201
|
"checked": f in role.functionalities,
|
139
202
|
}
|
140
|
-
for f in
|
141
|
-
[
|
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),
|
142
210
|
)
|
143
211
|
],
|
144
212
|
)
|
145
213
|
|
146
214
|
ras = roles_test_data["restrictionareas"]
|
147
|
-
assert
|
215
|
+
assert {ras[0].id, ras[1].id} == {ra.id for ra in role.restrictionareas}
|
148
216
|
self.check_checkboxes(
|
149
217
|
form,
|
150
218
|
"restrictionareas",
|
@@ -154,6 +222,15 @@ class TestRole(AbstractViewsTests):
|
|
154
222
|
],
|
155
223
|
)
|
156
224
|
|
225
|
+
self.check_children(
|
226
|
+
form,
|
227
|
+
"users",
|
228
|
+
[
|
229
|
+
{"label": user.username, "values": {"id": str(user.id)}}
|
230
|
+
for user in sorted(role.users, key=lambda u: u.username)
|
231
|
+
],
|
232
|
+
)
|
233
|
+
|
157
234
|
form["name"] = "New name"
|
158
235
|
form["description"] = "New description"
|
159
236
|
form["extent"] = json.dumps(
|
@@ -172,9 +249,9 @@ class TestRole(AbstractViewsTests):
|
|
172
249
|
)
|
173
250
|
|
174
251
|
functionality_ids = [
|
175
|
-
roles_test_data["functionalities"]["
|
176
|
-
roles_test_data["functionalities"]["
|
177
|
-
roles_test_data["functionalities"]["
|
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,
|
178
255
|
]
|
179
256
|
form["functionalities"] = [str(id) for id in functionality_ids]
|
180
257
|
|
@@ -203,18 +280,26 @@ class TestRole(AbstractViewsTests):
|
|
203
280
|
)
|
204
281
|
assert expected.almost_equals(to_shape(role.extent), decimal=0)
|
205
282
|
|
206
|
-
assert set(functionality_ids) ==
|
207
|
-
assert set(ra_ids) ==
|
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"
|
208
293
|
|
209
294
|
def test_duplicate(self, roles_test_data, test_app, dbsession):
|
210
295
|
from c2cgeoportal_commons.models.main import Role
|
211
296
|
|
212
297
|
role_proto = roles_test_data["roles"][7]
|
213
298
|
|
214
|
-
resp = test_app.get("/admin/roles/{}/duplicate"
|
299
|
+
resp = test_app.get(f"/admin/roles/{role_proto.id}/duplicate", status=200)
|
215
300
|
form = resp.form
|
216
301
|
|
217
|
-
assert "" == form
|
302
|
+
assert "" == self.get_first_field_named(form, "id").value
|
218
303
|
assert role_proto.name == form["name"].value
|
219
304
|
assert role_proto.description == form["description"].value
|
220
305
|
form["name"].value = "clone"
|
@@ -225,62 +310,37 @@ class TestRole(AbstractViewsTests):
|
|
225
310
|
r"http://localhost/admin/roles/(.*)\?msg_col=submit_ok", resp.location
|
226
311
|
).group(1)
|
227
312
|
assert role_proto.id != role.id
|
228
|
-
assert role_proto.functionalities
|
229
|
-
assert role_proto.
|
230
|
-
assert role_proto.
|
231
|
-
assert role_proto.restrictionareas[1].name == role.restrictionareas[1].name
|
232
|
-
assert role_proto.restrictionareas[1].id == role.restrictionareas[1].id
|
313
|
+
assert set(role_proto.functionalities) == set(role.functionalities)
|
314
|
+
assert set(role_proto.restrictionareas) == set(role.restrictionareas)
|
315
|
+
assert set(role_proto.users) == set(role.users)
|
233
316
|
|
234
317
|
def test_delete(self, test_app, dbsession):
|
235
|
-
from c2cgeoportal_commons.models.main import Role
|
318
|
+
from c2cgeoportal_commons.models.main import Log, LogAction, Role
|
236
319
|
|
237
|
-
|
238
|
-
test_app.delete("/admin/roles/{}"
|
239
|
-
assert dbsession.query(Role).get(
|
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
|
323
|
+
|
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"
|
240
331
|
|
241
332
|
def test_unicity_validator(self, roles_test_data, test_app):
|
242
333
|
role_proto = roles_test_data["roles"][7]
|
243
|
-
resp = test_app.get("/admin/roles/{}/duplicate"
|
334
|
+
resp = test_app.get(f"/admin/roles/{role_proto.id}/duplicate", status=200)
|
244
335
|
|
245
336
|
resp = resp.form.submit("submit")
|
246
337
|
|
247
|
-
self._check_submission_problem(resp, "{} is already used."
|
338
|
+
self._check_submission_problem(resp, f"{role_proto.name} is already used.")
|
248
339
|
|
249
340
|
@pytest.mark.usefixtures("raise_db_error_on_query")
|
250
341
|
def test_grid_dberror(self, dbsession):
|
251
342
|
from c2cgeoportal_admin.views.roles import RoleViews
|
252
343
|
|
253
344
|
request = DummyRequest(dbsession=dbsession, params={"offset": 0, "limit": 10})
|
254
|
-
|
255
|
-
|
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)
|
345
|
+
with pytest.raises(pyramid.httpexceptions.HTTPInternalServerError):
|
346
|
+
RoleViews(request).grid()
|