From 04bfc7b2a06b71e187b6714b339ea559a3aac8c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sascha=20I=C3=9Fbr=C3=BCcker?= Date: Mon, 23 Sep 2024 23:20:42 +0200 Subject: [PATCH] prevent creating duplicate URLs on edit --- bookmarks/models.py | 16 ++++++++++ bookmarks/tests/test_bookmark_edit_view.py | 36 ++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/bookmarks/models.py b/bookmarks/models.py index e65c2251..333c1b1d 100644 --- a/bookmarks/models.py +++ b/bookmarks/models.py @@ -168,6 +168,22 @@ def has_notes(self): self.instance and self.instance.notes ) + def clean(self): + cleaned_data = super().clean() + url = cleaned_data.get("url") + + if self.instance.pk and url: + # Ensure there is no existing Bookmark with the same URL + existing_bookmark = ( + Bookmark.objects.filter(url=url, owner=self.instance.owner) + .exclude(pk=self.instance.pk) + .first() + ) + if existing_bookmark: + self.add_error("url", "A bookmark with this URL already exists.") + + return cleaned_data + class BookmarkSearch: SORT_ADDED_ASC = "added_asc" diff --git a/bookmarks/tests/test_bookmark_edit_view.py b/bookmarks/tests/test_bookmark_edit_view.py index 18b04ec9..1ca7dba4 100644 --- a/bookmarks/tests/test_bookmark_edit_view.py +++ b/bookmarks/tests/test_bookmark_edit_view.py @@ -141,6 +141,42 @@ def test_should_prefill_bookmark_form_fields(self): html, ) + def test_should_prevent_changing_url_to_existing_url_for_same_owner(self): + edited_bookmark = self.setup_bookmark(url="http://example.com/edited") + existing_bookmark = self.setup_bookmark(url="http://example.com/existing") + + form_data = self.create_form_data( + {"id": edited_bookmark.id, "url": existing_bookmark.url} + ) + response = self.client.post( + reverse("bookmarks:edit", args=[edited_bookmark.id]), form_data + ) + + self.assertEqual(response.status_code, 422) + self.assertInHTML( + "
  • A bookmark with this URL already exists.
  • ", + response.content.decode(), + ) + edited_bookmark.refresh_from_db() + self.assertNotEqual(edited_bookmark.url, existing_bookmark.url) + + def test_should_allow_changing_url_to_existing_url_for_different_owner(self): + edited_bookmark = self.setup_bookmark(url="http://example.com/edited") + existing_bookmark = self.setup_bookmark( + url="http://example.com/existing", user=User.objects.create_user("other") + ) + + form_data = self.create_form_data( + {"id": edited_bookmark.id, "url": existing_bookmark.url} + ) + response = self.client.post( + reverse("bookmarks:edit", args=[edited_bookmark.id]), form_data + ) + + self.assertEqual(response.status_code, 302) + edited_bookmark.refresh_from_db() + self.assertEqual(edited_bookmark.url, existing_bookmark.url) + def test_should_redirect_to_return_url(self): bookmark = self.setup_bookmark() form_data = self.create_form_data()