aboutsummaryrefslogtreecommitdiff
path: root/tests/Jellyfin.Controller.Tests/Entities/PlaylistTests.cs
blob: 1794469359b0182fc69942276e61e2187885cd77 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
using System;
using System.Linq;
using Jellyfin.Data;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Enums;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Playlists;
using Moq;
using Xunit;

namespace Jellyfin.Controller.Tests.Entities;

[Collection("LibraryManagerTests")]
public sealed class PlaylistTests : IDisposable
{
    private readonly ILibraryManager? _previousLibraryManager = BaseItem.LibraryManager;

    public void Dispose()
    {
        BaseItem.LibraryManager = _previousLibraryManager;
    }

    [Fact]
    public void IsVisible_PlaylistWithNothingLeftInIt_IsHidden()
    {
        // The SQL parental filter hides a container whose every member is blocked, so a listing
        // built in memory has to reach the same answer.
        var blocked = new Movie { Id = Guid.NewGuid(), Name = "Movie" };
        SetupLibrary(blocked);

        Assert.False(BuildPlaylist(blocked).IsVisible(BuildRestrictedUser()));
    }

    [Fact]
    public void IsVisible_PlaylistWithOneAllowedItem_StaysVisible()
    {
        var blocked = new Movie { Id = Guid.NewGuid(), Name = "Movie" };
        var allowed = new Audio { Id = Guid.NewGuid(), Name = "Song" };
        SetupLibrary(blocked, allowed);

        Assert.True(BuildPlaylist(blocked, allowed).IsVisible(BuildRestrictedUser()));
    }

    [Fact]
    public void IsVisible_UnrestrictedUser_LeavesTheItemsUnresolved()
    {
        var blocked = new Movie { Id = Guid.NewGuid(), Name = "Movie" };
        var libraryManager = SetupLibrary(blocked);
        var user = new User("user", "auth-provider", "reset-provider");

        Assert.True(BuildPlaylist(blocked).IsVisible(user));

        // Resolving a playlist's items is a query per playlist; nothing may run it for a user no
        // rating keeps anything from.
        libraryManager.Verify(x => x.GetItemList(It.IsAny<InternalItemsQuery>()), Times.Never);
    }

    private static Mock<ILibraryManager> SetupLibrary(params BaseItem[] items)
    {
        var libraryManager = new Mock<ILibraryManager>();
        libraryManager
            .Setup(x => x.GetItemList(It.IsAny<InternalItemsQuery>()))
            .Returns(items);
        BaseItem.LibraryManager = libraryManager.Object;

        return libraryManager;
    }

    private static Playlist BuildPlaylist(params BaseItem[] items)
    {
        // An empty path keeps the playlist out of the shared-playlist branch.
        return new Playlist
        {
            Id = Guid.NewGuid(),
            Name = "Playlist",
            LinkedChildren = items.Select(LinkedChild.Create).ToArray()
        };
    }

    private static User BuildRestrictedUser()
    {
        var user = new User("user", "auth-provider", "reset-provider") { MaxParentalRatingScore = 5 };
        user.SetPreference(PreferenceKind.BlockUnratedItems, new[] { UnratedItem.Movie });

        return user;
    }
}