using Ludarium.Application; using Ludarium.Domain; namespace Ludarium.UnitTests; /// /// The library browser's question to the catalog. /// /// /// Filtering and ordering are properties of the query, not of the page the browser happens to hold. /// The playable-copy filter in particular must stay derived from the players' own policies, so it /// can never offer a format nothing accepts. /// public sealed class GameQueryTests { [Fact] public void AnEmptyQueryAsksForTheWholeCatalog() { var query = new GameQuery(); Assert.False(query.HasFilters); Assert.Equal(1, query.Page); Assert.Equal(50, query.PageSize); Assert.Null(query.Sort); } [Theory] [InlineData("title")] [InlineData("recent")] [InlineData("updated")] [InlineData("played")] [InlineData("rating")] public void EverySortKeyTheInterfaceOffersIsPartOfTheContract(string sort) => Assert.Contains(sort, GameQuery.SortKeys); [Fact] public void EveryLibraryFilterCountsAsAFilter() { Assert.True(new GameQuery { Search = "mario" }.HasFilters); Assert.True(new GameQuery { Platform = "snes" }.HasFilters); Assert.True(new GameQuery { Favorite = true }.HasFilters); Assert.True(new GameQuery { Status = GamePlayStatus.Playing }.HasFilters); Assert.True(new GameQuery { CollectionId = Guid.NewGuid() }.HasFilters); Assert.True(new GameQuery { Tag = "co-op" }.HasFilters); Assert.True(new GameQuery { MinimumRating = 4 }.HasFilters); Assert.True(new GameQuery { PlayableOnly = true }.HasFilters); // Sorting and paging change the order, not the population. Assert.False(new GameQuery { Sort = "rating", Page = 3 }.HasFilters); } [Fact] public void PlayableFormatsCoverEveryFormatAPlayerAccepts() { foreach (var platform in BrowserPlayPolicy.DescribePlatforms()) foreach (var extension in platform.Extensions) Assert.Contains($"{platform.Platform}|{extension}".ToLowerInvariant(), PlayableFormats.Pairs); foreach (var player in NativeRemotePlayerRegistry.All) foreach (var owned in player.Platforms) foreach (var extension in player.Extensions) Assert.Contains($"{owned}|{extension}".ToLowerInvariant(), PlayableFormats.Pairs); } [Fact] public void PlayableFormatsNeverOfferAPairNoPlayerAccepts() { Assert.DoesNotContain("nes|.iso", PlayableFormats.Pairs); Assert.DoesNotContain("wii|.nes", PlayableFormats.Pairs); // Play!.js cannot mount an archive, so a PS2 CUE set is not a playable copy. Assert.DoesNotContain("ps2|.cue", PlayableFormats.Pairs); Assert.Contains("psx|.cue", PlayableFormats.Pairs); Assert.Contains("gamecube|.rvz", PlayableFormats.Pairs); } [Fact] public void PlayableFormatsAreOrderedLowerCasedPairs() { Assert.All(PlayableFormats.Pairs, pair => { Assert.Equal(pair.ToLowerInvariant(), pair); var parts = pair.Split('|'); Assert.Equal(2, parts.Length); Assert.StartsWith(".", parts[1], StringComparison.Ordinal); }); Assert.Equal(PlayableFormats.Pairs.Order(StringComparer.Ordinal), PlayableFormats.Pairs); Assert.Equal(PlayableFormats.Pairs.Distinct(), PlayableFormats.Pairs); } }