Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create nodecontainers also for episodes #599

Merged
merged 13 commits into from
Dec 17, 2024
3 changes: 2 additions & 1 deletion lib/radiator/outline.ex
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,8 @@ defmodule Radiator.Outline do
"content" => new_node_content,
"episode_id" => node.episode_id,
"parent_id" => node.parent_id,
"prev_id" => node.uuid
"prev_id" => node.uuid,
"outline_node_container_id" => node.outline_node_container_id
}

{:ok, %NodeRepoResult{node: new_node, next: old_next_node}} =
Expand Down
14 changes: 12 additions & 2 deletions lib/radiator/outline/command_processor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ defmodule Radiator.Outline.CommandProcessor do

alias Radiator.EventStore
alias Radiator.Outline
alias Radiator.Outline.NodeRepoResult

alias Radiator.Outline.Command
alias Radiator.Outline.NodeRepoResult
alias Radiator.Podcast

alias Radiator.Outline.Command.{
ChangeNodeContentCommand,
Expand Down Expand Up @@ -54,6 +54,7 @@ defmodule Radiator.Outline.CommandProcessor do

defp process_command(%InsertNodeCommand{payload: payload, user_id: user_id} = command) do
payload
|> add_node_container()
|> Map.merge(%{"user_id" => user_id})
|> Outline.insert_node()
|> handle_insert_node_result(command)
Expand Down Expand Up @@ -216,4 +217,13 @@ defmodule Radiator.Outline.CommandProcessor do
Logger.error("Update node content failed. #{inspect(changeset)}")
:error
end

defp add_node_container(%{"outline_node_container_id" => _outline_node_container_id} = payload),
do: payload

defp add_node_container(%{"episode_id" => episode_id} = payload) do
episode = Podcast.get_episode!(episode_id)

Map.put(payload, "outline_node_container_id", episode.outline_node_container_id)
end
end
5 changes: 3 additions & 2 deletions lib/radiator/outline/node.ex
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,11 @@ defmodule Radiator.Outline.Node do
:parent_id,
:prev_id,
:show_id,
:_type
:_type,
:outline_node_container_id
])
|> put_uuid()
|> validate_required([:show_id])
|> validate_required([:outline_node_container_id])
|> validate_format(:uuid, ~r/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i)
|> unique_constraint(:uuid, name: "outline_nodes_pkey")
end
Expand Down
22 changes: 18 additions & 4 deletions lib/radiator/podcast.ex
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@ defmodule Radiator.Podcast do
{:error, %Ecto.Changeset{}}

"""

def create_show(attrs \\ %{}) do
Ecto.Multi.new()
|> Ecto.Multi.insert(:inbox, NodeContainer.changeset(%NodeContainer{}, %{}))
Expand Down Expand Up @@ -474,6 +473,7 @@ defmodule Radiator.Podcast do
from e in Episode,
where: [show_id: ^show_id, is_deleted: false],
order_by: [desc: e.number],
preload: [:inbox_node_container, :outline_node_container],
limit: 1
)
end
Expand All @@ -491,9 +491,23 @@ defmodule Radiator.Podcast do

"""
def create_episode(attrs \\ %{}) do
%Episode{}
|> Episode.changeset(attrs)
|> Repo.insert()
Ecto.Multi.new()
|> Ecto.Multi.insert(:inbox, NodeContainer.changeset(%NodeContainer{}, %{}))
|> Ecto.Multi.insert(:root, NodeContainer.changeset(%NodeContainer{}, %{}))
|> Ecto.Multi.insert(:episode, fn %{root: root, inbox: inbox} ->
%Episode{}
|> Episode.changeset(attrs)
|> Ecto.Changeset.put_assoc(:inbox_node_container, inbox)
|> Ecto.Changeset.put_assoc(:outline_node_container, root)
end)
|> Repo.transaction()
|> case do
{:ok, %{episode: episode}} ->
{:ok, episode}

{:error, _tag, error, _others} ->
{:error, error}
end
end

def get_next_episode_number(show_id) do
Expand Down
8 changes: 5 additions & 3 deletions lib/radiator_web/controllers/api/outline_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ defmodule RadiatorWeb.Api.OutlineController do
token
|> decode_token()
|> get_user_by_token()
|> create_node(content, episode.id)
# Deprecated: for bookmarklet
|> create_node(content, episode)
|> get_response()

conn
Expand All @@ -32,11 +33,12 @@ defmodule RadiatorWeb.Api.OutlineController do
defp create_node(nil, _, _), do: {:error, :user}
defp create_node(_, _, nil), do: {:error, :episode}

defp create_node(user, content, episode_id) do
defp create_node(user, content, episode) do
Outline.insert_node(%{
"content" => content,
"creator_id" => user.id,
"episode_id" => episode_id
"episode_id" => episode.id,
"outline_node_container_id" => episode.outline_node_container_id
})
end

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
defmodule Radiator.Repo.Migrations.AddNodeContainersToExistingRecords do
use Ecto.Migration

import Ecto.Query, warn: false
alias Radiator.Repo
alias Radiator.Outline.{Node, NodeContainer}
alias Radiator.Podcast.{Episode, Show}

def up do
# Disable automatic timestamps for this migration
Application.put_env(:radiator, :disable_timestamps, true)

# Add node containers to existing shows
Repo.all(Show)
|> Enum.each(fn show ->
# Create containers
{:ok, inbox} = %NodeContainer{} |> Repo.insert()
{:ok, outline} = %NodeContainer{} |> Repo.insert()

# Update show with containers
show
|> Ecto.Changeset.change(%{
inbox_node_container_id: inbox.id,
outline_node_container_id: outline.id
})
|> Repo.update!()

# Update all nodes belonging to this show
from(n in Node, where: n.show_id == ^show.id)
|> Repo.update_all(set: [outline_node_container_id: outline.id])
end)

# Add node containers to existing episodes
Repo.all(Episode)
|> Enum.each(fn episode ->
# Create containers
{:ok, inbox} = %NodeContainer{} |> Repo.insert()
{:ok, outline} = %NodeContainer{} |> Repo.insert()

# Update episode with containers
episode
|> Ecto.Changeset.change(%{
inbox_node_container_id: inbox.id,
outline_node_container_id: outline.id
})
|> Repo.update!()

# Update all nodes belonging to this episode
from(n in Node, where: n.episode_id == ^episode.id)
|> Repo.update_all(set: [outline_node_container_id: outline.id])
end)

# Re-enable automatic timestamps
Application.delete_env(:radiator, :disable_timestamps)
end

def down do
# In down migration, we'll remove the container associations but keep the containers
# to prevent data loss

# Remove container associations from shows
from(s in Show)
|> Repo.update_all(
set: [
inbox_node_container_id: nil,
outline_node_container_id: nil
]
)

# Remove container associations from episodes
from(e in Episode)
|> Repo.update_all(
set: [
inbox_node_container_id: nil,
outline_node_container_id: nil
]
)

# Remove container associations from nodes
from(n in Node)
|> Repo.update_all(set: [outline_node_container_id: nil])
end
end
15 changes: 8 additions & 7 deletions priv/repo/seeds.exs
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,15 @@ alias Radiator.Outline.NodeRepository
NodeRepository.create_node(%{
"content" => "Node 1",
"show_id" => current_episode.show_id,
"outline_node_container_id" => current_episode.outline_node_container_id,
"episode_id" => current_episode.id
})

{:ok, node2} =
NodeRepository.create_node(%{
"content" => "Node 2",
"show_id" => current_episode.show_id,
"outline_node_container_id" => current_episode.outline_node_container_id,
"episode_id" => current_episode.id,
"prev_id" => node1.uuid
})
Expand All @@ -71,6 +73,7 @@ alias Radiator.Outline.NodeRepository
NodeRepository.create_node(%{
"content" => "Node 3",
"show_id" => current_episode.show_id,
"outline_node_container_id" => current_episode.outline_node_container_id,
"episode_id" => current_episode.id,
"prev_id" => node2.uuid
})
Expand All @@ -79,6 +82,7 @@ alias Radiator.Outline.NodeRepository
NodeRepository.create_node(%{
"content" => "Node 4",
"show_id" => current_episode.show_id,
"outline_node_container_id" => current_episode.outline_node_container_id,
"episode_id" => current_episode.id,
"prev_id" => node3.uuid
})
Expand All @@ -87,6 +91,7 @@ alias Radiator.Outline.NodeRepository
NodeRepository.create_node(%{
"content" => "Node 2.1",
"show_id" => current_episode.show_id,
"outline_node_container_id" => current_episode.outline_node_container_id,
"episode_id" => current_episode.id,
"parent_id" => node2.uuid
})
Expand All @@ -95,6 +100,7 @@ alias Radiator.Outline.NodeRepository
NodeRepository.create_node(%{
"content" => "Node 2.2",
"show_id" => current_episode.show_id,
"outline_node_container_id" => current_episode.outline_node_container_id,
"episode_id" => current_episode.id,
"parent_id" => node2.uuid,
"prev_id" => node21.uuid
Expand All @@ -104,6 +110,7 @@ alias Radiator.Outline.NodeRepository
NodeRepository.create_node(%{
"content" => "Node 2.1.1",
"show_id" => current_episode.show_id,
"outline_node_container_id" => current_episode.outline_node_container_id,
"episode_id" => current_episode.id,
"parent_id" => node21.uuid
})
Expand All @@ -112,14 +119,8 @@ alias Radiator.Outline.NodeRepository
NodeRepository.create_node(%{
"content" => "Node 2.1.2",
"show_id" => current_episode.show_id,
"outline_node_container_id" => current_episode.outline_node_container_id,
"episode_id" => current_episode.id,
"parent_id" => node21.uuid,
"prev_id" => node211.uuid
})

{:ok, _past_parent_node} =
NodeRepository.create_node(%{
"content" => "Old Content",
"show_id" => current_episode.show_id,
"episode_id" => past_episode.id
})
9 changes: 8 additions & 1 deletion test/radiator/outline/node_repository_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@ defmodule Radiator.Outline.NodeRepositoryTest do
describe "create_node/1" do
test "with valid data creates a node" do
episode = PodcastFixtures.episode_fixture()
valid_attrs = %{content: "some content", episode_id: episode.id, show_id: episode.show_id}

valid_attrs = %{
content: "some content",
episode_id: episode.id,
show_id: episode.show_id,
outline_node_container_id: episode.outline_node_container_id
}

assert {:ok, %Node{} = node} = NodeRepository.create_node(valid_attrs)
assert node.content == "some content"
Expand All @@ -27,6 +33,7 @@ defmodule Radiator.Outline.NodeRepositoryTest do
content: "some content",
episode_id: episode.id,
show_id: episode.show_id,
outline_node_container_id: episode.outline_node_container_id,
creator_id: user.id
}

Expand Down
3 changes: 3 additions & 0 deletions test/radiator/outline/node_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ defmodule Radiator.Outline.NodeTest do
"uuid" => uuid,
"episode_id" => episode.id,
"show_id" => episode.show_id,
"outline_node_container_id" => episode.outline_node_container_id,
"content" => "Node Content"
}

Expand All @@ -48,6 +49,7 @@ defmodule Radiator.Outline.NodeTest do
attributes = %{
"episode_id" => episode.id,
"show_id" => episode.show_id,
"outline_node_container_id" => episode.outline_node_container_id,
"content" => "Node Content"
}

Expand All @@ -62,6 +64,7 @@ defmodule Radiator.Outline.NodeTest do
"uuid" => "not-a-uuid",
"episode_id" => episode.id,
"show_id" => episode.show_id,
"outline_node_container_id" => episode.outline_node_container_id,
"content" => "Node Content"
}

Expand Down
8 changes: 7 additions & 1 deletion test/radiator/outline/validations_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ defmodule Radiator.Outline.ValidationsTest do
%{
episode_id: episode_id,
show_id: show_id,
outline_node_container_id: node_1.outline_node_container_id,
parent_id: node_1.uuid,
prev_id: nil,
content: "child of node 1"
Expand All @@ -40,6 +41,7 @@ defmodule Radiator.Outline.ValidationsTest do
%{
episode_id: episode_id,
show_id: show_id,
outline_node_container_id: node_2.outline_node_container_id,
parent_id: node_2.parent_id,
prev_id: node_2.prev_id
}
Expand All @@ -56,6 +58,7 @@ defmodule Radiator.Outline.ValidationsTest do
%{
episode_id: episode_id,
show_id: show_id,
outline_node_container_id: node_2.outline_node_container_id,
parent_id: node_2.parent_id,
prev_id: node_2.prev_id
}
Expand All @@ -66,12 +69,14 @@ defmodule Radiator.Outline.ValidationsTest do
end

test "when a parent has two childs with prev_id nil the tree is invalid", %{
nested_node_1: %Node{episode_id: episode_id, parent_id: parent_id, show_id: show_id}
nested_node_1:
%Node{episode_id: episode_id, parent_id: parent_id, show_id: show_id} = nested_node_1
} do
{:ok, %Node{} = _node_invalid} =
%{
episode_id: episode_id,
show_id: show_id,
outline_node_container_id: nested_node_1.outline_node_container_id,
parent_id: parent_id,
prev_id: nil,
content: "invalid node"
Expand All @@ -90,6 +95,7 @@ defmodule Radiator.Outline.ValidationsTest do
%{
episode_id: episode_id,
show_id: show_id,
outline_node_container_id: nested_node_2.outline_node_container_id,
parent_id: parent_node.uuid,
prev_id: nested_node_2.uuid
}
Expand Down
Loading
Loading