using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Jellyfin.Data;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Enums;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Users;
using Moq;
namespace Jellyfin.Plugin.WatchedTogether.Tests;
///
/// Sets up the members whose signatures differ between Jellyfin 10.11
/// and 12, so the suites read the same whichever generation they are compiled against.
///
internal static class UserManagerMockExtensions
{
///
/// Routes ChangePassword to with the user the real server
/// would act on: the instance handed in on 10.11, the stored row looked up by id on 12.
///
/// The user manager mock.
/// The users the mock knows about, used to resolve ids on 12.
/// The behaviour to run for the change.
public static void SetupChangePassword(
this Mock mock,
List users,
Func onChange)
{
#if JELLYFIN_12
mock.Setup(m => m.ChangePassword(It.IsAny(), It.IsAny()))
.Returns((Guid id, string password) =>
{
var user = users.Find(u => u.Id == id)
?? throw new KeyNotFoundException($"No user with id {id}");
return onChange(user, password);
});
#else
mock.Setup(m => m.ChangePassword(It.IsAny(), It.IsAny()))
.Returns((User user, string password) => onChange(user, password));
#endif
}
///
/// Models the policy round trip the way Jellyfin's UserManager does it: GetUserDto
/// projects the user's live fields into a , and
/// UpdatePolicyAsync writes a policy back onto the user entity, so code that reads the
/// user afterwards sees what was written.
///
/// The user manager mock.
/// The users the mock knows about.
public static void SetupPolicyRoundTrip(this Mock mock, List users)
{
mock.Setup(m => m.GetUserDto(It.IsAny(), It.IsAny()))
.Returns((User user, string? _) => new UserDto
{
Id = user.Id,
Name = user.Username,
Policy = new UserPolicy
{
IsAdministrator = user.HasPermission(PermissionKind.IsAdministrator),
EnableAllFolders = user.HasPermission(PermissionKind.EnableAllFolders),
EnabledFolders = user.GetPreferenceValues(PreferenceKind.EnabledFolders),
MaxParentalRating = user.MaxParentalRatingScore,
MaxParentalSubRating = user.MaxParentalRatingSubScore,
BlockUnratedItems = user.GetPreferenceValues(PreferenceKind.BlockUnratedItems),
BlockedTags = user.GetPreference(PreferenceKind.BlockedTags),
AllowedTags = user.GetPreference(PreferenceKind.AllowedTags),
}
});
mock.Setup(m => m.UpdatePolicyAsync(It.IsAny(), It.IsAny()))
.Returns((Guid id, UserPolicy policy) =>
{
var user = users.Find(u => u.Id == id)
?? throw new KeyNotFoundException($"No user with id {id}");
user.SetPermission(PermissionKind.IsAdministrator, policy.IsAdministrator);
user.SetPermission(PermissionKind.EnableAllFolders, policy.EnableAllFolders);
user.SetPreference(PreferenceKind.EnabledFolders, policy.EnabledFolders ?? []);
user.MaxParentalRatingScore = policy.MaxParentalRating;
user.MaxParentalRatingSubScore = policy.MaxParentalSubRating;
user.SetPreference(PreferenceKind.BlockUnratedItems, policy.BlockUnratedItems ?? []);
user.SetPreference(PreferenceKind.BlockedTags, policy.BlockedTags ?? []);
user.SetPreference(PreferenceKind.AllowedTags, policy.AllowedTags ?? []);
return Task.CompletedTask;
});
}
///
/// Sets a user's content restrictions directly, the way the user editor would.
///
/// The user to restrict.
/// The rating cap, or null for none.
/// The sub-score cap at the rating cap.
/// The unrated kinds to block.
/// The tags that hide an item.
/// The whitelist, or none for no whitelist.
/// The same user, for chaining.
public static User Restrict(
this User user,
int? maxRating = null,
int? maxSubRating = null,
IEnumerable? blockUnrated = null,
IEnumerable? blockedTags = null,
IEnumerable? allowedTags = null)
{
user.MaxParentalRatingScore = maxRating;
user.MaxParentalRatingSubScore = maxSubRating;
user.SetPreference(PreferenceKind.BlockUnratedItems, (blockUnrated ?? []).ToArray());
user.SetPreference(PreferenceKind.BlockedTags, (blockedTags ?? []).ToArray());
user.SetPreference(PreferenceKind.AllowedTags, (allowedTags ?? []).ToArray());
return user;
}
}