wagtail 6.2.2__py3-none-any.whl → 6.3rc1__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 (386) hide show
  1. wagtail/__init__.py +1 -1
  2. wagtail/actions/copy_for_translation.py +6 -0
  3. wagtail/actions/publish_revision.py +3 -3
  4. wagtail/admin/action_menu.py +5 -3
  5. wagtail/admin/forms/account.py +1 -1
  6. wagtail/admin/icons.py +2 -6
  7. wagtail/admin/locale/cy/LC_MESSAGES/django.mo +0 -0
  8. wagtail/admin/locale/cy/LC_MESSAGES/django.po +32 -0
  9. wagtail/admin/locale/dv/LC_MESSAGES/django.mo +0 -0
  10. wagtail/admin/locale/dv/LC_MESSAGES/django.po +28 -0
  11. wagtail/admin/locale/en/LC_MESSAGES/django.po +451 -485
  12. wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +7 -7
  13. wagtail/admin/locale/sl/LC_MESSAGES/django.mo +0 -0
  14. wagtail/admin/locale/sl/LC_MESSAGES/django.po +150 -0
  15. wagtail/admin/locale/sl/LC_MESSAGES/djangojs.mo +0 -0
  16. wagtail/admin/locale/sl/LC_MESSAGES/djangojs.po +9 -2
  17. wagtail/admin/locale/ug/LC_MESSAGES/django.mo +0 -0
  18. wagtail/admin/locale/ug/LC_MESSAGES/django.po +3250 -196
  19. wagtail/admin/localization.py +8 -2
  20. wagtail/admin/panels/model_utils.py +1 -1
  21. wagtail/admin/site_summary.py +0 -2
  22. wagtail/admin/static/wagtailadmin/css/core.css +1 -1
  23. wagtail/admin/static/wagtailadmin/css/panels/draftail.css +1 -1
  24. wagtail/admin/static/wagtailadmin/images/email-header.jpg +0 -0
  25. wagtail/admin/static/wagtailadmin/js/bulk-actions.js +1 -1
  26. wagtail/admin/static/wagtailadmin/js/core.js +1 -1
  27. wagtail/admin/static/wagtailadmin/js/core.js.LICENSE.txt +12 -0
  28. wagtail/admin/static/wagtailadmin/js/draftail.js +1 -1
  29. wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
  30. wagtail/admin/static/wagtailadmin/js/telepath/telepath.js +1 -1
  31. wagtail/admin/static/wagtailadmin/js/telepath/widgets.js +1 -1
  32. wagtail/admin/static/wagtailadmin/js/userbar.js +1 -1
  33. wagtail/admin/static/wagtailadmin/js/userbar.js.LICENSE.txt +1 -1
  34. wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
  35. wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
  36. wagtail/admin/static/wagtailadmin/js/workflow-action.js +1 -1
  37. wagtail/admin/staticfiles.py +6 -4
  38. wagtail/admin/templates/wagtailadmin/account/account.html +42 -59
  39. wagtail/admin/templates/wagtailadmin/admin_base.html +0 -28
  40. wagtail/admin/templates/wagtailadmin/bulk_actions/footer.html +1 -1
  41. wagtail/admin/templates/wagtailadmin/chooser/_search_results.html +7 -5
  42. wagtail/admin/templates/wagtailadmin/chooser/tables/page_navigate_to_children_cell.html +1 -1
  43. wagtail/admin/templates/wagtailadmin/generic/chooser/results.html +7 -5
  44. wagtail/admin/templates/wagtailadmin/generic/edit.html +0 -8
  45. wagtail/admin/templates/wagtailadmin/generic/form.html +60 -17
  46. wagtail/admin/templates/wagtailadmin/generic/index.html +17 -0
  47. wagtail/admin/templates/wagtailadmin/generic/index_results.html +9 -35
  48. wagtail/admin/templates/wagtailadmin/generic/inspect.html +2 -21
  49. wagtail/admin/templates/wagtailadmin/generic/listing.html +11 -17
  50. wagtail/admin/templates/wagtailadmin/generic/listing_results.html +19 -1
  51. wagtail/admin/templates/wagtailadmin/home/account_summary.html +26 -0
  52. wagtail/admin/templates/wagtailadmin/home/locked_pages.html +28 -18
  53. wagtail/admin/templates/wagtailadmin/home/recent_edits.html +28 -17
  54. wagtail/admin/templates/wagtailadmin/home/site_summary_pages.html +2 -2
  55. wagtail/admin/templates/wagtailadmin/home/upgrade_notification.html +35 -13
  56. wagtail/admin/templates/wagtailadmin/home/user_objects_in_workflow_moderation.html +28 -18
  57. wagtail/admin/templates/wagtailadmin/home/workflow_objects_to_moderate.html +43 -32
  58. wagtail/admin/templates/wagtailadmin/home.html +22 -5
  59. wagtail/admin/templates/wagtailadmin/pages/_editor_js.html +0 -1
  60. wagtail/admin/templates/wagtailadmin/pages/action_menu/menu.html +1 -11
  61. wagtail/admin/templates/wagtailadmin/pages/action_menu/menu_item.html +1 -6
  62. wagtail/admin/templates/wagtailadmin/pages/action_menu/page_locked.html +1 -1
  63. wagtail/admin/templates/wagtailadmin/pages/action_menu/publish.html +1 -1
  64. wagtail/admin/templates/wagtailadmin/pages/action_menu/save_draft.html +1 -1
  65. wagtail/admin/templates/wagtailadmin/pages/bulk_actions/confirm_bulk_delete.html +12 -6
  66. wagtail/admin/templates/wagtailadmin/pages/bulk_actions/confirm_bulk_move.html +12 -7
  67. wagtail/admin/templates/wagtailadmin/pages/bulk_actions/confirm_bulk_publish.html +17 -11
  68. wagtail/admin/templates/wagtailadmin/pages/bulk_actions/confirm_bulk_unpublish.html +15 -9
  69. wagtail/admin/templates/wagtailadmin/pages/confirm_delete.html +9 -9
  70. wagtail/admin/templates/wagtailadmin/pages/confirm_move.html +2 -2
  71. wagtail/admin/templates/wagtailadmin/pages/confirm_unpublish.html +4 -4
  72. wagtail/admin/templates/wagtailadmin/pages/create.html +15 -34
  73. wagtail/admin/templates/wagtailadmin/pages/edit.html +15 -30
  74. wagtail/admin/templates/wagtailadmin/pages/explorable_index.html +6 -0
  75. wagtail/admin/templates/wagtailadmin/pages/explorable_index_results.html +60 -0
  76. wagtail/admin/templates/wagtailadmin/pages/index.html +1 -36
  77. wagtail/admin/templates/wagtailadmin/pages/index_results.html +2 -50
  78. wagtail/admin/templates/wagtailadmin/pages/listing/_locked_indicator.html +1 -1
  79. wagtail/admin/templates/wagtailadmin/pages/listing/_ordering_cell.html +1 -1
  80. wagtail/admin/templates/wagtailadmin/pages/listing/_page_header_buttons.html +1 -1
  81. wagtail/admin/templates/wagtailadmin/pages/listing/_page_title_column_header.html +3 -3
  82. wagtail/admin/templates/wagtailadmin/pages/listing/_pagination.html +1 -1
  83. wagtail/admin/templates/wagtailadmin/pages/listing.html +24 -0
  84. wagtail/admin/templates/wagtailadmin/pages/search.html +1 -20
  85. wagtail/admin/templates/wagtailadmin/pages/search_results.html +27 -25
  86. wagtail/admin/templates/wagtailadmin/permissions/includes/collection_member_permissions_formset.html +0 -1
  87. wagtail/admin/templates/wagtailadmin/reports/listing/_list_page_report.html +2 -2
  88. wagtail/admin/templates/wagtailadmin/reports/listing/_list_page_types_usage.html +6 -6
  89. wagtail/admin/templates/wagtailadmin/reports/workflow_tasks_results.html +1 -1
  90. wagtail/admin/templates/wagtailadmin/shared/action_menu/menu.html +14 -0
  91. wagtail/admin/templates/wagtailadmin/shared/action_menu/menu_item.html +6 -0
  92. wagtail/admin/templates/wagtailadmin/shared/avatar.html +13 -3
  93. wagtail/admin/templates/wagtailadmin/shared/header.html +0 -5
  94. wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html +1 -1
  95. wagtail/admin/templates/wagtailadmin/shared/page_status_tag_new.html +4 -1
  96. wagtail/admin/templates/wagtailadmin/shared/pagination_nav.html +1 -1
  97. wagtail/admin/templates/wagtailadmin/shared/side_panel_toggle.html +1 -1
  98. wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/status/locale.html +1 -1
  99. wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/status/usage.html +2 -2
  100. wagtail/admin/templates/wagtailadmin/shared/side_panels/preview.html +94 -52
  101. wagtail/admin/templates/wagtailadmin/{pages/_unsaved_changes_warning.html → shared/unsaved_changes_warning.html} +4 -4
  102. wagtail/admin/templates/wagtailadmin/shared/usage_summary.html +2 -2
  103. wagtail/admin/templates/wagtailadmin/shared/workflow_history/detail.html +1 -7
  104. wagtail/admin/templates/wagtailadmin/shared/workflow_history/listing.html +1 -0
  105. wagtail/admin/templates/wagtailadmin/shared/workflow_history/{list.html → listing_results.html} +33 -35
  106. wagtail/admin/templates/wagtailadmin/tables/references_cell.html +1 -1
  107. wagtail/admin/templates/wagtailadmin/workflows/create.html +11 -36
  108. wagtail/admin/templates/wagtailadmin/workflows/create_task.html +0 -38
  109. wagtail/admin/templates/wagtailadmin/workflows/edit.html +44 -74
  110. wagtail/admin/templates/wagtailadmin/workflows/edit_task.html +27 -66
  111. wagtail/admin/templates/wagtailadmin/workflows/includes/task_usage_cell.html +4 -2
  112. wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_tasks_cell.html +4 -4
  113. wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_used_by_cell.html +15 -11
  114. wagtail/admin/templates/wagtailadmin/workflows/task_chooser/includes/results.html +7 -5
  115. wagtail/admin/templatetags/wagtailadmin_tags.py +51 -22
  116. wagtail/admin/tests/pages/test_content_type_use_view.py +82 -2
  117. wagtail/admin/tests/pages/test_edit_page.py +70 -0
  118. wagtail/admin/tests/pages/test_explorer_view.py +65 -4
  119. wagtail/admin/tests/pages/test_page_search.py +8 -7
  120. wagtail/admin/tests/pages/test_page_usage.py +3 -1
  121. wagtail/admin/tests/pages/test_preview.py +208 -63
  122. wagtail/admin/tests/pages/test_reorder_page.py +91 -1
  123. wagtail/admin/tests/pages/test_view_draft.py +32 -1
  124. wagtail/admin/tests/pages/test_workflow_history.py +288 -7
  125. wagtail/admin/tests/test_account_management.py +23 -3
  126. wagtail/admin/tests/test_audit_log.py +24 -2
  127. wagtail/admin/tests/test_collections_views.py +17 -5
  128. wagtail/admin/tests/test_dashboard.py +1 -1
  129. wagtail/admin/tests/test_edit_handlers.py +3 -2
  130. wagtail/admin/tests/test_icon_sprite.py +4 -0
  131. wagtail/admin/tests/test_privacy.py +5 -19
  132. wagtail/admin/tests/test_reports_views.py +1 -1
  133. wagtail/admin/tests/test_site_summary.py +3 -3
  134. wagtail/admin/tests/test_templatetags.py +27 -3
  135. wagtail/admin/tests/test_upgrade_notification.py +71 -18
  136. wagtail/admin/tests/test_views.py +2 -2
  137. wagtail/admin/tests/test_views_generic.py +13 -0
  138. wagtail/admin/tests/test_widgets.py +3 -3
  139. wagtail/admin/tests/test_workflows.py +172 -27
  140. wagtail/admin/tests/tests.py +1 -1
  141. wagtail/admin/tests/viewsets/test_model_viewset.py +55 -3
  142. wagtail/admin/ui/side_panels.py +19 -0
  143. wagtail/admin/ui/sidebar.py +4 -3
  144. wagtail/admin/ui/tables/__init__.py +14 -1
  145. wagtail/admin/ui/tables/pages.py +6 -1
  146. wagtail/admin/urls/pages.py +10 -1
  147. wagtail/admin/urls/workflows.py +6 -1
  148. wagtail/admin/views/account.py +5 -1
  149. wagtail/admin/views/collections.py +0 -2
  150. wagtail/admin/views/generic/base.py +118 -1
  151. wagtail/admin/views/generic/history.py +158 -26
  152. wagtail/admin/views/generic/models.py +113 -99
  153. wagtail/admin/views/home.py +24 -9
  154. wagtail/admin/views/page_privacy.py +54 -30
  155. wagtail/admin/views/pages/history.py +11 -4
  156. wagtail/admin/views/pages/listing.py +76 -89
  157. wagtail/admin/views/pages/preview.py +1 -1
  158. wagtail/admin/views/pages/search.py +27 -71
  159. wagtail/admin/views/pages/usage.py +63 -24
  160. wagtail/admin/views/pages/utils.py +4 -3
  161. wagtail/admin/views/reports/base.py +0 -6
  162. wagtail/admin/views/workflows.py +67 -25
  163. wagtail/admin/viewsets/model.py +4 -3
  164. wagtail/admin/widgets/chooser.py +2 -1
  165. wagtail/api/v2/tests/test_pages.py +15 -2
  166. wagtail/blocks/field_block.py +15 -3
  167. wagtail/blocks/static_block.py +3 -0
  168. wagtail/contrib/forms/locale/cy/LC_MESSAGES/django.mo +0 -0
  169. wagtail/contrib/forms/locale/cy/LC_MESSAGES/django.po +29 -1
  170. wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +15 -11
  171. wagtail/contrib/forms/templates/wagtailforms/confirm_delete.html +1 -0
  172. wagtail/contrib/forms/templates/wagtailforms/index.html +1 -1
  173. wagtail/contrib/forms/templates/wagtailforms/index_results.html +1 -1
  174. wagtail/contrib/forms/templates/wagtailforms/list_submissions.html +2 -1
  175. wagtail/contrib/forms/templates/wagtailforms/panels/form_responses_panel.html +2 -2
  176. wagtail/contrib/forms/tests/test_views.py +234 -35
  177. wagtail/contrib/forms/utils.py +8 -14
  178. wagtail/contrib/forms/views.py +72 -27
  179. wagtail/contrib/frontend_cache/backends/azure.py +1 -1
  180. wagtail/contrib/frontend_cache/backends/cloudfront.py +2 -2
  181. wagtail/contrib/frontend_cache/backends/dummy.py +11 -0
  182. wagtail/contrib/frontend_cache/tests.py +31 -37
  183. wagtail/contrib/frontend_cache/utils.py +12 -5
  184. wagtail/contrib/redirects/locale/cy/LC_MESSAGES/django.mo +0 -0
  185. wagtail/contrib/redirects/locale/cy/LC_MESSAGES/django.po +16 -1
  186. wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +20 -24
  187. wagtail/contrib/redirects/models.py +16 -1
  188. wagtail/contrib/redirects/signal_handlers.py +18 -3
  189. wagtail/contrib/redirects/templates/wagtailredirects/add.html +5 -16
  190. wagtail/contrib/redirects/templates/wagtailredirects/import_summary.html +1 -1
  191. wagtail/contrib/redirects/tests/test_redirects.py +49 -6
  192. wagtail/contrib/redirects/tests/test_signal_handlers.py +42 -1
  193. wagtail/contrib/redirects/views.py +27 -3
  194. wagtail/contrib/search_promotions/locale/cy/LC_MESSAGES/django.mo +0 -0
  195. wagtail/contrib/search_promotions/locale/cy/LC_MESSAGES/django.po +60 -1
  196. wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +12 -18
  197. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/add.html +5 -8
  198. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/edit.html +15 -10
  199. wagtail/contrib/search_promotions/tests.py +13 -2
  200. wagtail/contrib/search_promotions/views.py +15 -3
  201. wagtail/contrib/settings/locale/cy/LC_MESSAGES/django.mo +0 -0
  202. wagtail/contrib/settings/locale/cy/LC_MESSAGES/django.po +6 -1
  203. wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +2 -10
  204. wagtail/contrib/settings/templates/wagtailsettings/edit.html +12 -45
  205. wagtail/contrib/simple_translation/locale/cy/LC_MESSAGES/django.mo +0 -0
  206. wagtail/contrib/simple_translation/locale/cy/LC_MESSAGES/django.po +13 -1
  207. wagtail/contrib/simple_translation/locale/dv/LC_MESSAGES/django.mo +0 -0
  208. wagtail/contrib/simple_translation/locale/dv/LC_MESSAGES/django.po +3 -0
  209. wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +4 -4
  210. wagtail/contrib/simple_translation/locale/sl/LC_MESSAGES/django.mo +0 -0
  211. wagtail/contrib/simple_translation/locale/sl/LC_MESSAGES/django.po +5 -2
  212. wagtail/contrib/simple_translation/tests/test_views.py +51 -0
  213. wagtail/contrib/simple_translation/wagtail_hooks.py +16 -11
  214. wagtail/contrib/styleguide/locale/cy/LC_MESSAGES/django.mo +0 -0
  215. wagtail/contrib/styleguide/locale/cy/LC_MESSAGES/django.po +5 -1
  216. wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +1 -1
  217. wagtail/contrib/table_block/locale/cy/LC_MESSAGES/django.mo +0 -0
  218. wagtail/contrib/table_block/locale/cy/LC_MESSAGES/django.po +27 -1
  219. wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +1 -1
  220. wagtail/contrib/typed_table_block/blocks.py +25 -0
  221. wagtail/contrib/typed_table_block/locale/cy/LC_MESSAGES/django.mo +0 -0
  222. wagtail/contrib/typed_table_block/locale/cy/LC_MESSAGES/django.po +12 -1
  223. wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +10 -10
  224. wagtail/contrib/typed_table_block/tests.py +24 -1
  225. wagtail/coreutils.py +5 -11
  226. wagtail/documents/admin_urls.py +2 -2
  227. wagtail/documents/locale/cy/LC_MESSAGES/django.mo +0 -0
  228. wagtail/documents/locale/cy/LC_MESSAGES/django.po +10 -0
  229. wagtail/documents/locale/en/LC_MESSAGES/django.po +61 -76
  230. wagtail/documents/migrations/0014_alter_document_file_size.py +18 -0
  231. wagtail/documents/models.py +1 -1
  232. wagtail/documents/rich_text/__init__.py +1 -3
  233. wagtail/documents/static/wagtaildocs/js/add-multiple.js +1 -1
  234. wagtail/documents/templates/wagtaildocs/bulk_actions/confirm_bulk_add_tags.html +5 -1
  235. wagtail/documents/templates/wagtaildocs/bulk_actions/confirm_bulk_add_to_collection.html +5 -1
  236. wagtail/documents/templates/wagtaildocs/bulk_actions/confirm_bulk_delete.html +11 -5
  237. wagtail/documents/templates/wagtaildocs/documents/add.html +13 -41
  238. wagtail/documents/templates/wagtaildocs/documents/edit.html +28 -56
  239. wagtail/documents/templates/wagtaildocs/documents/index.html +1 -4
  240. wagtail/documents/templates/wagtaildocs/homepage/site_summary_documents.html +2 -2
  241. wagtail/documents/templates/wagtaildocs/multiple/add.html +36 -41
  242. wagtail/documents/tests/test_admin_views.py +64 -6
  243. wagtail/documents/tests/test_site_summary.py +3 -3
  244. wagtail/documents/views/documents.py +103 -113
  245. wagtail/documents/views/multiple.py +19 -1
  246. wagtail/embeds/locale/en/LC_MESSAGES/django.po +1 -1
  247. wagtail/embeds/oembed_providers.py +9 -19
  248. wagtail/fields.py +43 -27
  249. wagtail/images/admin_urls.py +2 -2
  250. wagtail/images/blocks.py +230 -2
  251. wagtail/images/fields.py +17 -29
  252. wagtail/images/image_operations.py +1 -1
  253. wagtail/images/locale/cy/LC_MESSAGES/django.mo +0 -0
  254. wagtail/images/locale/cy/LC_MESSAGES/django.po +128 -1
  255. wagtail/images/locale/en/LC_MESSAGES/django.po +119 -129
  256. wagtail/images/migrations/0025_alter_image_file_alter_rendition_file.py +36 -43
  257. wagtail/images/migrations/0027_image_description.py +20 -0
  258. wagtail/images/models.py +120 -45
  259. wagtail/images/rich_text/__init__.py +1 -3
  260. wagtail/images/static/wagtailimages/js/add-multiple.js +1 -1
  261. wagtail/images/static/wagtailimages/js/image-block.js +1 -0
  262. wagtail/images/templates/wagtailimages/bulk_actions/confirm_bulk_add_tags.html +5 -1
  263. wagtail/images/templates/wagtailimages/bulk_actions/confirm_bulk_add_to_collection.html +5 -1
  264. wagtail/images/templates/wagtailimages/bulk_actions/confirm_bulk_delete.html +11 -5
  265. wagtail/images/templates/wagtailimages/chooser/results.html +2 -2
  266. wagtail/images/templates/wagtailimages/homepage/site_summary_images.html +2 -2
  267. wagtail/images/templates/wagtailimages/images/_file_field.html +2 -2
  268. wagtail/images/templates/wagtailimages/images/add.html +13 -31
  269. wagtail/images/templates/wagtailimages/images/edit.html +53 -82
  270. wagtail/images/templates/wagtailimages/images/index.html +1 -4
  271. wagtail/images/templates/wagtailimages/images/url_generator.html +1 -1
  272. wagtail/images/templates/wagtailimages/multiple/add.html +40 -47
  273. wagtail/images/templates/wagtailimages/widgets/image.html +5 -0
  274. wagtail/images/templates/wagtailimages/widgets/image_chooser.html +1 -1
  275. wagtail/images/tests/test_admin_views.py +70 -10
  276. wagtail/images/tests/test_blocks.py +367 -1
  277. wagtail/images/tests/test_image_operations.py +23 -0
  278. wagtail/images/tests/test_models.py +20 -0
  279. wagtail/images/tests/test_signal_handlers.py +99 -95
  280. wagtail/images/tests/test_site_summary.py +3 -3
  281. wagtail/images/tests/test_templatetags.py +11 -7
  282. wagtail/images/tests/tests.py +4 -0
  283. wagtail/images/views/images.py +103 -104
  284. wagtail/images/views/multiple.py +17 -1
  285. wagtail/locale/cy/LC_MESSAGES/django.mo +0 -0
  286. wagtail/locale/cy/LC_MESSAGES/django.po +3 -0
  287. wagtail/locale/en/LC_MESSAGES/django.po +137 -125
  288. wagtail/locale/sl/LC_MESSAGES/django.mo +0 -0
  289. wagtail/locale/sl/LC_MESSAGES/django.po +3 -0
  290. wagtail/locales/locale/en/LC_MESSAGES/django.po +8 -8
  291. wagtail/locales/views.py +4 -1
  292. wagtail/migrations/0089_log_entry_data_json_null_to_object.py +1 -7
  293. wagtail/models/__init__.py +122 -14
  294. wagtail/models/audit_log.py +1 -3
  295. wagtail/models/i18n.py +1 -2
  296. wagtail/project_template/Dockerfile +3 -3
  297. wagtail/project_template/requirements.txt +2 -2
  298. wagtail/query.py +17 -4
  299. wagtail/rich_text/__init__.py +2 -3
  300. wagtail/rich_text/pages.py +2 -4
  301. wagtail/rich_text/rewriters.py +2 -2
  302. wagtail/search/backends/database/mysql/query.py +3 -3
  303. wagtail/search/backends/database/sqlite/query.py +6 -6
  304. wagtail/search/locale/en/LC_MESSAGES/django.po +1 -1
  305. wagtail/sites/locale/en/LC_MESSAGES/django.po +6 -6
  306. wagtail/sites/views.py +0 -1
  307. wagtail/snippets/action_menu.py +14 -4
  308. wagtail/snippets/locale/cy/LC_MESSAGES/django.mo +0 -0
  309. wagtail/snippets/locale/cy/LC_MESSAGES/django.po +73 -1
  310. wagtail/snippets/locale/en/LC_MESSAGES/django.po +27 -33
  311. wagtail/snippets/static/wagtailsnippets/js/snippet-chooser-telepath.js +1 -1
  312. wagtail/snippets/static/wagtailsnippets/js/snippet-chooser.js +1 -1
  313. wagtail/snippets/templates/wagtailsnippets/bulk_actions/confirm_bulk_delete.html +5 -3
  314. wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/locked.html +1 -1
  315. wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/menu.html +1 -11
  316. wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/menu_item.html +1 -6
  317. wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/publish.html +1 -1
  318. wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/save.html +1 -1
  319. wagtail/snippets/templates/wagtailsnippets/snippets/create.html +1 -18
  320. wagtail/snippets/templates/wagtailsnippets/snippets/edit.html +1 -14
  321. wagtail/snippets/templates/wagtailsnippets/snippets/index.html +2 -5
  322. wagtail/snippets/tests/test_preview.py +193 -61
  323. wagtail/snippets/tests/test_snippets.py +247 -38
  324. wagtail/snippets/tests/test_usage.py +5 -0
  325. wagtail/snippets/tests/test_viewset.py +25 -9
  326. wagtail/snippets/tests/test_workflows.py +232 -19
  327. wagtail/snippets/views/snippets.py +1 -10
  328. wagtail/test/numberformat.py +104 -0
  329. wagtail/test/settings.py +10 -0
  330. wagtail/test/settings_ui.py +2 -0
  331. wagtail/test/testapp/migrations/0010_alter_customimage_file_and_more.py +71 -78
  332. wagtail/test/testapp/migrations/0040_nocreatablesubpagetypespage_nosubpagetypespage.py +54 -0
  333. wagtail/test/testapp/migrations/0041_alter_jsonstreammodel_options.py +17 -0
  334. wagtail/test/testapp/migrations/0042_alter_customdocument_file_size_and_more.py +28 -0
  335. wagtail/test/testapp/migrations/0043_customimage_description.py +41 -0
  336. wagtail/test/testapp/migrations/0044_custompreviewsizesmodel_custompreviewsizespage.py +52 -0
  337. wagtail/test/testapp/migrations/0045_alter_streampage_body.py +52 -0
  338. wagtail/test/testapp/models.py +62 -4
  339. wagtail/test/testapp/rich_text.py +2 -2
  340. wagtail/test/testapp/templates/tests/form_page_landing.html +2 -1
  341. wagtail/test/testapp/urls.py +5 -0
  342. wagtail/test/testapp/views.py +5 -0
  343. wagtail/test/utils/page_tests.py +5 -5
  344. wagtail/test/utils/template_tests.py +2 -2
  345. wagtail/tests/test_blocks.py +15 -0
  346. wagtail/tests/test_page_permissions.py +109 -0
  347. wagtail/tests/test_revision_model.py +27 -0
  348. wagtail/tests/test_signals.py +21 -2
  349. wagtail/tests/test_tests.py +30 -0
  350. wagtail/users/locale/cy/LC_MESSAGES/django.mo +0 -0
  351. wagtail/users/locale/cy/LC_MESSAGES/django.po +118 -1
  352. wagtail/users/locale/dv/LC_MESSAGES/django.mo +0 -0
  353. wagtail/users/locale/dv/LC_MESSAGES/django.po +3 -0
  354. wagtail/users/locale/en/LC_MESSAGES/django.po +89 -113
  355. wagtail/users/locale/sl/LC_MESSAGES/django.mo +0 -0
  356. wagtail/users/locale/sl/LC_MESSAGES/django.po +3 -0
  357. wagtail/users/migrations/0014_userprofile_contrast.py +23 -0
  358. wagtail/users/models.py +11 -0
  359. wagtail/users/templates/wagtailusers/bulk_actions/confirm_bulk_assign_role.html +5 -1
  360. wagtail/users/templates/wagtailusers/bulk_actions/confirm_bulk_delete.html +5 -1
  361. wagtail/users/templates/wagtailusers/bulk_actions/confirm_bulk_set_active_state.html +5 -1
  362. wagtail/users/templates/wagtailusers/groups/create.html +19 -17
  363. wagtail/users/templates/wagtailusers/groups/edit.html +2 -40
  364. wagtail/users/templates/wagtailusers/groups/includes/formatted_permissions.html +1 -62
  365. wagtail/users/templates/wagtailusers/groups/includes/page_permissions_formset.html +0 -1
  366. wagtail/users/templates/wagtailusers/users/create.html +46 -50
  367. wagtail/users/templates/wagtailusers/users/edit.html +45 -62
  368. wagtail/users/templates/wagtailusers/users/index.html +1 -4
  369. wagtail/users/templatetags/wagtailusers_tags.py +1 -5
  370. wagtail/users/tests/test_admin_views.py +85 -66
  371. wagtail/users/views/groups.py +4 -1
  372. wagtail/users/views/users.py +2 -0
  373. {wagtail-6.2.2.dist-info → wagtail-6.3rc1.dist-info}/METADATA +6 -6
  374. {wagtail-6.2.2.dist-info → wagtail-6.3rc1.dist-info}/RECORD +378 -367
  375. wagtail/admin/static/wagtailadmin/js/preview-panel.js +0 -2
  376. wagtail/admin/static/wagtailadmin/js/preview-panel.js.LICENSE.txt +0 -11
  377. wagtail/admin/templates/wagtailadmin/generic/history_results.html +0 -1
  378. wagtail/admin/templates/wagtailadmin/page_privacy/ancestor_privacy.html +0 -3
  379. wagtail/admin/templates/wagtailadmin/pages/usage_results.html +0 -6
  380. wagtail/admin/templates/wagtailadmin/shared/workflow_history/index.html +0 -17
  381. wagtail/admin/templates/wagtailadmin/shared/workflow_history/results.html +0 -17
  382. wagtail/admin/templates/wagtailadmin/workflows/usage.html +0 -44
  383. {wagtail-6.2.2.dist-info → wagtail-6.3rc1.dist-info}/LICENSE +0 -0
  384. {wagtail-6.2.2.dist-info → wagtail-6.3rc1.dist-info}/WHEEL +0 -0
  385. {wagtail-6.2.2.dist-info → wagtail-6.3rc1.dist-info}/entry_points.txt +0 -0
  386. {wagtail-6.2.2.dist-info → wagtail-6.3rc1.dist-info}/top_level.txt +0 -0
@@ -11,7 +11,8 @@ from django.test.utils import override_settings
11
11
  from django.utils import timezone
12
12
  from freezegun import freeze_time
13
13
 
14
- from wagtail.admin.staticfiles import versioned_static
14
+ from wagtail.admin.localization import get_js_translation_strings
15
+ from wagtail.admin.staticfiles import VERSION_HASH, versioned_static
15
16
  from wagtail.admin.templatetags.wagtailadmin_tags import (
16
17
  avatar_url,
17
18
  i18n_enabled,
@@ -27,6 +28,7 @@ from wagtail.models import Locale, Page
27
28
  from wagtail.test.utils import WagtailTestUtils
28
29
  from wagtail.test.utils.template_tests import AdminTemplateTestUtils
29
30
  from wagtail.users.models import UserProfile
31
+ from wagtail.utils.deprecation import RemovedInWagtail70Warning
30
32
 
31
33
 
32
34
  class TestAvatarTemplateTag(WagtailTestUtils, TestCase):
@@ -99,9 +101,12 @@ class TestNotificationStaticTemplateTag(SimpleTestCase):
99
101
 
100
102
 
101
103
  class TestVersionedStatic(SimpleTestCase):
104
+ def test_version_hash(self):
105
+ self.assertEqual(len(VERSION_HASH), 8)
106
+
102
107
  def test_versioned_static(self):
103
108
  result = versioned_static("wagtailadmin/js/core.js")
104
- self.assertRegex(result, r"^/static/wagtailadmin/js/core.js\?v=(\w+)$")
109
+ self.assertRegex(result, r"^/static/wagtailadmin/js/core.js\?v=(\w{8})$")
105
110
 
106
111
  @mock.patch("wagtail.admin.staticfiles.static")
107
112
  def test_versioned_static_version_string(self, mock_static):
@@ -375,7 +380,12 @@ class TestInternationalisationTags(TestCase):
375
380
  self.assertTrue(i18n_enabled())
376
381
 
377
382
  def test_locales(self):
378
- locales_output = locales_tag()
383
+ with self.assertWarnsMessage(
384
+ RemovedInWagtail70Warning,
385
+ "The `locales` template tag will be removed in a future release.",
386
+ ):
387
+ locales_output = locales_tag()
388
+
379
389
  self.assertIsInstance(locales_output, str)
380
390
  self.assertEqual(
381
391
  json.loads(locales_output),
@@ -398,6 +408,20 @@ class TestInternationalisationTags(TestCase):
398
408
  with self.assertNumQueries(0):
399
409
  self.assertIsNone(locale_label_from_id(self.locale_ids[-1] + 100), None)
400
410
 
411
+ def test_js_translation_strings(self):
412
+ template = """
413
+ {% load wagtailadmin_tags %}
414
+ {% js_translation_strings %}
415
+ """
416
+
417
+ expected = json.dumps(get_js_translation_strings())
418
+
419
+ with self.assertWarnsMessage(
420
+ RemovedInWagtail70Warning,
421
+ "The `js_translation_strings` template tag will be removed in a future release.",
422
+ ):
423
+ self.assertHTMLEqual(expected, Template(template).render(Context()))
424
+
401
425
 
402
426
  class ComponentTest(SimpleTestCase):
403
427
  def test_render_block_component(self):
@@ -1,12 +1,17 @@
1
1
  from django.test import RequestFactory, TestCase, override_settings
2
2
 
3
+ from wagtail import __version__
3
4
  from wagtail.admin.views.home import UpgradeNotificationPanel
4
5
  from wagtail.test.utils import WagtailTestUtils
6
+ from wagtail.users.models import UserProfile
5
7
 
6
8
 
7
9
  class TestUpgradeNotificationPanel(WagtailTestUtils, TestCase):
8
- DATA_ATTRIBUTE_UPGRADE_CHECK = "data-w-upgrade"
9
- DATA_ATTRIBUTE_UPGRADE_CHECK_LTS = "data-w-upgrade-lts-only"
10
+ ATTR_UPGRADE_CHECK_LTS = "data-w-upgrade-lts-only-value"
11
+ ATTR_CURRENT_VERSION = "data-w-upgrade-current-version-value"
12
+ ATTR_DISMISSIBLE_ID = "data-w-dismissible-id-value"
13
+ ATTR_LAST_DISMISSED_VALUE = "data-w-dismissible-value-param"
14
+ DISMISSIBLE_ID = "last_upgrade_check"
10
15
 
11
16
  @classmethod
12
17
  def setUpTestData(cls):
@@ -59,9 +64,21 @@ class TestUpgradeNotificationPanel(WagtailTestUtils, TestCase):
59
64
  parent_context = {"request": self.request}
60
65
 
61
66
  result = self.panel.render_html(parent_context)
62
-
63
- self.assertIn(self.DATA_ATTRIBUTE_UPGRADE_CHECK, result)
64
- self.assertNotIn(self.DATA_ATTRIBUTE_UPGRADE_CHECK_LTS, result)
67
+ soup = self.get_soup(result)
68
+ controller = soup.select_one("[data-controller]")
69
+ self.assertIsNotNone(controller)
70
+ self.assertEqual(
71
+ set(controller["data-controller"].split()),
72
+ {"w-upgrade", "w-dismissible"},
73
+ )
74
+ self.assertFalse(controller.get(self.ATTR_UPGRADE_CHECK_LTS))
75
+ self.assertEqual(
76
+ controller.get(self.ATTR_DISMISSIBLE_ID),
77
+ self.DISMISSIBLE_ID,
78
+ )
79
+ toggle = soup.select_one("[data-action='w-dismissible#toggle']")
80
+ self.assertIsNotNone(toggle)
81
+ self.assertIsNone(toggle.get(self.ATTR_LAST_DISMISSED_VALUE))
65
82
 
66
83
  @override_settings(WAGTAIL_ENABLE_UPDATE_CHECK=False)
67
84
  def test_render_html_setting_false(self):
@@ -72,22 +89,58 @@ class TestUpgradeNotificationPanel(WagtailTestUtils, TestCase):
72
89
 
73
90
  self.assertEqual(result, "")
74
91
 
75
- @override_settings(WAGTAIL_ENABLE_UPDATE_CHECK="LTS")
76
- def test_render_html_setting_LTS(self):
92
+ def test_render_html_setting_lts(self):
77
93
  self.request.user = self.superuser
78
94
  parent_context = {"request": self.request}
79
-
80
- result = self.panel.render_html(parent_context)
81
-
82
- self.assertIn(self.DATA_ATTRIBUTE_UPGRADE_CHECK, result)
83
- self.assertIn(self.DATA_ATTRIBUTE_UPGRADE_CHECK_LTS, result)
84
-
85
- @override_settings(WAGTAIL_ENABLE_UPDATE_CHECK="lts")
86
- def test_render_html_setting_lts(self):
95
+ setting_values = ["lts", "LTS"]
96
+ for value in setting_values:
97
+ with self.subTest(setting=value):
98
+ with override_settings(WAGTAIL_ENABLE_UPDATE_CHECK=value):
99
+ result = self.panel.render_html(parent_context)
100
+
101
+ soup = self.get_soup(result)
102
+ controller = soup.select_one("[data-controller]")
103
+ self.assertIsNotNone(controller)
104
+ self.assertEqual(
105
+ set(controller["data-controller"].split()),
106
+ {"w-upgrade", "w-dismissible"},
107
+ )
108
+ self.assertEqual(
109
+ controller.get(self.ATTR_UPGRADE_CHECK_LTS),
110
+ "true",
111
+ )
112
+ self.assertEqual(
113
+ controller.get(self.ATTR_DISMISSIBLE_ID),
114
+ self.DISMISSIBLE_ID,
115
+ )
116
+ toggle = soup.select_one("[data-action='w-dismissible#toggle']")
117
+ self.assertIsNotNone(toggle)
118
+ self.assertIsNone(toggle.get(self.ATTR_LAST_DISMISSED_VALUE))
119
+
120
+ def test_render_html_dismissed_version(self):
121
+ profile = UserProfile.get_for_user(self.superuser)
122
+ profile.dismissibles.update({self.DISMISSIBLE_ID: "6.2.2"})
123
+ profile.save()
87
124
  self.request.user = self.superuser
88
125
  parent_context = {"request": self.request}
89
126
 
90
127
  result = self.panel.render_html(parent_context)
91
-
92
- self.assertIn(self.DATA_ATTRIBUTE_UPGRADE_CHECK, result)
93
- self.assertIn(self.DATA_ATTRIBUTE_UPGRADE_CHECK_LTS, result)
128
+ soup = self.get_soup(result)
129
+
130
+ controller = soup.select_one("[data-controller='w-upgrade w-dismissible']")
131
+ self.assertIsNotNone(controller)
132
+
133
+ self.assertEqual(
134
+ controller.get(self.ATTR_DISMISSIBLE_ID),
135
+ self.DISMISSIBLE_ID,
136
+ )
137
+ self.assertEqual(
138
+ controller.get(self.ATTR_CURRENT_VERSION),
139
+ __version__,
140
+ )
141
+ toggle = soup.select_one("[data-action='w-dismissible#toggle']")
142
+ self.assertIsNotNone(toggle)
143
+ self.assertEqual(
144
+ toggle.get(self.ATTR_LAST_DISMISSED_VALUE),
145
+ "6.2.2",
146
+ )
@@ -81,7 +81,7 @@ class TestLoginView(WagtailTestUtils, TestCase):
81
81
  response = self.client.get(reverse("wagtailadmin_login"))
82
82
  self.assertContains(
83
83
  response,
84
- '<html lang="de" dir="ltr" class="w-theme-system w-density-default">',
84
+ '<html lang="de" dir="ltr" class="w-theme-system w-density-default w-contrast-system">',
85
85
  )
86
86
 
87
87
  @override_settings(LANGUAGE_CODE="he")
@@ -89,7 +89,7 @@ class TestLoginView(WagtailTestUtils, TestCase):
89
89
  response = self.client.get(reverse("wagtailadmin_login"))
90
90
  self.assertContains(
91
91
  response,
92
- '<html lang="he" dir="rtl" class="w-theme-system w-density-default">',
92
+ '<html lang="he" dir="rtl" class="w-theme-system w-density-default w-contrast-system">',
93
93
  )
94
94
 
95
95
  @override_settings(
@@ -24,6 +24,19 @@ class TestGenericIndexView(WagtailTestUtils, TestCase):
24
24
  self.assertEqual(h1.text.strip(), "Model with string type primary keys")
25
25
 
26
26
 
27
+ class TestGenericIndexViewWithoutModel(WagtailTestUtils, TestCase):
28
+ fixtures = ["test.json"]
29
+
30
+ def get(self, params={}):
31
+ return self.client.get(reverse("testapp_generic_index_without_model"), params)
32
+
33
+ def test_non_integer_primary_key(self):
34
+ response = self.get()
35
+ self.assertEqual(response.status_code, 200)
36
+ response_object_count = response.context_data["object_list"].count()
37
+ self.assertEqual(response_object_count, 3)
38
+
39
+
27
40
  class TestGenericEditView(WagtailTestUtils, TestCase):
28
41
  fixtures = ["test.json"]
29
42
 
@@ -119,7 +119,7 @@ class TestAdminPageChooserWidget(TestCase):
119
119
  )
120
120
 
121
121
  html = widget.render("test", self.child_page, {"id": "test-id"})
122
- self.assertIn("Choose a page (Simple Page)", html)
122
+ self.assertIn("Choose a page (Simple page)", html)
123
123
 
124
124
  def test_render_with_target_model_as_single_instance(self):
125
125
  widget = widgets.AdminPageChooser(target_models=SimplePage)
@@ -131,7 +131,7 @@ class TestAdminPageChooserWidget(TestCase):
131
131
  )
132
132
 
133
133
  html = widget.render("test", self.child_page, {"id": "test-id"})
134
- self.assertIn("Choose a page (Simple Page)", html)
134
+ self.assertIn("Choose a page (Simple page)", html)
135
135
 
136
136
  def test_render_with_target_model_as_single_string(self):
137
137
  widget = widgets.AdminPageChooser(target_models="tests.SimplePage")
@@ -143,7 +143,7 @@ class TestAdminPageChooserWidget(TestCase):
143
143
  )
144
144
 
145
145
  html = widget.render("test", self.child_page, {"id": "test-id"})
146
- self.assertIn("Choose a page (Simple Page)", html)
146
+ self.assertIn("Choose a page (Simple page)", html)
147
147
 
148
148
  def test_render_with_multiple_target_models(self):
149
149
  target_models = [SimplePage, "tests.eventpage"]
@@ -43,6 +43,7 @@ from wagtail.signals import page_published, published
43
43
  from wagtail.test.testapp.models import (
44
44
  FullFeaturedSnippet,
45
45
  ModeratedModel,
46
+ MultiPreviewModesPage,
46
47
  SimplePage,
47
48
  SimpleTask,
48
49
  )
@@ -162,6 +163,33 @@ class TestWorkflowsIndexView(AdminTemplateTestUtils, WagtailTestUtils, TestCase)
162
163
  self.assertNotContains(response, "There are no enabled workflows.")
163
164
  self.assertContains(response, "test_workflow")
164
165
 
166
+ def test_multiple_snippets_assigned_to_workflow(self):
167
+ Workflow.objects.create(name="Nocontenttypes")
168
+ multi_ct_workflow = Workflow.objects.create(name="Multicontenttypes")
169
+ for model in [FullFeaturedSnippet, ModeratedModel]:
170
+ WorkflowContentType.objects.create(
171
+ workflow=multi_ct_workflow,
172
+ content_type=ContentType.objects.get_for_model(model),
173
+ )
174
+
175
+ response = self.get()
176
+ self.assertEqual(response.status_code, 200)
177
+ soup = self.get_soup(response.content)
178
+ cells = [
179
+ text
180
+ for td in soup.select("td")
181
+ if (text := td.get_text(separator=" | ", strip=True))
182
+ ]
183
+ self.assertEqual(
184
+ cells,
185
+ [
186
+ "Multicontenttypes",
187
+ "0 pages | 2 snippet types",
188
+ "Nocontenttypes",
189
+ "0 pages | 0 snippet types",
190
+ ],
191
+ )
192
+
165
193
  def test_num_queries(self):
166
194
  self.create_workflows()
167
195
  self.get()
@@ -290,7 +318,15 @@ class TestWorkflowsIndexView(AdminTemplateTestUtils, WagtailTestUtils, TestCase)
290
318
  self.assertContains(response, url + "?p=3")
291
319
 
292
320
  response = self.get({"p": 4})
293
- self.assertEqual(response.status_code, 404)
321
+ # Check response
322
+ self.assertEqual(response.status_code, 200)
323
+ self.assertTemplateUsed(response, "wagtailadmin/workflows/index.html")
324
+
325
+ # Check that we got the last page
326
+ self.assertEqual(
327
+ response.context["page_obj"].number,
328
+ response.context["paginator"].num_pages,
329
+ )
294
330
 
295
331
 
296
332
  class TestWorkflowPermissions(WagtailTestUtils, TestCase):
@@ -981,7 +1017,7 @@ class TestTaskIndexView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
981
1017
  self.assertEqual(response.status_code, 200)
982
1018
  self.assertTemplateUsed(response, "wagtailadmin/workflows/task_index.html")
983
1019
  self.assertBreadcrumbsItemsRendered(
984
- [{"url": "", "label": "Tasks"}],
1020
+ [{"url": "", "label": "Workflow tasks"}],
985
1021
  response.content,
986
1022
  )
987
1023
 
@@ -1199,7 +1235,15 @@ class TestTaskIndexView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
1199
1235
  self.assertContains(response, url + "?p=3")
1200
1236
 
1201
1237
  response = self.get({"p": 4})
1202
- self.assertEqual(response.status_code, 404)
1238
+ # Check response
1239
+ self.assertEqual(response.status_code, 200)
1240
+ self.assertTemplateUsed(response, "wagtailadmin/workflows/task_index.html")
1241
+
1242
+ # Check that we got the last page
1243
+ self.assertEqual(
1244
+ response.context["page_obj"].number,
1245
+ response.context["paginator"].num_pages,
1246
+ )
1203
1247
 
1204
1248
  def test_num_queries(self):
1205
1249
  workflows = [Workflow.objects.create(name=f"workflow_{i}") for i in range(7)]
@@ -1877,7 +1921,7 @@ class TestSubmitPageToWorkflow(BasePageWorkflowTests):
1877
1921
  self.assertNotContains(response, "Request changes")
1878
1922
  self.assertNotContains(
1879
1923
  response,
1880
- '<button type="submit" class="button action-save " disabled>',
1924
+ '<button type="submit" class="button action-save" disabled>',
1881
1925
  )
1882
1926
 
1883
1927
  # submit for approval
@@ -1893,7 +1937,7 @@ class TestSubmitPageToWorkflow(BasePageWorkflowTests):
1893
1937
  self.assertNotContains(response, "Request changes")
1894
1938
  self.assertContains(
1895
1939
  response,
1896
- '<button type="submit" class="button action-save " disabled>',
1940
+ '<button type="submit" class="button action-save" disabled>',
1897
1941
  )
1898
1942
 
1899
1943
  # After submit, as a moderator, should only see save, approve, and reject buttons
@@ -1907,7 +1951,7 @@ class TestSubmitPageToWorkflow(BasePageWorkflowTests):
1907
1951
  self.assertContains(response, "Request changes")
1908
1952
  self.assertNotContains(
1909
1953
  response,
1910
- '<button type="submit" class="button action-save " disabled>',
1954
+ '<button type="submit" class="button action-save" disabled>',
1911
1955
  )
1912
1956
 
1913
1957
  self.reject()
@@ -1923,7 +1967,7 @@ class TestSubmitPageToWorkflow(BasePageWorkflowTests):
1923
1967
  self.assertNotContains(response, "Request changes")
1924
1968
  self.assertNotContains(
1925
1969
  response,
1926
- '<button type="submit" class="button action-save " disabled>',
1970
+ '<button type="submit" class="button action-save" disabled>',
1927
1971
  )
1928
1972
 
1929
1973
  # After cancel, as a submitter, should only see save and submit buttons
@@ -1936,7 +1980,7 @@ class TestSubmitPageToWorkflow(BasePageWorkflowTests):
1936
1980
  self.assertNotContains(response, "Request changes")
1937
1981
  self.assertNotContains(
1938
1982
  response,
1939
- '<button type="submit" class="button action-save " disabled>',
1983
+ '<button type="submit" class="button action-save" disabled>',
1940
1984
  )
1941
1985
 
1942
1986
  def test_workflow_action_menu_items_when_reverting(self):
@@ -1956,7 +2000,7 @@ class TestSubmitPageToWorkflow(BasePageWorkflowTests):
1956
2000
  self.assertNotContains(response, "Request changes")
1957
2001
  self.assertNotContains(
1958
2002
  response,
1959
- '<button type="submit" class="button action-save warning" disabled>',
2003
+ '<button type="submit" class="button action-save" disabled>',
1960
2004
  )
1961
2005
 
1962
2006
  # submit for approval
@@ -1972,7 +2016,7 @@ class TestSubmitPageToWorkflow(BasePageWorkflowTests):
1972
2016
  self.assertNotContains(response, "Request changes")
1973
2017
  self.assertContains(
1974
2018
  response,
1975
- '<button type="submit" class="button action-save warning" disabled>',
2019
+ '<button type="submit" class="button action-save" disabled>',
1976
2020
  )
1977
2021
 
1978
2022
  # After submit, as a moderator, should only see save button
@@ -1986,7 +2030,7 @@ class TestSubmitPageToWorkflow(BasePageWorkflowTests):
1986
2030
  self.assertNotContains(response, "Request changes")
1987
2031
  self.assertNotContains(
1988
2032
  response,
1989
- '<button type="submit" class="button action-save warning" disabled>',
2033
+ '<button type="submit" class="button action-save" disabled>',
1990
2034
  )
1991
2035
 
1992
2036
  self.reject()
@@ -2002,7 +2046,7 @@ class TestSubmitPageToWorkflow(BasePageWorkflowTests):
2002
2046
  self.assertNotContains(response, "Request changes")
2003
2047
  self.assertNotContains(
2004
2048
  response,
2005
- '<button type="submit" class="button action-save warning" disabled>',
2049
+ '<button type="submit" class="button action-save" disabled>',
2006
2050
  )
2007
2051
 
2008
2052
  # After cancel, as a submitter, should only see save button
@@ -2016,7 +2060,7 @@ class TestSubmitPageToWorkflow(BasePageWorkflowTests):
2016
2060
  self.assertNotContains(response, "Request changes")
2017
2061
  self.assertNotContains(
2018
2062
  response,
2019
- '<button type="submit" class="button action-save warning" disabled>',
2063
+ '<button type="submit" class="button action-save" disabled>',
2020
2064
  )
2021
2065
 
2022
2066
  @override_settings(WAGTAILADMIN_BASE_URL="http://admin.example.com")
@@ -2163,7 +2207,7 @@ class TestSubmitPageToWorkflow(BasePageWorkflowTests):
2163
2207
 
2164
2208
  self.assertNotContains(
2165
2209
  response,
2166
- '<button type="submit" class="button action-save " disabled>',
2210
+ '<button type="submit" class="button action-save" disabled>',
2167
2211
  )
2168
2212
  self.assertNotContains(
2169
2213
  response,
@@ -2228,7 +2272,7 @@ class TestSubmitSnippetToWorkflowNotLockable(TestSubmitSnippetToWorkflow):
2228
2272
  self.assertNotContains(response, "Request changes")
2229
2273
  self.assertNotContains(
2230
2274
  response,
2231
- '<button type="submit" class="button action-save warning" disabled>',
2275
+ '<button type="submit" class="button action-save" disabled>',
2232
2276
  )
2233
2277
 
2234
2278
  # submit for approval
@@ -2245,7 +2289,7 @@ class TestSubmitSnippetToWorkflowNotLockable(TestSubmitSnippetToWorkflow):
2245
2289
  self.assertNotContains(response, "Request changes")
2246
2290
  self.assertNotContains(
2247
2291
  response,
2248
- '<button type="submit" class="button action-save warning" disabled>',
2292
+ '<button type="submit" class="button action-save" disabled>',
2249
2293
  )
2250
2294
 
2251
2295
  # After submit, as a moderator, should only see save, approve, and reject buttons
@@ -2259,7 +2303,7 @@ class TestSubmitSnippetToWorkflowNotLockable(TestSubmitSnippetToWorkflow):
2259
2303
  self.assertContains(response, "Request changes")
2260
2304
  self.assertNotContains(
2261
2305
  response,
2262
- '<button type="submit" class="button action-save warning" disabled>',
2306
+ '<button type="submit" class="button action-save" disabled>',
2263
2307
  )
2264
2308
 
2265
2309
  self.reject()
@@ -2275,7 +2319,7 @@ class TestSubmitSnippetToWorkflowNotLockable(TestSubmitSnippetToWorkflow):
2275
2319
  self.assertNotContains(response, "Request changes")
2276
2320
  self.assertNotContains(
2277
2321
  response,
2278
- '<button type="submit" class="button action-save warning" disabled>',
2322
+ '<button type="submit" class="button action-save" disabled>',
2279
2323
  )
2280
2324
 
2281
2325
  def test_workflow_action_menu_items_when_reverting(self):
@@ -2295,7 +2339,7 @@ class TestSubmitSnippetToWorkflowNotLockable(TestSubmitSnippetToWorkflow):
2295
2339
  self.assertNotContains(response, "Request changes")
2296
2340
  self.assertNotContains(
2297
2341
  response,
2298
- '<button type="submit" class="button action-save warning" disabled>',
2342
+ '<button type="submit" class="button action-save" disabled>',
2299
2343
  )
2300
2344
 
2301
2345
  # submit for approval
@@ -2312,7 +2356,7 @@ class TestSubmitSnippetToWorkflowNotLockable(TestSubmitSnippetToWorkflow):
2312
2356
  self.assertNotContains(response, "Request changes")
2313
2357
  self.assertNotContains(
2314
2358
  response,
2315
- '<button type="submit" class="button action-save warning" disabled>',
2359
+ '<button type="submit" class="button action-save" disabled>',
2316
2360
  )
2317
2361
 
2318
2362
  # After submit, as a moderator, should only see save button
@@ -2326,7 +2370,7 @@ class TestSubmitSnippetToWorkflowNotLockable(TestSubmitSnippetToWorkflow):
2326
2370
  self.assertNotContains(response, "Request changes")
2327
2371
  self.assertNotContains(
2328
2372
  response,
2329
- '<button type="submit" class="button action-save warning" disabled>',
2373
+ '<button type="submit" class="button action-save" disabled>',
2330
2374
  )
2331
2375
 
2332
2376
  self.reject()
@@ -2342,7 +2386,7 @@ class TestSubmitSnippetToWorkflowNotLockable(TestSubmitSnippetToWorkflow):
2342
2386
  self.assertNotContains(response, "Request changes")
2343
2387
  self.assertNotContains(
2344
2388
  response,
2345
- '<button type="submit" class="button action-save warning" disabled>',
2389
+ '<button type="submit" class="button action-save" disabled>',
2346
2390
  )
2347
2391
 
2348
2392
  def test_submit_for_approval_changes_lock_status(self):
@@ -4117,12 +4161,15 @@ class TestTaskChooserChosenView(WagtailTestUtils, TestCase):
4117
4161
 
4118
4162
  class TestWorkflowUsageView(WagtailTestUtils, TestCase):
4119
4163
  def setUp(self):
4120
- self.login()
4164
+ self.user = self.login()
4121
4165
  self.workflow = Workflow.objects.get()
4122
4166
 
4123
4167
  self.root_page = Page.objects.get(depth=1)
4124
4168
  self.home_page = Page.objects.get(depth=2)
4125
4169
 
4170
+ self.child_page_with_default_workflow = self.home_page.add_child(
4171
+ instance=SimplePage(title="A page", content="I'm a page")
4172
+ )
4126
4173
  self.child_page_with_another_workflow = self.home_page.add_child(
4127
4174
  instance=SimplePage(title="Another page", content="I'm another page")
4128
4175
  )
@@ -4137,11 +4184,109 @@ class TestWorkflowUsageView(WagtailTestUtils, TestCase):
4137
4184
  )
4138
4185
 
4139
4186
  self.assertEqual(response.status_code, 200)
4187
+ self.assertTemplateUsed(response, "wagtailadmin/pages/listing.html")
4188
+
4189
+ object_set = {page.id for page in response.context["object_list"]}
4190
+ # Should not contain child_page_with_another_workflow. It should also
4191
+ # not contain the root page, as it's irrelevant (you'll never be able to
4192
+ # edit and submit it to the workflow)
4193
+ self.assertEqual(
4194
+ object_set,
4195
+ {self.home_page.id, self.child_page_with_default_workflow.id},
4196
+ )
4197
+
4198
+ def test_with_no_permission(self):
4199
+ group = Group.objects.create(name="test group")
4200
+ self.user.is_superuser = False
4201
+ self.user.save()
4202
+ self.user.groups.add(group)
4203
+ group.permissions.add(
4204
+ Permission.objects.get(
4205
+ content_type__app_label="wagtailadmin", codename="access_admin"
4206
+ )
4207
+ )
4208
+ # No GroupPagePermission created
4209
+
4210
+ response = self.client.get(
4211
+ reverse("wagtailadmin_workflows:usage", args=[self.workflow.id])
4212
+ )
4213
+ self.assertEqual(response.status_code, 302)
4214
+ self.assertRedirects(response, reverse("wagtailadmin_home"))
4215
+
4216
+ # Only a page permission is created, but no workflow permission, not enough
4217
+ permission = GroupPagePermission.objects.create(
4218
+ group=group,
4219
+ page=Page.objects.first(),
4220
+ permission_type="change",
4221
+ )
4222
+
4223
+ response = self.client.get(
4224
+ reverse("wagtailadmin_workflows:usage", args=[self.workflow.id])
4225
+ )
4226
+ self.assertEqual(response.status_code, 302)
4227
+ self.assertRedirects(response, reverse("wagtailadmin_home"))
4228
+
4229
+ # Delete page permission and add workflow permission, also not enough
4230
+ permission.delete()
4231
+ group.permissions.add(
4232
+ Permission.objects.get(
4233
+ content_type__app_label="wagtailcore", codename="change_workflow"
4234
+ )
4235
+ )
4236
+
4237
+ response = self.client.get(
4238
+ reverse("wagtailadmin_workflows:usage", args=[self.workflow.id])
4239
+ )
4240
+ self.assertEqual(response.status_code, 302)
4241
+ self.assertRedirects(response, reverse("wagtailadmin_home"))
4242
+
4243
+ def test_with_minimal_permissions(self):
4244
+ group = Group.objects.create(name="test group")
4245
+ self.user.is_superuser = False
4246
+ self.user.save()
4247
+ self.user.groups.add(group)
4248
+ group.permissions.add(
4249
+ Permission.objects.get(
4250
+ content_type__app_label="wagtailadmin", codename="access_admin"
4251
+ ),
4252
+ Permission.objects.get(
4253
+ content_type__app_label="wagtailcore", codename="change_workflow"
4254
+ ),
4255
+ )
4256
+ GroupPagePermission.objects.create(
4257
+ group=group,
4258
+ page=Page.objects.first(),
4259
+ permission_type="change",
4260
+ )
4261
+
4262
+ # With a workflow permission and a page permission, the user should be
4263
+ # able to access the view
4264
+ response = self.client.get(
4265
+ reverse("wagtailadmin_workflows:usage", args=[self.workflow.id])
4266
+ )
4267
+
4268
+ self.assertEqual(response.status_code, 200)
4269
+
4270
+ def test_get_search_and_filtered_results(self):
4271
+ page_1 = SimplePage(title="Hello wagtail", content="test")
4272
+ page_2 = SimplePage(title="Hello django", content="test")
4273
+ self.home_page.add_child(instance=page_1)
4274
+ self.home_page.add_child(instance=page_2)
4275
+ self.home_page.add_child(instance=MultiPreviewModesPage(title="Hello python"))
4276
+
4277
+ response = self.client.get(
4278
+ reverse("wagtailadmin_workflows:usage_results", args=[self.workflow.id]),
4279
+ {
4280
+ "content_type": ContentType.objects.get_for_model(SimplePage).id,
4281
+ "q": "hello",
4282
+ },
4283
+ )
4284
+
4285
+ self.assertEqual(response.status_code, 200)
4286
+ self.assertTemplateUsed(response, "wagtailadmin/generic/listing_results.html")
4140
4287
 
4141
- object_set = {page.id for page in response.context["used_by"].object_list}
4142
- self.assertIn(self.root_page.id, object_set)
4143
- self.assertIn(self.home_page.id, object_set)
4144
- self.assertNotIn(self.child_page_with_another_workflow.id, object_set)
4288
+ object_set = {page.id for page in response.context["object_list"]}
4289
+ self.assertEqual(object_set, {page_1.id, page_2.id})
4145
4290
 
4146
4291
 
4147
4292
  @freeze_time("2020-06-01 12:00:00")
@@ -29,7 +29,7 @@ class TestHome(WagtailTestUtils, TestCase):
29
29
  def test_simple(self):
30
30
  response = self.client.get(reverse("wagtailadmin_home"))
31
31
  self.assertEqual(response.status_code, 200)
32
- self.assertContains(response, "Welcome to the Test Site Wagtail CMS")
32
+ self.assertContains(response, "Test Site")
33
33
 
34
34
  def test_admin_menu(self):
35
35
  response = self.client.get(reverse("wagtailadmin_home"))