umap-project 2.5.1__py3-none-any.whl → 2.6.0b0__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.

Potentially problematic release.


This version of umap-project might be problematic. Click here for more details.

Files changed (193) hide show
  1. umap/__init__.py +1 -1
  2. umap/admin.py +6 -1
  3. umap/context_processors.py +2 -1
  4. umap/decorators.py +13 -2
  5. umap/forms.py +26 -2
  6. umap/locale/br/LC_MESSAGES/django.mo +0 -0
  7. umap/locale/br/LC_MESSAGES/django.po +252 -146
  8. umap/locale/ca/LC_MESSAGES/django.mo +0 -0
  9. umap/locale/ca/LC_MESSAGES/django.po +274 -162
  10. umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
  11. umap/locale/cs_CZ/LC_MESSAGES/django.po +261 -150
  12. umap/locale/de/LC_MESSAGES/django.mo +0 -0
  13. umap/locale/de/LC_MESSAGES/django.po +299 -187
  14. umap/locale/el/LC_MESSAGES/django.mo +0 -0
  15. umap/locale/el/LC_MESSAGES/django.po +215 -159
  16. umap/locale/en/LC_MESSAGES/django.po +211 -155
  17. umap/locale/es/LC_MESSAGES/django.mo +0 -0
  18. umap/locale/es/LC_MESSAGES/django.po +255 -144
  19. umap/locale/eu/LC_MESSAGES/django.mo +0 -0
  20. umap/locale/eu/LC_MESSAGES/django.po +254 -198
  21. umap/locale/fa_IR/LC_MESSAGES/django.mo +0 -0
  22. umap/locale/fa_IR/LC_MESSAGES/django.po +346 -234
  23. umap/locale/fr/LC_MESSAGES/django.mo +0 -0
  24. umap/locale/fr/LC_MESSAGES/django.po +216 -160
  25. umap/locale/hu/LC_MESSAGES/django.mo +0 -0
  26. umap/locale/hu/LC_MESSAGES/django.po +215 -159
  27. umap/locale/it/LC_MESSAGES/django.mo +0 -0
  28. umap/locale/it/LC_MESSAGES/django.po +252 -146
  29. umap/locale/ms/LC_MESSAGES/django.mo +0 -0
  30. umap/locale/ms/LC_MESSAGES/django.po +252 -146
  31. umap/locale/pl/LC_MESSAGES/django.mo +0 -0
  32. umap/locale/pl/LC_MESSAGES/django.po +254 -148
  33. umap/locale/pt/LC_MESSAGES/django.mo +0 -0
  34. umap/locale/pt/LC_MESSAGES/django.po +215 -159
  35. umap/locale/sv/LC_MESSAGES/django.mo +0 -0
  36. umap/locale/sv/LC_MESSAGES/django.po +254 -143
  37. umap/locale/th_TH/LC_MESSAGES/django.mo +0 -0
  38. umap/locale/th_TH/LC_MESSAGES/django.po +125 -70
  39. umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
  40. umap/locale/zh_TW/LC_MESSAGES/django.po +256 -145
  41. umap/migrations/0022_add_team.py +94 -0
  42. umap/models.py +45 -10
  43. umap/settings/__init__.py +2 -0
  44. umap/settings/base.py +3 -2
  45. umap/static/umap/base.css +32 -41
  46. umap/static/umap/content.css +19 -25
  47. umap/static/umap/css/icon.css +63 -37
  48. umap/static/umap/css/importers.css +1 -1
  49. umap/static/umap/css/slideshow.css +7 -5
  50. umap/static/umap/css/tableeditor.css +4 -3
  51. umap/static/umap/img/16-white.svg +1 -4
  52. umap/static/umap/img/16.svg +2 -6
  53. umap/static/umap/img/24-white.svg +4 -4
  54. umap/static/umap/img/24.svg +6 -6
  55. umap/static/umap/img/source/16-white.svg +2 -5
  56. umap/static/umap/img/source/16.svg +3 -7
  57. umap/static/umap/img/source/24-white.svg +7 -14
  58. umap/static/umap/img/source/24.svg +10 -17
  59. umap/static/umap/js/components/alerts/alert.css +20 -8
  60. umap/static/umap/js/modules/autocomplete.js +3 -3
  61. umap/static/umap/js/modules/browser.js +4 -3
  62. umap/static/umap/js/modules/caption.js +9 -11
  63. umap/static/umap/js/modules/data/features.js +994 -0
  64. umap/static/umap/js/modules/data/layer.js +1210 -0
  65. umap/static/umap/js/modules/formatter.js +12 -3
  66. umap/static/umap/js/modules/global.js +21 -5
  67. umap/static/umap/js/modules/permissions.js +280 -0
  68. umap/static/umap/js/{umap.icon.js → modules/rendering/icon.js} +77 -56
  69. umap/static/umap/js/modules/rendering/layers/base.js +105 -0
  70. umap/static/umap/js/modules/rendering/layers/classified.js +484 -0
  71. umap/static/umap/js/modules/rendering/layers/cluster.js +103 -0
  72. umap/static/umap/js/modules/rendering/layers/heat.js +182 -0
  73. umap/static/umap/js/modules/rendering/popup.js +99 -0
  74. umap/static/umap/js/modules/rendering/template.js +217 -0
  75. umap/static/umap/js/modules/rendering/ui.js +573 -0
  76. umap/static/umap/js/modules/schema.js +24 -0
  77. umap/static/umap/js/modules/share.js +66 -45
  78. umap/static/umap/js/modules/sync/updaters.js +9 -10
  79. umap/static/umap/js/modules/tableeditor.js +7 -7
  80. umap/static/umap/js/modules/ui/dialog.js +8 -4
  81. umap/static/umap/js/modules/utils.js +22 -13
  82. umap/static/umap/js/umap.controls.js +79 -146
  83. umap/static/umap/js/umap.core.js +9 -9
  84. umap/static/umap/js/umap.forms.js +32 -12
  85. umap/static/umap/js/umap.js +65 -63
  86. umap/static/umap/locale/br.js +35 -35
  87. umap/static/umap/locale/br.json +35 -35
  88. umap/static/umap/locale/ca.js +50 -50
  89. umap/static/umap/locale/ca.json +50 -50
  90. umap/static/umap/locale/de.js +136 -136
  91. umap/static/umap/locale/de.json +136 -136
  92. umap/static/umap/locale/el.js +47 -47
  93. umap/static/umap/locale/el.json +47 -47
  94. umap/static/umap/locale/en.js +7 -1
  95. umap/static/umap/locale/en.json +7 -1
  96. umap/static/umap/locale/fa_IR.js +44 -44
  97. umap/static/umap/locale/fa_IR.json +44 -44
  98. umap/static/umap/locale/fr.js +8 -2
  99. umap/static/umap/locale/fr.json +8 -2
  100. umap/static/umap/locale/pt.js +17 -17
  101. umap/static/umap/locale/pt.json +17 -17
  102. umap/static/umap/locale/pt_PT.js +207 -207
  103. umap/static/umap/locale/pt_PT.json +207 -207
  104. umap/static/umap/locale/th_TH.js +25 -25
  105. umap/static/umap/locale/th_TH.json +25 -25
  106. umap/static/umap/map.css +107 -104
  107. umap/static/umap/nav.css +19 -10
  108. umap/static/umap/unittests/utils.js +230 -107
  109. umap/static/umap/vendors/csv2geojson/csv2geojson.js +62 -40
  110. umap/static/umap/vendors/markercluster/MarkerCluster.Default.css +1 -1
  111. umap/storage.py +1 -0
  112. umap/templates/404.html +5 -1
  113. umap/templates/500.html +3 -1
  114. umap/templates/auth/user_detail.html +8 -2
  115. umap/templates/auth/user_form.html +19 -10
  116. umap/templates/auth/user_stars.html +8 -2
  117. umap/templates/base.html +1 -0
  118. umap/templates/registration/login.html +18 -3
  119. umap/templates/umap/about.html +1 -0
  120. umap/templates/umap/about_summary.html +22 -7
  121. umap/templates/umap/components/alerts/alert.html +42 -21
  122. umap/templates/umap/content.html +2 -0
  123. umap/templates/umap/content_footer.html +6 -2
  124. umap/templates/umap/css.html +1 -0
  125. umap/templates/umap/dashboard_menu.html +15 -0
  126. umap/templates/umap/home.html +14 -4
  127. umap/templates/umap/js.html +4 -9
  128. umap/templates/umap/login_popup_end.html +10 -4
  129. umap/templates/umap/map_detail.html +8 -2
  130. umap/templates/umap/map_fragment.html +3 -1
  131. umap/templates/umap/map_init.html +2 -1
  132. umap/templates/umap/map_list.html +4 -3
  133. umap/templates/umap/map_table.html +36 -12
  134. umap/templates/umap/messages.html +0 -1
  135. umap/templates/umap/navigation.html +2 -1
  136. umap/templates/umap/password_change.html +5 -1
  137. umap/templates/umap/password_change_done.html +8 -2
  138. umap/templates/umap/search.html +8 -2
  139. umap/templates/umap/search_bar.html +1 -0
  140. umap/templates/umap/team_confirm_delete.html +19 -0
  141. umap/templates/umap/team_detail.html +27 -0
  142. umap/templates/umap/team_form.html +60 -0
  143. umap/templates/umap/user_dashboard.html +7 -9
  144. umap/templates/umap/user_teams.html +51 -0
  145. umap/tests/base.py +8 -1
  146. umap/tests/conftest.py +6 -0
  147. umap/tests/fixtures/test_circles_layer.geojson +219 -0
  148. umap/tests/fixtures/test_upload_georss.xml +20 -0
  149. umap/tests/integration/conftest.py +18 -4
  150. umap/tests/integration/helpers.py +12 -0
  151. umap/tests/integration/test_anonymous_owned_map.py +23 -0
  152. umap/tests/integration/test_basics.py +29 -0
  153. umap/tests/integration/test_caption.py +20 -0
  154. umap/tests/integration/test_circles_layer.py +69 -0
  155. umap/tests/integration/test_draw_polygon.py +110 -13
  156. umap/tests/integration/test_draw_polyline.py +8 -18
  157. umap/tests/integration/test_edit_datalayer.py +1 -1
  158. umap/tests/integration/test_import.py +64 -5
  159. umap/tests/integration/test_owned_map.py +21 -13
  160. umap/tests/integration/test_team.py +47 -0
  161. umap/tests/integration/test_tilelayer.py +19 -2
  162. umap/tests/integration/test_view_marker.py +28 -1
  163. umap/tests/integration/test_websocket_sync.py +5 -5
  164. umap/tests/test_datalayer.py +32 -7
  165. umap/tests/test_datalayer_views.py +1 -1
  166. umap/tests/test_map.py +30 -4
  167. umap/tests/test_map_views.py +2 -2
  168. umap/tests/test_statics.py +40 -0
  169. umap/tests/test_team_views.py +131 -0
  170. umap/tests/test_views.py +15 -1
  171. umap/urls.py +23 -13
  172. umap/views.py +116 -10
  173. {umap_project-2.5.1.dist-info → umap_project-2.6.0b0.dist-info}/METADATA +9 -9
  174. {umap_project-2.5.1.dist-info → umap_project-2.6.0b0.dist-info}/RECORD +177 -170
  175. umap/static/umap/js/umap.datalayer.permissions.js +0 -70
  176. umap/static/umap/js/umap.features.js +0 -1290
  177. umap/static/umap/js/umap.layer.js +0 -1837
  178. umap/static/umap/js/umap.permissions.js +0 -208
  179. umap/static/umap/js/umap.popup.js +0 -341
  180. umap/static/umap/test/TableEditor.js +0 -104
  181. umap/static/umap/vendors/leaflet/leaflet-src.js +0 -14512
  182. umap/static/umap/vendors/leaflet/leaflet-src.js.map +0 -1
  183. umap/static/umap/vendors/leaflet/leaflet.js +0 -6
  184. umap/static/umap/vendors/leaflet/leaflet.js.map +0 -1
  185. umap/static/umap/vendors/markercluster/WhereAreTheJavascriptFiles.txt +0 -5
  186. umap/static/umap/vendors/markercluster/leaflet.markercluster-src.js +0 -2718
  187. umap/static/umap/vendors/markercluster/leaflet.markercluster-src.js.map +0 -1
  188. umap/static/umap/vendors/toolbar/leaflet.toolbar-src.css +0 -117
  189. umap/static/umap/vendors/toolbar/leaflet.toolbar-src.js +0 -365
  190. umap/tests/integration/test_statics.py +0 -47
  191. {umap_project-2.5.1.dist-info → umap_project-2.6.0b0.dist-info}/WHEEL +0 -0
  192. {umap_project-2.5.1.dist-info → umap_project-2.6.0b0.dist-info}/entry_points.txt +0 -0
  193. {umap_project-2.5.1.dist-info → umap_project-2.6.0b0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,219 @@
1
+ {
2
+ "type": "FeatureCollection",
3
+ "features": [
4
+ {
5
+ "type": "Feature",
6
+ "geometry": {
7
+ "type": "Point",
8
+ "coordinates": [
9
+ -1.5869228,
10
+ 47.1988448
11
+ ]
12
+ },
13
+ "properties": {
14
+ "@id": "node/8371195387",
15
+ "access": "private",
16
+ "amenity": "bicycle_parking",
17
+ "covered": "yes",
18
+ "fee": "no",
19
+ "name": "station with unknown capacity"
20
+ },
21
+ "id": "capa0"
22
+ },
23
+ {
24
+ "type": "Feature",
25
+ "geometry": {
26
+ "type": "Point",
27
+ "coordinates": [
28
+ -1.5567325,
29
+ 47.2223201
30
+ ]
31
+ },
32
+ "properties": {
33
+ "@id": "node/3750335624",
34
+ "amenity": "bicycle_parking",
35
+ "bicycle_parking": "stands",
36
+ "capacity": "2",
37
+ "check_date:capacity": "2021-05-12",
38
+ "covered": "no",
39
+ "material": "metal",
40
+ "name": "tiny station with 2"
41
+ },
42
+ "id": "capa2"
43
+ },
44
+ {
45
+ "type": "Feature",
46
+ "geometry": {
47
+ "type": "Point",
48
+ "coordinates": [
49
+ -1.5293571,
50
+ 47.2285598
51
+ ]
52
+ },
53
+ "properties": {
54
+ "@id": "node/7149702104",
55
+ "amenity": "bicycle_parking",
56
+ "bicycle_parking": "wall_loops",
57
+ "covered": "yes",
58
+ "capacity": "2",
59
+ "name": "tiny station with 3"
60
+ },
61
+ "id": "capa3"
62
+ },
63
+ {
64
+ "type": "Feature",
65
+ "geometry": {
66
+ "type": "Point",
67
+ "coordinates": [
68
+ -1.5613176,
69
+ 47.2223468
70
+ ]
71
+ },
72
+ "properties": {
73
+ "@id": "node/5206704322",
74
+ "amenity": "bicycle_parking",
75
+ "bicycle_parking": "stands",
76
+ "capacity": "4",
77
+ "name": "small station with 4"
78
+ },
79
+ "id": "capa4"
80
+ },
81
+ {
82
+ "type": "Feature",
83
+ "geometry": {
84
+ "type": "Point",
85
+ "coordinates": [
86
+ -1.5465724,
87
+ 47.2074831
88
+ ]
89
+ },
90
+ "properties": {
91
+ "@id": "node/10539987424",
92
+ "amenity": "bicycle_parking",
93
+ "bicycle_parking": "stands",
94
+ "capacity": "6",
95
+ "covered": "no",
96
+ "material": "metal",
97
+ "name": "small station with 6"
98
+ },
99
+ "id": "capa6"
100
+ },
101
+ {
102
+ "type": "Feature",
103
+ "geometry": {
104
+ "type": "Point",
105
+ "coordinates": [
106
+ -1.5877882,
107
+ 47.2179441
108
+ ]
109
+ },
110
+ "properties": {
111
+ "@id": "node/10239046793",
112
+ "amenity": "bicycle_parking",
113
+ "capacity": 8
114
+ },
115
+ "id": "capa8"
116
+ },
117
+ {
118
+ "type": "Feature",
119
+ "geometry": {
120
+ "type": "Point",
121
+ "coordinates": [
122
+ -1.5406938,
123
+ 47.2312451
124
+ ]
125
+ },
126
+ "properties": {
127
+ "@id": "node/5176046494",
128
+ "amenity": "bicycle_parking",
129
+ "bicycle_parking": "rack",
130
+ "capacity": "27",
131
+ "name": "middle station with 27"
132
+ },
133
+ "id": "cap27"
134
+ },
135
+ {
136
+ "type": "Feature",
137
+ "geometry": {
138
+ "type": "Point",
139
+ "coordinates": [
140
+ -1.5344658,
141
+ 47.1988441
142
+ ]
143
+ },
144
+ "properties": {
145
+ "@id": "node/4126326089",
146
+ "access": "private",
147
+ "amenity": "bicycle_parking",
148
+ "bicycle_parking": "building",
149
+ "capacity": "64",
150
+ "covered": "yes",
151
+ "material": "metal",
152
+ "name": "middle station with 64"
153
+ },
154
+ "id": "cap64"
155
+ },
156
+ {
157
+ "type": "Feature",
158
+ "geometry": {
159
+ "type": "Point",
160
+ "coordinates": [
161
+ -1.5433176,
162
+ 47.2172633
163
+ ]
164
+ },
165
+ "properties": {
166
+ "@id": "way/1001063092",
167
+ "access": "yes",
168
+ "amenity": "bicycle_parking",
169
+ "architect": "Forma 6;Phytolab",
170
+ "bicycle_parking": "shed",
171
+ "building": "roof",
172
+ "building:architecture": "contemporary",
173
+ "capacity": "676",
174
+ "capacity:cargo_bike": "22",
175
+ "capacity:motorcycle": "33",
176
+ "covered": "yes",
177
+ "fee": "no",
178
+ "name": "big station with 676",
179
+ "start_date": "2021-11-15",
180
+ "@geometry": "center"
181
+ },
182
+ "id": "ca676"
183
+ },
184
+ {
185
+ "type": "Feature",
186
+ "geometry": {
187
+ "type": "Point",
188
+ "coordinates": [
189
+ -1.5291998,
190
+ 47.259166
191
+ ]
192
+ },
193
+ "properties": {
194
+ "@id": "node/11141117088",
195
+ "amenity": "bicycle_parking",
196
+ "bicycle_parking": "stands",
197
+ "capacity": "1160",
198
+ "temporary": "yes",
199
+ "temporary:date_off": "2023-10-28",
200
+ "temporary:date_on": "2023-09-08",
201
+ "name": "huge station with 1160"
202
+ },
203
+ "id": "c1160"
204
+ }
205
+ ],
206
+ "_umap_options": {
207
+ "displayOnLoad": true,
208
+ "inCaption": true,
209
+ "browsable": true,
210
+ "editMode": "advanced",
211
+ "name": "Calque 1",
212
+ "remoteData": {},
213
+ "type": "Circles",
214
+ "circles": {
215
+ "radius": {"min": 2, "max": 40},
216
+ "property": "capacity"
217
+ }
218
+ }
219
+ }
@@ -0,0 +1,20 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <rss version="2.0" xmlns:creativeCommons="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:flickr="urn:flickr:user" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:georss="http://www.georss.org/georss" xmlns:media="http://search.yahoo.com/mrss/" xmlns:woe="http://where.yahooapis.com/v1/schema.rng">
3
+ <channel>
4
+ <title>Test stream</title>
5
+ <link>http://www.pouet.fr/link/</link>
6
+ <description/>
7
+ <pubDate>Sun, 13 Apr 2014 09:20:36 -0700</pubDate>
8
+ <lastBuildDate>Sun, 13 Apr 2014 09:20:36 -0700</lastBuildDate>
9
+ <generator>http://www.pouet.com/</generator>
10
+ <item>
11
+ <title>Title 1</title>
12
+ <link>http://link.com</link>
13
+ <description>Description 1</description>
14
+ <pubDate>Sun, 13 Apr 2014 09:20:36 -0700</pubDate>
15
+ <geo:lat>53.443324</geo:lat>
16
+ <geo:long>-2.218337</geo:long>
17
+ <enclosure url="http://farm4.staticflickr.com/3758/13906321891_faa9be0b8e_b.jpg" type="image/jpeg" />
18
+ </item>
19
+ </channel>
20
+ </rss>
@@ -27,10 +27,24 @@ def mock_osm_tiles(page):
27
27
 
28
28
 
29
29
  @pytest.fixture
30
- def page(context):
31
- page = context.new_page()
32
- page.on("console", lambda msg: print(msg.text) if msg.type != "warning" else None)
33
- return page
30
+ def new_page(context):
31
+ def make_page(prefix="console"):
32
+ page = context.new_page()
33
+ page.on(
34
+ "console",
35
+ lambda msg: print(f"{prefix}: {msg.text}")
36
+ if msg.type != "warning"
37
+ else None,
38
+ )
39
+ page.on("pageerror", lambda exc: print(f"{prefix} uncaught exception: {exc}"))
40
+ return page
41
+
42
+ yield make_page
43
+
44
+
45
+ @pytest.fixture
46
+ def page(new_page):
47
+ return new_page()
34
48
 
35
49
 
36
50
  @pytest.fixture
@@ -0,0 +1,12 @@
1
+ import json
2
+ import re
3
+ from pathlib import Path
4
+
5
+ from umap.models import DataLayer
6
+
7
+
8
+ def save_and_get_json(page):
9
+ with page.expect_response(re.compile(r".*/datalayer/create/.*")):
10
+ page.get_by_role("button", name="Save").click()
11
+ datalayer = DataLayer.objects.last()
12
+ return json.loads(Path(datalayer.geojson.path).read_text())
@@ -219,3 +219,26 @@ def test_alert_message_after_create_show_link_even_without_mail(
219
219
  ).to_be_visible()
220
220
  expect(alert.get_by_role("button", name="Copy")).to_be_visible()
221
221
  expect(alert.get_by_role("button", name="Send me the link")).to_be_hidden()
222
+
223
+
224
+ def test_anonymous_owner_can_delete_the_map(anonymap, live_server, owner_session):
225
+ assert Map.objects.count() == 1
226
+ owner_session.goto(f"{live_server.url}{anonymap.get_absolute_url()}")
227
+ owner_session.get_by_role("button", name="Edit").click()
228
+ owner_session.get_by_role("link", name="Map advanced properties").click()
229
+ owner_session.get_by_text("Advanced actions").click()
230
+ expect(owner_session.get_by_role("button", name="Delete")).to_be_visible()
231
+ owner_session.get_by_role("button", name="Delete").click()
232
+ with owner_session.expect_response(re.compile(r".*/update/delete/.*")):
233
+ owner_session.get_by_role("button", name="OK").click()
234
+ assert not Map.objects.count()
235
+
236
+
237
+ def test_non_owner_cannot_see_delete_button(anonymap, live_server, page):
238
+ anonymap.edit_status = Map.ANONYMOUS
239
+ anonymap.save()
240
+ page.goto(f"{live_server.url}{anonymap.get_absolute_url()}")
241
+ page.get_by_role("button", name="Edit").click()
242
+ page.get_by_role("link", name="Map advanced properties").click()
243
+ page.get_by_text("Advanced actions").click()
244
+ expect(page.get_by_role("button", name="Delete")).to_be_hidden()
@@ -1,6 +1,10 @@
1
+ import re
2
+
1
3
  import pytest
2
4
  from playwright.sync_api import expect
3
5
 
6
+ from umap.models import Map
7
+
4
8
 
5
9
  def test_page_title(page, live_server):
6
10
  page.goto(live_server.url)
@@ -66,3 +70,28 @@ def test_cannot_put_script_tag_in_datalayer_name_or_description(
66
70
  expect(page.get_by_text('<script>alert("attack")</script>')).to_be_visible()
67
71
  # Description should contain escaped HTML
68
72
  expect(page.get_by_text("before after")).to_be_visible()
73
+
74
+
75
+ def test_login_from_map_page(live_server, page, tilelayer, settings, user, context):
76
+ settings.ENABLE_ACCOUNT_LOGIN = True
77
+ assert Map.objects.count() == 0
78
+ page.goto(f"{live_server.url}/en/map/new/")
79
+ with (
80
+ page.expect_response(re.compile(r".*/map/create/")),
81
+ context.expect_page() as login_page_info,
82
+ ):
83
+ page.get_by_role("button", name="Save").click()
84
+ assert Map.objects.count() == 0
85
+ login_page = login_page_info.value
86
+ expect(login_page).to_have_title("Login")
87
+ login_page.get_by_placeholder("Username").fill(user.username)
88
+ login_page.get_by_placeholder("Password").fill("123123")
89
+ with page.expect_response(re.compile(r".*/map/create/")):
90
+ login_page.locator('#login_form input[type="submit"]').click()
91
+ # Login page should be closed
92
+ page.wait_for_timeout(500) # Seems needed from time to time…
93
+ assert len(context.pages) == 1
94
+ # Save should have proceed
95
+ assert Map.objects.count() == 1
96
+ # Use name should now appear on the header toolbar
97
+ expect(page.get_by_text("My Dashboard (Joe)")).to_be_visible()
@@ -25,3 +25,23 @@ def test_caption(live_server, page, map):
25
25
  panel.locator(".datalayer-legend .off").get_by_text(non_loaded.name)
26
26
  ).to_be_visible()
27
27
  expect(panel.locator(".datalayer-legend").get_by_text(hidden.name)).to_be_hidden()
28
+
29
+
30
+ def test_caption_should_display_owner_as_author(live_server, page, map):
31
+ map.settings["properties"]["onLoadPanel"] = "caption"
32
+ map.save()
33
+ page.goto(f"{live_server.url}{map.get_absolute_url()}")
34
+ panel = page.locator(".panel.left.on")
35
+ expect(panel).to_be_visible()
36
+ expect(panel.get_by_text("By Gabriel")).to_be_visible()
37
+
38
+
39
+ def test_caption_should_display_team_as_author(live_server, page, map, team):
40
+ map.settings["properties"]["onLoadPanel"] = "caption"
41
+ map.team = team
42
+ map.save()
43
+ page.goto(f"{live_server.url}{map.get_absolute_url()}")
44
+ panel = page.locator(".panel.left.on")
45
+ expect(panel).to_be_visible()
46
+ expect(panel.get_by_text("By Gabriel")).to_be_hidden()
47
+ expect(panel.get_by_text("By Awesome Team")).to_be_visible()
@@ -0,0 +1,69 @@
1
+ import json
2
+ from pathlib import Path
3
+
4
+ import pytest
5
+ from playwright.sync_api import expect
6
+
7
+ from ..base import DataLayerFactory
8
+
9
+ pytestmark = pytest.mark.django_db
10
+
11
+
12
+ def test_basic_circles_layer(map, live_server, page):
13
+ path = Path(__file__).parent.parent / "fixtures/test_circles_layer.geojson"
14
+ data = json.loads(path.read_text())
15
+ DataLayerFactory(data=data, map=map)
16
+ page.goto(f"{live_server.url}{map.get_absolute_url()}#12/47.2210/-1.5621")
17
+ paths = page.locator("path")
18
+ expect(paths).to_have_count(10)
19
+ # Last arc curve command
20
+ assert (
21
+ page.locator("[data-feature=c1160]")
22
+ .get_attribute("d")
23
+ .endswith("a40,40 0 1,0 -80,0 ")
24
+ )
25
+ assert (
26
+ page.locator("[data-feature=ca676]")
27
+ .get_attribute("d")
28
+ .endswith("a31,31 0 1,0 -62,0 ")
29
+ )
30
+ assert (
31
+ page.locator("[data-feature=cap64]")
32
+ .get_attribute("d")
33
+ .endswith("a10,10 0 1,0 -20,0 ")
34
+ )
35
+ assert (
36
+ page.locator("[data-feature=cap27]")
37
+ .get_attribute("d")
38
+ .endswith("a6,6 0 1,0 -12,0 ")
39
+ )
40
+ assert (
41
+ page.locator("[data-feature=capa8]")
42
+ .get_attribute("d")
43
+ .endswith("a4,4 0 1,0 -8,0 ")
44
+ )
45
+ assert (
46
+ page.locator("[data-feature=capa6]")
47
+ .get_attribute("d")
48
+ .endswith("a3,3 0 1,0 -6,0 ")
49
+ )
50
+ assert (
51
+ page.locator("[data-feature=capa4]")
52
+ .get_attribute("d")
53
+ .endswith("a3,3 0 1,0 -6,0 ")
54
+ )
55
+ assert (
56
+ page.locator("[data-feature=capa3]")
57
+ .get_attribute("d")
58
+ .endswith("a2,2 0 1,0 -4,0 ")
59
+ )
60
+ assert (
61
+ page.locator("[data-feature=capa2]")
62
+ .get_attribute("d")
63
+ .endswith("a2,2 0 1,0 -4,0 ")
64
+ )
65
+ assert (
66
+ page.locator("[data-feature=capa0]")
67
+ .get_attribute("d")
68
+ .endswith("a2,2 0 1,0 -4,0 ")
69
+ )
@@ -1,22 +1,11 @@
1
- import json
2
- import re
3
- from pathlib import Path
4
-
5
1
  import pytest
6
2
  from playwright.sync_api import expect
7
3
 
8
- from umap.models import DataLayer
4
+ from .helpers import save_and_get_json
9
5
 
10
6
  pytestmark = pytest.mark.django_db
11
7
 
12
8
 
13
- def save_and_get_json(page):
14
- with page.expect_response(re.compile(r".*/datalayer/create/.*")):
15
- page.get_by_role("button", name="Save").click()
16
- datalayer = DataLayer.objects.last()
17
- return json.loads(Path(datalayer.geojson.path).read_text())
18
-
19
-
20
9
  def test_draw_polygon(page, live_server, tilelayer):
21
10
  page.goto(f"{live_server.url}/en/map/new/")
22
11
 
@@ -243,7 +232,8 @@ def test_can_transfer_shape_from_simple_polygon(live_server, page, tilelayer):
243
232
  expect(polygons).to_have_count(1)
244
233
 
245
234
 
246
- def test_can_extract_shape(live_server, page, tilelayer):
235
+ def test_can_extract_shape(live_server, page, tilelayer, settings):
236
+ settings.UMAP_ALLOW_ANONYMOUS = True
247
237
  page.goto(f"{live_server.url}/en/map/new/")
248
238
  polygons = page.locator(".leaflet-overlay-pane path")
249
239
  expect(polygons).to_have_count(0)
@@ -269,6 +259,58 @@ def test_can_extract_shape(live_server, page, tilelayer):
269
259
  polygons.first.click(position={"x": 20, "y": 20}, button="right")
270
260
  extract_button.click()
271
261
  expect(polygons).to_have_count(2)
262
+ data = save_and_get_json(page)
263
+ assert len(data["features"]) == 2
264
+ assert data["features"][0]["geometry"]["type"] == "Polygon"
265
+ assert data["features"][1]["geometry"]["type"] == "Polygon"
266
+ assert data["features"][0]["geometry"]["coordinates"] == [
267
+ [
268
+ [
269
+ -6.569824,
270
+ 53.159947,
271
+ ],
272
+ [
273
+ -6.569824,
274
+ 52.49616,
275
+ ],
276
+ [
277
+ -7.668457,
278
+ 52.49616,
279
+ ],
280
+ [
281
+ -7.668457,
282
+ 53.159947,
283
+ ],
284
+ [
285
+ -6.569824,
286
+ 53.159947,
287
+ ],
288
+ ],
289
+ ]
290
+ assert data["features"][1]["geometry"]["coordinates"] == [
291
+ [
292
+ [
293
+ -8.76709,
294
+ 54.457267,
295
+ ],
296
+ [
297
+ -8.76709,
298
+ 53.813626,
299
+ ],
300
+ [
301
+ -9.865723,
302
+ 53.813626,
303
+ ],
304
+ [
305
+ -9.865723,
306
+ 54.457267,
307
+ ],
308
+ [
309
+ -8.76709,
310
+ 54.457267,
311
+ ],
312
+ ],
313
+ ]
272
314
 
273
315
 
274
316
  def test_cannot_transfer_shape_to_line(live_server, page, tilelayer):
@@ -367,3 +409,58 @@ def test_can_transform_polygon_to_line(live_server, page, tilelayer, settings):
367
409
  data = save_and_get_json(page)
368
410
  assert len(data["features"]) == 1
369
411
  assert data["features"][0]["geometry"]["type"] == "LineString"
412
+
413
+
414
+ def test_can_draw_a_polygon_and_invert_it(live_server, page, tilelayer, settings):
415
+ settings.UMAP_ALLOW_ANONYMOUS = True
416
+ page.goto(f"{live_server.url}/en/map/new/")
417
+ paths = page.locator(".leaflet-overlay-pane path")
418
+ expect(paths).to_have_count(0)
419
+ page.get_by_title("Draw a polygon").click()
420
+ map = page.locator("#map")
421
+ map.click(position={"x": 200, "y": 100})
422
+ map.click(position={"x": 200, "y": 200})
423
+ map.click(position={"x": 100, "y": 200})
424
+ map.click(position={"x": 100, "y": 100})
425
+ # Click again to finish
426
+ map.click(position={"x": 100, "y": 100})
427
+ expect(paths).to_have_count(1)
428
+ page.get_by_text("Advanced properties").click()
429
+ page.get_by_text("Display the polygon inverted").click()
430
+ data = save_and_get_json(page)
431
+ assert len(data["features"]) == 1
432
+ assert data["features"][0]["geometry"]["type"] == "Polygon"
433
+ assert data["features"][0]["geometry"]["coordinates"] == [
434
+ [
435
+ [
436
+ -7.668457,
437
+ 54.457267,
438
+ ],
439
+ [
440
+ -7.668457,
441
+ 53.159947,
442
+ ],
443
+ [
444
+ -9.865723,
445
+ 53.159947,
446
+ ],
447
+ [
448
+ -9.865723,
449
+ 54.457267,
450
+ ],
451
+ [
452
+ -7.668457,
453
+ 54.457267,
454
+ ],
455
+ ],
456
+ ]
457
+
458
+ page.get_by_role("button", name="View").click()
459
+ popup = page.locator(".leaflet-popup")
460
+ expect(popup).to_be_hidden()
461
+ # Now click on the middle of the polygon, it should not show the popup
462
+ map.click(position={"x": 150, "y": 150})
463
+ expect(popup).to_be_hidden()
464
+ # Click elsewhere on the map, it should now show the popup
465
+ map.click(position={"x": 250, "y": 250})
466
+ expect(popup).to_be_visible()
@@ -1,22 +1,11 @@
1
- import json
2
- import re
3
- from pathlib import Path
4
-
5
1
  import pytest
6
2
  from playwright.sync_api import expect
7
3
 
8
- from umap.models import DataLayer
4
+ from .helpers import save_and_get_json
9
5
 
10
6
  pytestmark = pytest.mark.django_db
11
7
 
12
8
 
13
- def save_and_get_json(page):
14
- with page.expect_response(re.compile(r".*/datalayer/create/.*")):
15
- page.get_by_role("button", name="Save").click()
16
- datalayer = DataLayer.objects.last()
17
- return json.loads(Path(datalayer.geojson.path).read_text())
18
-
19
-
20
9
  def test_draw_polyline(page, live_server, tilelayer):
21
10
  page.goto(f"{live_server.url}/en/map/new/")
22
11
 
@@ -187,7 +176,7 @@ def test_can_transfer_shape_from_simple_polyline(live_server, page, tilelayer):
187
176
  map.click(position={"x": 100, "y": 200})
188
177
  expect(lines).to_have_count(1)
189
178
 
190
- # Draw another polygon
179
+ # Draw another line
191
180
  page.get_by_title("Draw a polyline").click()
192
181
  map.click(position={"x": 250, "y": 250})
193
182
  map.click(position={"x": 200, "y": 250})
@@ -196,7 +185,7 @@ def test_can_transfer_shape_from_simple_polyline(live_server, page, tilelayer):
196
185
  map.click(position={"x": 200, "y": 200})
197
186
  expect(lines).to_have_count(2)
198
187
 
199
- # Now that polygon 2 is selected, right click on first one
188
+ # Now that line 2 is selected, right click on first one
200
189
  # and transfer shape
201
190
  lines.first.click(position={"x": 10, "y": 1}, button="right")
202
191
  page.get_by_role("link", name="Transfer shape to edited feature").click()
@@ -235,18 +224,19 @@ def test_can_transfer_shape_from_multi(live_server, page, tilelayer, settings):
235
224
  map.click(position={"x": 300, "y": 300})
236
225
  expect(lines).to_have_count(2)
237
226
 
238
- # Now that polygon 2 is selected, right click on first one
227
+ # Now that line 2 is selected, right click on first one
239
228
  # and transfer shape
240
229
  lines.first.click(position={"x": 10, "y": 1}, button="right")
241
230
  page.get_by_role("link", name="Transfer shape to edited feature").click()
242
231
  expect(lines).to_have_count(2)
243
232
  data = save_and_get_json(page)
244
- # FIXME this should be a LineString, not MultiLineString
245
233
  assert data["features"][0]["geometry"] == {
246
234
  "coordinates": [
247
- [[-6.569824, 52.49616], [-7.668457, 52.49616], [-7.668457, 53.159947]]
235
+ [-6.569824, 52.49616],
236
+ [-7.668457, 52.49616],
237
+ [-7.668457, 53.159947],
248
238
  ],
249
- "type": "MultiLineString",
239
+ "type": "LineString",
250
240
  }
251
241
  assert data["features"][1]["geometry"] == {
252
242
  "coordinates": [
@@ -107,7 +107,7 @@ def test_can_change_icon_class(live_server, openmap, page):
107
107
  page.locator(".panel.right").get_by_title("Edit", exact=True).click()
108
108
  page.get_by_text("Shape properties").click()
109
109
  page.locator(".umap-field-iconClass a.define").click()
110
- page.get_by_text("Circle").click()
110
+ page.get_by_text("Circle", exact=True).click()
111
111
  expect(page.locator(".umap-circle-icon")).to_be_visible()
112
112
  expect(page.locator(".umap-div-icon")).to_be_hidden()
113
113