aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorCody Robibero <cody@robibe.ro>2026-07-21 18:17:22 -0400
committerGitHub <noreply@github.com>2026-07-21 18:17:22 -0400
commit635fd0433d7eb3d6b145a2e41b17785a300eff05 (patch)
tree3af141c29681dfabad2ea5225ad1134ad4681e2f /tests
parent370170bab0c74f85f0fd3164193aae06af4a71c1 (diff)
parent53e58d8b1b61c44405322bf91a8aa230f02b8323 (diff)
Merge pull request #17370 from zerafachris/fix/item-update-null-optional-fields
fix: don't throw ArgumentNullException on partial UpdateItem payloads (#17366)
Diffstat (limited to 'tests')
-rw-r--r--tests/Jellyfin.Api.Tests/Controllers/ItemUpdateControllerTests.cs77
1 files changed, 77 insertions, 0 deletions
diff --git a/tests/Jellyfin.Api.Tests/Controllers/ItemUpdateControllerTests.cs b/tests/Jellyfin.Api.Tests/Controllers/ItemUpdateControllerTests.cs
new file mode 100644
index 0000000000..1a91efe4f2
--- /dev/null
+++ b/tests/Jellyfin.Api.Tests/Controllers/ItemUpdateControllerTests.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Threading.Tasks;
+using Jellyfin.Api.Controllers;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Globalization;
+using MediaBrowser.Model.IO;
+using Moq;
+using Xunit;
+
+namespace Jellyfin.Api.Tests.Controllers;
+
+public class ItemUpdateControllerTests
+{
+ private readonly ItemUpdateController _subject;
+
+ public ItemUpdateControllerTests()
+ {
+ _subject = new ItemUpdateController(
+ Mock.Of<IFileSystem>(),
+ Mock.Of<ILibraryManager>(),
+ Mock.Of<IProviderManager>(),
+ Mock.Of<ILocalizationManager>(),
+ Mock.Of<IServerConfigurationManager>());
+ }
+
+ [Fact]
+ public async Task UpdateItem_WhenOnlyTagsFieldSupplied_DoesNotThrowAndAppliesTags()
+ {
+ // Regression test for https://github.com/jellyfin/jellyfin/issues/17366
+ // A partial update payload that only sets "Tags" leaves every other
+ // BaseItemDto collection property null (they have no default
+ // initializer). Genres and ProviderIds used to be fed straight into
+ // Distinct()/ToList() without a null check, so this call used to throw
+ // ArgumentNullException before the fix below was applied.
+ var movie = new Movie();
+ var request = new BaseItemDto
+ {
+ Tags = new[] { "new-tag-1", "new-tag-2" }
+ };
+
+ await InvokeUpdateItem(request, movie);
+
+ Assert.Equal(new[] { "new-tag-1", "new-tag-2" }, movie.Tags);
+ Assert.Empty(movie.Genres);
+ Assert.Empty(movie.ProviderIds);
+ }
+
+ [Fact]
+ public async Task UpdateItem_WhenGenresAndProviderIdsOmitted_LeavesExistingValuesUnchanged()
+ {
+ var movie = new Movie
+ {
+ Genres = new[] { "Action" }
+ };
+ movie.ProviderIds["Imdb"] = "tt1234567";
+
+ var request = new BaseItemDto
+ {
+ Tags = Array.Empty<string>()
+ };
+
+ await InvokeUpdateItem(request, movie);
+
+ Assert.Equal(new[] { "Action" }, movie.Genres);
+ Assert.Equal("tt1234567", movie.ProviderIds["Imdb"]);
+ }
+
+ private Task InvokeUpdateItem(BaseItemDto request, BaseItem item)
+ {
+ return _subject.UpdateItem(request, item);
+ }
+}