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.
- c2cgeoportal_admin/__init__.py +42 -12
- c2cgeoportal_admin/lib/lingva_extractor.py +77 -0
- c2cgeoportal_admin/lib/ogcserver_synchronizer.py +170 -57
- c2cgeoportal_admin/py.typed +0 -0
- c2cgeoportal_admin/routes.py +18 -6
- c2cgeoportal_admin/schemas/dimensions.py +16 -10
- c2cgeoportal_admin/schemas/functionalities.py +59 -21
- c2cgeoportal_admin/schemas/interfaces.py +26 -18
- c2cgeoportal_admin/schemas/metadata.py +101 -48
- c2cgeoportal_admin/schemas/restriction_areas.py +25 -19
- c2cgeoportal_admin/schemas/roles.py +12 -6
- c2cgeoportal_admin/schemas/treegroup.py +46 -21
- c2cgeoportal_admin/schemas/treeitem.py +3 -4
- c2cgeoportal_admin/static/layertree.css +3 -4
- c2cgeoportal_admin/static/navbar.css +36 -35
- c2cgeoportal_admin/static/theme.css +19 -9
- c2cgeoportal_admin/subscribers.py +3 -3
- c2cgeoportal_admin/templates/404.jinja2 +18 -2
- c2cgeoportal_admin/templates/layertree.jinja2 +31 -9
- c2cgeoportal_admin/templates/navigation_navbar.jinja2 +33 -0
- c2cgeoportal_admin/templates/ogcserver_synchronize.jinja2 +12 -0
- c2cgeoportal_admin/templates/widgets/functionality_fields.pt +51 -0
- c2cgeoportal_admin/templates/widgets/metadata.pt +7 -1
- 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 +26 -20
- 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 +55 -34
- c2cgeoportal_admin/views/layers_wmts.py +54 -34
- c2cgeoportal_admin/views/layertree.py +38 -29
- c2cgeoportal_admin/views/logged_views.py +83 -0
- c2cgeoportal_admin/views/logs.py +91 -0
- c2cgeoportal_admin/views/oauth2_clients.py +30 -18
- c2cgeoportal_admin/views/ogc_servers.py +132 -36
- c2cgeoportal_admin/views/restriction_areas.py +39 -27
- c2cgeoportal_admin/views/roles.py +42 -28
- c2cgeoportal_admin/views/themes.py +47 -35
- c2cgeoportal_admin/views/themes_ordering.py +19 -14
- c2cgeoportal_admin/views/treeitems.py +21 -17
- c2cgeoportal_admin/views/users.py +46 -26
- c2cgeoportal_admin/widgets.py +17 -14
- {c2cgeoportal_admin-2.6.0.dist-info → c2cgeoportal_admin-2.9rc44.dist-info}/METADATA +12 -12
- c2cgeoportal_admin-2.9rc44.dist-info/RECORD +97 -0
- {c2cgeoportal_admin-2.6.0.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 +24 -20
- tests/conftest.py +22 -11
- tests/test_edit_url.py +11 -14
- tests/test_functionalities.py +52 -14
- tests/test_home.py +0 -1
- tests/test_interface.py +34 -11
- tests/test_layer_groups.py +57 -27
- tests/test_layers_cog.py +243 -0
- tests/test_layers_vectortiles.py +43 -25
- tests/test_layers_wms.py +67 -45
- tests/test_layers_wmts.py +47 -26
- tests/test_layertree.py +99 -16
- 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 +3 -1
- tests/test_metadatas.py +34 -21
- tests/test_oauth2_clients.py +40 -11
- tests/test_ogc_servers.py +84 -35
- tests/test_restriction_areas.py +38 -15
- tests/test_role.py +71 -43
- tests/test_themes.py +71 -37
- tests/test_themes_ordering.py +1 -2
- tests/test_treegroup.py +2 -2
- tests/test_user.py +56 -19
- tests/themes_ordering.py +1 -2
- c2cgeoportal_admin/templates/navigation_vertical.jinja2 +0 -33
- c2cgeoportal_admin-2.6.0.dist-info/RECORD +0 -89
- c2cgeoportal_admin-2.6.0.dist-info/entry_points.txt +0 -3
- {c2cgeoportal_admin-2.6.0.dist-info → c2cgeoportal_admin-2.9rc44.dist-info}/top_level.txt +0 -0
c2cgeoportal_admin/widgets.py
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
# Copyright (c) 2018-2020, Camptocamp SA
|
1
|
+
# Copyright (c) 2018-2024, Camptocamp SA
|
4
2
|
# All rights reserved.
|
5
3
|
|
6
4
|
# Redistribution and use in source and binary forms, with or without
|
@@ -27,9 +25,10 @@
|
|
27
25
|
# of the authors and should not be interpreted as representing official policies,
|
28
26
|
# either expressed or implied, of the FreeBSD Project.
|
29
27
|
|
30
|
-
from typing import
|
28
|
+
from typing import Any
|
31
29
|
|
32
30
|
import colander
|
31
|
+
import pyramid.request
|
33
32
|
from colander import Mapping, SchemaNode
|
34
33
|
from deform import widget
|
35
34
|
from deform.widget import MappingWidget, SequenceWidget
|
@@ -55,10 +54,11 @@ widget.DateTimeInputWidget._pstruct_schema = SchemaNode( # pylint: disable=prot
|
|
55
54
|
)
|
56
55
|
|
57
56
|
|
58
|
-
class ChildWidget(MappingWidget):
|
57
|
+
class ChildWidget(MappingWidget): # type: ignore
|
59
58
|
"""
|
60
|
-
Extension of the widget ````deform.widget.MappingWidget
|
61
|
-
|
59
|
+
Extension of the widget ````deform.widget.MappingWidget``.
|
60
|
+
|
61
|
+
To be used in conjunction with ChildrenWidget, to manage n-m relationships.
|
62
62
|
|
63
63
|
Do not embed complete children forms, but just an hidden input for child primary key.
|
64
64
|
|
@@ -82,7 +82,7 @@ class ChildWidget(MappingWidget):
|
|
82
82
|
|
83
83
|
For further attributes, please refer to the documentation of
|
84
84
|
``deform.widget.MappingWidget`` in the deform documentation:
|
85
|
-
<
|
85
|
+
<https://deform.readthedocs.org/en/latest/api.html>
|
86
86
|
"""
|
87
87
|
|
88
88
|
template = "child"
|
@@ -90,11 +90,13 @@ class ChildWidget(MappingWidget):
|
|
90
90
|
model = TreeItem
|
91
91
|
label_field = "name"
|
92
92
|
|
93
|
-
def icon_class(self, child) ->
|
93
|
+
def icon_class(self, child: Any) -> str | None: # pylint: disable=useless-return
|
94
94
|
del child
|
95
95
|
return None
|
96
96
|
|
97
|
-
def edit_url(
|
97
|
+
def edit_url( # pylint: disable=useless-return
|
98
|
+
self, request: pyramid.request.Request, child: Any
|
99
|
+
) -> str | None:
|
98
100
|
del request
|
99
101
|
del child
|
100
102
|
return None
|
@@ -107,10 +109,11 @@ class ChildWidget(MappingWidget):
|
|
107
109
|
return super().serialize(field, cstruct, **kw)
|
108
110
|
|
109
111
|
|
110
|
-
class ChildrenWidget(SequenceWidget):
|
112
|
+
class ChildrenWidget(SequenceWidget): # type: ignore
|
111
113
|
"""
|
112
|
-
Extension of the widget ````deform.widget.SequenceWidget
|
113
|
-
|
114
|
+
Extension of the widget ````deform.widget.SequenceWidget``.
|
115
|
+
|
116
|
+
To be used in conjunction with ChildWidget, to manage n-m relationships.
|
114
117
|
|
115
118
|
Use Magicsuggest for searching into parent schema candidates property, which should be a list of
|
116
119
|
dictionaries of the form:
|
@@ -129,7 +132,7 @@ class ChildrenWidget(SequenceWidget):
|
|
129
132
|
|
130
133
|
For further attributes, please refer to the documentation of
|
131
134
|
``deform.widget.SequenceWidget`` in the deform documentation:
|
132
|
-
<
|
135
|
+
<https://deform.readthedocs.org/en/latest/api.html>
|
133
136
|
"""
|
134
137
|
|
135
138
|
template = "children"
|
@@ -1,21 +1,23 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: c2cgeoportal-admin
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.9rc44
|
4
4
|
Summary: c2cgeoportal admin
|
5
5
|
Home-page: https://github.com/camptocamp/c2cgeoportal/
|
6
6
|
Author: Camptocamp
|
7
7
|
Author-email: info@camptocamp.com
|
8
|
-
License: UNKNOWN
|
9
8
|
Keywords: web gis geoportail c2cgeoportal geocommune pyramid
|
10
|
-
|
11
|
-
Classifier:
|
12
|
-
Classifier: Programming Language :: Python :: 3
|
13
|
-
Classifier: Programming Language :: Python :: 3.7
|
9
|
+
Classifier: Development Status :: 6 - Mature
|
10
|
+
Classifier: Environment :: Web Environment
|
14
11
|
Classifier: Framework :: Pyramid
|
15
|
-
Classifier:
|
16
|
-
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
|
12
|
+
Classifier: Intended Audience :: Other Audience
|
17
13
|
Classifier: License :: OSI Approved :: BSD License
|
18
|
-
Classifier:
|
14
|
+
Classifier: Operating System :: OS Independent
|
15
|
+
Classifier: Programming Language :: Python
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
19
|
+
Classifier: Typing :: Typed
|
20
|
+
Requires-Python: >=3.10
|
19
21
|
Description-Content-Type: text/markdown
|
20
22
|
Requires-Dist: c2cgeoform
|
21
23
|
Requires-Dist: c2cwsgiutils
|
@@ -42,6 +44,4 @@ make preparedev
|
|
42
44
|
make serve
|
43
45
|
```
|
44
46
|
|
45
|
-
Now open http://localhost:8888/ in your favorite browser.
|
46
|
-
|
47
|
-
|
47
|
+
Now open http://localhost:8888/admin/ in your favorite browser.
|
@@ -0,0 +1,97 @@
|
|
1
|
+
c2cgeoportal_admin/__init__.py,sha256=HVSQ-CwK5aR9URA-NVH7JlYHGU49xT5vARiTkdxpV70,5767
|
2
|
+
c2cgeoportal_admin/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
+
c2cgeoportal_admin/routes.py,sha256=oja-Seyn08geema9lKJEVU-bPzuT8RaNBfUORDxEm6w,5302
|
4
|
+
c2cgeoportal_admin/subscribers.py,sha256=P1CaccDTpuxrWak_gMN2qBurz3OrAZ6aZ1LA7P3avu8,2430
|
5
|
+
c2cgeoportal_admin/widgets.py,sha256=8bozaTGBZKxDIMWbkHU1eD0MmOQ9KMOn21PDLYbQGFs,6092
|
6
|
+
c2cgeoportal_admin/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
|
+
c2cgeoportal_admin/lib/lingva_extractor.py,sha256=5XsUHeVHnGF6GmD83shaTXasigGXtDXwgnswU0xA410,3355
|
8
|
+
c2cgeoportal_admin/lib/ogcserver_synchronizer.py,sha256=AFr0TbI_l7QTf9oNyO6rFEy6Ix096R2V0EFYcw-ArIc,15536
|
9
|
+
c2cgeoportal_admin/schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
|
+
c2cgeoportal_admin/schemas/dimensions.py,sha256=pVEN8VjPjoANWUEIB-aWh6Yli_ybu1ghQcaYC2tSFyI,2368
|
11
|
+
c2cgeoportal_admin/schemas/functionalities.py,sha256=JecG1DYagM_Bgd7sMj0clN-4CAuYZEdELwDXlLRLBZs,3852
|
12
|
+
c2cgeoportal_admin/schemas/interfaces.py,sha256=N_b1LQ0Ur2i09dprnLLqXrcEq1p7uaKZJhaQpW7mOKc,2662
|
13
|
+
c2cgeoportal_admin/schemas/metadata.py,sha256=cp-QJkUf0zH0s6rBgV3uIZuXhHVFG5E8mF4J1ty2c6c,8897
|
14
|
+
c2cgeoportal_admin/schemas/restriction_areas.py,sha256=1xVR1SQfBReWVK5eFyGyrvw8tYqY2iOehuXVX3EMdf0,2682
|
15
|
+
c2cgeoportal_admin/schemas/roles.py,sha256=YyRaStlu1IJwB5gRHlvS285twSy2xxatNOqV9klq1s8,2591
|
16
|
+
c2cgeoportal_admin/schemas/treegroup.py,sha256=pLBIGBeaCmsAUMC4yCFCdSkYqLytG38qVygYqNr_AX8,7150
|
17
|
+
c2cgeoportal_admin/schemas/treeitem.py,sha256=VhGhpG8VcsT-3dnnNlln-uVlsqjwJQXbg6Ap1tEanMI,2146
|
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=3knC4gpPnEwLF0-jEJze15C1hm1K87aCpxGyqdjrLxw,2068
|
21
|
+
c2cgeoportal_admin/templates/404.jinja2,sha256=KSpqCNFwv37rKSmX6kL_VvCnn5egcT1eRD6kIKwWx34,1807
|
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=P8noHX8YAv3m6EGh0IDUJCFsyeZDX88HtlqOWab8DAU,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=jtI6CdoXJwizznjwb8ClYySgq4kbwhTIJYutSw89PAw,683
|
45
|
+
c2cgeoportal_admin/views/dimension_layers.py,sha256=WL3CqfAY8mref9cen1lCF5vADg_csf2Pp5zeEYX1ZXg,2778
|
46
|
+
c2cgeoportal_admin/views/functionalities.py,sha256=F51rdqVqbdWx1iNz8DHauhh3B8f6x6lEidaskxBn1so,4379
|
47
|
+
c2cgeoportal_admin/views/home.py,sha256=h_hJWIKpzJeSmXl58J0nvZdEg7avSYOOVUEEnlV-r0k,1943
|
48
|
+
c2cgeoportal_admin/views/interfaces.py,sha256=psp5dw22rI3enY9AS0aIspHBdv-sVzSPBQKGIhW3-Hw,3844
|
49
|
+
c2cgeoportal_admin/views/layer_groups.py,sha256=xQiEkO7LuNy0FiwfHZa1XwaoMvr9UE2bLpckOtdyuMM,4489
|
50
|
+
c2cgeoportal_admin/views/layers.py,sha256=JDEO8hEIPhRxZVpxyT_0FU6gWCgREllw5O9qBCCxipU,3248
|
51
|
+
c2cgeoportal_admin/views/layers_cog.py,sha256=tFljZufefGP8YZvidAhUA5cgwbO1R2D7wXdQdS1EX1I,5627
|
52
|
+
c2cgeoportal_admin/views/layers_vectortiles.py,sha256=fTNaGGt7ZIX9wydZvED6mp1B8iBtt-qbywv2MqQgV_Q,5617
|
53
|
+
c2cgeoportal_admin/views/layers_wms.py,sha256=kjhH4TWnVnH81J__vcbyST2qEMSz3qHOxcEL8ELvLuU,8335
|
54
|
+
c2cgeoportal_admin/views/layers_wmts.py,sha256=Kb-j_yPEJycBYh5E-D-eP3xEhuzraotNL9bLup7GoNM,8080
|
55
|
+
c2cgeoportal_admin/views/layertree.py,sha256=0FxaVrIg2A7ArMCiI9tj7diaLPn2Cl16iFUerdPDpV4,8629
|
56
|
+
c2cgeoportal_admin/views/logged_views.py,sha256=Yg8HnrLCog4geNWOjkhF_Zo2ByOKuevdVT8xLd9x5Ow,3335
|
57
|
+
c2cgeoportal_admin/views/logs.py,sha256=N1I0gqzoqbEtkOsP0EhrlEWsDYuiuKQ46_YeKy7zFHs,3776
|
58
|
+
c2cgeoportal_admin/views/oauth2_clients.py,sha256=RC_vrMQaYGujN97wHihQXrO_0K7CrcFF1rSI0-dHZlg,3840
|
59
|
+
c2cgeoportal_admin/views/ogc_servers.py,sha256=kIhlZ7Sp_mdZUlyl2h4foTTgkevWrbZb_chLZUXEF1o,9716
|
60
|
+
c2cgeoportal_admin/views/restriction_areas.py,sha256=QQKDC7nUkNecC2knnnoLijhc2LvvjV8wZm3fcmRjftc,6122
|
61
|
+
c2cgeoportal_admin/views/roles.py,sha256=I6di90WR20EkFoy33milrHZ74_dgCkEVeNDM8E4P46w,6387
|
62
|
+
c2cgeoportal_admin/views/themes.py,sha256=6le9_3vhYa_ez0q52i--M24xPsycrGtpVKoCRhn7H0k,6267
|
63
|
+
c2cgeoportal_admin/views/themes_ordering.py,sha256=PgPaqKe7A5d2cYcDeJyoK615BNXayOmRcKNAAopvfRc,5689
|
64
|
+
c2cgeoportal_admin/views/treeitems.py,sha256=EgDArC5M39iihbB1Ok2VXmAAuH2DhhBrjeF0TbJgOQ4,4038
|
65
|
+
c2cgeoportal_admin/views/users.py,sha256=8zoSgSn0RFnu-Gc6gJr58T5ySsd0L2UQFZdSwfptdY8,6147
|
66
|
+
tests/__init__.py,sha256=weLUoRCG6zIlhW7Rfr7QEA0Ju-gYLfBekRcTCb5lTZ4,9785
|
67
|
+
tests/conftest.py,sha256=vowo5nwQ3DLSfost3ndihoYJFuhuhpoK__-B_ffsSLY,2646
|
68
|
+
tests/test_edit_url.py,sha256=Mo_Vo5xvdpPasfjvhQUif5F3nKVpJ6GQJ_x_Hj5VNY8,4494
|
69
|
+
tests/test_functionalities.py,sha256=tGQbEsQWjr_oExI3vWhLIioxylDaoUaOfEas42YPw50,5191
|
70
|
+
tests/test_home.py,sha256=oWsKaWqRicNpUdaca54YvLIBRaGYnsXlv_Tjqv7guEQ,425
|
71
|
+
tests/test_interface.py,sha256=z1jpRzW0R2e9BJWWurE-j-YkG5yhorn7h1XRIauUQ7A,5669
|
72
|
+
tests/test_layer_groups.py,sha256=bisbaDY0SiyBc0rexYajbcvfdDt8Kux6VqXIEBLSULM,12191
|
73
|
+
tests/test_layers_cog.py,sha256=5p7NHZw1IXfHg8Weqie3ibjDIJYVm7KAGGOiaZoBYO0,9848
|
74
|
+
tests/test_layers_vectortiles.py,sha256=uZGO-0-uVuvkPVMQI11tSY381tEmgWeYvlxKI19pslg,10158
|
75
|
+
tests/test_layers_wms.py,sha256=ynqO1cnXk2ZbSXR3l9hp0IyG8PMXbmR4eyubnwRvRfU,19494
|
76
|
+
tests/test_layers_wmts.py,sha256=7zye_pZ_e0RyJdoT8oeHKPoYJMKWfTg0K8lEgMIu77Q,12181
|
77
|
+
tests/test_layertree.py,sha256=Dxe10OwuilQ-AEgVIDU4Ns9U6PQ4kPWTxwItdBE7nSg,11335
|
78
|
+
tests/test_learn.py,sha256=gQwe-Bim0eihZH0rbBWDn6_rIBxvQD_lyu9MlOljupM,2307
|
79
|
+
tests/test_left_menu.py,sha256=xnlv5sD0k3wpCChKCnbpYRN0TA895pg8k6wVvjf99-4,919
|
80
|
+
tests/test_lingva_extractor_config.py,sha256=ZQE8zBl91khK68MX0chL6mQPgfpIWQgMxlqFFpCwmSw,2495
|
81
|
+
tests/test_logs.py,sha256=pxzHyOElW-x2-M3yoMEsHIZ3nrm5EptDAAAGfziEfv4,3132
|
82
|
+
tests/test_main.py,sha256=_gUdMrMMAEzvGIf1QwkoHQkd0eBACz05ycTidCHP5Ao,365
|
83
|
+
tests/test_metadatas.py,sha256=bVNxvZRKNRMmjQGr7Al1d4H85EjEaoesRpxytyld4Fw,12088
|
84
|
+
tests/test_oauth2_clients.py,sha256=5vyuCsba2WVgr6yMJysw73pAnXCZXhLO7dLIgV-spic,7028
|
85
|
+
tests/test_ogc_servers.py,sha256=DGSMVIzYnw3bJT53VFGuPYIPMPCyHJDb5ZPJj1VM3Bo,8204
|
86
|
+
tests/test_restriction_areas.py,sha256=5VhO9ZvtFQPy1kVFm96Mh_vf1LCI5oeIdl0dfvS6JD8,9003
|
87
|
+
tests/test_role.py,sha256=2mbi0RwTESnIZIuUTxMi275ONOcPNKWN-ni7b00SO90,12804
|
88
|
+
tests/test_themes.py,sha256=uhzHe2TbuNoLnL4VdYATPnOqtnZWWPKsvUTq6GUxwiU,16207
|
89
|
+
tests/test_themes_ordering.py,sha256=T4Esr0C3EN5UdeEyYLa4ePvEn-bx3RNPkGBK3lDFoBo,2243
|
90
|
+
tests/test_treegroup.py,sha256=Plv119G4TWlurWLE7Z1mWGeHHPScK_fWKcDmDzMUlIU,576
|
91
|
+
tests/test_user.py,sha256=5C9nrQVk4Bf0Z9BKd0uf_J8EtJLTOFSpzrNHXfg3NzI,13095
|
92
|
+
tests/themes_ordering.py,sha256=UdydcRIzWC6RRnTMfl2JM_250DHuAhGC7rijHqfy7lk,1342
|
93
|
+
c2cgeoportal_admin-2.9rc44.dist-info/METADATA,sha256=FL4D_vI8WCcesDbNuwvSy7SVtqGOj7z5mYoC_jQRlQc,1382
|
94
|
+
c2cgeoportal_admin-2.9rc44.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
95
|
+
c2cgeoportal_admin-2.9rc44.dist-info/entry_points.txt,sha256=iRK5w2E-PVbqHx48OuxznFEXTpoOdJyx6kjpaca0Fxc,164
|
96
|
+
c2cgeoportal_admin-2.9rc44.dist-info/top_level.txt,sha256=DgcTJgTvpJUB8HqwYB14PdLBPAOAFk0B8oqnSTFoAU4,25
|
97
|
+
c2cgeoportal_admin-2.9rc44.dist-info/RECORD,,
|
tests/__init__.py
CHANGED
@@ -9,13 +9,15 @@ skip_if_ci = pytest.mark.skipif(os.environ.get("CI", "false") == "true", reason=
|
|
9
9
|
|
10
10
|
|
11
11
|
def get_test_default_layers(dbsession, default_ogc_server):
|
12
|
-
from c2cgeoportal_commons.models.main import LayerVectorTiles, LayerWMS, LayerWMTS
|
13
|
-
|
14
|
-
default_wms =
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
from c2cgeoportal_commons.models.main import LayerCOG, LayerVectorTiles, LayerWMS, LayerWMTS
|
13
|
+
|
14
|
+
default_wms = None
|
15
|
+
if default_ogc_server:
|
16
|
+
default_wms = LayerWMS("wms-defaults")
|
17
|
+
default_wms.ogc_server = default_ogc_server
|
18
|
+
default_wms.time_widget = "datepicker"
|
19
|
+
default_wms.time_mode = "value"
|
20
|
+
dbsession.add(default_wms)
|
19
21
|
default_wmts = LayerWMTS("wmts-defaults")
|
20
22
|
default_wmts.url = "https:///wmts.geo.admin_default.ch.org?service=wms&request=GetCapabilities"
|
21
23
|
default_wmts.layer = "default"
|
@@ -24,8 +26,11 @@ def get_test_default_layers(dbsession, default_ogc_server):
|
|
24
26
|
default_vectortiles = LayerVectorTiles("vectortiles-defaults")
|
25
27
|
default_vectortiles.style = "https://vectortiles-staging.geoportail.lu/styles/roadmap/style.json"
|
26
28
|
dbsession.add(default_vectortiles)
|
29
|
+
default_cog = LayerCOG("cog-defaults")
|
30
|
+
default_cog.url = "https://example.com/image.tiff"
|
31
|
+
dbsession.add(default_cog)
|
27
32
|
dbsession.flush()
|
28
|
-
return {"wms": default_wms, "wmts": default_wmts, "vectortiles": default_vectortiles}
|
33
|
+
return {"wms": default_wms, "wmts": default_wmts, "vectortiles": default_vectortiles, "cog": default_cog}
|
29
34
|
|
30
35
|
|
31
36
|
def factory_build_layers(layer_builder, dbsession, add_dimension=True):
|
@@ -38,7 +43,7 @@ def factory_build_layers(layer_builder, dbsession, add_dimension=True):
|
|
38
43
|
RestrictionArea,
|
39
44
|
)
|
40
45
|
|
41
|
-
restrictionareas = [RestrictionArea(name="restrictionarea_{}"
|
46
|
+
restrictionareas = [RestrictionArea(name=f"restrictionarea_{i}") for i in range(0, 5)]
|
42
47
|
|
43
48
|
interfaces = [Interface(name) for name in ["desktop", "mobile", "edit", "routing"]]
|
44
49
|
|
@@ -50,11 +55,10 @@ def factory_build_layers(layer_builder, dbsession, add_dimension=True):
|
|
50
55
|
("snappingConfig", '{"tolerance": 50}'),
|
51
56
|
]
|
52
57
|
|
53
|
-
groups = [LayerGroup(name="layer_group_{}"
|
58
|
+
groups = [LayerGroup(name=f"layer_group_{i}") for i in range(0, 5)]
|
54
59
|
|
55
60
|
layers = []
|
56
61
|
for i in range(0, 25):
|
57
|
-
|
58
62
|
layer = layer_builder(i)
|
59
63
|
|
60
64
|
if add_dimension:
|
@@ -90,23 +94,22 @@ def factory_build_layers(layer_builder, dbsession, add_dimension=True):
|
|
90
94
|
|
91
95
|
|
92
96
|
class AbstractViewsTests:
|
93
|
-
|
94
97
|
_prefix = None # url prefix (index view url). Example: /users
|
95
98
|
|
96
99
|
def get(self, test_app, path="", locale="en", status=200, **kwargs):
|
97
100
|
return test_app.get(
|
98
|
-
"{}{}"
|
99
|
-
headers={"Cookie": "_LOCALE_={}"
|
101
|
+
f"{self._prefix}{path}",
|
102
|
+
headers={"Cookie": f"_LOCALE_={locale}"},
|
100
103
|
status=status,
|
101
104
|
**kwargs,
|
102
105
|
)
|
103
106
|
|
104
107
|
def get_item(self, test_app, item_id, **kwargs):
|
105
|
-
return self.get(test_app, "/{}"
|
108
|
+
return self.get(test_app, f"/{item_id}", **kwargs)
|
106
109
|
|
107
110
|
def check_left_menu(self, resp, title):
|
108
111
|
link = resp.html.select_one(".navbar li.active a")
|
109
|
-
assert "http://localhost{
|
112
|
+
assert f"http://localhost{self._prefix}" == link.attrs["href"]
|
110
113
|
assert title == link.getText()
|
111
114
|
|
112
115
|
def check_grid_headers(self, resp, expected_col_headers, new="New"):
|
@@ -120,11 +123,12 @@ class AbstractViewsTests:
|
|
120
123
|
)
|
121
124
|
actions = resp.html.select_one('th[data-field="actions"]')
|
122
125
|
assert "false" == actions.attrs["data-sortable"]
|
123
|
-
|
126
|
+
if new is not False:
|
127
|
+
assert 1 == len(list(filter(lambda x: next(x.stripped_strings) == new, resp.html.findAll("a"))))
|
124
128
|
|
125
129
|
def check_search(self, test_app, search="", offset=0, limit=10, sort="", order="", total=None):
|
126
130
|
json = test_app.post(
|
127
|
-
"{}/grid.json"
|
131
|
+
f"{self._prefix}/grid.json",
|
128
132
|
params={"offset": offset, "limit": limit, "search": search, "sort": sort, "order": order},
|
129
133
|
status=200,
|
130
134
|
).json
|
@@ -135,8 +139,8 @@ class AbstractViewsTests:
|
|
135
139
|
def check_checkboxes(self, form, name, expected):
|
136
140
|
for i, exp in enumerate(expected):
|
137
141
|
field = form.get(name, index=i)
|
138
|
-
checkbox = form.html.select_one("#{
|
139
|
-
label = form.html.select_one("label[for={}]"
|
142
|
+
checkbox = form.html.select_one(f"#{field.id}")
|
143
|
+
label = form.html.select_one(f"label[for={field.id}]")
|
140
144
|
assert exp["label"] == list(label.stripped_strings)[0]
|
141
145
|
assert exp["value"] == checkbox["value"]
|
142
146
|
assert exp["checked"] == field.checked
|
tests/conftest.py
CHANGED
@@ -1,8 +1,15 @@
|
|
1
|
+
from typing import Any
|
2
|
+
|
3
|
+
import pyramid.request
|
1
4
|
import pytest
|
5
|
+
import sqlalchemy.exc
|
2
6
|
import transaction
|
3
7
|
from pyramid import testing
|
4
8
|
from pyramid.paster import bootstrap
|
9
|
+
from pyramid.router import Router
|
10
|
+
from pyramid.scripting import AppEnvironment
|
5
11
|
from sqlalchemy.exc import DBAPIError
|
12
|
+
from sqlalchemy.orm import Session, SessionTransaction
|
6
13
|
from webtest import TestApp as WebTestApp # Avoid warning with pytest
|
7
14
|
|
8
15
|
from c2cgeoportal_commons.testing import generate_mappers, get_engine, get_session_factory, get_tm_session
|
@@ -11,31 +18,34 @@ from c2cgeoportal_commons.testing.initializedb import truncate_tables
|
|
11
18
|
|
12
19
|
@pytest.fixture(scope="session")
|
13
20
|
@pytest.mark.usefixtures("settings")
|
14
|
-
def dbsession(settings):
|
21
|
+
def dbsession(settings: dict[str, Any]) -> Session:
|
15
22
|
generate_mappers()
|
16
23
|
engine = get_engine(settings)
|
17
|
-
truncate_tables(engine)
|
18
24
|
session_factory = get_session_factory(engine)
|
19
25
|
session = get_tm_session(session_factory, transaction.manager)
|
26
|
+
truncate_tables(session)
|
20
27
|
yield session
|
21
28
|
|
22
29
|
|
23
30
|
@pytest.fixture(scope="function")
|
24
31
|
@pytest.mark.usefixtures("dbsession")
|
25
|
-
def transact(dbsession):
|
32
|
+
def transact(dbsession: Session) -> SessionTransaction:
|
26
33
|
t = dbsession.begin_nested()
|
27
34
|
yield t
|
28
|
-
|
35
|
+
try:
|
36
|
+
t.rollback()
|
37
|
+
except sqlalchemy.exc.ResourceClosedError:
|
38
|
+
print("The transaction was already closed")
|
29
39
|
dbsession.expire_all()
|
30
40
|
|
31
41
|
|
32
|
-
def raise_db_error(_):
|
42
|
+
def raise_db_error(_: Any) -> None:
|
33
43
|
raise DBAPIError("this is a test !", None, None)
|
34
44
|
|
35
45
|
|
36
46
|
@pytest.fixture(scope="function")
|
37
47
|
@pytest.mark.usefixtures("dbsession")
|
38
|
-
def raise_db_error_on_query(dbsession):
|
48
|
+
def raise_db_error_on_query(dbsession: Session) -> None:
|
39
49
|
query = dbsession.query
|
40
50
|
dbsession.query = raise_db_error
|
41
51
|
yield
|
@@ -43,7 +53,7 @@ def raise_db_error_on_query(dbsession):
|
|
43
53
|
|
44
54
|
|
45
55
|
@pytest.fixture(scope="session")
|
46
|
-
def app_env():
|
56
|
+
def app_env() -> AppEnvironment:
|
47
57
|
file_name = "/opt/c2cgeoportal/admin/tests/tests.ini"
|
48
58
|
with bootstrap(file_name) as env:
|
49
59
|
yield env
|
@@ -51,11 +61,12 @@ def app_env():
|
|
51
61
|
|
52
62
|
@pytest.fixture(scope="session")
|
53
63
|
@pytest.mark.usefixtures("app_env", "dbsession")
|
54
|
-
def app(app_env, dbsession):
|
64
|
+
def app(app_env: AppEnvironment, dbsession: Session) -> Router:
|
55
65
|
config = testing.setUp(registry=app_env["registry"])
|
56
66
|
config.add_request_method(lambda request: dbsession, "dbsession", reify=True)
|
57
67
|
config.add_route("user_add", "user_add")
|
58
68
|
config.add_route("users_nb", "users_nb")
|
69
|
+
config.add_route("base", "/", static=True)
|
59
70
|
config.scan(package="tests")
|
60
71
|
app = config.make_wsgi_app()
|
61
72
|
yield app
|
@@ -63,12 +74,12 @@ def app(app_env, dbsession):
|
|
63
74
|
|
64
75
|
@pytest.fixture(scope="session")
|
65
76
|
@pytest.mark.usefixtures("app_env")
|
66
|
-
def settings(app_env):
|
77
|
+
def settings(app_env: AppEnvironment) -> Any:
|
67
78
|
yield app_env.get("registry").settings
|
68
79
|
|
69
80
|
|
70
|
-
@pytest.fixture(scope="session") # noqa: F811
|
81
|
+
@pytest.fixture(scope="session") # noqa: ignore=F811
|
71
82
|
@pytest.mark.usefixtures("app")
|
72
|
-
def test_app(request, app):
|
83
|
+
def test_app(request: pyramid.request.Request, app: Router) -> WebTestApp:
|
73
84
|
testapp = WebTestApp(app)
|
74
85
|
yield testapp
|
tests/test_edit_url.py
CHANGED
@@ -24,12 +24,12 @@ def edit_url_test_data(dbsession, transact):
|
|
24
24
|
Theme,
|
25
25
|
)
|
26
26
|
|
27
|
-
restrictionareas = [RestrictionArea(name="restrictionarea_{}"
|
27
|
+
restrictionareas = [RestrictionArea(name=f"restrictionarea_{i}") for i in range(0, 5)]
|
28
28
|
functionalities = {}
|
29
|
-
for name in ("default_basemap", "
|
29
|
+
for name in ("default_basemap", "default_theme"):
|
30
30
|
functionalities[name] = []
|
31
31
|
for v in range(0, 4):
|
32
|
-
functionality = Functionality(name=name, value="value_{}"
|
32
|
+
functionality = Functionality(name=name, value=f"value_{v}")
|
33
33
|
dbsession.add(functionality)
|
34
34
|
functionalities[name].append(functionality)
|
35
35
|
|
@@ -38,10 +38,10 @@ def edit_url_test_data(dbsession, transact):
|
|
38
38
|
|
39
39
|
layers_wmts = []
|
40
40
|
for i in range(0, 5):
|
41
|
-
name = "layer_wmts_{}"
|
41
|
+
name = f"layer_wmts_{i}"
|
42
42
|
layer_wmts = LayerWMTS(name=name)
|
43
43
|
layer_wmts.layer = name
|
44
|
-
layer_wmts.url = "https://server{}.net/wmts"
|
44
|
+
layer_wmts.url = f"https://server{i}.net/wmts"
|
45
45
|
layer_wmts.restrictionareas = [restrictionareas[i % 5], restrictionareas[(i + 2) % 5]]
|
46
46
|
if i % 10 != 1:
|
47
47
|
layer_wmts.interfaces = [interfaces[i % 4], interfaces[(i + 2) % 4]]
|
@@ -52,8 +52,8 @@ def edit_url_test_data(dbsession, transact):
|
|
52
52
|
|
53
53
|
layers_wms = []
|
54
54
|
for i in range(0, 5):
|
55
|
-
layer_wms = LayerWMS(name="layer_wms_{}"
|
56
|
-
layer_wms.layer = "wms_layer_{}"
|
55
|
+
layer_wms = LayerWMS(name=f"layer_wms_{i}")
|
56
|
+
layer_wms.layer = f"wms_layer_{i}"
|
57
57
|
layer_wms.ogc_server = ogc_server
|
58
58
|
layers_wms.append(layer_wms)
|
59
59
|
dbsession.add(layer_wms)
|
@@ -63,9 +63,7 @@ def edit_url_test_data(dbsession, transact):
|
|
63
63
|
for i in range(0, 5):
|
64
64
|
role = Role("secretary_" + str(i))
|
65
65
|
role.functionalities = [
|
66
|
-
functionalities["
|
67
|
-
functionalities["location"][0],
|
68
|
-
functionalities["location"][1],
|
66
|
+
functionalities["default_theme"][0],
|
69
67
|
]
|
70
68
|
role.restrictionareas = [restrictionareas[0], restrictionareas[1]]
|
71
69
|
dbsession.add(role)
|
@@ -94,16 +92,15 @@ def edit_url_test_data(dbsession, transact):
|
|
94
92
|
|
95
93
|
@pytest.mark.usefixtures("edit_url_test_data", "test_app")
|
96
94
|
class TestUrlEdit(AbstractViewsTests):
|
97
|
-
|
98
95
|
_prefix = "/admin/"
|
99
96
|
|
100
97
|
def _get(self, test_app, tablename, pk):
|
101
|
-
path = "/{}/{}"
|
98
|
+
path = f"/{tablename}/{pk}"
|
102
99
|
return test_app.get(path, status=200)
|
103
100
|
|
104
101
|
def _check_link(self, test_app, resp, item, table, status):
|
105
|
-
link = resp.html.select_one(".form-group.item-{} a"
|
106
|
-
assert re.match(
|
102
|
+
link = resp.html.select_one(f".form-group.item-{item} a")
|
103
|
+
assert re.match(rf"http://localhost/admin/{table}/\d+", link["href"]) is not None
|
107
104
|
test_app.get(link.get("href"), status=status)
|
108
105
|
|
109
106
|
def test_layer_wms_edit(self, edit_url_test_data, test_app):
|
tests/test_functionalities.py
CHANGED
@@ -9,15 +9,18 @@ from . import AbstractViewsTests
|
|
9
9
|
|
10
10
|
@pytest.fixture(scope="function")
|
11
11
|
@pytest.mark.usefixtures("dbsession", "transact")
|
12
|
-
def functionality_test_data(dbsession, transact):
|
12
|
+
def functionality_test_data(dbsession, transact, settings):
|
13
13
|
del transact
|
14
14
|
|
15
15
|
from c2cgeoportal_commons.models.main import Functionality
|
16
16
|
|
17
17
|
functionalities = []
|
18
18
|
for i in range(0, 4):
|
19
|
-
functionality = Functionality(
|
20
|
-
|
19
|
+
functionality = Functionality(
|
20
|
+
settings["admin_interface"]["available_functionalities"][i]["name"],
|
21
|
+
value=f"value_{i}",
|
22
|
+
)
|
23
|
+
functionality.description = f"description_{i}"
|
21
24
|
dbsession.add(functionality)
|
22
25
|
functionalities.append(functionality)
|
23
26
|
|
@@ -28,7 +31,6 @@ def functionality_test_data(dbsession, transact):
|
|
28
31
|
|
29
32
|
@pytest.mark.usefixtures("functionality_test_data", "test_app")
|
30
33
|
class TestFunctionality(AbstractViewsTests):
|
31
|
-
|
32
34
|
_prefix = "/admin/functionalities"
|
33
35
|
|
34
36
|
def test_index_rendering(self, test_app):
|
@@ -47,10 +49,10 @@ class TestFunctionality(AbstractViewsTests):
|
|
47
49
|
|
48
50
|
def test_grid_search(self, test_app):
|
49
51
|
# search on functionality name
|
50
|
-
self.check_search(test_app, "
|
52
|
+
self.check_search(test_app, "default_basemap", total=1)
|
51
53
|
|
52
54
|
def test_submit_new(self, dbsession, test_app):
|
53
|
-
from c2cgeoportal_commons.models.main import Functionality
|
55
|
+
from c2cgeoportal_commons.models.main import Functionality, Log, LogAction
|
54
56
|
|
55
57
|
resp = test_app.post(
|
56
58
|
"/admin/functionalities/new",
|
@@ -63,9 +65,19 @@ class TestFunctionality(AbstractViewsTests):
|
|
63
65
|
).group(1)
|
64
66
|
assert functionality.name == "new_name"
|
65
67
|
|
66
|
-
|
68
|
+
log = dbsession.query(Log).one()
|
69
|
+
assert log.date != None
|
70
|
+
assert log.action == LogAction.INSERT
|
71
|
+
assert log.element_type == "functionality"
|
72
|
+
assert log.element_id == functionality.id
|
73
|
+
assert log.element_name == functionality.name
|
74
|
+
assert log.username == "test_user"
|
75
|
+
|
76
|
+
def test_edit(self, test_app, functionality_test_data, dbsession):
|
77
|
+
from c2cgeoportal_commons.models.main import Log, LogAction
|
78
|
+
|
67
79
|
functionality = functionality_test_data["functionalities"][0]
|
68
|
-
resp = test_app.get("/admin/functionalities/{
|
80
|
+
resp = test_app.get(f"/admin/functionalities/{functionality.id}", status=200)
|
69
81
|
form = resp.form
|
70
82
|
assert str(functionality.id) == self.get_first_field_named(form, "id").value
|
71
83
|
assert "hidden" == self.get_first_field_named(form, "id").attrs["type"]
|
@@ -74,25 +86,51 @@ class TestFunctionality(AbstractViewsTests):
|
|
74
86
|
assert form.submit().status_int == 302
|
75
87
|
assert functionality.description == "new_description"
|
76
88
|
|
89
|
+
log = dbsession.query(Log).one()
|
90
|
+
assert log.date != None
|
91
|
+
assert log.action == LogAction.UPDATE
|
92
|
+
assert log.element_type == "functionality"
|
93
|
+
assert log.element_id == functionality.id
|
94
|
+
assert log.element_name == functionality.name
|
95
|
+
assert log.username == "test_user"
|
96
|
+
|
77
97
|
def test_delete(self, test_app, functionality_test_data, dbsession):
|
78
|
-
from c2cgeoportal_commons.models.main import Functionality
|
98
|
+
from c2cgeoportal_commons.models.main import Functionality, Log, LogAction
|
79
99
|
|
80
100
|
functionality = functionality_test_data["functionalities"][0]
|
81
101
|
deleted_id = functionality.id
|
82
|
-
test_app.delete("/admin/functionalities/{}"
|
102
|
+
test_app.delete(f"/admin/functionalities/{deleted_id}", status=200)
|
83
103
|
assert dbsession.query(Functionality).get(deleted_id) is None
|
84
104
|
|
105
|
+
log = dbsession.query(Log).one()
|
106
|
+
assert log.date != None
|
107
|
+
assert log.action == LogAction.DELETE
|
108
|
+
assert log.element_type == "functionality"
|
109
|
+
assert log.element_id == functionality.id
|
110
|
+
assert log.element_name == functionality.name
|
111
|
+
assert log.username == "test_user"
|
112
|
+
|
85
113
|
def test_duplicate(self, functionality_test_data, test_app, dbsession):
|
86
114
|
from c2cgeoportal_commons.models.main import Functionality
|
87
115
|
|
88
116
|
functionality = functionality_test_data["functionalities"][3]
|
89
|
-
|
117
|
+
|
118
|
+
resp = test_app.get(f"/admin/functionalities/{functionality.id}/duplicate", status=200)
|
119
|
+
|
90
120
|
form = resp.form
|
91
|
-
assert "" ==
|
92
|
-
|
121
|
+
assert form["name"].value == functionality.name
|
122
|
+
assert form["description"].value == functionality.description
|
123
|
+
assert form["value"].value == functionality.value
|
124
|
+
form["value"].value = "another_value"
|
93
125
|
resp = form.submit("submit")
|
126
|
+
|
94
127
|
assert resp.status_int == 302
|
95
|
-
functionality =
|
128
|
+
functionality = (
|
129
|
+
dbsession.query(Functionality)
|
130
|
+
.filter(Functionality.name == functionality.name)
|
131
|
+
.filter(Functionality.value == "another_value")
|
132
|
+
.one()
|
133
|
+
)
|
96
134
|
assert str(functionality.id) == re.match(
|
97
135
|
r"http://localhost/admin/functionalities/(.*)\?msg_col=submit_ok", resp.location
|
98
136
|
).group(1)
|