wagtail 6.1.2__py3-none-any.whl → 6.2rc1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (644) hide show
  1. wagtail/__init__.py +1 -1
  2. wagtail/actions/copy_for_translation.py +15 -1
  3. wagtail/admin/checks.py +20 -30
  4. wagtail/admin/forms/pages.py +10 -0
  5. wagtail/admin/icons.py +43 -0
  6. wagtail/admin/locale/ar/LC_MESSAGES/django.po +2 -2
  7. wagtail/admin/locale/be/LC_MESSAGES/django.po +7 -7
  8. wagtail/admin/locale/be/LC_MESSAGES/djangojs.po +3 -3
  9. wagtail/admin/locale/ca/LC_MESSAGES/django.mo +0 -0
  10. wagtail/admin/locale/ca/LC_MESSAGES/django.po +51 -50
  11. wagtail/admin/locale/cs/LC_MESSAGES/django.po +10 -8
  12. wagtail/admin/locale/de/LC_MESSAGES/django.po +49 -47
  13. wagtail/admin/locale/dv/LC_MESSAGES/django.po +8 -8
  14. wagtail/admin/locale/el/LC_MESSAGES/django.po +4 -4
  15. wagtail/admin/locale/en/LC_MESSAGES/django.po +405 -295
  16. wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +21 -3
  17. wagtail/admin/locale/es/LC_MESSAGES/django.po +40 -39
  18. wagtail/admin/locale/es_419/LC_MESSAGES/django.po +8 -8
  19. wagtail/admin/locale/et/LC_MESSAGES/django.po +14 -12
  20. wagtail/admin/locale/fa/LC_MESSAGES/django.mo +0 -0
  21. wagtail/admin/locale/fa/LC_MESSAGES/django.po +93 -19
  22. wagtail/admin/locale/fa/LC_MESSAGES/djangojs.mo +0 -0
  23. wagtail/admin/locale/fa/LC_MESSAGES/djangojs.po +5 -1
  24. wagtail/admin/locale/fi/LC_MESSAGES/django.po +18 -18
  25. wagtail/admin/locale/fr/LC_MESSAGES/django.mo +0 -0
  26. wagtail/admin/locale/fr/LC_MESSAGES/django.po +134 -46
  27. wagtail/admin/locale/gl/LC_MESSAGES/django.po +55 -54
  28. wagtail/admin/locale/hr_HR/LC_MESSAGES/django.po +13 -12
  29. wagtail/admin/locale/hr_HR/LC_MESSAGES/djangojs.po +2 -2
  30. wagtail/admin/locale/hu/LC_MESSAGES/django.po +45 -42
  31. wagtail/admin/locale/id_ID/LC_MESSAGES/django.po +6 -6
  32. wagtail/admin/locale/is_IS/LC_MESSAGES/django.po +53 -51
  33. wagtail/admin/locale/it/LC_MESSAGES/django.po +56 -55
  34. wagtail/admin/locale/ja/LC_MESSAGES/django.po +2 -2
  35. wagtail/admin/locale/ko/LC_MESSAGES/django.po +18 -17
  36. wagtail/admin/locale/lt/LC_MESSAGES/django.po +4 -4
  37. wagtail/admin/locale/nb/LC_MESSAGES/django.po +22 -22
  38. wagtail/admin/locale/nl/LC_MESSAGES/django.po +44 -41
  39. wagtail/admin/locale/pl/LC_MESSAGES/django.po +49 -47
  40. wagtail/admin/locale/pl/LC_MESSAGES/djangojs.po +3 -3
  41. wagtail/admin/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
  42. wagtail/admin/locale/pt_BR/LC_MESSAGES/django.po +46 -26
  43. wagtail/admin/locale/pt_PT/LC_MESSAGES/django.po +21 -20
  44. wagtail/admin/locale/ro/LC_MESSAGES/django.po +51 -50
  45. wagtail/admin/locale/ru/LC_MESSAGES/django.po +60 -59
  46. wagtail/admin/locale/ru/LC_MESSAGES/djangojs.po +3 -3
  47. wagtail/admin/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
  48. wagtail/admin/locale/sk_SK/LC_MESSAGES/django.po +15 -5
  49. wagtail/admin/locale/sl/LC_MESSAGES/django.mo +0 -0
  50. wagtail/admin/locale/sl/LC_MESSAGES/django.po +86 -39
  51. wagtail/admin/locale/sl/LC_MESSAGES/djangojs.po +2 -2
  52. wagtail/admin/locale/sv/LC_MESSAGES/django.mo +0 -0
  53. wagtail/admin/locale/sv/LC_MESSAGES/django.po +117 -41
  54. wagtail/admin/locale/sv/LC_MESSAGES/djangojs.mo +0 -0
  55. wagtail/admin/locale/sv/LC_MESSAGES/djangojs.po +5 -2
  56. wagtail/admin/locale/tet/LC_MESSAGES/django.po +2 -2
  57. wagtail/admin/locale/th/LC_MESSAGES/django.po +4 -4
  58. wagtail/admin/locale/tr/LC_MESSAGES/django.po +4 -4
  59. wagtail/admin/locale/tr_TR/LC_MESSAGES/django.po +4 -4
  60. wagtail/admin/locale/uk/LC_MESSAGES/django.po +11 -10
  61. wagtail/admin/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  62. wagtail/admin/locale/zh_Hans/LC_MESSAGES/django.po +84 -13
  63. wagtail/admin/locale/zh_Hant/LC_MESSAGES/django.po +2 -2
  64. wagtail/admin/menu.py +2 -2
  65. wagtail/admin/migrations/0004_editingsession.py +57 -0
  66. wagtail/admin/migrations/0005_editingsession_is_editing.py +18 -0
  67. wagtail/admin/models.py +36 -3
  68. wagtail/admin/rich_text/editors/draftail/__init__.py +2 -20
  69. wagtail/admin/static/wagtailadmin/css/core.css +1 -1
  70. wagtail/admin/static/wagtailadmin/js/bulk-actions.js +1 -1
  71. wagtail/admin/static/wagtailadmin/js/chooser-modal.js +1 -1
  72. wagtail/admin/static/wagtailadmin/js/chooser-widget-telepath.js +1 -1
  73. wagtail/admin/static/wagtailadmin/js/chooser-widget.js +1 -1
  74. wagtail/admin/static/wagtailadmin/js/comments.js +1 -1
  75. wagtail/admin/static/wagtailadmin/js/core.js +1 -1
  76. wagtail/admin/static/wagtailadmin/js/date-time-chooser.js +1 -1
  77. wagtail/admin/static/wagtailadmin/js/draftail.js +1 -1
  78. wagtail/admin/static/wagtailadmin/js/expanding-formset.js +1 -1
  79. wagtail/admin/static/wagtailadmin/js/filtered-select.js +1 -1
  80. wagtail/admin/static/wagtailadmin/js/modal-workflow.js +1 -1
  81. wagtail/admin/static/wagtailadmin/js/page-chooser-modal.js +1 -1
  82. wagtail/admin/static/wagtailadmin/js/page-chooser-telepath.js +1 -1
  83. wagtail/admin/static/wagtailadmin/js/page-chooser.js +1 -1
  84. wagtail/admin/static/wagtailadmin/js/preview-panel.js +2 -1
  85. wagtail/admin/static/wagtailadmin/js/preview-panel.js.LICENSE.txt +11 -0
  86. wagtail/admin/static/wagtailadmin/js/privacy-switch.js +1 -1
  87. wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
  88. wagtail/admin/static/wagtailadmin/js/task-chooser-modal.js +1 -1
  89. wagtail/admin/static/wagtailadmin/js/task-chooser.js +1 -1
  90. wagtail/admin/static/wagtailadmin/js/telepath/blocks.js +1 -1
  91. wagtail/admin/static/wagtailadmin/js/telepath/widgets.js +1 -1
  92. wagtail/admin/static/wagtailadmin/js/userbar.js +2 -1
  93. wagtail/admin/static/wagtailadmin/js/userbar.js.LICENSE.txt +11 -0
  94. wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
  95. wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt +0 -12
  96. wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
  97. wagtail/admin/static/wagtailadmin/js/workflow-action.js +1 -1
  98. wagtail/admin/templates/wagtailadmin/collection_privacy/ancestor_privacy.html +2 -6
  99. wagtail/admin/templates/wagtailadmin/generic/index_results.html +1 -17
  100. wagtail/admin/templates/wagtailadmin/generic/listing_results.html +20 -1
  101. wagtail/admin/templates/wagtailadmin/home/workflow_objects_to_moderate.html +2 -11
  102. wagtail/admin/templates/wagtailadmin/page_privacy/ancestor_privacy.html +2 -6
  103. wagtail/admin/templates/wagtailadmin/page_privacy/no_privacy.html +2 -0
  104. wagtail/admin/templates/wagtailadmin/pages/_editor_js.html +0 -1
  105. wagtail/admin/templates/wagtailadmin/pages/action_menu/menu.html +1 -1
  106. wagtail/admin/templates/wagtailadmin/reports/aging_pages_results.html +54 -0
  107. wagtail/admin/templates/wagtailadmin/reports/base_page_report.html +1 -17
  108. wagtail/admin/templates/wagtailadmin/reports/base_page_report_results.html +10 -0
  109. wagtail/admin/templates/wagtailadmin/reports/base_report.html +1 -40
  110. wagtail/admin/templates/wagtailadmin/reports/base_report_results.html +1 -0
  111. wagtail/admin/templates/wagtailadmin/reports/listing/_list_page_report.html +21 -27
  112. wagtail/admin/templates/wagtailadmin/reports/listing/_list_page_types_usage.html +48 -54
  113. wagtail/admin/templates/wagtailadmin/reports/{locked_pages.html → locked_pages_results.html} +3 -3
  114. wagtail/admin/templates/wagtailadmin/reports/page_types_usage_results.html +10 -0
  115. wagtail/admin/templates/wagtailadmin/reports/site_history_results.html +53 -0
  116. wagtail/admin/templates/wagtailadmin/reports/workflow_results.html +74 -0
  117. wagtail/admin/templates/wagtailadmin/reports/workflow_tasks_results.html +56 -0
  118. wagtail/admin/templates/wagtailadmin/shared/_workflow_init.html +8 -44
  119. wagtail/admin/templates/wagtailadmin/shared/avatar.html +11 -1
  120. wagtail/admin/templates/wagtailadmin/shared/dialog/dialog.html +5 -4
  121. wagtail/admin/templates/wagtailadmin/shared/dropdown/dropdown_button.html +2 -1
  122. wagtail/admin/templates/wagtailadmin/shared/editing_sessions/list.html +132 -0
  123. wagtail/admin/templates/wagtailadmin/shared/editing_sessions/module.html +44 -0
  124. wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html +7 -1
  125. wagtail/admin/templates/wagtailadmin/shared/page_status_tag_new.html +1 -1
  126. wagtail/admin/templates/wagtailadmin/shared/side_panels/checks.html +32 -16
  127. wagtail/admin/templates/wagtailadmin/skeleton.html +1 -1
  128. wagtail/admin/templates/wagtailadmin/userbar/item_accessibility.html +9 -11
  129. wagtail/admin/templatetags/wagtailadmin_tags.py +13 -2
  130. wagtail/admin/tests/formats/en/__init__.py +0 -0
  131. wagtail/admin/tests/formats/en/formats.py +1 -0
  132. wagtail/admin/tests/pages/test_create_page.py +47 -0
  133. wagtail/admin/tests/pages/test_edit_page.py +10 -8
  134. wagtail/admin/tests/pages/test_parent_page_chooser_view.py +45 -1
  135. wagtail/admin/tests/test_checks.py +53 -3
  136. wagtail/admin/tests/test_collections_views.py +62 -1
  137. wagtail/admin/tests/test_edit_handlers.py +37 -0
  138. wagtail/admin/tests/test_editing_sessions.py +1336 -0
  139. wagtail/admin/tests/test_icon_sprite.py +12 -21
  140. wagtail/admin/tests/test_page_chooser.py +309 -7
  141. wagtail/admin/tests/test_privacy.py +82 -0
  142. wagtail/admin/tests/test_reports_views.py +464 -70
  143. wagtail/admin/tests/test_userbar.py +93 -6
  144. wagtail/admin/tests/test_workflows.py +223 -33
  145. wagtail/admin/tests/viewsets/test_model_viewset.py +151 -2
  146. wagtail/admin/ui/editing_sessions.py +57 -0
  147. wagtail/admin/urls/__init__.py +9 -15
  148. wagtail/admin/urls/editing_sessions.py +17 -0
  149. wagtail/admin/urls/reports.py +33 -1
  150. wagtail/admin/userbar.py +77 -20
  151. wagtail/admin/views/chooser.py +49 -22
  152. wagtail/admin/views/collections.py +0 -11
  153. wagtail/admin/views/editing_sessions.py +193 -0
  154. wagtail/admin/views/generic/__init__.py +1 -0
  155. wagtail/admin/views/generic/base.py +3 -2
  156. wagtail/admin/views/generic/history.py +9 -3
  157. wagtail/admin/views/generic/mixins.py +44 -3
  158. wagtail/admin/views/generic/models.py +46 -72
  159. wagtail/admin/views/generic/permissions.py +20 -10
  160. wagtail/admin/views/home.py +2 -31
  161. wagtail/admin/views/page_privacy.py +20 -5
  162. wagtail/admin/views/pages/choose_parent.py +62 -0
  163. wagtail/admin/views/pages/edit.py +28 -0
  164. wagtail/admin/views/reports/aging_pages.py +6 -10
  165. wagtail/admin/views/reports/audit_logging.py +13 -42
  166. wagtail/admin/views/reports/base.py +31 -4
  167. wagtail/admin/views/reports/locked_pages.py +5 -8
  168. wagtail/admin/views/reports/page_types_usage.py +6 -10
  169. wagtail/admin/views/reports/workflows.py +36 -12
  170. wagtail/admin/viewsets/base.py +8 -3
  171. wagtail/admin/viewsets/chooser.py +1 -1
  172. wagtail/admin/viewsets/model.py +26 -1
  173. wagtail/admin/wagtail_hooks.py +2 -1
  174. wagtail/api/v2/filters.py +6 -0
  175. wagtail/api/v2/tests/test_documents.py +1 -1
  176. wagtail/api/v2/tests/test_images.py +1 -1
  177. wagtail/api/v2/tests/test_pages.py +11 -1
  178. wagtail/api/v2/utils.py +2 -2
  179. wagtail/blocks/base.py +35 -12
  180. wagtail/blocks/definition_lookup.py +85 -0
  181. wagtail/blocks/list_block.py +12 -0
  182. wagtail/blocks/migrations/migrate_operation.py +2 -0
  183. wagtail/blocks/stream_block.py +19 -0
  184. wagtail/blocks/struct_block.py +19 -0
  185. wagtail/contrib/forms/locale/be/LC_MESSAGES/django.po +3 -3
  186. wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +1 -1
  187. wagtail/contrib/forms/locale/hr_HR/LC_MESSAGES/django.po +2 -2
  188. wagtail/contrib/forms/locale/pl/LC_MESSAGES/django.po +3 -3
  189. wagtail/contrib/forms/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
  190. wagtail/contrib/forms/locale/pt_BR/LC_MESSAGES/django.po +2 -2
  191. wagtail/contrib/forms/locale/ru/LC_MESSAGES/django.po +3 -3
  192. wagtail/contrib/forms/locale/sl/LC_MESSAGES/django.po +2 -2
  193. wagtail/contrib/frontend_cache/backends/__init__.py +5 -0
  194. wagtail/contrib/frontend_cache/backends/azure.py +179 -0
  195. wagtail/contrib/frontend_cache/backends/base.py +28 -0
  196. wagtail/contrib/frontend_cache/backends/cloudflare.py +114 -0
  197. wagtail/contrib/frontend_cache/backends/cloudfront.py +99 -0
  198. wagtail/contrib/frontend_cache/backends/http.py +64 -0
  199. wagtail/contrib/frontend_cache/tests.py +59 -17
  200. wagtail/contrib/frontend_cache/utils.py +26 -8
  201. wagtail/contrib/redirects/filters.py +15 -1
  202. wagtail/contrib/redirects/locale/ar/LC_MESSAGES/django.po +4 -4
  203. wagtail/contrib/redirects/locale/be/LC_MESSAGES/django.po +3 -3
  204. wagtail/contrib/redirects/locale/bg/LC_MESSAGES/django.po +4 -4
  205. wagtail/contrib/redirects/locale/ca/LC_MESSAGES/django.po +4 -4
  206. wagtail/contrib/redirects/locale/cs/LC_MESSAGES/django.po +4 -4
  207. wagtail/contrib/redirects/locale/cy/LC_MESSAGES/django.po +6 -6
  208. wagtail/contrib/redirects/locale/de/LC_MESSAGES/django.po +5 -4
  209. wagtail/contrib/redirects/locale/el/LC_MESSAGES/django.po +7 -7
  210. wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +37 -72
  211. wagtail/contrib/redirects/locale/es/LC_MESSAGES/django.po +6 -6
  212. wagtail/contrib/redirects/locale/et/LC_MESSAGES/django.po +4 -4
  213. wagtail/contrib/redirects/locale/fa/LC_MESSAGES/django.mo +0 -0
  214. wagtail/contrib/redirects/locale/fa/LC_MESSAGES/django.po +18 -5
  215. wagtail/contrib/redirects/locale/fi/LC_MESSAGES/django.po +6 -6
  216. wagtail/contrib/redirects/locale/fr/LC_MESSAGES/django.po +4 -4
  217. wagtail/contrib/redirects/locale/gl/LC_MESSAGES/django.po +4 -4
  218. wagtail/contrib/redirects/locale/hr_HR/LC_MESSAGES/django.po +8 -8
  219. wagtail/contrib/redirects/locale/hu/LC_MESSAGES/django.po +6 -6
  220. wagtail/contrib/redirects/locale/id_ID/LC_MESSAGES/django.po +4 -4
  221. wagtail/contrib/redirects/locale/is_IS/LC_MESSAGES/django.po +6 -6
  222. wagtail/contrib/redirects/locale/it/LC_MESSAGES/django.po +4 -4
  223. wagtail/contrib/redirects/locale/ja/LC_MESSAGES/django.po +2 -2
  224. wagtail/contrib/redirects/locale/ko/LC_MESSAGES/django.po +4 -4
  225. wagtail/contrib/redirects/locale/lt/LC_MESSAGES/django.po +4 -4
  226. wagtail/contrib/redirects/locale/mn/LC_MESSAGES/django.po +4 -4
  227. wagtail/contrib/redirects/locale/nb/LC_MESSAGES/django.po +4 -4
  228. wagtail/contrib/redirects/locale/nl/LC_MESSAGES/django.po +4 -4
  229. wagtail/contrib/redirects/locale/pl/LC_MESSAGES/django.po +9 -9
  230. wagtail/contrib/redirects/locale/pt_BR/LC_MESSAGES/django.po +5 -5
  231. wagtail/contrib/redirects/locale/pt_PT/LC_MESSAGES/django.po +4 -4
  232. wagtail/contrib/redirects/locale/ro/LC_MESSAGES/django.po +4 -4
  233. wagtail/contrib/redirects/locale/ru/LC_MESSAGES/django.po +7 -7
  234. wagtail/contrib/redirects/locale/sk_SK/LC_MESSAGES/django.po +4 -4
  235. wagtail/contrib/redirects/locale/sl/LC_MESSAGES/django.po +6 -6
  236. wagtail/contrib/redirects/locale/sr/LC_MESSAGES/django.po +2 -2
  237. wagtail/contrib/redirects/locale/sv/LC_MESSAGES/django.po +4 -4
  238. wagtail/contrib/redirects/locale/tet/LC_MESSAGES/django.po +4 -4
  239. wagtail/contrib/redirects/locale/th/LC_MESSAGES/django.po +4 -4
  240. wagtail/contrib/redirects/locale/tr/LC_MESSAGES/django.po +4 -4
  241. wagtail/contrib/redirects/locale/tr_TR/LC_MESSAGES/django.po +4 -4
  242. wagtail/contrib/redirects/locale/uk/LC_MESSAGES/django.po +4 -4
  243. wagtail/contrib/redirects/locale/zh/LC_MESSAGES/django.po +4 -4
  244. wagtail/contrib/redirects/locale/zh_Hans/LC_MESSAGES/django.po +4 -4
  245. wagtail/contrib/redirects/locale/zh_Hant/LC_MESSAGES/django.po +4 -4
  246. wagtail/contrib/redirects/models.py +6 -5
  247. wagtail/contrib/redirects/templates/wagtailredirects/edit.html +1 -38
  248. wagtail/contrib/redirects/tests/test_redirects.py +141 -1
  249. wagtail/contrib/redirects/urls.py +1 -2
  250. wagtail/contrib/redirects/views.py +39 -80
  251. wagtail/contrib/routable_page/models.py +6 -4
  252. wagtail/contrib/routable_page/tests.py +11 -0
  253. wagtail/contrib/search_promotions/locale/ar/LC_MESSAGES/django.po +4 -4
  254. wagtail/contrib/search_promotions/locale/be/LC_MESSAGES/django.po +7 -7
  255. wagtail/contrib/search_promotions/locale/ca/LC_MESSAGES/django.po +8 -8
  256. wagtail/contrib/search_promotions/locale/cs/LC_MESSAGES/django.po +2 -2
  257. wagtail/contrib/search_promotions/locale/cy/LC_MESSAGES/django.po +4 -4
  258. wagtail/contrib/search_promotions/locale/de/LC_MESSAGES/django.po +6 -6
  259. wagtail/contrib/search_promotions/locale/el/LC_MESSAGES/django.po +4 -4
  260. wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +1 -1
  261. wagtail/contrib/search_promotions/locale/es/LC_MESSAGES/django.po +6 -6
  262. wagtail/contrib/search_promotions/locale/et/LC_MESSAGES/django.po +4 -4
  263. wagtail/contrib/search_promotions/locale/fa/LC_MESSAGES/django.po +4 -4
  264. wagtail/contrib/search_promotions/locale/fi/LC_MESSAGES/django.po +6 -6
  265. wagtail/contrib/search_promotions/locale/fr/LC_MESSAGES/django.mo +0 -0
  266. wagtail/contrib/search_promotions/locale/fr/LC_MESSAGES/django.po +9 -6
  267. wagtail/contrib/search_promotions/locale/gl/LC_MESSAGES/django.po +6 -6
  268. wagtail/contrib/search_promotions/locale/hr_HR/LC_MESSAGES/django.po +8 -8
  269. wagtail/contrib/search_promotions/locale/hu/LC_MESSAGES/django.po +4 -4
  270. wagtail/contrib/search_promotions/locale/id_ID/LC_MESSAGES/django.po +4 -4
  271. wagtail/contrib/search_promotions/locale/is_IS/LC_MESSAGES/django.po +8 -8
  272. wagtail/contrib/search_promotions/locale/it/LC_MESSAGES/django.po +6 -6
  273. wagtail/contrib/search_promotions/locale/ja/LC_MESSAGES/django.po +4 -4
  274. wagtail/contrib/search_promotions/locale/ko/LC_MESSAGES/django.po +4 -4
  275. wagtail/contrib/search_promotions/locale/lt/LC_MESSAGES/django.po +6 -6
  276. wagtail/contrib/search_promotions/locale/nb/LC_MESSAGES/django.po +4 -4
  277. wagtail/contrib/search_promotions/locale/nl/LC_MESSAGES/django.po +6 -6
  278. wagtail/contrib/search_promotions/locale/pl/LC_MESSAGES/django.po +9 -9
  279. wagtail/contrib/search_promotions/locale/pt_BR/LC_MESSAGES/django.po +4 -4
  280. wagtail/contrib/search_promotions/locale/pt_PT/LC_MESSAGES/django.po +4 -4
  281. wagtail/contrib/search_promotions/locale/ro/LC_MESSAGES/django.po +4 -4
  282. wagtail/contrib/search_promotions/locale/ru/LC_MESSAGES/django.po +9 -9
  283. wagtail/contrib/search_promotions/locale/sk_SK/LC_MESSAGES/django.po +4 -4
  284. wagtail/contrib/search_promotions/locale/sl/LC_MESSAGES/django.mo +0 -0
  285. wagtail/contrib/search_promotions/locale/sl/LC_MESSAGES/django.po +62 -8
  286. wagtail/contrib/search_promotions/locale/sr/LC_MESSAGES/django.po +2 -2
  287. wagtail/contrib/search_promotions/locale/sv/LC_MESSAGES/django.mo +0 -0
  288. wagtail/contrib/search_promotions/locale/sv/LC_MESSAGES/django.po +9 -6
  289. wagtail/contrib/search_promotions/locale/th/LC_MESSAGES/django.po +4 -4
  290. wagtail/contrib/search_promotions/locale/tr/LC_MESSAGES/django.po +4 -4
  291. wagtail/contrib/search_promotions/locale/tr_TR/LC_MESSAGES/django.po +4 -4
  292. wagtail/contrib/search_promotions/locale/uk/LC_MESSAGES/django.po +4 -4
  293. wagtail/contrib/search_promotions/locale/zh_Hans/LC_MESSAGES/django.po +2 -2
  294. wagtail/contrib/search_promotions/locale/zh_Hant/LC_MESSAGES/django.po +2 -2
  295. wagtail/contrib/settings/locale/be/LC_MESSAGES/django.po +3 -3
  296. wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +4 -4
  297. wagtail/contrib/settings/locale/hr_HR/LC_MESSAGES/django.po +2 -2
  298. wagtail/contrib/settings/locale/pl/LC_MESSAGES/django.po +3 -3
  299. wagtail/contrib/settings/locale/pt_BR/LC_MESSAGES/django.po +1 -1
  300. wagtail/contrib/settings/locale/ru/LC_MESSAGES/django.po +3 -3
  301. wagtail/contrib/settings/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
  302. wagtail/contrib/settings/locale/sk_SK/LC_MESSAGES/django.po +10 -1
  303. wagtail/contrib/settings/locale/sl/LC_MESSAGES/django.po +2 -2
  304. wagtail/contrib/settings/locale/sr/LC_MESSAGES/django.po +2 -2
  305. wagtail/contrib/simple_translation/locale/be/LC_MESSAGES/django.po +3 -3
  306. wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +5 -1
  307. wagtail/contrib/simple_translation/locale/hr_HR/LC_MESSAGES/django.po +2 -2
  308. wagtail/contrib/simple_translation/locale/pl/LC_MESSAGES/django.po +3 -3
  309. wagtail/contrib/simple_translation/locale/pt_BR/LC_MESSAGES/django.po +1 -1
  310. wagtail/contrib/simple_translation/locale/ru/LC_MESSAGES/django.po +3 -3
  311. wagtail/contrib/simple_translation/locale/sl/LC_MESSAGES/django.po +2 -2
  312. wagtail/contrib/simple_translation/models.py +2 -1
  313. wagtail/contrib/styleguide/locale/be/LC_MESSAGES/django.po +3 -3
  314. wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +7 -7
  315. wagtail/contrib/styleguide/locale/hr_HR/LC_MESSAGES/django.po +2 -2
  316. wagtail/contrib/styleguide/locale/pl/LC_MESSAGES/django.po +3 -3
  317. wagtail/contrib/styleguide/locale/ru/LC_MESSAGES/django.po +3 -3
  318. wagtail/contrib/styleguide/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
  319. wagtail/contrib/styleguide/locale/sk_SK/LC_MESSAGES/django.po +5 -1
  320. wagtail/contrib/styleguide/locale/sl/LC_MESSAGES/django.po +2 -2
  321. wagtail/contrib/styleguide/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  322. wagtail/contrib/styleguide/locale/zh_Hans/LC_MESSAGES/django.po +3 -0
  323. wagtail/contrib/table_block/locale/be/LC_MESSAGES/django.po +3 -3
  324. wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +1 -1
  325. wagtail/contrib/table_block/locale/fr/LC_MESSAGES/django.mo +0 -0
  326. wagtail/contrib/table_block/locale/fr/LC_MESSAGES/django.po +27 -1
  327. wagtail/contrib/table_block/locale/hr_HR/LC_MESSAGES/django.po +2 -2
  328. wagtail/contrib/table_block/locale/pl/LC_MESSAGES/django.po +3 -3
  329. wagtail/contrib/table_block/locale/ru/LC_MESSAGES/django.po +3 -3
  330. wagtail/contrib/table_block/locale/sl/LC_MESSAGES/django.mo +0 -0
  331. wagtail/contrib/table_block/locale/sl/LC_MESSAGES/django.po +29 -3
  332. wagtail/contrib/table_block/static/table_block/js/table.js +1 -1
  333. wagtail/contrib/typed_table_block/blocks.py +19 -0
  334. wagtail/contrib/typed_table_block/locale/be/LC_MESSAGES/django.po +3 -3
  335. wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +10 -10
  336. wagtail/contrib/typed_table_block/locale/fr/LC_MESSAGES/django.mo +0 -0
  337. wagtail/contrib/typed_table_block/locale/fr/LC_MESSAGES/django.po +12 -1
  338. wagtail/contrib/typed_table_block/locale/pl/LC_MESSAGES/django.po +3 -3
  339. wagtail/contrib/typed_table_block/locale/pt_BR/LC_MESSAGES/django.po +1 -1
  340. wagtail/contrib/typed_table_block/locale/ru/LC_MESSAGES/django.po +3 -3
  341. wagtail/contrib/typed_table_block/locale/sl/LC_MESSAGES/django.mo +0 -0
  342. wagtail/contrib/typed_table_block/locale/sl/LC_MESSAGES/django.po +14 -4
  343. wagtail/contrib/typed_table_block/static/typed_table_block/js/typed_table_block.js +1 -1
  344. wagtail/contrib/typed_table_block/tests.py +38 -0
  345. wagtail/coreutils.py +1 -1
  346. wagtail/documents/__init__.py +1 -1
  347. wagtail/documents/locale/ar/LC_MESSAGES/django.po +8 -8
  348. wagtail/documents/locale/be/LC_MESSAGES/django.po +11 -11
  349. wagtail/documents/locale/bg/LC_MESSAGES/django.po +4 -4
  350. wagtail/documents/locale/ca/LC_MESSAGES/django.mo +0 -0
  351. wagtail/documents/locale/ca/LC_MESSAGES/django.po +12 -11
  352. wagtail/documents/locale/cs/LC_MESSAGES/django.po +6 -6
  353. wagtail/documents/locale/de/LC_MESSAGES/django.po +10 -8
  354. wagtail/documents/locale/el/LC_MESSAGES/django.po +8 -8
  355. wagtail/documents/locale/en/LC_MESSAGES/django.po +8 -8
  356. wagtail/documents/locale/es/LC_MESSAGES/django.po +8 -8
  357. wagtail/documents/locale/et/LC_MESSAGES/django.po +6 -6
  358. wagtail/documents/locale/fa/LC_MESSAGES/django.mo +0 -0
  359. wagtail/documents/locale/fa/LC_MESSAGES/django.po +17 -8
  360. wagtail/documents/locale/fi/LC_MESSAGES/django.po +10 -10
  361. wagtail/documents/locale/fr/LC_MESSAGES/django.po +6 -6
  362. wagtail/documents/locale/gl/LC_MESSAGES/django.po +8 -8
  363. wagtail/documents/locale/hr_HR/LC_MESSAGES/django.po +14 -14
  364. wagtail/documents/locale/hu/LC_MESSAGES/django.po +12 -12
  365. wagtail/documents/locale/id_ID/LC_MESSAGES/django.po +6 -6
  366. wagtail/documents/locale/is_IS/LC_MESSAGES/django.po +8 -8
  367. wagtail/documents/locale/it/LC_MESSAGES/django.po +8 -8
  368. wagtail/documents/locale/ja/LC_MESSAGES/django.po +8 -8
  369. wagtail/documents/locale/ko/LC_MESSAGES/django.po +8 -8
  370. wagtail/documents/locale/lt/LC_MESSAGES/django.po +8 -8
  371. wagtail/documents/locale/mi/LC_MESSAGES/django.po +10 -10
  372. wagtail/documents/locale/mn/LC_MESSAGES/django.po +5 -4
  373. wagtail/documents/locale/nb/LC_MESSAGES/django.po +6 -6
  374. wagtail/documents/locale/nl/LC_MESSAGES/django.po +8 -8
  375. wagtail/documents/locale/pl/LC_MESSAGES/django.po +11 -11
  376. wagtail/documents/locale/pt_BR/LC_MESSAGES/django.po +8 -8
  377. wagtail/documents/locale/pt_PT/LC_MESSAGES/django.po +8 -8
  378. wagtail/documents/locale/ro/LC_MESSAGES/django.po +8 -8
  379. wagtail/documents/locale/ru/LC_MESSAGES/django.po +9 -9
  380. wagtail/documents/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
  381. wagtail/documents/locale/sk_SK/LC_MESSAGES/django.po +55 -12
  382. wagtail/documents/locale/sl/LC_MESSAGES/django.mo +0 -0
  383. wagtail/documents/locale/sl/LC_MESSAGES/django.po +30 -10
  384. wagtail/documents/locale/sr/LC_MESSAGES/django.po +2 -2
  385. wagtail/documents/locale/sv/LC_MESSAGES/django.po +6 -6
  386. wagtail/documents/locale/th/LC_MESSAGES/django.po +8 -8
  387. wagtail/documents/locale/tr/LC_MESSAGES/django.po +8 -8
  388. wagtail/documents/locale/tr_TR/LC_MESSAGES/django.po +8 -8
  389. wagtail/documents/locale/uk/LC_MESSAGES/django.po +8 -8
  390. wagtail/documents/locale/zh/LC_MESSAGES/django.po +2 -2
  391. wagtail/documents/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  392. wagtail/documents/locale/zh_Hans/LC_MESSAGES/django.po +11 -5
  393. wagtail/documents/locale/zh_Hant/LC_MESSAGES/django.po +4 -4
  394. wagtail/documents/models.py +5 -1
  395. wagtail/documents/static/wagtaildocs/js/document-chooser-modal.js +1 -1
  396. wagtail/documents/static/wagtaildocs/js/document-chooser-telepath.js +1 -1
  397. wagtail/documents/static/wagtaildocs/js/document-chooser.js +1 -1
  398. wagtail/documents/tests/test_models.py +5 -1
  399. wagtail/embeds/apps.py +2 -0
  400. wagtail/embeds/embeds.py +12 -14
  401. wagtail/embeds/finders/__init__.py +2 -0
  402. wagtail/embeds/finders/facebook.py +17 -33
  403. wagtail/embeds/finders/instagram.py +19 -16
  404. wagtail/embeds/locale/be/LC_MESSAGES/django.po +3 -3
  405. wagtail/embeds/locale/en/LC_MESSAGES/django.po +1 -1
  406. wagtail/embeds/locale/hr_HR/LC_MESSAGES/django.po +2 -2
  407. wagtail/embeds/locale/pl/LC_MESSAGES/django.po +3 -3
  408. wagtail/embeds/locale/ru/LC_MESSAGES/django.po +3 -3
  409. wagtail/embeds/locale/sl/LC_MESSAGES/django.po +2 -2
  410. wagtail/embeds/signal_handlers.py +13 -0
  411. wagtail/embeds/tests/test_embeds.py +7 -7
  412. wagtail/fields.py +58 -14
  413. wagtail/images/__init__.py +1 -1
  414. wagtail/images/locale/ar/LC_MESSAGES/django.po +6 -6
  415. wagtail/images/locale/be/LC_MESSAGES/django.po +3 -3
  416. wagtail/images/locale/ca/LC_MESSAGES/django.po +8 -8
  417. wagtail/images/locale/cs/LC_MESSAGES/django.po +8 -8
  418. wagtail/images/locale/cy/LC_MESSAGES/django.po +8 -8
  419. wagtail/images/locale/de/LC_MESSAGES/django.po +6 -6
  420. wagtail/images/locale/el/LC_MESSAGES/django.po +8 -8
  421. wagtail/images/locale/en/LC_MESSAGES/django.po +34 -34
  422. wagtail/images/locale/es/LC_MESSAGES/django.po +10 -10
  423. wagtail/images/locale/et/LC_MESSAGES/django.po +8 -8
  424. wagtail/images/locale/fa/LC_MESSAGES/django.mo +0 -0
  425. wagtail/images/locale/fa/LC_MESSAGES/django.po +28 -9
  426. wagtail/images/locale/fi/LC_MESSAGES/django.po +8 -8
  427. wagtail/images/locale/fr/LC_MESSAGES/django.po +6 -6
  428. wagtail/images/locale/gl/LC_MESSAGES/django.po +8 -8
  429. wagtail/images/locale/hr_HR/LC_MESSAGES/django.po +8 -8
  430. wagtail/images/locale/hu/LC_MESSAGES/django.po +8 -8
  431. wagtail/images/locale/id_ID/LC_MESSAGES/django.po +6 -6
  432. wagtail/images/locale/is_IS/LC_MESSAGES/django.po +8 -8
  433. wagtail/images/locale/it/LC_MESSAGES/django.po +8 -8
  434. wagtail/images/locale/ja/LC_MESSAGES/django.po +8 -8
  435. wagtail/images/locale/ko/LC_MESSAGES/django.po +6 -6
  436. wagtail/images/locale/lt/LC_MESSAGES/django.po +8 -8
  437. wagtail/images/locale/nb/LC_MESSAGES/django.po +8 -8
  438. wagtail/images/locale/nl/LC_MESSAGES/django.po +8 -8
  439. wagtail/images/locale/pl/LC_MESSAGES/django.po +11 -11
  440. wagtail/images/locale/pt_BR/LC_MESSAGES/django.po +8 -8
  441. wagtail/images/locale/pt_PT/LC_MESSAGES/django.po +8 -8
  442. wagtail/images/locale/ro/LC_MESSAGES/django.po +8 -8
  443. wagtail/images/locale/ru/LC_MESSAGES/django.po +11 -11
  444. wagtail/images/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
  445. wagtail/images/locale/sk_SK/LC_MESSAGES/django.po +23 -8
  446. wagtail/images/locale/sl/LC_MESSAGES/django.mo +0 -0
  447. wagtail/images/locale/sl/LC_MESSAGES/django.po +44 -12
  448. wagtail/images/locale/sv/LC_MESSAGES/django.mo +0 -0
  449. wagtail/images/locale/sv/LC_MESSAGES/django.po +20 -8
  450. wagtail/images/locale/tet/LC_MESSAGES/django.po +4 -4
  451. wagtail/images/locale/th/LC_MESSAGES/django.po +8 -8
  452. wagtail/images/locale/tr/LC_MESSAGES/django.po +6 -6
  453. wagtail/images/locale/tr_TR/LC_MESSAGES/django.po +6 -6
  454. wagtail/images/locale/uk/LC_MESSAGES/django.po +8 -8
  455. wagtail/images/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  456. wagtail/images/locale/zh_Hans/LC_MESSAGES/django.po +49 -5
  457. wagtail/images/locale/zh_Hant/LC_MESSAGES/django.po +4 -4
  458. wagtail/images/models.py +3 -0
  459. wagtail/images/static/wagtailimages/js/image-chooser-modal.js +1 -1
  460. wagtail/images/static/wagtailimages/js/image-chooser-telepath.js +1 -1
  461. wagtail/images/static/wagtailimages/js/image-chooser.js +1 -1
  462. wagtail/images/templates/wagtailimages/images/edit.html +4 -4
  463. wagtail/images/tests/test_admin_views.py +58 -2
  464. wagtail/images/tests/test_image_operations.py +12 -0
  465. wagtail/images/tests/tests.py +27 -2
  466. wagtail/images/views/chooser.py +6 -1
  467. wagtail/images/views/images.py +7 -3
  468. wagtail/images/views/serve.py +1 -0
  469. wagtail/locale/be/LC_MESSAGES/django.po +3 -3
  470. wagtail/locale/en/LC_MESSAGES/django.po +84 -80
  471. wagtail/locale/fa/LC_MESSAGES/django.mo +0 -0
  472. wagtail/locale/fa/LC_MESSAGES/django.po +3 -0
  473. wagtail/locale/fr/LC_MESSAGES/django.mo +0 -0
  474. wagtail/locale/fr/LC_MESSAGES/django.po +23 -4
  475. wagtail/locale/hr_HR/LC_MESSAGES/django.po +2 -2
  476. wagtail/locale/pl/LC_MESSAGES/django.po +3 -3
  477. wagtail/locale/pt_BR/LC_MESSAGES/django.po +1 -1
  478. wagtail/locale/ru/LC_MESSAGES/django.po +3 -3
  479. wagtail/locale/sl/LC_MESSAGES/django.po +2 -2
  480. wagtail/locale/sv/LC_MESSAGES/django.mo +0 -0
  481. wagtail/locale/sv/LC_MESSAGES/django.po +11 -2
  482. wagtail/locales/locale/be/LC_MESSAGES/django.po +3 -3
  483. wagtail/locales/locale/en/LC_MESSAGES/django.po +2 -2
  484. wagtail/locales/locale/hr_HR/LC_MESSAGES/django.po +2 -2
  485. wagtail/locales/locale/pl/LC_MESSAGES/django.po +3 -3
  486. wagtail/locales/locale/ru/LC_MESSAGES/django.po +3 -3
  487. wagtail/locales/locale/sl/LC_MESSAGES/django.po +2 -2
  488. wagtail/locales/tests.py +16 -0
  489. wagtail/locales/wagtail_hooks.py +0 -9
  490. wagtail/migrations/0094_alter_page_locale.py +19 -0
  491. wagtail/models/__init__.py +11 -5
  492. wagtail/models/i18n.py +6 -1
  493. wagtail/project_template/requirements.txt +1 -1
  494. wagtail/search/locale/be/LC_MESSAGES/django.po +3 -3
  495. wagtail/search/locale/en/LC_MESSAGES/django.po +1 -1
  496. wagtail/search/locale/fa/LC_MESSAGES/django.mo +0 -0
  497. wagtail/search/locale/fa/LC_MESSAGES/django.po +24 -0
  498. wagtail/search/locale/hr_HR/LC_MESSAGES/django.po +2 -2
  499. wagtail/search/locale/pl/LC_MESSAGES/django.po +3 -3
  500. wagtail/search/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
  501. wagtail/search/locale/pt_BR/LC_MESSAGES/django.po +2 -2
  502. wagtail/search/locale/ru/LC_MESSAGES/django.po +3 -3
  503. wagtail/search/locale/sl/LC_MESSAGES/django.po +2 -2
  504. wagtail/search/tests/test_queries.py +24 -0
  505. wagtail/search/utils.py +6 -12
  506. wagtail/signals.py +4 -0
  507. wagtail/sites/locale/be/LC_MESSAGES/django.po +3 -3
  508. wagtail/sites/locale/en/LC_MESSAGES/django.po +2 -2
  509. wagtail/sites/locale/hr_HR/LC_MESSAGES/django.po +2 -2
  510. wagtail/sites/locale/pl/LC_MESSAGES/django.po +3 -3
  511. wagtail/sites/locale/ru/LC_MESSAGES/django.po +3 -3
  512. wagtail/sites/locale/sl/LC_MESSAGES/django.po +2 -2
  513. wagtail/sites/locale/sr/LC_MESSAGES/django.po +2 -2
  514. wagtail/sites/tests.py +15 -0
  515. wagtail/sites/wagtail_hooks.py +0 -9
  516. wagtail/snippets/locale/be/LC_MESSAGES/django.po +3 -3
  517. wagtail/snippets/locale/ca/LC_MESSAGES/django.po +6 -6
  518. wagtail/snippets/locale/de/LC_MESSAGES/django.po +5 -5
  519. wagtail/snippets/locale/en/LC_MESSAGES/django.po +9 -9
  520. wagtail/snippets/locale/es/LC_MESSAGES/django.po +6 -6
  521. wagtail/snippets/locale/fa/LC_MESSAGES/django.mo +0 -0
  522. wagtail/snippets/locale/fa/LC_MESSAGES/django.po +17 -1
  523. wagtail/snippets/locale/fr/LC_MESSAGES/django.po +5 -5
  524. wagtail/snippets/locale/gl/LC_MESSAGES/django.po +6 -6
  525. wagtail/snippets/locale/hr_HR/LC_MESSAGES/django.po +8 -8
  526. wagtail/snippets/locale/hu/LC_MESSAGES/django.po +7 -7
  527. wagtail/snippets/locale/is_IS/LC_MESSAGES/django.po +5 -5
  528. wagtail/snippets/locale/it/LC_MESSAGES/django.po +5 -5
  529. wagtail/snippets/locale/ko/LC_MESSAGES/django.po +6 -6
  530. wagtail/snippets/locale/nb/LC_MESSAGES/django.po +6 -6
  531. wagtail/snippets/locale/nl/LC_MESSAGES/django.po +8 -8
  532. wagtail/snippets/locale/pl/LC_MESSAGES/django.po +9 -9
  533. wagtail/snippets/locale/pt_BR/LC_MESSAGES/django.po +1 -1
  534. wagtail/snippets/locale/ro/LC_MESSAGES/django.po +6 -6
  535. wagtail/snippets/locale/ru/LC_MESSAGES/django.po +8 -8
  536. wagtail/snippets/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
  537. wagtail/snippets/locale/sk_SK/LC_MESSAGES/django.po +3 -0
  538. wagtail/snippets/locale/sl/LC_MESSAGES/django.po +8 -8
  539. wagtail/snippets/locale/sr/LC_MESSAGES/django.po +2 -2
  540. wagtail/snippets/locale/sv/LC_MESSAGES/django.po +6 -6
  541. wagtail/snippets/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  542. wagtail/snippets/locale/zh_Hans/LC_MESSAGES/django.po +40 -1
  543. wagtail/snippets/permissions.py +5 -3
  544. wagtail/snippets/static/wagtailsnippets/js/snippet-chooser-telepath.js +1 -1
  545. wagtail/snippets/static/wagtailsnippets/js/snippet-chooser.js +1 -1
  546. wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/menu.html +1 -1
  547. wagtail/snippets/tests/test_snippets.py +78 -12
  548. wagtail/snippets/tests/test_viewset.py +22 -0
  549. wagtail/snippets/views/snippets.py +19 -14
  550. wagtail/snippets/wagtail_hooks.py +2 -10
  551. wagtail/templatetags/wagtailcore_tags.py +3 -0
  552. wagtail/test/dummy_external_storage.py +1 -1
  553. wagtail/test/i18n/migrations/0003_alter_clusterabletestmodel_locale_and_more.py +40 -0
  554. wagtail/test/routablepage/models.py +4 -0
  555. wagtail/test/snippets/migrations/0012_alter_translatablesnippet_locale.py +20 -0
  556. wagtail/test/testapp/migrations/0038_sociallink.py +52 -0
  557. wagtail/test/testapp/migrations/0039_alter_eventcategory_locale_and_more.py +45 -0
  558. wagtail/test/testapp/models.py +24 -0
  559. wagtail/test/testapp/views.py +1 -0
  560. wagtail/test/testapp/wagtail_hooks.py +9 -0
  561. wagtail/test/urls_multilang.py +6 -1
  562. wagtail/test/urls_multilang_non_root.py +11 -0
  563. wagtail/tests/streamfield_migrations/test_migrations.py +53 -12
  564. wagtail/tests/test_audit_log.py +72 -2
  565. wagtail/tests/test_blocks.py +103 -0
  566. wagtail/tests/test_signals.py +49 -2
  567. wagtail/tests/test_streamfield.py +153 -0
  568. wagtail/tests/test_utils.py +42 -1
  569. wagtail/tests/tests.py +5 -0
  570. wagtail/users/apps.py +1 -0
  571. wagtail/users/forms.py +7 -0
  572. wagtail/users/locale/ar/LC_MESSAGES/django.po +4 -4
  573. wagtail/users/locale/be/LC_MESSAGES/django.po +9 -9
  574. wagtail/users/locale/ca/LC_MESSAGES/django.po +8 -8
  575. wagtail/users/locale/cs/LC_MESSAGES/django.po +6 -6
  576. wagtail/users/locale/cy/LC_MESSAGES/django.po +8 -8
  577. wagtail/users/locale/de/LC_MESSAGES/django.po +8 -8
  578. wagtail/users/locale/el/LC_MESSAGES/django.po +4 -4
  579. wagtail/users/locale/en/LC_MESSAGES/django.po +55 -50
  580. wagtail/users/locale/es/LC_MESSAGES/django.po +8 -8
  581. wagtail/users/locale/et/LC_MESSAGES/django.po +8 -8
  582. wagtail/users/locale/fa/LC_MESSAGES/django.mo +0 -0
  583. wagtail/users/locale/fa/LC_MESSAGES/django.po +69 -7
  584. wagtail/users/locale/fi/LC_MESSAGES/django.po +8 -8
  585. wagtail/users/locale/fr/LC_MESSAGES/django.mo +0 -0
  586. wagtail/users/locale/fr/LC_MESSAGES/django.po +52 -11
  587. wagtail/users/locale/gl/LC_MESSAGES/django.po +8 -8
  588. wagtail/users/locale/hr_HR/LC_MESSAGES/django.po +10 -10
  589. wagtail/users/locale/hu/LC_MESSAGES/django.po +8 -8
  590. wagtail/users/locale/id_ID/LC_MESSAGES/django.po +4 -4
  591. wagtail/users/locale/is_IS/LC_MESSAGES/django.po +8 -8
  592. wagtail/users/locale/it/LC_MESSAGES/django.po +8 -8
  593. wagtail/users/locale/ja/LC_MESSAGES/django.po +4 -4
  594. wagtail/users/locale/ko/LC_MESSAGES/django.po +4 -4
  595. wagtail/users/locale/lt/LC_MESSAGES/django.po +4 -4
  596. wagtail/users/locale/lv/LC_MESSAGES/django.po +4 -4
  597. wagtail/users/locale/mn/LC_MESSAGES/django.po +5 -4
  598. wagtail/users/locale/nb/LC_MESSAGES/django.po +8 -8
  599. wagtail/users/locale/nl/LC_MESSAGES/django.po +6 -6
  600. wagtail/users/locale/pl/LC_MESSAGES/django.po +9 -9
  601. wagtail/users/locale/pt_BR/LC_MESSAGES/django.po +9 -9
  602. wagtail/users/locale/pt_PT/LC_MESSAGES/django.po +8 -8
  603. wagtail/users/locale/ro/LC_MESSAGES/django.po +8 -8
  604. wagtail/users/locale/ru/LC_MESSAGES/django.po +11 -11
  605. wagtail/users/locale/sk_SK/LC_MESSAGES/django.mo +0 -0
  606. wagtail/users/locale/sk_SK/LC_MESSAGES/django.po +12 -5
  607. wagtail/users/locale/sl/LC_MESSAGES/django.mo +0 -0
  608. wagtail/users/locale/sl/LC_MESSAGES/django.po +56 -12
  609. wagtail/users/locale/sv/LC_MESSAGES/django.mo +0 -0
  610. wagtail/users/locale/sv/LC_MESSAGES/django.po +49 -10
  611. wagtail/users/locale/tet/LC_MESSAGES/django.po +4 -4
  612. wagtail/users/locale/th/LC_MESSAGES/django.po +4 -4
  613. wagtail/users/locale/tr/LC_MESSAGES/django.po +4 -4
  614. wagtail/users/locale/tr_TR/LC_MESSAGES/django.po +4 -4
  615. wagtail/users/locale/uk/LC_MESSAGES/django.po +8 -8
  616. wagtail/users/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
  617. wagtail/users/locale/zh_Hans/LC_MESSAGES/django.po +49 -5
  618. wagtail/users/locale/zh_Hant/LC_MESSAGES/django.po +2 -2
  619. wagtail/users/models.py +1 -0
  620. wagtail/users/templates/wagtailusers/groups/includes/formatted_permissions.html +3 -2
  621. wagtail/users/templatetags/wagtailusers_tags.py +9 -0
  622. wagtail/users/tests/__init__.py +7 -1
  623. wagtail/users/tests/test_admin_views.py +117 -32
  624. wagtail/users/views/groups.py +4 -0
  625. wagtail/users/views/users.py +58 -14
  626. wagtail/users/wagtail_hooks.py +7 -123
  627. wagtail/utils/utils.py +27 -0
  628. wagtail/utils/version.py +5 -2
  629. wagtail-6.2rc1.dist-info/METADATA +78 -0
  630. {wagtail-6.1.2.dist-info → wagtail-6.2rc1.dist-info}/RECORD +634 -607
  631. {wagtail-6.1.2.dist-info → wagtail-6.2rc1.dist-info}/WHEEL +1 -1
  632. wagtail/admin/templates/wagtailadmin/reports/aging_pages.html +0 -58
  633. wagtail/admin/templates/wagtailadmin/reports/page_types_usage.html +0 -18
  634. wagtail/admin/templates/wagtailadmin/reports/site_history.html +0 -57
  635. wagtail/admin/templates/wagtailadmin/reports/workflow.html +0 -81
  636. wagtail/admin/templates/wagtailadmin/reports/workflow_tasks.html +0 -63
  637. wagtail/contrib/frontend_cache/backends.py +0 -400
  638. wagtail/contrib/redirects/templates/wagtailredirects/list.html +0 -43
  639. wagtail/contrib/redirects/templates/wagtailredirects/reports/redirects_report.html +0 -14
  640. wagtail/contrib/redirects/tests/test_reports_view.py +0 -82
  641. wagtail-6.1.2.dist-info/METADATA +0 -78
  642. {wagtail-6.1.2.dist-info → wagtail-6.2rc1.dist-info}/LICENSE +0 -0
  643. {wagtail-6.1.2.dist-info → wagtail-6.2rc1.dist-info}/entry_points.txt +0 -0
  644. {wagtail-6.1.2.dist-info → wagtail-6.2rc1.dist-info}/top_level.txt +0 -0
@@ -1,26 +1,17 @@
1
- import re
1
+ from django.test import SimpleTestCase
2
2
 
3
- from django.test import TestCase
4
- from django.urls import reverse
3
+ from wagtail.admin.icons import get_icon_sprite_hash, get_icon_sprite_url
5
4
 
6
- from wagtail.admin.urls import get_sprite_hash, sprite_hash
7
5
 
6
+ class TestIconSpriteView(SimpleTestCase):
7
+ def test_content_type(self):
8
+ response = self.client.get(get_icon_sprite_url())
9
+ self.assertEqual(
10
+ response.headers["Content-Type"], "image/svg+xml; charset=utf-8"
11
+ )
12
+ self.assertEqual(response.wsgi_request.GET["h"], get_icon_sprite_hash())
8
13
 
9
- class TestIconSprite(TestCase):
10
- def test_get_sprite_hash(self):
11
- result = get_sprite_hash()
12
- self.assertTrue(bool(re.match(r"^[a-z0-9]{8}$", result)))
13
-
14
- def test_hash_var(self):
15
- self.assertIsInstance(sprite_hash, str)
16
- self.assertEqual(len(sprite_hash), 8)
17
-
18
- def test_url(self):
19
- url = reverse("wagtailadmin_sprite")
20
- self.assertEqual(url[:14], "/admin/sprite-")
21
14
 
22
- def test_view(self):
23
- response = self.client.get(reverse("wagtailadmin_sprite"))
24
- self.assertIn(
25
- "Content-Type: text/html; charset=utf-8", str(response.serialize_headers())
26
- )
15
+ class TestIconSpriteHash(SimpleTestCase):
16
+ def test_hash(self):
17
+ self.assertEqual(len(get_icon_sprite_hash()), 8)
@@ -1,5 +1,5 @@
1
1
  import json
2
- import urllib.parse as urlparse
2
+ from urllib.parse import parse_qs, urlsplit
3
3
 
4
4
  from django.contrib.auth import get_user_model
5
5
  from django.test import TestCase, TransactionTestCase, override_settings
@@ -724,6 +724,7 @@ class TestChooserExternalLink(WagtailTestUtils, TestCase):
724
724
  self.assertEqual(
725
725
  response_json["external"]["url"], "http://localhost/about?test=1"
726
726
  )
727
+ self.assertEqual(response_json["internal"]["url"], "/about/")
727
728
  self.assertEqual(response_json["internal"]["id"], self.internal_page.pk)
728
729
 
729
730
  def test_convert_relative_external_link_to_internal_link(self):
@@ -752,6 +753,7 @@ class TestChooserExternalLink(WagtailTestUtils, TestCase):
752
753
 
753
754
  self.assertEqual(response_json["result"]["url"], url)
754
755
  self.assertEqual(response_json["result"]["title"], title)
756
+ self.assertNotIn("id", response_json["result"])
755
757
 
756
758
  @override_settings(WAGTAILADMIN_EXTERNAL_LINK_CONVERSION="exact")
757
759
  def test_no_confirm_external_to_internal_link_when_exact(self):
@@ -767,6 +769,7 @@ class TestChooserExternalLink(WagtailTestUtils, TestCase):
767
769
 
768
770
  self.assertEqual(response_json["result"]["url"], url)
769
771
  self.assertEqual(response_json["result"]["title"], title)
772
+ self.assertNotIn("id", response_json["result"])
770
773
 
771
774
  @override_settings(WAGTAILADMIN_EXTERNAL_LINK_CONVERSION="confirm")
772
775
  def test_convert_external_link_to_internal_link_with_confirm_setting(self):
@@ -785,9 +788,308 @@ class TestChooserExternalLink(WagtailTestUtils, TestCase):
785
788
  self.assertEqual(response_json["step"], "confirm_external_to_internal")
786
789
 
787
790
  self.assertEqual(response_json["external"]["url"], url)
791
+ self.assertEqual(response_json["internal"]["url"], "/about/")
788
792
  self.assertEqual(response_json["internal"]["id"], self.internal_page.pk)
789
793
 
790
794
 
795
+ @override_settings(ROOT_URLCONF="wagtail.test.headless_urls")
796
+ class TestChooserExternalLinkWithNoServePath(TestChooserExternalLink):
797
+ def test_convert_external_to_internal_link(self):
798
+ # Normally this should be converted without any confirmation, but since
799
+ # the serve path is not registered, the page route will resolve to None,
800
+ # so the user should be asked to confirm the conversion.
801
+ # As a result, this test is now identical to
802
+ # test_convert_external_link_to_internal_link_with_confirm_setting
803
+ response = self.post(
804
+ {
805
+ "external-link-chooser-url": "http://localhost/about/",
806
+ "external-link-chooser-link_text": "about",
807
+ }
808
+ )
809
+ self.assertEqual(response.status_code, 200)
810
+ response_json = json.loads(response.content.decode())
811
+ self.assertEqual(response_json["step"], "confirm_external_to_internal")
812
+ self.assertEqual(response_json["external"]["url"], "http://localhost/about/")
813
+ self.assertIsNone(response_json["internal"]["url"])
814
+ self.assertEqual(response_json["internal"]["id"], self.internal_page.pk)
815
+
816
+ def test_convert_external_link_with_query_parameters_to_internal_link(self):
817
+ response = self.post(
818
+ {
819
+ "external-link-chooser-url": "http://localhost/about?test=1",
820
+ "external-link-chooser-link_text": "about",
821
+ }
822
+ )
823
+ self.assertEqual(response.status_code, 200)
824
+ response_json = json.loads(response.content.decode())
825
+
826
+ # Query parameters will get stripped, so the user should get asked to confirm the conversion
827
+ self.assertEqual(response_json["step"], "confirm_external_to_internal")
828
+
829
+ self.assertEqual(
830
+ response_json["external"]["url"], "http://localhost/about?test=1"
831
+ )
832
+ # The serve path is not registered, so the page route will resolve to None
833
+ self.assertIsNone(response_json["internal"]["url"])
834
+ self.assertEqual(response_json["internal"]["id"], self.internal_page.pk)
835
+
836
+ def test_convert_relative_external_link_to_internal_link(self):
837
+ response = self.post(
838
+ {
839
+ "external-link-chooser-url": "/about/",
840
+ "external-link-chooser-link_text": "about",
841
+ }
842
+ )
843
+ self.assertEqual(response.status_code, 200)
844
+ response_json = json.loads(response.content.decode())
845
+ # As with test_convert_external_to_internal_link, normally this doesn't
846
+ # require confirmation, but since the serve path is not registered, the
847
+ # full URL of the page is None, thus triggering the confirmation
848
+ self.assertEqual(response_json["step"], "confirm_external_to_internal")
849
+ self.assertEqual(response_json["external"]["url"], "/about/")
850
+ # The serve path is not registered, so the page route will resolve to None
851
+ self.assertIsNone(response_json["internal"]["url"])
852
+ self.assertEqual(response_json["internal"]["id"], self.internal_page.pk)
853
+
854
+ @override_settings(WAGTAILADMIN_EXTERNAL_LINK_CONVERSION="confirm")
855
+ def test_convert_external_link_to_internal_link_with_confirm_setting(self):
856
+ url = "http://localhost/about/"
857
+ response = self.post(
858
+ {
859
+ "external-link-chooser-url": url,
860
+ "external-link-chooser-link_text": "about",
861
+ }
862
+ )
863
+ self.assertEqual(response.status_code, 200)
864
+ response_json = json.loads(response.content.decode())
865
+
866
+ # The serve path is not registered so the URL can never be identical,
867
+ # which means the setting doesn't matter in this case, but we keep the
868
+ # test case anyway to ensure that the confirmation step is triggered
869
+ self.assertEqual(response_json["step"], "confirm_external_to_internal")
870
+
871
+ self.assertEqual(response_json["external"]["url"], url)
872
+ self.assertIsNone(response_json["internal"]["url"])
873
+ self.assertEqual(response_json["internal"]["id"], self.internal_page.pk)
874
+
875
+
876
+ @override_settings(ROOT_URLCONF="wagtail.test.non_root_urls")
877
+ class TestChooserExternalLinkWithNonRootServePath(TestChooserExternalLink):
878
+ prefix = "site/"
879
+
880
+ def test_convert_external_to_internal_link(self):
881
+ # Legacy behaviour: when using a non-root serve path, entering a full
882
+ # URL without the serve path will trigger the conversion.
883
+ # Normally this should be converted without any confirmation, but since
884
+ # the actual URL will include the serve path (thus different from the
885
+ # input URL), the user should be asked to confirm.
886
+ response = self.post(
887
+ {
888
+ "external-link-chooser-url": "http://localhost/about/",
889
+ "external-link-chooser-link_text": "about",
890
+ }
891
+ )
892
+ self.assertEqual(response.status_code, 200)
893
+ response_json = json.loads(response.content.decode())
894
+ self.assertEqual(response_json["step"], "confirm_external_to_internal")
895
+ self.assertEqual(response_json["external"]["url"], "http://localhost/about/")
896
+ self.assertEqual(response_json["internal"]["url"], f"/{self.prefix}about/")
897
+ self.assertEqual(response_json["internal"]["id"], self.internal_page.pk)
898
+
899
+ def test_convert_external_to_internal_link_with_serve_path(self):
900
+ # https://github.com/wagtail/wagtail/issues/11996
901
+ # New behaviour: when using a non-root serve path, entering a full
902
+ # URL with the serve path will trigger the conversion. Previously, this
903
+ # would have been considered an external link since the logic does not
904
+ # take the serve path into account, but now it should be correctly
905
+ # converted to an internal link (without needing confirmation as the
906
+ # input URL will be an exact match to the page's full URL).
907
+
908
+ # Warm up the cache
909
+ response = self.post(
910
+ {
911
+ "external-link-chooser-url": f"http://localhost/{self.prefix}about/",
912
+ "external-link-chooser-link_text": "about",
913
+ }
914
+ )
915
+ with self.assertNumQueries(11):
916
+ response = self.post(
917
+ {
918
+ "external-link-chooser-url": f"http://localhost/{self.prefix}about/",
919
+ "external-link-chooser-link_text": "about",
920
+ }
921
+ )
922
+ self.assertEqual(response.status_code, 200)
923
+ response_json = json.loads(response.content.decode())
924
+ self.assertEqual(response_json["step"], "external_link_chosen")
925
+ self.assertEqual(response_json["result"]["url"], f"/{self.prefix}about/")
926
+ self.assertEqual(response_json["result"]["id"], self.internal_page.pk)
927
+
928
+ def test_convert_external_link_with_query_parameters_to_internal_link(self):
929
+ # Legacy behaviour: when using a non-root serve path, entering a full
930
+ # URL without the serve path will trigger the conversion. The user
931
+ # should be asked to confirm the conversion as the input URL will be
932
+ # different from the page's full URL (as the serve path is added and
933
+ # the query parameters are removed).
934
+ response = self.post(
935
+ {
936
+ "external-link-chooser-url": "http://localhost/about?test=1",
937
+ "external-link-chooser-link_text": "about",
938
+ }
939
+ )
940
+ self.assertEqual(response.status_code, 200)
941
+ response_json = json.loads(response.content.decode())
942
+
943
+ # Query parameters will get stripped, so the user should get asked to confirm the conversion
944
+ self.assertEqual(response_json["step"], "confirm_external_to_internal")
945
+
946
+ self.assertEqual(
947
+ response_json["external"]["url"], "http://localhost/about?test=1"
948
+ )
949
+ self.assertEqual(response_json["internal"]["url"], f"/{self.prefix}about/")
950
+ self.assertEqual(response_json["internal"]["id"], self.internal_page.pk)
951
+
952
+ def test_convert_external_link_with_query_parameters_to_internal_link_with_serve_path(
953
+ self
954
+ ):
955
+ # https://github.com/wagtail/wagtail/issues/11996
956
+ # New behaviour: when using a non-root serve path, entering a full
957
+ # URL with the serve path will trigger the conversion. Previously, this
958
+ # would have been considered an external link since the logic does not
959
+ # take the serve path into account, but now it should be correctly
960
+ # converted to an internal link. It still needs a confirmation as the
961
+ # input URL includes query parameters that will be stripped when matching
962
+ # it with the page's full URL.
963
+ response = self.post(
964
+ {
965
+ "external-link-chooser-url": f"http://localhost/{self.prefix}about?test=1",
966
+ "external-link-chooser-link_text": "about",
967
+ }
968
+ )
969
+ self.assertEqual(response.status_code, 200)
970
+ response_json = json.loads(response.content.decode())
971
+
972
+ # Query parameters will get stripped, so the user should get asked to confirm the conversion
973
+ self.assertEqual(response_json["step"], "confirm_external_to_internal")
974
+
975
+ self.assertEqual(
976
+ response_json["external"]["url"],
977
+ f"http://localhost/{self.prefix}about?test=1",
978
+ )
979
+ self.assertEqual(response_json["internal"]["url"], f"/{self.prefix}about/")
980
+ self.assertEqual(response_json["internal"]["id"], self.internal_page.pk)
981
+
982
+ def test_convert_relative_external_link_to_internal_link(self):
983
+ # Legacy behaviour: when using a non-root serve path, entering a relative
984
+ # URL without the serve path will trigger the conversion.
985
+ # Normally this should be converted without any confirmation, but since
986
+ # the actual URL will include the serve path (thus different from the
987
+ # input URL), the user should be asked to confirm.
988
+ response = self.post(
989
+ {
990
+ "external-link-chooser-url": "/about/",
991
+ "external-link-chooser-link_text": "about",
992
+ }
993
+ )
994
+ self.assertEqual(response.status_code, 200)
995
+ response_json = json.loads(response.content.decode())
996
+ self.assertEqual(response_json["step"], "confirm_external_to_internal")
997
+ self.assertEqual(response_json["external"]["url"], "/about/")
998
+ self.assertEqual(response_json["internal"]["url"], f"/{self.prefix}about/")
999
+ self.assertEqual(response_json["internal"]["id"], self.internal_page.pk)
1000
+
1001
+ def test_convert_relative_external_link_to_internal_link_with_serve_path(self):
1002
+ # https://github.com/wagtail/wagtail/issues/11996
1003
+ # New behaviour: when using a non-root serve path, entering a relative
1004
+ # URL with the serve path will trigger the conversion. Previously, this
1005
+ # would have been considered an external link since the logic does not
1006
+ # take the serve path into account, but now it should be correctly
1007
+ # converted to an internal link (without needing confirmation as the
1008
+ # input URL will be an exact match to the page's relative URL).
1009
+ response = self.post(
1010
+ {
1011
+ "external-link-chooser-url": f"/{self.prefix}about/",
1012
+ "external-link-chooser-link_text": "about",
1013
+ }
1014
+ )
1015
+ self.assertEqual(response.status_code, 200)
1016
+ response_json = json.loads(response.content.decode())
1017
+ self.assertEqual(response_json["step"], "external_link_chosen")
1018
+ self.assertEqual(response_json["result"]["url"], f"/{self.prefix}about/")
1019
+ self.assertEqual(response_json["result"]["id"], self.internal_page.pk)
1020
+
1021
+ @override_settings(WAGTAILADMIN_EXTERNAL_LINK_CONVERSION="")
1022
+ def test_no_conversion_external_to_internal_link_when_disabled_with_serve_path(
1023
+ self
1024
+ ):
1025
+ url = f"http://localhost/{self.prefix}about/"
1026
+ title = "about"
1027
+ response = self.post(
1028
+ {"external-link-chooser-url": url, "external-link-chooser-link_text": title}
1029
+ )
1030
+ self.assertEqual(response.status_code, 200)
1031
+ response_json = json.loads(response.content.decode())
1032
+ self.assertEqual(response_json["step"], "external_link_chosen")
1033
+
1034
+ self.assertEqual(response_json["result"]["url"], url)
1035
+ self.assertEqual(response_json["result"]["title"], title)
1036
+ self.assertNotIn("id", response_json["result"])
1037
+
1038
+ @override_settings(WAGTAILADMIN_EXTERNAL_LINK_CONVERSION="exact")
1039
+ def test_no_confirm_external_to_internal_link_when_exact_with_serve_path(self):
1040
+ url = f"http://localhost/{self.prefix}about?test=1"
1041
+ title = "about"
1042
+ response = self.post(
1043
+ {"external-link-chooser-url": url, "external-link-chooser-link_text": title}
1044
+ )
1045
+ self.assertEqual(response.status_code, 200)
1046
+ response_json = json.loads(response.content.decode())
1047
+ # Query parameters will get stripped, so this link should be left as an external url with the 'exact' setting
1048
+ self.assertEqual(response_json["step"], "external_link_chosen")
1049
+
1050
+ self.assertEqual(response_json["result"]["url"], url)
1051
+ self.assertEqual(response_json["result"]["title"], title)
1052
+ self.assertNotIn("id", response_json["result"])
1053
+
1054
+ @override_settings(WAGTAILADMIN_EXTERNAL_LINK_CONVERSION="confirm")
1055
+ def test_convert_external_link_to_internal_link_with_confirm_setting(self):
1056
+ url = f"http://localhost/{self.prefix}about/"
1057
+ response = self.post(
1058
+ {
1059
+ "external-link-chooser-url": url,
1060
+ "external-link-chooser-link_text": "about",
1061
+ }
1062
+ )
1063
+ self.assertEqual(response.status_code, 200)
1064
+ response_json = json.loads(response.content.decode())
1065
+
1066
+ # The url is identical, but the conversion setting is set to 'confirm'
1067
+ # so the user should get asked to confirm the conversion
1068
+ self.assertEqual(response_json["step"], "confirm_external_to_internal")
1069
+
1070
+ self.assertEqual(response_json["external"]["url"], url)
1071
+ self.assertEqual(response_json["internal"]["url"], f"/{self.prefix}about/")
1072
+ self.assertEqual(response_json["internal"]["id"], self.internal_page.pk)
1073
+
1074
+
1075
+ @override_settings(
1076
+ WAGTAIL_I18N_ENABLED=True,
1077
+ ROOT_URLCONF="wagtail.test.urls_multilang",
1078
+ )
1079
+ class TestChooserExternalLinkWithI18n(TestChooserExternalLinkWithNonRootServePath):
1080
+ prefix = "en/"
1081
+
1082
+
1083
+ @override_settings(
1084
+ WAGTAIL_I18N_ENABLED=True,
1085
+ ROOT_URLCONF="wagtail.test.urls_multilang_non_root",
1086
+ )
1087
+ class TestChooserExternalLinkWithI18nNonRoot(
1088
+ TestChooserExternalLinkWithNonRootServePath
1089
+ ):
1090
+ prefix = "en/site/"
1091
+
1092
+
791
1093
  class TestChooserAnchorLink(WagtailTestUtils, TestCase):
792
1094
  def setUp(self):
793
1095
  self.login()
@@ -930,8 +1232,8 @@ class TestChooserEmailLink(WagtailTestUtils, TestCase):
930
1232
  ) # When link text is given, it is used
931
1233
  self.assertIs(result["prefer_this_title_as_link_text"], True)
932
1234
 
933
- mail_parts = urlparse.urlparse(url)
934
- query = urlparse.parse_qs(mail_parts.query)
1235
+ mail_parts = urlsplit(url)
1236
+ query = parse_qs(mail_parts.query)
935
1237
  self.assertEqual(mail_parts.path, "example@example.com")
936
1238
  self.assertEqual(query["subject"][0], "Awesome Subject")
937
1239
  self.assertEqual(query["body"][0], "An example body")
@@ -953,8 +1255,8 @@ class TestChooserEmailLink(WagtailTestUtils, TestCase):
953
1255
  ) # When link text is given, it is used
954
1256
  self.assertIs(result["prefer_this_title_as_link_text"], True)
955
1257
 
956
- mail_parts = urlparse.urlparse(url)
957
- query = urlparse.parse_qs(mail_parts.query)
1258
+ mail_parts = urlsplit(url)
1259
+ query = parse_qs(mail_parts.query)
958
1260
  self.assertEqual(mail_parts.path, "example@example.com")
959
1261
  self.assertEqual(query["subject"][0], "Awesome Subject")
960
1262
  self.assertTrue("body" not in query)
@@ -976,8 +1278,8 @@ class TestChooserEmailLink(WagtailTestUtils, TestCase):
976
1278
  ) # When link text is given, it is used
977
1279
  self.assertIs(result["prefer_this_title_as_link_text"], True)
978
1280
 
979
- mail_parts = urlparse.urlparse(url)
980
- query = urlparse.parse_qs(mail_parts.query)
1281
+ mail_parts = urlsplit(url)
1282
+ query = parse_qs(mail_parts.query)
981
1283
  self.assertEqual(mail_parts.path, "example@example.com")
982
1284
  self.assertEqual(query["body"][0], "An example body")
983
1285
  self.assertTrue("subject" not in query)
@@ -1,3 +1,5 @@
1
+ import json
2
+
1
3
  from django.contrib.auth.models import Group
2
4
  from django.test import TestCase, override_settings
3
5
  from django.urls import reverse
@@ -117,9 +119,24 @@ class TestSetPrivacyView(WagtailTestUtils, TestCase):
117
119
  self.assertTemplateUsed(
118
120
  response, "wagtailadmin/page_privacy/ancestor_privacy.html"
119
121
  )
122
+ self.assertContains(
123
+ response, "This page has been made private by a parent page."
124
+ )
120
125
  self.assertEqual(
121
126
  response.context["page_with_restriction"].specific, self.private_page
122
127
  )
128
+ # Should render without any heading, as the dialog already has a heading
129
+ soup = self.get_soup(json.loads(response.content)["html"])
130
+ self.assertIsNone(soup.select_one("header"))
131
+ self.assertIsNone(soup.select_one("h1"))
132
+
133
+ # Should link to the edit page for the collection with the restriction
134
+ link = soup.select_one("a")
135
+ parent_edit_url = reverse(
136
+ "wagtailadmin_pages:edit",
137
+ args=(self.private_page.pk,),
138
+ )
139
+ self.assertEqual(link.get("href"), parent_edit_url)
123
140
 
124
141
  def test_set_password_restriction(self):
125
142
  """
@@ -527,3 +544,68 @@ class TestPrivacyIndicators(WagtailTestUtils, TestCase):
527
544
  self.assertContains(
528
545
  response, '<div class="w-hidden" data-privacy-sidebar-public>'
529
546
  )
547
+
548
+ def test_private_page_options_only_password_groups(self):
549
+ # change the private_page_options to password and login
550
+ original_private_page_options = self.public_page.private_page_options
551
+ self.public_page.specific.__class__.private_page_options = [
552
+ "password",
553
+ "groups",
554
+ ]
555
+
556
+ response = self.client.get(
557
+ reverse("wagtailadmin_pages:set_privacy", args=(self.public_page.id,))
558
+ )
559
+
560
+ restriction_types = [
561
+ choice[0]
562
+ for choice in response.context["form"].fields["restriction_type"].choices
563
+ ]
564
+
565
+ # Check response
566
+ self.assertListEqual(restriction_types, ["none", "password", "groups"])
567
+
568
+ # Reset the private_page_options to previous value
569
+ self.public_page.specific.__class__.private_page_options = (
570
+ original_private_page_options
571
+ )
572
+
573
+ def test_private_page_options_only_password_login(self):
574
+ # change the private_page_options to password and login
575
+ original_private_page_options = self.public_page.private_page_options
576
+ self.public_page.specific.__class__.private_page_options = ["password", "login"]
577
+
578
+ response = self.client.get(
579
+ reverse("wagtailadmin_pages:set_privacy", args=(self.public_page.id,))
580
+ )
581
+
582
+ restriction_types = [
583
+ choice[0]
584
+ for choice in response.context["form"].fields["restriction_type"].choices
585
+ ]
586
+
587
+ # Check response
588
+ self.assertListEqual(restriction_types, ["none", "password", "login"])
589
+
590
+ # Reset the private_page_options to previous value
591
+ self.public_page.specific.__class__.private_page_options = (
592
+ original_private_page_options
593
+ )
594
+
595
+ def test_private_page_no_options(self):
596
+ # change the private_page_options to empty list
597
+ original_private_page_options = self.public_page.private_page_options
598
+ self.public_page.specific.__class__.private_page_options = []
599
+
600
+ response = self.client.get(
601
+ reverse("wagtailadmin_pages:set_privacy", args=(self.public_page.id,))
602
+ )
603
+
604
+ # Check response
605
+ self.assertEqual(response.status_code, 200)
606
+ self.assertTemplateUsed(response, "wagtailadmin/page_privacy/no_privacy.html")
607
+
608
+ # Reset the private_page_options to previous value
609
+ self.public_page.specific.__class__.private_page_options = (
610
+ original_private_page_options
611
+ )