aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Jellyfin.Api.Tests/Auth/CustomAuthenticationHandlerTests.cs2
-rw-r--r--tests/Jellyfin.Api.Tests/TestHelpers.cs7
-rw-r--r--tests/Jellyfin.Common.Tests/Crc32Tests.cs33
-rw-r--r--tests/Jellyfin.Common.Tests/Json/JsonStringConverterTests.cs39
-rw-r--r--tests/Jellyfin.MediaEncoding.Tests/FFprobeParserTests.cs2
-rw-r--r--tests/Jellyfin.Naming.Tests/Video/CleanStringTests.cs36
-rw-r--r--tests/Jellyfin.Naming.Tests/Video/MultiVersionTests.cs45
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs65
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/Library/PathExtensionsTests.cs6
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/LiveTv/HdHomerunManagerTests.cs58
-rw-r--r--tests/Jellyfin.Server.Integration.Tests/Controllers/DashboardControllerTests.cs2
-rw-r--r--tests/Jellyfin.Server.Integration.Tests/Controllers/StartupControllerTests.cs119
-rw-r--r--tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj2
-rw-r--r--tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj7
14 files changed, 390 insertions, 33 deletions
diff --git a/tests/Jellyfin.Api.Tests/Auth/CustomAuthenticationHandlerTests.cs b/tests/Jellyfin.Api.Tests/Auth/CustomAuthenticationHandlerTests.cs
index ee20cc573..de03aa5f5 100644
--- a/tests/Jellyfin.Api.Tests/Auth/CustomAuthenticationHandlerTests.cs
+++ b/tests/Jellyfin.Api.Tests/Auth/CustomAuthenticationHandlerTests.cs
@@ -128,6 +128,8 @@ namespace Jellyfin.Api.Tests.Auth
{
var authorizationInfo = _fixture.Create<AuthorizationInfo>();
authorizationInfo.User = _fixture.Create<User>();
+ authorizationInfo.User.AddDefaultPermissions();
+ authorizationInfo.User.AddDefaultPreferences();
authorizationInfo.User.SetPermission(PermissionKind.IsAdministrator, isAdmin);
authorizationInfo.IsApiKey = false;
diff --git a/tests/Jellyfin.Api.Tests/TestHelpers.cs b/tests/Jellyfin.Api.Tests/TestHelpers.cs
index f27cdf7b6..f9bca4146 100644
--- a/tests/Jellyfin.Api.Tests/TestHelpers.cs
+++ b/tests/Jellyfin.Api.Tests/TestHelpers.cs
@@ -26,8 +26,11 @@ namespace Jellyfin.Api.Tests
{
var user = new User(
"jellyfin",
- typeof(DefaultAuthenticationProvider).FullName,
- typeof(DefaultPasswordResetProvider).FullName);
+ typeof(DefaultAuthenticationProvider).FullName!,
+ typeof(DefaultPasswordResetProvider).FullName!);
+
+ user.AddDefaultPermissions();
+ user.AddDefaultPreferences();
// Set administrator flag.
user.SetPermission(PermissionKind.IsAdministrator, role.Equals(UserRoles.Administrator, StringComparison.OrdinalIgnoreCase));
diff --git a/tests/Jellyfin.Common.Tests/Crc32Tests.cs b/tests/Jellyfin.Common.Tests/Crc32Tests.cs
new file mode 100644
index 000000000..e95a2867f
--- /dev/null
+++ b/tests/Jellyfin.Common.Tests/Crc32Tests.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Text;
+using MediaBrowser.Common;
+using Xunit;
+
+namespace Jellyfin.Common.Tests
+{
+ public static class Crc32Tests
+ {
+ [Fact]
+ public static void Compute_Empty_Zero()
+ {
+ Assert.Equal<uint>(0, Crc32.Compute(Array.Empty<byte>()));
+ }
+
+ [Theory]
+ [InlineData(0x414fa339, "The quick brown fox jumps over the lazy dog")]
+ public static void Compute_Valid_Success(uint expected, string data)
+ {
+ Assert.Equal(expected, Crc32.Compute(Encoding.UTF8.GetBytes(data)));
+ }
+
+ [Theory]
+ [InlineData(0x414fa339, "54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F67")]
+ [InlineData(0x190a55ad, "0000000000000000000000000000000000000000000000000000000000000000")]
+ [InlineData(0xff6cab0b, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")]
+ [InlineData(0x91267e8a, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F")]
+ public static void Compute_ValidHex_Success(uint expected, string data)
+ {
+ Assert.Equal(expected, Crc32.Compute(Convert.FromHexString(data)));
+ }
+ }
+}
diff --git a/tests/Jellyfin.Common.Tests/Json/JsonStringConverterTests.cs b/tests/Jellyfin.Common.Tests/Json/JsonStringConverterTests.cs
new file mode 100644
index 000000000..fd77694b3
--- /dev/null
+++ b/tests/Jellyfin.Common.Tests/Json/JsonStringConverterTests.cs
@@ -0,0 +1,39 @@
+using System.Text.Json;
+using MediaBrowser.Common.Json.Converters;
+using Xunit;
+
+namespace Jellyfin.Common.Tests.Json
+{
+ public class JsonStringConverterTests
+ {
+ private readonly JsonSerializerOptions _jsonSerializerOptions
+ = new ()
+ {
+ Converters =
+ {
+ new JsonStringConverter()
+ }
+ };
+
+ [Theory]
+ [InlineData("\"test\"", "test")]
+ [InlineData("123", "123")]
+ [InlineData("123.45", "123.45")]
+ [InlineData("true", "true")]
+ [InlineData("false", "false")]
+ public void Deserialize_String_Valid_Success(string input, string output)
+ {
+ var deserialized = JsonSerializer.Deserialize<string>(input, _jsonSerializerOptions);
+ Assert.Equal(deserialized, output);
+ }
+
+ [Fact]
+ public void Deserialize_Int32asInt32_Valid_Success()
+ {
+ const string? input = "123";
+ const int output = 123;
+ var deserialized = JsonSerializer.Deserialize<int>(input, _jsonSerializerOptions);
+ Assert.Equal(deserialized, output);
+ }
+ }
+} \ No newline at end of file
diff --git a/tests/Jellyfin.MediaEncoding.Tests/FFprobeParserTests.cs b/tests/Jellyfin.MediaEncoding.Tests/FFprobeParserTests.cs
index c39ef0ce9..415682e85 100644
--- a/tests/Jellyfin.MediaEncoding.Tests/FFprobeParserTests.cs
+++ b/tests/Jellyfin.MediaEncoding.Tests/FFprobeParserTests.cs
@@ -16,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, JsonDefaults.GetOptions()).ConfigureAwait(false);
+ await JsonSerializer.DeserializeAsync<InternalMediaInfoResult>(stream, JsonDefaults.Options).ConfigureAwait(false);
}
}
}
diff --git a/tests/Jellyfin.Naming.Tests/Video/CleanStringTests.cs b/tests/Jellyfin.Naming.Tests/Video/CleanStringTests.cs
index 4b363843a..a720bdade 100644
--- a/tests/Jellyfin.Naming.Tests/Video/CleanStringTests.cs
+++ b/tests/Jellyfin.Naming.Tests/Video/CleanStringTests.cs
@@ -7,18 +7,13 @@ namespace Jellyfin.Naming.Tests.Video
{
public sealed class CleanStringTests
{
- private readonly NamingOptions _namingOptions = new NamingOptions();
+ private readonly VideoResolver _videoResolver = new VideoResolver(new NamingOptions());
[Theory]
[InlineData("Super movie 480p.mp4", "Super movie")]
[InlineData("Super movie 480p 2001.mp4", "Super movie")]
[InlineData("Super movie [480p].mp4", "Super movie")]
[InlineData("480 Super movie [tmdbid=12345].mp4", "480 Super movie")]
- [InlineData("Super movie(2009).mp4", "Super movie(2009).mp4")]
- [InlineData("Run lola run (lola rennt) (2009).mp4", "Run lola run (lola rennt) (2009).mp4")]
- [InlineData(@"American.Psycho.mkv", "American.Psycho.mkv")]
- [InlineData(@"American Psycho.mkv", "American Psycho.mkv")]
- [InlineData(@"[rec].mkv", "[rec].mkv")]
[InlineData("Crouching.Tiger.Hidden.Dragon.4k.mkv", "Crouching.Tiger.Hidden.Dragon")]
[InlineData("Crouching.Tiger.Hidden.Dragon.UltraHD.mkv", "Crouching.Tiger.Hidden.Dragon")]
[InlineData("Crouching.Tiger.Hidden.Dragon.UHD.mkv", "Crouching.Tiger.Hidden.Dragon")]
@@ -28,19 +23,26 @@ namespace Jellyfin.Naming.Tests.Video
[InlineData("Crouching.Tiger.Hidden.Dragon.BDrip.mkv", "Crouching.Tiger.Hidden.Dragon")]
[InlineData("Crouching.Tiger.Hidden.Dragon.BDrip-HDC.mkv", "Crouching.Tiger.Hidden.Dragon")]
[InlineData("Crouching.Tiger.Hidden.Dragon.4K.UltraHD.HDR.BDrip-HDC.mkv", "Crouching.Tiger.Hidden.Dragon")]
- [InlineData(null, null)]
// FIXME: [InlineData("After The Sunset - [0004].mkv", "After The Sunset")]
- public void CleanStringTest(string input, string expectedName)
+ public void CleanStringTest_NeedsCleaning_Success(string input, string expectedName)
{
- if (new VideoResolver(_namingOptions).TryCleanString(input, out ReadOnlySpan<char> newName))
- {
- // TODO: compare spans when XUnit supports it
- Assert.Equal(expectedName, newName.ToString());
- }
- else
- {
- Assert.Equal(expectedName, input);
- }
+ Assert.True(_videoResolver.TryCleanString(input, out ReadOnlySpan<char> newName));
+ // TODO: compare spans when XUnit supports it
+ Assert.Equal(expectedName, newName.ToString());
+ }
+
+ [Theory]
+ [InlineData(null)]
+ [InlineData("")]
+ [InlineData("Super movie(2009).mp4")]
+ [InlineData("[rec].mkv")]
+ [InlineData("American.Psycho.mkv")]
+ [InlineData("American Psycho.mkv")]
+ [InlineData("Run lola run (lola rennt) (2009).mp4")]
+ public void CleanStringTest_DoesntNeedCleaning_False(string? input)
+ {
+ Assert.False(_videoResolver.TryCleanString(input, out ReadOnlySpan<char> newName));
+ Assert.True(newName.IsEmpty);
}
}
}
diff --git a/tests/Jellyfin.Naming.Tests/Video/MultiVersionTests.cs b/tests/Jellyfin.Naming.Tests/Video/MultiVersionTests.cs
index bc5e6fa63..6e803593e 100644
--- a/tests/Jellyfin.Naming.Tests/Video/MultiVersionTests.cs
+++ b/tests/Jellyfin.Naming.Tests/Video/MultiVersionTests.cs
@@ -295,12 +295,9 @@ namespace Jellyfin.Naming.Tests.Video
FullName = i
}).ToList()).ToList();
- Assert.Single(result);
+ Assert.Equal(7, result.Count);
Assert.Empty(result[0].Extras);
- Assert.Equal(6, result[0].AlternateVersions.Count);
- Assert.False(result[0].AlternateVersions[2].Is3D);
- Assert.True(result[0].AlternateVersions[3].Is3D);
- Assert.True(result[0].AlternateVersions[4].Is3D);
+ Assert.Empty(result[0].AlternateVersions);
}
[Fact]
@@ -369,6 +366,44 @@ namespace Jellyfin.Naming.Tests.Video
}
[Fact]
+ public void Resolve_GivenFolderNameWithBracketsAndHyphens_GroupsBasedOnFolderName()
+ {
+ var files = new[]
+ {
+ @"/movies/John Wick - Kapitel 3 (2019) [imdbid=tt6146586]/John Wick - Kapitel 3 (2019) [imdbid=tt6146586] - Version 1.mkv",
+ @"/movies/John Wick - Kapitel 3 (2019) [imdbid=tt6146586]/John Wick - Kapitel 3 (2019) [imdbid=tt6146586] - Version 2.mkv"
+ };
+
+ var result = _videoListResolver.Resolve(files.Select(i => new FileSystemMetadata
+ {
+ IsDirectory = false,
+ FullName = i
+ }).ToList()).ToList();
+
+ Assert.Single(result);
+ Assert.Empty(result[0].Extras);
+ Assert.Single(result[0].AlternateVersions);
+ }
+
+ [Fact]
+ public void Resolve_GivenUnclosedBrackets_DoesNotGroup()
+ {
+ var files = new[]
+ {
+ @"/movies/John Wick - Chapter 3 (2019)/John Wick - Chapter 3 (2019) [Version 1].mkv",
+ @"/movies/John Wick - Chapter 3 (2019)/John Wick - Chapter 3 (2019) [Version 2.mkv"
+ };
+
+ var result = _videoListResolver.Resolve(files.Select(i => new FileSystemMetadata
+ {
+ IsDirectory = false,
+ FullName = i
+ }).ToList()).ToList();
+
+ Assert.Equal(2, result.Count);
+ }
+
+ [Fact]
public void TestEmptyList()
{
var result = _videoListResolver.Resolve(new List<FileSystemMetadata>()).ToList();
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs
new file mode 100644
index 000000000..876519215
--- /dev/null
+++ b/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs
@@ -0,0 +1,65 @@
+using System;
+using Emby.Server.Implementations.Library.Resolvers.TV;
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Entities;
+using Moq;
+using Xunit;
+
+namespace Jellyfin.Server.Implementations.Tests.Library
+{
+ public class EpisodeResolverTest
+ {
+ [Fact]
+ public void Resolve_GivenVideoInExtrasFolder_DoesNotResolveToEpisode()
+ {
+ var season = new Season { Name = "Season 1" };
+ var parent = new Folder { Name = "extras" };
+ var libraryManagerMock = new Mock<ILibraryManager>();
+ libraryManagerMock.Setup(x => x.GetItemById(It.IsAny<Guid>())).Returns(season);
+
+ var episodeResolver = new EpisodeResolver(libraryManagerMock.Object);
+ var itemResolveArgs = new ItemResolveArgs(
+ Mock.Of<IServerApplicationPaths>(),
+ Mock.Of<IDirectoryService>())
+ {
+ Parent = parent,
+ CollectionType = CollectionType.TvShows,
+ Path = "All My Children/Season 01/Extras/All My Children S01E01 - Behind The Scenes.mkv"
+ };
+
+ Assert.Null(episodeResolver.Resolve(itemResolveArgs));
+ }
+
+ [Fact]
+ public void Resolve_GivenVideoInExtrasSeriesFolder_ResolvesToEpisode()
+ {
+ var series = new Series { Name = "Extras" };
+
+ // Have to create a mock because of moq proxies not being castable to a concrete implementation
+ // https://github.com/jellyfin/jellyfin/blob/ab0cff8556403e123642dc9717ba778329554634/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs#L48
+ var episodeResolver = new EpisodeResolverMock(Mock.Of<ILibraryManager>());
+ var itemResolveArgs = new ItemResolveArgs(
+ Mock.Of<IServerApplicationPaths>(),
+ Mock.Of<IDirectoryService>())
+ {
+ Parent = series,
+ CollectionType = CollectionType.TvShows,
+ Path = "Extras/Extras S01E01.mkv"
+ };
+ Assert.NotNull(episodeResolver.Resolve(itemResolveArgs));
+ }
+
+ private class EpisodeResolverMock : EpisodeResolver
+ {
+ public EpisodeResolverMock(ILibraryManager libraryManager) : base(libraryManager)
+ {
+ }
+
+ protected override TVideoType ResolveVideo<TVideoType>(ItemResolveArgs args, bool parseName) => new ();
+ }
+ }
+}
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/PathExtensionsTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/PathExtensionsTests.cs
index a6fe90566..e5508243f 100644
--- a/tests/Jellyfin.Server.Implementations.Tests/Library/PathExtensionsTests.cs
+++ b/tests/Jellyfin.Server.Implementations.Tests/Library/PathExtensionsTests.cs
@@ -40,12 +40,16 @@ namespace Jellyfin.Server.Implementations.Tests.Library
}
[Theory]
+ [InlineData(null, null, null)]
+ [InlineData(null, "/my/path", "/another/path")]
+ [InlineData("/my/path", null, "/another/path")]
+ [InlineData("/my/path", "/another/path", null)]
[InlineData("", "", "")]
[InlineData("/my/path", "", "")]
[InlineData("", "/another/path", "")]
[InlineData("", "", "/new/subpath")]
[InlineData("/home/jeff/music/jeff's band/consistently inconsistent.mp3", "/home/jeff/music/not jeff's band", "/home/not jeff")]
- public void TryReplaceSubPath_InvalidInput_ReturnsFalseAndNull(string path, string subPath, string newSubPath)
+ public void TryReplaceSubPath_InvalidInput_ReturnsFalseAndNull(string? path, string? subPath, string? newSubPath)
{
Assert.False(PathExtensions.TryReplaceSubPath(path, subPath, newSubPath, out var result));
Assert.Null(result);
diff --git a/tests/Jellyfin.Server.Implementations.Tests/LiveTv/HdHomerunManagerTests.cs b/tests/Jellyfin.Server.Implementations.Tests/LiveTv/HdHomerunManagerTests.cs
new file mode 100644
index 000000000..7e04a1ec1
--- /dev/null
+++ b/tests/Jellyfin.Server.Implementations.Tests/LiveTv/HdHomerunManagerTests.cs
@@ -0,0 +1,58 @@
+using System;
+using Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun;
+using Xunit;
+
+namespace Jellyfin.Server.Implementations.Tests.LiveTv
+{
+ public class HdHomerunManagerTests
+ {
+ [Fact]
+ public void WriteNullTerminatedString_Empty_Success()
+ {
+ ReadOnlySpan<byte> expected = stackalloc byte[]
+ {
+ 1, 0
+ };
+
+ Span<byte> buffer = stackalloc byte[128];
+ int len = HdHomerunManager.WriteNullTerminatedString(buffer, string.Empty);
+
+ Assert.Equal(expected.Length, len);
+ Assert.True(expected.SequenceEqual(buffer.Slice(0, len)));
+ }
+
+ [Fact]
+ public void WriteNullTerminatedString_Valid_Success()
+ {
+ ReadOnlySpan<byte> expected = stackalloc byte[]
+ {
+ 10, (byte)'T', (byte)'h', (byte)'e', (byte)' ', (byte)'q', (byte)'u', (byte)'i', (byte)'c', (byte)'k', 0
+ };
+
+ Span<byte> buffer = stackalloc byte[128];
+ int len = HdHomerunManager.WriteNullTerminatedString(buffer, "The quick");
+
+ Assert.Equal(expected.Length, len);
+ Assert.True(expected.SequenceEqual(buffer.Slice(0, len)));
+ }
+
+ [Fact]
+ public void WriteGetMessage_Valid_Success()
+ {
+ ReadOnlySpan<byte> expected = stackalloc byte[]
+ {
+ 0, 4,
+ 0, 12,
+ 3,
+ 10, (byte)'/', (byte)'t', (byte)'u', (byte)'n', (byte)'e', (byte)'r', (byte)'0', (byte)'/', (byte)'N', 0,
+ 0xc0, 0xc9, 0x87, 0x33
+ };
+
+ Span<byte> buffer = stackalloc byte[128];
+ int len = HdHomerunManager.WriteGetMessage(buffer, 0, "N");
+
+ Assert.Equal(expected.Length, len);
+ Assert.True(expected.SequenceEqual(buffer.Slice(0, len)));
+ }
+ }
+}
diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/DashboardControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/DashboardControllerTests.cs
index 86d6326d8..f5411dcb8 100644
--- a/tests/Jellyfin.Server.Integration.Tests/Controllers/DashboardControllerTests.cs
+++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/DashboardControllerTests.cs
@@ -13,7 +13,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public sealed class DashboardControllerTests : IClassFixture<JellyfinApplicationFactory>
{
private readonly JellyfinApplicationFactory _factory;
- private readonly JsonSerializerOptions _jsonOpions = JsonDefaults.GetOptions();
+ private readonly JsonSerializerOptions _jsonOpions = JsonDefaults.Options;
public DashboardControllerTests(JellyfinApplicationFactory factory)
{
diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/StartupControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/StartupControllerTests.cs
new file mode 100644
index 000000000..169a5a6c5
--- /dev/null
+++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/StartupControllerTests.cs
@@ -0,0 +1,119 @@
+using System;
+using System.Net;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Net.Mime;
+using System.Text.Json;
+using System.Threading.Tasks;
+using Jellyfin.Api.Models.StartupDtos;
+using MediaBrowser.Common.Json;
+using Xunit;
+using Xunit.Priority;
+
+namespace Jellyfin.Server.Integration.Tests.Controllers
+{
+ [TestCaseOrderer(PriorityOrderer.Name, PriorityOrderer.Assembly)]
+ public sealed class StartupControllerTests : IClassFixture<JellyfinApplicationFactory>
+ {
+ private readonly JellyfinApplicationFactory _factory;
+ private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options;
+
+ public StartupControllerTests(JellyfinApplicationFactory factory)
+ {
+ _factory = factory;
+ }
+
+ [Fact]
+ [Priority(-2)]
+ public async Task Configuration_EditConfig_Success()
+ {
+ var client = _factory.CreateClient();
+
+ var config = new StartupConfigurationDto()
+ {
+ UICulture = "NewCulture",
+ MetadataCountryCode = "be",
+ PreferredMetadataLanguage = "nl"
+ };
+
+ using var postContent = new ByteArrayContent(JsonSerializer.SerializeToUtf8Bytes(config, _jsonOptions));
+ postContent.Headers.ContentType = MediaTypeHeaderValue.Parse(MediaTypeNames.Application.Json);
+ using var postResponse = await client.PostAsync("/Startup/Configuration", postContent).ConfigureAwait(false);
+ Assert.Equal(HttpStatusCode.NoContent, postResponse.StatusCode);
+
+ using var getResponse = await client.GetAsync("/Startup/Configuration").ConfigureAwait(false);
+ Assert.Equal(HttpStatusCode.OK, getResponse.StatusCode);
+ Assert.Equal(MediaTypeNames.Application.Json, getResponse.Content.Headers.ContentType?.MediaType);
+
+ using var responseStream = await getResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ var newConfig = await JsonSerializer.DeserializeAsync<StartupConfigurationDto>(responseStream, _jsonOptions).ConfigureAwait(false);
+ Assert.Equal(config.UICulture, newConfig!.UICulture);
+ Assert.Equal(config.MetadataCountryCode, newConfig.MetadataCountryCode);
+ Assert.Equal(config.PreferredMetadataLanguage, newConfig.PreferredMetadataLanguage);
+ }
+
+ [Fact]
+ [Priority(-2)]
+ public async Task User_DefaultUser_NameWithoutPassword()
+ {
+ var client = _factory.CreateClient();
+
+ using var response = await client.GetAsync("/Startup/User").ConfigureAwait(false);
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType);
+
+ using var contentStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ var user = await JsonSerializer.DeserializeAsync<StartupUserDto>(contentStream, _jsonOptions).ConfigureAwait(false);
+ Assert.NotEmpty(user!.Name);
+ Assert.Null(user.Password);
+ }
+
+ [Fact]
+ [Priority(-1)]
+ public async Task User_EditUser_Success()
+ {
+ var client = _factory.CreateClient();
+
+ var user = new StartupUserDto()
+ {
+ Name = "NewName",
+ Password = "NewPassword"
+ };
+
+ using var postContent = new ByteArrayContent(JsonSerializer.SerializeToUtf8Bytes(user, _jsonOptions));
+ postContent.Headers.ContentType = MediaTypeHeaderValue.Parse(MediaTypeNames.Application.Json);
+ var postResponse = await client.PostAsync("/Startup/User", postContent).ConfigureAwait(false);
+ Assert.Equal(HttpStatusCode.NoContent, postResponse.StatusCode);
+
+ var getResponse = await client.GetAsync("/Startup/User").ConfigureAwait(false);
+ Assert.Equal(HttpStatusCode.OK, getResponse.StatusCode);
+ Assert.Equal(MediaTypeNames.Application.Json, getResponse.Content.Headers.ContentType?.MediaType);
+
+ var contentStream = await getResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
+ var newUser = await JsonSerializer.DeserializeAsync<StartupUserDto>(contentStream, _jsonOptions).ConfigureAwait(false);
+ Assert.Equal(user.Name, newUser!.Name);
+ Assert.NotEmpty(newUser.Password);
+ Assert.NotEqual(user.Password, newUser.Password);
+ }
+
+ [Fact]
+ [Priority(0)]
+ public async Task CompleteWizard_Success()
+ {
+ var client = _factory.CreateClient();
+
+ var response = await client.PostAsync("/Startup/Complete", new ByteArrayContent(Array.Empty<byte>())).ConfigureAwait(false);
+ Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
+ }
+
+ [Fact]
+ [Priority(1)]
+ public async Task GetFirstUser_CompleteWizard_Unauthorized()
+ {
+ var client = _factory.CreateClient();
+
+ using var response = await client.GetAsync("/Startup/User").ConfigureAwait(false);
+ Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
+ }
+ }
+}
diff --git a/tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj b/tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj
index 49004966b..34cef9005 100644
--- a/tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj
+++ b/tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj
@@ -17,13 +17,13 @@
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
+ <PackageReference Include="Xunit.Priority" Version="1.1.6" />
<PackageReference Include="coverlet.collector" Version="3.0.3" />
<PackageReference Include="Moq" Version="4.16.0" />
</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" />
diff --git a/tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj b/tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj
index 65ea28e94..a310b0ea9 100644
--- a/tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj
+++ b/tests/Jellyfin.Server.Tests/Jellyfin.Server.Tests.csproj
@@ -5,6 +5,8 @@
<IsPackable>false</IsPackable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Nullable>enable</Nullable>
+ <AnalysisMode>AllEnabledByDefault</AnalysisMode>
+ <CodeAnalysisRuleSet>../jellyfin-tests.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
@@ -22,7 +24,6 @@
<!-- 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" />
@@ -32,8 +33,4 @@
<ProjectReference Include="../../Jellyfin.Server/Jellyfin.Server.csproj" />
</ItemGroup>
- <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
- <CodeAnalysisRuleSet>../jellyfin-tests.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
-
</Project>