wagtail 7.2.1__py3-none-any.whl → 7.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 (312) hide show
  1. wagtail/__init__.py +1 -1
  2. wagtail/actions/copy_for_translation.py +4 -2
  3. wagtail/admin/action_menu.py +4 -1
  4. wagtail/admin/api/actions/convert_alias.py +2 -2
  5. wagtail/admin/api/actions/copy.py +2 -2
  6. wagtail/admin/api/actions/copy_for_translation.py +2 -2
  7. wagtail/admin/api/actions/create_alias.py +2 -2
  8. wagtail/admin/api/actions/delete.py +1 -1
  9. wagtail/admin/api/actions/move.py +1 -1
  10. wagtail/admin/api/actions/publish.py +2 -2
  11. wagtail/admin/api/actions/revert_to_page_revision.py +2 -2
  12. wagtail/admin/api/actions/unpublish.py +1 -1
  13. wagtail/admin/api/filters.py +2 -2
  14. wagtail/admin/compare.py +22 -0
  15. wagtail/admin/forms/account.py +52 -1
  16. wagtail/admin/forms/comments.py +53 -0
  17. wagtail/admin/forms/models.py +36 -0
  18. wagtail/admin/forms/pages.py +7 -0
  19. wagtail/admin/forms/workflows.py +5 -2
  20. wagtail/admin/icons.py +4 -3
  21. wagtail/admin/locale/ar/LC_MESSAGES/django.mo +0 -0
  22. wagtail/admin/locale/ar/LC_MESSAGES/django.po +35 -0
  23. wagtail/admin/locale/en/LC_MESSAGES/django.po +262 -234
  24. wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +72 -43
  25. wagtail/admin/locale/it/LC_MESSAGES/django.mo +0 -0
  26. wagtail/admin/locale/it/LC_MESSAGES/django.po +566 -6
  27. wagtail/admin/locale/it/LC_MESSAGES/djangojs.mo +0 -0
  28. wagtail/admin/locale/it/LC_MESSAGES/djangojs.po +40 -2
  29. wagtail/admin/locale/nl/LC_MESSAGES/django.mo +0 -0
  30. wagtail/admin/locale/nl/LC_MESSAGES/django.po +2 -2
  31. wagtail/admin/locale/sv/LC_MESSAGES/django.mo +0 -0
  32. wagtail/admin/locale/sv/LC_MESSAGES/django.po +330 -15
  33. wagtail/admin/locale/sv/LC_MESSAGES/djangojs.mo +0 -0
  34. wagtail/admin/locale/sv/LC_MESSAGES/djangojs.po +3 -2
  35. wagtail/admin/panels/comment_panel.py +1 -51
  36. wagtail/admin/panels/title_field_panel.py +3 -1
  37. wagtail/admin/static/wagtailadmin/css/core.css +1 -1
  38. wagtail/admin/static/wagtailadmin/js/bulk-actions.js +1 -1
  39. wagtail/admin/static/wagtailadmin/js/comments.js +1 -1
  40. wagtail/admin/static/wagtailadmin/js/core.js +1 -1
  41. wagtail/admin/static/wagtailadmin/js/core.js.LICENSE.txt +1 -1
  42. wagtail/admin/static/wagtailadmin/js/draftail.js +1 -1
  43. wagtail/admin/static/wagtailadmin/js/privacy-switch.js +1 -1
  44. wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
  45. wagtail/admin/static/wagtailadmin/js/telepath/blocks.js +1 -1
  46. wagtail/admin/static/wagtailadmin/js/userbar.js +1 -1
  47. wagtail/admin/static/wagtailadmin/js/userbar.js.LICENSE.txt +1 -1
  48. wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
  49. wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
  50. wagtail/admin/templates/wagtailadmin/base.html +1 -1
  51. wagtail/admin/templates/wagtailadmin/generic/edit_partials.html +100 -0
  52. wagtail/admin/templates/wagtailadmin/generic/form.html +26 -5
  53. wagtail/admin/templates/wagtailadmin/generic/includes/_loaded_revision_inputs.html +3 -0
  54. wagtail/admin/templates/wagtailadmin/generic/listing_results.html +1 -17
  55. wagtail/admin/templates/wagtailadmin/pages/create.html +14 -4
  56. wagtail/admin/templates/wagtailadmin/pages/edit.html +16 -3
  57. wagtail/admin/templates/wagtailadmin/pages/edit_partials.html +31 -0
  58. wagtail/admin/templates/wagtailadmin/pages/index_results.html +1 -9
  59. wagtail/admin/templates/wagtailadmin/shared/autosave/indicator.html +36 -0
  60. wagtail/admin/templates/wagtailadmin/shared/breadcrumbs.html +1 -1
  61. wagtail/admin/templates/wagtailadmin/shared/editing_sessions/list.html +2 -2
  62. wagtail/admin/templates/wagtailadmin/shared/editing_sessions/module.html +19 -3
  63. wagtail/admin/templates/wagtailadmin/shared/headers/_actions.html +5 -0
  64. wagtail/admin/templates/wagtailadmin/shared/headers/_history_icon_link.html +2 -2
  65. wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html +8 -9
  66. wagtail/admin/templates/wagtailadmin/shared/listing/filter_partials.html +19 -0
  67. wagtail/admin/templates/wagtailadmin/shared/side_panel_toggle.html +3 -3
  68. wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/side_panel.html +3 -0
  69. wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/status/privacy.html +18 -6
  70. wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/status/usage.html +11 -4
  71. wagtail/admin/templates/wagtailadmin/shared/side_panels/includes/status/workflow.html +22 -1
  72. wagtail/admin/templates/wagtailadmin/shared/side_panels/preview.html +1 -0
  73. wagtail/admin/templates/wagtailadmin/shared/side_panels.html +1 -2
  74. wagtail/admin/templates/wagtailadmin/shared/unsaved_changes_warning.html +20 -20
  75. wagtail/admin/templates/wagtailadmin/userbar/base.html +2 -0
  76. wagtail/admin/templates/wagtailadmin/userbar/item_accessibility.html +1 -1
  77. wagtail/admin/templatetags/wagtailadmin_tags.py +6 -14
  78. wagtail/admin/tests/pages/test_create_page.py +298 -1
  79. wagtail/admin/tests/pages/test_custom_listing.py +48 -2
  80. wagtail/admin/tests/pages/test_edit_page.py +721 -7
  81. wagtail/admin/tests/pages/test_explorer_view.py +9 -5
  82. wagtail/admin/tests/pages/test_page_search.py +15 -0
  83. wagtail/admin/tests/pages/test_revisions.py +4 -0
  84. wagtail/admin/tests/test_account_management.py +88 -2
  85. wagtail/admin/tests/test_collections_views.py +15 -15
  86. wagtail/admin/tests/test_compare.py +34 -0
  87. wagtail/admin/tests/test_editing_sessions.py +230 -8
  88. wagtail/admin/tests/test_forms.py +192 -1
  89. wagtail/admin/tests/test_icon_sprite.py +22 -2
  90. wagtail/admin/tests/test_page_chooser.py +13 -13
  91. wagtail/admin/tests/test_reports_views.py +4 -1
  92. wagtail/admin/tests/test_userbar.py +69 -5
  93. wagtail/admin/tests/test_views_generic.py +5 -5
  94. wagtail/admin/tests/test_workflows.py +14 -12
  95. wagtail/admin/tests/viewsets/test_model_viewset.py +13 -0
  96. wagtail/admin/ui/autosave.py +5 -0
  97. wagtail/admin/ui/editing_sessions.py +3 -0
  98. wagtail/admin/ui/side_panels.py +19 -20
  99. wagtail/admin/userbar.py +48 -27
  100. wagtail/admin/views/bulk_action/dispatcher.py +2 -2
  101. wagtail/admin/views/chooser.py +6 -6
  102. wagtail/admin/views/editing_sessions.py +20 -7
  103. wagtail/admin/views/generic/__init__.py +1 -0
  104. wagtail/admin/views/generic/chooser.py +5 -5
  105. wagtail/admin/views/generic/mixins.py +143 -26
  106. wagtail/admin/views/generic/models.py +157 -27
  107. wagtail/admin/views/generic/ordering.py +1 -1
  108. wagtail/admin/views/generic/preview.py +4 -4
  109. wagtail/admin/views/home.py +3 -1
  110. wagtail/admin/views/pages/create.py +77 -29
  111. wagtail/admin/views/pages/edit.py +160 -34
  112. wagtail/admin/views/pages/preview.py +4 -4
  113. wagtail/admin/views/pages/revisions.py +3 -0
  114. wagtail/admin/views/pages/search.py +4 -4
  115. wagtail/admin/views/pages/usage.py +2 -2
  116. wagtail/admin/views/tags.py +2 -2
  117. wagtail/admin/views/workflows.py +73 -54
  118. wagtail/admin/viewsets/model.py +34 -8
  119. wagtail/admin/widgets/button.py +11 -4
  120. wagtail/admin/widgets/chooser.py +6 -4
  121. wagtail/admin/widgets/slug.py +1 -1
  122. wagtail/api/v2/filters.py +27 -21
  123. wagtail/api/v2/pagination.py +4 -4
  124. wagtail/api/v2/views.py +7 -7
  125. wagtail/blocks/list_block.py +0 -8
  126. wagtail/blocks/migrations/migrate_operation.py +8 -1
  127. wagtail/blocks/stream_block.py +2 -10
  128. wagtail/blocks/struct_block.py +192 -12
  129. wagtail/compat.py +2 -2
  130. wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +1 -1
  131. wagtail/contrib/forms/locale/it/LC_MESSAGES/django.mo +0 -0
  132. wagtail/contrib/forms/locale/it/LC_MESSAGES/django.po +40 -2
  133. wagtail/contrib/frontend_cache/backends/azure.py +6 -6
  134. wagtail/contrib/frontend_cache/backends/cloudfront.py +2 -2
  135. wagtail/contrib/frontend_cache/utils.py +1 -1
  136. wagtail/contrib/redirects/forms.py +1 -1
  137. wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +14 -14
  138. wagtail/contrib/redirects/locale/it/LC_MESSAGES/django.mo +0 -0
  139. wagtail/contrib/redirects/locale/it/LC_MESSAGES/django.po +15 -2
  140. wagtail/contrib/redirects/locale/sv/LC_MESSAGES/django.mo +0 -0
  141. wagtail/contrib/redirects/locale/sv/LC_MESSAGES/django.po +16 -3
  142. wagtail/contrib/redirects/middleware.py +11 -7
  143. wagtail/contrib/redirects/models.py +17 -1
  144. wagtail/contrib/redirects/tests/test_import_admin_views.py +3 -3
  145. wagtail/contrib/redirects/tests/test_redirects.py +56 -8
  146. wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +6 -6
  147. wagtail/contrib/search_promotions/locale/it/LC_MESSAGES/django.mo +0 -0
  148. wagtail/contrib/search_promotions/locale/it/LC_MESSAGES/django.po +43 -2
  149. wagtail/contrib/search_promotions/tests.py +1 -1
  150. wagtail/contrib/search_promotions/views/settings.py +24 -25
  151. wagtail/contrib/settings/jinja2tags.py +2 -2
  152. wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +2 -2
  153. wagtail/contrib/settings/locale/it/LC_MESSAGES/django.mo +0 -0
  154. wagtail/contrib/settings/locale/it/LC_MESSAGES/django.po +6 -2
  155. wagtail/contrib/settings/locale/sv/LC_MESSAGES/django.mo +0 -0
  156. wagtail/contrib/settings/locale/sv/LC_MESSAGES/django.po +3 -2
  157. wagtail/contrib/settings/tests/generic/test_admin.py +118 -2
  158. wagtail/contrib/settings/tests/site_specific/test_admin.py +78 -15
  159. wagtail/contrib/settings/tests/site_specific/test_model.py +2 -2
  160. wagtail/contrib/settings/views.py +7 -0
  161. wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +1 -1
  162. wagtail/contrib/simple_translation/locale/it/LC_MESSAGES/django.mo +0 -0
  163. wagtail/contrib/simple_translation/locale/it/LC_MESSAGES/django.po +5 -2
  164. wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +7 -7
  165. wagtail/contrib/styleguide/tests.py +2 -0
  166. wagtail/contrib/styleguide/views.py +4 -5
  167. wagtail/contrib/table_block/locale/ar/LC_MESSAGES/django.mo +0 -0
  168. wagtail/contrib/table_block/locale/ar/LC_MESSAGES/django.po +5 -1
  169. wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +1 -1
  170. wagtail/contrib/table_block/locale/it/LC_MESSAGES/django.mo +0 -0
  171. wagtail/contrib/table_block/locale/it/LC_MESSAGES/django.po +5 -2
  172. wagtail/contrib/typed_table_block/blocks.py +37 -0
  173. wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +10 -10
  174. wagtail/contrib/typed_table_block/locale/sv/LC_MESSAGES/django.mo +0 -0
  175. wagtail/contrib/typed_table_block/locale/sv/LC_MESSAGES/django.po +4 -3
  176. wagtail/contrib/typed_table_block/tests.py +108 -0
  177. wagtail/coreutils.py +4 -4
  178. wagtail/documents/__init__.py +4 -4
  179. wagtail/documents/locale/en/LC_MESSAGES/django.po +15 -15
  180. wagtail/documents/locale/it/LC_MESSAGES/django.mo +0 -0
  181. wagtail/documents/locale/it/LC_MESSAGES/django.po +32 -2
  182. wagtail/documents/locale/sv/LC_MESSAGES/django.mo +0 -0
  183. wagtail/documents/locale/sv/LC_MESSAGES/django.po +32 -4
  184. wagtail/documents/models.py +1 -1
  185. wagtail/documents/tests/test_admin_views.py +19 -4
  186. wagtail/documents/tests/test_search.py +0 -2
  187. wagtail/documents/tests/test_views.py +6 -4
  188. wagtail/documents/views/bulk_actions/add_tags.py +1 -1
  189. wagtail/embeds/finders/facebook.py +3 -3
  190. wagtail/embeds/finders/instagram.py +3 -3
  191. wagtail/embeds/finders/oembed.py +7 -2
  192. wagtail/embeds/locale/en/LC_MESSAGES/django.po +1 -1
  193. wagtail/embeds/oembed_providers.py +8 -0
  194. wagtail/embeds/tests/test_embeds.py +35 -0
  195. wagtail/images/__init__.py +4 -4
  196. wagtail/images/admin_urls.py +3 -3
  197. wagtail/images/blocks.py +1 -1
  198. wagtail/images/formats.py +2 -2
  199. wagtail/images/image_operations.py +2 -2
  200. wagtail/images/locale/en/LC_MESSAGES/django.po +44 -40
  201. wagtail/images/locale/it/LC_MESSAGES/django.mo +0 -0
  202. wagtail/images/locale/it/LC_MESSAGES/django.po +50 -4
  203. wagtail/images/locale/nl/LC_MESSAGES/django.mo +0 -0
  204. wagtail/images/locale/nl/LC_MESSAGES/django.po +3 -3
  205. wagtail/images/locale/sv/LC_MESSAGES/django.mo +0 -0
  206. wagtail/images/locale/sv/LC_MESSAGES/django.po +49 -6
  207. wagtail/images/models.py +11 -10
  208. wagtail/images/templates/wagtailimages/images/index_results.html +1 -1
  209. wagtail/images/templates/wagtailimages/images/url_generator.html +17 -38
  210. wagtail/images/templates/wagtailimages/images/url_generator_output.html +28 -0
  211. wagtail/images/templatetags/wagtailimages_tags.py +4 -4
  212. wagtail/images/tests/test_admin_views.py +432 -59
  213. wagtail/images/tests/test_image_operations.py +2 -2
  214. wagtail/images/tests/test_models.py +0 -2
  215. wagtail/images/views/bulk_actions/add_tags.py +1 -1
  216. wagtail/images/views/images.py +72 -39
  217. wagtail/locale/en/LC_MESSAGES/django.po +103 -105
  218. wagtail/locale/it/LC_MESSAGES/django.mo +0 -0
  219. wagtail/locale/it/LC_MESSAGES/django.po +105 -2
  220. wagtail/locale/sv/LC_MESSAGES/django.mo +0 -0
  221. wagtail/locale/sv/LC_MESSAGES/django.po +95 -12
  222. wagtail/locales/locale/en/LC_MESSAGES/django.po +1 -1
  223. wagtail/locales/locale/it/LC_MESSAGES/django.mo +0 -0
  224. wagtail/locales/locale/it/LC_MESSAGES/django.po +13 -2
  225. wagtail/locales/locale/sv/LC_MESSAGES/django.mo +0 -0
  226. wagtail/locales/locale/sv/LC_MESSAGES/django.po +4 -3
  227. wagtail/locales/tests.py +5 -5
  228. wagtail/models/i18n.py +4 -6
  229. wagtail/models/media.py +18 -0
  230. wagtail/models/pages.py +65 -11
  231. wagtail/models/reference_index.py +15 -0
  232. wagtail/models/revisions.py +40 -12
  233. wagtail/models/workflows.py +0 -3
  234. wagtail/permission_policies/base.py +2 -2
  235. wagtail/permission_policies/collections.py +2 -2
  236. wagtail/project_template/requirements.txt +2 -2
  237. wagtail/search/locale/en/LC_MESSAGES/django.po +1 -1
  238. wagtail/signal_handlers.py +1 -0
  239. wagtail/sites/locale/en/LC_MESSAGES/django.po +1 -1
  240. wagtail/sites/locale/sv/LC_MESSAGES/django.mo +0 -0
  241. wagtail/sites/locale/sv/LC_MESSAGES/django.po +3 -2
  242. wagtail/sites/tests.py +7 -7
  243. wagtail/snippets/action_menu.py +2 -1
  244. wagtail/snippets/locale/en/LC_MESSAGES/django.po +23 -13
  245. wagtail/snippets/locale/sv/LC_MESSAGES/django.mo +0 -0
  246. wagtail/snippets/locale/sv/LC_MESSAGES/django.po +12 -1
  247. wagtail/snippets/tests/test_chooser_block.py +197 -0
  248. wagtail/snippets/tests/test_chooser_panel.py +149 -0
  249. wagtail/snippets/tests/test_chooser_views.py +375 -0
  250. wagtail/snippets/tests/test_chooser_widget.py +22 -0
  251. wagtail/snippets/tests/test_compare_revisions_view.py +167 -0
  252. wagtail/snippets/tests/test_copy_view.py +38 -0
  253. wagtail/snippets/tests/test_create_view.py +1159 -0
  254. wagtail/snippets/tests/test_delete_view.py +225 -0
  255. wagtail/snippets/tests/test_edit_view.py +2882 -0
  256. wagtail/snippets/tests/test_history_view.py +182 -0
  257. wagtail/snippets/tests/test_index_view.py +105 -0
  258. wagtail/snippets/tests/test_list_view.py +786 -0
  259. wagtail/snippets/tests/test_locking.py +28 -0
  260. wagtail/snippets/tests/test_permissions.py +167 -0
  261. wagtail/snippets/tests/test_preview.py +3 -3
  262. wagtail/snippets/tests/test_revert_view.py +343 -0
  263. wagtail/snippets/tests/test_snippet_models.py +112 -0
  264. wagtail/snippets/tests/test_unpublish_view.py +228 -0
  265. wagtail/snippets/tests/test_unschedule_view.py +151 -0
  266. wagtail/snippets/tests/test_viewset.py +38 -5
  267. wagtail/snippets/views/snippets.py +78 -30
  268. wagtail/snippets/widgets.py +2 -2
  269. wagtail/templatetags/wagtailcore_tags.py +2 -2
  270. wagtail/test/dummy_external_storage.py +1 -1
  271. wagtail/test/testapp/fixtures/test.json +22 -0
  272. wagtail/test/testapp/fixtures/test_empty.json +2 -0
  273. wagtail/test/testapp/fixtures/test_explorable_pages.json +10 -0
  274. wagtail/test/testapp/fixtures/test_specific.json +9 -0
  275. wagtail/test/testapp/migrations/0059_nopromotepage.py +25 -0
  276. wagtail/test/testapp/models.py +7 -0
  277. wagtail/test/testapp/views.py +5 -0
  278. wagtail/test/utils/page_tests.py +7 -7
  279. wagtail/test/utils/wagtail_factories/builder.py +2 -2
  280. wagtail/tests/streamfield_migrations/test_migrations.py +35 -0
  281. wagtail/tests/test_blocks.py +321 -61
  282. wagtail/tests/test_collection_model.py +12 -0
  283. wagtail/tests/test_page_model.py +190 -1
  284. wagtail/tests/test_page_privacy.py +5 -0
  285. wagtail/tests/test_reference_index.py +42 -0
  286. wagtail/tests/test_revision_model.py +118 -1
  287. wagtail/tests/test_utils.py +2 -2
  288. wagtail/users/locale/en/LC_MESSAGES/django.po +14 -14
  289. wagtail/users/locale/id_ID/LC_MESSAGES/django.mo +0 -0
  290. wagtail/users/locale/id_ID/LC_MESSAGES/django.po +6 -2
  291. wagtail/users/locale/it/LC_MESSAGES/django.mo +0 -0
  292. wagtail/users/locale/it/LC_MESSAGES/django.po +14 -2
  293. wagtail/users/locale/sv/LC_MESSAGES/django.mo +0 -0
  294. wagtail/users/locale/sv/LC_MESSAGES/django.po +48 -17
  295. wagtail/users/tests/test_admin_views.py +39 -25
  296. wagtail/users/utils.py +4 -1
  297. wagtail/users/views/groups.py +19 -5
  298. wagtail/users/wagtail_hooks.py +1 -1
  299. wagtail/utils/loading.py +2 -2
  300. wagtail-7.3rc1.data/data/AGENTS.md +21 -0
  301. wagtail-7.3rc1.data/data/CHANGELOG.txt +4941 -0
  302. wagtail-7.3rc1.data/data/CODE_OF_CONDUCT.md +71 -0
  303. wagtail-7.3rc1.data/data/CONTRIBUTORS.md +999 -0
  304. wagtail-7.3rc1.data/data/SPONSORS.md +55 -0
  305. {wagtail-7.2.1.dist-info → wagtail-7.3rc1.dist-info}/METADATA +6 -6
  306. {wagtail-7.2.1.dist-info → wagtail-7.3rc1.dist-info}/RECORD +310 -280
  307. {wagtail-7.2.1.dist-info → wagtail-7.3rc1.dist-info}/WHEEL +1 -1
  308. wagtail/images/static/wagtailimages/js/image-url-generator.js +0 -1
  309. wagtail/snippets/tests/test_snippets.py +0 -6377
  310. {wagtail-7.2.1.dist-info → wagtail-7.3rc1.dist-info}/entry_points.txt +0 -0
  311. {wagtail-7.2.1.dist-info → wagtail-7.3rc1.dist-info}/licenses/LICENSE +0 -0
  312. {wagtail-7.2.1.dist-info → wagtail-7.3rc1.dist-info}/top_level.txt +0 -0
@@ -3,7 +3,10 @@ from django.test import SimpleTestCase, TestCase
3
3
 
4
4
  from wagtail.admin.forms.auth import LoginForm, PasswordResetForm
5
5
  from wagtail.admin.forms.models import WagtailAdminModelForm
6
- from wagtail.test.testapp.models import Advert
6
+ from wagtail.models import Page
7
+ from wagtail.test.snippets.models import MultiSectionRichTextSnippet
8
+ from wagtail.test.testapp.models import Advert, EventPage
9
+ from wagtail.test.utils.form_data import inline_formset, nested_form_data, rich_text
7
10
 
8
11
 
9
12
  class CustomLoginForm(LoginForm):
@@ -66,3 +69,191 @@ class TestDeferRequiredFields(TestCase):
66
69
  form.defer_required_fields()
67
70
  form.restore_required_fields()
68
71
  self.assertFalse(form.is_valid())
72
+
73
+
74
+ class SnippetForm(WagtailAdminModelForm):
75
+ class Meta:
76
+ model = MultiSectionRichTextSnippet
77
+ fields = []
78
+ formsets = {
79
+ "sections": {
80
+ "fields": ["body"],
81
+ }
82
+ }
83
+
84
+
85
+ class TestGetFieldUpdatesForResave(TestCase):
86
+ def test_get_field_updates_for_resave_on_create(self):
87
+ form = SnippetForm(
88
+ nested_form_data(
89
+ {
90
+ "sections": inline_formset(
91
+ [
92
+ {"id": "", "body": rich_text("<p>Section 1 body</p>")},
93
+ {"id": "", "body": rich_text("<p>Section 2 body</p>")},
94
+ ]
95
+ )
96
+ }
97
+ )
98
+ )
99
+ self.assertTrue(form.is_valid())
100
+ snippet = form.save()
101
+ section_1 = snippet.sections.get(body__contains="Section 1 body")
102
+ section_2 = snippet.sections.get(body__contains="Section 2 body")
103
+ self.assertCountEqual(
104
+ form.get_field_updates_for_resave(),
105
+ [
106
+ ("sections-INITIAL_FORMS", "2"),
107
+ ("sections-0-id", str(section_1.id)),
108
+ ("sections-1-id", str(section_2.id)),
109
+ ],
110
+ )
111
+
112
+ def test_get_field_updates_for_resave_on_update(self):
113
+ snippet = MultiSectionRichTextSnippet()
114
+ section_1 = snippet.sections.create(body="<p>Initial body 1</p>")
115
+ snippet.save()
116
+
117
+ form = SnippetForm(
118
+ nested_form_data(
119
+ {
120
+ "sections": inline_formset(
121
+ [
122
+ {
123
+ "id": str(section_1.id),
124
+ "body": rich_text("<p>Section 1 body</p>"),
125
+ },
126
+ {"id": "", "body": rich_text("<p>Section 2 body</p>")},
127
+ ],
128
+ initial=1,
129
+ )
130
+ }
131
+ ),
132
+ instance=snippet,
133
+ )
134
+ self.assertTrue(form.is_valid())
135
+ form.save()
136
+ section_2 = snippet.sections.get(body__contains="Section 2 body")
137
+ self.assertCountEqual(
138
+ form.get_field_updates_for_resave(),
139
+ [
140
+ ("sections-INITIAL_FORMS", "2"),
141
+ ("sections-1-id", str(section_2.id)),
142
+ ],
143
+ )
144
+
145
+ def test_get_field_updates_for_resave_on_update_when_deleting_child(self):
146
+ snippet = MultiSectionRichTextSnippet()
147
+ section_1 = snippet.sections.create(body="<p>Initial body 1</p>")
148
+ section_2 = snippet.sections.create(body="<p>Initial body 2</p>")
149
+ snippet.save()
150
+
151
+ form = SnippetForm(
152
+ nested_form_data(
153
+ {
154
+ "sections": inline_formset(
155
+ [
156
+ {
157
+ "id": str(section_1.id),
158
+ "body": rich_text("<p>Section 1 body</p>"),
159
+ "DELETE": "on",
160
+ },
161
+ {
162
+ "id": str(section_2.id),
163
+ "body": rich_text("<p>Section 2 body</p>"),
164
+ },
165
+ {
166
+ # created and immediately deleted - should not appear in updates
167
+ "id": "",
168
+ "body": rich_text("<p>Section 3 body</p>"),
169
+ "DELETE": "on",
170
+ },
171
+ ],
172
+ initial=2,
173
+ )
174
+ }
175
+ ),
176
+ instance=snippet,
177
+ )
178
+ self.assertTrue(form.is_valid())
179
+ form.save()
180
+ self.assertCountEqual(
181
+ form.get_field_updates_for_resave(),
182
+ [
183
+ ("sections-INITIAL_FORMS", "3"),
184
+ ("sections-0-id", ""),
185
+ ],
186
+ )
187
+
188
+ def test_get_field_updates_for_resave_with_nested_inline_panel(self):
189
+ event_page = EventPage(
190
+ title="Test event",
191
+ date_from="2024-01-01",
192
+ audience="public",
193
+ location="Test location",
194
+ cost="Free",
195
+ )
196
+ speaker = event_page.speakers.create(first_name="First", last_name="Last")
197
+ award_1 = speaker.awards.create(name="Award 1")
198
+ root_page = Page.objects.filter(depth=2).first()
199
+ root_page.add_child(instance=event_page)
200
+
201
+ form = event_page.get_edit_handler().get_form_class()(
202
+ nested_form_data(
203
+ {
204
+ "title": "Test event",
205
+ "date_from": "2024-01-01",
206
+ "audience": "public",
207
+ "location": "Test location",
208
+ "cost": "Free",
209
+ "slug": "test-event",
210
+ "speakers": inline_formset(
211
+ [
212
+ {
213
+ "id": str(speaker.id),
214
+ "first_name": "First",
215
+ "last_name": "Last",
216
+ "awards": inline_formset(
217
+ [
218
+ {"id": str(award_1.id), "name": "Award 1"},
219
+ {"id": "", "name": "Award 2"},
220
+ ],
221
+ initial=1,
222
+ ),
223
+ },
224
+ {
225
+ "id": "",
226
+ "first_name": "New",
227
+ "last_name": "Speaker",
228
+ "awards": inline_formset(
229
+ [
230
+ {"id": "", "name": "New Award"},
231
+ ]
232
+ ),
233
+ },
234
+ ],
235
+ initial=1,
236
+ ),
237
+ "carousel_items": inline_formset([]),
238
+ "related_links": inline_formset([]),
239
+ "head_counts": inline_formset([]),
240
+ },
241
+ ),
242
+ instance=event_page,
243
+ )
244
+ self.assertTrue(form.is_valid())
245
+ form.save()
246
+ award_2 = speaker.awards.get(name="Award 2")
247
+ speaker_2 = event_page.speakers.get(first_name="New", last_name="Speaker")
248
+ award_3 = speaker_2.awards.get(name="New Award")
249
+ self.assertCountEqual(
250
+ form.get_field_updates_for_resave(),
251
+ [
252
+ ("speakers-INITIAL_FORMS", "2"),
253
+ ("speakers-0-awards-INITIAL_FORMS", "2"),
254
+ ("speakers-0-awards-1-id", str(award_2.id)),
255
+ ("speakers-1-id", str(speaker_2.id)),
256
+ ("speakers-1-awards-INITIAL_FORMS", "1"),
257
+ ("speakers-1-awards-0-id", str(award_3.id)),
258
+ ],
259
+ )
@@ -1,9 +1,10 @@
1
1
  from django.test import SimpleTestCase
2
2
 
3
- from wagtail.admin.icons import get_icon_sprite_hash, get_icon_sprite_url
3
+ from wagtail.admin.icons import get_icon_sprite_hash, get_icon_sprite_url, get_icons
4
+ from wagtail.test.utils.wagtail_tests import WagtailTestUtils
4
5
 
5
6
 
6
- class TestIconSpriteView(SimpleTestCase):
7
+ class TestIconSpriteView(WagtailTestUtils, SimpleTestCase):
7
8
  def test_content_type(self):
8
9
  response = self.client.get(get_icon_sprite_url())
9
10
  self.assertEqual(
@@ -15,6 +16,25 @@ class TestIconSpriteView(SimpleTestCase):
15
16
  response = self.client.get(get_icon_sprite_url())
16
17
  self.assertNotContains(response, "<!--")
17
18
 
19
+ def test_register_icons_hook(self):
20
+ get_icons.cache_clear()
21
+ self.addCleanup(get_icons.cache_clear)
22
+
23
+ def register_icons(icons):
24
+ # The hook should receive the existing icons as an argument
25
+ self.assertIn("wagtailadmin/icons/wagtail.svg", icons)
26
+ return icons + [
27
+ "tests/icons/single-quotes.svg", # id='icon-single-quotes'
28
+ ]
29
+
30
+ with self.register_hook("register_icons", register_icons):
31
+ response = self.client.get(get_icon_sprite_url())
32
+
33
+ self.assertEqual(response.status_code, 200)
34
+ soup = self.get_soup(response.content)
35
+ icon = soup.select_one("symbol#icon-single-quotes")
36
+ self.assertIsNotNone(icon)
37
+
18
38
 
19
39
  class TestIconSpriteHash(SimpleTestCase):
20
40
  def test_hash(self):
@@ -28,7 +28,7 @@ class TestChooserBrowse(WagtailTestUtils, TestCase):
28
28
 
29
29
  self.login()
30
30
 
31
- def get(self, params={}):
31
+ def get(self, params=None):
32
32
  return self.client.get(reverse("wagtailadmin_choose_page"), params)
33
33
 
34
34
  def test_simple(self):
@@ -103,7 +103,7 @@ class TestCanChooseRootFlag(WagtailTestUtils, TestCase):
103
103
  def setUp(self):
104
104
  self.login()
105
105
 
106
- def get(self, params={}):
106
+ def get(self, params=None):
107
107
  return self.client.get(reverse("wagtailadmin_choose_page"), params)
108
108
 
109
109
  def test_cannot_choose_root_by_default(self):
@@ -125,12 +125,12 @@ class TestChooserBrowseChild(WagtailTestUtils, TestCase):
125
125
 
126
126
  self.login()
127
127
 
128
- def get(self, params={}):
128
+ def get(self, params=None):
129
129
  return self.client.get(
130
130
  reverse("wagtailadmin_choose_page_child", args=(self.root_page.id,)), params
131
131
  )
132
132
 
133
- def get_invalid(self, params={}):
133
+ def get_invalid(self, params=None):
134
134
  return self.client.get(
135
135
  reverse("wagtailadmin_choose_page_child", args=(9999999,)), params
136
136
  )
@@ -574,7 +574,7 @@ class TestAutomaticRootPageDetection(WagtailTestUtils, TestCase):
574
574
  )
575
575
  return event_index
576
576
 
577
- def get_best_root(self, params={}):
577
+ def get_best_root(self, params=None):
578
578
  response = self.client.get(reverse("wagtailadmin_choose_page"), params)
579
579
  return response.context["parent_page"].specific
580
580
 
@@ -629,12 +629,12 @@ class TestChooserExternalLink(WagtailTestUtils, TestCase):
629
629
  self.internal_page = SimplePage(title="About", content="About Foo")
630
630
  Page.objects.get(pk=2).add_child(instance=self.internal_page)
631
631
 
632
- def get(self, params={}):
632
+ def get(self, params=None):
633
633
  return self.client.get(
634
634
  reverse("wagtailadmin_choose_page_external_link"), params
635
635
  )
636
636
 
637
- def post(self, post_data={}, url_params={}):
637
+ def post(self, post_data=None, url_params=None):
638
638
  url = reverse("wagtailadmin_choose_page_external_link")
639
639
  if url_params:
640
640
  url += "?" + urlencode(url_params)
@@ -1141,10 +1141,10 @@ class TestChooserAnchorLink(WagtailTestUtils, TestCase):
1141
1141
  def setUp(self):
1142
1142
  self.login()
1143
1143
 
1144
- def get(self, params={}):
1144
+ def get(self, params=None):
1145
1145
  return self.client.get(reverse("wagtailadmin_choose_page_anchor_link"), params)
1146
1146
 
1147
- def post(self, post_data={}, url_params={}):
1147
+ def post(self, post_data=None, url_params=None):
1148
1148
  url = reverse("wagtailadmin_choose_page_anchor_link")
1149
1149
  if url_params:
1150
1150
  url += "?" + urlencode(url_params)
@@ -1224,10 +1224,10 @@ class TestChooserEmailLink(WagtailTestUtils, TestCase):
1224
1224
  def setUp(self):
1225
1225
  self.login()
1226
1226
 
1227
- def get(self, params={}):
1227
+ def get(self, params=None):
1228
1228
  return self.client.get(reverse("wagtailadmin_choose_page_email_link"), params)
1229
1229
 
1230
- def post(self, post_data={}, url_params={}):
1230
+ def post(self, post_data=None, url_params=None):
1231
1231
  url = reverse("wagtailadmin_choose_page_email_link")
1232
1232
  if url_params:
1233
1233
  url += "?" + urlencode(url_params)
@@ -1380,10 +1380,10 @@ class TestChooserPhoneLink(WagtailTestUtils, TestCase):
1380
1380
  def setUp(self):
1381
1381
  self.login()
1382
1382
 
1383
- def get(self, params={}):
1383
+ def get(self, params=None):
1384
1384
  return self.client.get(reverse("wagtailadmin_choose_page_phone_link"), params)
1385
1385
 
1386
- def post(self, post_data={}, url_params={}):
1386
+ def post(self, post_data=None, url_params=None):
1387
1387
  url = reverse("wagtailadmin_choose_page_phone_link")
1388
1388
  if url_params:
1389
1389
  url += "?" + urlencode(url_params)
@@ -50,17 +50,20 @@ class BaseReportViewTestCase(AdminTemplateTestUtils, WagtailTestUtils, TestCase)
50
50
  cls.header_buttons_parent_selector = (
51
51
  '[data-controller="w-teleport"]'
52
52
  '[data-w-teleport-target-value="#w-slim-header-buttons"]'
53
+ '[data-w-teleport-mode-value="innerHTML"]'
53
54
  )
54
55
  cls.drilldown_selector = (
55
56
  '[data-controller="w-teleport"]'
56
57
  '[data-w-teleport-target-value="#filters-drilldown"]'
58
+ '[data-w-teleport-mode-value="innerHTML"]'
57
59
  )
58
60
  cls.extra_params = "&_w_filter_fragment=true"
59
61
 
60
62
  def setUp(self):
61
63
  self.user = self.login()
62
64
 
63
- def get(self, params={}, **kwargs):
65
+ def get(self, params=None, **kwargs):
66
+ params = params or {}
64
67
  if self.results_only:
65
68
  params["_w_filter_fragment"] = "true"
66
69
  return self.client.get(self.url, params, **kwargs)
@@ -9,6 +9,7 @@ from django.utils.translation import gettext
9
9
 
10
10
  from wagtail import hooks
11
11
  from wagtail.admin.staticfiles import versioned_static
12
+ from wagtail.admin.ui.components import Component
12
13
  from wagtail.admin.userbar import AccessibilityItem, Userbar
13
14
  from wagtail.coreutils import get_dummy_request
14
15
  from wagtail.models import PAGE_TEMPLATE_VAR, Locale, Page, Site
@@ -761,7 +762,7 @@ class TestUserbarComponent(WagtailTestUtils, TestCase):
761
762
  self.assertIsNotNone(button)
762
763
  self.assertEqual(
763
764
  button.get_text(separator=" | ", strip=True).strip(),
764
- "Issues found | Accessibility",
765
+ "Issues found | Checks",
765
766
  )
766
767
 
767
768
  def test_render_no_request(self):
@@ -790,7 +791,7 @@ class TestUserbarComponent(WagtailTestUtils, TestCase):
790
791
  self.assertIsNotNone(button)
791
792
  self.assertEqual(
792
793
  button.get_text(separator=" | ", strip=True).strip(),
793
- "Issues found | Accessibility",
794
+ "Issues found | Checks",
794
795
  )
795
796
 
796
797
  css_links = soup.select("link[rel='stylesheet']")
@@ -842,7 +843,7 @@ class TestUserbarComponent(WagtailTestUtils, TestCase):
842
843
  self.assertIsNotNone(button)
843
844
  self.assertEqual(
844
845
  button.get_text(separator=" | ", strip=True).strip(),
845
- "Issues found | Accessibility",
846
+ "Issues found | Checks",
846
847
  )
847
848
 
848
849
  def test_render_with_page(self):
@@ -868,7 +869,7 @@ class TestUserbarComponent(WagtailTestUtils, TestCase):
868
869
  self.assertIsNotNone(accessibility_button)
869
870
  self.assertEqual(
870
871
  accessibility_button.get_text(separator=" | ", strip=True).strip(),
871
- "Issues found | Accessibility",
872
+ "Issues found | Checks",
872
873
  )
873
874
 
874
875
  @override_settings(WAGTAILADMIN_BASE_URL=None)
@@ -899,7 +900,7 @@ class TestUserbarComponent(WagtailTestUtils, TestCase):
899
900
  self.assertIsNotNone(button)
900
901
  self.assertEqual(
901
902
  button.get_text(separator=" | ", strip=True).strip(),
902
- "Issues found | Accessibility",
903
+ "Issues found | Checks",
903
904
  )
904
905
 
905
906
  css_links = soup.select("link[rel='stylesheet']")
@@ -923,3 +924,66 @@ class TestUserbarComponent(WagtailTestUtils, TestCase):
923
924
  versioned_static("wagtailadmin/js/userbar.js"),
924
925
  ],
925
926
  )
927
+
928
+ def test_component_item(self):
929
+ class TestItem(Component):
930
+ def render_html(self, parent_context):
931
+ return "<li><a href='#test-item'>Test item</a></li>"
932
+
933
+ def hook(request, items, page):
934
+ items.append(TestItem())
935
+
936
+ with hooks.register_temporarily("construct_wagtail_userbar", hook):
937
+ rendered = Userbar(object=self.homepage).render_html(
938
+ {"request": self.request, PAGE_TEMPLATE_VAR: self.homepage}
939
+ )
940
+ soup = self.get_soup(rendered)
941
+
942
+ self.assertIsNotNone(soup.css.select_one("a[href='#test-item']"))
943
+
944
+ def test_legacy_render_item(self):
945
+ class LegacyItem:
946
+ def render(self, request):
947
+ return "<li><a href='#legacy-item'>Legacy item</a></li>"
948
+
949
+ def hook(request, items, page):
950
+ items.append(LegacyItem())
951
+
952
+ with (
953
+ self.assertWarnsMessage(
954
+ RemovedInWagtail80Warning,
955
+ "Userbar items now use the `render_html(parent_context)` method instead of `render(request)` - "
956
+ "view the `construct_wagtail_userbar` docs to update LegacyItem",
957
+ ),
958
+ hooks.register_temporarily(
959
+ "construct_wagtail_userbar",
960
+ hook,
961
+ ),
962
+ ):
963
+ rendered = Userbar(object=self.homepage).render_html(
964
+ {"request": self.request, PAGE_TEMPLATE_VAR: self.homepage}
965
+ )
966
+ soup = self.get_soup(rendered)
967
+
968
+ self.assertIsNotNone(soup.css.select_one("a[href='#legacy-item']"))
969
+
970
+ def test_component_item_with_media(self):
971
+ class ItemWithMedia(Component):
972
+ def render_html(self, parent_context):
973
+ return ""
974
+
975
+ class Media:
976
+ js = ["custom-item.js"]
977
+ css = {"all": ["custom-item.css"]}
978
+
979
+ def hook(request, items, page):
980
+ items.append(ItemWithMedia())
981
+
982
+ with hooks.register_temporarily("construct_wagtail_userbar", hook):
983
+ rendered = Userbar(object=self.homepage).render_html(
984
+ {"request": self.request, PAGE_TEMPLATE_VAR: self.homepage}
985
+ )
986
+ soup = self.get_soup(rendered)
987
+
988
+ self.assertIsNotNone(soup.css.select_one('script[src$="custom-item.js"]'))
989
+ self.assertIsNotNone(soup.css.select_one('link[href$="custom-item.css"]'))
@@ -9,7 +9,7 @@ from wagtail.test.utils import WagtailTestUtils
9
9
  class TestGenericIndexView(WagtailTestUtils, TestCase):
10
10
  fixtures = ["test.json"]
11
11
 
12
- def get(self, params={}):
12
+ def get(self, params=None):
13
13
  return self.client.get(reverse("testapp_generic_index"), params)
14
14
 
15
15
  def test_non_integer_primary_key(self):
@@ -28,7 +28,7 @@ class TestGenericIndexView(WagtailTestUtils, TestCase):
28
28
  class TestGenericIndexViewWithoutModel(WagtailTestUtils, TestCase):
29
29
  fixtures = ["test.json"]
30
30
 
31
- def get(self, params={}):
31
+ def get(self, params=None):
32
32
  return self.client.get(reverse("testapp_generic_index_without_model"), params)
33
33
 
34
34
  def test_non_integer_primary_key(self):
@@ -41,7 +41,7 @@ class TestGenericIndexViewWithoutModel(WagtailTestUtils, TestCase):
41
41
  class TestGenericCreateView(WagtailTestUtils, TestCase):
42
42
  fixtures = ["test.json"]
43
43
 
44
- def get(self, params={}):
44
+ def get(self, params=None):
45
45
  return self.client.get(reverse("testapp_generic_create"), params)
46
46
 
47
47
  def test_get_create_view(self):
@@ -74,7 +74,7 @@ class TestGenericCreateView(WagtailTestUtils, TestCase):
74
74
  class TestGenericEditView(WagtailTestUtils, TestCase):
75
75
  fixtures = ["test.json"]
76
76
 
77
- def get(self, object_pk, params={}):
77
+ def get(self, object_pk, params=None):
78
78
  return self.client.get(
79
79
  reverse("testapp_generic_edit", args=(object_pk,)), params
80
80
  )
@@ -120,7 +120,7 @@ class TestGenericEditView(WagtailTestUtils, TestCase):
120
120
  class TestGenericDeleteView(WagtailTestUtils, TestCase):
121
121
  fixtures = ["test.json"]
122
122
 
123
- def get(self, object_pk, params={}):
123
+ def get(self, object_pk, params=None):
124
124
  return self.client.get(
125
125
  reverse("testapp_generic_edit", args=(object_pk,)), params
126
126
  )
@@ -143,7 +143,7 @@ class TestWorkflowsIndexView(AdminTemplateTestUtils, WagtailTestUtils, TestCase)
143
143
  ]
144
144
  WorkflowPage.objects.bulk_create(workflow_pages)
145
145
 
146
- def get(self, params={}):
146
+ def get(self, params=None):
147
147
  return self.client.get(reverse("wagtailadmin_workflows:index"), params)
148
148
 
149
149
  def test_simple(self):
@@ -339,7 +339,7 @@ class TestWorkflowPermissions(WagtailTestUtils, TestCase):
339
339
  def setUp(self):
340
340
  self.user = self.login()
341
341
 
342
- def get(self, params={}):
342
+ def get(self, params=None):
343
343
  return self.client.get(reverse(self.url_name), params)
344
344
 
345
345
  def test_simple(self):
@@ -417,10 +417,10 @@ class TestWorkflowsCreateView(AdminTemplateTestUtils, WagtailTestUtils, TestCase
417
417
  FullFeaturedSnippet
418
418
  )
419
419
 
420
- def get(self, params={}):
420
+ def get(self, params=None):
421
421
  return self.client.get(reverse("wagtailadmin_workflows:add"), params)
422
422
 
423
- def post(self, post_data={}):
423
+ def post(self, post_data=None):
424
424
  return self.client.post(reverse("wagtailadmin_workflows:add"), post_data)
425
425
 
426
426
  def test_get(self):
@@ -676,12 +676,12 @@ class TestWorkflowsEditView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
676
676
  moderators.user_set.add(self.moderator)
677
677
  moderators.permissions.add(Permission.objects.get(codename="change_workflow"))
678
678
 
679
- def get(self, params={}):
679
+ def get(self, params=None):
680
680
  return self.client.get(
681
681
  reverse("wagtailadmin_workflows:edit", args=[self.workflow.id]), params
682
682
  )
683
683
 
684
- def post(self, post_data={}):
684
+ def post(self, post_data=None):
685
685
  return self.client.post(
686
686
  reverse("wagtailadmin_workflows:edit", args=[self.workflow.id]), post_data
687
687
  )
@@ -1028,7 +1028,7 @@ class TestRemoveWorkflow(WagtailTestUtils, TestCase):
1028
1028
  moderators.user_set.add(self.moderator)
1029
1029
  moderators.permissions.add(Permission.objects.get(codename="change_workflow"))
1030
1030
 
1031
- def post(self, post_data={}):
1031
+ def post(self, post_data=None):
1032
1032
  return self.client.post(
1033
1033
  reverse(
1034
1034
  "wagtailadmin_workflows:remove", args=[self.page.id, self.workflow.id]
@@ -1082,7 +1082,7 @@ class TestTaskIndexView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
1082
1082
  moderators.user_set.add(self.moderator)
1083
1083
  moderators.permissions.add(Permission.objects.get(codename="change_task"))
1084
1084
 
1085
- def get(self, params={}):
1085
+ def get(self, params=None):
1086
1086
  return self.client.get(reverse("wagtailadmin_workflows:task_index"), params)
1087
1087
 
1088
1088
  def test_simple(self):
@@ -1370,7 +1370,7 @@ class TestCreateTaskView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
1370
1370
  moderators.user_set.add(self.moderator)
1371
1371
  moderators.permissions.add(Permission.objects.get(codename="add_task"))
1372
1372
 
1373
- def get(self, url_kwargs=None, params={}):
1373
+ def get(self, url_kwargs=None, params=None):
1374
1374
  url_kwargs = url_kwargs or {}
1375
1375
  url_kwargs.setdefault("app_label", SimpleTask._meta.app_label)
1376
1376
  url_kwargs.setdefault("model_name", SimpleTask._meta.model_name)
@@ -1378,7 +1378,7 @@ class TestCreateTaskView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
1378
1378
  reverse("wagtailadmin_workflows:add_task", kwargs=url_kwargs), params
1379
1379
  )
1380
1380
 
1381
- def post(self, post_data={}):
1381
+ def post(self, post_data=None):
1382
1382
  return self.client.post(
1383
1383
  reverse(
1384
1384
  "wagtailadmin_workflows:add_task",
@@ -1504,12 +1504,12 @@ class TestEditTaskView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
1504
1504
  moderators.user_set.add(self.moderator)
1505
1505
  moderators.permissions.add(Permission.objects.get(codename="change_task"))
1506
1506
 
1507
- def get(self, params={}):
1507
+ def get(self, params=None):
1508
1508
  return self.client.get(
1509
1509
  reverse("wagtailadmin_workflows:edit_task", args=[self.task.id]), params
1510
1510
  )
1511
1511
 
1512
- def post(self, post_data={}):
1512
+ def post(self, post_data=None):
1513
1513
  return self.client.post(
1514
1514
  reverse("wagtailadmin_workflows:edit_task", args=[self.task.id]), post_data
1515
1515
  )
@@ -3434,10 +3434,12 @@ class TestPageWorkflowReportResults(TestPageWorkflowReport):
3434
3434
  header_buttons_parent_selector = (
3435
3435
  '[data-controller="w-teleport"]'
3436
3436
  '[data-w-teleport-target-value="#w-slim-header-buttons"]'
3437
+ '[data-w-teleport-mode-value="innerHTML"]'
3437
3438
  )
3438
3439
  drilldown_selector = (
3439
3440
  '[data-controller="w-teleport"]'
3440
3441
  '[data-w-teleport-target-value="#filters-drilldown"]'
3442
+ '[data-w-teleport-mode-value="innerHTML"]'
3441
3443
  )
3442
3444
  extra_params = "&_w_filter_fragment=true"
3443
3445
 
@@ -91,6 +91,19 @@ class TestModelViewSetGroup(WagtailTestUtils, TestCase):
91
91
  self.assertNotContains(response, reverse("blockcounts_streammodel:index"))
92
92
 
93
93
 
94
+ class TestAdminURLs(WagtailTestUtils, TestCase):
95
+ def setUp(self):
96
+ self.user = self.login()
97
+
98
+ def test_cannot_reverse_mismatched_converter_value(self):
99
+ with self.assertRaises(NoReverseMatch):
100
+ reverse("streammodel:edit", kwargs={"pk": "123abc"})
101
+
102
+ def test_404_on_mismatched_converter_value(self):
103
+ response = self.client.get("/admin/streammodel/edit/123abc/")
104
+ self.assertEqual(response.status_code, 404)
105
+
106
+
94
107
  class TestTemplateConfiguration(WagtailTestUtils, TestCase):
95
108
  def setUp(self):
96
109
  self.user = self.login()
@@ -0,0 +1,5 @@
1
+ from wagtail.admin.ui.components import Component
2
+
3
+
4
+ class AutosaveIndicator(Component):
5
+ template_name = "wagtailadmin/shared/autosave/indicator.html"
@@ -13,12 +13,14 @@ class EditingSessionsModule(Component):
13
13
  release_url,
14
14
  other_sessions,
15
15
  revision_id=None,
16
+ revision_created_at=None,
16
17
  ):
17
18
  self.current_session = current_session
18
19
  self.ping_url = ping_url
19
20
  self.release_url = release_url
20
21
  self.sessions_list = EditingSessionsList(current_session, other_sessions)
21
22
  self.revision_id = revision_id
23
+ self.revision_created_at = revision_created_at
22
24
 
23
25
  def get_context_data(self, parent_context):
24
26
  ping_interval = getattr(
@@ -33,6 +35,7 @@ class EditingSessionsModule(Component):
33
35
  "ping_interval": ping_interval,
34
36
  "sessions_list": self.sessions_list,
35
37
  "revision_id": self.revision_id,
38
+ "revision_created_at": self.revision_created_at,
36
39
  }
37
40
 
38
41