From db0222ff94cdb1921852b564b0600242ee081f5a Mon Sep 17 00:00:00 2001 From: CJ_Clippy Date: Tue, 21 Jan 2025 12:42:01 -0800 Subject: [PATCH] fix create_thumbnail automation --- services/bright/lib/bright/b2.ex | 37 ++++-- services/bright/lib/bright/cache.ex | 122 ++++-------------- services/bright/lib/bright/downloader.ex | 33 +++++ services/bright/lib/bright/images.ex | 29 ++++- .../bright/oban_workers/create_s3_asset.ex | 65 +++++----- .../bright/oban_workers/create_thumbnail.ex | 66 ++++++---- .../lib/bright/oban_workers/process_vod.ex | 20 +-- services/bright/lib/bright/streams.ex | 44 +++---- services/bright/lib/bright/streams/stream.ex | 1 - services/bright/lib/bright/uploads.ex | 2 +- .../controllers/vod_html/show.html.heex | 1 + ...250121125008_remove_views_from_streams.exs | 9 ++ services/bright/test/bright/b2_test.exs | 23 +++- services/bright/test/bright/blog_test.exs | 61 --------- services/bright/test/bright/cache_test.ex | 32 ++++- services/bright/test/bright/catalog_test.exs | 119 ----------------- .../bright/test/bright/downloader_test.exs | 23 ++++ services/bright/test/bright/images_test.exs | 16 ++- .../oban_workers/create_hls_playlist_test.exs | 86 +----------- .../oban_workers/create_s3_asset_test.exs | 72 ++++++++--- .../oban_workers/create_thumbnail_test.exs | 22 +++- .../bright/oban_workers/process_vod_test.exs | 63 +++++++++ services/bright/test/bright/orders_test.exs | 117 ----------------- .../bright/test/bright/platforms_test.exs | 8 +- .../bright/test/bright/shopping_cart_test.exs | 115 ----------------- services/bright/test/bright/streams_test.exs | 23 ++-- services/bright/test/bright/tags_test.exs | 2 +- .../test/support/fixtures/catalog_fixtures.ex | 42 ------ .../test/support/fixtures/orders_fixtures.ex | 36 ------ .../fixtures/shopping_cart_fixtures.ex | 42 ------ .../test/support/fixtures/streams_fixtures.ex | 8 +- 31 files changed, 469 insertions(+), 870 deletions(-) create mode 100644 services/bright/lib/bright/downloader.ex create mode 100644 services/bright/priv/repo/migrations/20250121125008_remove_views_from_streams.exs delete mode 100644 services/bright/test/bright/blog_test.exs delete mode 100644 services/bright/test/bright/catalog_test.exs create mode 100644 services/bright/test/bright/downloader_test.exs create mode 100644 services/bright/test/bright/oban_workers/process_vod_test.exs delete mode 100644 services/bright/test/bright/orders_test.exs delete mode 100644 services/bright/test/bright/shopping_cart_test.exs delete mode 100644 services/bright/test/support/fixtures/catalog_fixtures.ex delete mode 100644 services/bright/test/support/fixtures/orders_fixtures.ex delete mode 100644 services/bright/test/support/fixtures/shopping_cart_fixtures.ex diff --git a/services/bright/lib/bright/b2.ex b/services/bright/lib/bright/b2.ex index d7e6f27..2f6c820 100644 --- a/services/bright/lib/bright/b2.ex +++ b/services/bright/lib/bright/b2.ex @@ -12,9 +12,16 @@ defmodule Bright.B2 do alias Bright.B2 + @doc """ + Put a file from local disk to Backblaze. This function uses the filename as the S3 key. Use put/2 if you want to specify the key + """ + def put(local_file) do + object_key = Path.basename(local_file) + put(local_file, object_key) + end @doc """ - Put a file from local disk to Backblaze + Put a file from local disk to Backblaze. """ def put(local_file, object_key) do @@ -23,13 +30,19 @@ defmodule Bright.B2 do raise("bucket specification is missing") end + s3_cdn_endpoint = Application.get_env(:bright, :s3_cdn_endpoint) + if s3_cdn_endpoint === nil do + raise("s3_cdn_endpoint specification is missing") + end + cdn_url = "#{s3_cdn_endpoint}/#{object_key}" + local_file |> S3.Upload.stream_file |> S3.upload(bucket, object_key) |> ExAws.request |> case do - {:ok, %{status_code: 200}} -> {:ok, object_key} + {:ok, %{status_code: 200}} -> {:ok, %{key: object_key, cdn_url: cdn_url}} {:error, reason} -> {:error, reason} end @@ -56,17 +69,19 @@ defmodule Bright.B2 do end + + + end + + + @doc """ + Given a S3 object_key, generate an appropriate CDN url. + """ + def generate_cdn_url(object_key) do + cdn_url = Application.get_env(:bright, :public_s3_endpoint) || raise(":public_s3_endpoint missing from App env") + "#{cdn_url}/#{object_key}" end - # defp upload_to_s3(body, key) do - # body - # |> S3.upload(@bucket_name, key) - # |> ExAws.request() - # |> case do - # {:ok, _response} -> :ok - # {:error, reason} -> {:error, reason} - # end - # end end diff --git a/services/bright/lib/bright/cache.ex b/services/bright/lib/bright/cache.ex index d0af26b..e49e649 100644 --- a/services/bright/lib/bright/cache.ex +++ b/services/bright/lib/bright/cache.ex @@ -6,16 +6,38 @@ defmodule Bright.Cache do alias Bright.Streams.Vod - @cache_dir "/tmp/bright_cache" + @cache_dir Path.join(System.user_home!(), ".cache/futureporn") require Logger - def generate_filename(input) do + def generate_basename(input) do prefix = :crypto.strong_rand_bytes(6) |> Base.encode64(padding: false) |> String.replace(~r/[^a-zA-Z0-9]/, "") base = Path.basename(input) "#{prefix}-#{base}" end + def generate_basename(input, ext) do + input + |> generate_basename + |> Path.rootname + |> Kernel.<>(".#{ext}") + end + + def generate_filename(input) do + Path.join(@cache_dir, generate_basename(input)) + end + + def generate_filename(input, ext) do + Path.join(@cache_dir, generate_basename(input, ext)) + + # @cache_dir + # input + # |> generate_basename + # |> Path.join(@cache_dir) + # |> Path.rootname + # |> Kernel.<>(".#{ext}") + end + # Ensure the cache directory exists defp ensure_cache_dir! do @@ -24,98 +46,9 @@ defmodule Bright.Cache do end end - @doc """ - Save data to the cache with a given key. - - ## Examples - - iex> Bright.Cache.put("example_key", "example_data") - :ok - """ - def put(key, data) do - - ensure_cache_dir!() - - file_path = cache_file_path(key) - - case File.write(file_path, data) do - :ok -> - Logger.debug("[Cache] Saved key #{key} to #{file_path}") - :ok - - {:error, reason} -> - Logger.error("[Cache] Failed to save key #{key}: #{reason}") - {:error, reason} - end - end - - @doc """ - Save a VOD file to the cache using its origin_temp_input_url. - - ## Examples - - iex> Bright.Cache.put(%Vod{key: "vod_key", origin_temp_input_url: "http://example.com/video.mp4"}) - :ok - """ - def put(%Vod{origin_temp_input_url: url}) do - ensure_cache_dir!() - - key = generate_filename(url) - file_path = cache_file_path(key) - - case HTTPoison.get(url) do - {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> - case File.write(file_path, body) do - :ok -> - Logger.debug("[Cache] Downloaded and saved VOD #{key} from #{url} to #{file_path}") - :ok - - {:error, reason} -> - Logger.error("[Cache] Failed to save VOD #{key}: #{reason}") - {:error, reason} - end - - {:ok, %HTTPoison.Response{status_code: status}} -> - Logger.error("[Cache] Failed to download VOD #{key}: HTTP #{status}") - {:error, :http_error} - - {:error, %HTTPoison.Error{reason: reason}} -> - Logger.error("[Cache] Failed to download VOD #{key}: #{reason}") - {:error, reason} - end - end - @doc """ - Retrieve data from the cache for a given key. - ## Examples - - iex> Bright.Cache.get("example_key") - {:ok, "example_data"} - - iex> Bright.Cache.get("nonexistent_key") - :error - """ - def get(key) do - ensure_cache_dir!() - - file_path = cache_file_path(key) - - case File.read(file_path) do - {:ok, data} -> - Logger.debug("[Cache] Retrieved key #{key} from #{file_path}") - {:ok, data} - - {:error, :enoent} -> - Logger.debug("[Cache] Key #{key} not found in cache") - :error - - {:error, reason} -> - Logger.error("[Cache] Failed to retrieve key #{key}: #{reason}") - {:error, reason} - end - end @doc """ Delete a cached item by its key. @@ -131,7 +64,7 @@ defmodule Bright.Cache do def delete(key) do ensure_cache_dir!() - file_path = cache_file_path(key) + file_path = generate_filename(key) case File.rm(file_path) do :ok -> @@ -171,8 +104,5 @@ defmodule Bright.Cache do end end - # Helper function to generate the file path for a given key - defp cache_file_path(key) do - Path.join(@cache_dir, key) - end + end diff --git a/services/bright/lib/bright/downloader.ex b/services/bright/lib/bright/downloader.ex new file mode 100644 index 0000000..0fc141f --- /dev/null +++ b/services/bright/lib/bright/downloader.ex @@ -0,0 +1,33 @@ +defmodule Bright.Downloader do + @moduledoc """ + Downloader functions + """ + + + def get(url) do + + local_file = Bright.Cache.generate_filename(url) + headers = %{} + case HTTPoison.get(url, headers) do + {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> + case File.write(local_file, body) do + :ok -> {:ok, local_file} + end + + {:ok, %HTTPoison.Response{status_code: status, body: body}} -> + {:error, %{status: status, body: body}} + + {:error, %HTTPoison.Error{reason: reason}} -> + {:error, reason} + + failed -> + Logger.error("Failed to GET #{url}") + {:error, :failed} + end + + + + + end + +end diff --git a/services/bright/lib/bright/images.ex b/services/bright/lib/bright/images.ex index b6af1aa..71b5001 100644 --- a/services/bright/lib/bright/images.ex +++ b/services/bright/lib/bright/images.ex @@ -6,7 +6,7 @@ defmodule Bright.Images do import FFmpex use FFmpex.Options require Logger - + alias Bright.Cache def get_video_duration(file_path) do case FFprobe.streams(file_path) do @@ -56,9 +56,7 @@ defmodule Bright.Images do end end - - def create_thumbnail(input_file, output_file) do - + defp gen_thumb(input_file, output_file) do case get_video_framecount(input_file) do {:error, reason} -> {:error, reason} {:ok, framecount} -> @@ -75,14 +73,33 @@ defmodule Bright.Images do |> add_output_file(output_file) |> add_file_option(option_vframes(1)) |> add_file_option(option_vf("select=not(mod(n\\,#{frame_interval})),scale=#{scale_width}:-1,tile=#{tile_grid}")) - |> add_file_option(option_vsync(1)) # -vsync is deprecated in ffmpeg but ffmpex doesn't have the modern replacement, -fps_mode + |> add_file_option(option_vsync(0)) # -vsync is deprecated in ffmpeg but ffmpex doesn't have the modern replacement, -fps_mode # |> add_file_option(option_update(1)) # ffmpeg complains but it doesn't necessarily need this. I'm omitting because ffmpex doesn't know this function # |> add_file_option(option_fps_mode("passthrough")) # -fps_mode is the modern replacement for -vsync - execute(command) + + Logger.info("generating thumbnail...") + IO.puts "generating thumbnail with input_file=#{input_file} output_file=#{output_file}" + case execute(command) do + {:ok, output} -> + {:ok, %{output: output, filename: output_file}} + {:error, reason} -> + Logger.error("Error generating thumbnail: #{inspect(reason)}") + {:error, reason} + end end end + def create_thumbnail(input_file) do + output_file = Cache.generate_filename(input_file, "png") + IO.puts "creating_thumbnail from #{input_file} and saving it to #{output_file}" + gen_thumb(input_file, output_file) + end + + def create_thumbnail(input_file, output_file) do + gen_thumb(input_file, output_file) + end + diff --git a/services/bright/lib/bright/oban_workers/create_s3_asset.ex b/services/bright/lib/bright/oban_workers/create_s3_asset.ex index f828eda..122db13 100644 --- a/services/bright/lib/bright/oban_workers/create_s3_asset.ex +++ b/services/bright/lib/bright/oban_workers/create_s3_asset.ex @@ -1,47 +1,48 @@ defmodule Bright.ObanWorkers.CreateS3Asset do use Oban.Worker, queue: :default, max_attempts: 3 - alias ExAws.S3 require Logger - @bucket_name System.get_env("AWS_BUCKET") + alias ExAws.S3 + alias Bright.Cache + alias Bright.Downloader + alias Bright.B2 + alias Bright.Repo + @impl Oban.Worker def perform(%Oban.Job{args: %{"input_url" => input_url, "vod_id" => vod_id}}) do - Logger.info("@todo implementation needed") - # random_string = for _ <- 1..12, into: "", do: <> - # output_file = "/tmp/#{random_string}-#{key}" - # with {:ok, %HTTPoison.Response{status_code: 200, body: body}} <- fetch_file(input_url), - # {:ok, local_path} <- save_file(body, key), - # :ok <- upload_to_s3(local_path, key) do - # :ok - # else - # {:error, reason} -> - # Logger.error("Failed to process job: #{inspect(reason)}") - # {:error, reason} - # end + + Logger.info("CreateS3Asset begin.") + vod = Repo.get!(Vod, vod_id) + basename = Cache.generate_basename(input_url) + + with {:ok, local_file} <- Downloader.get(input_url), + {:ok, object_key} <- B2.put(local_file, basename) do + update_vod_with_s3_asset(vod, object_key) + + else + {:error, reason} -> + Logger.error("Failed to create S3 Asset for VOD ID #{vod_id}: #{inspect(reason)}") + {:error, reason} + end end - # defp fetch_file(url) do - # case HTTPoison.get(url, [], stream_to: self()) do - # {:ok, response} when response.status_code in 200..299 -> - # {:ok, response} + defp update_vod_with_s3_asset(vod, object_key) do + basename = Path.basename(vod.thumbnail_url) + s3_cdn_url = B2.generate_cdn_url(object_key) - # {:ok, %HTTPoison.Response{status_code: status}} -> - # {:error, "HTTP request failed with status: #{status}"} + vod + |> Ecto.Changeset.change(s3_cdn_url: s3_cdn_url) + |> Repo.update!() + end - # {:error, %HTTPoison.Error{reason: reason}} -> - # {:error, reason} - # end + # defp update_vod_with_playlist_url(vod, asset_id) do + # playlist_url = generate_playlist_url(asset_id) + # Logger.info("playlist_url=#{playlist_url}") + # vod + # |> Ecto.Changeset.change(playlist_url: playlist_url) + # |> Repo.update!() # end - # defp upload_to_s3(body, key) do - # body - # |> S3.upload(@bucket_name, key) - # |> ExAws.request() - # |> case do - # {:ok, _response} -> :ok - # {:error, reason} -> {:error, reason} - # end - # end end diff --git a/services/bright/lib/bright/oban_workers/create_thumbnail.ex b/services/bright/lib/bright/oban_workers/create_thumbnail.ex index d6e449c..18ace3d 100644 --- a/services/bright/lib/bright/oban_workers/create_thumbnail.ex +++ b/services/bright/lib/bright/oban_workers/create_thumbnail.ex @@ -1,46 +1,60 @@ defmodule Bright.ObanWorkers.CreateThumbnail do use Oban.Worker, queue: :default, max_attempts: 3 - alias Bright.Cache - alias Bright.Images - alias Bright.B2 + alias Bright.Streams.Vod + alias Bright.{ + Repo, + Downloader, + B2, + Images, + Cache + } require Logger @impl Oban.Worker - def perform(%Oban.Job{args: %{"vod_id" => vod_id, "origin_temp_input_url" => origin_temp_input_url}}) do + def perform(%Oban.Job{args: %{"vod_id" => vod_id}}) do + Logger.info(">>>> CreateThumbnail is performing. with vod_id=#{vod_id}") - IO.puts ">>>> CreateThumbnail is performing. with vod_id=#{vod_id}" - vod = Repo.get!(Vod, vod_id) + case Repo.get(Vod, vod_id) do + nil -> + Logger.error("VOD ID #{vod_id} not found") + {:error, "VOD not found"} - with {:ok, cache_filename} <- Cache.put(origin_temp_input_url), - {:ok, thumb_filename} <- Images.create_thumbnail(cache_filename), - {:ok, s3Asset} <- B2.put(thumb_filename) do - update_vod_with_thumbnail_url(vod, s3Asset.cdn_url) - else - {:error, reason} -> - Logger.error("Failed to create HLS playlist for VOD ID #{vod_id}: #{inspect(reason)}") - {:error, reason} + %Vod{origin_temp_input_url: origin_temp_input_url} = vod -> + with {:ok, local_filename} <- Downloader.get(origin_temp_input_url), + {:ok, %{output: output, filename: output_file}} <- Images.create_thumbnail(local_filename), + {:ok, s3Asset} <- B2.put(output_file) + do + IO.puts("updating vod ...") + update_vod_with_thumbnail_url(vod, s3Asset.cdn_url) + else + {:error, reason} -> + Logger.error("Failed to create thumbnail for VOD ID #{vod_id}: #{inspect(reason)}") + {:error, reason} + end end end - - # vod - # |> Cache.put - # |> Images.create_thumbnail - # |> B2.put - defp generate_thumbnail_url(basename), do: "#{@public_s3_endpoint}/#{basename}" + # defp update_vod_with_thumbnail_url(vod, thumbnail_url) do + # IO.puts "thumbnail_url=#{thumbnail_url}" + # vod + # |> Ecto.Changeset.change(thumbnail_url: thumbnail_url) + # |> Repo.update!() + + # end + defp update_vod_with_thumbnail_url(vod, thumbnail_url) do - basename = Path.basename(thumbnail_url) - thumbnail_url = generate_thumbnail_url(basename) - Logger.info("thumbnail_url=#{thumbnail_url}") - vod - |> Ecto.Changeset.change(thumbnail_url: thumbnail_url) - |> Repo.update!() + IO.puts "thumbnail_url=#{thumbnail_url}" + case Repo.update(vod |> Ecto.Changeset.change(thumbnail_url: thumbnail_url)) do + {:ok, updated_vod} -> {:ok, updated_vod} + {:error, changeset} -> {:error, changeset} + end end + end diff --git a/services/bright/lib/bright/oban_workers/process_vod.ex b/services/bright/lib/bright/oban_workers/process_vod.ex index 645477b..42bd290 100644 --- a/services/bright/lib/bright/oban_workers/process_vod.ex +++ b/services/bright/lib/bright/oban_workers/process_vod.ex @@ -12,22 +12,16 @@ defmodule Bright.ObanWorkers.ProcessVod do } @impl Oban.Worker - def perform(%Oban.Job{args: %{"id" => id}} = job) do - Logger.info("Performing job: #{inspect(job)}") + def perform(%Oban.Job{args: %{"vod_id" => vod_id}}) do - vod = Repo.get!(Vod, id) + vod = Repo.get!(Vod, vod_id) - if vod.playlist_url == nil and vod.origin_temp_input_url != nil do - queue_create_hls_playlist(vod) - end - if vod.s3_key == nil do - queue_create_s3_asset(vod) - end - - if vod.thumbnail_url == nil and vod.origin_temp_input_url != nil do - queue_create_thumbnail(vod) + if vod.origin_temp_input_url do + unless vod.playlist_url, do: queue_create_hls_playlist(vod) + unless vod.s3_cdn_url, do: queue_create_s3_asset(vod) + unless vod.thumbnail_url, do: queue_create_thumbnail(vod) end @@ -46,7 +40,7 @@ defmodule Bright.ObanWorkers.ProcessVod do end defp queue_create_thumbnail(%Vod{id: id, origin_temp_input_url: url}) do - job_args = %{vod_id: id} + job_args = %{vod_id: id, input_url: url} Oban.insert!(CreateThumbnail.new(job_args)) end diff --git a/services/bright/lib/bright/streams.ex b/services/bright/lib/bright/streams.ex index b4d008c..5e41794 100644 --- a/services/bright/lib/bright/streams.ex +++ b/services/bright/lib/bright/streams.ex @@ -123,12 +123,6 @@ defmodule Bright.Streams do |> Ecto.Changeset.put_assoc(:platforms, platforms) end - def inc_page_views(%Stream{} = stream) do - {1, [%Stream{views: views}]} = - from(s in Stream, where: s.id == ^stream.id, select: [:views]) - |> Repo.update_all(inc: [views: 1]) - put_in(stream.views, views) - end def list_tags_by_id(nil), do: [] def list_tags_by_id(tag_ids) do @@ -198,8 +192,8 @@ defmodule Bright.Streams do |> Vod.changeset(attrs) |> Repo.insert() |> case do - {:ok, vod} -> - maybe_enqueue_process_vod(vod) + {:ok, %Vod{} = vod} -> + Oban.insert!(Bright.ObanWorkers.ProcessVod.new(%{vod_id: vod.id})) {:ok, vod} {:error, changeset} -> @@ -207,22 +201,28 @@ defmodule Bright.Streams do end end - - defp maybe_enqueue_process_vod(%Vod{id: id, origin_temp_input_url: origin_temp_input_url} = vod) do - - - - if origin_temp_input_url do - - - %{id: id, origin_temp_input_url: origin_temp_input_url} - |> Bright.ObanWorkers.ProcessVod.new() - |> Oban.insert() - - end - vod + def create_tag(attrs \\ %{}) do + %Tag{} + |> Tag.changeset(attrs) + |> Repo.insert() end + # def create_stream(attrs \\ %{}) do + # %Stream{} + # # |> Stream.changeset(attrs) + # |> change_stream(attrs) + # |> Repo.insert() + # end + + + + # defp enqueue_process_vod(%Vod{id: id} = vod) do + # %{vod_id: id} + # |> Bright.ObanWorkers.ProcessVod.new() + # |> Oban.insert() + # vod + # end + @doc """ diff --git a/services/bright/lib/bright/streams/stream.ex b/services/bright/lib/bright/streams/stream.ex index 5395456..e7abbc3 100644 --- a/services/bright/lib/bright/streams/stream.ex +++ b/services/bright/lib/bright/streams/stream.ex @@ -9,7 +9,6 @@ defmodule Bright.Streams.Stream do field :date, :utc_datetime field :title, :string field :notes, :string - field :views, :integer many_to_many :tags, Tag, join_through: "streams_tags", on_replace: :delete diff --git a/services/bright/lib/bright/uploads.ex b/services/bright/lib/bright/uploads.ex index 2a027b3..6bd8f69 100644 --- a/services/bright/lib/bright/uploads.ex +++ b/services/bright/lib/bright/uploads.ex @@ -23,7 +23,7 @@ defmodule Bright.Uploads do def download_file(url, destination_path) do case HTTPoison.get(url) do {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> - IO.puts "WE GOT A GOOD RESPONSE SO LETS WRITE" + # IO.puts "WE GOT A GOOD RESPONSE SO LETS WRITE" case File.write(destination_path, body) do :ok -> {:ok, "File downloaded successfully"} {:error, reason} -> {:error, reason} diff --git a/services/bright/lib/bright_web/controllers/vod_html/show.html.heex b/services/bright/lib/bright_web/controllers/vod_html/show.html.heex index 8b7cd6a..5628ced 100644 --- a/services/bright/lib/bright_web/controllers/vod_html/show.html.heex +++ b/services/bright/lib/bright_web/controllers/vod_html/show.html.heex @@ -52,6 +52,7 @@ <:item title="S3 upload">{@vod.s3_upload_id} <:item title="S3 key">{@vod.s3_key} <:item title="S3 bucket">{@vod.s3_bucket} + <:item title="Thumbnail URL">{@vod.thumbnail_url} <:item title="Ipfs CID">{@vod.ipfs_cid} <:item title="Torrent">{@vod.torrent} diff --git a/services/bright/priv/repo/migrations/20250121125008_remove_views_from_streams.exs b/services/bright/priv/repo/migrations/20250121125008_remove_views_from_streams.exs new file mode 100644 index 0000000..59f2383 --- /dev/null +++ b/services/bright/priv/repo/migrations/20250121125008_remove_views_from_streams.exs @@ -0,0 +1,9 @@ +defmodule Bright.Repo.Migrations.RemoveViewsFromStreams do + use Ecto.Migration + + def change do + alter table(:streams) do + remove :views + end + end +end diff --git a/services/bright/test/bright/b2_test.exs b/services/bright/test/bright/b2_test.exs index 3c33d84..b0cd85c 100644 --- a/services/bright/test/bright/b2_test.exs +++ b/services/bright/test/bright/b2_test.exs @@ -3,19 +3,25 @@ defmodule Bright.B2Test do - + @cdn_url Application.get_env(:bright, :public_s3_endpoint) describe "B2" do alias Bright.B2 - @tag :acceptance test "put/1" do + local_file = Path.absname("test/fixtures/SampleVideo_1280x720_1mb.mp4") + {:ok, %{key: key, cdn_url: cdn_url}} = B2.put(local_file) + assert key === "SampleVideo_1280x720_1mb.mp4" + end + + @tag :acceptance + test "put/2" do local_file = Path.absname("test/fixtures/SampleVideo_1280x720_1mb.mp4") object_key = "test/SampleVideo_1280x720_1mb.mp4" - {:ok, remote_file} = B2.put(local_file, object_key) - assert Regex.match?(~r/SampleVideo/, remote_file) + {:ok, %{key: key, cdn_url: cdn_url}} = B2.put(local_file, object_key) + assert Regex.match?(~r/SampleVideo/, key) end @@ -34,6 +40,15 @@ defmodule Bright.B2Test do File.rm!(local_file) end + + @tag :integration + test "generate_cdn_url/1" do + assert Regex.match?(~r"https:\/\/", @cdn_url), ":public_s3_endpoint was missing from `:bright` app config, which is a requirement for this test." + object_key = "test/SampleVideo_1280x720_1mb.mp4" + cdn_url = B2.generate_cdn_url(object_key) + assert cdn_url === "#{@cdn_url}/#{object_key}" + end + end end diff --git a/services/bright/test/bright/blog_test.exs b/services/bright/test/bright/blog_test.exs deleted file mode 100644 index da1953b..0000000 --- a/services/bright/test/bright/blog_test.exs +++ /dev/null @@ -1,61 +0,0 @@ -defmodule Bright.BlogTest do - use Bright.DataCase - - alias Bright.Blog - - describe "posts" do - alias Bright.Blog.Post - - import Bright.BlogFixtures - - @invalid_attrs %{title: nil, body: nil} - - test "list_posts/0 returns all posts" do - post = post_fixture() - assert Blog.list_posts() == [post] - end - - test "get_post!/1 returns the post with given id" do - post = post_fixture() - assert Blog.get_post!(post.id) == post - end - - test "create_post/1 with valid data creates a post" do - valid_attrs = %{title: "some title", body: "some body"} - - assert {:ok, %Post{} = post} = Blog.create_post(valid_attrs) - assert post.title == "some title" - assert post.body == "some body" - end - - test "create_post/1 with invalid data returns error changeset" do - assert {:error, %Ecto.Changeset{}} = Blog.create_post(@invalid_attrs) - end - - test "update_post/2 with valid data updates the post" do - post = post_fixture() - update_attrs = %{title: "some updated title", body: "some updated body"} - - assert {:ok, %Post{} = post} = Blog.update_post(post, update_attrs) - assert post.title == "some updated title" - assert post.body == "some updated body" - end - - test "update_post/2 with invalid data returns error changeset" do - post = post_fixture() - assert {:error, %Ecto.Changeset{}} = Blog.update_post(post, @invalid_attrs) - assert post == Blog.get_post!(post.id) - end - - test "delete_post/1 deletes the post" do - post = post_fixture() - assert {:ok, %Post{}} = Blog.delete_post(post) - assert_raise Ecto.NoResultsError, fn -> Blog.get_post!(post.id) end - end - - test "change_post/1 returns a post changeset" do - post = post_fixture() - assert %Ecto.Changeset{} = Blog.change_post(post) - end - end -end diff --git a/services/bright/test/bright/cache_test.ex b/services/bright/test/bright/cache_test.ex index 8fdf5db..f5e8143 100644 --- a/services/bright/test/bright/cache_test.ex +++ b/services/bright/test/bright/cache_test.ex @@ -3,23 +3,47 @@ defmodule Bright.CacheTest do alias Bright.Cache + @sample_url "https://example.com/my_video.mp4" + describe "cache" do + + @tag :unit - test "generate_filename generates a random alphanumeric prefix with the correct basename and extension" do + test "generate_basename/1" do # Test with a URL - url = "https://example.com/my_video.mp4" - filename = Cache.generate_filename(url) + url = @sample_url + filename = Cache.generate_basename(url) assert Regex.match?(~r/^[a-zA-Z0-9]+-my_video\.mp4$/, filename) # Test with a file path path = "/home/cj/Downloads/taco.mp4" - filename = Cache.generate_filename(path) + filename = Cache.generate_basename(path) assert Regex.match?(~r/^[a-zA-Z0-9]+-taco\.mp4$/, filename) end + @tag :unit + test "generate_basename/2" do + filename = Cache.generate_basename(@sample_url, "png") + assert Regex.match?(~r/^[a-zA-Z0-9]+-my_video\.png/, filename) + end + + @tag :unit + test "generate_filename/1" do + filename = Cache.generate_filename(@sample_url) + assert Regex.match?(~r/.cache\/futureporn\/.+-my_video\.mp4/, filename) + + filename = Cache.generate_filename("/home/cj/Downloads/test.mp4") + assert Regex.match?(~r/.cache\/futureporn\/.+-test\.mp4/, filename) + end + + @tag :unit + test "generate_filename/2" do + filename = Cache.generate_filename(@sample_url, "png") + assert Regex.match?(~r/.cache\/futureporn\/.+-my_video\.png/, filename) + end end diff --git a/services/bright/test/bright/catalog_test.exs b/services/bright/test/bright/catalog_test.exs deleted file mode 100644 index a4e835b..0000000 --- a/services/bright/test/bright/catalog_test.exs +++ /dev/null @@ -1,119 +0,0 @@ -defmodule Bright.CatalogTest do - use Bright.DataCase - - alias Bright.Catalog - - describe "products" do - alias Bright.Catalog.Product - - import Bright.CatalogFixtures - - @invalid_attrs %{description: nil, title: nil, price: nil, views: nil} - - test "list_products/0 returns all products" do - product = product_fixture() - assert Catalog.list_products() == [product] - end - - test "get_product!/1 returns the product with given id" do - product = product_fixture() - assert Catalog.get_product!(product.id) == product - end - - test "create_product/1 with valid data creates a product" do - valid_attrs = %{description: "some description", title: "some title", price: "120.5", views: 42} - - assert {:ok, %Product{} = product} = Catalog.create_product(valid_attrs) - assert product.description == "some description" - assert product.title == "some title" - assert product.price == Decimal.new("120.5") - assert product.views == 42 - end - - test "create_product/1 with invalid data returns error changeset" do - assert {:error, %Ecto.Changeset{}} = Catalog.create_product(@invalid_attrs) - end - - test "update_product/2 with valid data updates the product" do - product = product_fixture() - update_attrs = %{description: "some updated description", title: "some updated title", price: "456.7", views: 43} - - assert {:ok, %Product{} = product} = Catalog.update_product(product, update_attrs) - assert product.description == "some updated description" - assert product.title == "some updated title" - assert product.price == Decimal.new("456.7") - assert product.views == 43 - end - - test "update_product/2 with invalid data returns error changeset" do - product = product_fixture() - assert {:error, %Ecto.Changeset{}} = Catalog.update_product(product, @invalid_attrs) - assert product == Catalog.get_product!(product.id) - end - - test "delete_product/1 deletes the product" do - product = product_fixture() - assert {:ok, %Product{}} = Catalog.delete_product(product) - assert_raise Ecto.NoResultsError, fn -> Catalog.get_product!(product.id) end - end - - test "change_product/1 returns a product changeset" do - product = product_fixture() - assert %Ecto.Changeset{} = Catalog.change_product(product) - end - end - - describe "categories" do - alias Bright.Catalog.Category - - import Bright.CatalogFixtures - - @invalid_attrs %{title: nil} - - test "list_categories/0 returns all categories" do - category = category_fixture() - assert Catalog.list_categories() == [category] - end - - test "get_category!/1 returns the category with given id" do - category = category_fixture() - assert Catalog.get_category!(category.id) == category - end - - test "create_category/1 with valid data creates a category" do - valid_attrs = %{title: "some title"} - - assert {:ok, %Category{} = category} = Catalog.create_category(valid_attrs) - assert category.title == "some title" - end - - test "create_category/1 with invalid data returns error changeset" do - assert {:error, %Ecto.Changeset{}} = Catalog.create_category(@invalid_attrs) - end - - test "update_category/2 with valid data updates the category" do - category = category_fixture() - update_attrs = %{title: "some updated title"} - - assert {:ok, %Category{} = category} = Catalog.update_category(category, update_attrs) - assert category.title == "some updated title" - end - - test "update_category/2 with invalid data returns error changeset" do - category = category_fixture() - assert {:error, %Ecto.Changeset{}} = Catalog.update_category(category, @invalid_attrs) - assert category == Catalog.get_category!(category.id) - end - - test "delete_category/1 deletes the category" do - category = category_fixture() - assert {:ok, %Category{}} = Catalog.delete_category(category) - assert_raise Ecto.NoResultsError, fn -> Catalog.get_category!(category.id) end - end - - test "change_category/1 returns a category changeset" do - category = category_fixture() - assert %Ecto.Changeset{} = Catalog.change_category(category) - end - end -end diff --git a/services/bright/test/bright/downloader_test.exs b/services/bright/test/bright/downloader_test.exs new file mode 100644 index 0000000..05503a1 --- /dev/null +++ b/services/bright/test/bright/downloader_test.exs @@ -0,0 +1,23 @@ + + +defmodule Bright.DownloaderTest do + use Bright.DataCase + + alias Bright.Downloader + + @test_fixture "https://futureporn-b2.b-cdn.net/projekt-melody.jpg" + + describe "downloader" do + test "get/1" do + + {:ok, local_file} = Downloader.get(@test_fixture) + assert File.exists?(local_file) + {:ok, stat} = File.stat(local_file) + assert stat.size > 0, "File is empty" + assert Regex.match?(~r/.cache\/futureporn\/.+-projekt-melody\.jpg/, local_file) + + end + + end + +end diff --git a/services/bright/test/bright/images_test.exs b/services/bright/test/bright/images_test.exs index a4b02b1..39e65f4 100644 --- a/services/bright/test/bright/images_test.exs +++ b/services/bright/test/bright/images_test.exs @@ -9,7 +9,17 @@ defmodule Bright.ImagesTest do - test "should generate a 5x5 thumbnail using a local file" do + @tag :unit + test "create_thumbnail/1" do + {:ok, %{:output => output, :filename => filename}} = Images.create_thumbnail(@test_fixture) + assert output === "" + assert Regex.match?(~r/[a-zA-Z0-9]+-.*\.png$/, filename) + assert File.exists?(filename) + assert File.stat!(filename).size > 0, "thumbnail file is empty" + end + + @tag :unit + test "create_thumbnail/2" do # ffmpeg -y -i ~/Videos/moose-encounter_75.mp4 -frames:v 1 -vf 'select=not(mod(n\,257)),scale=160:-1,tile=5x5' -update 1 -fps_mode passthrough ~/Videos/thumb.jpg basename = "thumb.jpg" @@ -17,13 +27,11 @@ defmodule Bright.ImagesTest do output_file = "/tmp/#{random_string}-#{basename}" IO.puts "output_file=#{inspect(output_file)} @test_fixture=#{inspect(@test_fixture)}" - Images.create_thumbnail(@test_fixture, output_file) + {:ok, output } = Images.create_thumbnail(@test_fixture, output_file) assert File.exists?(output_file) {:ok, stat} = File.stat(output_file) assert stat.size > 0, "File is empty" - - end # Feature creep! Download the image for now. Make it work, first. THen make it right. THEN make it fast. diff --git a/services/bright/test/bright/oban_workers/create_hls_playlist_test.exs b/services/bright/test/bright/oban_workers/create_hls_playlist_test.exs index 4c19651..2802f92 100644 --- a/services/bright/test/bright/oban_workers/create_hls_playlist_test.exs +++ b/services/bright/test/bright/oban_workers/create_hls_playlist_test.exs @@ -13,6 +13,8 @@ defmodule Bright.CreateHlsPlaylistTest do describe "CreateHlsPlaylist" do + import Bright.StreamsFixtures + @tag :integration test "sheduling upon vod creation" do @@ -43,88 +45,4 @@ defmodule Bright.CreateHlsPlaylistTest do end - describe "perform/1" do - # test "throw when vod_id is missing" do - # job_args = %{"vod_id" => 1} - # {:error, reason} = CreateHlsPlaylist.perform(%Oban.Job{args: job_args}) - # assert Regex.match?(~r/missing.*vod_id/i, reason) - # end - - # test "evergreen?" do - # job_args = %{"vod_id" => 1, "input_url" => "https://example.com/my_video.mp4"} - # assert :ok = CreateHlsPlaylist.perform(%Oban.Job{args: job_args}) - # end - - # test "bypassing activation when sign up fails" do - # {:error, _reason} = CreateHlsPlaylist.perform(%Oban.Job{args: job_args}) - - # refute_enqueued worker: MyApp.ActivationWorker - # end - - # test "successfully creates an HLS playlist and updates the VOD" do - # # Mock the VOD to be returned by Repo.get!/2 - # vod = %Vod{id: 1, playlist_url: nil} - # expect(RepoMock, :get!, fn Vod, 1 -> vod end) - - # # Mock the start_transcode function - # expect(HTTPoisonMock, :post, fn url, body, headers -> - # assert url == "#{System.get_env("SUPERSTREAMER_URL")}/transcode" - # assert headers == [ - # {"authorization", "Bearer #{System.get_env("SUPERSTREAMER_AUTH_TOKEN")}"}, - # {"content-type", "application/json"} - # ] - # {:ok, %HTTPoison.Response{status_code: 200, body: ~s({"jobId": "transcode-job-id"})}} - # end) - - # # Mock the polling of the transcode job - # expect(HTTPoisonMock, :get, fn url, headers -> - # assert url == "#{System.get_env("SUPERSTREAMER_URL")}/jobs/transcode-job-id" - # {:ok, %HTTPoison.Response{ - # status_code: 200, - # body: ~s({"state": "completed", "outputData": {"assetId": "asset-id"}}) - # }} - # end) - - # # Mock the start_package function - # expect(HTTPoisonMock, :post, fn url, body, headers -> - # assert url == "#{System.get_env("SUPERSTREAMER_URL")}/package" - # {:ok, %HTTPoison.Response{status_code: 200, body: ~s({"jobId": "package-job-id"})}} - # end) - - # # Mock the polling of the package job - # expect(HTTPoisonMock, :get, fn url, headers -> - # assert url == "#{System.get_env("SUPERSTREAMER_URL")}/jobs/package-job-id" - # {:ok, %HTTPoison.Response{ - # status_code: 200, - # body: ~s({"state": "completed", "outputData": {"assetId": "asset-id"}}) - # }} - # end) - - - # # Mock the Repo.update!/1 call - # expect(RepoMock, :update!, fn changeset -> - # assert changeset.changes.playlist_url == "#{System.get_env("PUBLIC_S3_ENDPOINT")}/package/asset-id/hls/master.m3u8" - # {:ok, changeset} - # end) - - # # Call the worker's perform function - # job_args = %{"vod_id" => 1, "input_url" => "https://example.com/input.mp4"} - # assert :ok = CreateHlsPlaylist.perform(%Oban.Job{args: job_args}) - # end - - # test "handles errors gracefully" do - # # Mock the VOD to be returned by Repo.get!/2 - # vod = %Vod{id: 1, playlist_url: nil} - # expect(RepoMock, :get!, fn Vod, 1 -> vod end) - - # # Mock the start_transcode function to return an error - # expect(HTTPoisonMock, :post, fn _url, _body, _headers -> - # {:error, %HTTPoison.Error{reason: "transcoding failed"}} - # end) - - # # Call the worker's perform function - # job_args = %{"vod_id" => 1, "input_url" => "https://example.com/input.mp4"} - # assert {:error, _reason} = CreateHlsPlaylist.perform(%Oban.Job{args: job_args}) - # end - end end diff --git a/services/bright/test/bright/oban_workers/create_s3_asset_test.exs b/services/bright/test/bright/oban_workers/create_s3_asset_test.exs index 9db8e08..945145b 100644 --- a/services/bright/test/bright/oban_workers/create_s3_asset_test.exs +++ b/services/bright/test/bright/oban_workers/create_s3_asset_test.exs @@ -1,31 +1,67 @@ defmodule Bright.ObanWorkers.CreateS3AssetTest do use Bright.DataCase use Oban.Testing, repo: Bright.Repo - alias Bright.ObanWorkers.CreateS3Asset + alias Bright.ObanWorkers.{ + CreateS3Asset, + ProcessVod, + CreateThumbnail + } + alias Bright.Cache + alias Bright.Streams + alias Bright.Streams.Stream - @tag :unit - test "creating a new s3 asset (unit test)" do - - url = "https://example.com/video.ts" - key = "video.ts" - {:ok, asset} = perform_job(CreateS3Asset, %{url: url, key: key}) - end - - @tag :acceptance - test "creating a new s3 asset (acceptance test)" do + # @tag :unit + # test "creating a new s3 asset (unit test)" do - url = "http://38.242.193.246:8081/fixtures/2024-12-19T03-10-30Z.ts" - key = unique_filename + # example_video = "http://example.com/video.ts" + # stream_attrs = %{date: ~U[2024-12-28 03:31:00Z], title: "some title", notes: "some notes"} + # {:ok, %Stream{} = stream} = Streams.create_stream(stream_attrs) + # {:ok, vod} = Streams.create_vod(%{stream_id: stream.id, origin_temp_input_url: example_video}) + # assert :ok + # {:ok, asset} = perform_job(CreateS3Asset, %{input_url: example_video, vod_id: vod.id}) + # assert :ok + # end + + + @tag :integration + test "sheduling upon vod creation" do example_video = "http://example.com/video.ts" stream_attrs = %{date: ~U[2024-12-28 03:31:00Z], title: "some title", notes: "some notes"} {:ok, %Stream{} = stream} = Streams.create_stream(stream_attrs) {:ok, _vod} = Streams.create_vod(%{stream_id: stream.id, origin_temp_input_url: example_video}) - - - perform_job(CreateS3Asset, %{url: url, key: key}) - {:ok, asset} = Oban.drain_queue(queue: :default) - + assert_enqueued worker: ProcessVod, queue: :default + Oban.drain_queue(queue: :default) # ProcessVod is what queues CreateS3Asset so we need to make it run + assert_enqueued worker: CreateS3Asset, queue: :default end + + + @tag :integration + test "not scheduled when origin_temp_input_url is missing" do + + stream_attrs = %{date: ~U[2024-12-28 03:31:00Z], title: "some title", notes: "some notes"} + {:ok, %Stream{} = stream} = Streams.create_stream(stream_attrs) + {:ok, _vod} = Streams.create_vod(%{stream_id: stream.id}) + + refute_enqueued worker: CreateS3Asset + end + + # @tag :acceptance + # test "creating a new s3 asset (acceptance test)" do + + + # url = "http://38.242.193.246:8081/fixtures/2024-12-19T03-10-30Z.ts" + # key = Cache.generate_filename(url) + + # example_video = "http://example.com/video.ts" + # stream_attrs = %{date: ~U[2024-12-28 03:31:00Z], title: "some title", notes: "some notes"} + # {:ok, %Stream{} = stream} = Streams.create_stream(stream_attrs) + # {:ok, vod} = Streams.create_vod(%{stream_id: stream.id, origin_temp_input_url: example_video}) + + + # perform_job(CreateS3Asset, %{input_url: example_video, vod_id: vod.id}) + # {:ok, asset} = Oban.drain_queue(queue: :default) + + # end end diff --git a/services/bright/test/bright/oban_workers/create_thumbnail_test.exs b/services/bright/test/bright/oban_workers/create_thumbnail_test.exs index 8901797..31de3c0 100644 --- a/services/bright/test/bright/oban_workers/create_thumbnail_test.exs +++ b/services/bright/test/bright/oban_workers/create_thumbnail_test.exs @@ -4,10 +4,28 @@ defmodule Bright.ObanWorkers.CreateThumbnailTest do alias Bright.ObanWorkers.CreateThumbnail alias Bright.ObanWorkers.ProcessVod alias Bright.Streams - alias Bright.Streams.Stream + alias Bright.Streams.{ + Stream, + Vod + } + + describe "CreateThumbnail" do + import Bright.StreamsFixtures + @example_url "https://futureporn-b2.b-cdn.net/big_buck_bunny_720p_1mb.mp4" + + @tag :integration + test "thumbnail creation" do + stream = stream_fixture() + vod = vod_fixture(%{thumbnail_url: nil, stream_id: stream.id, origin_temp_input_url: @example_url}) + {:ok, %Vod{thumbnail_url: thumbnail_url}} = perform_job(Bright.ObanWorkers.CreateThumbnail, %{vod_id: vod.id}) + assert Regex.match?(~r/^https:\/\/.*\.png$/, thumbnail_url) + end + + + @tag :integration test "sheduling upon vod creation" do @@ -35,5 +53,7 @@ defmodule Bright.ObanWorkers.CreateThumbnailTest do refute_enqueued worker: CreateThumbnail end + + end end diff --git a/services/bright/test/bright/oban_workers/process_vod_test.exs b/services/bright/test/bright/oban_workers/process_vod_test.exs new file mode 100644 index 0000000..cd07b94 --- /dev/null +++ b/services/bright/test/bright/oban_workers/process_vod_test.exs @@ -0,0 +1,63 @@ +defmodule Bright.ObanWorkers.ProcessVodTest do + use Bright.DataCase + use Oban.Testing, repo: Bright.Repo + alias Bright.ObanWorkers.{ + CreateThumbnail, + ProcessVod, + CreateS3Asset, + CreateHlsPlaylist + } + alias Bright.Streams + alias Bright.Streams.{Stream,Vod} + + @example_url "https://example.com/my-video.mp4" + + describe "ProcessVod" do + + import Bright.StreamsFixtures + + @tag :unit + test "processing a new vod" do + stream = stream_fixture() + vod = vod_fixture(%{thumbnail_url: nil, stream_id: stream.id, origin_temp_input_url: @example_url}) + :ok = perform_job(Bright.ObanWorkers.ProcessVod, %{vod_id: vod.id}) + assert :ok + end + + @tag :integration + test "schedule ProcessVod when a new vod is created" do + stream = stream_fixture() + vod_fixture(%{thumbnail_url: nil, stream_id: stream.id, origin_temp_input_url: @example_url}) + assert_enqueued worker: ProcessVod, queue: :default + end + + @tag :integration + test "schedule CreateThumbnail when thumbnail_url is nil" do + stream = stream_fixture() + vod_fixture(%{thumbnail_url: nil, stream_id: stream.id, origin_temp_input_url: @example_url}) + assert_enqueued worker: ProcessVod, queue: :default + assert %{success: 1} = Oban.drain_queue(queue: :default, with_safety: false) # ProcessVod is what queues CreateThumbnail so we need to make it run + assert_enqueued worker: CreateThumbnail, queue: :default + end + + @tag :integration + test "schedule CreateS3Asset when s3_cdn_url is nil" do + stream = stream_fixture() + vod_fixture(%{s3_cdn_url: nil, stream_id: stream.id, origin_temp_input_url: @example_url}) + assert_enqueued worker: ProcessVod, queue: :default + assert %{success: 1} = Oban.drain_queue(queue: :default, with_safety: false) # ProcessVod is what queues CreateThumbnail so we need to make it run + assert_enqueued worker: CreateS3Asset, queue: :default + end + + @tag :integration + test "schedule CreateHlsPlaylist when playlist_url is nil" do + stream = stream_fixture() + vod_fixture(%{playlist_url: nil, stream_id: stream.id, origin_temp_input_url: @example_url}) + + assert_enqueued worker: ProcessVod, queue: :default + assert %{success: 1} = Oban.drain_queue(queue: :default, with_safety: false) # ProcessVod is what queues CreateThumbnail so we need to make it run + assert_enqueued worker: CreateHlsPlaylist, queue: :default + end + + end +end diff --git a/services/bright/test/bright/orders_test.exs b/services/bright/test/bright/orders_test.exs deleted file mode 100644 index 9ada911..0000000 --- a/services/bright/test/bright/orders_test.exs +++ /dev/null @@ -1,117 +0,0 @@ -defmodule Bright.OrdersTest do - use Bright.DataCase - - alias Bright.Orders - - describe "orders" do - alias Bright.Orders.Order - - import Bright.OrdersFixtures - - @invalid_attrs %{user_uuid: nil, total_price: nil} - - test "list_orders/0 returns all orders" do - order = order_fixture() - assert Orders.list_orders() == [order] - end - - test "get_order!/1 returns the order with given id" do - order = order_fixture() - assert Orders.get_order!(order.id) == order - end - - test "create_order/1 with valid data creates a order" do - valid_attrs = %{user_uuid: "7488a646-e31f-11e4-aace-600308960662", total_price: "120.5"} - - assert {:ok, %Order{} = order} = Orders.create_order(valid_attrs) - assert order.user_uuid == "7488a646-e31f-11e4-aace-600308960662" - assert order.total_price == Decimal.new("120.5") - end - - test "create_order/1 with invalid data returns error changeset" do - assert {:error, %Ecto.Changeset{}} = Orders.create_order(@invalid_attrs) - end - - test "update_order/2 with valid data updates the order" do - order = order_fixture() - update_attrs = %{user_uuid: "7488a646-e31f-11e4-aace-600308960668", total_price: "456.7"} - - assert {:ok, %Order{} = order} = Orders.update_order(order, update_attrs) - assert order.user_uuid == "7488a646-e31f-11e4-aace-600308960668" - assert order.total_price == Decimal.new("456.7") - end - - test "update_order/2 with invalid data returns error changeset" do - order = order_fixture() - assert {:error, %Ecto.Changeset{}} = Orders.update_order(order, @invalid_attrs) - assert order == Orders.get_order!(order.id) - end - - test "delete_order/1 deletes the order" do - order = order_fixture() - assert {:ok, %Order{}} = Orders.delete_order(order) - assert_raise Ecto.NoResultsError, fn -> Orders.get_order!(order.id) end - end - - test "change_order/1 returns a order changeset" do - order = order_fixture() - assert %Ecto.Changeset{} = Orders.change_order(order) - end - end - - describe "order_line_items" do - alias Bright.Orders.LineItem - - import Bright.OrdersFixtures - - @invalid_attrs %{price: nil, quantity: nil} - - test "list_order_line_items/0 returns all order_line_items" do - line_item = line_item_fixture() - assert Orders.list_order_line_items() == [line_item] - end - - test "get_line_item!/1 returns the line_item with given id" do - line_item = line_item_fixture() - assert Orders.get_line_item!(line_item.id) == line_item - end - - test "create_line_item/1 with valid data creates a line_item" do - valid_attrs = %{price: "120.5", quantity: 42} - - assert {:ok, %LineItem{} = line_item} = Orders.create_line_item(valid_attrs) - assert line_item.price == Decimal.new("120.5") - assert line_item.quantity == 42 - end - - test "create_line_item/1 with invalid data returns error changeset" do - assert {:error, %Ecto.Changeset{}} = Orders.create_line_item(@invalid_attrs) - end - - test "update_line_item/2 with valid data updates the line_item" do - line_item = line_item_fixture() - update_attrs = %{price: "456.7", quantity: 43} - - assert {:ok, %LineItem{} = line_item} = Orders.update_line_item(line_item, update_attrs) - assert line_item.price == Decimal.new("456.7") - assert line_item.quantity == 43 - end - - test "update_line_item/2 with invalid data returns error changeset" do - line_item = line_item_fixture() - assert {:error, %Ecto.Changeset{}} = Orders.update_line_item(line_item, @invalid_attrs) - assert line_item == Orders.get_line_item!(line_item.id) - end - - test "delete_line_item/1 deletes the line_item" do - line_item = line_item_fixture() - assert {:ok, %LineItem{}} = Orders.delete_line_item(line_item) - assert_raise Ecto.NoResultsError, fn -> Orders.get_line_item!(line_item.id) end - end - - test "change_line_item/1 returns a line_item changeset" do - line_item = line_item_fixture() - assert %Ecto.Changeset{} = Orders.change_line_item(line_item) - end - end -end diff --git a/services/bright/test/bright/platforms_test.exs b/services/bright/test/bright/platforms_test.exs index a6fc77f..3db4a16 100644 --- a/services/bright/test/bright/platforms_test.exs +++ b/services/bright/test/bright/platforms_test.exs @@ -21,11 +21,11 @@ defmodule Bright.PlatformsTest do end test "create_platform/1 with valid data creates a platform" do - valid_attrs = %{name: "some name", url: true, icon: ""} + valid_attrs = %{name: "some name", url: "some url", icon: ""} assert {:ok, %Platform{} = platform} = Platforms.create_platform(valid_attrs) assert platform.name == "some name" - assert platform.url == true + assert platform.url == "some url" assert platform.icon == "" end @@ -35,11 +35,11 @@ defmodule Bright.PlatformsTest do test "update_platform/2 with valid data updates the platform" do platform = platform_fixture() - update_attrs = %{name: "some updated name", url: false, icon: "blah"} + update_attrs = %{name: "some updated name", url: "https://example.com", icon: "blah"} assert {:ok, %Platform{} = platform} = Platforms.update_platform(platform, update_attrs) assert platform.name == "some updated name" - assert platform.url == false + assert platform.url == "https://example.com" assert platform.icon == "blah" end diff --git a/services/bright/test/bright/shopping_cart_test.exs b/services/bright/test/bright/shopping_cart_test.exs deleted file mode 100644 index d333c17..0000000 --- a/services/bright/test/bright/shopping_cart_test.exs +++ /dev/null @@ -1,115 +0,0 @@ -defmodule Bright.ShoppingCartTest do - use Bright.DataCase - - alias Bright.ShoppingCart - - describe "carts" do - alias Bright.ShoppingCart.Cart - - import Bright.ShoppingCartFixtures - - @invalid_attrs %{user_uuid: nil} - - test "list_carts/0 returns all carts" do - cart = cart_fixture() - assert ShoppingCart.list_carts() == [cart] - end - - test "get_cart!/1 returns the cart with given id" do - cart = cart_fixture() - assert ShoppingCart.get_cart!(cart.id) == cart - end - - test "create_cart/1 with valid data creates a cart" do - valid_attrs = %{user_uuid: "7488a646-e31f-11e4-aace-600308960662"} - - assert {:ok, %Cart{} = cart} = ShoppingCart.create_cart(valid_attrs) - assert cart.user_uuid == "7488a646-e31f-11e4-aace-600308960662" - end - - test "create_cart/1 with invalid data returns error changeset" do - assert {:error, %Ecto.Changeset{}} = ShoppingCart.create_cart(@invalid_attrs) - end - - test "update_cart/2 with valid data updates the cart" do - cart = cart_fixture() - update_attrs = %{user_uuid: "7488a646-e31f-11e4-aace-600308960668"} - - assert {:ok, %Cart{} = cart} = ShoppingCart.update_cart(cart, update_attrs) - assert cart.user_uuid == "7488a646-e31f-11e4-aace-600308960668" - end - - test "update_cart/2 with invalid data returns error changeset" do - cart = cart_fixture() - assert {:error, %Ecto.Changeset{}} = ShoppingCart.update_cart(cart, @invalid_attrs) - assert cart == ShoppingCart.get_cart!(cart.id) - end - - test "delete_cart/1 deletes the cart" do - cart = cart_fixture() - assert {:ok, %Cart{}} = ShoppingCart.delete_cart(cart) - assert_raise Ecto.NoResultsError, fn -> ShoppingCart.get_cart!(cart.id) end - end - - test "change_cart/1 returns a cart changeset" do - cart = cart_fixture() - assert %Ecto.Changeset{} = ShoppingCart.change_cart(cart) - end - end - - describe "cart_items" do - alias Bright.ShoppingCart.CartItem - - import Bright.ShoppingCartFixtures - - @invalid_attrs %{price_when_carted: nil, quantity: nil} - - test "list_cart_items/0 returns all cart_items" do - cart_item = cart_item_fixture() - assert ShoppingCart.list_cart_items() == [cart_item] - end - - test "get_cart_item!/1 returns the cart_item with given id" do - cart_item = cart_item_fixture() - assert ShoppingCart.get_cart_item!(cart_item.id) == cart_item - end - - test "create_cart_item/1 with valid data creates a cart_item" do - valid_attrs = %{price_when_carted: "120.5", quantity: 42} - - assert {:ok, %CartItem{} = cart_item} = ShoppingCart.create_cart_item(valid_attrs) - assert cart_item.price_when_carted == Decimal.new("120.5") - assert cart_item.quantity == 42 - end - - test "create_cart_item/1 with invalid data returns error changeset" do - assert {:error, %Ecto.Changeset{}} = ShoppingCart.create_cart_item(@invalid_attrs) - end - - test "update_cart_item/2 with valid data updates the cart_item" do - cart_item = cart_item_fixture() - update_attrs = %{price_when_carted: "456.7", quantity: 43} - - assert {:ok, %CartItem{} = cart_item} = ShoppingCart.update_cart_item(cart_item, update_attrs) - assert cart_item.price_when_carted == Decimal.new("456.7") - assert cart_item.quantity == 43 - end - - test "update_cart_item/2 with invalid data returns error changeset" do - cart_item = cart_item_fixture() - assert {:error, %Ecto.Changeset{}} = ShoppingCart.update_cart_item(cart_item, @invalid_attrs) - assert cart_item == ShoppingCart.get_cart_item!(cart_item.id) - end - - test "delete_cart_item/1 deletes the cart_item" do - cart_item = cart_item_fixture() - assert {:ok, %CartItem{}} = ShoppingCart.delete_cart_item(cart_item) - assert_raise Ecto.NoResultsError, fn -> ShoppingCart.get_cart_item!(cart_item.id) end - end - - test "change_cart_item/1 returns a cart_item changeset" do - cart_item = cart_item_fixture() - assert %Ecto.Changeset{} = ShoppingCart.change_cart_item(cart_item) - end - end -end diff --git a/services/bright/test/bright/streams_test.exs b/services/bright/test/bright/streams_test.exs index bd8795d..7849dcc 100644 --- a/services/bright/test/bright/streams_test.exs +++ b/services/bright/test/bright/streams_test.exs @@ -66,20 +66,23 @@ defmodule Bright.StreamsTest do import Bright.StreamsFixtures - @invalid_attrs %{s3_cdn_url: nil, s3_upload_id: nil, s3_key: nil, s3_bucket: nil, mux_asset_id: nil, mux_playback_id: nil, ipfs_cid: nil, torrent: nil} + @invalid_attrs %{stream_id: nil, s3_cdn_url: nil, s3_upload_id: nil, s3_key: nil, s3_bucket: nil, mux_asset_id: nil, mux_playback_id: nil, ipfs_cid: nil, torrent: nil} test "list_vods/0 returns all vods" do - vod = vod_fixture() + stream = stream_fixture() + vod = vod_fixture(%{stream_id: stream.id}) assert Streams.list_vods() == [vod] end test "get_vod!/1 returns the vod with given id" do - vod = vod_fixture() + stream = stream_fixture() + vod = vod_fixture(%{stream_id: stream.id}) assert Streams.get_vod!(vod.id) == vod end test "create_vod/1 with valid data creates a vod" do - valid_attrs = %{s3_cdn_url: "some s3_cdn_url", s3_upload_id: "some s3_upload_id", s3_key: "some s3_key", s3_bucket: "some s3_bucket", mux_asset_id: "some mux_asset_id", mux_playback_id: "some mux_playback_id", ipfs_cid: "some ipfs_cid", torrent: "some torrent"} + stream = stream_fixture() + valid_attrs = %{stream_id: stream.id, s3_cdn_url: "some s3_cdn_url", s3_upload_id: "some s3_upload_id", s3_key: "some s3_key", s3_bucket: "some s3_bucket", mux_asset_id: "some mux_asset_id", mux_playback_id: "some mux_playback_id", ipfs_cid: "some ipfs_cid", torrent: "some torrent"} assert {:ok, %Vod{} = vod} = Streams.create_vod(valid_attrs) assert vod.s3_cdn_url == "some s3_cdn_url" @@ -97,7 +100,8 @@ defmodule Bright.StreamsTest do end test "update_vod/2 with valid data updates the vod" do - vod = vod_fixture() + stream = stream_fixture() + vod = vod_fixture(%{stream_id: stream.id}) update_attrs = %{s3_cdn_url: "some updated s3_cdn_url", s3_upload_id: "some updated s3_upload_id", s3_key: "some updated s3_key", s3_bucket: "some updated s3_bucket", mux_asset_id: "some updated mux_asset_id", mux_playback_id: "some updated mux_playback_id", ipfs_cid: "some updated ipfs_cid", torrent: "some updated torrent"} assert {:ok, %Vod{} = vod} = Streams.update_vod(vod, update_attrs) @@ -112,19 +116,22 @@ defmodule Bright.StreamsTest do end test "update_vod/2 with invalid data returns error changeset" do - vod = vod_fixture() + stream = stream_fixture() + vod = vod_fixture(%{stream_id: stream.id}) assert {:error, %Ecto.Changeset{}} = Streams.update_vod(vod, @invalid_attrs) assert vod == Streams.get_vod!(vod.id) end test "delete_vod/1 deletes the vod" do - vod = vod_fixture() + stream = stream_fixture() + vod = vod_fixture(%{stream_id: stream.id}) assert {:ok, %Vod{}} = Streams.delete_vod(vod) assert_raise Ecto.NoResultsError, fn -> Streams.get_vod!(vod.id) end end test "change_vod/1 returns a vod changeset" do - vod = vod_fixture() + stream = stream_fixture() + vod = vod_fixture(%{stream_id: stream.id}) assert %Ecto.Changeset{} = Streams.change_vod(vod) end end diff --git a/services/bright/test/bright/tags_test.exs b/services/bright/test/bright/tags_test.exs index efff959..051c743 100644 --- a/services/bright/test/bright/tags_test.exs +++ b/services/bright/test/bright/tags_test.exs @@ -12,7 +12,7 @@ defmodule Bright.TagsTest do test "list_tag/0 returns all tag" do tag = tag_fixture() - assert Tags.list_tag() == [tag] + assert Tags.list_tags() == [tag] end test "get_tag!/1 returns the tag with given id" do diff --git a/services/bright/test/support/fixtures/catalog_fixtures.ex b/services/bright/test/support/fixtures/catalog_fixtures.ex deleted file mode 100644 index 853f34d..0000000 --- a/services/bright/test/support/fixtures/catalog_fixtures.ex +++ /dev/null @@ -1,42 +0,0 @@ -defmodule Bright.CatalogFixtures do - @moduledoc """ - This module defines test helpers for creating - entities via the `Bright.Catalog` context. - """ - - @doc """ - Generate a product. - """ - def product_fixture(attrs \\ %{}) do - {:ok, product} = - attrs - |> Enum.into(%{ - description: "some description", - price: "120.5", - title: "some title", - views: 42 - }) - |> Bright.Catalog.create_product() - - product - end - - @doc """ - Generate a unique category title. - """ - def unique_category_title, do: "some title#{System.unique_integer([:positive])}" - - @doc """ - Generate a category. - """ - def category_fixture(attrs \\ %{}) do - {:ok, category} = - attrs - |> Enum.into(%{ - title: unique_category_title() - }) - |> Bright.Catalog.create_category() - - category - end -end diff --git a/services/bright/test/support/fixtures/orders_fixtures.ex b/services/bright/test/support/fixtures/orders_fixtures.ex deleted file mode 100644 index 77c6a0c..0000000 --- a/services/bright/test/support/fixtures/orders_fixtures.ex +++ /dev/null @@ -1,36 +0,0 @@ -defmodule Bright.OrdersFixtures do - @moduledoc """ - This module defines test helpers for creating - entities via the `Bright.Orders` context. - """ - - @doc """ - Generate a order. - """ - def order_fixture(attrs \\ %{}) do - {:ok, order} = - attrs - |> Enum.into(%{ - total_price: "120.5", - user_uuid: "7488a646-e31f-11e4-aace-600308960662" - }) - |> Bright.Orders.create_order() - - order - end - - @doc """ - Generate a line_item. - """ - def line_item_fixture(attrs \\ %{}) do - {:ok, line_item} = - attrs - |> Enum.into(%{ - price: "120.5", - quantity: 42 - }) - |> Bright.Orders.create_line_item() - - line_item - end -end diff --git a/services/bright/test/support/fixtures/shopping_cart_fixtures.ex b/services/bright/test/support/fixtures/shopping_cart_fixtures.ex deleted file mode 100644 index a5e57ff..0000000 --- a/services/bright/test/support/fixtures/shopping_cart_fixtures.ex +++ /dev/null @@ -1,42 +0,0 @@ -defmodule Bright.ShoppingCartFixtures do - @moduledoc """ - This module defines test helpers for creating - entities via the `Bright.ShoppingCart` context. - """ - - @doc """ - Generate a unique cart user_uuid. - """ - def unique_cart_user_uuid do - raise "implement the logic to generate a unique cart user_uuid" - end - - @doc """ - Generate a cart. - """ - def cart_fixture(attrs \\ %{}) do - {:ok, cart} = - attrs - |> Enum.into(%{ - user_uuid: unique_cart_user_uuid() - }) - |> Bright.ShoppingCart.create_cart() - - cart - end - - @doc """ - Generate a cart_item. - """ - def cart_item_fixture(attrs \\ %{}) do - {:ok, cart_item} = - attrs - |> Enum.into(%{ - price_when_carted: "120.5", - quantity: 42 - }) - |> Bright.ShoppingCart.create_cart_item() - - cart_item - end -end diff --git a/services/bright/test/support/fixtures/streams_fixtures.ex b/services/bright/test/support/fixtures/streams_fixtures.ex index d3775a3..5e53dc2 100644 --- a/services/bright/test/support/fixtures/streams_fixtures.ex +++ b/services/bright/test/support/fixtures/streams_fixtures.ex @@ -34,10 +34,14 @@ defmodule Bright.StreamsFixtures do s3_cdn_url: "some s3_cdn_url", s3_key: "some s3_key", s3_upload_id: "some s3_upload_id", - torrent: "some torrent" + torrent: "some torrent", + playlist_url: "some playlist_url", + thumbnail_url: "some thumbnail_url" }) |> Bright.Streams.create_vod() - vod end + + + end