Delete media items (#20)
* Added method for deleting media files and their content * Adds controllers and methods for deleting media and files * Improved tmpfile setup and teardown for tests * Actually got tmpfile cleanup running once per suite run * Finally fixed flash messages
This commit is contained in:
@@ -221,6 +221,24 @@ defmodule Pinchflat.MediaTest do
|
||||
end
|
||||
end
|
||||
|
||||
describe "media_filepaths/1" do
|
||||
test "returns filepaths in a flat list" do
|
||||
filepaths = %{
|
||||
media_filepath: "/video/test.mp4",
|
||||
thumbnail_filepath: "/video/test.jpg",
|
||||
subtitle_filepaths: [["en", "video/test.srt"]]
|
||||
}
|
||||
|
||||
media_item = media_item_fixture(filepaths)
|
||||
|
||||
assert Media.media_filepaths(media_item) == [
|
||||
"/video/test.mp4",
|
||||
"/video/test.jpg",
|
||||
"video/test.srt"
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
describe "create_media_item/1" do
|
||||
test "creating with valid data creates a media_item" do
|
||||
valid_attrs = %{
|
||||
@@ -282,6 +300,61 @@ defmodule Pinchflat.MediaTest do
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete_attachments/1" do
|
||||
test "deletes the media item's files" do
|
||||
media_item = media_item_with_attachments()
|
||||
|
||||
assert {:ok, _} = Media.delete_attachments(media_item)
|
||||
refute File.exists?(media_item.media_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)
|
||||
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)
|
||||
refute File.exists?(root_directory)
|
||||
end
|
||||
|
||||
test "does not delete the parent folder if it is not empty" do
|
||||
media_item = media_item_with_attachments()
|
||||
root_directory = Path.dirname(media_item.media_filepath)
|
||||
File.touch(Path.join([root_directory, "test.txt"]))
|
||||
|
||||
assert {:ok, _} = Media.delete_attachments(media_item)
|
||||
assert File.exists?(root_directory)
|
||||
|
||||
:ok = File.rm(Path.join([root_directory, "test.txt"]))
|
||||
:ok = File.rmdir(root_directory)
|
||||
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()
|
||||
|
||||
@@ -12,7 +12,7 @@ defmodule Pinchflat.Profiles.Options.YtDlp.DownloadOptionBuilderTest do
|
||||
test "it generates an expanded output path based on the given template" do
|
||||
assert {:ok, res} = DownloadOptionBuilder.build(@media_profile)
|
||||
|
||||
assert {:output, "/tmp/videos/%(title)S.%(ext)s"} in res
|
||||
assert {:output, "/tmp/test/videos/%(title)S.%(ext)s"} in res
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -3,15 +3,74 @@ defmodule PinchflatWeb.MediaItemControllerTest do
|
||||
|
||||
import Pinchflat.MediaFixtures
|
||||
|
||||
alias Pinchflat.Repo
|
||||
alias Pinchflat.Media
|
||||
|
||||
describe "show media" do
|
||||
setup [:create_media_item]
|
||||
|
||||
test "renders the page", %{conn: conn, media_item: media_item} do
|
||||
conn = get(conn, ~p"/media/#{media_item}")
|
||||
conn = get(conn, ~p"/sources/#{media_item.source_id}/media/#{media_item}")
|
||||
assert html_response(conn, 200) =~ "Media Item ##{media_item.id}"
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete media when just deleting the records" do
|
||||
setup do
|
||||
media_item = media_item_with_attachments()
|
||||
|
||||
on_exit(fn ->
|
||||
Media.delete_attachments(media_item)
|
||||
end)
|
||||
|
||||
%{media_item: media_item}
|
||||
end
|
||||
|
||||
test "the media item is deleted", %{conn: conn, media_item: media_item} do
|
||||
delete(conn, ~p"/sources/#{media_item.source_id}/media/#{media_item.id}")
|
||||
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(media_item) end
|
||||
end
|
||||
|
||||
test "the files are not deleted", %{conn: conn, media_item: media_item} do
|
||||
delete(conn, ~p"/sources/#{media_item.source_id}/media/#{media_item.id}")
|
||||
|
||||
assert File.exists?(media_item.media_filepath)
|
||||
end
|
||||
|
||||
test "redirects to the source page", %{conn: conn, media_item: media_item} do
|
||||
conn = delete(conn, ~p"/sources/#{media_item.source_id}/media/#{media_item.id}")
|
||||
|
||||
assert redirected_to(conn) == ~p"/sources/#{media_item.source_id}"
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete media when deleting the records and files" do
|
||||
setup do
|
||||
media_item = media_item_with_attachments()
|
||||
|
||||
%{media_item: media_item}
|
||||
end
|
||||
|
||||
test "the media item is deleted", %{conn: conn, media_item: media_item} do
|
||||
delete(conn, ~p"/sources/#{media_item.source_id}/media/#{media_item.id}?delete_files=true")
|
||||
|
||||
assert_raise Ecto.NoResultsError, fn -> Repo.reload!(media_item) end
|
||||
end
|
||||
|
||||
test "the files are deleted", %{conn: conn, media_item: media_item} do
|
||||
delete(conn, ~p"/sources/#{media_item.source_id}/media/#{media_item.id}?delete_files=true")
|
||||
|
||||
refute File.exists?(media_item.media_filepath)
|
||||
end
|
||||
|
||||
test "redirects to the source page", %{conn: conn, media_item: media_item} do
|
||||
conn = delete(conn, ~p"/sources/#{media_item.source_id}/media/#{media_item.id}?delete_files=true")
|
||||
|
||||
assert redirected_to(conn) == ~p"/sources/#{media_item.source_id}"
|
||||
end
|
||||
end
|
||||
|
||||
defp create_media_item(_) do
|
||||
media_item = media_item_fixture()
|
||||
%{media_item: media_item}
|
||||
|
||||
@@ -34,6 +34,7 @@ defmodule PinchflatWeb.ConnCase do
|
||||
|
||||
setup tags do
|
||||
Pinchflat.DataCase.setup_sandbox(tags)
|
||||
Pinchflat.DataCase.setup_temp_filepaths()
|
||||
{:ok, conn: Phoenix.ConnTest.build_conn()}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -32,6 +32,20 @@ defmodule Pinchflat.DataCase do
|
||||
|
||||
setup tags do
|
||||
Pinchflat.DataCase.setup_sandbox(tags)
|
||||
Pinchflat.DataCase.setup_temp_filepaths()
|
||||
:ok
|
||||
end
|
||||
|
||||
@doc """
|
||||
Sets up the temp filepaths for the media and metadata directories.
|
||||
"""
|
||||
def setup_temp_filepaths do
|
||||
File.rm_rf!(Application.get_env(:pinchflat, :media_directory))
|
||||
File.rm_rf!(Application.get_env(:pinchflat, :metadata_directory))
|
||||
|
||||
File.mkdir_p!(Application.get_env(:pinchflat, :media_directory))
|
||||
File.mkdir_p!(Application.get_env(:pinchflat, :metadata_directory))
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
@@ -31,9 +31,9 @@ defmodule Pinchflat.MediaFixtures do
|
||||
def media_item_with_metadata(attrs \\ %{}) do
|
||||
json_filepath =
|
||||
Path.join([
|
||||
Path.dirname(__ENV__.file),
|
||||
File.cwd!(),
|
||||
"test",
|
||||
"support",
|
||||
"fixtures",
|
||||
"files",
|
||||
"media_metadata.json"
|
||||
])
|
||||
@@ -44,4 +44,28 @@ defmodule Pinchflat.MediaFixtures do
|
||||
|
||||
media_item_fixture(merged_attrs)
|
||||
end
|
||||
|
||||
def media_item_with_attachments(attrs \\ %{}) do
|
||||
stored_media_filepath =
|
||||
Path.join([
|
||||
Application.get_env(:pinchflat, :media_directory),
|
||||
"#{:rand.uniform(1_000_000)}",
|
||||
"#{:rand.uniform(1_000_000)}_media.mkv"
|
||||
])
|
||||
|
||||
fixture_media_filepath =
|
||||
Path.join([
|
||||
File.cwd!(),
|
||||
"test",
|
||||
"support",
|
||||
"files",
|
||||
"media.mkv"
|
||||
])
|
||||
|
||||
:ok = File.mkdir_p(Path.dirname(stored_media_filepath))
|
||||
:ok = File.cp(fixture_media_filepath, stored_media_filepath)
|
||||
|
||||
merged_attrs = Map.merge(attrs, %{media_filepath: stored_media_filepath})
|
||||
media_item_fixture(merged_attrs)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,3 +4,11 @@ Application.put_env(:pinchflat, :yt_dlp_runner, YtDlpRunnerMock)
|
||||
ExUnit.start()
|
||||
Ecto.Adapters.SQL.Sandbox.mode(Pinchflat.Repo, :manual)
|
||||
Faker.start()
|
||||
|
||||
ExUnit.after_suite(fn _ ->
|
||||
File.rm_rf!(Application.get_env(:pinchflat, :media_directory))
|
||||
File.rm_rf!(Application.get_env(:pinchflat, :metadata_directory))
|
||||
|
||||
File.mkdir_p!(Application.get_env(:pinchflat, :media_directory))
|
||||
File.mkdir_p!(Application.get_env(:pinchflat, :metadata_directory))
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user