From ec826241c769522d574bc34cc41c5386e060cc10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Wo=CC=88ginger?= Date: Mon, 29 Jan 2024 22:11:11 +0100 Subject: [PATCH] split nodes changeset in different use cases --- lib/radiator/outline.ex | 32 ++++++--------- lib/radiator/outline/node.ex | 44 ++++++++++++++------- lib/radiator_web/live/episode_live/index.ex | 2 +- test/radiator/outline_test.exs | 13 ++---- 4 files changed, 47 insertions(+), 44 deletions(-) diff --git a/lib/radiator/outline.ex b/lib/radiator/outline.ex index d50ca3fd..455611d1 100644 --- a/lib/radiator/outline.ex +++ b/lib/radiator/outline.ex @@ -92,26 +92,33 @@ defmodule Radiator.Outline do """ def create_node(attrs \\ %{}) do %Node{} - |> Node.changeset(attrs) + |> Node.insert_changeset(attrs) + |> Repo.insert() + |> broadcast_node_action(:insert) + end + + def create_node(attrs, %{id: id}) do + %Node{creator_id: id} + |> Node.insert_changeset(attrs) |> Repo.insert() |> broadcast_node_action(:insert) end @doc """ - Updates a node. + Updates a nodes content. ## Examples - iex> update_node(node, %{field: new_value}) + iex> update_node_content(node, %{content: new_value}) {:ok, %Node{}} - iex> update_node(node, %{field: bad_value}) + iex> update_node_content(node, %{content: nil}) {:error, %Ecto.Changeset{}} """ - def update_node(%Node{} = node, attrs) do + def update_node_content(%Node{} = node, attrs) do node - |> Node.changeset(attrs) + |> Node.update_content_changeset(attrs) |> Repo.update() |> broadcast_node_action(:update) end @@ -134,19 +141,6 @@ defmodule Radiator.Outline do |> broadcast_node_action(:delete) end - @doc """ - Returns an `%Ecto.Changeset{}` for tracking node changes. - - ## Examples - - iex> change_node(node) - %Ecto.Changeset{data: %Node{}} - - """ - def change_node(%Node{} = node, attrs \\ %{}) do - Node.changeset(node, attrs) - end - defp broadcast_node_action({:ok, node}, action) do PubSub.broadcast(Radiator.PubSub, @topic, {action, node}) {:ok, node} diff --git a/lib/radiator/outline/node.ex b/lib/radiator/outline/node.ex index 8fb151ac..0ce640c6 100644 --- a/lib/radiator/outline/node.ex +++ b/lib/radiator/outline/node.ex @@ -10,6 +10,7 @@ defmodule Radiator.Outline.Node do @derive {Jason.Encoder, only: [:uuid, :content, :creator_id, :parent_id, :prev_id]} @primary_key {:uuid, :binary_id, autogenerate: true} + schema "outline_nodes" do field :content, :string field :creator_id, :integer @@ -21,25 +22,38 @@ defmodule Radiator.Outline.Node do timestamps(type: :utc_datetime) end - @required_fields [ - :episode_id - ] - - @optional_fields [ - :content, - :creator_id, - :parent_id, - :prev_id - ] + @doc """ + A changeset for inserting a new node + Work in progress. Since we currently ignore the tree structure, there is + no concept for a root node. + Also questionable wether a node really needs a content from beginning. So probably a root + doesnt have a content + Another issue might be we need to create the uuid upfront and pass it here + """ + def insert_changeset(node, attributes) do + node + |> cast(attributes, [:content, :episode_id, :creator_id, :parent_id, :prev_id]) + |> update_change(:content, &trim/1) + |> validate_required([:content, :episode_id]) + end - @all_fields @optional_fields ++ @required_fields + @doc """ + Changeset for moving a node + Only the parent_id is allowed and expected to be changed + """ + def move_changeset(node, attrs) do + node + |> cast(attrs, [:parent_id]) + end - @doc false - def changeset(node, attrs) do + @doc """ + Changeset for updating the content of a node + """ + def update_content_changeset(node, attrs) do node - |> cast(attrs, @all_fields) + |> cast(attrs, [:content]) |> update_change(:content, &trim/1) - |> validate_required(@required_fields) + |> validate_required([:content]) end defp trim(content) when is_binary(content), do: String.trim(content) diff --git a/lib/radiator_web/live/episode_live/index.ex b/lib/radiator_web/live/episode_live/index.ex index bacc25ae..0972bbd8 100644 --- a/lib/radiator_web/live/episode_live/index.ex +++ b/lib/radiator_web/live/episode_live/index.ex @@ -61,7 +61,7 @@ defmodule RadiatorWeb.EpisodeLive.Index do case Outline.get_node(uuid) do nil -> nil - node -> Outline.update_node(node, attrs) + node -> Outline.update_node_content(node, attrs) end socket diff --git a/test/radiator/outline_test.exs b/test/radiator/outline_test.exs index c44e6ea9..a30d2380 100644 --- a/test/radiator/outline_test.exs +++ b/test/radiator/outline_test.exs @@ -51,17 +51,17 @@ defmodule Radiator.OutlineTest do assert {:error, %Ecto.Changeset{}} = Outline.create_node(@invalid_attrs) end - test "update_node/2 with valid data updates the node" do + test "update_node_content/2 with valid data updates the node" do node = node_fixture() update_attrs = %{content: "some updated content"} - assert {:ok, %Node{} = node} = Outline.update_node(node, update_attrs) + assert {:ok, %Node{} = node} = Outline.update_node_content(node, update_attrs) assert node.content == "some updated content" end - test "update_node/2 with invalid data returns error changeset" do + test "update_node_content/2 with invalid data returns error changeset" do node = node_fixture() - assert {:error, %Ecto.Changeset{}} = Outline.update_node(node, @invalid_attrs) + assert {:error, %Ecto.Changeset{}} = Outline.update_node_content(node, @invalid_attrs) assert node == Outline.get_node!(node.uuid) end @@ -70,10 +70,5 @@ defmodule Radiator.OutlineTest do assert {:ok, %Node{}} = Outline.delete_node(node) assert_raise Ecto.NoResultsError, fn -> Outline.get_node!(node.uuid) end end - - test "change_node/1 returns a node changeset" do - node = node_fixture() - assert %Ecto.Changeset{} = Outline.change_node(node) - end end end