UX improvements v1 (#39)
* Removed collection_type user input instead inferring from yt-dlp response * Updated docs * Added delete buttons for source; Refactored the way deletion methods work * Update source to always run an initial index * Added deletion to the last models * Improved clarity around deletion operation * Improved task fetching and deletion methods * More tests
This commit is contained in:
@@ -36,6 +36,15 @@ defmodule Pinchflat.MediaTest do
|
||||
end
|
||||
end
|
||||
|
||||
describe "list_media_items_for/1" do
|
||||
test "it returns media_items for a given source" do
|
||||
source = source_fixture()
|
||||
media_item = media_item_fixture(%{source_id: source.id})
|
||||
|
||||
assert Media.list_media_items_for(source) == [media_item]
|
||||
end
|
||||
end
|
||||
|
||||
describe "list_pending_media_items_for/1" do
|
||||
test "it returns pending without a filepath for a given source" do
|
||||
source = source_fixture()
|
||||
@@ -331,7 +340,7 @@ defmodule Pinchflat.MediaTest do
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete_media_item/1" do
|
||||
describe "delete_media_item/2" do
|
||||
test "deletion deletes the media_item" do
|
||||
media_item = media_item_fixture()
|
||||
assert {:ok, %MediaItem{}} = Media.delete_media_item(media_item)
|
||||
@@ -345,13 +354,20 @@ defmodule Pinchflat.MediaTest do
|
||||
assert {:ok, %MediaItem{}} = Media.delete_media_item(media_item)
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(task) end
|
||||
end
|
||||
|
||||
test "does not delete the media_item's files by default" do
|
||||
media_item = media_item_with_attachments()
|
||||
|
||||
assert {:ok, _} = Media.delete_media_item(media_item)
|
||||
assert File.exists?(media_item.media_filepath)
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete_attachments/1" do
|
||||
describe "delete_media_item/2 when testing file deletion" do
|
||||
test "deletes the media item's files" do
|
||||
media_item = media_item_with_attachments()
|
||||
|
||||
assert {:ok, _} = Media.delete_attachments(media_item)
|
||||
assert {:ok, _} = Media.delete_media_item(media_item, delete_files: true)
|
||||
refute File.exists?(media_item.media_filepath)
|
||||
end
|
||||
|
||||
@@ -371,23 +387,21 @@ defmodule Pinchflat.MediaTest do
|
||||
|
||||
{:ok, updated_media_item} = Media.update_media_item(media_item, update_attrs)
|
||||
|
||||
assert {:ok, _} = Media.delete_attachments(updated_media_item)
|
||||
assert {:ok, _} = Media.delete_media_item(updated_media_item, delete_files: true)
|
||||
refute File.exists?(updated_media_item.metadata.metadata_filepath)
|
||||
end
|
||||
|
||||
test "does not delete the media item" do
|
||||
media_item = media_item_with_attachments()
|
||||
|
||||
assert {:ok, _} = Media.delete_attachments(media_item)
|
||||
|
||||
assert Repo.reload!(media_item)
|
||||
test "deletion deletes the media_item" do
|
||||
media_item = media_item_fixture()
|
||||
assert {:ok, %MediaItem{}} = Media.delete_media_item(media_item, delete_files: true)
|
||||
assert_raise Ecto.NoResultsError, fn -> Media.get_media_item!(media_item.id) end
|
||||
end
|
||||
|
||||
test "deletes the parent folder if it is empty" do
|
||||
media_item = media_item_with_attachments()
|
||||
root_directory = Path.dirname(media_item.media_filepath)
|
||||
|
||||
assert {:ok, _} = Media.delete_attachments(media_item)
|
||||
assert {:ok, _} = Media.delete_media_item(media_item, delete_files: true)
|
||||
refute File.exists?(root_directory)
|
||||
end
|
||||
|
||||
@@ -396,7 +410,7 @@ defmodule Pinchflat.MediaTest do
|
||||
root_directory = Path.dirname(media_item.media_filepath)
|
||||
File.touch(Path.join([root_directory, "test.txt"]))
|
||||
|
||||
assert {:ok, _} = Media.delete_attachments(media_item)
|
||||
assert {:ok, _} = Media.delete_media_item(media_item, delete_files: true)
|
||||
assert File.exists?(root_directory)
|
||||
|
||||
:ok = File.rm(Path.join([root_directory, "test.txt"]))
|
||||
@@ -404,24 +418,6 @@ defmodule Pinchflat.MediaTest do
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete_media_item_and_attachments/1" do
|
||||
setup do
|
||||
media_item = media_item_with_attachments()
|
||||
{:ok, media_item: media_item}
|
||||
end
|
||||
|
||||
test "deletes the media item", %{media_item: media_item} do
|
||||
assert {:ok, _} = Media.delete_media_item_and_attachments(media_item)
|
||||
assert_raise Ecto.NoResultsError, fn -> Media.get_media_item!(media_item.id) end
|
||||
end
|
||||
|
||||
test "deletes associated files", %{media_item: media_item} do
|
||||
assert File.exists?(media_item.media_filepath)
|
||||
assert {:ok, _} = Media.delete_media_item_and_attachments(media_item)
|
||||
refute File.exists?(media_item.media_filepath)
|
||||
end
|
||||
end
|
||||
|
||||
describe "change_media_item/1" do
|
||||
test "change_media_item/1 returns a media_item changeset" do
|
||||
media_item = media_item_fixture()
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
defmodule Pinchflat.ProfilesTest do
|
||||
use Pinchflat.DataCase
|
||||
|
||||
import Pinchflat.MediaFixtures
|
||||
import Pinchflat.SourcesFixtures
|
||||
import Pinchflat.ProfilesFixtures
|
||||
|
||||
alias Pinchflat.Profiles
|
||||
alias Pinchflat.Profiles.MediaProfile
|
||||
import Pinchflat.ProfilesFixtures
|
||||
|
||||
@invalid_attrs %{name: nil, output_path_template: nil}
|
||||
|
||||
@@ -61,11 +64,66 @@ defmodule Pinchflat.ProfilesTest do
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete_media_profile/1" do
|
||||
describe "delete_media_profile/2" do
|
||||
test "deletion deletes the media_profile" do
|
||||
media_profile = media_profile_fixture()
|
||||
|
||||
assert {:ok, %MediaProfile{}} = Profiles.delete_media_profile(media_profile)
|
||||
assert_raise Ecto.NoResultsError, fn -> Profiles.get_media_profile!(media_profile.id) end
|
||||
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(media_profile) end
|
||||
end
|
||||
|
||||
test "deletion deletes all sources" do
|
||||
media_profile = media_profile_fixture()
|
||||
source = source_fixture(media_profile_id: media_profile.id)
|
||||
|
||||
assert {:ok, %MediaProfile{}} = Profiles.delete_media_profile(media_profile)
|
||||
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(source) end
|
||||
end
|
||||
|
||||
test "deletion deletes all media items" do
|
||||
media_profile = media_profile_fixture()
|
||||
source = source_fixture(media_profile_id: media_profile.id)
|
||||
media_item = media_item_fixture(source_id: source.id)
|
||||
|
||||
assert {:ok, %MediaProfile{}} = Profiles.delete_media_profile(media_profile)
|
||||
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(media_item) end
|
||||
end
|
||||
|
||||
test "deletion does not delete files by default" do
|
||||
media_profile = media_profile_fixture()
|
||||
source = source_fixture(media_profile_id: media_profile.id)
|
||||
media_item = media_item_with_attachments(%{source_id: source.id})
|
||||
|
||||
assert {:ok, %MediaProfile{}} = Profiles.delete_media_profile(media_profile)
|
||||
|
||||
assert File.exists?(media_item.media_filepath)
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete_media_profile/2 when deleting files" do
|
||||
test "still deletes all the needful records" do
|
||||
media_profile = media_profile_fixture()
|
||||
source = source_fixture(media_profile_id: media_profile.id)
|
||||
media_item = media_item_fixture(source_id: source.id)
|
||||
|
||||
assert {:ok, %MediaProfile{}} = Profiles.delete_media_profile(media_profile, delete_files: true)
|
||||
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(media_profile) end
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(source) end
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(media_item) end
|
||||
end
|
||||
|
||||
test "deletes files" do
|
||||
media_profile = media_profile_fixture()
|
||||
source = source_fixture(media_profile_id: media_profile.id)
|
||||
media_item = media_item_with_attachments(%{source_id: source.id})
|
||||
|
||||
assert {:ok, %MediaProfile{}} = Profiles.delete_media_profile(media_profile, delete_files: true)
|
||||
|
||||
refute File.exists?(media_item.media_filepath)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
+144
-34
@@ -23,6 +23,15 @@ defmodule Pinchflat.SourcesTest do
|
||||
end
|
||||
end
|
||||
|
||||
describe "list_sources_for/1" do
|
||||
test "returns all sources for a given media profile" do
|
||||
media_profile = media_profile_fixture()
|
||||
source = source_fixture(media_profile_id: media_profile.id)
|
||||
|
||||
assert Sources.list_sources_for(media_profile) == [source]
|
||||
end
|
||||
end
|
||||
|
||||
describe "get_source!/1" do
|
||||
test "it returns the source with given id" do
|
||||
source = source_fixture()
|
||||
@@ -32,12 +41,11 @@ defmodule Pinchflat.SourcesTest do
|
||||
|
||||
describe "create_source/1" do
|
||||
test "creates a source and adds name + ID from runner response for channels" do
|
||||
expect(YtDlpRunnerMock, :run, &runner_function_mock/3)
|
||||
expect(YtDlpRunnerMock, :run, &channel_mock/3)
|
||||
|
||||
valid_attrs = %{
|
||||
media_profile_id: media_profile_fixture().id,
|
||||
original_url: "https://www.youtube.com/channel/abc123",
|
||||
collection_type: "channel"
|
||||
original_url: "https://www.youtube.com/channel/abc123"
|
||||
}
|
||||
|
||||
assert {:ok, %Source{} = source} = Sources.create_source(valid_attrs)
|
||||
@@ -46,12 +54,11 @@ defmodule Pinchflat.SourcesTest do
|
||||
end
|
||||
|
||||
test "creates a source and adds name + ID for playlists" do
|
||||
expect(YtDlpRunnerMock, :run, &runner_function_mock/3)
|
||||
expect(YtDlpRunnerMock, :run, &playlist_mock/3)
|
||||
|
||||
valid_attrs = %{
|
||||
media_profile_id: media_profile_fixture().id,
|
||||
original_url: "https://www.youtube.com/playlist?list=abc123",
|
||||
collection_type: "playlist"
|
||||
original_url: "https://www.youtube.com/playlist?list=abc123"
|
||||
}
|
||||
|
||||
assert {:ok, %Source{} = source} = Sources.create_source(valid_attrs)
|
||||
@@ -60,12 +67,11 @@ defmodule Pinchflat.SourcesTest do
|
||||
end
|
||||
|
||||
test "you can specify a custom friendly_name" do
|
||||
expect(YtDlpRunnerMock, :run, &runner_function_mock/3)
|
||||
expect(YtDlpRunnerMock, :run, &channel_mock/3)
|
||||
|
||||
valid_attrs = %{
|
||||
media_profile_id: media_profile_fixture().id,
|
||||
original_url: "https://www.youtube.com/channel/abc123",
|
||||
collection_type: "channel",
|
||||
friendly_name: "some custom name"
|
||||
}
|
||||
|
||||
@@ -75,12 +81,11 @@ defmodule Pinchflat.SourcesTest do
|
||||
end
|
||||
|
||||
test "friendly name is pulled from collection_name if not specified" do
|
||||
expect(YtDlpRunnerMock, :run, &runner_function_mock/3)
|
||||
expect(YtDlpRunnerMock, :run, &channel_mock/3)
|
||||
|
||||
valid_attrs = %{
|
||||
media_profile_id: media_profile_fixture().id,
|
||||
original_url: "https://www.youtube.com/channel/abc123",
|
||||
collection_type: "channel"
|
||||
original_url: "https://www.youtube.com/channel/abc123"
|
||||
}
|
||||
|
||||
assert {:ok, %Source{} = source} = Sources.create_source(valid_attrs)
|
||||
@@ -88,6 +93,22 @@ defmodule Pinchflat.SourcesTest do
|
||||
assert source.friendly_name == "some channel name"
|
||||
end
|
||||
|
||||
test "collection_type is inferred from source details" do
|
||||
expect(YtDlpRunnerMock, :run, &channel_mock/3)
|
||||
expect(YtDlpRunnerMock, :run, &playlist_mock/3)
|
||||
|
||||
valid_attrs = %{
|
||||
media_profile_id: media_profile_fixture().id,
|
||||
original_url: "https://www.youtube.com/channel/abc123"
|
||||
}
|
||||
|
||||
assert {:ok, %Source{} = source_1} = Sources.create_source(valid_attrs)
|
||||
assert {:ok, %Source{} = source_2} = Sources.create_source(valid_attrs)
|
||||
|
||||
assert source_1.collection_type == :channel
|
||||
assert source_2.collection_type == :playlist
|
||||
end
|
||||
|
||||
test "creation with invalid data returns error changeset" do
|
||||
assert {:error, %Ecto.Changeset{}} = Sources.create_source(@invalid_source_attrs)
|
||||
end
|
||||
@@ -97,14 +118,15 @@ defmodule Pinchflat.SourcesTest do
|
||||
{:ok,
|
||||
Phoenix.json_library().encode!(%{
|
||||
channel: "some channel name",
|
||||
channel_id: "some_channel_id_12345678"
|
||||
channel_id: "some_channel_id_12345678",
|
||||
playlist_id: "some_channel_id_12345678",
|
||||
playlist_title: "some channel name - videos"
|
||||
})}
|
||||
end)
|
||||
|
||||
valid_once_attrs = %{
|
||||
media_profile_id: media_profile_fixture().id,
|
||||
original_url: "https://www.youtube.com/channel/abc123",
|
||||
collection_type: "channel"
|
||||
original_url: "https://www.youtube.com/channel/abc123"
|
||||
}
|
||||
|
||||
assert {:ok, %Source{}} = Sources.create_source(valid_once_attrs)
|
||||
@@ -116,14 +138,15 @@ defmodule Pinchflat.SourcesTest do
|
||||
{:ok,
|
||||
Phoenix.json_library().encode!(%{
|
||||
channel: "some channel name",
|
||||
channel_id: "some_channel_id_12345678"
|
||||
channel_id: "some_channel_id_12345678",
|
||||
playlist_id: "some_channel_id_12345678",
|
||||
playlist_title: "some channel name - videos"
|
||||
})}
|
||||
end)
|
||||
|
||||
valid_attrs = %{
|
||||
name: "some name",
|
||||
original_url: "https://www.youtube.com/channel/abc123",
|
||||
collection_type: "channel"
|
||||
original_url: "https://www.youtube.com/channel/abc123"
|
||||
}
|
||||
|
||||
source_1_attrs = Map.merge(valid_attrs, %{media_profile_id: media_profile_fixture().id})
|
||||
@@ -134,12 +157,25 @@ defmodule Pinchflat.SourcesTest do
|
||||
end
|
||||
|
||||
test "creation will schedule the indexing task" do
|
||||
expect(YtDlpRunnerMock, :run, &runner_function_mock/3)
|
||||
expect(YtDlpRunnerMock, :run, &channel_mock/3)
|
||||
|
||||
valid_attrs = %{
|
||||
media_profile_id: media_profile_fixture().id,
|
||||
original_url: "https://www.youtube.com/channel/abc123"
|
||||
}
|
||||
|
||||
assert {:ok, %Source{} = source} = Sources.create_source(valid_attrs)
|
||||
|
||||
assert_enqueued(worker: MediaIndexingWorker, args: %{"id" => source.id})
|
||||
end
|
||||
|
||||
test "creation schedules an index test even if the index frequency is 0" do
|
||||
expect(YtDlpRunnerMock, :run, &channel_mock/3)
|
||||
|
||||
valid_attrs = %{
|
||||
media_profile_id: media_profile_fixture().id,
|
||||
original_url: "https://www.youtube.com/channel/abc123",
|
||||
collection_type: "channel"
|
||||
index_frequency_minutes: 0
|
||||
}
|
||||
|
||||
assert {:ok, %Source{} = source} = Sources.create_source(valid_attrs)
|
||||
@@ -158,7 +194,7 @@ defmodule Pinchflat.SourcesTest do
|
||||
end
|
||||
|
||||
test "updating the original_url will re-fetch the source details for channels" do
|
||||
expect(YtDlpRunnerMock, :run, &runner_function_mock/3)
|
||||
expect(YtDlpRunnerMock, :run, &channel_mock/3)
|
||||
|
||||
source = source_fixture()
|
||||
update_attrs = %{original_url: "https://www.youtube.com/channel/abc123"}
|
||||
@@ -169,9 +205,9 @@ defmodule Pinchflat.SourcesTest do
|
||||
end
|
||||
|
||||
test "updating the original_url will re-fetch the source details for playlists" do
|
||||
expect(YtDlpRunnerMock, :run, &runner_function_mock/3)
|
||||
expect(YtDlpRunnerMock, :run, &playlist_mock/3)
|
||||
|
||||
source = source_fixture(collection_type: "playlist")
|
||||
source = source_fixture()
|
||||
update_attrs = %{original_url: "https://www.youtube.com/playlist?list=abc123"}
|
||||
|
||||
assert {:ok, %Source{} = source} = Sources.update_source(source, update_attrs)
|
||||
@@ -180,7 +216,7 @@ defmodule Pinchflat.SourcesTest do
|
||||
end
|
||||
|
||||
test "not updating the original_url will not re-fetch the source details" do
|
||||
expect(YtDlpRunnerMock, :run, 0, &runner_function_mock/3)
|
||||
expect(YtDlpRunnerMock, :run, 0, &channel_mock/3)
|
||||
|
||||
source = source_fixture()
|
||||
update_attrs = %{name: "some updated name"}
|
||||
@@ -188,7 +224,7 @@ defmodule Pinchflat.SourcesTest do
|
||||
assert {:ok, %Source{}} = Sources.update_source(source, update_attrs)
|
||||
end
|
||||
|
||||
test "updating the index frequency will re-schedule the indexing task" do
|
||||
test "updating the index frequency to >0 will re-schedule the indexing task" do
|
||||
source = source_fixture()
|
||||
update_attrs = %{index_frequency_minutes: 123}
|
||||
|
||||
@@ -197,11 +233,34 @@ defmodule Pinchflat.SourcesTest do
|
||||
assert_enqueued(worker: MediaIndexingWorker, args: %{"id" => source.id})
|
||||
end
|
||||
|
||||
test "not updating the index frequency will not re-schedule the indexing task" do
|
||||
test "updating the index frequency to 0 will not re-schedule the indexing task" do
|
||||
source = source_fixture()
|
||||
update_attrs = %{index_frequency_minutes: 0}
|
||||
|
||||
assert {:ok, %Source{}} = Sources.update_source(source, update_attrs)
|
||||
|
||||
refute_enqueued(worker: MediaIndexingWorker, args: %{"id" => source.id})
|
||||
end
|
||||
|
||||
test "updating the index frequency to 0 will delete any pending tasks" do
|
||||
source = source_fixture()
|
||||
{:ok, job} = Oban.insert(MediaIndexingWorker.new(%{"id" => source.id}))
|
||||
task = task_fixture(source_id: source.id, job_id: job.id)
|
||||
update_attrs = %{index_frequency_minutes: 0}
|
||||
|
||||
assert {:ok, %Source{}} = Sources.update_source(source, update_attrs)
|
||||
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(task) end
|
||||
end
|
||||
|
||||
test "not updating the index frequency will not re-schedule the indexing task or delete tasks" do
|
||||
source = source_fixture()
|
||||
task = task_fixture(source_id: source.id)
|
||||
update_attrs = %{name: "some updated name"}
|
||||
|
||||
assert {:ok, %Source{}} = Sources.update_source(source, update_attrs)
|
||||
|
||||
assert Repo.reload!(task)
|
||||
refute_enqueued(worker: MediaIndexingWorker, args: %{"id" => source.id})
|
||||
end
|
||||
|
||||
@@ -236,7 +295,7 @@ defmodule Pinchflat.SourcesTest do
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete_source/1" do
|
||||
describe "delete_source/2" do
|
||||
test "it deletes the source" do
|
||||
source = source_fixture()
|
||||
assert {:ok, %Source{}} = Sources.delete_source(source)
|
||||
@@ -255,6 +314,43 @@ defmodule Pinchflat.SourcesTest do
|
||||
assert {:ok, %Source{}} = Sources.delete_source(source)
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(task) end
|
||||
end
|
||||
|
||||
test "deletion also deletes all associated media items" do
|
||||
source = source_fixture()
|
||||
media_item = media_item_fixture(source_id: source.id)
|
||||
|
||||
assert {:ok, %Source{}} = Sources.delete_source(source)
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(media_item) end
|
||||
end
|
||||
|
||||
test "deletion does not delete media files by default" do
|
||||
source = source_fixture()
|
||||
media_item = media_item_with_attachments(%{source_id: source.id})
|
||||
|
||||
assert {:ok, %Source{}} = Sources.delete_source(source)
|
||||
assert File.exists?(media_item.media_filepath)
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete_source/2 when deleting files" do
|
||||
test "deletes source and media_items" do
|
||||
source = source_fixture()
|
||||
media_item = media_item_with_attachments(%{source_id: source.id})
|
||||
|
||||
assert {:ok, %Source{}} = Sources.delete_source(source, delete_files: true)
|
||||
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(media_item) end
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(source) end
|
||||
end
|
||||
|
||||
test "also deletes media files" do
|
||||
source = source_fixture()
|
||||
media_item = media_item_with_attachments(%{source_id: source.id})
|
||||
|
||||
assert {:ok, %Source{}} = Sources.delete_source(source, delete_files: true)
|
||||
|
||||
refute File.exists?(media_item.media_filepath)
|
||||
end
|
||||
end
|
||||
|
||||
describe "change_source/2" do
|
||||
@@ -267,14 +363,14 @@ defmodule Pinchflat.SourcesTest do
|
||||
|
||||
describe "change_source_from_url/2" do
|
||||
test "it returns a changeset" do
|
||||
stub(YtDlpRunnerMock, :run, &runner_function_mock/3)
|
||||
stub(YtDlpRunnerMock, :run, &channel_mock/3)
|
||||
source = source_fixture()
|
||||
|
||||
assert %Ecto.Changeset{} = Sources.change_source_from_url(source, %{})
|
||||
end
|
||||
|
||||
test "it does not fetch source details if the original_url isn't in the changeset" do
|
||||
expect(YtDlpRunnerMock, :run, 0, &runner_function_mock/3)
|
||||
expect(YtDlpRunnerMock, :run, 0, &channel_mock/3)
|
||||
|
||||
changeset = Sources.change_source_from_url(%Source{}, %{name: "some updated name"})
|
||||
|
||||
@@ -282,7 +378,7 @@ defmodule Pinchflat.SourcesTest do
|
||||
end
|
||||
|
||||
test "it fetches source details if the original_url is in the changeset" do
|
||||
expect(YtDlpRunnerMock, :run, &runner_function_mock/3)
|
||||
expect(YtDlpRunnerMock, :run, &channel_mock/3)
|
||||
|
||||
changeset =
|
||||
Sources.change_source_from_url(%Source{}, %{
|
||||
@@ -293,13 +389,13 @@ defmodule Pinchflat.SourcesTest do
|
||||
end
|
||||
|
||||
test "it adds source details to the changeset, keeping the orignal details" do
|
||||
expect(YtDlpRunnerMock, :run, &runner_function_mock/3)
|
||||
expect(YtDlpRunnerMock, :run, &channel_mock/3)
|
||||
|
||||
media_profile = media_profile_fixture()
|
||||
media_profile_id = media_profile.id
|
||||
|
||||
changeset =
|
||||
Sources.change_source_from_url(%Source{collection_type: :channel}, %{
|
||||
Sources.change_source_from_url(%Source{}, %{
|
||||
original_url: "https://www.youtube.com/channel/abc123",
|
||||
media_profile_id: media_profile.id
|
||||
})
|
||||
@@ -329,15 +425,29 @@ defmodule Pinchflat.SourcesTest do
|
||||
end
|
||||
end
|
||||
|
||||
defp runner_function_mock(_url, _opts, _ot) do
|
||||
defp playlist_mock(_url, _opts, _ot) do
|
||||
{
|
||||
:ok,
|
||||
Phoenix.json_library().encode!(%{
|
||||
channel: "some channel name",
|
||||
channel_id: "some_channel_id_#{:rand.uniform(1_000_000)}",
|
||||
channel: nil,
|
||||
channel_id: nil,
|
||||
playlist_id: "some_playlist_id_#{:rand.uniform(1_000_000)}",
|
||||
playlist_title: "some playlist name"
|
||||
})
|
||||
}
|
||||
end
|
||||
|
||||
defp channel_mock(_url, _opts, _ot) do
|
||||
channel_id = "some_channel_id_#{:rand.uniform(1_000_000)}"
|
||||
|
||||
{
|
||||
:ok,
|
||||
Phoenix.json_library().encode!(%{
|
||||
channel: "some channel name",
|
||||
channel_id: channel_id,
|
||||
playlist_id: channel_id,
|
||||
playlist_title: "some channel name - videos"
|
||||
})
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -16,15 +16,7 @@ defmodule Pinchflat.Tasks.SourceTasksTest do
|
||||
setup :verify_on_exit!
|
||||
|
||||
describe "kickoff_indexing_task/1" do
|
||||
test "it does not schedule a job if the interval is <= 0" do
|
||||
source = source_fixture(index_frequency_minutes: -1)
|
||||
|
||||
assert {:ok, :should_not_index} = SourceTasks.kickoff_indexing_task(source)
|
||||
|
||||
refute_enqueued(worker: MediaIndexingWorker, args: %{"id" => source.id})
|
||||
end
|
||||
|
||||
test "it schedules a job if the interval is > 0" do
|
||||
test "it schedules a job" do
|
||||
source = source_fixture(index_frequency_minutes: 1)
|
||||
|
||||
assert {:ok, _} = SourceTasks.kickoff_indexing_task(source)
|
||||
@@ -32,7 +24,7 @@ defmodule Pinchflat.Tasks.SourceTasksTest do
|
||||
assert_enqueued(worker: MediaIndexingWorker, args: %{"id" => source.id})
|
||||
end
|
||||
|
||||
test "it creates and attaches a task if the interval is > 0" do
|
||||
test "it creates and attaches a task" do
|
||||
source = source_fixture(index_frequency_minutes: 1)
|
||||
|
||||
assert {:ok, %Task{} = task} = SourceTasks.kickoff_indexing_task(source)
|
||||
@@ -42,7 +34,8 @@ defmodule Pinchflat.Tasks.SourceTasksTest do
|
||||
|
||||
test "it deletes any pending tasks for the source" do
|
||||
source = source_fixture()
|
||||
task = task_fixture(source_id: source.id)
|
||||
{:ok, job} = Oban.insert(MediaIndexingWorker.new(%{"id" => source.id}))
|
||||
task = task_fixture(source_id: source.id, job_id: job.id)
|
||||
|
||||
assert {:ok, _} = SourceTasks.kickoff_indexing_task(source)
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ defmodule Pinchflat.TasksTest do
|
||||
end
|
||||
end
|
||||
|
||||
describe "list_tasks_for/3" do
|
||||
describe "list_tasks_for/4" do
|
||||
test "it lets you specify which record type/ID to join on" do
|
||||
task = task_fixture()
|
||||
|
||||
@@ -46,12 +46,25 @@ defmodule Pinchflat.TasksTest do
|
||||
test "it lets you specify which job states to include" do
|
||||
task = task_fixture()
|
||||
|
||||
assert Tasks.list_tasks_for(:source_id, task.source_id, [:available]) == [task]
|
||||
assert Tasks.list_tasks_for(:source_id, task.source_id, [:cancelled]) == []
|
||||
assert Tasks.list_tasks_for(:source_id, task.source_id, nil, [:available]) == [task]
|
||||
assert Tasks.list_tasks_for(:source_id, task.source_id, nil, [:cancelled]) == []
|
||||
end
|
||||
|
||||
test "it lets you specify which worker to include" do
|
||||
task = task_fixture()
|
||||
|
||||
assert Tasks.list_tasks_for(:source_id, task.source_id, "TestJobWorker") == [task]
|
||||
assert Tasks.list_tasks_for(:source_id, task.source_id, "FooBarWorker") == []
|
||||
end
|
||||
|
||||
test "it includes all workers if no worker is specified" do
|
||||
task = task_fixture()
|
||||
|
||||
assert Tasks.list_tasks_for(:source_id, task.source_id, nil) == [task]
|
||||
end
|
||||
end
|
||||
|
||||
describe "list_pending_tasks_for/2" do
|
||||
describe "list_pending_tasks_for/3" do
|
||||
test "it lists pending tasks" do
|
||||
task = task_fixture()
|
||||
|
||||
@@ -64,6 +77,13 @@ defmodule Pinchflat.TasksTest do
|
||||
|
||||
assert Tasks.list_pending_tasks_for(:source_id, task.source_id) == []
|
||||
end
|
||||
|
||||
test "it lets you specify which worker to include" do
|
||||
task = task_fixture()
|
||||
|
||||
assert Tasks.list_pending_tasks_for(:source_id, task.source_id, "TestJobWorker") == [task]
|
||||
assert Tasks.list_pending_tasks_for(:source_id, task.source_id, "FooBarWorker") == []
|
||||
end
|
||||
end
|
||||
|
||||
describe "get_task!/1" do
|
||||
@@ -154,7 +174,7 @@ defmodule Pinchflat.TasksTest do
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete_tasks_for/1" do
|
||||
describe "delete_tasks_for/2" do
|
||||
test "it deletes tasks attached to a source" do
|
||||
source = source_fixture()
|
||||
task = task_fixture(source_id: source.id)
|
||||
@@ -170,6 +190,28 @@ defmodule Pinchflat.TasksTest do
|
||||
assert :ok = Tasks.delete_tasks_for(media_item)
|
||||
assert_raise Ecto.NoResultsError, fn -> Tasks.get_task!(task.id) end
|
||||
end
|
||||
|
||||
test "deletion can specify which worker to include" do
|
||||
media_item = media_item_fixture()
|
||||
task = task_fixture(media_item_id: media_item.id)
|
||||
|
||||
assert :ok = Tasks.delete_tasks_for(media_item, "FooBarWorker")
|
||||
assert Repo.reload!(task)
|
||||
|
||||
assert :ok = Tasks.delete_tasks_for(media_item, "TestJobWorker")
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(task) end
|
||||
end
|
||||
|
||||
test "deletion does not impact unintended records" do
|
||||
source = source_fixture()
|
||||
task = task_fixture(source_id: source.id)
|
||||
|
||||
assert :ok = Tasks.delete_tasks_for(source_fixture())
|
||||
assert :ok = Tasks.delete_tasks_for(source_fixture(), "FooBarWorker")
|
||||
assert :ok = Tasks.delete_tasks_for(source_fixture(), "TestJobWorker")
|
||||
|
||||
assert Repo.reload!(task)
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete_pending_tasks_for/1" do
|
||||
@@ -200,6 +242,17 @@ defmodule Pinchflat.TasksTest do
|
||||
assert Tasks.get_task!(cancelled_task.id)
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(pending_task) end
|
||||
end
|
||||
|
||||
test "deletion can specify which worker to include" do
|
||||
media_item = media_item_fixture()
|
||||
task = task_fixture(media_item_id: media_item.id)
|
||||
|
||||
assert :ok = Tasks.delete_pending_tasks_for(media_item, "FooBarWorker")
|
||||
assert Repo.reload!(task)
|
||||
|
||||
assert :ok = Tasks.delete_pending_tasks_for(media_item, "TestJobWorker")
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(task) end
|
||||
end
|
||||
end
|
||||
|
||||
describe "change_task/1" do
|
||||
|
||||
@@ -4,7 +4,6 @@ defmodule PinchflatWeb.MediaItemControllerTest do
|
||||
import Pinchflat.MediaFixtures
|
||||
|
||||
alias Pinchflat.Repo
|
||||
alias Pinchflat.Media
|
||||
|
||||
describe "show media" do
|
||||
setup [:create_media_item]
|
||||
@@ -19,10 +18,6 @@ defmodule PinchflatWeb.MediaItemControllerTest do
|
||||
setup do
|
||||
media_item = media_item_with_attachments()
|
||||
|
||||
on_exit(fn ->
|
||||
Media.delete_attachments(media_item)
|
||||
end)
|
||||
|
||||
%{media_item: media_item}
|
||||
end
|
||||
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
defmodule PinchflatWeb.MediaProfileControllerTest do
|
||||
use PinchflatWeb.ConnCase
|
||||
|
||||
import Pinchflat.MediaFixtures
|
||||
import Pinchflat.SourcesFixtures
|
||||
import Pinchflat.ProfilesFixtures
|
||||
|
||||
alias Pinchflat.Repo
|
||||
|
||||
@create_attrs %{name: "some name", output_path_template: "some output_path_template"}
|
||||
@update_attrs %{
|
||||
name: "some updated name",
|
||||
@@ -97,21 +101,71 @@ defmodule PinchflatWeb.MediaProfileControllerTest do
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete media_profile" do
|
||||
describe "delete media_profile when just deleting the records" do
|
||||
setup [:create_media_profile]
|
||||
|
||||
test "deletes chosen media_profile", %{conn: conn, media_profile: media_profile} do
|
||||
test "deletes chosen media_profile and its associations", %{conn: conn, media_profile: media_profile} do
|
||||
source = source_fixture(media_profile_id: media_profile.id)
|
||||
media_item = media_item_with_attachments(%{source_id: source.id})
|
||||
|
||||
conn = delete(conn, ~p"/media_profiles/#{media_profile}")
|
||||
assert redirected_to(conn) == ~p"/media_profiles"
|
||||
|
||||
assert_error_sent 404, fn ->
|
||||
get(conn, ~p"/media_profiles/#{media_profile}")
|
||||
end
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(media_profile) end
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(source) end
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(media_item) end
|
||||
end
|
||||
|
||||
test "redirects to the media_profiles page", %{conn: conn, media_profile: media_profile} do
|
||||
conn = delete(conn, ~p"/media_profiles/#{media_profile}")
|
||||
|
||||
assert redirected_to(conn) == ~p"/media_profiles"
|
||||
end
|
||||
|
||||
test "doesn't delete any files", %{conn: conn, media_profile: media_profile} do
|
||||
source = source_fixture(media_profile_id: media_profile.id)
|
||||
media_item = media_item_with_attachments(%{source_id: source.id})
|
||||
|
||||
delete(conn, ~p"/media_profiles/#{media_profile}")
|
||||
|
||||
assert File.exists?(media_item.media_filepath)
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete media_profile when deleting the records and files" do
|
||||
setup [:create_media_profile]
|
||||
|
||||
test "deletes chosen media_profile and its associations", %{conn: conn, media_profile: media_profile} do
|
||||
source = source_fixture(media_profile_id: media_profile.id)
|
||||
media_item = media_item_with_attachments(%{source_id: source.id})
|
||||
|
||||
conn = delete(conn, ~p"/media_profiles/#{media_profile}?delete_files=true")
|
||||
assert redirected_to(conn) == ~p"/media_profiles"
|
||||
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(media_profile) end
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(source) end
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(media_item) end
|
||||
end
|
||||
|
||||
test "redirects to the media_profiles page", %{conn: conn, media_profile: media_profile} do
|
||||
conn = delete(conn, ~p"/media_profiles/#{media_profile}?delete_files=true")
|
||||
|
||||
assert redirected_to(conn) == ~p"/media_profiles"
|
||||
end
|
||||
|
||||
test "deletes the files", %{conn: conn, media_profile: media_profile} do
|
||||
source = source_fixture(media_profile_id: media_profile.id)
|
||||
media_item = media_item_with_attachments(%{source_id: source.id})
|
||||
|
||||
delete(conn, ~p"/media_profiles/#{media_profile}?delete_files=true")
|
||||
|
||||
refute File.exists?(media_item.media_filepath)
|
||||
end
|
||||
end
|
||||
|
||||
defp create_media_profile(_) do
|
||||
media_profile = media_profile_fixture()
|
||||
|
||||
%{media_profile: media_profile}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,8 +2,11 @@ defmodule PinchflatWeb.SourceControllerTest do
|
||||
use PinchflatWeb.ConnCase
|
||||
import Mox
|
||||
|
||||
import Pinchflat.ProfilesFixtures
|
||||
import Pinchflat.MediaFixtures
|
||||
import Pinchflat.SourcesFixtures
|
||||
import Pinchflat.ProfilesFixtures
|
||||
|
||||
alias Pinchflat.Repo
|
||||
|
||||
setup do
|
||||
media_profile = media_profile_fixture()
|
||||
@@ -119,21 +122,53 @@ defmodule PinchflatWeb.SourceControllerTest do
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete source" do
|
||||
describe "delete source when just deleting the records" do
|
||||
setup [:create_source]
|
||||
|
||||
test "deletes chosen source", %{conn: conn, source: source} do
|
||||
test "deletes chosen source and media_items", %{conn: conn, source: source, media_item: media_item} do
|
||||
delete(conn, ~p"/sources/#{source}")
|
||||
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(source) end
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(media_item) end
|
||||
end
|
||||
|
||||
test "redirects to the sources page", %{conn: conn, source: source} do
|
||||
conn = delete(conn, ~p"/sources/#{source}")
|
||||
assert redirected_to(conn) == ~p"/sources"
|
||||
end
|
||||
|
||||
assert_error_sent 404, fn ->
|
||||
get(conn, ~p"/sources/#{source}")
|
||||
end
|
||||
test "does not delete the files", %{conn: conn, source: source, media_item: media_item} do
|
||||
delete(conn, ~p"/sources/#{source}")
|
||||
assert File.exists?(media_item.media_filepath)
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete source when deleting the records and files" do
|
||||
setup [:create_source]
|
||||
|
||||
test "deletes chosen source and media_items", %{conn: conn, source: source, media_item: media_item} do
|
||||
delete(conn, ~p"/sources/#{source}?delete_files=true")
|
||||
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(source) end
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(media_item) end
|
||||
end
|
||||
|
||||
test "redirects to the sources page", %{conn: conn, source: source} do
|
||||
conn = delete(conn, ~p"/sources/#{source}?delete_files=true")
|
||||
assert redirected_to(conn) == ~p"/sources"
|
||||
end
|
||||
|
||||
test "deletes the files", %{conn: conn, source: source, media_item: media_item} do
|
||||
delete(conn, ~p"/sources/#{source}?delete_files=true")
|
||||
refute File.exists?(media_item.media_filepath)
|
||||
end
|
||||
end
|
||||
|
||||
defp create_source(_) do
|
||||
%{source: source_fixture()}
|
||||
source = source_fixture()
|
||||
media_item = media_item_with_attachments(%{source_id: source.id})
|
||||
|
||||
%{source: source, media_item: media_item}
|
||||
end
|
||||
|
||||
defp runner_function_mock(_url, _opts, _ot) do
|
||||
|
||||
Reference in New Issue
Block a user