From 7882c3299f60aa227a1814224983287cd3136c9f Mon Sep 17 00:00:00 2001 From: nickmoreton Date: Mon, 15 Sep 2025 15:33:05 +0100 Subject: [PATCH 1/7] Revise the test matrix and dependencies --- .github/workflows/test.yml | 6 +++--- pyproject.toml | 19 ++++++++++--------- tox.ini | 11 +++++------ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3378b1a..090a634 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -29,8 +29,8 @@ jobs: strategy: matrix: python-version: ["3.13"] - django: ["5.1"] - wagtail: ["6.3"] + django: ["5.2"] + wagtail: ["7.1"] db: ["postgres"] services: @@ -77,7 +77,7 @@ jobs: matrix: python-version: ["3.11", "3.12"] django: ["4.2"] - wagtail: ["5.2", "6.1", "6.2"] + wagtail: ["6.3", "7.0"] db: ["sqlite"] steps: - uses: actions/checkout@v4 diff --git a/pyproject.toml b/pyproject.toml index 11b694b..3b96c26 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,30 +18,31 @@ classifiers = [ "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Framework :: Django", "Framework :: Django :: 4.2", - "Framework :: Django :: 5.0", "Framework :: Django :: 5.1", + "Framework :: Django :: 5.2", "Framework :: Wagtail", - "Framework :: Wagtail :: 5", "Framework :: Wagtail :: 6", + "Framework :: Wagtail :: 7", ] dynamic = ["version"] requires-python = ">=3.11" dependencies = [ "Django>=4.2", - "Wagtail>=5.2", - "bynder-sdk>=1.1.5,<2.0" + "Wagtail>=6.3", + "bynder-sdk>=2.0.2,<3.0", ] [project.optional-dependencies] testing = [ - "dj-database-url>=2.1.0,<3.0", - "wagtail_factories>=4.1.0,<5.0", - "responses>=0.24,<1", - "coverage>=7.0,<8.0", - "freezegun>=1.1,<2", + "dj-database-url>=2.1.0,<3.1", + "wagtail-factories>=4.3.0,<5.0", + "responses>=0.25,<1", + "coverage>=7.10,<8.0", + "freezegun>=1.5,<2", ] [project.urls] diff --git a/tox.ini b/tox.ini index 6b66acf..5548971 100644 --- a/tox.ini +++ b/tox.ini @@ -2,8 +2,8 @@ min_version = 4.11 envlist = - py{3.11,3.12}-django{4.2,5.0}-wagtail{5.2,6.1,6.2,6.3} - py3.13-django5.1-wagtail6.3 + py{3.11,3.12}-django{4.2,5.1,5.2}-wagtail{6.3,7.0,7.1} + py3.13-django{5.1,5.2}-wagtail{6.3,7.0,7.1} [gh-actions] python = @@ -34,13 +34,12 @@ extras = testing deps = django4.2: Django>=4.2,<4.3 - django5.0: Django>=5.0,<5.1 django5.1: Django>=5.1,<5.2 + django5.2: Django>=5.2,<5.3 - wagtail5.2: wagtail>=5.2,<5.3 - wagtail6.1: wagtail>=6.1,<6.2 - wagtail6.2: wagtail>=6.2,<6.3 wagtail6.3: wagtail>=6.3,<6.4 + wagtail7.0: wagtail>=7.0,<7.1 + wagtail7.1: wagtail>=7.1,<7.2 wagtailmain: git+https://github.com/wagtail/wagtail.git postgres: psycopg2>=2.9 From 83ab3059a932f4dbb3453a9c45b961ae602115f7 Mon Sep 17 00:00:00 2001 From: nickmoreton Date: Mon, 15 Sep 2025 15:33:50 +0100 Subject: [PATCH 2/7] Recreated the test migration --- tests/testapp/migrations/0001_initial.py | 231 ++++++++++++----------- 1 file changed, 117 insertions(+), 114 deletions(-) diff --git a/tests/testapp/migrations/0001_initial.py b/tests/testapp/migrations/0001_initial.py index b33e57c..433cdb4 100644 --- a/tests/testapp/migrations/0001_initial.py +++ b/tests/testapp/migrations/0001_initial.py @@ -1,9 +1,9 @@ -# Generated by Django 5.0.4 on 2024-04-10 15:44 +# Generated by Django 4.2.24 on 2025-09-15 13:59 import django.db.models.deletion import taggit.managers import wagtail.images.models -import wagtail.models.collections +import wagtail.models.media import wagtail.search.index from django.conf import settings @@ -21,7 +21,7 @@ class Migration(migrations.Migration): operations = [ migrations.CreateModel( - name="CustomDocument", + name="CustomImage", fields=[ ( "id", @@ -33,15 +33,39 @@ class Migration(migrations.Migration): ), ), ("title", models.CharField(max_length=255, verbose_name="title")), - ("file", models.FileField(upload_to="documents", verbose_name="file")), + ( + "file", + wagtail.images.models.WagtailImageField( + height_field="height", + upload_to=wagtail.images.models.get_upload_to, + verbose_name="file", + width_field="width", + ), + ), + ("width", models.IntegerField(editable=False, verbose_name="width")), + ("height", models.IntegerField(editable=False, verbose_name="height")), ( "created_at", - models.DateTimeField(auto_now_add=True, verbose_name="created at"), + models.DateTimeField( + auto_now_add=True, db_index=True, verbose_name="created at" + ), + ), + ("focal_point_x", models.PositiveIntegerField(blank=True, null=True)), + ("focal_point_y", models.PositiveIntegerField(blank=True, null=True)), + ( + "focal_point_width", + models.PositiveIntegerField(blank=True, null=True), + ), + ( + "focal_point_height", + models.PositiveIntegerField(blank=True, null=True), ), ("file_size", models.PositiveIntegerField(editable=False, null=True)), ( "file_hash", - models.CharField(blank=True, editable=False, max_length=40), + models.CharField( + blank=True, db_index=True, editable=False, max_length=40 + ), ), ( "bynder_id", @@ -100,10 +124,22 @@ class Migration(migrations.Migration): default=False, verbose_name="asset is marked as public" ), ), + ( + "original_width", + models.IntegerField( + editable=False, null=True, verbose_name="original width" + ), + ), + ( + "original_height", + models.IntegerField( + editable=False, null=True, verbose_name="original height" + ), + ), ( "collection", models.ForeignKey( - default=wagtail.models.collections.get_root_collection_id, + default=wagtail.models.media.get_root_collection_id, on_delete=django.db.models.deletion.CASCADE, related_name="+", to="wagtailcore.collection", @@ -133,14 +169,16 @@ class Migration(migrations.Migration): ), ], options={ - "verbose_name": "document", - "verbose_name_plural": "documents", "abstract": False, }, - bases=(wagtail.search.index.Indexed, models.Model), + bases=( + wagtail.images.models.ImageFileMixin, + wagtail.search.index.Indexed, + models.Model, + ), ), migrations.CreateModel( - name="CustomImage", + name="Video", fields=[ ( "id", @@ -151,41 +189,6 @@ class Migration(migrations.Migration): verbose_name="ID", ), ), - ("title", models.CharField(max_length=255, verbose_name="title")), - ( - "file", - wagtail.images.models.WagtailImageField( - height_field="height", - upload_to=wagtail.images.models.get_upload_to, - verbose_name="file", - width_field="width", - ), - ), - ("width", models.IntegerField(editable=False, verbose_name="width")), - ("height", models.IntegerField(editable=False, verbose_name="height")), - ( - "created_at", - models.DateTimeField( - auto_now_add=True, db_index=True, verbose_name="created at" - ), - ), - ("focal_point_x", models.PositiveIntegerField(blank=True, null=True)), - ("focal_point_y", models.PositiveIntegerField(blank=True, null=True)), - ( - "focal_point_width", - models.PositiveIntegerField(blank=True, null=True), - ), - ( - "focal_point_height", - models.PositiveIntegerField(blank=True, null=True), - ), - ("file_size", models.PositiveIntegerField(editable=False, null=True)), - ( - "file_hash", - models.CharField( - blank=True, db_index=True, editable=False, max_length=40 - ), - ), ( "bynder_id", models.CharField( @@ -243,6 +246,19 @@ class Migration(migrations.Migration): default=False, verbose_name="asset is marked as public" ), ), + ("title", models.CharField(max_length=255, verbose_name="title")), + ( + "created_at", + models.DateTimeField( + auto_now_add=True, db_index=True, verbose_name="created at" + ), + ), + ( + "updated_at", + models.DateTimeField( + auto_now=True, db_index=True, verbose_name="last updated at" + ), + ), ( "original_width", models.IntegerField( @@ -256,48 +272,41 @@ class Migration(migrations.Migration): ), ), ( - "collection", - models.ForeignKey( - default=wagtail.models.collections.get_root_collection_id, - on_delete=django.db.models.deletion.CASCADE, - related_name="+", - to="wagtailcore.collection", - verbose_name="collection", + "primary_source_url", + models.URLField( + help_text="A derivative using a WebM container using the VP9 codec for video and the Opus codec for audio. These are all open, royalty-free formats which are generally well-supported, although only in quite recent browsers, which is why a fallback is a good idea.", + verbose_name="primary source URL", ), ), ( - "tags", - taggit.managers.TaggableManager( + "fallback_source_url", + models.URLField( blank=True, - help_text=None, - through="taggit.TaggedItem", - to="taggit.Tag", - verbose_name="tags", + help_text="A derivative using an MP4 container and the AVC (H.264) video codec, ideally with AAC as your audio codec. This is because the MP4 container with AVC and AAC codecs within is a broadly-supported combination—by every major browser, in fact—and the quality is typically good for most use cases.", + verbose_name="fallback source URL", ), ), + ("poster_image_url", models.URLField(verbose_name="poster image URL")), ( - "uploaded_by_user", + "collection", models.ForeignKey( - blank=True, - editable=False, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - to=settings.AUTH_USER_MODEL, - verbose_name="uploaded by user", + default=wagtail.models.media.get_root_collection_id, + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="wagtailcore.collection", + verbose_name="collection", ), ), ], options={ + "verbose_name": "video", + "verbose_name_plural": "videos", "abstract": False, }, - bases=( - wagtail.images.models.ImageFileMixin, - wagtail.search.index.Indexed, - models.Model, - ), + bases=(wagtail.search.index.Indexed, models.Model), ), migrations.CreateModel( - name="Video", + name="CustomDocument", fields=[ ( "id", @@ -308,6 +317,20 @@ class Migration(migrations.Migration): verbose_name="ID", ), ), + ("title", models.CharField(max_length=255, verbose_name="title")), + ("file", models.FileField(upload_to="documents", verbose_name="file")), + ( + "created_at", + models.DateTimeField(auto_now_add=True, verbose_name="created at"), + ), + ( + "file_size", + models.PositiveBigIntegerField(editable=False, null=True), + ), + ( + "file_hash", + models.CharField(blank=True, editable=False, max_length=40), + ), ( "bynder_id", models.CharField( @@ -365,61 +388,41 @@ class Migration(migrations.Migration): default=False, verbose_name="asset is marked as public" ), ), - ("title", models.CharField(max_length=255, verbose_name="title")), ( - "created_at", - models.DateTimeField( - auto_now_add=True, db_index=True, verbose_name="created at" - ), - ), - ( - "updated_at", - models.DateTimeField( - auto_now=True, db_index=True, verbose_name="last updated at" - ), - ), - ( - "original_width", - models.IntegerField( - editable=False, null=True, verbose_name="original width" - ), - ), - ( - "original_height", - models.IntegerField( - editable=False, null=True, verbose_name="original height" - ), - ), - ( - "primary_source_url", - models.URLField( - help_text="A derivative using a WebM container using the VP9 codec for video and the Opus codec for audio. These are all open, royalty-free formats which are generally well-supported, although only in quite recent browsers, which is why a fallback is a good idea.", - verbose_name="primary source URL", + "collection", + models.ForeignKey( + default=wagtail.models.media.get_root_collection_id, + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="wagtailcore.collection", + verbose_name="collection", ), ), ( - "fallback_source_url", - models.URLField( + "tags", + taggit.managers.TaggableManager( blank=True, - help_text="A derivative using an MP4 container and the AVC (H.264) video codec, ideally with AAC as your audio codec. This is because the MP4 container with AVC and AAC codecs within is a broadly-supported combination—by every major browser, in fact—and the quality is typically good for most use cases.", - verbose_name="fallback source URL", + help_text=None, + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="tags", ), ), - ("poster_image_url", models.URLField(verbose_name="poster image URL")), ( - "collection", + "uploaded_by_user", models.ForeignKey( - default=wagtail.models.collections.get_root_collection_id, - on_delete=django.db.models.deletion.CASCADE, - related_name="+", - to="wagtailcore.collection", - verbose_name="collection", + blank=True, + editable=False, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + verbose_name="uploaded by user", ), ), ], options={ - "verbose_name": "video", - "verbose_name_plural": "videos", + "verbose_name": "document", + "verbose_name_plural": "documents", "abstract": False, }, bases=(wagtail.search.index.Indexed, models.Model), From ce55b978b699f7b0c97218bd9f43f1b0606521af Mon Sep 17 00:00:00 2001 From: nickmoreton Date: Mon, 15 Sep 2025 15:34:34 +0100 Subject: [PATCH 3/7] Remove cmpatibility code for Wagtail < 6.3 --- src/wagtail_bynder/views/document.py | 36 +++------------------------- src/wagtail_bynder/views/image.py | 36 +++------------------------- 2 files changed, 6 insertions(+), 66 deletions(-) diff --git a/src/wagtail_bynder/views/document.py b/src/wagtail_bynder/views/document.py index 6697252..27e7e8f 100644 --- a/src/wagtail_bynder/views/document.py +++ b/src/wagtail_bynder/views/document.py @@ -1,17 +1,9 @@ from typing import TYPE_CHECKING from django.conf import settings -from django.views.generic import UpdateView -from wagtail import VERSION as WAGTAIL_VERSION from wagtail.documents import get_document_model from wagtail.documents.views import chooser as chooser_views - - -if WAGTAIL_VERSION < (6, 3): - from wagtail.documents.views.documents import DeleteView - from wagtail.documents.views.documents import edit as document_edit -else: - from wagtail.documents.views.documents import DeleteView, EditView +from wagtail.documents.views.documents import DeleteView, EditView from .mixins import BynderAssetCopyMixin, RedirectToBynderMixin @@ -20,30 +12,8 @@ from django.http import HttpRequest, JsonResponse -if WAGTAIL_VERSION < (6, 3): - - class ClassBasedDocumentEditView(UpdateView): - """ - A class-based view that mimics the behaviour of wagtail's function-based - document edit view, and can be extended with view mixins. - """ - - # TODO: Use class from Wagtail once the documents app views are refactored - model = get_document_model() - pk_url_kwarg = "document_id" - - def get(self, request, *args, **kwargs): - return document_edit(request, *args, **kwargs) - - def post(self, request, *args, **kwargs): - return document_edit(request, *args, **kwargs) - - class DocumentEditView(RedirectToBynderMixin, ClassBasedDocumentEditView): - pass -else: - - class DocumentEditView(RedirectToBynderMixin, EditView): - pass +class DocumentEditView(RedirectToBynderMixin, EditView): + pass class DocumentDeleteView(RedirectToBynderMixin, DeleteView): diff --git a/src/wagtail_bynder/views/image.py b/src/wagtail_bynder/views/image.py index f07e346..4006cca 100644 --- a/src/wagtail_bynder/views/image.py +++ b/src/wagtail_bynder/views/image.py @@ -1,17 +1,9 @@ from typing import TYPE_CHECKING from django.conf import settings -from django.views.generic import UpdateView -from wagtail import VERSION as WAGTAIL_VERSION from wagtail.images import get_image_model from wagtail.images.views import chooser as chooser_views - - -if WAGTAIL_VERSION < (6, 3): - from wagtail.images.views.images import DeleteView - from wagtail.images.views.images import edit as image_edit -else: - from wagtail.images.views.images import DeleteView, EditView +from wagtail.images.views.images import DeleteView, EditView from .mixins import BynderAssetCopyMixin, RedirectToBynderMixin @@ -20,30 +12,8 @@ from django.http import HttpRequest, JsonResponse -if WAGTAIL_VERSION < (6, 3): - - class ClassBasedWagtailImageEditView(UpdateView): - """ - A class-based view that mimics the behaviour of wagtail's function-based - image edit view, and can be extended with view mixins. - """ - - # TODO: Use class from Wagtail once the image app views are refactored - model = get_image_model() - pk_url_kwarg = "image_id" - - def get(self, request, *args, **kwargs): - return image_edit(request, *args, **kwargs) - - def post(self, request, *args, **kwargs): - return image_edit(request, *args, **kwargs) - - class ImageEditView(RedirectToBynderMixin, ClassBasedWagtailImageEditView): - pass -else: - - class ImageEditView(RedirectToBynderMixin, EditView): - pass +class ImageEditView(RedirectToBynderMixin, EditView): + pass class ImageDeleteView(RedirectToBynderMixin, DeleteView): From 5df2748784e03e820c8bceb8919393b6d96f6dd2 Mon Sep 17 00:00:00 2001 From: nickmoreton Date: Mon, 15 Sep 2025 15:35:18 +0100 Subject: [PATCH 4/7] Update test assertions to be less brittle --- tests/test_image_chooser_views.py | 51 +++++++++++++------------------ 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/tests/test_image_chooser_views.py b/tests/test_image_chooser_views.py index 22d1797..50e9e5a 100644 --- a/tests/test_image_chooser_views.py +++ b/tests/test_image_chooser_views.py @@ -40,18 +40,15 @@ def test_creates_image_if_asset_id_not_recognised(self): # Assertions create_object_mock.assert_called_once() self.assertEqual(response.status_code, 200) + response_json = response.json() + self.assertEqual(response_json["step"], "chosen") + result = response_json["result"] + self.assertEqual(result["id"], str(image.id)) + self.assertEqual(result["title"], image.title) self.assertEqual( - response.json(), - { - "step": "chosen", - "result": { - "id": str(image.id), - "title": image.title, - "preview": mock.ANY, - "edit_url": reverse("wagtailimages:edit", args=[image.id]), - }, - }, + result["edit_url"], reverse("wagtailimages:edit", args=[image.id]) ) + self.assertIn("preview", result) @mock.patch("wagtail_bynder.views.image.ImageChosenView.update_object") def test_uses_existing_image_without_updating(self, update_object_mock): @@ -67,18 +64,15 @@ def test_uses_existing_image_without_updating(self, update_object_mock): # Check response content self.assertEqual(response.status_code, 200) + response_json = response.json() + self.assertEqual(response_json["step"], "chosen") + result = response_json["result"] + self.assertEqual(result["id"], str(image.id)) + self.assertEqual(result["title"], image.title) self.assertEqual( - response.json(), - { - "step": "chosen", - "result": { - "id": str(image.id), - "title": image.title, - "preview": mock.ANY, - "edit_url": reverse("wagtailimages:edit", args=[image.id]), - }, - }, + result["edit_url"], reverse("wagtailimages:edit", args=[image.id]) ) + self.assertIn("preview", result) @override_settings(BYNDER_SYNC_EXISTING_IMAGES_ON_CHOOSE=True) @mock.patch("wagtail_bynder.views.image.ImageChosenView.update_object") @@ -94,15 +88,12 @@ def test_uses_existing_image_and_updates_it(self, update_object_mock): # Check response content self.assertEqual(response.status_code, 200) + response_json = response.json() + self.assertEqual(response_json["step"], "chosen") + result = response_json["result"] + self.assertEqual(result["id"], str(image.id)) + self.assertEqual(result["title"], image.title) self.assertEqual( - response.json(), - { - "step": "chosen", - "result": { - "id": str(image.id), - "title": image.title, - "preview": mock.ANY, - "edit_url": reverse("wagtailimages:edit", args=[image.id]), - }, - }, + result["edit_url"], reverse("wagtailimages:edit", args=[image.id]) ) + self.assertIn("preview", result) From 9fcb4a4de8d4383ebe2d516655391c583894318f Mon Sep 17 00:00:00 2001 From: nickmoreton Date: Mon, 15 Sep 2025 17:50:49 +0100 Subject: [PATCH 5/7] Revert "Update test assertions to be less brittle" This reverts commit 5df2748784e03e820c8bceb8919393b6d96f6dd2. --- tests/test_image_chooser_views.py | 51 ++++++++++++++++++------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/tests/test_image_chooser_views.py b/tests/test_image_chooser_views.py index 50e9e5a..22d1797 100644 --- a/tests/test_image_chooser_views.py +++ b/tests/test_image_chooser_views.py @@ -40,15 +40,18 @@ def test_creates_image_if_asset_id_not_recognised(self): # Assertions create_object_mock.assert_called_once() self.assertEqual(response.status_code, 200) - response_json = response.json() - self.assertEqual(response_json["step"], "chosen") - result = response_json["result"] - self.assertEqual(result["id"], str(image.id)) - self.assertEqual(result["title"], image.title) self.assertEqual( - result["edit_url"], reverse("wagtailimages:edit", args=[image.id]) + response.json(), + { + "step": "chosen", + "result": { + "id": str(image.id), + "title": image.title, + "preview": mock.ANY, + "edit_url": reverse("wagtailimages:edit", args=[image.id]), + }, + }, ) - self.assertIn("preview", result) @mock.patch("wagtail_bynder.views.image.ImageChosenView.update_object") def test_uses_existing_image_without_updating(self, update_object_mock): @@ -64,15 +67,18 @@ def test_uses_existing_image_without_updating(self, update_object_mock): # Check response content self.assertEqual(response.status_code, 200) - response_json = response.json() - self.assertEqual(response_json["step"], "chosen") - result = response_json["result"] - self.assertEqual(result["id"], str(image.id)) - self.assertEqual(result["title"], image.title) self.assertEqual( - result["edit_url"], reverse("wagtailimages:edit", args=[image.id]) + response.json(), + { + "step": "chosen", + "result": { + "id": str(image.id), + "title": image.title, + "preview": mock.ANY, + "edit_url": reverse("wagtailimages:edit", args=[image.id]), + }, + }, ) - self.assertIn("preview", result) @override_settings(BYNDER_SYNC_EXISTING_IMAGES_ON_CHOOSE=True) @mock.patch("wagtail_bynder.views.image.ImageChosenView.update_object") @@ -88,12 +94,15 @@ def test_uses_existing_image_and_updates_it(self, update_object_mock): # Check response content self.assertEqual(response.status_code, 200) - response_json = response.json() - self.assertEqual(response_json["step"], "chosen") - result = response_json["result"] - self.assertEqual(result["id"], str(image.id)) - self.assertEqual(result["title"], image.title) self.assertEqual( - result["edit_url"], reverse("wagtailimages:edit", args=[image.id]) + response.json(), + { + "step": "chosen", + "result": { + "id": str(image.id), + "title": image.title, + "preview": mock.ANY, + "edit_url": reverse("wagtailimages:edit", args=[image.id]), + }, + }, ) - self.assertIn("preview", result) From 78d89dd59d0acbf6cabda9d1aea00f582489290e Mon Sep 17 00:00:00 2001 From: nickmoreton Date: Tue, 16 Sep 2025 11:42:25 +0100 Subject: [PATCH 6/7] Add conditional inclusion of 'default_alt_text' in test assertions based on Wagtail version. Technically this is a wagtail 6.4+ compatibility fix. But as 6.4 isn't a supported or tested version then 7.0+ is OK. --- tests/test_image_chooser_views.py | 73 +++++++++++++++++-------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/tests/test_image_chooser_views.py b/tests/test_image_chooser_views.py index 22d1797..09e1cd6 100644 --- a/tests/test_image_chooser_views.py +++ b/tests/test_image_chooser_views.py @@ -3,6 +3,7 @@ from django.test import TestCase, TransactionTestCase, override_settings from django.urls import reverse, reverse_lazy from testapp.factories import CustomImageFactory +from wagtail import VERSION as WAGTAIL_VERSION from wagtail.test.utils import WagtailTestUtils from .utils import TEST_ASSET_ID @@ -40,18 +41,20 @@ def test_creates_image_if_asset_id_not_recognised(self): # Assertions create_object_mock.assert_called_once() self.assertEqual(response.status_code, 200) - self.assertEqual( - response.json(), - { - "step": "chosen", - "result": { - "id": str(image.id), - "title": image.title, - "preview": mock.ANY, - "edit_url": reverse("wagtailimages:edit", args=[image.id]), - }, + expected_json = { + "step": "chosen", + "result": { + "id": str(image.id), + "title": image.title, + "preview": mock.ANY, + "edit_url": reverse("wagtailimages:edit", args=[image.id]), }, - ) + } + + if WAGTAIL_VERSION >= (7, 0): + expected_json["result"].update({"default_alt_text": image.title}) + + self.assertEqual(response.json(), expected_json) @mock.patch("wagtail_bynder.views.image.ImageChosenView.update_object") def test_uses_existing_image_without_updating(self, update_object_mock): @@ -67,18 +70,20 @@ def test_uses_existing_image_without_updating(self, update_object_mock): # Check response content self.assertEqual(response.status_code, 200) - self.assertEqual( - response.json(), - { - "step": "chosen", - "result": { - "id": str(image.id), - "title": image.title, - "preview": mock.ANY, - "edit_url": reverse("wagtailimages:edit", args=[image.id]), - }, + expected_json = { + "step": "chosen", + "result": { + "id": str(image.id), + "title": image.title, + "preview": mock.ANY, + "edit_url": reverse("wagtailimages:edit", args=[image.id]), }, - ) + } + + if WAGTAIL_VERSION >= (7, 0): + expected_json["result"].update({"default_alt_text": image.title}) + + self.assertEqual(response.json(), expected_json) @override_settings(BYNDER_SYNC_EXISTING_IMAGES_ON_CHOOSE=True) @mock.patch("wagtail_bynder.views.image.ImageChosenView.update_object") @@ -94,15 +99,17 @@ def test_uses_existing_image_and_updates_it(self, update_object_mock): # Check response content self.assertEqual(response.status_code, 200) - self.assertEqual( - response.json(), - { - "step": "chosen", - "result": { - "id": str(image.id), - "title": image.title, - "preview": mock.ANY, - "edit_url": reverse("wagtailimages:edit", args=[image.id]), - }, + expected_json = { + "step": "chosen", + "result": { + "id": str(image.id), + "title": image.title, + "preview": mock.ANY, + "edit_url": reverse("wagtailimages:edit", args=[image.id]), }, - ) + } + + if WAGTAIL_VERSION >= (7, 0): + expected_json["result"].update({"default_alt_text": image.title}) + + self.assertEqual(response.json(), expected_json) From d9839c1afc9c5f877f72197ed012187e3659eea8 Mon Sep 17 00:00:00 2001 From: nickmoreton Date: Tue, 16 Sep 2025 15:14:01 +0100 Subject: [PATCH 7/7] Update telepath import location --- src/wagtail_bynder/widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wagtail_bynder/widgets.py b/src/wagtail_bynder/widgets.py index cd2a6ac..b00d36f 100644 --- a/src/wagtail_bynder/widgets.py +++ b/src/wagtail_bynder/widgets.py @@ -3,8 +3,8 @@ from django.utils.functional import cached_property from django.utils.translation import gettext_lazy as _ from wagtail.admin.staticfiles import versioned_static +from wagtail.admin.telepath import register from wagtail.admin.widgets import BaseChooser, BaseChooserAdapter -from wagtail.telepath import register from wagtail_bynder import get_video_model