aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.ci/azure-pipelines-package.yml1
-rw-r--r--.github/workflows/codeql-analysis.yml8
-rw-r--r--.github/workflows/commands.yml4
-rw-r--r--.github/workflows/openapi.yml4
-rw-r--r--.github/workflows/repo-bump-version.yaml82
-rw-r--r--Directory.Packages.props31
-rw-r--r--Emby.Server.Implementations/ApplicationHost.cs2
-rw-r--r--Emby.Server.Implementations/IO/FileRefresher.cs9
-rw-r--r--Emby.Server.Implementations/IO/LibraryMonitor.cs68
-rw-r--r--Emby.Server.Implementations/IO/ManagedFileSystem.cs18
-rw-r--r--Emby.Server.Implementations/IO/MbLinkShortcutHandler.cs11
-rw-r--r--Emby.Server.Implementations/Library/LibraryManager.cs2
-rw-r--r--Emby.Server.Implementations/Localization/Core/as.json44
-rw-r--r--Emby.Server.Implementations/Localization/Core/chr.json52
-rw-r--r--Emby.Server.Implementations/Localization/Core/nl.json4
-rw-r--r--Emby.Server.Implementations/Localization/Core/sl-SI.json2
-rw-r--r--Emby.Server.Implementations/Localization/Core/zu.json11
-rw-r--r--Emby.Server.Implementations/Playlists/PlaylistManager.cs5
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs146
-rw-r--r--Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionPathsTask.cs119
-rw-r--r--Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs1
-rw-r--r--Jellyfin.Server/Migrations/Routines/MigrateActivityLogDb.cs3
-rw-r--r--Jellyfin.Server/Migrations/Routines/MigrateAuthenticationDb.cs1
-rw-r--r--Jellyfin.Server/Migrations/Routines/MigrateDisplayPreferencesDb.cs1
-rw-r--r--Jellyfin.Server/Migrations/Routines/MigrateRatingLevels.cs3
-rw-r--r--Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs1
-rw-r--r--Jellyfin.Server/Migrations/Routines/RemoveDuplicateExtras.cs3
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs10
-rw-r--r--MediaBrowser.Controller/Playlists/IPlaylistManager.cs6
-rw-r--r--MediaBrowser.Model/IO/IFileSystem.cs7
-rw-r--r--deployment/Dockerfile.centos.amd642
-rw-r--r--deployment/Dockerfile.fedora.amd642
-rw-r--r--deployment/Dockerfile.ubuntu.amd642
-rw-r--r--deployment/Dockerfile.ubuntu.arm642
-rw-r--r--deployment/Dockerfile.ubuntu.armhf2
-rw-r--r--fedora/jellyfin-selinux-launcher.sh2
-rw-r--r--jellyfin.ruleset16
-rw-r--r--src/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj6
-rw-r--r--src/Jellyfin.Drawing.Skia/SkiaEncoder.cs7
-rw-r--r--src/Jellyfin.Drawing.Skia/SkiaHelper.cs8
-rw-r--r--src/Jellyfin.Drawing.Skia/StripCollageBuilder.cs4
-rw-r--r--src/Jellyfin.Drawing/Jellyfin.Drawing.csproj6
-rw-r--r--src/Jellyfin.Extensions/Jellyfin.Extensions.csproj4
-rw-r--r--src/Jellyfin.MediaEncoding.Hls/Jellyfin.MediaEncoding.Hls.csproj4
-rw-r--r--src/Jellyfin.MediaEncoding.Keyframes/Jellyfin.MediaEncoding.Keyframes.csproj4
-rw-r--r--tests/Jellyfin.MediaEncoding.Tests/Subtitles/SubtitleEncoderTests.cs2
-rw-r--r--tests/Jellyfin.Providers.Tests/Manager/ProviderManagerTests.cs4
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/LiveTv/HdHomerunHostTests.cs10
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/Updates/InstallationManagerTests.cs4
-rw-r--r--tests/Jellyfin.Server.Integration.Tests/AuthHelper.cs22
-rw-r--r--tests/Jellyfin.Server.Integration.Tests/Controllers/ActivityLogControllerTests.cs4
-rw-r--r--tests/Jellyfin.Server.Integration.Tests/Controllers/DashboardControllerTests.cs16
-rw-r--r--tests/Jellyfin.Server.Integration.Tests/Controllers/DlnaControllerTests.cs44
-rw-r--r--tests/Jellyfin.Server.Integration.Tests/Controllers/ItemsControllerTests.cs18
-rw-r--r--tests/Jellyfin.Server.Integration.Tests/Controllers/LibraryControllerTests.cs10
-rw-r--r--tests/Jellyfin.Server.Integration.Tests/Controllers/MediaInfoControllerTests.cs12
-rw-r--r--tests/Jellyfin.Server.Integration.Tests/Controllers/MediaStructureControllerTests.cs28
-rw-r--r--tests/Jellyfin.Server.Integration.Tests/Controllers/MusicGenreControllerTests.cs4
-rw-r--r--tests/Jellyfin.Server.Integration.Tests/Controllers/PlaystateControllerTests.cs20
-rw-r--r--tests/Jellyfin.Server.Integration.Tests/Controllers/SessionControllerTests.cs4
-rw-r--r--tests/Jellyfin.Server.Integration.Tests/Controllers/StartupControllerTests.cs26
-rw-r--r--tests/Jellyfin.Server.Integration.Tests/Controllers/UserControllerTests.cs30
-rw-r--r--tests/Jellyfin.Server.Integration.Tests/Controllers/UserLibraryControllerTests.cs56
-rw-r--r--tests/Jellyfin.Server.Integration.Tests/Controllers/VideosControllerTests.cs4
-rw-r--r--tests/Jellyfin.Server.Integration.Tests/EncodedQueryStringTest.cs8
-rw-r--r--tests/Jellyfin.Server.Integration.Tests/Middleware/RobotsRedirectionMiddlewareTests.cs2
66 files changed, 644 insertions, 414 deletions
diff --git a/.ci/azure-pipelines-package.yml b/.ci/azure-pipelines-package.yml
index c28b1bf7f..c91a084e5 100644
--- a/.ci/azure-pipelines-package.yml
+++ b/.ci/azure-pipelines-package.yml
@@ -168,6 +168,7 @@ jobs:
- job: CollectArtifacts
timeoutInMinutes: 20
displayName: 'Collect Artifacts'
+ condition: succeededOrFailed()
continueOnError: true
dependsOn:
- BuildPackage
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index cdb7f5c73..7855ee4f7 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -20,18 +20,18 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0
+ uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Setup .NET
uses: actions/setup-dotnet@3447fd6a9f9e57506b15f895c5b76d3b197dc7c2 # v3.2.0
with:
dotnet-version: '7.0.x'
- name: Initialize CodeQL
- uses: github/codeql-action/init@00e563ead9f72a8461b24876bee2d0c2e8bd2ee8 # v2.21.5
+ uses: github/codeql-action/init@6a28655e3dcb49cb0840ea372fd6d17733edd8a4 # v2.21.8
with:
languages: ${{ matrix.language }}
queries: +security-extended
- name: Autobuild
- uses: github/codeql-action/autobuild@00e563ead9f72a8461b24876bee2d0c2e8bd2ee8 # v2.21.5
+ uses: github/codeql-action/autobuild@6a28655e3dcb49cb0840ea372fd6d17733edd8a4 # v2.21.8
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@00e563ead9f72a8461b24876bee2d0c2e8bd2ee8 # v2.21.5
+ uses: github/codeql-action/analyze@6a28655e3dcb49cb0840ea372fd6d17733edd8a4 # v2.21.8
diff --git a/.github/workflows/commands.yml b/.github/workflows/commands.yml
index 02aeefdbd..ba7883a73 100644
--- a/.github/workflows/commands.yml
+++ b/.github/workflows/commands.yml
@@ -24,7 +24,7 @@ jobs:
reactions: '+1'
- name: Checkout the latest code
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0
+ uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
with:
token: ${{ secrets.JF_BOT_TOKEN }}
fetch-depth: 0
@@ -51,7 +51,7 @@ jobs:
reactions: eyes
- name: Checkout the latest code
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0
+ uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
with:
token: ${{ secrets.JF_BOT_TOKEN }}
fetch-depth: 0
diff --git a/.github/workflows/openapi.yml b/.github/workflows/openapi.yml
index 72f1b1d1f..693f98d16 100644
--- a/.github/workflows/openapi.yml
+++ b/.github/workflows/openapi.yml
@@ -14,7 +14,7 @@ jobs:
permissions: read-all
steps:
- name: Checkout repository
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0
+ uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
with:
ref: ${{ github.event.pull_request.head.sha }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
@@ -39,7 +39,7 @@ jobs:
permissions: read-all
steps:
- name: Checkout repository
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0
+ uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
with:
ref: ${{ github.event.pull_request.head.sha }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
diff --git a/.github/workflows/repo-bump-version.yaml b/.github/workflows/repo-bump-version.yaml
new file mode 100644
index 000000000..0ba68dda3
--- /dev/null
+++ b/.github/workflows/repo-bump-version.yaml
@@ -0,0 +1,82 @@
+name: '🆙 Auto bump_version'
+
+on:
+ release:
+ types:
+ - published
+ workflow_dispatch:
+ inputs:
+ TAG_BRANCH:
+ required: true
+ description: release-x.y.z
+ NEXT_VERSION:
+ required: true
+ description: x.y.z
+
+jobs:
+ auto_bump_version:
+ runs-on: ubuntu-latest
+ if: ${{ github.event_name == 'release' && !contains(github.event.release.tag_name, 'rc') }}
+ env:
+ TAG_BRANCH: ${{ github.event.release.target_commitish }}
+ steps:
+ - name: Wait for deploy checks to finish
+ uses: jitterbit/await-check-suites@292a541bb7618078395b2ce711a0d89cfb8a568a # v1
+ with:
+ ref: ${{ env.TAG_BRANCH }}
+ intervalSeconds: 60
+ timeoutSeconds: 3600
+
+ - name: Setup YQ
+ uses: chrisdickinson/setup-yq@latest
+ with:
+ yq-version: v4.9.8
+
+ - name: Checkout Repository
+ uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
+ with:
+ ref: ${{ env.TAG_BRANCH }}
+
+ - name: Setup EnvVars
+ run: |-
+ CURRENT_VERSION=$(yq e '.version' build.yaml)
+ CURRENT_MAJOR_MINOR=${CURRENT_VERSION%.*}
+ CURRENT_PATCH=${CURRENT_VERSION##*.}
+ echo "CURRENT_VERSION=${CURRENT_VERSION}" >> $GITHUB_ENV
+ echo "CURRENT_MAJOR_MINOR=${CURRENT_MAJOR_MINOR}" >> $GITHUB_ENV
+ echo "CURRENT_PATCH=${CURRENT_PATCH}" >> $GITHUB_ENV
+ echo "NEXT_VERSION=${CURRENT_MAJOR_MINOR}.$(($CURRENT_PATCH + 1))" >> $GITHUB_ENV
+
+ - name: Run bump_version
+ run: ./bump_version ${{ env.NEXT_VERSION }}
+
+ - name: Commit Changes
+ run: |-
+ git config user.name "jellyfin-bot"
+ git config user.email "team@jellyfin.org"
+ git checkout ${{ env.TAG_BRANCH }}
+ git commit -am "Bump version to ${{ env.NEXT_VERSION }}"
+ git push origin ${{ env.TAG_BRANCH }}
+
+ manual_bump_version:
+ runs-on: ubuntu-latest
+ if: ${{ github.event_name == 'workflow_dispatch' }}
+ env:
+ TAG_BRANCH: ${{ github.event.inputs.TAG_BRANCH }}
+ NEXT_VERSION: ${{ github.event.inputs.NEXT_VERSION }}
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
+ with:
+ ref: ${{ env.TAG_BRANCH }}
+
+ - name: Run bump_version
+ run: ./bump_version ${{ env.NEXT_VERSION }}
+
+ - name: Commit Changes
+ run: |-
+ git config user.name "jellyfin-bot"
+ git config user.email "team@jellyfin.org"
+ git checkout ${{ env.TAG_BRANCH }}
+ git commit -am "Bump version to ${{ env.NEXT_VERSION }}"
+ git push origin ${{ env.TAG_BRANCH }}
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 6b9b51826..6bf960bb7 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -19,19 +19,21 @@
<PackageVersion Include="DotNet.Glob" Version="3.1.3" />
<PackageVersion Include="EFCoreSecondLevelCacheInterceptor" Version="3.9.2" />
<PackageVersion Include="FsCheck.Xunit" Version="2.16.6" />
+ <PackageVersion Include="HarfBuzzSharp.NativeAssets.Linux" Version="7.3.0" />
+ <PackageVersion Include="IDisposableAnalyzers" Version="4.0.7" />
<PackageVersion Include="Jellyfin.XmlTv" Version="10.8.0" />
<PackageVersion Include="libse" Version="3.6.13" />
<PackageVersion Include="LrcParser" Version="2023.524.0" />
<PackageVersion Include="MetaBrainz.MusicBrainz" Version="5.0.0" />
- <PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="7.0.10" />
+ <PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="7.0.11" />
<PackageVersion Include="Microsoft.AspNetCore.HttpOverrides" Version="2.2.0" />
- <PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="7.0.10" />
+ <PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="7.0.11" />
<PackageVersion Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.4" />
- <PackageVersion Include="Microsoft.Data.Sqlite" Version="7.0.10" />
- <PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.10" />
- <PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.10" />
- <PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.10" />
- <PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.10" />
+ <PackageVersion Include="Microsoft.Data.Sqlite" Version="7.0.11" />
+ <PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.11" />
+ <PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.11" />
+ <PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.11" />
+ <PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.11" />
<PackageVersion Include="Microsoft.Extensions.Caching.Abstractions" Version="7.0.0" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0" />
@@ -40,8 +42,8 @@
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
- <PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="7.0.10" />
- <PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="7.0.10" />
+ <PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="7.0.11" />
+ <PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="7.0.11" />
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="7.0.0" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="7.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.1" />
@@ -67,14 +69,13 @@
<PackageVersion Include="Serilog.Sinks.Graylog" Version="3.0.2" />
<PackageVersion Include="SerilogAnalyzer" Version="0.15.0" />
<PackageVersion Include="SharpFuzz" Version="2.1.1" />
+ <PackageVersion Include="SkiaSharp" Version="2.88.5" />
+ <PackageVersion Include="SkiaSharp.HarfBuzz" Version="2.88.5" />
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.5" />
<PackageVersion Include="SkiaSharp.Svg" Version="1.60.0" />
- <PackageVersion Include="SkiaSharp.HarfBuzz" Version="2.88.5" />
- <PackageVersion Include="HarfBuzzSharp.NativeAssets.Linux" Version="2.8.2.5" />
- <PackageVersion Include="SkiaSharp" Version="2.88.5" />
<PackageVersion Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" />
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.507" />
- <PackageVersion Include="Swashbuckle.AspNetCore.ReDoc" Version="6.4.0" />
+ <PackageVersion Include="Swashbuckle.AspNetCore.ReDoc" Version="6.5.0" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.2.3" />
<PackageVersion Include="System.Globalization" Version="4.3.0" />
<PackageVersion Include="System.Linq.Async" Version="6.0.1" />
@@ -85,8 +86,8 @@
<PackageVersion Include="TMDbLib" Version="2.0.0" />
<PackageVersion Include="UTF.Unknown" Version="2.5.1" />
<PackageVersion Include="Xunit.Priority" Version="1.1.6" />
- <PackageVersion Include="xunit.runner.visualstudio" Version="2.5.0" />
+ <PackageVersion Include="xunit.runner.visualstudio" Version="2.5.1" />
<PackageVersion Include="Xunit.SkippableFact" Version="1.4.13" />
- <PackageVersion Include="xunit" Version="2.5.0" />
+ <PackageVersion Include="xunit" Version="2.5.1" />
</ItemGroup>
</Project>
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index 8b13ccada..f8208af70 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -157,7 +157,7 @@ namespace Emby.Server.Implementations
_fileSystemManager = new ManagedFileSystem(LoggerFactory.CreateLogger<ManagedFileSystem>(), applicationPaths);
Logger = LoggerFactory.CreateLogger<ApplicationHost>();
- _fileSystemManager.AddShortcutHandler(new MbLinkShortcutHandler(_fileSystemManager));
+ _fileSystemManager.AddShortcutHandler(new MbLinkShortcutHandler());
_deviceId = new DeviceId(ApplicationPaths, LoggerFactory);
ApplicationVersion = typeof(ApplicationHost).Assembly.GetName().Version;
diff --git a/Emby.Server.Implementations/IO/FileRefresher.cs b/Emby.Server.Implementations/IO/FileRefresher.cs
index 0ad81b653..15b1836eb 100644
--- a/Emby.Server.Implementations/IO/FileRefresher.cs
+++ b/Emby.Server.Implementations/IO/FileRefresher.cs
@@ -85,7 +85,7 @@ namespace Emby.Server.Implementations.IO
}
}
- public void ResetPath(string path, string affectedFile)
+ public void ResetPath(string path, string? affectedFile)
{
lock (_timerLock)
{
@@ -148,13 +148,6 @@ namespace Emby.Server.Implementations.IO
{
item.ChangedExternally();
}
- catch (IOException ex)
- {
- // For now swallow and log.
- // Research item: If an IOException occurs, the item may be in a disconnected state (media unavailable)
- // Should we remove it from it's parent?
- _logger.LogError(ex, "Error refreshing {Name}", item.Name);
- }
catch (Exception ex)
{
_logger.LogError(ex, "Error refreshing {Name}", item.Name);
diff --git a/Emby.Server.Implementations/IO/LibraryMonitor.cs b/Emby.Server.Implementations/IO/LibraryMonitor.cs
index f67a02be8..dde38906f 100644
--- a/Emby.Server.Implementations/IO/LibraryMonitor.cs
+++ b/Emby.Server.Implementations/IO/LibraryMonitor.cs
@@ -1,5 +1,3 @@
-#nullable disable
-
#pragma warning disable CS1591
using System;
@@ -160,7 +158,7 @@ namespace Emby.Server.Implementations.IO
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="ItemChangeEventArgs"/> instance containing the event data.</param>
- private void OnLibraryManagerItemRemoved(object sender, ItemChangeEventArgs e)
+ private void OnLibraryManagerItemRemoved(object? sender, ItemChangeEventArgs e)
{
if (e.Parent is AggregateFolder)
{
@@ -173,7 +171,7 @@ namespace Emby.Server.Implementations.IO
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="ItemChangeEventArgs"/> instance containing the event data.</param>
- private void OnLibraryManagerItemAdded(object sender, ItemChangeEventArgs e)
+ private void OnLibraryManagerItemAdded(object? sender, ItemChangeEventArgs e)
{
if (e.Parent is AggregateFolder)
{
@@ -189,19 +187,28 @@ namespace Emby.Server.Implementations.IO
/// <param name="path">The path.</param>
/// <returns><c>true</c> if [contains parent folder] [the specified LST]; otherwise, <c>false</c>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="path"/> is <c>null</c>.</exception>
- private static bool ContainsParentFolder(IEnumerable<string> lst, string path)
+ private static bool ContainsParentFolder(IReadOnlyList<string> lst, ReadOnlySpan<char> path)
{
- ArgumentException.ThrowIfNullOrEmpty(path);
+ if (path.IsEmpty)
+ {
+ throw new ArgumentException("Path can't be empty", nameof(path));
+ }
path = path.TrimEnd(Path.DirectorySeparatorChar);
- return lst.Any(str =>
+ foreach (var str in lst)
{
// this should be a little quicker than examining each actual parent folder...
- var compare = str.TrimEnd(Path.DirectorySeparatorChar);
+ var compare = str.AsSpan().TrimEnd(Path.DirectorySeparatorChar);
- return path.Equals(compare, StringComparison.OrdinalIgnoreCase) || (path.StartsWith(compare, StringComparison.OrdinalIgnoreCase) && path[compare.Length] == Path.DirectorySeparatorChar);
- });
+ if (path.Equals(compare, StringComparison.OrdinalIgnoreCase)
+ || (path.StartsWith(compare, StringComparison.OrdinalIgnoreCase) && path[compare.Length] == Path.DirectorySeparatorChar))
+ {
+ return true;
+ }
+ }
+
+ return false;
}
/// <summary>
@@ -349,21 +356,19 @@ namespace Emby.Server.Implementations.IO
{
ArgumentException.ThrowIfNullOrEmpty(path);
- var monitorPath = !IgnorePatterns.ShouldIgnore(path);
+ if (IgnorePatterns.ShouldIgnore(path))
+ {
+ return;
+ }
// Ignore certain files, If the parent of an ignored path has a change event, ignore that too
- if (_tempIgnoredPaths.Keys.Any(i =>
+ foreach (var i in _tempIgnoredPaths.Keys)
{
- if (_fileSystem.AreEqual(i, path))
- {
- _logger.LogDebug("Ignoring change to {Path}", path);
- return true;
- }
-
- if (_fileSystem.ContainsSubPath(i, path))
+ if (_fileSystem.AreEqual(i, path)
+ || _fileSystem.ContainsSubPath(i, path))
{
_logger.LogDebug("Ignoring change to {Path}", path);
- return true;
+ return;
}
// Go up a level
@@ -371,20 +376,11 @@ namespace Emby.Server.Implementations.IO
if (!string.IsNullOrEmpty(parent) && _fileSystem.AreEqual(parent, path))
{
_logger.LogDebug("Ignoring change to {Path}", path);
- return true;
+ return;
}
-
- return false;
- }))
- {
- monitorPath = false;
}
- if (monitorPath)
- {
- // Avoid implicitly captured closure
- CreateRefresher(path);
- }
+ CreateRefresher(path);
}
private void CreateRefresher(string path)
@@ -417,7 +413,8 @@ namespace Emby.Server.Implementations.IO
}
// They are siblings. Rebase the refresher to the parent folder.
- if (string.Equals(parentPath, Path.GetDirectoryName(refresher.Path), StringComparison.Ordinal))
+ if (parentPath is not null
+ && Path.GetDirectoryName(refresher.Path.AsSpan()).Equals(parentPath, StringComparison.Ordinal))
{
refresher.ResetPath(parentPath, path);
return;
@@ -430,8 +427,13 @@ namespace Emby.Server.Implementations.IO
}
}
- private void OnNewRefresherCompleted(object sender, EventArgs e)
+ private void OnNewRefresherCompleted(object? sender, EventArgs e)
{
+ if (sender is null)
+ {
+ return;
+ }
+
var refresher = (FileRefresher)sender;
DisposeRefresher(refresher);
}
diff --git a/Emby.Server.Implementations/IO/ManagedFileSystem.cs b/Emby.Server.Implementations/IO/ManagedFileSystem.cs
index 0ba4a488b..3aa5233ed 100644
--- a/Emby.Server.Implementations/IO/ManagedFileSystem.cs
+++ b/Emby.Server.Implementations/IO/ManagedFileSystem.cs
@@ -486,24 +486,10 @@ namespace Emby.Server.Implementations.IO
}
/// <inheritdoc />
- public virtual string NormalizePath(string path)
- {
- ArgumentException.ThrowIfNullOrEmpty(path);
-
- if (path.EndsWith(":\\", StringComparison.OrdinalIgnoreCase))
- {
- return path;
- }
-
- return Path.TrimEndingDirectorySeparator(path);
- }
-
- /// <inheritdoc />
public virtual bool AreEqual(string path1, string path2)
{
- return string.Equals(
- NormalizePath(path1),
- NormalizePath(path2),
+ return Path.TrimEndingDirectorySeparator(path1).Equals(
+ Path.TrimEndingDirectorySeparator(path2),
_isEnvironmentCaseInsensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
}
diff --git a/Emby.Server.Implementations/IO/MbLinkShortcutHandler.cs b/Emby.Server.Implementations/IO/MbLinkShortcutHandler.cs
index c2aab3879..5776c7a7c 100644
--- a/Emby.Server.Implementations/IO/MbLinkShortcutHandler.cs
+++ b/Emby.Server.Implementations/IO/MbLinkShortcutHandler.cs
@@ -8,24 +8,17 @@ namespace Emby.Server.Implementations.IO
{
public class MbLinkShortcutHandler : IShortcutHandler
{
- private readonly IFileSystem _fileSystem;
-
- public MbLinkShortcutHandler(IFileSystem fileSystem)
- {
- _fileSystem = fileSystem;
- }
-
public string Extension => ".mblink";
public string? Resolve(string shortcutPath)
{
ArgumentException.ThrowIfNullOrEmpty(shortcutPath);
- if (string.Equals(Path.GetExtension(shortcutPath), ".mblink", StringComparison.OrdinalIgnoreCase))
+ if (Path.GetExtension(shortcutPath.AsSpan()).Equals(".mblink", StringComparison.OrdinalIgnoreCase))
{
var path = File.ReadAllText(shortcutPath);
- return _fileSystem.NormalizePath(path);
+ return Path.TrimEndingDirectorySeparator(path);
}
return null;
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index 808cedd67..b0a4a4151 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -608,7 +608,7 @@ namespace Emby.Server.Implementations.Library
var originalList = paths.ToList();
var list = originalList.Where(i => i.IsDirectory)
- .Select(i => _fileSystem.NormalizePath(i.FullName))
+ .Select(i => Path.TrimEndingDirectorySeparator(i.FullName))
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToList();
diff --git a/Emby.Server.Implementations/Localization/Core/as.json b/Emby.Server.Implementations/Localization/Core/as.json
index 0967ef424..7c7dd26e9 100644
--- a/Emby.Server.Implementations/Localization/Core/as.json
+++ b/Emby.Server.Implementations/Localization/Core/as.json
@@ -1 +1,43 @@
-{}
+{
+ "Albums": "এলবাম",
+ "Application": "আবেদন",
+ "AppDeviceValues": "এপ্‌: {0}, ডিভাইচ: {1}",
+ "Artists": "শিল্পী",
+ "Channels": "চেনেলস",
+ "Default": "ডিফল্ট",
+ "AuthenticationSucceededWithUserName": "{0} সফলভাবে প্রমাণিত",
+ "Books": "পুস্তক",
+ "Movies": "চলচ্চিত্ৰ",
+ "CameraImageUploadedFrom": "একটি নতুন ক্যামেরা চিত্র আপলোড করা হয়েছে {0}",
+ "Collections": "সংগ্রহ",
+ "HeaderFavoriteShows": "প্রিয় শোসমূহ",
+ "Latest": "শেহতীয়া",
+ "MessageApplicationUpdated": "জেলিফিন চাইভাৰ আপডেট কৰা হৈছে",
+ "MixedContent": "মিশ্ৰিত সমগ্ৰতা",
+ "NewVersionIsAvailable": "ডাউনলোড কৰিবলৈ জেলিফিন চাইভাৰৰ এটা নতুন সংস্কৰণ উপলব্ধ আছে.",
+ "NotificationOptionCameraImageUploaded": "কেমেৰাৰ চিত্ৰ আপল'ড কৰা হ'ল",
+ "External": "বাহ্যিক",
+ "Favorites": "পছন্দসই",
+ "Folders": "ফোল্ডাৰ",
+ "Forced": "বলপূর্বক",
+ "Genres": "শ্রেণী",
+ "HeaderAlbumArtists": "অ্যালবাম শিল্পী",
+ "HeaderContinueWatching": "দেখা চালিয়ে যান",
+ "FailedLoginAttemptWithUserName": "লগইন ব্যর্থ চেষ্টা কৰা হৈছে থেকে {0}",
+ "HeaderFavoriteAlbums": "প্রিয় অ্যালবামসমূহ",
+ "HeaderFavoriteArtists": "প্রিয় শিল্পীসমূহ",
+ "HeaderFavoriteEpisodes": "প্রিয় পর্বসমূহ",
+ "HeaderFavoriteSongs": "প্ৰিয় গীত",
+ "HeaderLiveTV": "প্ৰতিবেদন টিভি",
+ "HeaderNextUp": "পৰৱৰ্তী অংশ",
+ "HeaderRecordingGroups": "অলংকৰণ গোষ্ঠীসমূহ",
+ "HearingImpaired": "শ্ৰবণ অক্ষম",
+ "HomeVideos": "ঘৰৰ ভিডিঅ'সমূহ",
+ "Inherit": "উত্তপ্ত কৰা",
+ "MessageServerConfigurationUpdated": "চাইভাৰ কনফিগাৰেশ্যন আপডেট কৰা হৈছে",
+ "NotificationOptionApplicationUpdateAvailable": "অ্যাপ্লিকেশ্যন আপডেট উপলব্ধ",
+ "NotificationOptionApplicationUpdateInstalled": "অ্যাপ্লিকেশ্যন আপডেট ইনষ্টল কৰা হ'ল",
+ "NotificationOptionAudioPlayback": "অডিঅ' প্লেবেক আৰম্ভ হ'ল",
+ "NotificationOptionAudioPlaybackStopped": "অডিঅ' প্লেবেক আঁতৰ হ'ল",
+ "NotificationOptionInstallationFailed": "ইনষ্টলেশ্যন ব্যৰ্থতা"
+}
diff --git a/Emby.Server.Implementations/Localization/Core/chr.json b/Emby.Server.Implementations/Localization/Core/chr.json
new file mode 100644
index 000000000..85d1f4c88
--- /dev/null
+++ b/Emby.Server.Implementations/Localization/Core/chr.json
@@ -0,0 +1,52 @@
+{
+ "ChapterNameValue": "Didanedi {0}",
+ "HeaderAlbumArtists": "Didanidanolisgisgi",
+ "HeaderFavoriteAlbums": "Dvganidi didanidisgisgi",
+ "HeaderLiveTV": "Anigadi didanidisgosgi",
+ "HeaderRecordingGroups": "Didanisquodiisgisgi",
+ "HomeVideos": "Diganadi dinagadisgisgi",
+ "Inherit": "Anigwe",
+ "MessageApplicationUpdatedTo": "Tsenigwidinonvhi Jellyfin Server tsadanidigwe anigadi {0}",
+ "MixedContent": "Ganinidi dininoladisgisgi",
+ "Movies": "Anidvnisgisgi",
+ "MusicVideos": "Danodisgisgi didanidisgosgi",
+ "NotificationOptionAudioPlayback": "Didanidigwe diganuyisgisgi anigadi",
+ "NotificationOptionInstallationFailed": "Diudvdi anadvnatisgisgi",
+ "NotificationOptionPluginUninstalled": "Ditsigvhnidv anawvdisgisgi",
+ "Albums": "Anigawidaniyv",
+ "Application": "Didanvyi",
+ "Artists": "Dinidaniyi",
+ "AuthenticationSucceededWithUserName": "{0} Sesoquonisdi nagadani",
+ "Books": "Didanedi",
+ "CameraImageUploadedFrom": "Anigawidaniyv nasgi didagwalanvyi {0}",
+ "Channels": "Diganadasgi",
+ "Collections": "Diganadisgi",
+ "Default": "Dinadi",
+ "DeviceOfflineWithName": "{0} Aniyvolehvi nasgi",
+ "External": "Amohdi",
+ "Favorites": "Nvdayelvdisgi",
+ "Folders": "Didanididisgi",
+ "Forced": "Ganedi",
+ "Genres": "Diganadisgi",
+ "HeaderContinueWatching": "Uwoditsu asdanidisgisgi",
+ "HeaderFavoriteArtists": "Dvganidi dinidanolisgisgi",
+ "HeaderFavoriteEpisodes": "Dvganidi didanidilisgadisgisgi",
+ "HeaderFavoriteShows": "Dvganidi didanididanolisgisgi)",
+ "HeaderFavoriteSongs": "Dvganidi danodisgisgi",
+ "HeaderNextUp": "Anidvli uwodoli",
+ "HearingImpaired": "Anitsunidi talunidisgisgi",
+ "ItemAddedWithName": "{0} Dinigwe anididanidisgi",
+ "Latest": "Uwodoli",
+ "MessageApplicationUpdated": "Tsenigwidinonvhi Jellyfin Server tsadanidigwe",
+ "MessageServerConfigurationUpdated": "Sedanidvdi anigadi diganidinonvhi",
+ "Music": "Danodisgisgi",
+ "NameSeasonUnknown": "Tsunita anidvdisgi",
+ "NewVersionIsAvailable": "Danodigwe anigadi Jellyfin Server tsadanidigwe adisdi uwodvdi diganidinonvhi.",
+ "NotificationOptionApplicationUpdateAvailable": "Disisdi tsadanidigwe udvdi",
+ "NotificationOptionApplicationUpdateInstalled": "Disisdi tsadanidigwe digawvdi",
+ "NotificationOptionAudioPlaybackStopped": "Didanidigwe diganuyisgisgi digawvdi",
+ "NotificationOptionCameraImageUploaded": "Asdayi adininisgisgi diganuyisgisgi",
+ "NotificationOptionNewLibraryContent": "Danodisgisgi anigadi digawvdi",
+ "NotificationOptionPluginError": "Ditsigvhnidv anadvnatisgisgi",
+ "NotificationOptionPluginInstalled": "Ditsigvhnidv digawvdi"
+}
diff --git a/Emby.Server.Implementations/Localization/Core/nl.json b/Emby.Server.Implementations/Localization/Core/nl.json
index 4eb00d289..ac7b92de6 100644
--- a/Emby.Server.Implementations/Localization/Core/nl.json
+++ b/Emby.Server.Implementations/Localization/Core/nl.json
@@ -1,9 +1,9 @@
{
"Albums": "Albums",
"AppDeviceValues": "App: {0}, Apparaat: {1}",
- "Application": "Toepassing",
+ "Application": "Applicatie",
"Artists": "Artiesten",
- "AuthenticationSucceededWithUserName": "{0} is succesvol geauthenticeerd",
+ "AuthenticationSucceededWithUserName": "{0} succesvol geauthenticeerd",
"Books": "Boeken",
"CameraImageUploadedFrom": "Nieuwe camera-afbeelding toegevoegd vanaf {0}",
"Channels": "Kanalen",
diff --git a/Emby.Server.Implementations/Localization/Core/sl-SI.json b/Emby.Server.Implementations/Localization/Core/sl-SI.json
index 4c23f71ef..1944e072c 100644
--- a/Emby.Server.Implementations/Localization/Core/sl-SI.json
+++ b/Emby.Server.Implementations/Localization/Core/sl-SI.json
@@ -11,7 +11,7 @@
"Collections": "Zbirke",
"DeviceOfflineWithName": "{0} je prekinil povezavo",
"DeviceOnlineWithName": "{0} je povezan",
- "FailedLoginAttemptWithUserName": "Neuspešen poskus prijave iz {0}",
+ "FailedLoginAttemptWithUserName": "Neuspešen poskus prijave z {0}",
"Favorites": "Priljubljeno",
"Folders": "Mape",
"Genres": "Zvrsti",
diff --git a/Emby.Server.Implementations/Localization/Core/zu.json b/Emby.Server.Implementations/Localization/Core/zu.json
index b5f4b920f..aa056d449 100644
--- a/Emby.Server.Implementations/Localization/Core/zu.json
+++ b/Emby.Server.Implementations/Localization/Core/zu.json
@@ -25,5 +25,14 @@
"Channels": "Amashaneli",
"Books": "Izincwadi",
"Artists": "Abadlali",
- "Albums": "Ama-albhamu"
+ "Albums": "Ama-albhamu",
+ "CameraImageUploadedFrom": "Kulandelayo lwesithonjana sekhamera selithunyelwe kusuka ku {0}",
+ "HeaderFavoriteArtists": "Abasethi Abathandekayo",
+ "HeaderFavoriteEpisodes": "Izilimi Ezithandekayo",
+ "HeaderFavoriteShows": "Izisho Ezithandekayo",
+ "External": "Kwezifungo",
+ "FailedLoginAttemptWithUserName": "Ukushayiswa kwesithombe sokungena okungekho {0}",
+ "HeaderContinueWatching": "Buyela Ukubona",
+ "HeaderFavoriteAlbums": "Izimpahla Ezithandwayo",
+ "HeaderAlbumArtists": "Abasethi wenkulumo"
}
diff --git a/Emby.Server.Implementations/Playlists/PlaylistManager.cs b/Emby.Server.Implementations/Playlists/PlaylistManager.cs
index 702f8d45b..0cb450cdf 100644
--- a/Emby.Server.Implementations/Playlists/PlaylistManager.cs
+++ b/Emby.Server.Implementations/Playlists/PlaylistManager.cs
@@ -518,6 +518,11 @@ namespace Emby.Server.Implementations.Playlists
return relativePath;
}
+ public Folder GetPlaylistsFolder()
+ {
+ return GetPlaylistsFolder(Guid.Empty);
+ }
+
public Folder GetPlaylistsFolder(Guid userId)
{
const string TypeName = "PlaylistsFolder";
diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs
new file mode 100644
index 000000000..acd4bf905
--- /dev/null
+++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionAndPlaylistPathsTask.cs
@@ -0,0 +1,146 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using MediaBrowser.Controller.Collections;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Playlists;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Globalization;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Tasks;
+using Microsoft.Extensions.Logging;
+
+namespace Emby.Server.Implementations.ScheduledTasks.Tasks;
+
+/// <summary>
+/// Deletes path references from collections and playlists that no longer exists.
+/// </summary>
+public class CleanupCollectionAndPlaylistPathsTask : IScheduledTask
+{
+ private readonly ILocalizationManager _localization;
+ private readonly ICollectionManager _collectionManager;
+ private readonly IPlaylistManager _playlistManager;
+ private readonly ILogger<CleanupCollectionAndPlaylistPathsTask> _logger;
+ private readonly IProviderManager _providerManager;
+ private readonly IFileSystem _fileSystem;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CleanupCollectionAndPlaylistPathsTask"/> class.
+ /// </summary>
+ /// <param name="localization">Instance of the <see cref="ILocalizationManager"/> interface.</param>
+ /// <param name="collectionManager">Instance of the <see cref="ICollectionManager"/> interface.</param>
+ /// <param name="playlistManager">Instance of the <see cref="IPlaylistManager"/> interface.</param>
+ /// <param name="logger">The logger.</param>
+ /// <param name="providerManager">The provider manager.</param>
+ /// <param name="fileSystem">The filesystem.</param>
+ public CleanupCollectionAndPlaylistPathsTask(
+ ILocalizationManager localization,
+ ICollectionManager collectionManager,
+ IPlaylistManager playlistManager,
+ ILogger<CleanupCollectionAndPlaylistPathsTask> logger,
+ IProviderManager providerManager,
+ IFileSystem fileSystem)
+ {
+ _localization = localization;
+ _collectionManager = collectionManager;
+ _playlistManager = playlistManager;
+ _logger = logger;
+ _providerManager = providerManager;
+ _fileSystem = fileSystem;
+ }
+
+ /// <inheritdoc />
+ public string Name => _localization.GetLocalizedString("TaskCleanCollectionsAndPlaylists");
+
+ /// <inheritdoc />
+ public string Key => "CleanCollectionsAndPlaylists";
+
+ /// <inheritdoc />
+ public string Description => _localization.GetLocalizedString("TaskCleanCollectionsAndPlaylistsDescription");
+
+ /// <inheritdoc />
+ public string Category => _localization.GetLocalizedString("TasksMaintenanceCategory");
+
+ /// <inheritdoc />
+ public async Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellationToken)
+ {
+ var collectionsFolder = await _collectionManager.GetCollectionsFolder(false).ConfigureAwait(false);
+ if (collectionsFolder is null)
+ {
+ _logger.LogDebug("There is no collections folder to be found");
+ }
+ else
+ {
+ var collections = collectionsFolder.Children.OfType<BoxSet>().ToArray();
+ _logger.LogDebug("Found {CollectionLength} boxsets", collections.Length);
+
+ for (var index = 0; index < collections.Length; index++)
+ {
+ var collection = collections[index];
+ _logger.LogDebug("Checking boxset {CollectionName}", collection.Name);
+
+ CleanupLinkedChildren(collection, cancellationToken);
+ progress.Report(50D / collections.Length * (index + 1));
+ }
+ }
+
+ var playlistsFolder = _playlistManager.GetPlaylistsFolder();
+ if (playlistsFolder is null)
+ {
+ _logger.LogDebug("There is no playlists folder to be found");
+ return;
+ }
+
+ var playlists = playlistsFolder.Children.OfType<Playlist>().ToArray();
+ _logger.LogDebug("Found {PlaylistLength} playlists", playlists.Length);
+
+ for (var index = 0; index < playlists.Length; index++)
+ {
+ var playlist = playlists[index];
+ _logger.LogDebug("Checking playlist {PlaylistName}", playlist.Name);
+
+ CleanupLinkedChildren(playlist, cancellationToken);
+ progress.Report(50D / playlists.Length * (index + 1));
+ }
+ }
+
+ private void CleanupLinkedChildren<T>(T folder, CancellationToken cancellationToken)
+ where T : Folder
+ {
+ List<LinkedChild>? itemsToRemove = null;
+ foreach (var linkedChild in folder.LinkedChildren)
+ {
+ if (!File.Exists(folder.Path))
+ {
+ _logger.LogInformation("Item in {FolderName} cannot be found at {ItemPath}", folder.Name, linkedChild.Path);
+ (itemsToRemove ??= new List<LinkedChild>()).Add(linkedChild);
+ }
+ }
+
+ if (itemsToRemove is not null)
+ {
+ _logger.LogDebug("Updating {FolderName}", folder.Name);
+ folder.LinkedChildren = folder.LinkedChildren.Except(itemsToRemove).ToArray();
+ folder.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, cancellationToken);
+
+ _providerManager.QueueRefresh(
+ folder.Id,
+ new MetadataRefreshOptions(new DirectoryService(_fileSystem))
+ {
+ ForceSave = true
+ },
+ RefreshPriority.High);
+ }
+ }
+
+ /// <inheritdoc />
+ public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
+ {
+ return new[] { new TaskTriggerInfo() { Type = TaskTriggerInfo.TriggerStartup } };
+ }
+}
diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionPathsTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionPathsTask.cs
deleted file mode 100644
index f78fc6f97..000000000
--- a/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanupCollectionPathsTask.cs
+++ /dev/null
@@ -1,119 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Controller.Collections;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.Movies;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Globalization;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Tasks;
-using Microsoft.Extensions.Logging;
-
-namespace Emby.Server.Implementations.ScheduledTasks.Tasks;
-
-/// <summary>
-/// Deletes Path references from collections that no longer exists.
-/// </summary>
-public class CleanupCollectionPathsTask : IScheduledTask
-{
- private readonly ILocalizationManager _localization;
- private readonly ICollectionManager _collectionManager;
- private readonly ILogger<CleanupCollectionPathsTask> _logger;
- private readonly IProviderManager _providerManager;
- private readonly IFileSystem _fileSystem;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="CleanupCollectionPathsTask"/> class.
- /// </summary>
- /// <param name="localization">Instance of the <see cref="ILocalizationManager"/> interface.</param>
- /// <param name="collectionManager">Instance of the <see cref="ICollectionManager"/> interface.</param>
- /// <param name="logger">The logger.</param>
- /// <param name="providerManager">The provider manager.</param>
- /// <param name="fileSystem">The filesystem.</param>
- public CleanupCollectionPathsTask(
- ILocalizationManager localization,
- ICollectionManager collectionManager,
- ILogger<CleanupCollectionPathsTask> logger,
- IProviderManager providerManager,
- IFileSystem fileSystem)
- {
- _localization = localization;
- _collectionManager = collectionManager;
- _logger = logger;
- _providerManager = providerManager;
- _fileSystem = fileSystem;
- }
-
- /// <inheritdoc />
- public string Name => _localization.GetLocalizedString("TaskCleanCollections");
-
- /// <inheritdoc />
- public string Key => "CleanCollections";
-
- /// <inheritdoc />
- public string Description => _localization.GetLocalizedString("TaskCleanCollectionsDescription");
-
- /// <inheritdoc />
- public string Category => _localization.GetLocalizedString("TasksMaintenanceCategory");
-
- /// <inheritdoc />
- public async Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellationToken)
- {
- var collectionsFolder = await _collectionManager.GetCollectionsFolder(false).ConfigureAwait(false);
- if (collectionsFolder is null)
- {
- _logger.LogDebug("There is no collection folder to be found");
- return;
- }
-
- var collections = collectionsFolder.Children.OfType<BoxSet>().ToArray();
- _logger.LogDebug("Found {CollectionLength} Boxsets", collections.Length);
-
- var itemsToRemove = new List<LinkedChild>();
- for (var index = 0; index < collections.Length; index++)
- {
- var collection = collections[index];
- _logger.LogDebug("Check Boxset {CollectionName}", collection.Name);
-
- foreach (var collectionLinkedChild in collection.LinkedChildren)
- {
- if (!File.Exists(collectionLinkedChild.Path))
- {
- _logger.LogInformation("Item in boxset {CollectionName} cannot be found at {ItemPath}", collection.Name, collectionLinkedChild.Path);
- itemsToRemove.Add(collectionLinkedChild);
- }
- }
-
- if (itemsToRemove.Count != 0)
- {
- _logger.LogDebug("Update Boxset {CollectionName}", collection.Name);
- collection.LinkedChildren = collection.LinkedChildren.Except(itemsToRemove).ToArray();
- await collection.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, cancellationToken)
- .ConfigureAwait(false);
-
- _providerManager.QueueRefresh(
- collection.Id,
- new MetadataRefreshOptions(new DirectoryService(_fileSystem))
- {
- ForceSave = true
- },
- RefreshPriority.High);
-
- itemsToRemove.Clear();
- }
-
- progress.Report(100D / collections.Length * (index + 1));
- }
- }
-
- /// <inheritdoc />
- public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
- {
- return new[] { new TaskTriggerInfo() { Type = TaskTriggerInfo.TriggerStartup } };
- }
-}
diff --git a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
index 3271e08e4..89dbbdd2f 100644
--- a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
+++ b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
@@ -59,6 +59,7 @@ namespace Jellyfin.Server.Extensions
serviceCollection.AddSingleton<IAuthorizationHandler, FirstTimeSetupHandler>();
serviceCollection.AddSingleton<IAuthorizationHandler, AnonymousLanAccessHandler>();
serviceCollection.AddSingleton<IAuthorizationHandler, SyncPlayAccessHandler>();
+ serviceCollection.AddSingleton<IAuthorizationHandler, LocalAccessOrRequiresElevationHandler>();
return serviceCollection.AddAuthorizationCore(options =>
{
diff --git a/Jellyfin.Server/Migrations/Routines/MigrateActivityLogDb.cs b/Jellyfin.Server/Migrations/Routines/MigrateActivityLogDb.cs
index c7c9c1250..2f23cb1f8 100644
--- a/Jellyfin.Server/Migrations/Routines/MigrateActivityLogDb.cs
+++ b/Jellyfin.Server/Migrations/Routines/MigrateActivityLogDb.cs
@@ -63,7 +63,10 @@ namespace Jellyfin.Server.Migrations.Routines
var dataPath = _paths.DataPath;
using (var connection = new SqliteConnection($"Filename={Path.Combine(dataPath, DbFilename)}"))
{
+ connection.Open();
+
using var userDbConnection = new SqliteConnection($"Filename={Path.Combine(dataPath, "users.db")}");
+ userDbConnection.Open();
_logger.LogWarning("Migrating the activity database may take a while, do not stop Jellyfin.");
using var dbContext = _provider.CreateDbContext();
diff --git a/Jellyfin.Server/Migrations/Routines/MigrateAuthenticationDb.cs b/Jellyfin.Server/Migrations/Routines/MigrateAuthenticationDb.cs
index 63cbe4950..c845beef2 100644
--- a/Jellyfin.Server/Migrations/Routines/MigrateAuthenticationDb.cs
+++ b/Jellyfin.Server/Migrations/Routines/MigrateAuthenticationDb.cs
@@ -58,6 +58,7 @@ namespace Jellyfin.Server.Migrations.Routines
var dataPath = _appPaths.DataPath;
using (var connection = new SqliteConnection($"Filename={Path.Combine(dataPath, DbFilename)}"))
{
+ connection.Open();
using var dbContext = _dbProvider.CreateDbContext();
var authenticatedDevices = connection.Query("SELECT * FROM Tokens");
diff --git a/Jellyfin.Server/Migrations/Routines/MigrateDisplayPreferencesDb.cs b/Jellyfin.Server/Migrations/Routines/MigrateDisplayPreferencesDb.cs
index a036fe9bb..249b39ae4 100644
--- a/Jellyfin.Server/Migrations/Routines/MigrateDisplayPreferencesDb.cs
+++ b/Jellyfin.Server/Migrations/Routines/MigrateDisplayPreferencesDb.cs
@@ -86,6 +86,7 @@ namespace Jellyfin.Server.Migrations.Routines
var dbFilePath = Path.Combine(_paths.DataPath, DbFilename);
using (var connection = new SqliteConnection($"Filename={dbFilePath}"))
{
+ connection.Open();
using var dbContext = _provider.CreateDbContext();
var results = connection.Query("SELECT * FROM userdisplaypreferences");
diff --git a/Jellyfin.Server/Migrations/Routines/MigrateRatingLevels.cs b/Jellyfin.Server/Migrations/Routines/MigrateRatingLevels.cs
index 06eda329c..996f3fe8a 100644
--- a/Jellyfin.Server/Migrations/Routines/MigrateRatingLevels.cs
+++ b/Jellyfin.Server/Migrations/Routines/MigrateRatingLevels.cs
@@ -66,7 +66,8 @@ namespace Jellyfin.Server.Migrations.Routines
// Migrate parental rating strings to new levels
_logger.LogInformation("Recalculating parental rating levels based on rating string.");
- using (var connection = new SqliteConnection($"Filename={dbPath}"))
+ using var connection = new SqliteConnection($"Filename={dbPath}");
+ connection.Open();
using (var transaction = connection.BeginTransaction())
{
var queryResult = connection.Query("SELECT DISTINCT OfficialRating FROM TypedBaseItems");
diff --git a/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs b/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs
index 9cf888d62..4fee88b68 100644
--- a/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs
+++ b/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs
@@ -66,6 +66,7 @@ namespace Jellyfin.Server.Migrations.Routines
using (var connection = new SqliteConnection($"Filename={Path.Combine(dataPath, DbFilename)}"))
{
+ connection.Open();
var dbContext = _provider.CreateDbContext();
var queryResult = connection.Query("SELECT * FROM LocalUsersv2");
diff --git a/Jellyfin.Server/Migrations/Routines/RemoveDuplicateExtras.cs b/Jellyfin.Server/Migrations/Routines/RemoveDuplicateExtras.cs
index 6c34e1f5b..7b0d9456d 100644
--- a/Jellyfin.Server/Migrations/Routines/RemoveDuplicateExtras.cs
+++ b/Jellyfin.Server/Migrations/Routines/RemoveDuplicateExtras.cs
@@ -38,7 +38,8 @@ namespace Jellyfin.Server.Migrations.Routines
{
var dataPath = _paths.DataPath;
var dbPath = Path.Combine(dataPath, DbFilename);
- using (var connection = new SqliteConnection($"Filename={dbPath}"))
+ using var connection = new SqliteConnection($"Filename={dbPath}");
+ connection.Open();
using (var transaction = connection.BeginTransaction())
{
// Query the database for the ids of duplicate extras
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
index e619e690d..b6e680ab9 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
@@ -3822,12 +3822,6 @@ namespace MediaBrowser.Controller.MediaEncoding
// map from d3d11va to qsv.
mainFilters.Add("hwmap=derive_device=qsv");
}
- else
- {
- // Insert a qsv scaler to sync the decoder surface,
- // msdk will passthrough this internally.
- mainFilters.Add("hwmap=derive_device=qsv,scale_qsv");
- }
}
// hw deint
@@ -5252,10 +5246,8 @@ namespace MediaBrowser.Controller.MediaEncoding
if (isD3d11Supported && isCodecAvailable)
{
- // set -threads 3 to intel d3d11va decoder explicitly. Lower threads may result in dead lock.
- // on newer devices such as Xe, the larger the init_pool_size, the longer the initialization time for opencl to derive from d3d11.
return " -hwaccel d3d11va" + (outputHwSurface ? " -hwaccel_output_format d3d11" : string.Empty)
- + (profileMismatch ? " -hwaccel_flags +allow_profile_mismatch" : string.Empty) + " -threads 3" + (isAv1 ? " -c:v av1" : string.Empty);
+ + (profileMismatch ? " -hwaccel_flags +allow_profile_mismatch" : string.Empty) + " -threads 2" + (isAv1 ? " -c:v av1" : string.Empty);
}
}
else
diff --git a/MediaBrowser.Controller/Playlists/IPlaylistManager.cs b/MediaBrowser.Controller/Playlists/IPlaylistManager.cs
index d1a51c2cf..bb68a3b6d 100644
--- a/MediaBrowser.Controller/Playlists/IPlaylistManager.cs
+++ b/MediaBrowser.Controller/Playlists/IPlaylistManager.cs
@@ -44,6 +44,12 @@ namespace MediaBrowser.Controller.Playlists
/// <summary>
/// Gets the playlists folder.
/// </summary>
+ /// <returns>Folder.</returns>
+ Folder GetPlaylistsFolder();
+
+ /// <summary>
+ /// Gets the playlists folder for a user.
+ /// </summary>
/// <param name="userId">The user identifier.</param>
/// <returns>Folder.</returns>
Folder GetPlaylistsFolder(Guid userId);
diff --git a/MediaBrowser.Model/IO/IFileSystem.cs b/MediaBrowser.Model/IO/IFileSystem.cs
index 786b20e9e..5bdda2b24 100644
--- a/MediaBrowser.Model/IO/IFileSystem.cs
+++ b/MediaBrowser.Model/IO/IFileSystem.cs
@@ -117,13 +117,6 @@ namespace MediaBrowser.Model.IO
bool ContainsSubPath(string parentPath, string path);
/// <summary>
- /// Normalizes the path.
- /// </summary>
- /// <param name="path">The path.</param>
- /// <returns>System.String.</returns>
- string NormalizePath(string path);
-
- /// <summary>
/// Gets the file name without extension.
/// </summary>
/// <param name="info">The information.</param>
diff --git a/deployment/Dockerfile.centos.amd64 b/deployment/Dockerfile.centos.amd64
index 28b6310ef..28cf585e9 100644
--- a/deployment/Dockerfile.centos.amd64
+++ b/deployment/Dockerfile.centos.amd64
@@ -13,7 +13,7 @@ RUN yum update -yq \
&& yum install -yq @buildsys-build rpmdevtools yum-plugins-core libcurl-devel fontconfig-devel freetype-devel openssl-devel glibc-devel libicu-devel git wget
# Install DotNET SDK
-RUN wget -q https://download.visualstudio.microsoft.com/download/pr/dbfe6cc7-dd82-4cec-b267-31ed988b1652/c60ab4793c3714be878abcb9aa834b63/dotnet-sdk-7.0.400-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
+RUN wget -q https://download.visualstudio.microsoft.com/download/pr/61f29db0-10a5-4816-8fd8-ca2f71beaea3/e15fb7288eb5bc0053b91ea7b0bfd580/dotnet-sdk-7.0.401-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
&& mkdir -p dotnet-sdk \
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
diff --git a/deployment/Dockerfile.fedora.amd64 b/deployment/Dockerfile.fedora.amd64
index 8a5258714..0e8166f46 100644
--- a/deployment/Dockerfile.fedora.amd64
+++ b/deployment/Dockerfile.fedora.amd64
@@ -12,7 +12,7 @@ RUN dnf update -yq \
&& dnf install -yq @buildsys-build rpmdevtools git dnf-plugins-core libcurl-devel fontconfig-devel freetype-devel openssl-devel glibc-devel libicu-devel systemd wget make
# Install DotNET SDK
-RUN wget -q https://download.visualstudio.microsoft.com/download/pr/dbfe6cc7-dd82-4cec-b267-31ed988b1652/c60ab4793c3714be878abcb9aa834b63/dotnet-sdk-7.0.400-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
+RUN wget -q https://download.visualstudio.microsoft.com/download/pr/61f29db0-10a5-4816-8fd8-ca2f71beaea3/e15fb7288eb5bc0053b91ea7b0bfd580/dotnet-sdk-7.0.401-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
&& mkdir -p dotnet-sdk \
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
diff --git a/deployment/Dockerfile.ubuntu.amd64 b/deployment/Dockerfile.ubuntu.amd64
index e06179ac9..04c748d09 100644
--- a/deployment/Dockerfile.ubuntu.amd64
+++ b/deployment/Dockerfile.ubuntu.amd64
@@ -17,7 +17,7 @@ RUN apt-get update -yqq \
libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0
# Install dotnet repository
-RUN wget -q https://download.visualstudio.microsoft.com/download/pr/dbfe6cc7-dd82-4cec-b267-31ed988b1652/c60ab4793c3714be878abcb9aa834b63/dotnet-sdk-7.0.400-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
+RUN wget -q https://download.visualstudio.microsoft.com/download/pr/61f29db0-10a5-4816-8fd8-ca2f71beaea3/e15fb7288eb5bc0053b91ea7b0bfd580/dotnet-sdk-7.0.401-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
&& mkdir -p dotnet-sdk \
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
diff --git a/deployment/Dockerfile.ubuntu.arm64 b/deployment/Dockerfile.ubuntu.arm64
index 964c3fca7..5bc197679 100644
--- a/deployment/Dockerfile.ubuntu.arm64
+++ b/deployment/Dockerfile.ubuntu.arm64
@@ -16,7 +16,7 @@ RUN apt-get update -yqq \
mmv build-essential lsb-release
# Install dotnet repository
-RUN wget -q https://download.visualstudio.microsoft.com/download/pr/dbfe6cc7-dd82-4cec-b267-31ed988b1652/c60ab4793c3714be878abcb9aa834b63/dotnet-sdk-7.0.400-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
+RUN wget -q https://download.visualstudio.microsoft.com/download/pr/61f29db0-10a5-4816-8fd8-ca2f71beaea3/e15fb7288eb5bc0053b91ea7b0bfd580/dotnet-sdk-7.0.401-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
&& mkdir -p dotnet-sdk \
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
diff --git a/deployment/Dockerfile.ubuntu.armhf b/deployment/Dockerfile.ubuntu.armhf
index 4eb1343ac..fab869a6b 100644
--- a/deployment/Dockerfile.ubuntu.armhf
+++ b/deployment/Dockerfile.ubuntu.armhf
@@ -16,7 +16,7 @@ RUN apt-get update -yqq \
mmv build-essential lsb-release
# Install dotnet repository
-RUN wget -q https://download.visualstudio.microsoft.com/download/pr/dbfe6cc7-dd82-4cec-b267-31ed988b1652/c60ab4793c3714be878abcb9aa834b63/dotnet-sdk-7.0.400-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
+RUN wget -q https://download.visualstudio.microsoft.com/download/pr/61f29db0-10a5-4816-8fd8-ca2f71beaea3/e15fb7288eb5bc0053b91ea7b0bfd580/dotnet-sdk-7.0.401-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
&& mkdir -p dotnet-sdk \
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
diff --git a/fedora/jellyfin-selinux-launcher.sh b/fedora/jellyfin-selinux-launcher.sh
index a735a238f..e07a351d9 100644
--- a/fedora/jellyfin-selinux-launcher.sh
+++ b/fedora/jellyfin-selinux-launcher.sh
@@ -1,3 +1,3 @@
#!/bin/sh
-exec /usr/lib64/jellyfin/jellyfin ${@}
+exec /usr/lib64/jellyfin/jellyfin "${@}"
diff --git a/jellyfin.ruleset b/jellyfin.ruleset
index 505d35481..870cf253f 100644
--- a/jellyfin.ruleset
+++ b/jellyfin.ruleset
@@ -52,6 +52,8 @@
<Rule Id="SA1204" Action="None" />
<!-- disable warning SA1309: Fields must not begin with an underscore -->
<Rule Id="SA1309" Action="None" />
+ <!-- disable warning SA1311: Static readonly fields should begin with upper-case letter -->
+ <Rule Id="SA1311" Action="None" />
<!-- disable warning SA1413: Use trailing comma in multi-line initializers -->
<Rule Id="SA1413" Action="None" />
<!-- disable warning SA1512: Single-line comments must not be followed by blank line -->
@@ -171,4 +173,18 @@
<!-- error on RS0030: Do not used banned APIs -->
<Rule Id="RS0030" Action="Error" />
</Rules>
+
+ <Rules AnalyzerId="IDisposableAnalyzers" RuleNamespace="IDisposableAnalyzers.Correctness">
+ <!-- disable warning IDISP001: Dispose created -->
+ <Rule Id="IDISP001" Action="Info" />
+ <!-- TODO: Enable when false positives are fixed -->
+ <!-- disable warning IDISP003: Dispose previous before re-assigning -->
+ <Rule Id="IDISP003" Action="Info" />
+ <!-- disable warning IDISP004: Don't ignore created IDisposable -->
+ <Rule Id="IDISP004" Action="Info" />
+ <!-- disable warning IDISP007: Don't dispose injected -->
+ <Rule Id="IDISP007" Action="Info" />
+ <!-- disable warning IDISP008: Don't assign member with injected and created disposables -->
+ <Rule Id="IDISP008" Action="Info" />
+ </Rules>
</RuleSet>
diff --git a/src/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj b/src/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj
index 034691322..c465c4ad0 100644
--- a/src/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj
+++ b/src/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj
@@ -31,8 +31,12 @@
<ProjectReference Include="..\..\MediaBrowser.Common\MediaBrowser.Common.csproj" />
</ItemGroup>
- <!-- Code analysers-->
+ <!-- Code Analyzers-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
+ <PackageReference Include="IDisposableAnalyzers">
+ <PrivateAssets>all</PrivateAssets>
+ <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
+ </PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
diff --git a/src/Jellyfin.Drawing.Skia/SkiaEncoder.cs b/src/Jellyfin.Drawing.Skia/SkiaEncoder.cs
index 5a1d3dc5f..126c0503e 100644
--- a/src/Jellyfin.Drawing.Skia/SkiaEncoder.cs
+++ b/src/Jellyfin.Drawing.Skia/SkiaEncoder.cs
@@ -122,8 +122,8 @@ public class SkiaEncoder : IImageEncoder
var svg = new SKSvg();
try
{
- svg.Load(path);
- return new ImageDimensions(Convert.ToInt32(svg.Picture.CullRect.Width), Convert.ToInt32(svg.Picture.CullRect.Height));
+ using var picture = svg.Load(path);
+ return new ImageDimensions(Convert.ToInt32(picture.CullRect.Width), Convert.ToInt32(picture.CullRect.Height));
}
catch (FormatException skiaColorException)
{
@@ -432,7 +432,8 @@ public class SkiaEncoder : IImageEncoder
// scale image (the FromImage creates a copy)
var imageInfo = new SKImageInfo(width, height, bitmap.ColorType, bitmap.AlphaType, bitmap.ColorSpace);
- using var resizedBitmap = SKBitmap.FromImage(ResizeImage(bitmap, imageInfo));
+ using var resizedImage = ResizeImage(bitmap, imageInfo);
+ using var resizedBitmap = SKBitmap.FromImage(resizedImage);
// If all we're doing is resizing then we can stop now
if (!hasBackgroundColor && !hasForegroundColor && blur == 0 && !hasIndicator)
diff --git a/src/Jellyfin.Drawing.Skia/SkiaHelper.cs b/src/Jellyfin.Drawing.Skia/SkiaHelper.cs
index 00d224da9..bd1b2b0da 100644
--- a/src/Jellyfin.Drawing.Skia/SkiaHelper.cs
+++ b/src/Jellyfin.Drawing.Skia/SkiaHelper.cs
@@ -19,7 +19,6 @@ public static class SkiaHelper
public static SKBitmap? GetNextValidImage(SkiaEncoder skiaEncoder, IReadOnlyList<string> paths, int currentIndex, out int newIndex)
{
var imagesTested = new Dictionary<int, int>();
- SKBitmap? bitmap = null;
while (imagesTested.Count < paths.Count)
{
@@ -28,7 +27,7 @@ public static class SkiaHelper
currentIndex = 0;
}
- bitmap = skiaEncoder.Decode(paths[currentIndex], false, null, out _);
+ SKBitmap? bitmap = skiaEncoder.Decode(paths[currentIndex], false, null, out _);
imagesTested[currentIndex] = 0;
@@ -36,11 +35,12 @@ public static class SkiaHelper
if (bitmap is not null)
{
- break;
+ newIndex = currentIndex;
+ return bitmap;
}
}
newIndex = currentIndex;
- return bitmap;
+ return null;
}
}
diff --git a/src/Jellyfin.Drawing.Skia/StripCollageBuilder.cs b/src/Jellyfin.Drawing.Skia/StripCollageBuilder.cs
index a8f80f7e2..6dff7aa9b 100644
--- a/src/Jellyfin.Drawing.Skia/StripCollageBuilder.cs
+++ b/src/Jellyfin.Drawing.Skia/StripCollageBuilder.cs
@@ -189,12 +189,12 @@ public partial class StripCollageBuilder
// Scale image. The FromBitmap creates a copy
var imageInfo = new SKImageInfo(cellWidth, cellHeight, currentBitmap.ColorType, currentBitmap.AlphaType, currentBitmap.ColorSpace);
- using var resizedBitmap = SKBitmap.FromImage(SkiaEncoder.ResizeImage(currentBitmap, imageInfo));
+ using var resizeImage = SkiaEncoder.ResizeImage(currentBitmap, imageInfo);
// draw this image into the strip at the next position
var xPos = x * cellWidth;
var yPos = y * cellHeight;
- canvas.DrawBitmap(resizedBitmap, xPos, yPos);
+ canvas.DrawImage(resizeImage, xPos, yPos);
}
}
diff --git a/src/Jellyfin.Drawing/Jellyfin.Drawing.csproj b/src/Jellyfin.Drawing/Jellyfin.Drawing.csproj
index e0963ac34..2a5e24a44 100644
--- a/src/Jellyfin.Drawing/Jellyfin.Drawing.csproj
+++ b/src/Jellyfin.Drawing/Jellyfin.Drawing.csproj
@@ -21,8 +21,12 @@
<Compile Include="..\..\SharedVersion.cs" />
</ItemGroup>
- <!-- Code analysers-->
+ <!-- Code Analyzers-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
+ <PackageReference Include="IDisposableAnalyzers">
+ <PrivateAssets>all</PrivateAssets>
+ <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
+ </PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
diff --git a/src/Jellyfin.Extensions/Jellyfin.Extensions.csproj b/src/Jellyfin.Extensions/Jellyfin.Extensions.csproj
index 4f80aa941..36ae55ed2 100644
--- a/src/Jellyfin.Extensions/Jellyfin.Extensions.csproj
+++ b/src/Jellyfin.Extensions/Jellyfin.Extensions.csproj
@@ -34,6 +34,10 @@
<!-- Code Analyzers-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
+ <PackageReference Include="IDisposableAnalyzers">
+ <PrivateAssets>all</PrivateAssets>
+ <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
+ </PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
diff --git a/src/Jellyfin.MediaEncoding.Hls/Jellyfin.MediaEncoding.Hls.csproj b/src/Jellyfin.MediaEncoding.Hls/Jellyfin.MediaEncoding.Hls.csproj
index 3f4f55ee4..b792e7ec6 100644
--- a/src/Jellyfin.MediaEncoding.Hls/Jellyfin.MediaEncoding.Hls.csproj
+++ b/src/Jellyfin.MediaEncoding.Hls/Jellyfin.MediaEncoding.Hls.csproj
@@ -7,6 +7,10 @@
<!-- Code Analyzers-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
+ <PackageReference Include="IDisposableAnalyzers">
+ <PrivateAssets>all</PrivateAssets>
+ <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
+ </PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
diff --git a/src/Jellyfin.MediaEncoding.Keyframes/Jellyfin.MediaEncoding.Keyframes.csproj b/src/Jellyfin.MediaEncoding.Keyframes/Jellyfin.MediaEncoding.Keyframes.csproj
index 71572bcf6..09b1f8faa 100644
--- a/src/Jellyfin.MediaEncoding.Keyframes/Jellyfin.MediaEncoding.Keyframes.csproj
+++ b/src/Jellyfin.MediaEncoding.Keyframes/Jellyfin.MediaEncoding.Keyframes.csproj
@@ -11,6 +11,10 @@
<!-- Code Analyzers-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
+ <PackageReference Include="IDisposableAnalyzers">
+ <PrivateAssets>all</PrivateAssets>
+ <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
+ </PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
diff --git a/tests/Jellyfin.MediaEncoding.Tests/Subtitles/SubtitleEncoderTests.cs b/tests/Jellyfin.MediaEncoding.Tests/Subtitles/SubtitleEncoderTests.cs
index 9ace80bbd..ce1f005f4 100644
--- a/tests/Jellyfin.MediaEncoding.Tests/Subtitles/SubtitleEncoderTests.cs
+++ b/tests/Jellyfin.MediaEncoding.Tests/Subtitles/SubtitleEncoderTests.cs
@@ -97,7 +97,7 @@ namespace Jellyfin.MediaEncoding.Subtitles.Tests
{
var fixture = new Fixture().Customize(new AutoMoqCustomization { ConfigureMembers = true });
var subtitleEncoder = fixture.Create<SubtitleEncoder>();
- var result = await subtitleEncoder.GetReadableFile(mediaSource, subtitleStream, CancellationToken.None).ConfigureAwait(false);
+ var result = await subtitleEncoder.GetReadableFile(mediaSource, subtitleStream, CancellationToken.None);
Assert.Equal(subtitleInfo.Path, result.Path);
Assert.Equal(subtitleInfo.Protocol, result.Protocol);
Assert.Equal(subtitleInfo.Format, result.Format);
diff --git a/tests/Jellyfin.Providers.Tests/Manager/ProviderManagerTests.cs b/tests/Jellyfin.Providers.Tests/Manager/ProviderManagerTests.cs
index 400e30bd6..1e0851993 100644
--- a/tests/Jellyfin.Providers.Tests/Manager/ProviderManagerTests.cs
+++ b/tests/Jellyfin.Providers.Tests/Manager/ProviderManagerTests.cs
@@ -82,7 +82,7 @@ namespace Jellyfin.Providers.Tests.Manager
AddParts(providerManager, metadataServices: servicesList.Select(s => s.Object).ToArray());
var refreshOptions = new MetadataRefreshOptions(Mock.Of<IDirectoryService>(MockBehavior.Strict));
- var actual = await providerManager.RefreshSingleItem(item, refreshOptions, CancellationToken.None).ConfigureAwait(false);
+ var actual = await providerManager.RefreshSingleItem(item, refreshOptions, CancellationToken.None);
Assert.Equal(ItemUpdateType.MetadataDownload, actual);
for (var i = 0; i < servicesList.Length; i++)
@@ -105,7 +105,7 @@ namespace Jellyfin.Providers.Tests.Manager
AddParts(providerManager, metadataServices: servicesList.Select(s => s.Object).ToArray());
var refreshOptions = new MetadataRefreshOptions(Mock.Of<IDirectoryService>(MockBehavior.Strict));
- var actual = await providerManager.RefreshSingleItem(item, refreshOptions, CancellationToken.None).ConfigureAwait(false);
+ var actual = await providerManager.RefreshSingleItem(item, refreshOptions, CancellationToken.None);
var expectedResult = serviceFound ? ItemUpdateType.MetadataDownload : ItemUpdateType.None;
Assert.Equal(expectedResult, actual);
diff --git a/tests/Jellyfin.Server.Implementations.Tests/LiveTv/HdHomerunHostTests.cs b/tests/Jellyfin.Server.Implementations.Tests/LiveTv/HdHomerunHostTests.cs
index c859d11c6..13ac3ddb0 100644
--- a/tests/Jellyfin.Server.Implementations.Tests/LiveTv/HdHomerunHostTests.cs
+++ b/tests/Jellyfin.Server.Implementations.Tests/LiveTv/HdHomerunHostTests.cs
@@ -52,7 +52,7 @@ namespace Jellyfin.Server.Implementations.Tests.LiveTv
Url = "192.168.1.182"
};
- var modelInfo = await _hdHomerunHost.GetModelInfo(host, true, CancellationToken.None).ConfigureAwait(false);
+ var modelInfo = await _hdHomerunHost.GetModelInfo(host, true, CancellationToken.None);
Assert.Equal("HDHomeRun PRIME", modelInfo.FriendlyName);
Assert.Equal("HDHR3-CC", modelInfo.ModelNumber);
Assert.Equal("hdhomerun3_cablecard", modelInfo.FirmwareName);
@@ -72,7 +72,7 @@ namespace Jellyfin.Server.Implementations.Tests.LiveTv
Url = "10.10.10.100"
};
- var modelInfo = await _hdHomerunHost.GetModelInfo(host, true, CancellationToken.None).ConfigureAwait(false);
+ var modelInfo = await _hdHomerunHost.GetModelInfo(host, true, CancellationToken.None);
Assert.Equal("HDHomeRun DUAL", modelInfo.FriendlyName);
Assert.Equal("HDHR3-US", modelInfo.ModelNumber);
Assert.Equal("hdhomerun3_atsc", modelInfo.FirmwareName);
@@ -103,7 +103,7 @@ namespace Jellyfin.Server.Implementations.Tests.LiveTv
Url = "192.168.1.182"
};
- var channels = await _hdHomerunHost.GetLineup(host, CancellationToken.None).ConfigureAwait(false);
+ var channels = await _hdHomerunHost.GetLineup(host, CancellationToken.None);
Assert.Equal(6, channels.Count);
Assert.Equal("4.1", channels[0].GuideNumber);
Assert.Equal("WCMH-DT", channels[0].GuideName);
@@ -133,7 +133,7 @@ namespace Jellyfin.Server.Implementations.Tests.LiveTv
ImportFavoritesOnly = true
};
- var channels = await _hdHomerunHost.GetLineup(host, CancellationToken.None).ConfigureAwait(false);
+ var channels = await _hdHomerunHost.GetLineup(host, CancellationToken.None);
Assert.Single(channels);
Assert.Equal("4.1", channels[0].GuideNumber);
Assert.Equal("WCMH-DT", channels[0].GuideName);
@@ -145,7 +145,7 @@ namespace Jellyfin.Server.Implementations.Tests.LiveTv
[Fact]
public async Task TryGetTunerHostInfo_Valid_Success()
{
- var host = await _hdHomerunHost.TryGetTunerHostInfo("192.168.1.182", CancellationToken.None).ConfigureAwait(false);
+ var host = await _hdHomerunHost.TryGetTunerHostInfo("192.168.1.182", CancellationToken.None);
Assert.Equal(_hdHomerunHost.Type, host.Type);
Assert.Equal("192.168.1.182", host.Url);
Assert.Equal("HDHomeRun PRIME", host.FriendlyName);
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Updates/InstallationManagerTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Updates/InstallationManagerTests.cs
index 7abd2e685..5caf7d124 100644
--- a/tests/Jellyfin.Server.Implementations.Tests/Updates/InstallationManagerTests.cs
+++ b/tests/Jellyfin.Server.Implementations.Tests/Updates/InstallationManagerTests.cs
@@ -90,7 +90,7 @@ namespace Jellyfin.Server.Implementations.Tests.Updates
Checksum = "InvalidChecksum"
};
- await Assert.ThrowsAsync<InvalidDataException>(() => _installationManager.InstallPackage(packageInfo, CancellationToken.None)).ConfigureAwait(false);
+ await Assert.ThrowsAsync<InvalidDataException>(() => _installationManager.InstallPackage(packageInfo, CancellationToken.None));
}
[Fact]
@@ -103,7 +103,7 @@ namespace Jellyfin.Server.Implementations.Tests.Updates
Checksum = "11b5b2f1a9ebc4f66d6ef19018543361"
};
- var ex = await Record.ExceptionAsync(() => _installationManager.InstallPackage(packageInfo, CancellationToken.None)).ConfigureAwait(false);
+ var ex = await Record.ExceptionAsync(() => _installationManager.InstallPackage(packageInfo, CancellationToken.None));
Assert.Null(ex);
}
}
diff --git a/tests/Jellyfin.Server.Integration.Tests/AuthHelper.cs b/tests/Jellyfin.Server.Integration.Tests/AuthHelper.cs
index 3737fee0a..3dc62afaf 100644
--- a/tests/Jellyfin.Server.Integration.Tests/AuthHelper.cs
+++ b/tests/Jellyfin.Server.Integration.Tests/AuthHelper.cs
@@ -21,10 +21,10 @@ namespace Jellyfin.Server.Integration.Tests
public static async Task<string> CompleteStartupAsync(HttpClient client)
{
var jsonOptions = JsonDefaults.Options;
- var userResponse = await client.GetByteArrayAsync("/Startup/User").ConfigureAwait(false);
+ var userResponse = await client.GetByteArrayAsync("/Startup/User");
var user = JsonSerializer.Deserialize<StartupUserDto>(userResponse, jsonOptions);
- using var completeResponse = await client.PostAsync("/Startup/Complete", new ByteArrayContent(Array.Empty<byte>())).ConfigureAwait(false);
+ using var completeResponse = await client.PostAsync("/Startup/Complete", new ByteArrayContent(Array.Empty<byte>()));
Assert.Equal(HttpStatusCode.NoContent, completeResponse.StatusCode);
using var content = JsonContent.Create(
@@ -36,20 +36,20 @@ namespace Jellyfin.Server.Integration.Tests
options: jsonOptions);
content.Headers.Add("X-Emby-Authorization", DummyAuthHeader);
- using var authResponse = await client.PostAsync("/Users/AuthenticateByName", content).ConfigureAwait(false);
+ using var authResponse = await client.PostAsync("/Users/AuthenticateByName", content);
var auth = await JsonSerializer.DeserializeAsync<AuthenticationResultDto>(
- await authResponse.Content.ReadAsStreamAsync().ConfigureAwait(false),
- jsonOptions).ConfigureAwait(false);
+ await authResponse.Content.ReadAsStreamAsync(),
+ jsonOptions);
return auth!.AccessToken;
}
public static async Task<UserDto> GetUserDtoAsync(HttpClient client)
{
- using var response = await client.GetAsync("Users/Me").ConfigureAwait(false);
+ using var response = await client.GetAsync("Users/Me");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var userDto = await JsonSerializer.DeserializeAsync<UserDto>(
- await response.Content.ReadAsStreamAsync().ConfigureAwait(false), JsonDefaults.Options).ConfigureAwait(false);
+ await response.Content.ReadAsStreamAsync(), JsonDefaults.Options);
Assert.NotNull(userDto);
return userDto;
}
@@ -58,15 +58,15 @@ namespace Jellyfin.Server.Integration.Tests
{
if (userId.Equals(default))
{
- var userDto = await GetUserDtoAsync(client).ConfigureAwait(false);
+ var userDto = await GetUserDtoAsync(client);
userId = userDto.Id;
}
- var response = await client.GetAsync($"Users/{userId}/Items/Root").ConfigureAwait(false);
+ var response = await client.GetAsync($"Users/{userId}/Items/Root");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var rootDto = await JsonSerializer.DeserializeAsync<BaseItemDto>(
- await response.Content.ReadAsStreamAsync().ConfigureAwait(false),
- JsonDefaults.Options).ConfigureAwait(false);
+ await response.Content.ReadAsStreamAsync(),
+ JsonDefaults.Options);
Assert.NotNull(rootDto);
return rootDto;
}
diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/ActivityLogControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/ActivityLogControllerTests.cs
index be89fbc9a..96ca96558 100644
--- a/tests/Jellyfin.Server.Integration.Tests/Controllers/ActivityLogControllerTests.cs
+++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/ActivityLogControllerTests.cs
@@ -19,9 +19,9 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public async Task ActivityLog_GetEntries_Ok()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var response = await client.GetAsync("System/ActivityLog/Entries").ConfigureAwait(false);
+ var response = await client.GetAsync("System/ActivityLog/Entries");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType);
diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/DashboardControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/DashboardControllerTests.cs
index 52df1cd60..bd6e1b690 100644
--- a/tests/Jellyfin.Server.Integration.Tests/Controllers/DashboardControllerTests.cs
+++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/DashboardControllerTests.cs
@@ -26,7 +26,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
{
var client = _factory.CreateClient();
- var response = await client.GetAsync("web/ConfigurationPage?name=ThisPageDoesntExists").ConfigureAwait(false);
+ var response = await client.GetAsync("web/ConfigurationPage?name=ThisPageDoesntExists");
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
@@ -36,12 +36,12 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
{
var client = _factory.CreateClient();
- var response = await client.GetAsync("/web/ConfigurationPage?name=TestPlugin").ConfigureAwait(false);
+ var response = await client.GetAsync("/web/ConfigurationPage?name=TestPlugin");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(MediaTypeNames.Text.Html, response.Content.Headers.ContentType?.MediaType);
StreamReader reader = new StreamReader(typeof(TestPlugin).Assembly.GetManifestResourceStream("Jellyfin.Server.Integration.Tests.TestPage.html")!);
- Assert.Equal(await response.Content.ReadAsStringAsync().ConfigureAwait(false), await reader.ReadToEndAsync().ConfigureAwait(false));
+ Assert.Equal(await response.Content.ReadAsStringAsync(), await reader.ReadToEndAsync());
}
[Fact]
@@ -49,7 +49,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
{
var client = _factory.CreateClient();
- var response = await client.GetAsync("/web/ConfigurationPage?name=BrokenPage").ConfigureAwait(false);
+ var response = await client.GetAsync("/web/ConfigurationPage?name=BrokenPage");
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
@@ -58,9 +58,9 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public async Task GetConfigurationPages_NoParams_AllConfigurationPages()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var response = await client.GetAsync("/web/ConfigurationPages").ConfigureAwait(false);
+ var response = await client.GetAsync("/web/ConfigurationPages");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
@@ -73,9 +73,9 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public async Task GetConfigurationPages_True_MainMenuConfigurationPages()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var response = await client.GetAsync("/web/ConfigurationPages?enableInMainMenu=true").ConfigureAwait(false);
+ var response = await client.GetAsync("/web/ConfigurationPages?enableInMainMenu=true");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType);
diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/DlnaControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/DlnaControllerTests.cs
index a65f65bb2..65e70caa0 100644
--- a/tests/Jellyfin.Server.Integration.Tests/Controllers/DlnaControllerTests.cs
+++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/DlnaControllerTests.cs
@@ -32,9 +32,9 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public async Task GetProfile_DoesNotExist_NotFound()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- using var response = await client.GetAsync("/Dlna/Profiles/" + NonExistentProfile).ConfigureAwait(false);
+ using var response = await client.GetAsync("/Dlna/Profiles/" + NonExistentProfile);
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
@@ -43,9 +43,9 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public async Task DeleteProfile_DoesNotExist_NotFound()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- using var response = await client.DeleteAsync("/Dlna/Profiles/" + NonExistentProfile).ConfigureAwait(false);
+ using var response = await client.DeleteAsync("/Dlna/Profiles/" + NonExistentProfile);
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
@@ -54,14 +54,14 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public async Task UpdateProfile_DoesNotExist_NotFound()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
var deviceProfile = new DeviceProfile()
{
Name = "ThisProfileDoesNotExist"
};
- using var response = await client.PostAsJsonAsync("/Dlna/Profiles/" + NonExistentProfile, deviceProfile, _jsonOptions).ConfigureAwait(false);
+ using var response = await client.PostAsJsonAsync("/Dlna/Profiles/" + NonExistentProfile, deviceProfile, _jsonOptions);
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
@@ -70,14 +70,14 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public async Task CreateProfile_Valid_NoContent()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
var deviceProfile = new DeviceProfile()
{
Name = "ThisProfileIsNew"
};
- using var response = await client.PostAsJsonAsync("/Dlna/Profiles", deviceProfile, _jsonOptions).ConfigureAwait(false);
+ using var response = await client.PostAsJsonAsync("/Dlna/Profiles", deviceProfile, _jsonOptions);
Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
}
@@ -86,16 +86,16 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public async Task GetProfileInfos_Valid_ContainsThisProfileIsNew()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- using var response = await client.GetAsync("/Dlna/ProfileInfos").ConfigureAwait(false);
+ using var response = await client.GetAsync("/Dlna/ProfileInfos");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType);
Assert.Equal(Encoding.UTF8.BodyName, response.Content.Headers.ContentType?.CharSet);
var profiles = await JsonSerializer.DeserializeAsync<DeviceProfileInfo[]>(
- await response.Content.ReadAsStreamAsync().ConfigureAwait(false),
- _jsonOptions).ConfigureAwait(false);
+ await response.Content.ReadAsStreamAsync(),
+ _jsonOptions);
var newProfile = profiles?.FirstOrDefault(x => string.Equals(x.Name, "ThisProfileIsNew", StringComparison.Ordinal));
Assert.NotNull(newProfile);
@@ -107,7 +107,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public async Task UpdateProfile_Valid_NoContent()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
var updatedProfile = new DeviceProfile()
{
@@ -115,18 +115,18 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
Id = _newDeviceProfileId
};
- using var postResponse = await client.PostAsJsonAsync("/Dlna/Profiles/" + _newDeviceProfileId, updatedProfile, _jsonOptions).ConfigureAwait(false);
+ using var postResponse = await client.PostAsJsonAsync("/Dlna/Profiles/" + _newDeviceProfileId, updatedProfile, _jsonOptions);
Assert.Equal(HttpStatusCode.NoContent, postResponse.StatusCode);
// Verify that the profile got updated
- using var response = await client.GetAsync("/Dlna/ProfileInfos").ConfigureAwait(false);
+ using var response = await client.GetAsync("/Dlna/ProfileInfos");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType);
Assert.Equal(Encoding.UTF8.BodyName, response.Content.Headers.ContentType?.CharSet);
var profiles = await JsonSerializer.DeserializeAsync<DeviceProfileInfo[]>(
- await response.Content.ReadAsStreamAsync().ConfigureAwait(false),
- _jsonOptions).ConfigureAwait(false);
+ await response.Content.ReadAsStreamAsync(),
+ _jsonOptions);
Assert.Null(profiles?.FirstOrDefault(x => string.Equals(x.Name, "ThisProfileIsNew", StringComparison.Ordinal)));
var newProfile = profiles?.FirstOrDefault(x => string.Equals(x.Name, "ThisProfileIsUpdated", StringComparison.Ordinal));
@@ -139,20 +139,20 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public async Task DeleteProfile_Valid_NoContent()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- using var deleteResponse = await client.DeleteAsync("/Dlna/Profiles/" + _newDeviceProfileId).ConfigureAwait(false);
+ using var deleteResponse = await client.DeleteAsync("/Dlna/Profiles/" + _newDeviceProfileId);
Assert.Equal(HttpStatusCode.NoContent, deleteResponse.StatusCode);
// Verify that the profile got deleted
- using var response = await client.GetAsync("/Dlna/ProfileInfos").ConfigureAwait(false);
+ using var response = await client.GetAsync("/Dlna/ProfileInfos");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(MediaTypeNames.Application.Json, response.Content.Headers.ContentType?.MediaType);
Assert.Equal(Encoding.UTF8.BodyName, response.Content.Headers.ContentType?.CharSet);
var profiles = await JsonSerializer.DeserializeAsync<DeviceProfileInfo[]>(
- await response.Content.ReadAsStreamAsync().ConfigureAwait(false),
- _jsonOptions).ConfigureAwait(false);
+ await response.Content.ReadAsStreamAsync(),
+ _jsonOptions);
Assert.Null(profiles?.FirstOrDefault(x => string.Equals(x.Name, "ThisProfileIsUpdated", StringComparison.Ordinal)));
}
diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/ItemsControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/ItemsControllerTests.cs
index 078002994..a12e7ca0d 100644
--- a/tests/Jellyfin.Server.Integration.Tests/Controllers/ItemsControllerTests.cs
+++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/ItemsControllerTests.cs
@@ -25,9 +25,9 @@ public sealed class ItemsControllerTests : IClassFixture<JellyfinApplicationFact
public async Task GetItems_NoApiKeyOrUserId_Success()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var response = await client.GetAsync("Items").ConfigureAwait(false);
+ var response = await client.GetAsync("Items");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
@@ -37,9 +37,9 @@ public sealed class ItemsControllerTests : IClassFixture<JellyfinApplicationFact
public async Task GetUserItems_NonExistentUserId_NotFound(string format)
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var response = await client.GetAsync(string.Format(CultureInfo.InvariantCulture, format, Guid.NewGuid())).ConfigureAwait(false);
+ var response = await client.GetAsync(string.Format(CultureInfo.InvariantCulture, format, Guid.NewGuid()));
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
@@ -50,15 +50,15 @@ public sealed class ItemsControllerTests : IClassFixture<JellyfinApplicationFact
public async Task GetItems_UserId_Ok(string format)
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var userDto = await AuthHelper.GetUserDtoAsync(client).ConfigureAwait(false);
+ var userDto = await AuthHelper.GetUserDtoAsync(client);
- var response = await client.GetAsync(string.Format(CultureInfo.InvariantCulture, format, userDto.Id)).ConfigureAwait(false);
+ var response = await client.GetAsync(string.Format(CultureInfo.InvariantCulture, format, userDto.Id));
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var items = await JsonSerializer.DeserializeAsync<QueryResult<BaseItemDto>>(
- await response.Content.ReadAsStreamAsync().ConfigureAwait(false),
- _jsonOptions).ConfigureAwait(false);
+ await response.Content.ReadAsStreamAsync(),
+ _jsonOptions);
Assert.NotNull(items);
}
}
diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/LibraryControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/LibraryControllerTests.cs
index 8998683a7..06abae14c 100644
--- a/tests/Jellyfin.Server.Integration.Tests/Controllers/LibraryControllerTests.cs
+++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/LibraryControllerTests.cs
@@ -32,9 +32,9 @@ public sealed class LibraryControllerTests : IClassFixture<JellyfinApplicationFa
public async Task Get_NonExistentItemId_NotFound(string format)
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var response = await client.GetAsync(string.Format(CultureInfo.InvariantCulture, format, Guid.NewGuid())).ConfigureAwait(false);
+ var response = await client.GetAsync(string.Format(CultureInfo.InvariantCulture, format, Guid.NewGuid()));
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
@@ -45,7 +45,7 @@ public sealed class LibraryControllerTests : IClassFixture<JellyfinApplicationFa
{
var client = _factory.CreateClient();
- var response = await client.DeleteAsync(string.Format(CultureInfo.InvariantCulture, format, Guid.NewGuid())).ConfigureAwait(false);
+ var response = await client.DeleteAsync(string.Format(CultureInfo.InvariantCulture, format, Guid.NewGuid()));
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
}
@@ -55,9 +55,9 @@ public sealed class LibraryControllerTests : IClassFixture<JellyfinApplicationFa
public async Task Delete_NonExistentItemId_NotFound(string format)
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var response = await client.DeleteAsync(string.Format(CultureInfo.InvariantCulture, format, Guid.NewGuid())).ConfigureAwait(false);
+ var response = await client.DeleteAsync(string.Format(CultureInfo.InvariantCulture, format, Guid.NewGuid()));
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
}
diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/MediaInfoControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/MediaInfoControllerTests.cs
index 34d26680a..abc8b6009 100644
--- a/tests/Jellyfin.Server.Integration.Tests/Controllers/MediaInfoControllerTests.cs
+++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/MediaInfoControllerTests.cs
@@ -20,9 +20,9 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public async Task BitrateTest_Default_Ok()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var response = await client.GetAsync("Playback/BitrateTest").ConfigureAwait(false);
+ var response = await client.GetAsync("Playback/BitrateTest");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(MediaTypeNames.Application.Octet, response.Content.Headers.ContentType?.MediaType);
@@ -34,9 +34,9 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public async Task BitrateTest_WithValidParam_Ok(int size)
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var response = await client.GetAsync("Playback/BitrateTest?size=" + size.ToString(CultureInfo.InvariantCulture)).ConfigureAwait(false);
+ var response = await client.GetAsync("Playback/BitrateTest?size=" + size.ToString(CultureInfo.InvariantCulture));
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(MediaTypeNames.Application.Octet, response.Content.Headers.ContentType?.MediaType);
@@ -51,9 +51,9 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public async Task BitrateTest_InvalidValue_BadRequest(int size)
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var response = await client.GetAsync("Playback/BitrateTest?size=" + size.ToString(CultureInfo.InvariantCulture)).ConfigureAwait(false);
+ var response = await client.GetAsync("Playback/BitrateTest?size=" + size.ToString(CultureInfo.InvariantCulture));
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
}
diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/MediaStructureControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/MediaStructureControllerTests.cs
index 24251013c..6699c6834 100644
--- a/tests/Jellyfin.Server.Integration.Tests/Controllers/MediaStructureControllerTests.cs
+++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/MediaStructureControllerTests.cs
@@ -26,10 +26,10 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public async Task RenameVirtualFolder_WhiteSpaceName_ReturnsBadRequest()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
using var postContent = new ByteArrayContent(Array.Empty<byte>());
- var response = await client.PostAsync("Library/VirtualFolders/Name?name=+&newName=test", postContent).ConfigureAwait(false);
+ var response = await client.PostAsync("Library/VirtualFolders/Name?name=+&newName=test", postContent);
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
}
@@ -38,10 +38,10 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public async Task RenameVirtualFolder_WhiteSpaceNewName_ReturnsBadRequest()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
using var postContent = new ByteArrayContent(Array.Empty<byte>());
- var response = await client.PostAsync("Library/VirtualFolders/Name?name=test&newName=+", postContent).ConfigureAwait(false);
+ var response = await client.PostAsync("Library/VirtualFolders/Name?name=test&newName=+", postContent);
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
}
@@ -50,10 +50,10 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public async Task RenameVirtualFolder_NameDoesntExist_ReturnsNotFound()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
using var postContent = new ByteArrayContent(Array.Empty<byte>());
- var response = await client.PostAsync("Library/VirtualFolders/Name?name=doesnt+exist&newName=test", postContent).ConfigureAwait(false);
+ var response = await client.PostAsync("Library/VirtualFolders/Name?name=doesnt+exist&newName=test", postContent);
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
@@ -62,7 +62,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public async Task AddMediaPath_PathDoesntExist_ReturnsNotFound()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
var data = new MediaPathDto()
{
@@ -70,7 +70,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
Path = "/this/path/doesnt/exist"
};
- var response = await client.PostAsJsonAsync("Library/VirtualFolders/Paths", data, _jsonOptions).ConfigureAwait(false);
+ var response = await client.PostAsJsonAsync("Library/VirtualFolders/Paths", data, _jsonOptions);
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
@@ -79,7 +79,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public async Task UpdateMediaPath_WhiteSpaceName_ReturnsBadRequest()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
var data = new UpdateMediaPathRequestDto()
{
@@ -87,7 +87,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
PathInfo = new MediaPathInfo("test")
};
- var response = await client.PostAsJsonAsync("Library/VirtualFolders/Paths/Update", data, _jsonOptions).ConfigureAwait(false);
+ var response = await client.PostAsJsonAsync("Library/VirtualFolders/Paths/Update", data, _jsonOptions);
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
}
@@ -96,9 +96,9 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public async Task RemoveMediaPath_WhiteSpaceName_ReturnsBadRequest()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var response = await client.DeleteAsync("Library/VirtualFolders/Paths?name=+").ConfigureAwait(false);
+ var response = await client.DeleteAsync("Library/VirtualFolders/Paths?name=+");
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
}
@@ -107,9 +107,9 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public async Task RemoveMediaPath_PathDoesntExist_ReturnsNotFound()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var response = await client.DeleteAsync("Library/VirtualFolders/Paths?name=none&path=%2Fthis%2Fpath%2Fdoesnt%2Fexist").ConfigureAwait(false);
+ var response = await client.DeleteAsync("Library/VirtualFolders/Paths?name=none&path=%2Fthis%2Fpath%2Fdoesnt%2Fexist");
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/MusicGenreControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/MusicGenreControllerTests.cs
index 17f3dc99f..f9982cf12 100644
--- a/tests/Jellyfin.Server.Integration.Tests/Controllers/MusicGenreControllerTests.cs
+++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/MusicGenreControllerTests.cs
@@ -18,9 +18,9 @@ public sealed class MusicGenreControllerTests : IClassFixture<JellyfinApplicatio
public async Task MusicGenres_FakeMusicGenre_NotFound()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var response = await client.GetAsync("MusicGenres/Fake-MusicGenre").ConfigureAwait(false);
+ var response = await client.GetAsync("MusicGenres/Fake-MusicGenre");
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
}
diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/PlaystateControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/PlaystateControllerTests.cs
index 868ecd53f..9554d3ebc 100644
--- a/tests/Jellyfin.Server.Integration.Tests/Controllers/PlaystateControllerTests.cs
+++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/PlaystateControllerTests.cs
@@ -19,9 +19,9 @@ public class PlaystateControllerTests : IClassFixture<JellyfinApplicationFactory
public async Task DeleteMarkUnplayedItem_NonExistentUserId_NotFound()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- using var response = await client.DeleteAsync($"Users/{Guid.NewGuid()}/PlayedItems/{Guid.NewGuid()}").ConfigureAwait(false);
+ using var response = await client.DeleteAsync($"Users/{Guid.NewGuid()}/PlayedItems/{Guid.NewGuid()}");
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
@@ -29,9 +29,9 @@ public class PlaystateControllerTests : IClassFixture<JellyfinApplicationFactory
public async Task PostMarkPlayedItem_NonExistentUserId_NotFound()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- using var response = await client.PostAsync($"Users/{Guid.NewGuid()}/PlayedItems/{Guid.NewGuid()}", null).ConfigureAwait(false);
+ using var response = await client.PostAsync($"Users/{Guid.NewGuid()}/PlayedItems/{Guid.NewGuid()}", null);
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
@@ -39,11 +39,11 @@ public class PlaystateControllerTests : IClassFixture<JellyfinApplicationFactory
public async Task DeleteMarkUnplayedItem_NonExistentItemId_NotFound()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var userDto = await AuthHelper.GetUserDtoAsync(client).ConfigureAwait(false);
+ var userDto = await AuthHelper.GetUserDtoAsync(client);
- using var response = await client.DeleteAsync($"Users/{userDto.Id}/PlayedItems/{Guid.NewGuid()}").ConfigureAwait(false);
+ using var response = await client.DeleteAsync($"Users/{userDto.Id}/PlayedItems/{Guid.NewGuid()}");
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
@@ -51,11 +51,11 @@ public class PlaystateControllerTests : IClassFixture<JellyfinApplicationFactory
public async Task PostMarkPlayedItem_NonExistentItemId_NotFound()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var userDto = await AuthHelper.GetUserDtoAsync(client).ConfigureAwait(false);
+ var userDto = await AuthHelper.GetUserDtoAsync(client);
- using var response = await client.PostAsync($"Users/{userDto.Id}/PlayedItems/{Guid.NewGuid()}", null).ConfigureAwait(false);
+ using var response = await client.PostAsync($"Users/{userDto.Id}/PlayedItems/{Guid.NewGuid()}", null);
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
}
diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/SessionControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/SessionControllerTests.cs
index cb0a829e8..b9def13f8 100644
--- a/tests/Jellyfin.Server.Integration.Tests/Controllers/SessionControllerTests.cs
+++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/SessionControllerTests.cs
@@ -19,9 +19,9 @@ public class SessionControllerTests : IClassFixture<JellyfinApplicationFactory>
public async Task GetSessions_NonExistentUserId_NotFound()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- using var response = await client.GetAsync($"Session/Sessions?userId={Guid.NewGuid()}").ConfigureAwait(false);
+ using var response = await client.GetAsync($"Session/Sessions?userId={Guid.NewGuid()}");
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
}
diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/StartupControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/StartupControllerTests.cs
index 0dd22644a..2d3879bdb 100644
--- a/tests/Jellyfin.Server.Integration.Tests/Controllers/StartupControllerTests.cs
+++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/StartupControllerTests.cs
@@ -36,15 +36,15 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
PreferredMetadataLanguage = "nl"
};
- using var postResponse = await client.PostAsJsonAsync("/Startup/Configuration", config, _jsonOptions).ConfigureAwait(false);
+ using var postResponse = await client.PostAsJsonAsync("/Startup/Configuration", config, _jsonOptions);
Assert.Equal(HttpStatusCode.NoContent, postResponse.StatusCode);
- using var getResponse = await client.GetAsync("/Startup/Configuration").ConfigureAwait(false);
+ using var getResponse = await client.GetAsync("/Startup/Configuration");
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);
+ using var responseStream = await getResponse.Content.ReadAsStreamAsync();
+ var newConfig = await JsonSerializer.DeserializeAsync<StartupConfigurationDto>(responseStream, _jsonOptions);
Assert.Equal(config.UICulture, newConfig!.UICulture);
Assert.Equal(config.MetadataCountryCode, newConfig.MetadataCountryCode);
Assert.Equal(config.PreferredMetadataLanguage, newConfig.PreferredMetadataLanguage);
@@ -56,12 +56,12 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
{
var client = _factory.CreateClient();
- using var response = await client.GetAsync("/Startup/User").ConfigureAwait(false);
+ using var response = await client.GetAsync("/Startup/User");
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);
+ using var contentStream = await response.Content.ReadAsStreamAsync();
+ var user = await JsonSerializer.DeserializeAsync<StartupUserDto>(contentStream, _jsonOptions);
Assert.NotNull(user);
Assert.NotNull(user.Name);
Assert.NotEmpty(user.Name);
@@ -80,15 +80,15 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
Password = "NewPassword"
};
- var postResponse = await client.PostAsJsonAsync("/Startup/User", user, _jsonOptions).ConfigureAwait(false);
+ var postResponse = await client.PostAsJsonAsync("/Startup/User", user, _jsonOptions);
Assert.Equal(HttpStatusCode.NoContent, postResponse.StatusCode);
- var getResponse = await client.GetAsync("/Startup/User").ConfigureAwait(false);
+ var getResponse = await client.GetAsync("/Startup/User");
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);
+ var contentStream = await getResponse.Content.ReadAsStreamAsync();
+ var newUser = await JsonSerializer.DeserializeAsync<StartupUserDto>(contentStream, _jsonOptions);
Assert.NotNull(newUser);
Assert.Equal(user.Name, newUser.Name);
Assert.NotNull(newUser.Password);
@@ -102,7 +102,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
{
var client = _factory.CreateClient();
- var response = await client.PostAsync("/Startup/Complete", new ByteArrayContent(Array.Empty<byte>())).ConfigureAwait(false);
+ var response = await client.PostAsync("/Startup/Complete", new ByteArrayContent(Array.Empty<byte>()));
Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
}
@@ -112,7 +112,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
{
var client = _factory.CreateClient();
- using var response = await client.GetAsync("/Startup/User").ConfigureAwait(false);
+ using var response = await client.GetAsync("/Startup/User");
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
}
}
diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/UserControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/UserControllerTests.cs
index 2a3c53dbe..79d03d539 100644
--- a/tests/Jellyfin.Server.Integration.Tests/Controllers/UserControllerTests.cs
+++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/UserControllerTests.cs
@@ -41,10 +41,10 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
{
var client = _factory.CreateClient();
- using var response = await client.GetAsync("Users/Public").ConfigureAwait(false);
+ using var response = await client.GetAsync("Users/Public");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var users = await JsonSerializer.DeserializeAsync<UserDto[]>(
- await response.Content.ReadAsStreamAsync().ConfigureAwait(false), _jsonOpions).ConfigureAwait(false);
+ await response.Content.ReadAsStreamAsync(), _jsonOpions);
// User are hidden by default
Assert.NotNull(users);
Assert.Empty(users);
@@ -55,12 +55,12 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public async Task GetUsers_Valid_Success()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- using var response = await client.GetAsync("Users").ConfigureAwait(false);
+ using var response = await client.GetAsync("Users");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var users = await JsonSerializer.DeserializeAsync<UserDto[]>(
- await response.Content.ReadAsStreamAsync().ConfigureAwait(false), _jsonOpions).ConfigureAwait(false);
+ await response.Content.ReadAsStreamAsync(), _jsonOpions);
Assert.NotNull(users);
Assert.Single(users);
Assert.False(users![0].HasConfiguredPassword);
@@ -71,9 +71,9 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
public async Task Me_Valid_Success()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- _ = await AuthHelper.GetUserDtoAsync(client).ConfigureAwait(false);
+ _ = await AuthHelper.GetUserDtoAsync(client);
}
[Fact]
@@ -90,10 +90,10 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
Name = TestUsername
};
- using var response = await CreateUserByName(client, createRequest).ConfigureAwait(false);
+ using var response = await CreateUserByName(client, createRequest);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var user = await JsonSerializer.DeserializeAsync<UserDto>(
- await response.Content.ReadAsStreamAsync().ConfigureAwait(false), _jsonOpions).ConfigureAwait(false);
+ await response.Content.ReadAsStreamAsync(), _jsonOpions);
Assert.Equal(TestUsername, user!.Name);
Assert.False(user.HasPassword);
Assert.False(user.HasConfiguredPassword);
@@ -121,7 +121,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
Name = username!
};
- using var response = await CreateUserByName(client, createRequest).ConfigureAwait(false);
+ using var response = await CreateUserByName(client, createRequest);
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
}
@@ -134,7 +134,7 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
// access token can't be null here as the previous test populated it
client.DefaultRequestHeaders.AddAuthHeader(_accessToken!);
- using var response = await client.DeleteAsync($"User/{Guid.NewGuid()}").ConfigureAwait(false);
+ using var response = await client.DeleteAsync($"User/{Guid.NewGuid()}");
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
@@ -150,11 +150,11 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
NewPw = "4randomPa$$word"
};
- using var response = await UpdateUserPassword(client, _testUserId, createRequest).ConfigureAwait(false);
+ using var response = await UpdateUserPassword(client, _testUserId, createRequest);
Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
var users = await JsonSerializer.DeserializeAsync<UserDto[]>(
- await client.GetStreamAsync("Users").ConfigureAwait(false), _jsonOpions).ConfigureAwait(false);
+ await client.GetStreamAsync("Users"), _jsonOpions);
var user = users!.First(x => x.Id.Equals(_testUserId));
Assert.True(user.HasPassword);
Assert.True(user.HasConfiguredPassword);
@@ -173,11 +173,11 @@ namespace Jellyfin.Server.Integration.Tests.Controllers
CurrentPw = "4randomPa$$word",
};
- using var response = await UpdateUserPassword(client, _testUserId, createRequest).ConfigureAwait(false);
+ using var response = await UpdateUserPassword(client, _testUserId, createRequest);
Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
var users = await JsonSerializer.DeserializeAsync<UserDto[]>(
- await client.GetStreamAsync("Users").ConfigureAwait(false), _jsonOpions).ConfigureAwait(false);
+ await client.GetStreamAsync("Users"), _jsonOpions);
var user = users!.First(x => x.Id.Equals(_testUserId));
Assert.False(user.HasPassword);
Assert.False(user.HasConfiguredPassword);
diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/UserLibraryControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/UserLibraryControllerTests.cs
index 69f2ccf33..826a0a69d 100644
--- a/tests/Jellyfin.Server.Integration.Tests/Controllers/UserLibraryControllerTests.cs
+++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/UserLibraryControllerTests.cs
@@ -25,9 +25,9 @@ public sealed class UserLibraryControllerTests : IClassFixture<JellyfinApplicati
public async Task GetRootFolder_NonExistenUserId_NotFound()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var response = await client.GetAsync($"Users/{Guid.NewGuid()}/Items/Root").ConfigureAwait(false);
+ var response = await client.GetAsync($"Users/{Guid.NewGuid()}/Items/Root");
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
@@ -35,9 +35,9 @@ public sealed class UserLibraryControllerTests : IClassFixture<JellyfinApplicati
public async Task GetRootFolder_UserId_Valid()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- _ = await AuthHelper.GetRootFolderDtoAsync(client).ConfigureAwait(false);
+ _ = await AuthHelper.GetRootFolderDtoAsync(client);
}
[Theory]
@@ -49,11 +49,11 @@ public sealed class UserLibraryControllerTests : IClassFixture<JellyfinApplicati
public async Task GetItem_NonExistenUserId_NotFound(string format)
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var rootFolderDto = await AuthHelper.GetRootFolderDtoAsync(client).ConfigureAwait(false);
+ var rootFolderDto = await AuthHelper.GetRootFolderDtoAsync(client);
- var response = await client.GetAsync(string.Format(CultureInfo.InvariantCulture, format, Guid.NewGuid(), rootFolderDto.Id)).ConfigureAwait(false);
+ var response = await client.GetAsync(string.Format(CultureInfo.InvariantCulture, format, Guid.NewGuid(), rootFolderDto.Id));
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
@@ -66,11 +66,11 @@ public sealed class UserLibraryControllerTests : IClassFixture<JellyfinApplicati
public async Task GetItem_NonExistentItemId_NotFound(string format)
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var userDto = await AuthHelper.GetUserDtoAsync(client).ConfigureAwait(false);
+ var userDto = await AuthHelper.GetUserDtoAsync(client);
- var response = await client.GetAsync(string.Format(CultureInfo.InvariantCulture, format, userDto.Id, Guid.NewGuid())).ConfigureAwait(false);
+ var response = await client.GetAsync(string.Format(CultureInfo.InvariantCulture, format, userDto.Id, Guid.NewGuid()));
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
@@ -78,16 +78,16 @@ public sealed class UserLibraryControllerTests : IClassFixture<JellyfinApplicati
public async Task GetItem_UserIdAndItemId_Valid()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var userDto = await AuthHelper.GetUserDtoAsync(client).ConfigureAwait(false);
- var rootFolderDto = await AuthHelper.GetRootFolderDtoAsync(client, userDto.Id).ConfigureAwait(false);
+ var userDto = await AuthHelper.GetUserDtoAsync(client);
+ var rootFolderDto = await AuthHelper.GetRootFolderDtoAsync(client, userDto.Id);
- var response = await client.GetAsync($"Users/{userDto.Id}/Items/{rootFolderDto.Id}").ConfigureAwait(false);
+ var response = await client.GetAsync($"Users/{userDto.Id}/Items/{rootFolderDto.Id}");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var rootDto = await JsonSerializer.DeserializeAsync<BaseItemDto>(
- await response.Content.ReadAsStreamAsync().ConfigureAwait(false),
- _jsonOptions).ConfigureAwait(false);
+ await response.Content.ReadAsStreamAsync(),
+ _jsonOptions);
Assert.NotNull(rootDto);
}
@@ -95,16 +95,16 @@ public sealed class UserLibraryControllerTests : IClassFixture<JellyfinApplicati
public async Task GetIntros_UserIdAndItemId_Valid()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var userDto = await AuthHelper.GetUserDtoAsync(client).ConfigureAwait(false);
- var rootFolderDto = await AuthHelper.GetRootFolderDtoAsync(client, userDto.Id).ConfigureAwait(false);
+ var userDto = await AuthHelper.GetUserDtoAsync(client);
+ var rootFolderDto = await AuthHelper.GetRootFolderDtoAsync(client, userDto.Id);
- var response = await client.GetAsync($"Users/{userDto.Id}/Items/{rootFolderDto.Id}/Intros").ConfigureAwait(false);
+ var response = await client.GetAsync($"Users/{userDto.Id}/Items/{rootFolderDto.Id}/Intros");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var rootDto = await JsonSerializer.DeserializeAsync<QueryResult<BaseItemDto>>(
- await response.Content.ReadAsStreamAsync().ConfigureAwait(false),
- _jsonOptions).ConfigureAwait(false);
+ await response.Content.ReadAsStreamAsync(),
+ _jsonOptions);
Assert.NotNull(rootDto);
}
@@ -114,16 +114,16 @@ public sealed class UserLibraryControllerTests : IClassFixture<JellyfinApplicati
public async Task LocalTrailersAndSpecialFeatures_UserIdAndItemId_Valid(string format)
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var userDto = await AuthHelper.GetUserDtoAsync(client).ConfigureAwait(false);
- var rootFolderDto = await AuthHelper.GetRootFolderDtoAsync(client, userDto.Id).ConfigureAwait(false);
+ var userDto = await AuthHelper.GetUserDtoAsync(client);
+ var rootFolderDto = await AuthHelper.GetRootFolderDtoAsync(client, userDto.Id);
- var response = await client.GetAsync(string.Format(CultureInfo.InvariantCulture, format, userDto.Id, rootFolderDto.Id)).ConfigureAwait(false);
+ var response = await client.GetAsync(string.Format(CultureInfo.InvariantCulture, format, userDto.Id, rootFolderDto.Id));
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var rootDto = await JsonSerializer.DeserializeAsync<BaseItemDto[]>(
- await response.Content.ReadAsStreamAsync().ConfigureAwait(false),
- _jsonOptions).ConfigureAwait(false);
+ await response.Content.ReadAsStreamAsync(),
+ _jsonOptions);
Assert.NotNull(rootDto);
}
}
diff --git a/tests/Jellyfin.Server.Integration.Tests/Controllers/VideosControllerTests.cs b/tests/Jellyfin.Server.Integration.Tests/Controllers/VideosControllerTests.cs
index 0f9a2e90a..47bec5d79 100644
--- a/tests/Jellyfin.Server.Integration.Tests/Controllers/VideosControllerTests.cs
+++ b/tests/Jellyfin.Server.Integration.Tests/Controllers/VideosControllerTests.cs
@@ -19,9 +19,9 @@ public sealed class VideosControllerTests : IClassFixture<JellyfinApplicationFac
public async Task DeleteAlternateSources_NonExistentItemId_NotFound()
{
var client = _factory.CreateClient();
- client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client).ConfigureAwait(false));
+ client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
- var response = await client.DeleteAsync($"Videos/{Guid.NewGuid()}").ConfigureAwait(false);
+ var response = await client.DeleteAsync($"Videos/{Guid.NewGuid()}");
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
}
diff --git a/tests/Jellyfin.Server.Integration.Tests/EncodedQueryStringTest.cs b/tests/Jellyfin.Server.Integration.Tests/EncodedQueryStringTest.cs
index 2361e4aa4..d2249cdc3 100644
--- a/tests/Jellyfin.Server.Integration.Tests/EncodedQueryStringTest.cs
+++ b/tests/Jellyfin.Server.Integration.Tests/EncodedQueryStringTest.cs
@@ -27,9 +27,9 @@ namespace Jellyfin.Server.Integration.Tests
{
var client = _factory.CreateClient();
- var response = await client.GetAsync("Encoder/UrlDecode?" + sourceUrl).ConfigureAwait(false);
+ var response = await client.GetAsync("Encoder/UrlDecode?" + sourceUrl);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
- string reply = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
+ string reply = await response.Content.ReadAsStringAsync();
Assert.Equal(unencodedUrl, reply);
}
@@ -40,9 +40,9 @@ namespace Jellyfin.Server.Integration.Tests
{
var client = _factory.CreateClient();
- var response = await client.GetAsync("Encoder/UrlArrayDecode?" + sourceUrl).ConfigureAwait(false);
+ var response = await client.GetAsync("Encoder/UrlArrayDecode?" + sourceUrl);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
- string reply = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
+ string reply = await response.Content.ReadAsStringAsync();
Assert.Equal(unencodedUrl, reply);
}
}
diff --git a/tests/Jellyfin.Server.Integration.Tests/Middleware/RobotsRedirectionMiddlewareTests.cs b/tests/Jellyfin.Server.Integration.Tests/Middleware/RobotsRedirectionMiddlewareTests.cs
index 8c49a2e2b..c8ad9d2a1 100644
--- a/tests/Jellyfin.Server.Integration.Tests/Middleware/RobotsRedirectionMiddlewareTests.cs
+++ b/tests/Jellyfin.Server.Integration.Tests/Middleware/RobotsRedirectionMiddlewareTests.cs
@@ -23,7 +23,7 @@ namespace Jellyfin.Server.Integration.Tests.Middleware
AllowAutoRedirect = false
});
- var response = await client.GetAsync("robots.txt").ConfigureAwait(false);
+ var response = await client.GetAsync("robots.txt");
Assert.Equal(HttpStatusCode.Redirect, response.StatusCode);
Assert.Equal("web/robots.txt", response.Headers.Location?.ToString());