From 2e7a81c121af4cd55c94cd4900fb18544958566e Mon Sep 17 00:00:00 2001
From: sloane <git@sloanelybutsurely.com>
Date: Tue, 25 Mar 2025 22:21:51 -0400
Subject: [PATCH] prevent changing slugs of published posts

---
 lib/core/posts/post.ex   |  7 +++++++
 test/core/posts_test.exs | 11 +++++++++++
 2 files changed, 18 insertions(+)

diff --git a/lib/core/posts/post.ex b/lib/core/posts/post.ex
index d2dad96..52de1f8 100644
--- a/lib/core/posts/post.ex
+++ b/lib/core/posts/post.ex
@@ -13,6 +13,13 @@ defmodule Core.Posts.Post do
     changeset =
       case get_field(changeset, :kind) do
         :blog ->
+          changeset =
+            if not is_nil(get_field(changeset, :published_at)) and changed?(changeset, :slug) do
+              add_error(changeset, :slug, "cannot change slug of published post")
+            else
+              changeset
+            end
+
           validate_required(changeset, [:title, :slug])
 
         :status ->
diff --git a/test/core/posts_test.exs b/test/core/posts_test.exs
index 3adacd3..c3a053a 100644
--- a/test/core/posts_test.exs
+++ b/test/core/posts_test.exs
@@ -114,6 +114,17 @@ defmodule Test.Core.PostsTest do
       assert post.title == "A new title"
     end
 
+    @tag blog: :to_update
+    test "prevents updating the slug of a published post", %{blogs: %{to_update: post}} do
+      {:ok, post} = Core.Posts.publish_post(post)
+
+      assert {:error, %Ecto.Changeset{} = changeset} =
+               Core.Posts.update_post(post, %{slug: "a-new-slug"})
+
+      refute changeset.valid?
+      assert "cannot change slug of published post" in errors_on(changeset).slug
+    end
+
     @tag status: :to_update
     test "updates a status post", %{statuses: %{to_update: post}} do
       assert {:ok, %Schema.Post{} = post} = Core.Posts.update_post(post, %{body: "Hello, World!"})