diff options
Diffstat (limited to 'tests')
25 files changed, 461 insertions, 213 deletions
diff --git a/tests/Jellyfin.Api.Tests/Auth/CustomAuthenticationHandlerTests.cs b/tests/Jellyfin.Api.Tests/Auth/CustomAuthenticationHandlerTests.cs index 4245c3249..4ea5094b6 100644 --- a/tests/Jellyfin.Api.Tests/Auth/CustomAuthenticationHandlerTests.cs +++ b/tests/Jellyfin.Api.Tests/Auth/CustomAuthenticationHandlerTests.cs @@ -1,7 +1,6 @@ using System; using System.Linq; using System.Security.Claims; -using System.Text.Encodings.Web; using System.Threading.Tasks; using AutoFixture; using AutoFixture.AutoMoq; @@ -9,7 +8,6 @@ using Jellyfin.Api.Auth; using Jellyfin.Api.Constants; using Jellyfin.Data.Entities; using Jellyfin.Data.Enums; -using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Net; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Http; @@ -26,12 +24,6 @@ namespace Jellyfin.Api.Tests.Auth private readonly IFixture _fixture; private readonly Mock<IAuthService> _jellyfinAuthServiceMock; - private readonly Mock<IOptionsMonitor<AuthenticationSchemeOptions>> _optionsMonitorMock; - private readonly Mock<ISystemClock> _clockMock; - private readonly Mock<IServiceProvider> _serviceProviderMock; - private readonly Mock<IAuthenticationService> _authenticationServiceMock; - private readonly UrlEncoder _urlEncoder; - private readonly HttpContext _context; private readonly CustomAuthenticationHandler _sut; private readonly AuthenticationScheme _scheme; @@ -47,26 +39,23 @@ namespace Jellyfin.Api.Tests.Auth AllowFixtureCircularDependencies(); _jellyfinAuthServiceMock = _fixture.Freeze<Mock<IAuthService>>(); - _optionsMonitorMock = _fixture.Freeze<Mock<IOptionsMonitor<AuthenticationSchemeOptions>>>(); - _clockMock = _fixture.Freeze<Mock<ISystemClock>>(); - _serviceProviderMock = _fixture.Freeze<Mock<IServiceProvider>>(); - _authenticationServiceMock = _fixture.Freeze<Mock<IAuthenticationService>>(); + var optionsMonitorMock = _fixture.Freeze<Mock<IOptionsMonitor<AuthenticationSchemeOptions>>>(); + var serviceProviderMock = _fixture.Freeze<Mock<IServiceProvider>>(); + var authenticationServiceMock = _fixture.Freeze<Mock<IAuthenticationService>>(); _fixture.Register<ILoggerFactory>(() => new NullLoggerFactory()); - _urlEncoder = UrlEncoder.Default; + serviceProviderMock.Setup(s => s.GetService(typeof(IAuthenticationService))) + .Returns(authenticationServiceMock.Object); - _serviceProviderMock.Setup(s => s.GetService(typeof(IAuthenticationService))) - .Returns(_authenticationServiceMock.Object); - - _optionsMonitorMock.Setup(o => o.Get(It.IsAny<string>())) + optionsMonitorMock.Setup(o => o.Get(It.IsAny<string>())) .Returns(new AuthenticationSchemeOptions { ForwardAuthenticate = null }); - _context = new DefaultHttpContext + HttpContext context = new DefaultHttpContext { - RequestServices = _serviceProviderMock.Object + RequestServices = serviceProviderMock.Object }; _scheme = new AuthenticationScheme( @@ -75,22 +64,7 @@ namespace Jellyfin.Api.Tests.Auth typeof(CustomAuthenticationHandler)); _sut = _fixture.Create<CustomAuthenticationHandler>(); - _sut.InitializeAsync(_scheme, _context).Wait(); - } - - [Fact] - public async Task HandleAuthenticateAsyncShouldFailWithNullUser() - { - _jellyfinAuthServiceMock.Setup( - a => a.Authenticate( - It.IsAny<HttpRequest>(), - It.IsAny<AuthenticatedAttribute>())) - .Returns((User?)null); - - var authenticateResult = await _sut.AuthenticateAsync(); - - Assert.False(authenticateResult.Succeeded); - Assert.Equal("Invalid user", authenticateResult.Failure.Message); + _sut.InitializeAsync(_scheme, context).Wait(); } [Fact] @@ -100,8 +74,7 @@ namespace Jellyfin.Api.Tests.Auth _jellyfinAuthServiceMock.Setup( a => a.Authenticate( - It.IsAny<HttpRequest>(), - It.IsAny<AuthenticatedAttribute>())) + It.IsAny<HttpRequest>())) .Throws(new SecurityException(errorMessage)); var authenticateResult = await _sut.AuthenticateAsync(); @@ -123,10 +96,10 @@ namespace Jellyfin.Api.Tests.Auth [Fact] public async Task HandleAuthenticateAsyncShouldAssignNameClaim() { - var user = SetupUser(); + var authorizationInfo = SetupUser(); var authenticateResult = await _sut.AuthenticateAsync(); - Assert.True(authenticateResult.Principal.HasClaim(ClaimTypes.Name, user.Username)); + Assert.True(authenticateResult.Principal.HasClaim(ClaimTypes.Name, authorizationInfo.User.Username)); } [Theory] @@ -134,10 +107,10 @@ namespace Jellyfin.Api.Tests.Auth [InlineData(false)] public async Task HandleAuthenticateAsyncShouldAssignRoleClaim(bool isAdmin) { - var user = SetupUser(isAdmin); + var authorizationInfo = SetupUser(isAdmin); var authenticateResult = await _sut.AuthenticateAsync(); - var expectedRole = user.HasPermission(PermissionKind.IsAdministrator) ? UserRoles.Administrator : UserRoles.User; + var expectedRole = authorizationInfo.User.HasPermission(PermissionKind.IsAdministrator) ? UserRoles.Administrator : UserRoles.User; Assert.True(authenticateResult.Principal.HasClaim(ClaimTypes.Role, expectedRole)); } @@ -150,18 +123,18 @@ namespace Jellyfin.Api.Tests.Auth Assert.Equal(_scheme.Name, authenticatedResult.Ticket.AuthenticationScheme); } - private User SetupUser(bool isAdmin = false) + private AuthorizationInfo SetupUser(bool isAdmin = false) { - var user = _fixture.Create<User>(); - user.SetPermission(PermissionKind.IsAdministrator, isAdmin); + var authorizationInfo = _fixture.Create<AuthorizationInfo>(); + authorizationInfo.User = _fixture.Create<User>(); + authorizationInfo.User.SetPermission(PermissionKind.IsAdministrator, isAdmin); _jellyfinAuthServiceMock.Setup( a => a.Authenticate( - It.IsAny<HttpRequest>(), - It.IsAny<AuthenticatedAttribute>())) - .Returns(user); + It.IsAny<HttpRequest>())) + .Returns(authorizationInfo); - return user; + return authorizationInfo; } private void AllowFixtureCircularDependencies() diff --git a/tests/Jellyfin.Api.Tests/Auth/DefaultAuthorizationPolicy/DefaultAuthorizationHandlerTests.cs b/tests/Jellyfin.Api.Tests/Auth/DefaultAuthorizationPolicy/DefaultAuthorizationHandlerTests.cs new file mode 100644 index 000000000..a62fd8d5a --- /dev/null +++ b/tests/Jellyfin.Api.Tests/Auth/DefaultAuthorizationPolicy/DefaultAuthorizationHandlerTests.cs @@ -0,0 +1,53 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using AutoFixture; +using AutoFixture.AutoMoq; +using Jellyfin.Api.Auth.DefaultAuthorizationPolicy; +using Jellyfin.Api.Constants; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Library; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Moq; +using Xunit; + +namespace Jellyfin.Api.Tests.Auth.DefaultAuthorizationPolicy +{ + public class DefaultAuthorizationHandlerTests + { + private readonly Mock<IConfigurationManager> _configurationManagerMock; + private readonly List<IAuthorizationRequirement> _requirements; + private readonly DefaultAuthorizationHandler _sut; + private readonly Mock<IUserManager> _userManagerMock; + private readonly Mock<IHttpContextAccessor> _httpContextAccessor; + + public DefaultAuthorizationHandlerTests() + { + var fixture = new Fixture().Customize(new AutoMoqCustomization()); + _configurationManagerMock = fixture.Freeze<Mock<IConfigurationManager>>(); + _requirements = new List<IAuthorizationRequirement> { new DefaultAuthorizationRequirement() }; + _userManagerMock = fixture.Freeze<Mock<IUserManager>>(); + _httpContextAccessor = fixture.Freeze<Mock<IHttpContextAccessor>>(); + + _sut = fixture.Create<DefaultAuthorizationHandler>(); + } + + [Theory] + [InlineData(UserRoles.Administrator)] + [InlineData(UserRoles.Guest)] + [InlineData(UserRoles.User)] + public async Task ShouldSucceedOnUser(string userRole) + { + TestHelpers.SetupConfigurationManager(_configurationManagerMock, true); + var claims = TestHelpers.SetupUser( + _userManagerMock, + _httpContextAccessor, + userRole); + + var context = new AuthorizationHandlerContext(_requirements, claims, null); + + await _sut.HandleAsync(context); + Assert.True(context.HasSucceeded); + } + } +} diff --git a/tests/Jellyfin.Api.Tests/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedHandlerTests.cs b/tests/Jellyfin.Api.Tests/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedHandlerTests.cs index e40af703f..ee42216e4 100644 --- a/tests/Jellyfin.Api.Tests/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedHandlerTests.cs +++ b/tests/Jellyfin.Api.Tests/Auth/FirstTimeSetupOrElevatedPolicy/FirstTimeSetupOrElevatedHandlerTests.cs @@ -1,13 +1,13 @@ using System.Collections.Generic; -using System.Security.Claims; using System.Threading.Tasks; using AutoFixture; using AutoFixture.AutoMoq; using Jellyfin.Api.Auth.FirstTimeSetupOrElevatedPolicy; using Jellyfin.Api.Constants; using MediaBrowser.Common.Configuration; -using MediaBrowser.Model.Configuration; +using MediaBrowser.Controller.Library; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using Moq; using Xunit; @@ -18,12 +18,16 @@ namespace Jellyfin.Api.Tests.Auth.FirstTimeSetupOrElevatedPolicy private readonly Mock<IConfigurationManager> _configurationManagerMock; private readonly List<IAuthorizationRequirement> _requirements; private readonly FirstTimeSetupOrElevatedHandler _sut; + private readonly Mock<IUserManager> _userManagerMock; + private readonly Mock<IHttpContextAccessor> _httpContextAccessor; public FirstTimeSetupOrElevatedHandlerTests() { var fixture = new Fixture().Customize(new AutoMoqCustomization()); _configurationManagerMock = fixture.Freeze<Mock<IConfigurationManager>>(); _requirements = new List<IAuthorizationRequirement> { new FirstTimeSetupOrElevatedRequirement() }; + _userManagerMock = fixture.Freeze<Mock<IUserManager>>(); + _httpContextAccessor = fixture.Freeze<Mock<IHttpContextAccessor>>(); _sut = fixture.Create<FirstTimeSetupOrElevatedHandler>(); } @@ -34,9 +38,13 @@ namespace Jellyfin.Api.Tests.Auth.FirstTimeSetupOrElevatedPolicy [InlineData(UserRoles.User)] public async Task ShouldSucceedIfStartupWizardIncomplete(string userRole) { - SetupConfigurationManager(false); - var user = SetupUser(userRole); - var context = new AuthorizationHandlerContext(_requirements, user, null); + TestHelpers.SetupConfigurationManager(_configurationManagerMock, false); + var claims = TestHelpers.SetupUser( + _userManagerMock, + _httpContextAccessor, + userRole); + + var context = new AuthorizationHandlerContext(_requirements, claims, null); await _sut.HandleAsync(context); Assert.True(context.HasSucceeded); @@ -48,30 +56,16 @@ namespace Jellyfin.Api.Tests.Auth.FirstTimeSetupOrElevatedPolicy [InlineData(UserRoles.User, false)] public async Task ShouldRequireAdministratorIfStartupWizardComplete(string userRole, bool shouldSucceed) { - SetupConfigurationManager(true); - var user = SetupUser(userRole); - var context = new AuthorizationHandlerContext(_requirements, user, null); + TestHelpers.SetupConfigurationManager(_configurationManagerMock, true); + var claims = TestHelpers.SetupUser( + _userManagerMock, + _httpContextAccessor, + userRole); + + var context = new AuthorizationHandlerContext(_requirements, claims, null); await _sut.HandleAsync(context); Assert.Equal(shouldSucceed, context.HasSucceeded); } - - private static ClaimsPrincipal SetupUser(string role) - { - var claims = new[] { new Claim(ClaimTypes.Role, role) }; - var identity = new ClaimsIdentity(claims); - return new ClaimsPrincipal(identity); - } - - private void SetupConfigurationManager(bool startupWizardCompleted) - { - var commonConfiguration = new BaseApplicationConfiguration - { - IsStartupWizardCompleted = startupWizardCompleted - }; - - _configurationManagerMock.Setup(c => c.CommonConfiguration) - .Returns(commonConfiguration); - } } } diff --git a/tests/Jellyfin.Api.Tests/Auth/IgnoreSchedulePolicy/IgnoreScheduleHandlerTests.cs b/tests/Jellyfin.Api.Tests/Auth/IgnoreSchedulePolicy/IgnoreScheduleHandlerTests.cs new file mode 100644 index 000000000..7150c90bb --- /dev/null +++ b/tests/Jellyfin.Api.Tests/Auth/IgnoreSchedulePolicy/IgnoreScheduleHandlerTests.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using AutoFixture; +using AutoFixture.AutoMoq; +using Jellyfin.Api.Auth.IgnoreParentalControlPolicy; +using Jellyfin.Api.Constants; +using Jellyfin.Data.Entities; +using Jellyfin.Data.Enums; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Library; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Moq; +using Xunit; + +namespace Jellyfin.Api.Tests.Auth.IgnoreSchedulePolicy +{ + public class IgnoreScheduleHandlerTests + { + private readonly Mock<IConfigurationManager> _configurationManagerMock; + private readonly List<IAuthorizationRequirement> _requirements; + private readonly IgnoreParentalControlHandler _sut; + private readonly Mock<IUserManager> _userManagerMock; + private readonly Mock<IHttpContextAccessor> _httpContextAccessor; + + /// <summary> + /// Globally disallow access. + /// </summary> + private readonly AccessSchedule[] _accessSchedules = { new AccessSchedule(DynamicDayOfWeek.Everyday, 0, 0, Guid.Empty) }; + + public IgnoreScheduleHandlerTests() + { + var fixture = new Fixture().Customize(new AutoMoqCustomization()); + _configurationManagerMock = fixture.Freeze<Mock<IConfigurationManager>>(); + _requirements = new List<IAuthorizationRequirement> { new IgnoreParentalControlRequirement() }; + _userManagerMock = fixture.Freeze<Mock<IUserManager>>(); + _httpContextAccessor = fixture.Freeze<Mock<IHttpContextAccessor>>(); + + _sut = fixture.Create<IgnoreParentalControlHandler>(); + } + + [Theory] + [InlineData(UserRoles.Administrator, true)] + [InlineData(UserRoles.User, true)] + [InlineData(UserRoles.Guest, true)] + public async Task ShouldAllowScheduleCorrectly(string role, bool shouldSucceed) + { + TestHelpers.SetupConfigurationManager(_configurationManagerMock, true); + var claims = TestHelpers.SetupUser( + _userManagerMock, + _httpContextAccessor, + role, + _accessSchedules); + + var context = new AuthorizationHandlerContext(_requirements, claims, null); + + await _sut.HandleAsync(context); + Assert.Equal(shouldSucceed, context.HasSucceeded); + } + } +} diff --git a/tests/Jellyfin.Api.Tests/Auth/LocalAccessPolicy/LocalAccessHandlerTests.cs b/tests/Jellyfin.Api.Tests/Auth/LocalAccessPolicy/LocalAccessHandlerTests.cs new file mode 100644 index 000000000..09ffa8468 --- /dev/null +++ b/tests/Jellyfin.Api.Tests/Auth/LocalAccessPolicy/LocalAccessHandlerTests.cs @@ -0,0 +1,58 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using AutoFixture; +using AutoFixture.AutoMoq; +using Jellyfin.Api.Auth.LocalAccessPolicy; +using Jellyfin.Api.Constants; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Library; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Moq; +using Xunit; + +namespace Jellyfin.Api.Tests.Auth.LocalAccessPolicy +{ + public class LocalAccessHandlerTests + { + private readonly Mock<IConfigurationManager> _configurationManagerMock; + private readonly List<IAuthorizationRequirement> _requirements; + private readonly LocalAccessHandler _sut; + private readonly Mock<IUserManager> _userManagerMock; + private readonly Mock<IHttpContextAccessor> _httpContextAccessor; + private readonly Mock<INetworkManager> _networkManagerMock; + + public LocalAccessHandlerTests() + { + var fixture = new Fixture().Customize(new AutoMoqCustomization()); + _configurationManagerMock = fixture.Freeze<Mock<IConfigurationManager>>(); + _requirements = new List<IAuthorizationRequirement> { new LocalAccessRequirement() }; + _userManagerMock = fixture.Freeze<Mock<IUserManager>>(); + _httpContextAccessor = fixture.Freeze<Mock<IHttpContextAccessor>>(); + _networkManagerMock = fixture.Freeze<Mock<INetworkManager>>(); + + _sut = fixture.Create<LocalAccessHandler>(); + } + + [Theory] + [InlineData(true, true)] + [InlineData(false, false)] + public async Task LocalAccessOnly(bool isInLocalNetwork, bool shouldSucceed) + { + _networkManagerMock + .Setup(n => n.IsInLocalNetwork(It.IsAny<string>())) + .Returns(isInLocalNetwork); + + TestHelpers.SetupConfigurationManager(_configurationManagerMock, true); + var claims = TestHelpers.SetupUser( + _userManagerMock, + _httpContextAccessor, + UserRoles.User); + + var context = new AuthorizationHandlerContext(_requirements, claims, null); + await _sut.HandleAsync(context); + Assert.Equal(shouldSucceed, context.HasSucceeded); + } + } +} diff --git a/tests/Jellyfin.Api.Tests/Auth/RequiresElevationPolicy/RequiresElevationHandlerTests.cs b/tests/Jellyfin.Api.Tests/Auth/RequiresElevationPolicy/RequiresElevationHandlerTests.cs index cd05a8328..ffe88fcde 100644 --- a/tests/Jellyfin.Api.Tests/Auth/RequiresElevationPolicy/RequiresElevationHandlerTests.cs +++ b/tests/Jellyfin.Api.Tests/Auth/RequiresElevationPolicy/RequiresElevationHandlerTests.cs @@ -1,20 +1,35 @@ using System.Collections.Generic; -using System.Security.Claims; using System.Threading.Tasks; +using AutoFixture; +using AutoFixture.AutoMoq; using Jellyfin.Api.Auth.RequiresElevationPolicy; using Jellyfin.Api.Constants; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Library; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Moq; using Xunit; namespace Jellyfin.Api.Tests.Auth.RequiresElevationPolicy { public class RequiresElevationHandlerTests { + private readonly Mock<IConfigurationManager> _configurationManagerMock; + private readonly List<IAuthorizationRequirement> _requirements; private readonly RequiresElevationHandler _sut; + private readonly Mock<IUserManager> _userManagerMock; + private readonly Mock<IHttpContextAccessor> _httpContextAccessor; public RequiresElevationHandlerTests() { - _sut = new RequiresElevationHandler(); + var fixture = new Fixture().Customize(new AutoMoqCustomization()); + _configurationManagerMock = fixture.Freeze<Mock<IConfigurationManager>>(); + _requirements = new List<IAuthorizationRequirement> { new RequiresElevationRequirement() }; + _userManagerMock = fixture.Freeze<Mock<IUserManager>>(); + _httpContextAccessor = fixture.Freeze<Mock<IHttpContextAccessor>>(); + + _sut = fixture.Create<RequiresElevationHandler>(); } [Theory] @@ -23,13 +38,13 @@ namespace Jellyfin.Api.Tests.Auth.RequiresElevationPolicy [InlineData(UserRoles.Guest, false)] public async Task ShouldHandleRolesCorrectly(string role, bool shouldSucceed) { - var requirements = new List<IAuthorizationRequirement> { new RequiresElevationRequirement() }; - - var claims = new[] { new Claim(ClaimTypes.Role, role) }; - var identity = new ClaimsIdentity(claims); - var user = new ClaimsPrincipal(identity); + TestHelpers.SetupConfigurationManager(_configurationManagerMock, true); + var claims = TestHelpers.SetupUser( + _userManagerMock, + _httpContextAccessor, + role); - var context = new AuthorizationHandlerContext(requirements, user, null); + var context = new AuthorizationHandlerContext(_requirements, claims, null); await _sut.HandleAsync(context); Assert.Equal(shouldSucceed, context.HasSucceeded); diff --git a/tests/MediaBrowser.Api.Tests/BrandingServiceTests.cs b/tests/Jellyfin.Api.Tests/BrandingServiceTests.cs index 34698fe25..6fc287420 100644 --- a/tests/MediaBrowser.Api.Tests/BrandingServiceTests.cs +++ b/tests/Jellyfin.Api.Tests/BrandingServiceTests.cs @@ -3,7 +3,7 @@ using System.Threading.Tasks; using MediaBrowser.Model.Branding; using Xunit; -namespace MediaBrowser.Api.Tests +namespace Jellyfin.Api.Tests { public sealed class BrandingServiceTests : IClassFixture<JellyfinApplicationFactory> { @@ -43,7 +43,7 @@ namespace MediaBrowser.Api.Tests // Assert response.EnsureSuccessStatusCode(); - Assert.Equal("text/css", response.Content.Headers.ContentType.ToString()); + Assert.Equal("text/css; charset=utf-8", response.Content.Headers.ContentType.ToString()); } } } diff --git a/tests/Jellyfin.Api.Tests/GetPathValueTests.cs b/tests/Jellyfin.Api.Tests/GetPathValueTests.cs deleted file mode 100644 index b01d1af1f..000000000 --- a/tests/Jellyfin.Api.Tests/GetPathValueTests.cs +++ /dev/null @@ -1,45 +0,0 @@ -using MediaBrowser.Api; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Net; -using MediaBrowser.Model.Configuration; -using MediaBrowser.Model.Services; -using Microsoft.Extensions.Logging.Abstractions; -using Moq; -using Xunit; - -namespace Jellyfin.Api.Tests -{ - public class GetPathValueTests - { - [Theory] - [InlineData("https://localhost:8096/ScheduledTasks/1234/Triggers", "", 1, "1234")] - [InlineData("https://localhost:8096/emby/ScheduledTasks/1234/Triggers", "", 1, "1234")] - [InlineData("https://localhost:8096/mediabrowser/ScheduledTasks/1234/Triggers", "", 1, "1234")] - [InlineData("https://localhost:8096/jellyfin/2/ScheduledTasks/1234/Triggers", "jellyfin/2", 1, "1234")] - [InlineData("https://localhost:8096/jellyfin/2/emby/ScheduledTasks/1234/Triggers", "jellyfin/2", 1, "1234")] - [InlineData("https://localhost:8096/jellyfin/2/mediabrowser/ScheduledTasks/1234/Triggers", "jellyfin/2", 1, "1234")] - [InlineData("https://localhost:8096/JELLYFIN/2/ScheduledTasks/1234/Triggers", "jellyfin/2", 1, "1234")] - [InlineData("https://localhost:8096/JELLYFIN/2/Emby/ScheduledTasks/1234/Triggers", "jellyfin/2", 1, "1234")] - [InlineData("https://localhost:8096/JELLYFIN/2/MediaBrowser/ScheduledTasks/1234/Triggers", "jellyfin/2", 1, "1234")] - public void GetPathValueTest(string path, string baseUrl, int index, string value) - { - var reqMock = Mock.Of<IRequest>(x => x.PathInfo == path); - var conf = new ServerConfiguration() - { - BaseUrl = baseUrl - }; - - var confManagerMock = Mock.Of<IServerConfigurationManager>(x => x.Configuration == conf); - - var service = new BrandingService( - new NullLogger<BrandingService>(), - confManagerMock, - Mock.Of<IHttpResultFactory>()) - { - Request = reqMock - }; - - Assert.Equal(value, service.GetPathValue(index).ToString()); - } - } -} diff --git a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj index d8c764c67..bcba3a203 100644 --- a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj +++ b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj @@ -13,15 +13,16 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="AutoFixture" Version="4.11.0" /> - <PackageReference Include="AutoFixture.AutoMoq" Version="4.11.0" /> - <PackageReference Include="AutoFixture.Xunit2" Version="4.11.0" /> - <PackageReference Include="Microsoft.Extensions.Options" Version="3.1.5" /> - <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" /> + <PackageReference Include="AutoFixture" Version="4.13.0" /> + <PackageReference Include="AutoFixture.AutoMoq" Version="4.13.0" /> + <PackageReference Include="AutoFixture.Xunit2" Version="4.13.0" /> + <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="3.1.7" /> + <PackageReference Include="Microsoft.Extensions.Options" Version="3.1.7" /> + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" /> <PackageReference Include="xunit" Version="2.4.1" /> - <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" /> + <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" /> <PackageReference Include="coverlet.collector" Version="1.3.0" /> - <PackageReference Include="Moq" Version="4.14.1" /> + <PackageReference Include="Moq" Version="4.14.5" /> </ItemGroup> <!-- Code Analyzers --> @@ -33,8 +34,7 @@ </ItemGroup> <ItemGroup> - <ProjectReference Include="../../MediaBrowser.Api/MediaBrowser.Api.csproj" /> - <ProjectReference Include="../../Jellyfin.Api/Jellyfin.Api.csproj" /> + <ProjectReference Include="..\..\Jellyfin.Server\Jellyfin.Server.csproj" /> </ItemGroup> <PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> diff --git a/tests/MediaBrowser.Api.Tests/JellyfinApplicationFactory.cs b/tests/Jellyfin.Api.Tests/JellyfinApplicationFactory.cs index c39ed07de..77f1640fa 100644 --- a/tests/MediaBrowser.Api.Tests/JellyfinApplicationFactory.cs +++ b/tests/Jellyfin.Api.Tests/JellyfinApplicationFactory.cs @@ -15,7 +15,7 @@ using Microsoft.Extensions.Logging; using Serilog; using Serilog.Extensions.Logging; -namespace MediaBrowser.Api.Tests +namespace Jellyfin.Api.Tests { /// <summary> /// Factory for bootstrapping the Jellyfin application in memory for functional end to end tests. @@ -72,6 +72,7 @@ namespace MediaBrowser.Api.Tests var startupConfig = Program.CreateAppConfiguration(commandLineOpts, appPaths); ILoggerFactory loggerFactory = new SerilogLoggerFactory(); + var serviceCollection = new ServiceCollection(); _disposableComponents.Add(loggerFactory); // Create the app host and initialize it @@ -80,10 +81,10 @@ namespace MediaBrowser.Api.Tests loggerFactory, commandLineOpts, new ManagedFileSystem(loggerFactory.CreateLogger<ManagedFileSystem>(), appPaths), - new NetworkManager(loggerFactory.CreateLogger<NetworkManager>())); + new NetworkManager(loggerFactory.CreateLogger<NetworkManager>()), + serviceCollection); _disposableComponents.Add(appHost); - var serviceCollection = new ServiceCollection(); - appHost.Init(serviceCollection); + appHost.Init(); // Configure the web host builder Program.ConfigureWebHostBuilder(builder, appHost, serviceCollection, commandLineOpts, startupConfig, appPaths); diff --git a/tests/Jellyfin.Api.Tests/OpenApiSpecTests.cs b/tests/Jellyfin.Api.Tests/OpenApiSpecTests.cs new file mode 100644 index 000000000..3a85b5514 --- /dev/null +++ b/tests/Jellyfin.Api.Tests/OpenApiSpecTests.cs @@ -0,0 +1,42 @@ +using System.IO; +using System.Reflection; +using System.Text.Json; +using System.Threading.Tasks; +using MediaBrowser.Model.Branding; +using Xunit; +using Xunit.Abstractions; + +namespace Jellyfin.Api.Tests +{ + public sealed class OpenApiSpecTests : IClassFixture<JellyfinApplicationFactory> + { + private readonly JellyfinApplicationFactory _factory; + private readonly ITestOutputHelper _outputHelper; + + public OpenApiSpecTests(JellyfinApplicationFactory factory, ITestOutputHelper outputHelper) + { + _factory = factory; + _outputHelper = outputHelper; + } + + [Fact] + public async Task GetSpec_ReturnsCorrectResponse() + { + // Arrange + var client = _factory.CreateClient(); + + // Act + var response = await client.GetAsync("/api-docs/openapi.json"); + + // Assert + response.EnsureSuccessStatusCode(); + Assert.Equal("application/json; charset=utf-8", response.Content.Headers.ContentType.ToString()); + + // Write out for publishing + var responseBody = await response.Content.ReadAsStringAsync(); + string outputPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? ".", "openapi.json")); + _outputHelper.WriteLine("Writing OpenAPI Spec JSON to '{0}'.", outputPath); + File.WriteAllText(outputPath, responseBody); + } + } +} diff --git a/tests/Jellyfin.Api.Tests/TestHelpers.cs b/tests/Jellyfin.Api.Tests/TestHelpers.cs new file mode 100644 index 000000000..a4dd4e409 --- /dev/null +++ b/tests/Jellyfin.Api.Tests/TestHelpers.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Net; +using System.Security.Claims; +using Jellyfin.Api.Constants; +using Jellyfin.Data.Entities; +using Jellyfin.Data.Enums; +using Jellyfin.Server.Implementations.Users; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Configuration; +using Microsoft.AspNetCore.Http; +using Moq; +using AccessSchedule = Jellyfin.Data.Entities.AccessSchedule; + +namespace Jellyfin.Api.Tests +{ + public static class TestHelpers + { + public static ClaimsPrincipal SetupUser( + Mock<IUserManager> userManagerMock, + Mock<IHttpContextAccessor> httpContextAccessorMock, + string role, + IEnumerable<AccessSchedule>? accessSchedules = null) + { + var user = new User( + "jellyfin", + typeof(DefaultAuthenticationProvider).FullName, + typeof(DefaultPasswordResetProvider).FullName); + + // Set administrator flag. + user.SetPermission(PermissionKind.IsAdministrator, role.Equals(UserRoles.Administrator, StringComparison.OrdinalIgnoreCase)); + + // Add access schedules if set. + if (accessSchedules != null) + { + foreach (var accessSchedule in accessSchedules) + { + user.AccessSchedules.Add(accessSchedule); + } + } + + var claims = new[] + { + new Claim(ClaimTypes.Role, role), + new Claim(ClaimTypes.Name, "jellyfin"), + new Claim(InternalClaimTypes.UserId, Guid.Empty.ToString("N", CultureInfo.InvariantCulture)), + new Claim(InternalClaimTypes.DeviceId, Guid.Empty.ToString("N", CultureInfo.InvariantCulture)), + new Claim(InternalClaimTypes.Device, "test"), + new Claim(InternalClaimTypes.Client, "test"), + new Claim(InternalClaimTypes.Version, "test"), + new Claim(InternalClaimTypes.Token, "test"), + }; + + var identity = new ClaimsIdentity(claims); + + userManagerMock + .Setup(u => u.GetUserById(It.IsAny<Guid>())) + .Returns(user); + + httpContextAccessorMock + .Setup(h => h.HttpContext.Connection.RemoteIpAddress) + .Returns(new IPAddress(0)); + + return new ClaimsPrincipal(identity); + } + + public static void SetupConfigurationManager(in Mock<IConfigurationManager> configurationManagerMock, bool startupWizardCompleted) + { + var commonConfiguration = new BaseApplicationConfiguration + { + IsStartupWizardCompleted = startupWizardCompleted + }; + + configurationManagerMock + .Setup(c => c.CommonConfiguration) + .Returns(commonConfiguration); + } + } +} diff --git a/tests/Jellyfin.Common.Tests/Jellyfin.Common.Tests.csproj b/tests/Jellyfin.Common.Tests/Jellyfin.Common.Tests.csproj index 4cb1da994..e3f87d29b 100644 --- a/tests/Jellyfin.Common.Tests/Jellyfin.Common.Tests.csproj +++ b/tests/Jellyfin.Common.Tests/Jellyfin.Common.Tests.csproj @@ -13,9 +13,9 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" /> + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" /> <PackageReference Include="xunit" Version="2.4.1" /> - <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" /> + <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" /> <PackageReference Include="coverlet.collector" Version="1.3.0" /> </ItemGroup> diff --git a/tests/Jellyfin.Controller.Tests/Jellyfin.Controller.Tests.csproj b/tests/Jellyfin.Controller.Tests/Jellyfin.Controller.Tests.csproj index 18724f31c..5de02a29b 100644 --- a/tests/Jellyfin.Controller.Tests/Jellyfin.Controller.Tests.csproj +++ b/tests/Jellyfin.Controller.Tests/Jellyfin.Controller.Tests.csproj @@ -13,9 +13,9 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" /> + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" /> <PackageReference Include="xunit" Version="2.4.1" /> - <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" /> + <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" /> <PackageReference Include="coverlet.collector" Version="1.3.0" /> </ItemGroup> diff --git a/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTests.cs b/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTests.cs index af29fec87..39fd8afda 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTests.cs +++ b/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTests.cs @@ -13,14 +13,18 @@ namespace Jellyfin.MediaEncoding.Tests [ClassData(typeof(GetFFmpegVersionTestData))] public void GetFFmpegVersionTest(string versionOutput, Version? version) { - Assert.Equal(version, EncoderValidator.GetFFmpegVersion(versionOutput)); + var val = new EncoderValidator(new NullLogger<EncoderValidatorTests>()); + Assert.Equal(version, val.GetFFmpegVersion(versionOutput)); } [Theory] + [InlineData(EncoderValidatorTestsData.FFmpegV431Output, true)] + [InlineData(EncoderValidatorTestsData.FFmpegV43Output, true)] [InlineData(EncoderValidatorTestsData.FFmpegV421Output, true)] [InlineData(EncoderValidatorTestsData.FFmpegV42Output, true)] [InlineData(EncoderValidatorTestsData.FFmpegV414Output, true)] [InlineData(EncoderValidatorTestsData.FFmpegV404Output, true)] + [InlineData(EncoderValidatorTestsData.FFmpegGitUnknownOutput2, true)] [InlineData(EncoderValidatorTestsData.FFmpegGitUnknownOutput, false)] public void ValidateVersionInternalTest(string versionOutput, bool valid) { @@ -32,10 +36,13 @@ namespace Jellyfin.MediaEncoding.Tests { public IEnumerator<object?[]> GetEnumerator() { + yield return new object?[] { EncoderValidatorTestsData.FFmpegV431Output, new Version(4, 3, 1) }; + yield return new object?[] { EncoderValidatorTestsData.FFmpegV43Output, new Version(4, 3) }; yield return new object?[] { EncoderValidatorTestsData.FFmpegV421Output, new Version(4, 2, 1) }; yield return new object?[] { EncoderValidatorTestsData.FFmpegV42Output, new Version(4, 2) }; yield return new object?[] { EncoderValidatorTestsData.FFmpegV414Output, new Version(4, 1, 4) }; yield return new object?[] { EncoderValidatorTestsData.FFmpegV404Output, new Version(4, 0, 4) }; + yield return new object?[] { EncoderValidatorTestsData.FFmpegGitUnknownOutput2, new Version(4, 0) }; yield return new object?[] { EncoderValidatorTestsData.FFmpegGitUnknownOutput, null }; } diff --git a/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTestsData.cs b/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTestsData.cs index c46c9578b..9f5bef9a8 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTestsData.cs +++ b/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTestsData.cs @@ -2,6 +2,30 @@ namespace Jellyfin.MediaEncoding.Tests { internal static class EncoderValidatorTestsData { + public const string FFmpegV431Output = @"ffmpeg version n4.3.1 Copyright (c) 2000-2020 the FFmpeg developers +built with gcc 10.1.0 (GCC) +configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-avisynth --enable-fontconfig --enable-gmp --enable-gnutls --enable-gpl --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libdav1d --enable-libdrm --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libiec61883 --enable-libjack --enable-libmfx --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librav1e --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxcb --enable-libxml2 --enable-libxvid --enable-nvdec --enable-nvenc --enable-omx --enable-shared --enable-version3 +libavutil 56. 51.100 / 56. 51.100 +libavcodec 58. 91.100 / 58. 91.100 +libavformat 58. 45.100 / 58. 45.100 +libavdevice 58. 10.100 / 58. 10.100 +libavfilter 7. 85.100 / 7. 85.100 +libswscale 5. 7.100 / 5. 7.100 +libswresample 3. 7.100 / 3. 7.100 +libpostproc 55. 7.100 / 55. 7.100"; + + public const string FFmpegV43Output = @"ffmpeg version 4.3 Copyright (c) 2000-2020 the FFmpeg developers +built with gcc 7 (Ubuntu 7.5.0-3ubuntu1~18.04) +configuration: --prefix=/usr/lib/jellyfin-ffmpeg --target-os=linux --disable-doc --disable-ffplay --disable-shared --disable-libxcb --disable-vdpau --disable-sdl2 --disable-xlib --enable-gpl --enable-version3 --enable-static --enable-libfontconfig --enable-fontconfig --enable-gmp --enable-gnutls --enable-libass --enable-libbluray --enable-libdrm --enable-libfreetype --enable-libfribidi --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libwebp --enable-libx264 --enable-libx265 --enable-libzvbi --arch=amd64 --enable-amf --enable-nvenc --enable-nvdec --enable-vaapi --enable-opencl +libavutil 56. 51.100 / 56. 51.100 +libavcodec 58. 91.100 / 58. 91.100 +libavformat 58. 45.100 / 58. 45.100 +libavdevice 58. 10.100 / 58. 10.100 +libavfilter 7. 85.100 / 7. 85.100 +libswscale 5. 7.100 / 5. 7.100 +libswresample 3. 7.100 / 3. 7.100 +libpostproc 55. 7.100 / 55. 7.100"; + public const string FFmpegV421Output = @"ffmpeg version 4.2.1 Copyright (c) 2000-2019 the FFmpeg developers built with gcc 9.1.1 (GCC) 20190807 configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt @@ -51,7 +75,7 @@ libswscale 5. 1.100 / 5. 1.100 libswresample 3. 1.100 / 3. 1.100 libpostproc 55. 1.100 / 55. 1.100"; - public const string FFmpegGitUnknownOutput = @"ffmpeg version N-94303-g7cb4f8c962 Copyright (c) 2000-2019 the FFmpeg developers + public const string FFmpegGitUnknownOutput2 = @"ffmpeg version N-94303-g7cb4f8c962 Copyright (c) 2000-2019 the FFmpeg developers built with gcc 9.1.1 (GCC) 20190716 configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt libavutil 56. 30.100 / 56. 30.100 @@ -62,5 +86,17 @@ libavfilter 7. 56.101 / 7. 56.101 libswscale 5. 4.101 / 5. 4.101 libswresample 3. 4.100 / 3. 4.100 libpostproc 55. 4.100 / 55. 4.100"; + + public const string FFmpegGitUnknownOutput = @"ffmpeg version N-45325-gb173e0353-static https://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2018 the FFmpeg developers +built with gcc 6.3.0 (Debian 6.3.0-18+deb9u1) 20170516 +configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-6 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gray --enable-libfribidi --enable-libass --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libzimg +libavutil 56. 9.100 / 56. 9.100 +libavcodec 58. 14.100 / 58. 14.100 +libavformat 58. 10.100 / 58. 10.100 +libavdevice 58. 2.100 / 58. 2.100 +libavfilter 7. 13.100 / 7. 13.100 +libswscale 5. 0.102 / 5. 0.102 +libswresample 3. 0.101 / 3. 0.101 +libpostproc 55. 0.100 / 55. 0.100"; } } diff --git a/tests/Jellyfin.MediaEncoding.Tests/FFprobeParserTests.cs b/tests/Jellyfin.MediaEncoding.Tests/FFprobeParserTests.cs index 2032f6cec..c39ef0ce9 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/FFprobeParserTests.cs +++ b/tests/Jellyfin.MediaEncoding.Tests/FFprobeParserTests.cs @@ -1,6 +1,7 @@ using System.IO; using System.Text.Json; using System.Threading.Tasks; +using MediaBrowser.Common.Json; using MediaBrowser.MediaEncoding.Probing; using Xunit; @@ -15,7 +16,7 @@ namespace Jellyfin.MediaEncoding.Tests var path = Path.Join("Test Data", fileName); using (var stream = File.OpenRead(path)) { - await JsonSerializer.DeserializeAsync<InternalMediaInfoResult>(stream).ConfigureAwait(false); + await JsonSerializer.DeserializeAsync<InternalMediaInfoResult>(stream, JsonDefaults.GetOptions()).ConfigureAwait(false); } } } diff --git a/tests/Jellyfin.MediaEncoding.Tests/Jellyfin.MediaEncoding.Tests.csproj b/tests/Jellyfin.MediaEncoding.Tests/Jellyfin.MediaEncoding.Tests.csproj index 646ef00fd..3ac60819b 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/Jellyfin.MediaEncoding.Tests.csproj +++ b/tests/Jellyfin.MediaEncoding.Tests/Jellyfin.MediaEncoding.Tests.csproj @@ -19,9 +19,9 @@ </ItemGroup> <ItemGroup> - <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" /> + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" /> <PackageReference Include="xunit" Version="2.4.1" /> - <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" /> + <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" /> <PackageReference Include="coverlet.collector" Version="1.3.0" /> </ItemGroup> diff --git a/tests/Jellyfin.Naming.Tests/Jellyfin.Naming.Tests.csproj b/tests/Jellyfin.Naming.Tests/Jellyfin.Naming.Tests.csproj index 1434cce96..37d0a9929 100644 --- a/tests/Jellyfin.Naming.Tests/Jellyfin.Naming.Tests.csproj +++ b/tests/Jellyfin.Naming.Tests/Jellyfin.Naming.Tests.csproj @@ -13,9 +13,9 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" /> + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" /> <PackageReference Include="xunit" Version="2.4.1" /> - <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" /> + <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" /> <PackageReference Include="coverlet.collector" Version="1.3.0" /> </ItemGroup> diff --git a/tests/Jellyfin.Naming.Tests/Video/CleanDateTimeTests.cs b/tests/Jellyfin.Naming.Tests/Video/CleanDateTimeTests.cs index 917d8fb3a..ed971eed7 100644 --- a/tests/Jellyfin.Naming.Tests/Video/CleanDateTimeTests.cs +++ b/tests/Jellyfin.Naming.Tests/Video/CleanDateTimeTests.cs @@ -47,6 +47,10 @@ namespace Jellyfin.Naming.Tests.Video // FIXME: [InlineData("Robin Hood [Multi-Subs] [2018].mkv", "Robin Hood", 2018)] [InlineData(@"3.Days.to.Kill.2014.720p.BluRay.x264.YIFY.mkv", "3.Days.to.Kill", 2014)] // In this test case, running CleanDateTime first produces no date, so it will attempt to run CleanString first and then CleanDateTime again [InlineData("3 days to kill (2005).mkv", "3 days to kill", 2005)] + [InlineData("My Movie 2013.12.09", "My Movie 2013.12.09", null)] + [InlineData("My Movie 2013-12-09", "My Movie 2013-12-09", null)] + [InlineData("My Movie 20131209", "My Movie 20131209", null)] + [InlineData("My Movie 2013-12-09 2013", "My Movie 2013-12-09", 2013)] public void CleanDateTimeTest(string input, string expectedName, int? expectedYear) { input = Path.GetFileName(input); diff --git a/tests/Jellyfin.Server.Implementations.Tests/HttpServer/ResponseFilterTests.cs b/tests/Jellyfin.Server.Implementations.Tests/HttpServer/ResponseFilterTests.cs deleted file mode 100644 index 39bd94b59..000000000 --- a/tests/Jellyfin.Server.Implementations.Tests/HttpServer/ResponseFilterTests.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Emby.Server.Implementations.HttpServer; -using Xunit; - -namespace Jellyfin.Server.Implementations.Tests.HttpServer -{ - public class ResponseFilterTests - { - [Theory] - [InlineData(null, null)] - [InlineData("", "")] - [InlineData("This is a clean string.", "This is a clean string.")] - [InlineData("This isn't \n\ra clean string.", "This isn't a clean string.")] - public void RemoveControlCharacters_ValidArgs_Correct(string? input, string? result) - { - Assert.Equal(result, ResponseFilter.RemoveControlCharacters(input)); - } - } -} diff --git a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj index 2e6caba07..d1679c279 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj +++ b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj @@ -14,11 +14,12 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="AutoFixture" Version="4.11.0" /> - <PackageReference Include="AutoFixture.AutoMoq" Version="4.11.0" /> - <PackageReference Include="Moq" Version="4.14.1" /> + <PackageReference Include="AutoFixture" Version="4.13.0" /> + <PackageReference Include="AutoFixture.AutoMoq" Version="4.13.0" /> + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" /> + <PackageReference Include="Moq" Version="4.14.5" /> <PackageReference Include="xunit" Version="2.4.1" /> - <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" /> + <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" /> <PackageReference Include="coverlet.collector" Version="1.3.0" /> </ItemGroup> diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/IgnorePatternsTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/IgnorePatternsTests.cs index 26dee38c6..09eb22328 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Library/IgnorePatternsTests.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/Library/IgnorePatternsTests.cs @@ -7,12 +7,30 @@ namespace Jellyfin.Server.Implementations.Tests.Library { [Theory] [InlineData("/media/small.jpg", true)] + [InlineData("/media/albumart.jpg", true)] + [InlineData("/media/movie.sample.mp4", true)] + [InlineData("/media/movie/sample.mp4", true)] + [InlineData("/media/movie/sample/movie.mp4", true)] + [InlineData("/foo/sample/bar/baz.mkv", false)] + [InlineData("/media/movies/the sample/the sample.mkv", false)] + [InlineData("/media/movies/sampler.mkv", false)] [InlineData("/media/movies/#Recycle/test.txt", true)] [InlineData("/media/movies/#recycle/", true)] + [InlineData("/media/movies/#recycle", true)] [InlineData("thumbs.db", true)] [InlineData(@"C:\media\movies\movie.avi", false)] - [InlineData("/media/.hiddendir/file.mp4", true)] + [InlineData("/media/.hiddendir/file.mp4", false)] [InlineData("/media/dir/.hiddenfile.mp4", true)] + [InlineData("/media/dir/._macjunk.mp4", true)] + [InlineData("/volume1/video/Series/@eaDir", true)] + [InlineData("/volume1/video/Series/@eaDir/file.txt", true)] + [InlineData("/directory/@Recycle", true)] + [InlineData("/directory/@Recycle/file.mp3", true)] + [InlineData("/media/movies/.@__thumb", true)] + [InlineData("/media/movies/.@__thumb/foo-bar-thumbnail.png", true)] + [InlineData("/media/music/Foo B.A.R./epic.flac", false)] + [InlineData("/media/music/Foo B.A.R", false)] + [InlineData("/media/music/Foo B.A.R.", false)] public void PathIgnored(string path, bool expected) { Assert.Equal(expected, IgnorePatterns.ShouldIgnore(path)); diff --git a/tests/MediaBrowser.Api.Tests/MediaBrowser.Api.Tests.csproj b/tests/MediaBrowser.Api.Tests/MediaBrowser.Api.Tests.csproj deleted file mode 100644 index a767c0039..000000000 --- a/tests/MediaBrowser.Api.Tests/MediaBrowser.Api.Tests.csproj +++ /dev/null @@ -1,35 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk"> - - <PropertyGroup> - <TargetFramework>netcoreapp3.1</TargetFramework> - <IsPackable>false</IsPackable> - <TreatWarningsAsErrors>true</TreatWarningsAsErrors> - <Nullable>enable</Nullable> - </PropertyGroup> - - <ItemGroup> - <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="3.1.5" /> - <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" /> - <PackageReference Include="xunit" Version="2.4.1" /> - <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" /> - <PackageReference Include="coverlet.collector" Version="1.3.0" /> - </ItemGroup> - - <ItemGroup> - <ProjectReference Include="..\..\Jellyfin.Server\Jellyfin.Server.csproj" /> - <ProjectReference Include="..\..\MediaBrowser.Api\MediaBrowser.Api.csproj" /> - </ItemGroup> - - <!-- Code Analyzers --> - <ItemGroup Condition=" '$(Configuration)' == 'Debug' "> - <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8" PrivateAssets="All" /> - <PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" /> - <PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" /> - <PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" /> - </ItemGroup> - - <PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> - <CodeAnalysisRuleSet>../jellyfin-tests.ruleset</CodeAnalysisRuleSet> - </PropertyGroup> - -</Project> diff --git a/tests/jellyfin-tests.ruleset b/tests/jellyfin-tests.ruleset index 5a113e955..e2abaf5bb 100644 --- a/tests/jellyfin-tests.ruleset +++ b/tests/jellyfin-tests.ruleset @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<RuleSet Name="Rules for MediaBrowser.Api.Tests" Description="Code analysis rules for MediaBrowser.Api.Tests.csproj" ToolsVersion="14.0"> +<RuleSet Name="Rules for Jellyfin.Api.Tests" Description="Code analysis rules for Jellyfin.Api.Tests.csproj" ToolsVersion="14.0"> <!-- Include the solution default RuleSet. The rules in this file will override the defaults. --> <Include Path="../jellyfin.ruleset" Action="Default" /> @@ -17,6 +17,6 @@ <!-- CA2007: Consider calling ConfigureAwait on the awaited task --> <Rule Id="CA2007" Action="None" /> <!-- CA2234: Pass system uri objects instead of strings --> - <Rule Id="CA2234" Action="Info" /> + <Rule Id="CA2234" Action="Info" /> </Rules> </RuleSet> |
