[WIP] saving before attempting LiveView
This commit is contained in:
parent
94414989af
commit
f9249ff130
4 changed files with 123 additions and 29 deletions
|
|
@ -7,6 +7,7 @@ defmodule Pinchflat.MediaSource do
|
||||||
alias Pinchflat.Repo
|
alias Pinchflat.Repo
|
||||||
|
|
||||||
alias Pinchflat.MediaSource.Channel
|
alias Pinchflat.MediaSource.Channel
|
||||||
|
alias Pinchflat.MediaClient.ChannelDetails
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Returns the list of channels. Returns [%Channel{}, ...]
|
Returns the list of channels. Returns [%Channel{}, ...]
|
||||||
|
|
@ -31,6 +32,31 @@ defmodule Pinchflat.MediaSource do
|
||||||
|> Repo.insert()
|
|> Repo.insert()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Creates a channel from a given Channel URL and additional attrs.
|
||||||
|
|
||||||
|
Returns {:ok, %Channel{}} | {:error, %Ecto.Changeset{}} | {:error, binary()}
|
||||||
|
|
||||||
|
IDEA: maybe instead of creating a channel from a URL, instead the form should
|
||||||
|
extract details from the URL and automatically update based on that. So the
|
||||||
|
actual submission would be a normal form object
|
||||||
|
"""
|
||||||
|
def create_channel_from_url(channel_url, attrs) do
|
||||||
|
case ChannelDetails.get_channel_details(channel_url) do
|
||||||
|
{:ok, %ChannelDetails{} = channel_details} ->
|
||||||
|
record_attrs =
|
||||||
|
Map.merge(attrs, %{
|
||||||
|
name: channel_details.name,
|
||||||
|
channel_id: channel_details.id
|
||||||
|
})
|
||||||
|
|
||||||
|
create_channel(record_attrs)
|
||||||
|
|
||||||
|
{:error, runner_error, _status_code} ->
|
||||||
|
{:error, runner_error}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Updates a channel. Returns {:ok, %Channel{}} | {:error, %Ecto.Changeset{}}
|
Updates a channel. Returns {:ok, %Channel{}} | {:error, %Ecto.Changeset{}}
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
defmodule PinchflatWeb.MediaSources.ChannelController do
|
defmodule PinchflatWeb.MediaSources.ChannelController do
|
||||||
use PinchflatWeb, :controller
|
use PinchflatWeb, :controller
|
||||||
|
|
||||||
|
alias Pinchflat.Profiles
|
||||||
alias Pinchflat.MediaSource
|
alias Pinchflat.MediaSource
|
||||||
alias Pinchflat.MediaSource.Channel
|
alias Pinchflat.MediaSource.Channel
|
||||||
|
|
||||||
|
|
@ -10,12 +11,14 @@ defmodule PinchflatWeb.MediaSources.ChannelController do
|
||||||
end
|
end
|
||||||
|
|
||||||
def new(conn, _params) do
|
def new(conn, _params) do
|
||||||
|
media_profiles = Profiles.list_media_profiles()
|
||||||
changeset = MediaSource.change_channel(%Channel{})
|
changeset = MediaSource.change_channel(%Channel{})
|
||||||
render(conn, :new, changeset: changeset)
|
|
||||||
|
render(conn, :new, changeset: changeset, media_profiles: media_profiles)
|
||||||
end
|
end
|
||||||
|
|
||||||
def create(conn, %{"channel" => channel_params}) do
|
def create(conn, %{"channel" => channel_params}) do
|
||||||
case MediaSource.create_channel(channel_params) do
|
case MediaSource.create_channel_from_url(channel_params["channel_url"], channel_params) do
|
||||||
{:ok, channel} ->
|
{:ok, channel} ->
|
||||||
conn
|
conn
|
||||||
|> put_flash(:info, "Channel created successfully.")
|
|> put_flash(:info, "Channel created successfully.")
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,20 @@
|
||||||
<:subtitle>Use this form to manage channel records in your database.</:subtitle>
|
<:subtitle>Use this form to manage channel records in your database.</:subtitle>
|
||||||
</.header>
|
</.header>
|
||||||
|
|
||||||
<.channel_form changeset={@changeset} action={~p"/media_sources/channels"} />
|
<.simple_form :let={f} for={@changeset} action={~p"/media_sources/channels"}>
|
||||||
|
<.error :if={@changeset.action}>
|
||||||
|
Oops, something went wrong! Please check the errors below.
|
||||||
|
</.error>
|
||||||
|
<.input
|
||||||
|
field={f[:media_profile_id]}
|
||||||
|
options={Enum.map(@media_profiles, &{&1.name, &1.id})}
|
||||||
|
type="select"
|
||||||
|
label="Media Profile"
|
||||||
|
/>
|
||||||
|
<.input field={f[:channel_url]} type="text" label="Channel URL" />
|
||||||
|
<:actions>
|
||||||
|
<.button>Save Channel</.button>
|
||||||
|
</:actions>
|
||||||
|
</.simple_form>
|
||||||
|
|
||||||
<.back navigate={~p"/media_sources/channels"}>Back to channels</.back>
|
<.back navigate={~p"/media_sources/channels"}>Back to channels</.back>
|
||||||
|
|
|
||||||
|
|
@ -2,26 +2,29 @@ defmodule Pinchflat.MediaSourceTest do
|
||||||
use Pinchflat.DataCase
|
use Pinchflat.DataCase
|
||||||
|
|
||||||
alias Pinchflat.MediaSource
|
alias Pinchflat.MediaSource
|
||||||
|
alias Pinchflat.MediaSource.Channel
|
||||||
|
|
||||||
describe "channels" do
|
import Pinchflat.ProfilesFixtures
|
||||||
alias Pinchflat.MediaSource.Channel
|
import Pinchflat.MediaSourceFixtures
|
||||||
|
|
||||||
import Pinchflat.ProfilesFixtures
|
@invalid_channel_attrs %{name: nil, channel_id: nil}
|
||||||
import Pinchflat.MediaSourceFixtures
|
|
||||||
|
|
||||||
@invalid_attrs %{name: nil, channel_id: nil}
|
describe "list_channels/0" do
|
||||||
|
test "it returns all channels" do
|
||||||
test "list_channels/0 returns all channels" do
|
|
||||||
channel = channel_fixture()
|
channel = channel_fixture()
|
||||||
assert MediaSource.list_channels() == [channel]
|
assert MediaSource.list_channels() == [channel]
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
test "get_channel!/1 returns the channel with given id" do
|
describe "get_channel!/1" do
|
||||||
|
test "it returns the channel with given id" do
|
||||||
channel = channel_fixture()
|
channel = channel_fixture()
|
||||||
assert MediaSource.get_channel!(channel.id) == channel
|
assert MediaSource.get_channel!(channel.id) == channel
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
test "create_channel/1 with valid data creates a channel" do
|
describe "create_channel/1" do
|
||||||
|
test "creates a channel with valid data" do
|
||||||
valid_attrs = %{
|
valid_attrs = %{
|
||||||
name: "some name",
|
name: "some name",
|
||||||
channel_id: "some channel_id",
|
channel_id: "some channel_id",
|
||||||
|
|
@ -33,11 +36,11 @@ defmodule Pinchflat.MediaSourceTest do
|
||||||
assert channel.channel_id == "some channel_id"
|
assert channel.channel_id == "some channel_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "create_channel/1 with invalid data returns error changeset" do
|
test "creation with invalid data returns error changeset" do
|
||||||
assert {:error, %Ecto.Changeset{}} = MediaSource.create_channel(@invalid_attrs)
|
assert {:error, %Ecto.Changeset{}} = MediaSource.create_channel(@invalid_channel_attrs)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "create_channel/1 enforces uniqueness of channel_id scoped to the media_profile" do
|
test "creation enforces uniqueness of channel_id scoped to the media_profile" do
|
||||||
valid_once_attrs = %{
|
valid_once_attrs = %{
|
||||||
name: "some name",
|
name: "some name",
|
||||||
channel_id: "abc123",
|
channel_id: "abc123",
|
||||||
|
|
@ -48,24 +51,67 @@ defmodule Pinchflat.MediaSourceTest do
|
||||||
assert {:error, %Ecto.Changeset{}} = MediaSource.create_channel(valid_once_attrs)
|
assert {:error, %Ecto.Changeset{}} = MediaSource.create_channel(valid_once_attrs)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "create_channel/1 lets you duplicate channel_ids as long as the media profile is different" do
|
test "creation lets you duplicate channel_ids as long as the media profile is different" do
|
||||||
valid_attrs = %{
|
valid_attrs = %{
|
||||||
name: "some name",
|
name: "some name",
|
||||||
channel_id: "abc123"
|
channel_id: "abc123"
|
||||||
}
|
}
|
||||||
|
|
||||||
assert {:ok, %Channel{}} =
|
channel_1_attrs = Map.merge(valid_attrs, %{media_profile_id: media_profile_fixture().id})
|
||||||
MediaSource.create_channel(
|
channel_2_attrs = Map.merge(valid_attrs, %{media_profile_id: media_profile_fixture().id})
|
||||||
Map.merge(valid_attrs, %{media_profile_id: media_profile_fixture().id})
|
|
||||||
)
|
|
||||||
|
|
||||||
assert {:ok, %Channel{}} =
|
assert {:ok, %Channel{}} = MediaSource.create_channel(channel_1_attrs)
|
||||||
MediaSource.create_channel(
|
assert {:ok, %Channel{}} = MediaSource.create_channel(channel_2_attrs)
|
||||||
Map.merge(valid_attrs, %{media_profile_id: media_profile_fixture().id})
|
end
|
||||||
)
|
end
|
||||||
|
|
||||||
|
describe "create_channel_from_url/2" do
|
||||||
|
import Mox
|
||||||
|
|
||||||
|
setup :verify_on_exit!
|
||||||
|
|
||||||
|
test "it creates a channel with valid data" do
|
||||||
|
channel_url = "https://www.youtube.com/c/TheUselessTrials"
|
||||||
|
valid_attrs = %{media_profile_id: media_profile_fixture().id}
|
||||||
|
|
||||||
|
expect(YtDlpRunnerMock, :run, fn ^channel_url, _opts ->
|
||||||
|
{:ok, "{\"channel\": \"TheUselessTrials\", \"channel_id\": \"UCQH2\"}"}
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert {:ok, %Channel{} = channel} =
|
||||||
|
MediaSource.create_channel_from_url(channel_url, valid_attrs)
|
||||||
|
|
||||||
|
assert channel.name == "TheUselessTrials"
|
||||||
|
assert channel.channel_id == "UCQH2"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "update_channel/2 with valid data updates the channel" do
|
test "it returns an error string if the runner returns an error" do
|
||||||
|
channel_url = "https://www.youtube.com/c/TheUselessTrials"
|
||||||
|
valid_attrs = %{media_profile_id: media_profile_fixture().id}
|
||||||
|
|
||||||
|
expect(YtDlpRunnerMock, :run, fn ^channel_url, _opts ->
|
||||||
|
{:error, "Big issue", 1}
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert {:error, "Big issue"} =
|
||||||
|
MediaSource.create_channel_from_url(channel_url, valid_attrs)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "creation with invalid data returns error changeset" do
|
||||||
|
channel_url = "https://www.youtube.com/c/TheUselessTrials"
|
||||||
|
invalid_attrs = %{media_profile_id: nil}
|
||||||
|
|
||||||
|
expect(YtDlpRunnerMock, :run, fn ^channel_url, _opts ->
|
||||||
|
{:ok, "{\"channel\": \"TheUselessTrials\", \"channel_id\": \"UCQH2\"}"}
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert {:error, %Ecto.Changeset{}} =
|
||||||
|
MediaSource.create_channel_from_url(channel_url, invalid_attrs)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "update_channel/2" do
|
||||||
|
test "updates with valid data updates the channel" do
|
||||||
channel = channel_fixture()
|
channel = channel_fixture()
|
||||||
update_attrs = %{name: "some updated name", channel_id: "some updated channel_id"}
|
update_attrs = %{name: "some updated name", channel_id: "some updated channel_id"}
|
||||||
|
|
||||||
|
|
@ -74,19 +120,24 @@ defmodule Pinchflat.MediaSourceTest do
|
||||||
assert channel.channel_id == "some updated channel_id"
|
assert channel.channel_id == "some updated channel_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "update_channel/2 with invalid data returns error changeset" do
|
test "updates with invalid data returns error changeset" do
|
||||||
channel = channel_fixture()
|
channel = channel_fixture()
|
||||||
assert {:error, %Ecto.Changeset{}} = MediaSource.update_channel(channel, @invalid_attrs)
|
|
||||||
|
assert {:error, %Ecto.Changeset{}} =
|
||||||
|
MediaSource.update_channel(channel, @invalid_channel_attrs)
|
||||||
|
|
||||||
assert channel == MediaSource.get_channel!(channel.id)
|
assert channel == MediaSource.get_channel!(channel.id)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
test "delete_channel/1 deletes the channel" do
|
describe "delete_channel/1" do
|
||||||
|
test "it deletes the channel" do
|
||||||
channel = channel_fixture()
|
channel = channel_fixture()
|
||||||
assert {:ok, %Channel{}} = MediaSource.delete_channel(channel)
|
assert {:ok, %Channel{}} = MediaSource.delete_channel(channel)
|
||||||
assert_raise Ecto.NoResultsError, fn -> MediaSource.get_channel!(channel.id) end
|
assert_raise Ecto.NoResultsError, fn -> MediaSource.get_channel!(channel.id) end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "change_channel/1 returns a channel changeset" do
|
test "it returns a channel changeset" do
|
||||||
channel = channel_fixture()
|
channel = channel_fixture()
|
||||||
assert %Ecto.Changeset{} = MediaSource.change_channel(channel)
|
assert %Ecto.Changeset{} = MediaSource.change_channel(channel)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue