aboutsummaryrefslogtreecommitdiff
path: root/tests/Jellyfin.Server.Implementations.Tests
AgeCommit message (Collapse)Author
10 daysFix other two missing DE localization DE updatesMarc Brooks
Turns out there were two more instances of test broken by commit 21fec95b07f04e70dc2a6250f3f00d7b63003650
11 daysFix unit test for localizationMarc Brooks
DE localization for Artists was changed in localization commit 21fec95b07f04e70dc2a6250f3f00d7b63003650
2026-08-08Address review on MediaSourceCount batchingbrandon
Rename GetItemsWithAlternateVersions to GetItemIdsWithAlternateVersions across the interfaces and implementations since it returns ids. Return the hashset straight from the query instead of materializing an array first. Rename the DtoService guard to mayHaveAlternateVersions and invert it so the computed path is the explicit case. Assert the media source count value in the batch skip test and add a test covering an item that is in the returned set still resolving to the correct count.
2026-08-07Batch alternate version detection in DtoService to remove MediaSourceCount N+1brandon
Browsing a page of videos with the MediaSourceCount field ran one alternate version query per item, each opening a fresh DbContext. On a large library that turned a single page into hundreds of sequential round trips and made the Items endpoint take tens of seconds while holding a request thread the whole time. Detect which videos own alternate versions once per page with a single query, mirroring the existing people batch. Videos absent from that set have a single media source, so the per item lookups are skipped for the common case. Behavior is unchanged: a video with no alternates already resolved to a count of one. Adds a regression test asserting the count resolves from the batch and the per item lookups are never called.
2026-08-07Merge pull request #17571 from obiwantoby/perf/batch-people-dtoCody Robibero
Batch people lookups when building item DTOs
2026-08-07Merge pull request #17541 from vdatanet/fix/byname-total-record-countCody Robibero
Fix by-name endpoints reporting TotalRecordCount=0 next to a populated Items array
2026-08-07Merge pull request #17555 from IDisposable/fix/reorder-update-itemsCody Robibero
Delete old related info in bulk as late as possible in UpdateOrInsertItems
2026-08-07Merge pull request #17521 from Shadowghost/fix-plugin-disableCody Robibero
Fix disabled plugins being re-enabled on restart
2026-08-07Batch people lookups when building item DTOsbrandon
GetBaseItemDtos already batch fetches user data, child counts, played counts and artists before its per item loop, but AttachPeople still ran one GetPeople query per item. Rendering a page of items (for example a large playlist) fired one extra query per row. Add GetPeopleByItems to IPeopleRepository, which reads every requested item in a single query over the people mapping table and returns full PersonInfo (role, type and sort order) grouped by item id. GetBaseItemDtos prefetches this once when the People field is requested and passes it into AttachPeople, which reads from the batch instead of querying per item. The single item GetBaseItemDto path keeps its existing per item behaviour when no batch is supplied. Adds a DtoService test asserting people resolve from the batch and the per item GetPeople is never called.
2026-08-06Move the deletion of old related info to just before the saveMarc Brooks
This makes the deletion of BaseItemProviders, BaseItemImageInfos, and BaseItemMetadataFields happen in batch as a contiguous block so the lock isn't held across items, just before the bulk SaveChanges.
2026-08-05Project the lowered person credit values once when updating peopleShadowghost
2026-08-05Fix by-name endpoints reporting TotalRecordCount=0 next to a populated Items ↵vdatanet
array `GetItemValues` -- the shared path behind `/Artists`, `/AlbumArtists`, `/Genres`, `/MusicGenres` and `/Studios` -- disabled the total record count whenever the query carried no `Limit`: if (!filter.Limit.HasValue) { filter.EnableTotalRecordCount = false; } A request without an explicit limit therefore came back with N entries in `Items` and `TotalRecordCount = 0`. Clients that page on the reported total -- the documented contract every other list endpoint honours -- read that as an empty library. `/Items` and `/Persons` do not share this path and report the count correctly, which is what makes the inconsistency visible from the outside. Measured against master with a 62-track music library: GET /Artists?UserId=... -> TotalRecordCount=0 Items=5 GET /Artists?UserId=...&limit=100 -> TotalRecordCount=5 Items=5 Dropping the block costs nothing: `representativeIds` is materialised into a `List<Guid>` a few lines below regardless, so `.Count` was already available and the count is now reported from it. Callers that genuinely want to skip the count still can -- `EnableTotalRecordCount = false` is honoured as before. The block also mutated the caller's own query object, so a query instance reused across calls silently lost its total after the first limitless one. That is covered by a test as well.
2026-08-03Fix disabled plugins being re-enabled on restartShadowghost
2026-07-27Fix extras naming and version assignmentShadowghost
2026-07-26Merge pull request #17422 from Shadowghost/performanceCody Robibero
Reduce correlated subqueries to improve query performance
2026-07-25Merge pull request #17399 from Shadowghost/fix-extra-yearCody Robibero
Fix incorrect year on local trailers
2026-07-25Merge pull request #17395 from paoloantinori/fix/userdata-null-user-nre-masterCody Robibero
Avoid NRE when sorting by user-dependent keys without a user
2026-07-25Remove added comments (#17395 review)Paolo Antinori
2026-07-24Merge pull request #17234 from Eneo-org/fix/syncplay-playqueue-indexCody Robibero
Fix play queue index handling in SyncPlay
2026-07-23Reduce correlated subqueries to improve performanceShadowghost
2026-07-22fix: avoid NRE when sorting by user-dependent keys without a userPaolo Antinori
A query sorted by a user-dependent key (PlayCount, IsFavoriteOrLiked, DatePlayed, IsPlayed, IsUnplayed) but carrying no User caused a NullReferenceException inside UserDataManager.GetUserData, surfacing as "Failed to compare two elements in the array" (InvalidOperationException wrapping the NRE from the LINQ sort) and 500-ing the /Items request. Root cause: LibraryManager.GetComparer assigned comparer.User = user without a null guard, so PlayCountComparer.GetValue called UserDataManager.GetUserData(null, item), dereferencing user.Id. Two-part fix: - LibraryManager.GetComparer: when user is null and the sort key requires a user (IUserBaseItemComparer), substitute the SortName comparer so the result stays deterministic instead of 500-ing. SortName is the project's canonical tiebreaker (ItemsController injects it for album-by-artist). - UserDataManager.GetUserData: ArgumentNullException.ThrowIfNull(user) as defense in depth (matches the existing guards on the SaveUserData overloads in the same file). On master this overload was rewritten to use ResolveUserDataRow, so the NRE dereferences user.Id rather than user.InternalId as on the release branch — same bug, different line. Also fixes DateLastMediaAddedComparer being statically mis-tagged as IUserBaseItemComparer: its GetDate is static and never reads User, so it does not need one. Without this, the SortName fallback above would wrongly engage for DateLastContentAdded on anonymous queries (returning SortName order instead of date order). Re-tagged to IBaseItemComparer and dropped the unused User/UserManager/UserDataManager properties. Tests: - UserDataManagerTests.GetUserData_NullUser_ThrowsArgumentNullException: reproduces the crash (NRE -> now ArgumentNullException). Added to master's existing UserDataManagerTests. - LibraryManagerSortTests.Sort_UserDependentKey_NullUser_FallsBackToSortNameWithoutThrowing: Sort with a user-dependent key + null user no longer throws and returns items ordered by the SortName fallback (direction preserved). - LibraryManagerSortTests.Sort_DateLastContentAdded_NullUser_OrdersByDateNotSortName: guards that DateLastContentAdded still sorts by date with no user (fixture chosen so date-desc and SortName-desc disagree, so a revert is caught). Full Jellyfin.Server.Implementations.Tests suite: 642 passed, 0 failed. Fixes #17393
2026-07-21Fix incorrect year on local trailersShadowghost
2026-07-21Merge pull request #17160 from 854562/truncate-language-stringsCody Robibero
Truncate ISO-639-2 language display names at first delimiter
2026-07-21Merge pull request #17368 from Shadowghost/security-path-traversal-fixesBond-009
Backport and extend path traversal fixes
2026-07-21fix: use build output directory for backup test temp root to avoid low ↵zerafachris
free-space failures on Windows CI runners BackupServiceTests rooted its temp directory under Path.GetTempPath(), which on GitHub-hosted windows-latest runners resolves to the constrained system C: drive. BackupService.CreateBackupAsync requires 5GiB free at the backup path before starting, and the C: drive's free temp space can dip below that, failing CreateBackupAsync_WithCorruptKeyframeDataRow_SkipsRowAndCompletesBackup even though the fix itself is correct. Rooting the test directory under AppContext.BaseDirectory keeps it on the same (much larger) drive as the repo checkout on all platforms, without touching the real BackupService free-space check.
2026-07-21Merge remote-tracking branch 'upstream/master' into ↵Shadowghost
security-path-traversal-fixes # Conflicts: # Jellyfin.Api/Controllers/HlsSegmentController.cs # Jellyfin.Api/Controllers/PluginsController.cs
2026-07-20Merge branch 'master' into fix/backup-skip-corrupt-keyframe-dataCody Robibero
2026-07-20Merge pull request #17282 from TowyTowy/fix/13137-clear-profile-imageCody Robibero
Fix profile image being impossible to clear when its in-memory key is temporary
2026-07-20Merge pull request #17320 from TaterTechStudios/fix/item-correct-selectorCody Robibero
Fix: Fetch the correct row matching the most up to date file
2026-07-20Merge pull request #17254 from sjakub/attribute_aliasesCody Robibero
Add additional attribute aliases and improve attribute detection
2026-07-20Extract truncation logic to helper and add tests854562
2026-07-20Merge pull request #17365 from Shadowghost/fix-resume-perfBond-009
Fix Resume query performance
2026-07-17Merge pull request #17327 from ↵Bond-009
Shadowghost/remove-playbackpositionticks-mediasourceinfo Remove PlaybackPositionTicks from MediaSourceInfo
2026-07-17Harden remaining path-construction sinks against traversalShadowghost
2026-07-17Skip corrupt KeyframeData rows during full system backupzerafachris
A single row with malformed KeyframeTicks JSON (e.g. a truncated array from an interrupted write) currently aborts the entire backup, because the try/catch in BackupService.CreateBackupAsync only wraps serialization of an already-materialized entity, not the enumeration itself. EF Core throws JsonReaderException from MoveNextAsync() while materializing the corrupt row, which propagates past that catch block. Switch to manual enumerator iteration so MoveNextAsync() failures can be caught per-row, logged as a warning identifying the affected table, and skipped, allowing the remaining rows and the rest of the backup to complete. Fixes #17216 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-16Fix tie-breaker performanceShadowghost
2026-07-15Move GetUserDataBatch to use ResolveUserDataRow when item.UserData isn't ↵Jordan Rushing
preloaded
2026-07-14remove PlaybackPositionTicks from MediaSourceInfoShadowghost
2026-07-13Fix: Fetch the correct row matching the most up to date fileJordan Rushing
2026-07-09Fix profile image being impossible to clear when its in-memory key is temporaryTowyTowy
ClearProfileImageAsync removed the ProfileImage instance attached to the passed-in User, but that instance can carry a stale, never-persisted (temporary) key because UpdateUserAsync creates the persisted image on a separately loaded entity and never copies the generated key back. Removing that detached entity on a fresh DbContext made EF Core throw InvalidOperationException ('ImageInfo.Id has a temporary value'), leaving the profile image impossible to delete or replace. Load the tracked, persisted user and remove its actual ProfileImage, matching the removal pattern already used in UpdateUserAsync. Adds regression tests covering the temporary-key case and the no-image no-op (the first fails before this change and passes after). Fixes #13137 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09Cleanup PreferEpisodeParentPoster)Shadowghost
2026-07-09Remove episode image override hackShadowghost
2026-07-07Added more aliases for attributesJakub Schmidtke
Adds tvdb alias for tvdbid and imdb alias for imdbid. It also fixes an issue where tmdb alias was being ignored if it was followed by something like "tmdbidfoo". The same issue prevented imdb pattern matching from working, if it was followed by something like "imdbidfoo". It also allows for detecting the first matching occurence, whether it was an alias or not. Finally, it ignores attributes with values consisting of only whitespaces.
2026-07-05Merge pull request #17044 from Shadowghost/version-model-and-handlingCody Robibero
Fixes for multi version handling
2026-07-04Fix play queue index handling in SyncPlayEnea D'Angiò
Three index bugs in PlayQueueManager, two of which leave PlayingItemIndex out of bounds, making every subsequent Buffering/Ready request throw and leaving the group unusable until it empties: - RemoveFromPlaylist did not compensate for removed items preceding the playing item: removing the playing item together with earlier items could select the wrong item or crash with an out-of-bounds index. - Next/Previous on an empty playlist with RepeatOne/RepeatAll reported success or set PlayingItemIndex to 0 on an empty list, crashing downstream in Group and corrupting the index. - SetPlayingItemByIndex accepted an index equal to the playlist count (latent off-by-one, callers currently pre-validate).
2026-07-02Fix review commentsShadowghost
2026-06-27Merge pull request #17013 from dfederm/dfederm/fix-jellyfin-16899Cody Robibero
Reject unsafe plugin package names in installer
2026-06-26Fix localization lookupShadowghost
2026-06-19Surface the played version for resumeShadowghost
2026-06-18Merge pull request #14935 from JadedRain/masterBond-009
Fixed "Deleting media that is still being watched in SyncPlay results in errors"