diff --git a/lib/pinchflat_web/controllers/media_sources/channel_controller.ex b/lib/pinchflat_web/controllers/media_sources/channel_controller.ex deleted file mode 100644 index c17cee8..0000000 --- a/lib/pinchflat_web/controllers/media_sources/channel_controller.ex +++ /dev/null @@ -1,75 +0,0 @@ -defmodule PinchflatWeb.MediaSources.ChannelController do - use PinchflatWeb, :controller - - alias Pinchflat.Profiles - alias Pinchflat.MediaSource - alias Pinchflat.MediaSource.Channel - - def index(conn, _params) do - channels = MediaSource.list_sources() - - render(conn, :index, channels: channels) - end - - def new(conn, _params) do - changeset = MediaSource.change_source(%Channel{}) - - render(conn, :new, changeset: changeset, media_profiles: media_profiles()) - end - - def create(conn, %{"channel" => channel_params}) do - case MediaSource.create_source(channel_params) do - {:ok, channel} -> - conn - |> put_flash(:info, "Channel created successfully.") - |> redirect(to: ~p"/media_sources/channels/#{channel}") - - {:error, %Ecto.Changeset{} = changeset} -> - render(conn, :new, changeset: changeset, media_profiles: media_profiles()) - end - end - - def show(conn, %{"id" => id}) do - channel = MediaSource.get_source!(id) - - render(conn, :show, channel: channel) - end - - def edit(conn, %{"id" => id}) do - channel = MediaSource.get_source!(id) - changeset = MediaSource.change_source(channel) - - render(conn, :edit, channel: channel, changeset: changeset, media_profiles: media_profiles()) - end - - def update(conn, %{"id" => id, "channel" => channel_params}) do - channel = MediaSource.get_source!(id) - - case MediaSource.update_source(channel, channel_params) do - {:ok, channel} -> - conn - |> put_flash(:info, "Channel updated successfully.") - |> redirect(to: ~p"/media_sources/channels/#{channel}") - - {:error, %Ecto.Changeset{} = changeset} -> - render(conn, :edit, - channel: channel, - changeset: changeset, - media_profiles: media_profiles() - ) - end - end - - def delete(conn, %{"id" => id}) do - channel = MediaSource.get_source!(id) - {:ok, _channel} = MediaSource.delete_source(channel) - - conn - |> put_flash(:info, "Channel deleted successfully.") - |> redirect(to: ~p"/media_sources/channels") - end - - defp media_profiles do - Profiles.list_media_profiles() - end -end diff --git a/lib/pinchflat_web/controllers/media_sources/channel_html/edit.html.heex b/lib/pinchflat_web/controllers/media_sources/channel_html/edit.html.heex deleted file mode 100644 index c65d810..0000000 --- a/lib/pinchflat_web/controllers/media_sources/channel_html/edit.html.heex +++ /dev/null @@ -1,12 +0,0 @@ -<.header> - Edit Channel <%= @channel.id %> - <:subtitle>Use this form to manage channel records in your database. - - -<.channel_form - changeset={@changeset} - media_profiles={@media_profiles} - action={~p"/media_sources/channels/#{@channel}"} -/> - -<.back navigate={~p"/media_sources/channels"}>Back to channels diff --git a/lib/pinchflat_web/controllers/media_sources/channel_html/index.html.heex b/lib/pinchflat_web/controllers/media_sources/channel_html/index.html.heex deleted file mode 100644 index b78a61b..0000000 --- a/lib/pinchflat_web/controllers/media_sources/channel_html/index.html.heex +++ /dev/null @@ -1,28 +0,0 @@ -<.header> - Listing Channels - <:actions> - <.link href={~p"/media_sources/channels/new"}> - <.button>New Channel - - - - -<.table id="channels" rows={@channels} row_click={&JS.navigate(~p"/media_sources/channels/#{&1}")}> - <:col :let={channel} label="Name"><%= channel.name %> - <:col :let={channel} label="Channel"><%= channel.channel_id %> - <:action :let={channel}> -
- <.link navigate={~p"/media_sources/channels/#{channel}"}>Show -
- <.link navigate={~p"/media_sources/channels/#{channel}/edit"}>Edit - - <:action :let={channel}> - <.link - href={~p"/media_sources/channels/#{channel}"} - method="delete" - data-confirm="Are you sure?" - > - Delete - - - diff --git a/lib/pinchflat_web/controllers/media_sources/channel_html/new.html.heex b/lib/pinchflat_web/controllers/media_sources/channel_html/new.html.heex deleted file mode 100644 index b09a477..0000000 --- a/lib/pinchflat_web/controllers/media_sources/channel_html/new.html.heex +++ /dev/null @@ -1,12 +0,0 @@ -<.header> - New Channel - <:subtitle>Use this form to manage channel records in your database. - - -<.channel_form - changeset={@changeset} - media_profiles={@media_profiles} - action={~p"/media_sources/channels"} -/> - -<.back navigate={~p"/media_sources/channels"}>Back to channels diff --git a/lib/pinchflat_web/controllers/media_sources/channel_html/show.html.heex b/lib/pinchflat_web/controllers/media_sources/channel_html/show.html.heex deleted file mode 100644 index 0f59e3b..0000000 --- a/lib/pinchflat_web/controllers/media_sources/channel_html/show.html.heex +++ /dev/null @@ -1,17 +0,0 @@ -<.header> - Channel <%= @channel.id %> - <:subtitle>This is a channel record from your database. - <:actions> - <.link href={~p"/media_sources/channels/#{@channel}/edit"}> - <.button>Edit channel - - - - -<.list> - <:item title="Channel Name"><%= @channel.name %> - <:item title="Channel ID"><%= @channel.channel_id %> - <:item title="Original URL"><%= @channel.original_url %> - - -<.back navigate={~p"/media_sources/channels"}>Back to channels diff --git a/lib/pinchflat_web/controllers/media_sources/source_controller.ex b/lib/pinchflat_web/controllers/media_sources/source_controller.ex new file mode 100644 index 0000000..ac220fa --- /dev/null +++ b/lib/pinchflat_web/controllers/media_sources/source_controller.ex @@ -0,0 +1,75 @@ +defmodule PinchflatWeb.MediaSources.SourceController do + use PinchflatWeb, :controller + + alias Pinchflat.Profiles + alias Pinchflat.MediaSource + alias Pinchflat.MediaSource.Channel + + def index(conn, _params) do + sources = MediaSource.list_sources() + + render(conn, :index, sources: sources) + end + + def new(conn, _params) do + changeset = MediaSource.change_source(%Channel{}) + + render(conn, :new, changeset: changeset, media_profiles: media_profiles()) + end + + def create(conn, %{"source" => source_params}) do + case MediaSource.create_source(source_params) do + {:ok, source} -> + conn + |> put_flash(:info, "Source created successfully.") + |> redirect(to: ~p"/media_sources/sources/#{source}") + + {:error, %Ecto.Changeset{} = changeset} -> + render(conn, :new, changeset: changeset, media_profiles: media_profiles()) + end + end + + def show(conn, %{"id" => id}) do + source = MediaSource.get_source!(id) + + render(conn, :show, source: source) + end + + def edit(conn, %{"id" => id}) do + source = MediaSource.get_source!(id) + changeset = MediaSource.change_source(source) + + render(conn, :edit, source: source, changeset: changeset, media_profiles: media_profiles()) + end + + def update(conn, %{"id" => id, "source" => source_params}) do + source = MediaSource.get_source!(id) + + case MediaSource.update_source(source, source_params) do + {:ok, source} -> + conn + |> put_flash(:info, "Channel updated successfully.") + |> redirect(to: ~p"/media_sources/sources/#{source}") + + {:error, %Ecto.Changeset{} = changeset} -> + render(conn, :edit, + source: source, + changeset: changeset, + media_profiles: media_profiles() + ) + end + end + + def delete(conn, %{"id" => id}) do + source = MediaSource.get_source!(id) + {:ok, _source} = MediaSource.delete_source(source) + + conn + |> put_flash(:info, "Channel deleted successfully.") + |> redirect(to: ~p"/media_sources/sources") + end + + defp media_profiles do + Profiles.list_media_profiles() + end +end diff --git a/lib/pinchflat_web/controllers/media_sources/channel_html.ex b/lib/pinchflat_web/controllers/media_sources/source_html.ex similarity index 77% rename from lib/pinchflat_web/controllers/media_sources/channel_html.ex rename to lib/pinchflat_web/controllers/media_sources/source_html.ex index 0feb191..9531a59 100644 --- a/lib/pinchflat_web/controllers/media_sources/channel_html.ex +++ b/lib/pinchflat_web/controllers/media_sources/source_html.ex @@ -1,16 +1,16 @@ -defmodule PinchflatWeb.MediaSources.ChannelHTML do +defmodule PinchflatWeb.MediaSources.SourceHTML do use PinchflatWeb, :html - embed_templates "channel_html/*" + embed_templates "source_html/*" @doc """ - Renders a channel form. + Renders a source form. """ attr :changeset, Ecto.Changeset, required: true attr :action, :string, required: true attr :media_profiles, :list, required: true - def channel_form(assigns) + def source_form(assigns) def friendly_index_frequencies do [ diff --git a/lib/pinchflat_web/controllers/media_sources/source_html/edit.html.heex b/lib/pinchflat_web/controllers/media_sources/source_html/edit.html.heex new file mode 100644 index 0000000..d1afc04 --- /dev/null +++ b/lib/pinchflat_web/controllers/media_sources/source_html/edit.html.heex @@ -0,0 +1,12 @@ +<.header> + Edit Source <%= @source.id %> + <:subtitle>Use this form to manage source records in your database. + + +<.source_form + changeset={@changeset} + media_profiles={@media_profiles} + action={~p"/media_sources/sources/#{@source}"} +/> + +<.back navigate={~p"/media_sources/sources"}>Back to sources diff --git a/lib/pinchflat_web/controllers/media_sources/source_html/index.html.heex b/lib/pinchflat_web/controllers/media_sources/source_html/index.html.heex new file mode 100644 index 0000000..348873d --- /dev/null +++ b/lib/pinchflat_web/controllers/media_sources/source_html/index.html.heex @@ -0,0 +1,24 @@ +<.header> + Listing Sources + <:actions> + <.link href={~p"/media_sources/sources/new"}> + <.button>New Source + + + + +<.table id="sources" rows={@sources} row_click={&JS.navigate(~p"/media_sources/sources/#{&1}")}> + <:col :let={source} label="Name"><%= source.name %> + <:col :let={source} label="Source"><%= source.collection_id %> + <:action :let={source}> +
+ <.link navigate={~p"/media_sources/sources/#{source}"}>Show +
+ <.link navigate={~p"/media_sources/sources/#{source}/edit"}>Edit + + <:action :let={source}> + <.link href={~p"/media_sources/sources/#{source}"} method="delete" data-confirm="Are you sure?"> + Delete + + + diff --git a/lib/pinchflat_web/controllers/media_sources/source_html/new.html.heex b/lib/pinchflat_web/controllers/media_sources/source_html/new.html.heex new file mode 100644 index 0000000..4ef5741 --- /dev/null +++ b/lib/pinchflat_web/controllers/media_sources/source_html/new.html.heex @@ -0,0 +1,12 @@ +<.header> + New Source + <:subtitle>Use this form to manage source records in your database. + + +<.source_form + changeset={@changeset} + media_profiles={@media_profiles} + action={~p"/media_sources/sources"} +/> + +<.back navigate={~p"/media_sources/sources"}>Back to sources diff --git a/lib/pinchflat_web/controllers/media_sources/source_html/show.html.heex b/lib/pinchflat_web/controllers/media_sources/source_html/show.html.heex new file mode 100644 index 0000000..5ae2176 --- /dev/null +++ b/lib/pinchflat_web/controllers/media_sources/source_html/show.html.heex @@ -0,0 +1,17 @@ +<.header> + Source <%= @source.id %> + <:subtitle>This is a source record from your database. + <:actions> + <.link href={~p"/media_sources/sources/#{@source}/edit"}> + <.button>Edit source + + + + +<.list> + <:item title="Source Name"><%= @source.name %> + <:item title="Source ID"><%= @source.collection_id %> + <:item title="Original URL"><%= @source.original_url %> + + +<.back navigate={~p"/media_sources/sources"}>Back to sources diff --git a/lib/pinchflat_web/controllers/media_sources/channel_html/channel_form.html.heex b/lib/pinchflat_web/controllers/media_sources/source_html/source_form.html.heex similarity index 73% rename from lib/pinchflat_web/controllers/media_sources/channel_html/channel_form.html.heex rename to lib/pinchflat_web/controllers/media_sources/source_html/source_form.html.heex index b8b4d4e..f8a0a87 100644 --- a/lib/pinchflat_web/controllers/media_sources/channel_html/channel_form.html.heex +++ b/lib/pinchflat_web/controllers/media_sources/source_html/source_form.html.heex @@ -10,7 +10,8 @@ label="Media Profile" /> - <.input field={f[:original_url]} type="text" label="Channel URL" /> + <.input field={f[:collection_type]} type="text" label="Collection Type" /> + <.input field={f[:original_url]} type="text" label="Source URL" /> <.input field={f[:index_frequency_minutes]} @@ -20,6 +21,6 @@ /> <:actions> - <.button>Save Channel + <.button>Save Source diff --git a/lib/pinchflat_web/router.ex b/lib/pinchflat_web/router.ex index e0775ea..fd06da3 100644 --- a/lib/pinchflat_web/router.ex +++ b/lib/pinchflat_web/router.ex @@ -22,7 +22,7 @@ defmodule PinchflatWeb.Router do resources "/media_profiles", MediaProfiles.MediaProfileController scope "/media_sources", MediaSources do - resources "/channels", ChannelController + resources "/sources", SourceController end end diff --git a/test/pinchflat_web/controllers/channel_controller_test.exs b/test/pinchflat_web/controllers/channel_controller_test.exs deleted file mode 100644 index 28d1cf7..0000000 --- a/test/pinchflat_web/controllers/channel_controller_test.exs +++ /dev/null @@ -1,119 +0,0 @@ -defmodule PinchflatWeb.ChannelControllerTest do - use PinchflatWeb.ConnCase - import Mox - - import Pinchflat.ProfilesFixtures - import Pinchflat.MediaSourceFixtures - - setup do - media_profile = media_profile_fixture() - - { - :ok, - %{ - create_attrs: %{ - media_profile_id: media_profile.id, - original_url: "https://www.youtube.com/channel/abc123" - }, - update_attrs: %{ - original_url: "https://www.youtube.com/channel/321xyz" - }, - invalid_attrs: %{original_url: nil, media_profile_id: nil} - } - } - end - - setup :verify_on_exit! - - describe "index" do - test "lists all channels", %{conn: conn} do - conn = get(conn, ~p"/media_sources/channels") - assert html_response(conn, 200) =~ "Listing Channels" - end - end - - describe "new channel" do - test "renders form", %{conn: conn} do - conn = get(conn, ~p"/media_sources/channels/new") - assert html_response(conn, 200) =~ "New Channel" - end - end - - describe "create channel" do - test "redirects to show when data is valid", %{conn: conn, create_attrs: create_attrs} do - expect(YtDlpRunnerMock, :run, 1, &runner_function_mock/3) - conn = post(conn, ~p"/media_sources/channels", channel: create_attrs) - - assert %{id: id} = redirected_params(conn) - assert redirected_to(conn) == ~p"/media_sources/channels/#{id}" - - conn = get(conn, ~p"/media_sources/channels/#{id}") - assert html_response(conn, 200) =~ "Channel #{id}" - end - - test "renders errors when data is invalid", %{conn: conn, invalid_attrs: invalid_attrs} do - conn = post(conn, ~p"/media_sources/channels", channel: invalid_attrs) - assert html_response(conn, 200) =~ "New Channel" - end - end - - describe "edit channel" do - setup [:create_source] - - test "renders form for editing chosen channel", %{conn: conn, channel: channel} do - conn = get(conn, ~p"/media_sources/channels/#{channel}/edit") - assert html_response(conn, 200) =~ "Edit Channel" - end - end - - describe "update channel" do - setup [:create_source] - - test "redirects when data is valid", %{conn: conn, channel: channel, update_attrs: update_attrs} do - expect(YtDlpRunnerMock, :run, 1, &runner_function_mock/3) - - conn = put(conn, ~p"/media_sources/channels/#{channel}", channel: update_attrs) - assert redirected_to(conn) == ~p"/media_sources/channels/#{channel}" - - conn = get(conn, ~p"/media_sources/channels/#{channel}") - assert html_response(conn, 200) =~ "https://www.youtube.com/channel/321xyz" - end - - test "renders errors when data is invalid", %{ - conn: conn, - channel: channel, - invalid_attrs: invalid_attrs - } do - conn = put(conn, ~p"/media_sources/channels/#{channel}", channel: invalid_attrs) - assert html_response(conn, 200) =~ "Edit Channel" - end - end - - describe "delete channel" do - setup [:create_source] - - test "deletes chosen channel", %{conn: conn, channel: channel} do - conn = delete(conn, ~p"/media_sources/channels/#{channel}") - assert redirected_to(conn) == ~p"/media_sources/channels" - - assert_error_sent 404, fn -> - get(conn, ~p"/media_sources/channels/#{channel}") - end - end - end - - defp create_source(_) do - source = source_fixture() - %{channel: source} - end - - defp runner_function_mock(_url, _opts, _ot) do - { - :ok, - Phoenix.json_library().encode!(%{ - channel: "some name", - channel_id: "some_channel_id_#{:rand.uniform(1_000_000)}" - }) - } - end -end diff --git a/test/pinchflat_web/controllers/source_controller_test.exs b/test/pinchflat_web/controllers/source_controller_test.exs new file mode 100644 index 0000000..f973e8d --- /dev/null +++ b/test/pinchflat_web/controllers/source_controller_test.exs @@ -0,0 +1,120 @@ +defmodule PinchflatWeb.SourceControllerTest do + use PinchflatWeb.ConnCase + import Mox + + import Pinchflat.ProfilesFixtures + import Pinchflat.MediaSourceFixtures + + setup do + media_profile = media_profile_fixture() + + { + :ok, + %{ + create_attrs: %{ + media_profile_id: media_profile.id, + collection_type: "channel", + original_url: "https://www.youtube.com/source/abc123" + }, + update_attrs: %{ + original_url: "https://www.youtube.com/source/321xyz" + }, + invalid_attrs: %{original_url: nil, media_profile_id: nil} + } + } + end + + setup :verify_on_exit! + + describe "index" do + test "lists all sources", %{conn: conn} do + conn = get(conn, ~p"/media_sources/sources") + assert html_response(conn, 200) =~ "Listing Sources" + end + end + + describe "new source" do + test "renders form", %{conn: conn} do + conn = get(conn, ~p"/media_sources/sources/new") + assert html_response(conn, 200) =~ "New Source" + end + end + + describe "create source" do + test "redirects to show when data is valid", %{conn: conn, create_attrs: create_attrs} do + expect(YtDlpRunnerMock, :run, 1, &runner_function_mock/3) + conn = post(conn, ~p"/media_sources/sources", source: create_attrs) + + assert %{id: id} = redirected_params(conn) + assert redirected_to(conn) == ~p"/media_sources/sources/#{id}" + + conn = get(conn, ~p"/media_sources/sources/#{id}") + assert html_response(conn, 200) =~ "Source #{id}" + end + + test "renders errors when data is invalid", %{conn: conn, invalid_attrs: invalid_attrs} do + conn = post(conn, ~p"/media_sources/sources", source: invalid_attrs) + assert html_response(conn, 200) =~ "New Source" + end + end + + describe "edit source" do + setup [:create_source] + + test "renders form for editing chosen source", %{conn: conn, source: source} do + conn = get(conn, ~p"/media_sources/sources/#{source}/edit") + assert html_response(conn, 200) =~ "Edit Source" + end + end + + describe "update source" do + setup [:create_source] + + test "redirects when data is valid", %{conn: conn, source: source, update_attrs: update_attrs} do + expect(YtDlpRunnerMock, :run, 1, &runner_function_mock/3) + + conn = put(conn, ~p"/media_sources/sources/#{source}", source: update_attrs) + assert redirected_to(conn) == ~p"/media_sources/sources/#{source}" + + conn = get(conn, ~p"/media_sources/sources/#{source}") + assert html_response(conn, 200) =~ "https://www.youtube.com/source/321xyz" + end + + test "renders errors when data is invalid", %{ + conn: conn, + source: source, + invalid_attrs: invalid_attrs + } do + conn = put(conn, ~p"/media_sources/sources/#{source}", source: invalid_attrs) + assert html_response(conn, 200) =~ "Edit Source" + end + end + + describe "delete source" do + setup [:create_source] + + test "deletes chosen source", %{conn: conn, source: source} do + conn = delete(conn, ~p"/media_sources/sources/#{source}") + assert redirected_to(conn) == ~p"/media_sources/sources" + + assert_error_sent 404, fn -> + get(conn, ~p"/media_sources/sources/#{source}") + end + end + end + + defp create_source(_) do + source = source_fixture() + %{source: source} + end + + defp runner_function_mock(_url, _opts, _ot) do + { + :ok, + Phoenix.json_library().encode!(%{ + channel: "some name", + channel_id: "some_source_id_#{:rand.uniform(1_000_000)}" + }) + } + end +end