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
@@ -0,0 +1,197 @@
1
+ from django.core.exceptions import ImproperlyConfigured, ValidationError
2
+ from django.test import TestCase
3
+
4
+ from wagtail.blocks.field_block import FieldBlockAdapter
5
+ from wagtail.models import Locale
6
+ from wagtail.snippets.blocks import SnippetChooserBlock
7
+ from wagtail.snippets.widgets import AdminSnippetChooser
8
+ from wagtail.test.testapp.models import Advert, AdvertWithCustomPrimaryKey
9
+
10
+
11
+ class TestSnippetChooserBlock(TestCase):
12
+ fixtures = ["test.json"]
13
+
14
+ def test_serialize(self):
15
+ """The value of a SnippetChooserBlock (a snippet instance) should serialize to an ID"""
16
+ block = SnippetChooserBlock(Advert)
17
+ test_advert = Advert.objects.get(text="test_advert")
18
+
19
+ self.assertEqual(block.get_prep_value(test_advert), test_advert.id)
20
+
21
+ # None should serialize to None
22
+ self.assertIsNone(block.get_prep_value(None))
23
+
24
+ def test_deserialize(self):
25
+ """The serialized value of a SnippetChooserBlock (an ID) should deserialize to a snippet instance"""
26
+ block = SnippetChooserBlock(Advert)
27
+ test_advert = Advert.objects.get(text="test_advert")
28
+
29
+ self.assertEqual(block.to_python(test_advert.id), test_advert)
30
+
31
+ # None should deserialize to None
32
+ self.assertIsNone(block.to_python(None))
33
+
34
+ def test_reference_model_by_string(self):
35
+ block = SnippetChooserBlock("tests.Advert")
36
+ test_advert = Advert.objects.get(text="test_advert")
37
+ self.assertEqual(block.to_python(test_advert.id), test_advert)
38
+
39
+ def test_adapt(self):
40
+ block = SnippetChooserBlock(
41
+ Advert,
42
+ help_text="pick an advert, any advert",
43
+ description="An advert to be displayed on the sidebar.",
44
+ )
45
+
46
+ block.set_name("test_snippetchooserblock")
47
+ js_args = FieldBlockAdapter().js_args(block)
48
+
49
+ self.assertEqual(js_args[0], "test_snippetchooserblock")
50
+ self.assertIsInstance(js_args[1], AdminSnippetChooser)
51
+ self.assertEqual(js_args[1].model, Advert)
52
+ self.assertEqual(
53
+ js_args[2],
54
+ {
55
+ "label": "Test snippetchooserblock",
56
+ "description": "An advert to be displayed on the sidebar.",
57
+ "required": True,
58
+ "icon": "snippet",
59
+ "blockDefId": block.definition_prefix,
60
+ "isPreviewable": block.is_previewable,
61
+ "helpText": "pick an advert, any advert",
62
+ "classname": "w-field w-field--model_choice_field w-field--admin_snippet_chooser",
63
+ "attrs": {},
64
+ "showAddCommentButton": True,
65
+ "strings": {"ADD_COMMENT": "Add Comment"},
66
+ },
67
+ )
68
+
69
+ def test_form_response(self):
70
+ block = SnippetChooserBlock(Advert)
71
+ test_advert = Advert.objects.get(text="test_advert")
72
+
73
+ value = block.value_from_datadict({"advert": str(test_advert.id)}, {}, "advert")
74
+ self.assertEqual(value, test_advert)
75
+
76
+ empty_value = block.value_from_datadict({"advert": ""}, {}, "advert")
77
+ self.assertIsNone(empty_value)
78
+
79
+ def test_clean(self):
80
+ required_block = SnippetChooserBlock(Advert)
81
+ nonrequired_block = SnippetChooserBlock(Advert, required=False)
82
+ test_advert = Advert.objects.get(text="test_advert")
83
+
84
+ self.assertEqual(required_block.clean(test_advert), test_advert)
85
+ with self.assertRaises(ValidationError):
86
+ required_block.clean(None)
87
+
88
+ self.assertEqual(nonrequired_block.clean(test_advert), test_advert)
89
+ self.assertIsNone(nonrequired_block.clean(None))
90
+
91
+ def test_deconstruct(self):
92
+ block = SnippetChooserBlock(Advert, required=False)
93
+ path, args, kwargs = block.deconstruct()
94
+ self.assertEqual(path, "wagtail.snippets.blocks.SnippetChooserBlock")
95
+ self.assertEqual(args, (Advert,))
96
+ self.assertEqual(kwargs, {"required": False})
97
+
98
+ def test_extract_references(self):
99
+ block = SnippetChooserBlock(Advert)
100
+ test_advert = Advert.objects.get(text="test_advert")
101
+
102
+ self.assertListEqual(
103
+ list(block.extract_references(test_advert)),
104
+ [(Advert, str(test_advert.id), "", "")],
105
+ )
106
+
107
+ # None should not yield any references
108
+ self.assertListEqual(list(block.extract_references(None)), [])
109
+
110
+ def test_exception_on_non_snippet_model(self):
111
+ with self.assertRaises(ImproperlyConfigured):
112
+ block = SnippetChooserBlock(Locale)
113
+ block.widget
114
+
115
+
116
+ class TestSnippetChooserBlockWithCustomPrimaryKey(TestCase):
117
+ fixtures = ["test.json"]
118
+
119
+ def test_serialize(self):
120
+ """The value of a SnippetChooserBlock (a snippet instance) should serialize to an ID"""
121
+ block = SnippetChooserBlock(AdvertWithCustomPrimaryKey)
122
+ test_advert = AdvertWithCustomPrimaryKey.objects.get(pk="advert/01")
123
+
124
+ self.assertEqual(block.get_prep_value(test_advert), test_advert.pk)
125
+
126
+ # None should serialize to None
127
+ self.assertIsNone(block.get_prep_value(None))
128
+
129
+ def test_deserialize(self):
130
+ """The serialized value of a SnippetChooserBlock (an ID) should deserialize to a snippet instance"""
131
+ block = SnippetChooserBlock(AdvertWithCustomPrimaryKey)
132
+ test_advert = AdvertWithCustomPrimaryKey.objects.get(pk="advert/01")
133
+
134
+ self.assertEqual(block.to_python(test_advert.pk), test_advert)
135
+
136
+ # None should deserialize to None
137
+ self.assertIsNone(block.to_python(None))
138
+
139
+ def test_adapt(self):
140
+ block = SnippetChooserBlock(
141
+ AdvertWithCustomPrimaryKey,
142
+ help_text="pick an advert, any advert",
143
+ description="An advert to be displayed on the footer.",
144
+ )
145
+
146
+ block.set_name("test_snippetchooserblock")
147
+ js_args = FieldBlockAdapter().js_args(block)
148
+
149
+ self.assertEqual(js_args[0], "test_snippetchooserblock")
150
+ self.assertIsInstance(js_args[1], AdminSnippetChooser)
151
+ self.assertEqual(js_args[1].model, AdvertWithCustomPrimaryKey)
152
+ self.assertEqual(
153
+ js_args[2],
154
+ {
155
+ "label": "Test snippetchooserblock",
156
+ "description": "An advert to be displayed on the footer.",
157
+ "required": True,
158
+ "icon": "snippet",
159
+ "blockDefId": block.definition_prefix,
160
+ "isPreviewable": block.is_previewable,
161
+ "helpText": "pick an advert, any advert",
162
+ "classname": "w-field w-field--model_choice_field w-field--admin_snippet_chooser",
163
+ "attrs": {},
164
+ "showAddCommentButton": True,
165
+ "strings": {"ADD_COMMENT": "Add Comment"},
166
+ },
167
+ )
168
+
169
+ def test_form_response(self):
170
+ block = SnippetChooserBlock(AdvertWithCustomPrimaryKey)
171
+ test_advert = AdvertWithCustomPrimaryKey.objects.get(pk="advert/01")
172
+
173
+ value = block.value_from_datadict(
174
+ {"advertwithcustomprimarykey": str(test_advert.pk)},
175
+ {},
176
+ "advertwithcustomprimarykey",
177
+ )
178
+ self.assertEqual(value, test_advert)
179
+
180
+ empty_value = block.value_from_datadict(
181
+ {"advertwithcustomprimarykey": ""}, {}, "advertwithcustomprimarykey"
182
+ )
183
+ self.assertIsNone(empty_value)
184
+
185
+ def test_clean(self):
186
+ required_block = SnippetChooserBlock(AdvertWithCustomPrimaryKey)
187
+ nonrequired_block = SnippetChooserBlock(
188
+ AdvertWithCustomPrimaryKey, required=False
189
+ )
190
+ test_advert = AdvertWithCustomPrimaryKey.objects.get(pk="advert/01")
191
+
192
+ self.assertEqual(required_block.clean(test_advert), test_advert)
193
+ with self.assertRaises(ValidationError):
194
+ required_block.clean(None)
195
+
196
+ self.assertEqual(nonrequired_block.clean(test_advert), test_advert)
197
+ self.assertIsNone(nonrequired_block.clean(None))
@@ -0,0 +1,149 @@
1
+ from django.contrib.auth.models import AnonymousUser
2
+ from django.test import RequestFactory, TestCase
3
+
4
+ from wagtail.admin.panels import FieldPanel, ObjectList, get_edit_handler
5
+ from wagtail.snippets.widgets import AdminSnippetChooser
6
+ from wagtail.test.testapp.models import (
7
+ Advert,
8
+ AdvertWithCustomPrimaryKey,
9
+ SnippetChooserModel,
10
+ SnippetChooserModelWithCustomPrimaryKey,
11
+ )
12
+ from wagtail.test.utils import WagtailTestUtils
13
+
14
+
15
+ class TestSnippetChooserPanel(WagtailTestUtils, TestCase):
16
+ fixtures = ["test.json"]
17
+
18
+ def setUp(self):
19
+ self.request = RequestFactory().get("/")
20
+ user = AnonymousUser() # technically, Anonymous users cannot access the admin
21
+ self.request.user = user
22
+
23
+ model = SnippetChooserModel
24
+ self.advert_text = "Test advert text"
25
+ test_snippet = model.objects.create(
26
+ advert=Advert.objects.create(text=self.advert_text)
27
+ )
28
+
29
+ self.edit_handler = get_edit_handler(model)
30
+ self.form_class = self.edit_handler.get_form_class()
31
+ form = self.form_class(instance=test_snippet)
32
+ edit_handler = self.edit_handler.get_bound_panel(
33
+ instance=test_snippet, form=form, request=self.request
34
+ )
35
+
36
+ self.snippet_chooser_panel = [
37
+ panel
38
+ for panel in edit_handler.children
39
+ if getattr(panel, "field_name", None) == "advert"
40
+ ][0]
41
+
42
+ def test_render_html(self):
43
+ field_html = self.snippet_chooser_panel.render_html()
44
+ self.assertIn(self.advert_text, field_html)
45
+ self.assertIn("Choose advert", field_html)
46
+ self.assertIn("Choose another advert", field_html)
47
+ self.assertIn("icon icon-snippet icon", field_html)
48
+
49
+ def test_render_as_empty_field(self):
50
+ test_snippet = SnippetChooserModel()
51
+ form = self.form_class(instance=test_snippet)
52
+ edit_handler = self.edit_handler.get_bound_panel(
53
+ instance=test_snippet, form=form, request=self.request
54
+ )
55
+
56
+ snippet_chooser_panel = [
57
+ panel
58
+ for panel in edit_handler.children
59
+ if getattr(panel, "field_name", None) == "advert"
60
+ ][0]
61
+
62
+ field_html = snippet_chooser_panel.render_html()
63
+ self.assertIn("Choose advert", field_html)
64
+ self.assertIn("Choose another advert", field_html)
65
+
66
+ def test_render_js(self):
67
+ self.assertIn(
68
+ 'new SnippetChooser("id_advert", {"modalUrl": "/admin/snippets/choose/tests/advert/"});',
69
+ self.snippet_chooser_panel.render_html(),
70
+ )
71
+
72
+ def test_target_model_autodetected(self):
73
+ edit_handler = ObjectList([FieldPanel("advert")]).bind_to_model(
74
+ SnippetChooserModel
75
+ )
76
+ form_class = edit_handler.get_form_class()
77
+ form = form_class()
78
+ widget = form.fields["advert"].widget
79
+ self.assertIsInstance(widget, AdminSnippetChooser)
80
+ self.assertEqual(widget.model, Advert)
81
+
82
+
83
+ class TestSnippetChooserPanelWithCustomPrimaryKey(WagtailTestUtils, TestCase):
84
+ fixtures = ["test.json"]
85
+
86
+ def setUp(self):
87
+ self.request = RequestFactory().get("/")
88
+ user = AnonymousUser() # technically, Anonymous users cannot access the admin
89
+ self.request.user = user
90
+
91
+ model = SnippetChooserModelWithCustomPrimaryKey
92
+ self.advert_text = "Test advert text"
93
+ test_snippet = model.objects.create(
94
+ advertwithcustomprimarykey=AdvertWithCustomPrimaryKey.objects.create(
95
+ advert_id="advert/02", text=self.advert_text
96
+ )
97
+ )
98
+
99
+ self.edit_handler = get_edit_handler(model)
100
+ self.form_class = self.edit_handler.get_form_class()
101
+ form = self.form_class(instance=test_snippet)
102
+ edit_handler = self.edit_handler.get_bound_panel(
103
+ instance=test_snippet, form=form, request=self.request
104
+ )
105
+
106
+ self.snippet_chooser_panel = [
107
+ panel
108
+ for panel in edit_handler.children
109
+ if getattr(panel, "field_name", None) == "advertwithcustomprimarykey"
110
+ ][0]
111
+
112
+ def test_render_html(self):
113
+ field_html = self.snippet_chooser_panel.render_html()
114
+ self.assertIn(self.advert_text, field_html)
115
+ self.assertIn("Choose advert with custom primary key", field_html)
116
+ self.assertIn("Choose another advert with custom primary key", field_html)
117
+
118
+ def test_render_as_empty_field(self):
119
+ test_snippet = SnippetChooserModelWithCustomPrimaryKey()
120
+ form = self.form_class(instance=test_snippet)
121
+ edit_handler = self.edit_handler.get_bound_panel(
122
+ instance=test_snippet, form=form, request=self.request
123
+ )
124
+
125
+ snippet_chooser_panel = [
126
+ panel
127
+ for panel in edit_handler.children
128
+ if getattr(panel, "field_name", None) == "advertwithcustomprimarykey"
129
+ ][0]
130
+
131
+ field_html = snippet_chooser_panel.render_html()
132
+ self.assertIn("Choose advert with custom primary key", field_html)
133
+ self.assertIn("Choose another advert with custom primary key", field_html)
134
+
135
+ def test_render_js(self):
136
+ self.assertIn(
137
+ 'new SnippetChooser("id_advertwithcustomprimarykey", {"modalUrl": "/admin/snippets/choose/tests/advertwithcustomprimarykey/"});',
138
+ self.snippet_chooser_panel.render_html(),
139
+ )
140
+
141
+ def test_target_model_autodetected(self):
142
+ edit_handler = ObjectList(
143
+ [FieldPanel("advertwithcustomprimarykey")]
144
+ ).bind_to_model(SnippetChooserModelWithCustomPrimaryKey)
145
+ form_class = edit_handler.get_form_class()
146
+ form = form_class()
147
+ widget = form.fields["advertwithcustomprimarykey"].widget
148
+ self.assertIsInstance(widget, AdminSnippetChooser)
149
+ self.assertEqual(widget.model, AdvertWithCustomPrimaryKey)