Added tests
This commit is contained in:
parent
fa095cfa8f
commit
c21f2c6b93
5 changed files with 145 additions and 17 deletions
|
|
@ -51,7 +51,6 @@ defmodule Pinchflat.FastIndexing.FastIndexingHelpers do
|
||||||
# If possible, use the YouTube API to fetch media IDs. If that fails, fall back to the RSS feed.
|
# If possible, use the YouTube API to fetch media IDs. If that fails, fall back to the RSS feed.
|
||||||
# If the YouTube API isn't set up, just use the RSS feed.
|
# If the YouTube API isn't set up, just use the RSS feed.
|
||||||
defp get_recent_media_ids(source) do
|
defp get_recent_media_ids(source) do
|
||||||
# TODO: test
|
|
||||||
with true <- YoutubeApi.enabled?(),
|
with true <- YoutubeApi.enabled?(),
|
||||||
{:ok, media_ids} <- YoutubeApi.get_recent_media_ids(source) do
|
{:ok, media_ids} <- YoutubeApi.get_recent_media_ids(source) do
|
||||||
{:ok, media_ids}
|
{:ok, media_ids}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ defmodule Pinchflat.FastIndexing.YoutubeApi do
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
|
alias Pinchflat.Settings
|
||||||
alias Pinchflat.Sources.Source
|
alias Pinchflat.Sources.Source
|
||||||
alias Pinchflat.Utils.FunctionUtils
|
alias Pinchflat.Utils.FunctionUtils
|
||||||
alias Pinchflat.FastIndexing.YoutubeBehaviour
|
alias Pinchflat.FastIndexing.YoutubeBehaviour
|
||||||
|
|
@ -12,16 +13,14 @@ defmodule Pinchflat.FastIndexing.YoutubeApi do
|
||||||
@behaviour YoutubeBehaviour
|
@behaviour YoutubeBehaviour
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Determines if the YouTube API is enabled for fast indexing
|
Determines if the YouTube API is enabled for fast indexing by checking
|
||||||
|
if the user has an API key set
|
||||||
|
|
||||||
Returns boolean()
|
Returns boolean()
|
||||||
"""
|
"""
|
||||||
# TODO: test
|
|
||||||
# TODO: update this to use a user setting
|
|
||||||
@impl YoutubeBehaviour
|
@impl YoutubeBehaviour
|
||||||
def enabled?(), do: true
|
def enabled?(), do: is_binary(api_key())
|
||||||
|
|
||||||
# TODO: test
|
|
||||||
@doc """
|
@doc """
|
||||||
Fetches the recent media IDs from the YouTube API for a given source.
|
Fetches the recent media IDs from the YouTube API for a given source.
|
||||||
|
|
||||||
|
|
@ -75,9 +74,8 @@ defmodule Pinchflat.FastIndexing.YoutubeApi do
|
||||||
|> FunctionUtils.wrap_ok()
|
|> FunctionUtils.wrap_ok()
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO: replace this with a user setting
|
|
||||||
defp api_key do
|
defp api_key do
|
||||||
System.get_env("YOUTUBE_API_KEY")
|
Settings.get!(:youtube_api_key)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp http_client do
|
defp http_client do
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,7 @@ defmodule Pinchflat.Sources.Source do
|
||||||
@doc false
|
@doc false
|
||||||
def fast_index_frequency do
|
def fast_index_frequency do
|
||||||
# minutes
|
# minutes
|
||||||
15
|
10
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc false
|
@doc false
|
||||||
|
|
|
||||||
|
|
@ -6,19 +6,20 @@ defmodule Pinchflat.FastIndexing.FastIndexingHelpersTest do
|
||||||
import Pinchflat.ProfilesFixtures
|
import Pinchflat.ProfilesFixtures
|
||||||
|
|
||||||
alias Pinchflat.Tasks
|
alias Pinchflat.Tasks
|
||||||
|
alias Pinchflat.Settings
|
||||||
alias Pinchflat.Media.MediaItem
|
alias Pinchflat.Media.MediaItem
|
||||||
alias Pinchflat.Downloading.MediaDownloadWorker
|
alias Pinchflat.Downloading.MediaDownloadWorker
|
||||||
alias Pinchflat.FastIndexing.FastIndexingHelpers
|
alias Pinchflat.FastIndexing.FastIndexingHelpers
|
||||||
|
|
||||||
|
setup do
|
||||||
|
stub(YtDlpRunnerMock, :run, fn _url, _opts, _ot ->
|
||||||
|
{:ok, media_attributes_return_fixture()}
|
||||||
|
end)
|
||||||
|
|
||||||
|
{:ok, [source: source_fixture()]}
|
||||||
|
end
|
||||||
|
|
||||||
describe "kickoff_download_tasks_from_youtube_rss_feed/1" do
|
describe "kickoff_download_tasks_from_youtube_rss_feed/1" do
|
||||||
setup do
|
|
||||||
stub(YtDlpRunnerMock, :run, fn _url, _opts, _ot ->
|
|
||||||
{:ok, media_attributes_return_fixture()}
|
|
||||||
end)
|
|
||||||
|
|
||||||
{:ok, [source: source_fixture()]}
|
|
||||||
end
|
|
||||||
|
|
||||||
test "enqueues a new worker for each new media_id in the source's RSS feed", %{source: source} do
|
test "enqueues a new worker for each new media_id in the source's RSS feed", %{source: source} do
|
||||||
expect(HTTPClientMock, :get, fn _url -> {:ok, "<yt:videoId>test_1</yt:videoId>"} end)
|
expect(HTTPClientMock, :get, fn _url -> {:ok, "<yt:videoId>test_1</yt:videoId>"} end)
|
||||||
|
|
||||||
|
|
@ -107,4 +108,49 @@ defmodule Pinchflat.FastIndexing.FastIndexingHelpersTest do
|
||||||
assert [] = FastIndexingHelpers.kickoff_download_tasks_from_youtube_rss_feed(source)
|
assert [] = FastIndexingHelpers.kickoff_download_tasks_from_youtube_rss_feed(source)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "kickoff_download_tasks_from_youtube_rss_feed/1 when testing backends" do
|
||||||
|
test "uses the YouTube API if it is enabled", %{source: source} do
|
||||||
|
expect(HTTPClientMock, :get, fn url, _headers ->
|
||||||
|
assert url =~ "https://youtube.googleapis.com/youtube/v3/playlistItems"
|
||||||
|
|
||||||
|
{:ok, "{}"}
|
||||||
|
end)
|
||||||
|
|
||||||
|
Settings.set(youtube_api_key: "test_key")
|
||||||
|
|
||||||
|
assert [] = FastIndexingHelpers.kickoff_download_tasks_from_youtube_rss_feed(source)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "the YouTube API creates records as expected", %{source: source} do
|
||||||
|
expect(HTTPClientMock, :get, fn _url, _headers ->
|
||||||
|
{:ok, ~s({ "items": [ {"contentDetails": {"videoId": "test_1"}} ] })}
|
||||||
|
end)
|
||||||
|
|
||||||
|
Settings.set(youtube_api_key: "test_key")
|
||||||
|
|
||||||
|
assert [%MediaItem{}] = FastIndexingHelpers.kickoff_download_tasks_from_youtube_rss_feed(source)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "RSS is used as a backup if the API fails", %{source: source} do
|
||||||
|
expect(HTTPClientMock, :get, fn _url, _headers -> {:error, ""} end)
|
||||||
|
expect(HTTPClientMock, :get, fn _url -> {:ok, "<yt:videoId>test_1</yt:videoId>"} end)
|
||||||
|
|
||||||
|
Settings.set(youtube_api_key: "test_key")
|
||||||
|
|
||||||
|
assert [%MediaItem{}] = FastIndexingHelpers.kickoff_download_tasks_from_youtube_rss_feed(source)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "RSS is used if the API is not enabled", %{source: source} do
|
||||||
|
expect(HTTPClientMock, :get, fn url ->
|
||||||
|
assert url =~ "https://www.youtube.com/feeds/videos.xml"
|
||||||
|
|
||||||
|
{:ok, "<yt:videoId>test_1</yt:videoId>"}
|
||||||
|
end)
|
||||||
|
|
||||||
|
Settings.set(youtube_api_key: nil)
|
||||||
|
|
||||||
|
assert [%MediaItem{}] = FastIndexingHelpers.kickoff_download_tasks_from_youtube_rss_feed(source)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
85
test/pinchflat/fast_indexing/youtube_api_test.exs
Normal file
85
test/pinchflat/fast_indexing/youtube_api_test.exs
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
defmodule Pinchflat.FastIndexing.YoutubeApiTest do
|
||||||
|
use Pinchflat.DataCase
|
||||||
|
|
||||||
|
import Pinchflat.SourcesFixtures
|
||||||
|
|
||||||
|
alias Pinchflat.Settings
|
||||||
|
alias Pinchflat.FastIndexing.YoutubeApi
|
||||||
|
|
||||||
|
describe "enabled?/0" do
|
||||||
|
test "returns true if the user has set a YouTube API key" do
|
||||||
|
Settings.set(youtube_api_key: "test_key")
|
||||||
|
|
||||||
|
assert YoutubeApi.enabled?()
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns false if the user has not set an API key" do
|
||||||
|
Settings.set(youtube_api_key: nil)
|
||||||
|
|
||||||
|
refute YoutubeApi.enabled?()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "get_recent_media_ids/1" do
|
||||||
|
setup do
|
||||||
|
source = source_fixture()
|
||||||
|
Settings.set(youtube_api_key: "test_key")
|
||||||
|
|
||||||
|
{:ok, source: source}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "calls the expected URL", %{source: source} do
|
||||||
|
expect(HTTPClientMock, :get, fn url, headers ->
|
||||||
|
api_base = "https://youtube.googleapis.com/youtube/v3/playlistItems"
|
||||||
|
request_url = "#{api_base}?part=contentDetails&maxResults=50&playlistId=#{source.collection_id}&key=test_key"
|
||||||
|
|
||||||
|
assert url == request_url
|
||||||
|
assert headers == [accept: "application/json"]
|
||||||
|
|
||||||
|
{:ok, "{}"}
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert {:ok, _} = YoutubeApi.get_recent_media_ids(source)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "replaces channel IDs with playlist IDs if needed" do
|
||||||
|
source = source_fixture(collection_id: "UC_ABC123")
|
||||||
|
|
||||||
|
expect(HTTPClientMock, :get, fn url, _headers ->
|
||||||
|
assert url =~ "playlistId=UU_ABC123&"
|
||||||
|
|
||||||
|
{:ok, "{}"}
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert {:ok, _} = YoutubeApi.get_recent_media_ids(source)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns an empty list if no media is returned", %{source: source} do
|
||||||
|
expect(HTTPClientMock, :get, fn _url, _headers -> {:ok, "{}"} end)
|
||||||
|
|
||||||
|
assert {:ok, []} = YoutubeApi.get_recent_media_ids(source)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns media IDs if present", %{source: source} do
|
||||||
|
expect(HTTPClientMock, :get, fn _url, _headers ->
|
||||||
|
{:ok,
|
||||||
|
"""
|
||||||
|
{
|
||||||
|
"items": [
|
||||||
|
{"contentDetails": {"videoId": "test_1"}},
|
||||||
|
{"contentDetails": {"videoId": "test_2"}}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"""}
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert {:ok, ["test_1", "test_2"]} = YoutubeApi.get_recent_media_ids(source)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns an error if the HTTP request fails", %{source: source} do
|
||||||
|
expect(HTTPClientMock, :get, fn _url, _headers -> {:error, "error"} end)
|
||||||
|
|
||||||
|
assert {:error, "error"} = YoutubeApi.get_recent_media_ids(source)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Reference in a new issue