From a85b2adfa976db60852e0bbc825c08db02210c43 Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Sun, 24 Mar 2024 17:13:51 -0400 Subject: [PATCH] tests: parametrize tests using theories (#272) --- .../FixtureJellyfinServer.cs | 113 ++-- .../TestThemerrController.cs | 57 +- .../TestThemerrManager.cs | 569 ++++++++---------- 3 files changed, 323 insertions(+), 416 deletions(-) diff --git a/Jellyfin.Plugin.Themerr.Tests/FixtureJellyfinServer.cs b/Jellyfin.Plugin.Themerr.Tests/FixtureJellyfinServer.cs index 25ab6a6..1989f57 100644 --- a/Jellyfin.Plugin.Themerr.Tests/FixtureJellyfinServer.cs +++ b/Jellyfin.Plugin.Themerr.Tests/FixtureJellyfinServer.cs @@ -12,10 +12,25 @@ namespace Jellyfin.Plugin.Themerr.Tests; public class FixtureJellyfinServer { /// - /// Mock media items to use for testing + /// Gets a list of mock items. + /// + public static IEnumerable MockItemsData => MockItems().Select(item => new object[] { item }); + + /// + /// Gets a list of mock items. + /// + public static IEnumerable MockItems2Data => MockItems2().Select(item => new object[] { item }); + + /// + /// Gets a list of unsupported mock items. + /// + public static IEnumerable UnsupportedMockItemsData => UnsupportedMockItems().Select(item => new object[] { item }); + + /// + /// Mock media items to use for testing. /// /// List containing mock objects. - public static List MockItems() + private static List MockItems() { return new List { @@ -83,10 +98,10 @@ public static List MockItems() } /// - /// Mock items without an associated theme in ThemerrDB to use for testing + /// Mock items without an associated theme in ThemerrDB to use for testing. /// /// List containing mock objects. - public static List MockItems2() + private static List MockItems2() { return new List { @@ -114,10 +129,10 @@ public static List MockItems2() } /// - /// Mock items which are not supported by Themerr + /// Mock items which are not supported by Themerr. /// /// List containing mock objects. - public static List UnsupportedMockItems() + private static List UnsupportedMockItems() { return new List { @@ -133,14 +148,13 @@ public static List UnsupportedMockItems() } /// - /// Create mock items from stub video + /// Create mock items from stub video. /// - [Fact] + [Theory] [Trait("Category", "Init")] - private void CreateMockItems() + [MemberData(nameof(MockItemsData))] + private void CreateMockItems(BaseItem item) { - var mockItems = MockItems(); - // get the stub video path based on the directory of this file var stubVideoPath = Path.Combine( Directory.GetCurrentDirectory(), @@ -149,50 +163,47 @@ private void CreateMockItems() Assert.True(File.Exists(stubVideoPath), "Could not find ./data/video_stub.mp4"); - foreach (var item in mockItems) - { - // copy the ./data/video_stub.mp4 to the movie folder "movie.Name (movie.ProductionYear)" - var itemFolder = Path.Combine( - "themerr_jellyfin_tests", - $"{item.Name} ({item.ProductionYear})"); + // copy the ./data/video_stub.mp4 to the movie folder "movie.Name (movie.ProductionYear)" + var itemFolder = Path.Combine( + "themerr_jellyfin_tests", + $"{item.Name} ({item.ProductionYear})"); - // create the movie folder - Directory.CreateDirectory(itemFolder); - - string? itemVideoPath = null; - if (item is Movie) - { - // copy the video_stub.mp4 to the movie folder, renaming it based on movie name - itemVideoPath = Path.Combine( - itemFolder, - $"{item.Name} ({item.ProductionYear}).mp4"); - } - else if (item is Series) - { - // season folder - var seasonFolder = Path.Combine( - itemFolder, - "Season 01"); - Directory.CreateDirectory(seasonFolder); + // create the movie folder + Directory.CreateDirectory(itemFolder); - // copy the video_stub.mp4 to the season folder, renaming it based on series name - itemVideoPath = Path.Combine( - seasonFolder, - $"{item.Name} ({item.ProductionYear}) - S01E01 - Episode Name.mp4"); - } - else - { - Assert.Fail($"Unknown item type: {item.GetType()}"); - } + string? itemVideoPath = null; + if (item is Movie) + { + // copy the video_stub.mp4 to the movie folder, renaming it based on movie name + itemVideoPath = Path.Combine( + itemFolder, + $"{item.Name} ({item.ProductionYear}).mp4"); + } + else if (item is Series) + { + // season folder + var seasonFolder = Path.Combine( + itemFolder, + "Season 01"); + Directory.CreateDirectory(seasonFolder); - // if file does not exist - if (!File.Exists(itemVideoPath)) - { - // copy the stub video to the item folder - File.Copy(stubVideoPath, itemVideoPath); - } + // copy the video_stub.mp4 to the season folder, renaming it based on series name + itemVideoPath = Path.Combine( + seasonFolder, + $"{item.Name} ({item.ProductionYear}) - S01E01 - Episode Name.mp4"); + } + else + { + Assert.Fail($"Unknown item type: {item.GetType()}"); + } - Assert.True(File.Exists(itemVideoPath), $"Could not find {itemVideoPath}"); + // if file does not exist + if (!File.Exists(itemVideoPath)) + { + // copy the stub video to the item folder + File.Copy(stubVideoPath, itemVideoPath); } + + Assert.True(File.Exists(itemVideoPath), $"Could not find {itemVideoPath}"); } } diff --git a/Jellyfin.Plugin.Themerr.Tests/TestThemerrController.cs b/Jellyfin.Plugin.Themerr.Tests/TestThemerrController.cs index bb4c119..456b4e8 100644 --- a/Jellyfin.Plugin.Themerr.Tests/TestThemerrController.cs +++ b/Jellyfin.Plugin.Themerr.Tests/TestThemerrController.cs @@ -97,42 +97,35 @@ public void TestGetTranslations() /// /// Test GetCultureResource function. /// - [Fact] + /// The culture to test. + [Theory] [Trait("Category", "Unit")] - public void TestGetCultureResource() + [InlineData("de")] + [InlineData("en")] + [InlineData("en-GB")] + [InlineData("en-US")] + [InlineData("es")] + [InlineData("fr")] + [InlineData("it")] + [InlineData("ru")] + [InlineData("sv")] + [InlineData("zh")] + public void TestGetCultureResource(string culture) { - // list of english cultures - var enCultures = new List - { - "de", - "en", - "en-GB", - "en-US", - "es", - "fr", - "it", - "ru", - "sv", - "zh" - }; - - foreach (var t in enCultures) - { - var result = _controller.GetCultureResource(t); - Assert.IsType>(result); + var result = _controller.GetCultureResource(culture); + Assert.IsType>(result); - // replace - with _ in the culture - var t2 = t.Replace("-", "_"); + // replace - with _ in the culture + var culture2 = culture.Replace("-", "_"); - // en is not included in the list - if (t != "en") - { - // assert that `en_<>.json` is in the list - Assert.Contains(t2 + ".json", result); - } - - // assert that `en` is NOT in the list - Assert.DoesNotContain("en.json", result); + // en is not included in the list + if (culture != "en") + { + // assert that `en_<>.json` is in the list + Assert.Contains(culture2 + ".json", result); } + + // assert that `en` is NOT in the list + Assert.DoesNotContain("en.json", result); } } diff --git a/Jellyfin.Plugin.Themerr.Tests/TestThemerrManager.cs b/Jellyfin.Plugin.Themerr.Tests/TestThemerrManager.cs index 9285f31..d064c9d 100644 --- a/Jellyfin.Plugin.Themerr.Tests/TestThemerrManager.cs +++ b/Jellyfin.Plugin.Themerr.Tests/TestThemerrManager.cs @@ -1,3 +1,4 @@ +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; @@ -31,20 +32,16 @@ public TestThemerrManager(ITestOutputHelper output) _themerrManager = new ThemerrManager(mockLibraryManager.Object, mockLogger.Object); } - private static List FixtureYoutubeUrls() + /// + /// Gets a list of Youtube URLs. + /// + public static IEnumerable YoutubeUrls => new List { - // create a list and return it - var youtubeUrls = new List() - { - "https://www.youtube.com/watch?v=dQw4w9WgXcQ", - "https://www.youtube.com/watch?v=yPYZpwSpKmA", - "https://www.youtube.com/watch?v=Ghmd4QzT9YY", - "https://www.youtube.com/watch?v=LVEWkghDh9A" - }; - - // return the list - return youtubeUrls; - } + new object[] { "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }, + new object[] { "https://www.youtube.com/watch?v=yPYZpwSpKmA" }, + new object[] { "https://www.youtube.com/watch?v=Ghmd4QzT9YY" }, + new object[] { "https://www.youtube.com/watch?v=LVEWkghDh9A" } + }; [Fact] [Trait("Category", "Unit")] @@ -84,84 +81,82 @@ private void TestGetExistingThemerrDataValue() Assert.Null(_themerrManager.GetExistingThemerrDataValue("any_key", themerrDataPath)); } - [Fact] + [Theory] [Trait("Category", "Unit")] - private void TestSaveMp3() + [MemberData(nameof(YoutubeUrls))] + private void TestSaveMp3(string videoUrl) { // set destination with themerr_jellyfin_tests as the folder name var destinationFile = Path.Combine( "theme.mp3"); - foreach (var videoUrl in FixtureYoutubeUrls()) - { - // log - TestLogger.Info($"Attempting to download {videoUrl}"); + // log + TestLogger.Info($"Attempting to download {videoUrl}"); - // run and wait - var themeExists = _themerrManager.SaveMp3(destinationFile, videoUrl); - Assert.True(themeExists, $"SaveMp3 did not return True for {videoUrl}"); + // run and wait + var themeExists = _themerrManager.SaveMp3(destinationFile, videoUrl); + Assert.True(themeExists, $"SaveMp3 did not return True for {videoUrl}"); - // check if file exists - Assert.True(File.Exists(destinationFile), $"File {destinationFile} does not exist"); + // check if file exists + Assert.True(File.Exists(destinationFile), $"File {destinationFile} does not exist"); - // check if the file is an actual mp3 - // https://en.wikipedia.org/wiki/List_of_file_signatures - var fileBytes = File.ReadAllBytes(destinationFile); - var fileBytesHex = BitConverter.ToString(fileBytes); + // check if the file is an actual mp3 + // https://en.wikipedia.org/wiki/List_of_file_signatures + var fileBytes = File.ReadAllBytes(destinationFile); + var fileBytesHex = BitConverter.ToString(fileBytes); - // make sure the file is not WebM, starts with `1A 45 DF A3` - var isWebM = fileBytesHex.StartsWith("1A-45-DF-A3"); - Assert.False(isWebM, $"File {destinationFile} is WebM"); + // make sure the file is not WebM, starts with `1A 45 DF A3` + var isWebM = fileBytesHex.StartsWith("1A-45-DF-A3"); + Assert.False(isWebM, $"File {destinationFile} is WebM"); - // valid mp3 signatures dictionary with offsets - var validMp3Signatures = new Dictionary - { - {"66-74-79-70-64-61-73-68", 4}, // Mp4 container? - {"66-74-79-70-69-73-6F-6D", 4}, // Mp4 container - {"49-44-33", 0}, // ID3 - {"FF-FB", 0}, // MPEG-1 Layer 3 - {"FF-F3", 0}, // MPEG-1 Layer 3 - {"FF-F2", 0}, // MPEG-1 Layer 3 - }; - - // log beginning of fileBytesHex - TestLogger.Debug($"Beginning of fileBytesHex: {fileBytesHex.Substring(0, 40)}"); - - // check if the file is an actual mp3 - var isMp3 = false; - - // loop through validMp3Signatures - foreach (var (signature, offset) in validMp3Signatures) - { - // log - TestLogger.Debug($"Checking for {signature} at offset of {offset} bytes"); + // valid mp3 signatures dictionary with offsets + var validMp3Signatures = new Dictionary + { + {"66-74-79-70-64-61-73-68", 4}, // Mp4 container? + {"66-74-79-70-69-73-6F-6D", 4}, // Mp4 container + {"49-44-33", 0}, // ID3 + {"FF-FB", 0}, // MPEG-1 Layer 3 + {"FF-F3", 0}, // MPEG-1 Layer 3 + {"FF-F2", 0}, // MPEG-1 Layer 3 + }; - // remove the offset bytes - var fileBytesHexWithoutOffset = fileBytesHex.Substring(offset * 3); + // log beginning of fileBytesHex + TestLogger.Debug($"Beginning of fileBytesHex: {fileBytesHex.Substring(0, 40)}"); - // check if the beginning of the fileBytesHexWithoutOffset matches the signature - var isSignature = fileBytesHexWithoutOffset.StartsWith(signature); - if (isSignature) - { - // log - TestLogger.Info($"Found {signature} at offset {offset}"); + // check if the file is an actual mp3 + var isMp3 = false; - // set isMp3 to true - isMp3 = true; + // loop through validMp3Signatures + foreach (var (signature, offset) in validMp3Signatures) + { + // log + TestLogger.Debug($"Checking for {signature} at offset of {offset} bytes"); - // break out of loop - break; - } + // remove the offset bytes + var fileBytesHexWithoutOffset = fileBytesHex.Substring(offset * 3); + // check if the beginning of the fileBytesHexWithoutOffset matches the signature + var isSignature = fileBytesHexWithoutOffset.StartsWith(signature); + if (isSignature) + { // log - TestLogger.Debug($"Did not find {signature} at offset {offset}"); - } + TestLogger.Info($"Found {signature} at offset {offset}"); + + // set isMp3 to true + isMp3 = true; - Assert.True(isMp3, $"File {destinationFile} is not an mp3"); + // break out of loop + break; + } - // delete file - File.Delete(destinationFile); + // log + TestLogger.Debug($"Did not find {signature} at offset {offset}"); } + + Assert.True(isMp3, $"File {destinationFile} is not an mp3"); + + // delete file + File.Delete(destinationFile); } [Fact] @@ -195,79 +190,57 @@ private void TestGetTmdbItemsFromLibrary() // todo: test with actual items } - [Fact] + [Theory] [Trait("Category", "Unit")] - private void TestProcessItemTheme() + [MemberData(nameof(FixtureJellyfinServer.MockItemsData), MemberType = typeof(FixtureJellyfinServer))] + private void TestProcessItemTheme(BaseItem item) { - // get fixture movies - var mockItems = FixtureJellyfinServer.MockItems(); - - Assert.True(mockItems.Count > 0, "mockItems.Count is not greater than 0"); - - foreach (var item in mockItems) - { - // get the item theme - _themerrManager.ProcessItemTheme(item); + // get the item theme + _themerrManager.ProcessItemTheme(item); - Assert.True(File.Exists(_themerrManager.GetThemePath(item)), $"File {_themerrManager.GetThemePath(item)} does not exist"); + Assert.True(File.Exists(_themerrManager.GetThemePath(item)), $"File {_themerrManager.GetThemePath(item)} does not exist"); - // cleanup and delete the file - File.Delete(_themerrManager.GetThemePath(item)); - } + // cleanup and delete the file + File.Delete(_themerrManager.GetThemePath(item)); } - [Fact] + [Theory] [Trait("Category", "Unit")] - private void TestProcessItemThemeUnsupportedType() + [MemberData(nameof(FixtureJellyfinServer.UnsupportedMockItemsData), MemberType = typeof(FixtureJellyfinServer))] + private void TestProcessItemThemeUnsupportedType(BaseItem item) { - // get fixture items - var mockItems = FixtureJellyfinServer.UnsupportedMockItems(); - - foreach (var item in mockItems) - { - // get the item theme - _themerrManager.ProcessItemTheme(item); + // get the item theme + _themerrManager.ProcessItemTheme(item); - Assert.False(File.Exists(_themerrManager.GetThemePath(item)), $"File {_themerrManager.GetThemePath(item)} exists"); - } + Assert.False(File.Exists(_themerrManager.GetThemePath(item)), $"File {_themerrManager.GetThemePath(item)} exists"); } - [Fact] + [Theory] [Trait("Category", "Unit")] - private void TestGetTmdbId() + [MemberData(nameof(FixtureJellyfinServer.MockItemsData), MemberType = typeof(FixtureJellyfinServer))] + private void TestGetTmdbId(BaseItem item) { - // get fixture items - var mockItems = FixtureJellyfinServer.MockItems(); - - foreach (var item in mockItems) - { - // get the item theme - var tmdbId = _themerrManager.GetTmdbId(item); + // get the item theme + var tmdbId = _themerrManager.GetTmdbId(item); - // ensure tmdbId is not empty - Assert.NotEmpty(tmdbId); + // ensure tmdbId is not empty + Assert.NotEmpty(tmdbId); - // ensure tmdbId is the same as the one in the item fixture - Assert.Equal(item.ProviderIds[MetadataProvider.Tmdb.ToString()], tmdbId); - } + // ensure tmdbId is the same as the one in the item fixture + Assert.Equal(item.ProviderIds[MetadataProvider.Tmdb.ToString()], tmdbId); } // todo: fix this test - // [Fact] + // [Theory] // [Trait("Category", "Unit")] - // private void TestGetThemeProvider() + // [MemberData(nameof(FixtureJellyfinServer.MockItemsData), MemberType = typeof(FixtureJellyfinServer))] + // private void TestGetThemeProvider(BaseItem item) // { - // // get fixture items - // var mockItems = FixtureJellyfinServer.MockItems(); + // // get the item theme + // var themeProvider = _themerrManager.GetThemeProvider(item); // - // foreach (var item in mockItems) - // { - // // get the item theme - // var themeProvider = _themerrManager.GetThemeProvider(item); - // - // // ensure themeProvider null - // Assert.Null(themeProvider); - // } + // // ensure themeProvider null + // Assert.Null(themeProvider); // // // todo: test with actual items // } @@ -350,263 +323,197 @@ private void TestContinueDownload() Assert.False(_themerrManager.ContinueDownload(themePath, themerrDataPath), "ContinueDownload returned True"); } - [Fact] + [Theory] [Trait("Category", "Unit")] - private void TestGetThemePath() + [MemberData(nameof(FixtureJellyfinServer.MockItemsData), MemberType = typeof(FixtureJellyfinServer))] + private void TestGetThemePath(BaseItem item) { - // get fixture items - var mockItems = FixtureJellyfinServer.MockItems(); - - Assert.True(mockItems.Count > 0, "mockItems.Count is not greater than 0"); - - foreach (var item in mockItems) - { - // get the item theme - var themePath = _themerrManager.GetThemePath(item); + // get the item theme + var themePath = _themerrManager.GetThemePath(item); - // ensure path ends with theme.mp3 - Assert.EndsWith("theme.mp3", themePath); - } + // ensure path ends with theme.mp3 + Assert.EndsWith("theme.mp3", themePath); } - [Fact] + [Theory] [Trait("Category", "Unit")] - private void TestGetThemePathUnsupportedType() + [MemberData(nameof(FixtureJellyfinServer.UnsupportedMockItemsData), MemberType = typeof(FixtureJellyfinServer))] + private void TestGetThemePathUnsupportedType(BaseItem item) { - // get fixture items - var mockItems = FixtureJellyfinServer.UnsupportedMockItems(); + // get the item theme + var themePath = _themerrManager.GetThemePath(item); - Assert.True(mockItems.Count > 0, "mockItems.Count is not greater than 0"); - - foreach (var item in mockItems) - { - // get the item theme - var themePath = _themerrManager.GetThemePath(item); - - // ensure path is null - Assert.Null(themePath); - } + // ensure path is null + Assert.Null(themePath); } - [Fact] + [Theory] [Trait("Category", "Unit")] - private void TestGetThemerrDataPath() + [MemberData(nameof(FixtureJellyfinServer.MockItemsData), MemberType = typeof(FixtureJellyfinServer))] + private void TestGetThemerrDataPath(BaseItem item) { - // get fixture items - var mockItems = FixtureJellyfinServer.MockItems(); + // get the item theme + var themerrDataPath = _themerrManager.GetThemerrDataPath(item); - Assert.True(mockItems.Count > 0, "mockItems.Count is not greater than 0"); - - foreach (var item in mockItems) - { - // get the item theme - var themerrDataPath = _themerrManager.GetThemerrDataPath(item); - - // ensure path ends with theme.mp3 - Assert.EndsWith("themerr.json", themerrDataPath); - } + // ensure path ends with theme.mp3 + Assert.EndsWith("themerr.json", themerrDataPath); } - [Fact] + [Theory] [Trait("Category", "Unit")] - private void TestGetThemerrDataPathUnsupportedType() + [MemberData(nameof(FixtureJellyfinServer.UnsupportedMockItemsData), MemberType = typeof(FixtureJellyfinServer))] + private void TestGetThemerrDataPathUnsupportedType(BaseItem item) { - // get fixture items - var mockItems = FixtureJellyfinServer.UnsupportedMockItems(); - - Assert.True(mockItems.Count > 0, "mockItems.Count is not greater than 0"); + // get the item theme + var themerrDataPath = _themerrManager.GetThemerrDataPath(item); - foreach (var item in mockItems) - { - // get the item theme - var themerrDataPath = _themerrManager.GetThemerrDataPath(item); - - // ensure path is null - Assert.Null(themerrDataPath); - } + // ensure path is null + Assert.Null(themerrDataPath); } - [Fact] + [Theory] [Trait("Category", "Unit")] - private void TestCreateThemerrDbLink() + [MemberData(nameof(FixtureJellyfinServer.MockItemsData), MemberType = typeof(FixtureJellyfinServer))] + private void TestCreateThemerrDbLink(BaseItem item) { - // get fixture items - var mockItems = FixtureJellyfinServer.MockItems(); - - Assert.True(mockItems.Count > 0, "mockItems.Count is not greater than 0"); - - foreach (var item in mockItems) + var dbType = item switch { - var dbType = item switch - { - Movie _ => "movies", - Series _ => "tv_shows", - _ => null - }; + Movie _ => "movies", + Series _ => "tv_shows", + _ => null + }; - // return if dbType is null - if (string.IsNullOrEmpty(dbType)) - { - Assert.Fail($"Unknown item type: {item.GetType()}"); - } + // return if dbType is null + if (string.IsNullOrEmpty(dbType)) + { + Assert.Fail($"Unknown item type: {item.GetType()}"); + } - var tmdbId = item.ProviderIds[MetadataProvider.Tmdb.ToString()]; - var themerrDbUrl = _themerrManager.CreateThemerrDbLink(tmdbId, dbType); + var tmdbId = item.ProviderIds[MetadataProvider.Tmdb.ToString()]; + var themerrDbUrl = _themerrManager.CreateThemerrDbLink(tmdbId, dbType); - TestLogger.Info($"themerrDbLink: {themerrDbUrl}"); + TestLogger.Info($"themerrDbLink: {themerrDbUrl}"); - Assert.EndsWith($"themoviedb/{tmdbId}.json", themerrDbUrl); - } + Assert.EndsWith($"themoviedb/{tmdbId}.json", themerrDbUrl); } - [Fact] + [Theory] [Trait("Category", "Unit")] - private void TestGetYoutubeThemeUrl() + [MemberData(nameof(FixtureJellyfinServer.MockItemsData), MemberType = typeof(FixtureJellyfinServer))] + private void TestGetYoutubeThemeUrl(BaseItem item) { - // get fixture items - var mockItems = FixtureJellyfinServer.MockItems(); - - Assert.True(mockItems.Count > 0, "mockItems.Count is not greater than 0"); - - // loop over each item - foreach (var item in mockItems) + var dbType = item switch { - var dbType = item switch - { - Movie _ => "movies", - Series _ => "tv_shows", - _ => null - }; + Movie _ => "movies", + Series _ => "tv_shows", + _ => null + }; - // return if dbType is null - if (string.IsNullOrEmpty(dbType)) - { - Assert.Fail($"Unknown item type: {item.GetType()}"); - } + // return if dbType is null + if (string.IsNullOrEmpty(dbType)) + { + Assert.Fail($"Unknown item type: {item.GetType()}"); + } - // get themerrDbUrl - var tmdbId = _themerrManager.GetTmdbId(item); - var themerrDbLink = _themerrManager.CreateThemerrDbLink(tmdbId, dbType); + // get themerrDbUrl + var tmdbId = _themerrManager.GetTmdbId(item); + var themerrDbLink = _themerrManager.CreateThemerrDbLink(tmdbId, dbType); - // get the new youtube theme url - var youtubeThemeUrl = _themerrManager.GetYoutubeThemeUrl(themerrDbLink, item); + // get the new youtube theme url + var youtubeThemeUrl = _themerrManager.GetYoutubeThemeUrl(themerrDbLink, item); - // log - TestLogger.Info($"youtubeThemeUrl: {youtubeThemeUrl}"); + // log + TestLogger.Info($"youtubeThemeUrl: {youtubeThemeUrl}"); - Assert.NotEmpty(youtubeThemeUrl); - } + Assert.NotEmpty(youtubeThemeUrl); } - [Fact] + [Theory] [Trait("Category", "Unit")] - private void TestGetYoutubeThemeUrlExceptions() + [MemberData(nameof(FixtureJellyfinServer.MockItems2Data), MemberType = typeof(FixtureJellyfinServer))] + private void TestGetYoutubeThemeUrlExceptions(BaseItem item) { - // get fixture items - var mockItems = FixtureJellyfinServer.MockItems2(); - - Assert.True(mockItems.Count > 0, "mockItems.Count is not greater than 0"); - - // loop over each item - foreach (var item in mockItems) + var dbType = item switch { - var dbType = item switch - { - Movie _ => "movies", - Series _ => "tv_shows", - _ => null - }; + Movie _ => "movies", + Series _ => "tv_shows", + _ => null + }; - // return if dbType is null - if (string.IsNullOrEmpty(dbType)) - { - Assert.Fail($"Unknown item type: {item.GetType()}"); - } + // return if dbType is null + if (string.IsNullOrEmpty(dbType)) + { + Assert.Fail($"Unknown item type: {item.GetType()}"); + } - // get themerrDbUrl - var tmdbId = _themerrManager.GetTmdbId(item); - var themerrDbLink = _themerrManager.CreateThemerrDbLink(tmdbId, dbType); + // get themerrDbUrl + var tmdbId = _themerrManager.GetTmdbId(item); + var themerrDbLink = _themerrManager.CreateThemerrDbLink(tmdbId, dbType); - // get the new youtube theme url - var youtubeThemeUrl = _themerrManager.GetYoutubeThemeUrl(themerrDbLink, item); + // get the new youtube theme url + var youtubeThemeUrl = _themerrManager.GetYoutubeThemeUrl(themerrDbLink, item); - Assert.Empty(youtubeThemeUrl); - } + Assert.Empty(youtubeThemeUrl); } - [Fact] + [Theory] [Trait("Category", "Unit")] - private void TestGetIssueUrl() + [MemberData(nameof(FixtureJellyfinServer.MockItemsData), MemberType = typeof(FixtureJellyfinServer))] + private void TestGetIssueUrl(BaseItem item) { - // get fixture items - var mockItems = FixtureJellyfinServer.MockItems(); - - Assert.True(mockItems.Count > 0, "mockItems.Count is not greater than 0"); - - // loop over each item - foreach (var item in mockItems) + var issueType = item switch { - var issueType = item switch - { - Movie _ => "MOVIE", - Series _ => "TV SHOW", - _ => null - }; + Movie _ => "MOVIE", + Series _ => "TV SHOW", + _ => null + }; - var tmdbEndpoint = item switch - { - Movie _ => "movie", - Series _ => "tv", - _ => null - }; + var tmdbEndpoint = item switch + { + Movie _ => "movie", + Series _ => "tv", + _ => null + }; - // return if dbType is null - if (string.IsNullOrEmpty(issueType) || string.IsNullOrEmpty(tmdbEndpoint)) - { - Assert.Fail($"Unknown item type: {item.GetType()}"); - } + // return if dbType is null + if (string.IsNullOrEmpty(issueType) || string.IsNullOrEmpty(tmdbEndpoint)) + { + Assert.Fail($"Unknown item type: {item.GetType()}"); + } - // parts of expected url - var tmdbId = _themerrManager.GetTmdbId(item); - var encodedName = item.Name.Replace(" ", "%20"); - var year = item.ProductionYear; - var expectedUrl = $"https://github.com/LizardByte/ThemerrDB/issues/new?assignees=&labels=request-theme&template=theme.yml&title=[{issueType}]:%20{encodedName}%20({year})&database_url=https://www.themoviedb.org/{tmdbEndpoint}/{tmdbId}"; + // parts of expected url + var tmdbId = _themerrManager.GetTmdbId(item); + var encodedName = item.Name.Replace(" ", "%20"); + var year = item.ProductionYear; + var expectedUrl = $"https://github.com/LizardByte/ThemerrDB/issues/new?assignees=&labels=request-theme&template=theme.yml&title=[{issueType}]:%20{encodedName}%20({year})&database_url=https://www.themoviedb.org/{tmdbEndpoint}/{tmdbId}"; - // get the new youtube theme url - var issueUrl = _themerrManager.GetIssueUrl(item); + // get the new youtube theme url + var issueUrl = _themerrManager.GetIssueUrl(item); - Assert.NotEmpty(issueUrl); + Assert.NotEmpty(issueUrl); - // ensure issue url ends with tmdbId - Assert.EndsWith(tmdbId, issueUrl); + // ensure issue url ends with tmdbId + Assert.EndsWith(tmdbId, issueUrl); - // ensure issue url matches expected url - Assert.Equal(expectedUrl, issueUrl); - } + // ensure issue url matches expected url + Assert.Equal(expectedUrl, issueUrl); } - [Fact] + [Theory] [Trait("Category", "Unit")] - private void TestGetIssueUrlUnsupportedType() + [MemberData(nameof(FixtureJellyfinServer.UnsupportedMockItemsData), MemberType = typeof(FixtureJellyfinServer))] + private void TestGetIssueUrlUnsupportedType(BaseItem item) { - // get fixture items - var mockItems = FixtureJellyfinServer.UnsupportedMockItems(); - - Assert.True(mockItems.Count > 0, "mockItems.Count is not greater than 0"); - - // loop over each item - foreach (var item in mockItems) - { - // get the new youtube theme url - var issueUrl = _themerrManager.GetIssueUrl(item); + // get the new youtube theme url + var issueUrl = _themerrManager.GetIssueUrl(item); - Assert.Null(issueUrl); - } + Assert.Null(issueUrl); } - [Fact] + [Theory] [Trait("Category", "Unit")] - private void TestSaveThemerrData() + [MemberData(nameof(YoutubeUrls))] + private void TestSaveThemerrData(string youtubeThemeUrl) { // set mock themerrDataPath using a random number var mockThemerrDataPath = $"themerr_{new Random().Next()}.json"; @@ -616,25 +523,21 @@ private void TestSaveThemerrData() "data", "video_stub.mp4"); - // loop over each themerrDbLink - foreach (var youtubeThemeUrl in FixtureYoutubeUrls()) - { - // save themerr data - var fileExists = _themerrManager.SaveThemerrData(stubVideoPath, mockThemerrDataPath, youtubeThemeUrl); - Assert.True(fileExists, $"SaveThemerrData did not return True for {youtubeThemeUrl}"); - - // check if file exists - Assert.True(File.Exists(mockThemerrDataPath), $"File {mockThemerrDataPath} does not exist"); - - // make sure the saved json file contains a key named "youtube_theme_url", and value is correct - var jsonString = File.ReadAllText(mockThemerrDataPath); - File.Delete(mockThemerrDataPath); // delete the file - dynamic jsonData = JsonConvert.DeserializeObject(jsonString) ?? throw new InvalidOperationException(); - var savedYoutubeThemeUrl = jsonData.youtube_theme_url.ToString(); - Assert.True( - youtubeThemeUrl == savedYoutubeThemeUrl, - $"youtubeThemeUrl {youtubeThemeUrl} does not match savedYoutubeThemeUrl {savedYoutubeThemeUrl}"); - } + // save themerr data + var fileExists = _themerrManager.SaveThemerrData(stubVideoPath, mockThemerrDataPath, youtubeThemeUrl); + Assert.True(fileExists, $"SaveThemerrData did not return True for {youtubeThemeUrl}"); + + // check if file exists + Assert.True(File.Exists(mockThemerrDataPath), $"File {mockThemerrDataPath} does not exist"); + + // make sure the saved json file contains a key named "youtube_theme_url", and value is correct + var jsonString = File.ReadAllText(mockThemerrDataPath); + File.Delete(mockThemerrDataPath); // delete the file + dynamic jsonData = JsonConvert.DeserializeObject(jsonString) ?? throw new InvalidOperationException(); + var savedYoutubeThemeUrl = jsonData.youtube_theme_url.ToString(); + Assert.True( + youtubeThemeUrl == savedYoutubeThemeUrl, + $"youtubeThemeUrl {youtubeThemeUrl} does not match savedYoutubeThemeUrl {savedYoutubeThemeUrl}"); } [Fact]