Commit graph

1,310 commits

Author SHA1 Message Date
Stephan Wahlen
1a464506fd
fix invisible button color fir muibutton
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-11-22 16:26:27 +01:00
Stephan Wahlen
d80b471b68 Update amusic.css.js 2025-11-22 16:17:22 +01:00
Stephan Wahlen
10708edc12 final touches 2025-11-22 16:01:27 +01:00
Stephan Wahlen
21ed2b46c0 unify border colors
and attempt to get album cover corner radius working
2025-11-22 15:47:32 +01:00
Stephan Wahlen
4c7f73154f mobile player floating panel background shade of green 2025-11-22 15:46:48 +01:00
Stephan Wahlen
04de91bb6d unify colors in player
same red shades as primary
2025-11-22 15:35:21 +01:00
Stephan Wahlen
95be380eec get rid of queue hover green 2025-11-22 15:32:44 +01:00
Stephan Wahlen
f04e4b0950 unify font colors + albumgrid corner radius 2025-11-22 15:29:45 +01:00
Stephan Wahlen
5433bb12a3 external links colors 2025-11-22 15:14:22 +01:00
Stephan Wahlen
3ee5e96662 artist and album heading 2025-11-22 15:09:56 +01:00
Stephan Wahlen
1c38c8c1a2 small tweaks to colors and radiuses 2025-11-22 15:05:06 +01:00
Stephan Wahlen
2cf7e11d43 rounded art in albumgridview 2025-11-22 14:47:19 +01:00
Stephan Wahlen
99135fc417 prettier 2025-11-22 14:37:36 +01:00
Stephan Wahlen
a117e7e078 artist page 2025-11-22 14:32:37 +01:00
Stephan Wahlen
09665efa36 more mobile color fixes 2025-11-22 14:01:10 +01:00
Stephan Wahlen
d904060f82 Update amusic.css.js 2025-11-22 13:45:03 +01:00
Stephan Wahlen
9fc8dee781 queue hover still green
and player preview image not rounded properly
2025-11-22 13:44:32 +01:00
Stephan Wahlen
223198c9e3 fix stray comma
and lint+prettier
2025-11-22 13:31:37 +01:00
Stephan Wahlen
d582194bfa fix queue panel background and border
to make it stand out more against the background
2025-11-22 13:25:24 +01:00
Stephan Wahlen
9dde22766c more styling to player
- fix some appearances of green in queue
- match queue styling to rest of theme
- round albumart in player and prevent rotation
2025-11-21 19:16:49 +01:00
Stephan Wahlen
ac3199d6d5 fix banded table styling and more 2025-11-20 18:52:23 +01:00
Stephan Wahlen
e92e75ca1b run prettier 2025-11-19 13:02:24 +01:00
Stephan Wahlen
92100c7e5b
Fix syntax error in amusic.js background property 2025-11-18 17:09:24 +01:00
Stephan Wahlen
657b53da45
Fix MuiToolbar background property in amusic.js 2025-11-18 17:03:15 +01:00
Stephan Wahlen
694daf8e91
Add styles for NDAlbumGridView in amusic.js 2025-11-18 13:51:39 +01:00
Stephan Wahlen
50dab201aa
Update amusic.js 2025-11-18 13:25:11 +01:00
Stephan Wahlen
9dfc66cc0a fix file name 2025-11-17 20:51:25 +01:00
Stephan Wahlen
0281b250b7 fix Duplicate key 'MuiButton' 2025-11-17 20:48:09 +01:00
Stephan Wahlen
b82a914a4c prettier 2025-11-17 20:44:30 +01:00
Stephan Wahlen
81186267b4 first show at AMuisc Theme 2025-11-17 20:10:08 +01:00
Deluan Quintão
395a36e10f
fix(ui): fix library selection state for single-library users (#4686)
* fix: validate library selection state for single-library users

Fixes issues where users with a single library see no content when
selectedLibraries in localStorage contains library IDs they no longer
have access to (e.g., after removing libraries or switching accounts).

Changes:
- libraryReducer: Validate selectedLibraries when SET_USER_LIBRARIES
  is dispatched, filtering out invalid IDs and resetting to empty for
  single-library users (empty means 'all accessible libraries')
- wrapperDataProvider: Add defensive validation in getSelectedLibraries
  to check against current user libraries before applying filters
- Add comprehensive test coverage for reducer validation logic

Fixes #4553, #4508, #4569

* style: format code with prettier
2025-11-15 17:42:28 -05:00
Deluan
0161a0958c fix(ui): add CreateButton back to LibraryListActions
Signed-off-by: Deluan <deluan@navidrome.org>
2025-11-15 17:31:37 -05:00
Deluan Quintão
28d5299ffc
feat(scanner): implement selective folder scanning and file system watcher improvements (#4674)
* feat: Add selective folder scanning capability

Implement targeted scanning of specific library/folder pairs without
full recursion. This enables efficient rescanning of individual folders
when changes are detected, significantly reducing scan time for large
libraries.

Key changes:
- Add ScanTarget struct and ScanFolders API to Scanner interface
- Implement CLI flag --targets for specifying libraryID:folderPath pairs
- Add FolderRepository.GetByPaths() for batch folder info retrieval
- Create loadSpecificFolders() for non-recursive directory loading
- Scope GC operations to affected libraries only (with TODO for full impl)
- Add comprehensive tests for selective scanning behavior

The selective scan:
- Only processes specified folders (no subdirectory recursion)
- Maintains library isolation
- Runs full maintenance pipeline scoped to affected libraries
- Supports both full and quick scan modes

Examples:
  navidrome scan --targets "1:Music/Rock,1:Music/Jazz"
  navidrome scan --full --targets "2:Classical"

* feat(folder): replace GetByPaths with GetFolderUpdateInfo for improved folder updates retrieval

Signed-off-by: Deluan <deluan@navidrome.org>

* test: update parseTargets test to handle folder names with spaces

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor(folder): remove unused LibraryPath struct and update GC logging message

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor(folder): enhance external scanner to support target-specific scanning

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor(scanner): simplify scanner methods

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(watcher): implement folder scanning notifications with deduplication

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor(watcher): add resolveFolderPath function for testability

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(watcher): implement path ignoring based on .ndignore patterns

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor(scanner): implement IgnoreChecker for managing .ndignore patterns

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor(ignore_checker): rename scanner to lineScanner for clarity

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor(scanner): enhance ScanTarget struct with String method for better target representation

Signed-off-by: Deluan <deluan@navidrome.org>

* fix(scanner): validate library ID to prevent negative values

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor(scanner): simplify GC method by removing library ID parameter

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(scanner): update folder scanning to include all descendants of specified folders

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(subsonic): allow selective scan in the /startScan endpoint

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor(scanner): update CallScan to handle specific library/folder pairs

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor(scanner): streamline scanning logic by removing scanAll method

Signed-off-by: Deluan <deluan@navidrome.org>

* test: enhance mockScanner for thread safety and improve test reliability

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor(scanner): move scanner.ScanTarget to model.ScanTarget

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor: move scanner types to model,implement MockScanner

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor(scanner): update scanner interface and implementations to use model.Scanner

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor(folder_repository): normalize target path handling by using filepath.Clean

Signed-off-by: Deluan <deluan@navidrome.org>

* test(folder_repository): add comprehensive tests for folder retrieval and child exclusion

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor(scanner): simplify selective scan logic using slice.Filter

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor(scanner): streamline phase folder and album creation by removing unnecessary library parameter

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor(scanner): move initialization logic from phase_1 to the scanner itself

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor(tests): rename selective scan test file to scanner_selective_test.go

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(configuration): add DevSelectiveWatcher configuration option

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(watcher): enhance .ndignore handling for folder deletions and file changes

Signed-off-by: Deluan <deluan@navidrome.org>

* docs(scanner): comments

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor(scanner): enhance walkDirTree to support target folder scanning

Signed-off-by: Deluan <deluan@navidrome.org>

* fix(scanner, watcher): handle errors when pushing ignore patterns for folders

Signed-off-by: Deluan <deluan@navidrome.org>

* Update scanner/phase_1_folders.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* refactor(scanner): replace parseTargets function with direct call to scanner.ParseTargets

Signed-off-by: Deluan <deluan@navidrome.org>

* test(scanner): add tests for ScanBegin and ScanEnd functionality

Signed-off-by: Deluan <deluan@navidrome.org>

* fix(library): update PRAGMA optimize to check table sizes without ANALYZE

Signed-off-by: Deluan <deluan@navidrome.org>

* test(scanner): refactor tests

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(ui): add selective scan options and update translations

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(ui): add quick and full scan options for individual libraries

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(ui): add Scan buttonsto the LibraryList

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(scan): update scanning parameters from 'path' to 'target' for selective scans.

* refactor(scan): move ParseTargets function to model package

* test(scan): suppress unused return value from SetUserLibraries in tests

* feat(gc): enhance garbage collection to support selective library purging

Signed-off-by: Deluan <deluan@navidrome.org>

* fix(scanner): prevent race condition when scanning deleted folders

When the watcher detects changes in a folder that gets deleted before
the scanner runs (due to the 10-second delay), the scanner was
prematurely removing these folders from the tracking map, preventing
them from being marked as missing.

The issue occurred because `newFolderEntry` was calling `popLastUpdate`
before verifying the folder actually exists on the filesystem.

Changes:
- Move fs.Stat check before newFolderEntry creation in loadDir to
  ensure deleted folders remain in lastUpdates for finalize() to handle
- Add early existence check in walkDirTree to skip non-existent target
  folders with a warning log
- Add unit test verifying non-existent folders aren't removed from
  lastUpdates prematurely
- Add integration test for deleted folder scenario with ScanFolders

Fixes the issue where deleting entire folders (e.g., /music/AC_DC)
wouldn't mark tracks as missing when using selective folder scanning.

* refactor(scan): streamline folder entry creation and update handling

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(scan): add '@Recycle' (QNAP) to ignored directories list

Signed-off-by: Deluan <deluan@navidrome.org>

* fix(log): improve thread safety in logging level management

* test(scan): move unit tests for ParseTargets function

Signed-off-by: Deluan <deluan@navidrome.org>

* review

Signed-off-by: Deluan <deluan@navidrome.org>

---------

Signed-off-by: Deluan <deluan@navidrome.org>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: deluan <deluan.quintao@mechanical-orchard.com>
2025-11-14 22:15:43 -05:00
Deluan
2385c8a548 test: mock formatFullDate for consistent test results 2025-11-13 18:46:06 -05:00
Deluan
9b3bdc8a8b fix(ui): adjust margins for bulk actions buttons in Spotify-ish and Ligera
Signed-off-by: Deluan <deluan@navidrome.org>
2025-11-13 18:30:44 -05:00
Deluan
f939ad84f3 fix(ui): increase contrast of button text in the Dark theme
Signed-off-by: Deluan <deluan@navidrome.org>
2025-11-12 16:17:41 -05:00
Deluan
c3e8c67116 feat(ui): update totalSize formatting to display two decimal places
Signed-off-by: Deluan <deluan@navidrome.org>
2025-11-12 13:23:18 -05:00
Deluan
73ec89e1af feat(ui): add SizeField to display total size in LibraryList
Signed-off-by: Deluan <deluan@navidrome.org>
2025-11-12 13:01:17 -05:00
Deluan Quintão
69527085db
fix(ui): resolve transparent dropdown background in Ligera theme (#4665)
Fixed the multi-library selector dropdown background in the Ligera theme by changing the palette.background.paper value from 'inherit' to bLight['500'] ('#ffffff'). This ensures the dropdown has a solid white background that properly overlays content, making the library selection options clearly readable.

Closes #4502
2025-11-08 12:47:02 -05:00
Deluan Quintão
290a9fdeaa
test: fix locale-dependent tests by making formatNumber locale-aware (#4619)
- Add optional locale parameter to formatNumber function
- Update tests to explicitly pass 'en-US' locale for deterministic results
- Maintains backward compatibility: defaults to system locale when no locale specified
- No need for cross-env or environment variable manipulation
- Tests now pass consistently regardless of system locale

Related to #4417
2025-11-06 14:34:00 -05:00
pca006132
e86dc03619
fix(ui): allow scrolling in play queue by adding delay (#4562) 2025-11-01 20:47:03 -04:00
deluan
0bdd3e6f8b fix(ui): fix Ligera theme's RaPaginationActions contrast 2025-10-30 16:34:31 -04:00
Konstantin Morenko
465846c1bc
fix(ui): fix color of MuiIconButton in Gruvbox Dark theme (#4585)
* Fixed color of MuiIconButton in gruvboxDark.js

* Update ui/src/themes/gruvboxDark.js

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-10-29 09:14:40 -04:00
Deluan Quintão
d021289279
fix: enable multi-valued releasetype in smart playlists (#4621)
* fix: prevent infinite loop in Type filter autocomplete

Fixed an infinite loop issue in the album Type filter caused by an inline
arrow function in the optionText prop. The inline function created a new
reference on every render, causing React-Admin's AutocompleteInput to
continuously re-fetch data from the /api/tag endpoint.

The solution extracts the formatting function outside the component scope
as formatReleaseType, ensuring a stable function reference across renders.
This prevents unnecessary re-renders and API calls while maintaining the
humanized display format for release type values.

* fix: enable multi-valued releasetype in smart playlists

Smart playlists can now match all values in multi-valued releasetype tags.
Previously, the albumtype field was mapped to the single-valued mbz_album_type
database field, which only stored the first value from tags like album; soundtrack.
This prevented smart playlists from matching albums with secondary release types
like soundtrack, live, or compilation when tagged by MusicBrainz Picard.

The fix removes the direct database field mapping and allows both albumtype and
releasetype to use the multi-valued tag system. The albumtype field is now an
alias that points to the releasetype tag field, ensuring both query the same
JSON path in the tags column. This maintains backward compatibility with the
documented albumtype field while enabling proper multi-value tag matching.

Added tests to verify both releasetype and albumtype correctly generate
multi-valued tag queries.

Fixes #4616

* fix: resolve albumtype alias for all operators and sorting

Codex correctly identified that the initial fix only worked for Contains/StartsWith/EndsWith operators. The alias resolution was happening too late in the code path.

Fixed by resolving the alias in two places:
1. tagCond.ToSql() - now uses the actual field name (releasetype) in the JSON path
2. Criteria.OrderBy() - now uses the actual field name when building sort expressions

Added tests for Is/IsNot operators and sorting to ensure complete coverage.
2025-10-26 19:36:44 -04:00
Deluan
e24f7984cc chore(deps-dev): update happy-dom to version 20.0.8
Signed-off-by: Deluan <deluan@navidrome.org>
2025-10-25 17:25:52 -04:00
dependabot[bot]
ac3e6ae6a5
chore(deps-dev): bump brace-expansion from 1.1.11 to 1.1.12 in /ui (#4217)
Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion) from 1.1.11 to 1.1.12.
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/1.1.11...v1.1.12)

---
updated-dependencies:
- dependency-name: brace-expansion
  dependency-version: 1.1.12
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Deluan Quintão <deluan@navidrome.org>
2025-10-25 17:24:31 -04:00
Deluan Quintão
b2019da999
chore(deps): update all dependencies (#4618)
* chore: update to Go 1.25.3

Signed-off-by: Deluan <deluan@navidrome.org>

* chore: update to golangci-lint

Signed-off-by: Deluan <deluan@navidrome.org>

* chore: update go dependencies

Signed-off-by: Deluan <deluan@navidrome.org>

* chore: update vite dependencies in package.json and improve EventSource mock in tests

- Upgraded @vitejs/plugin-react to version 5.1.0 and @vitest/coverage-v8 to version 4.0.3.
- Updated vite to version 7.1.12 and vite-plugin-pwa to version 1.1.0.
- Enhanced the EventSource mock implementation in eventStream.test.js for better test isolation.

* ci: remove coverage flag from Go test command in pipeline

* chore: update Node.js version to v24 in devcontainer, pipeline, and .nvmrc

* chore: prettier

Signed-off-by: Deluan <deluan@navidrome.org>

* chore: update actions/checkout from v4 to v5 in pipeline and update-translations workflows

* chore: update JS dependencies remove unused jest-dom import in Linkify.test.jsx

* chore: update actions/download-artifact from v4 to v5 in pipeline

---------

Signed-off-by: Deluan <deluan@navidrome.org>
2025-10-25 17:05:16 -04:00
Deluan
aff9c7120b feat(ui): add Genre column as optional field in playlist table view
Added genre as a toggleable column in the playlist songs table. The Genre column
displays genre information for each song in playlists and is available through
the column toggle menu but disabled by default.

Implements feature request from GitHub discussion #4400.

Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-29 20:54:04 -04:00
Deluan Quintão
a30fa478ac
feat(ui): reset activity panel error icon to normal state when clicked (#4379)
* ui: reset activity icon after viewing error

* refactor: improve ActivityPanel error acknowledgment logic

Replaced boolean errorAcknowledged state with acknowledgedError string state to track which specific error was acknowledged. This prevents icon flickering when error messages change and simplifies the logic by removing the need for useEffect.

Key changes:
- Changed from errorAcknowledged boolean to acknowledgedError string state
- Added derived isErrorVisible computed value for cleaner logic
- Removed useEffect dependency on scanStatus.error changes
- Updated handleMenuOpen to store actual error string instead of boolean flag
- Fixed test mock to return proper error state matching test expectations

This change addresses code review feedback and follows React best practices by using derived state instead of imperative effects.
2025-07-23 19:43:42 -04:00
Deluan Quintão
c193bb2a09
fix(server): headless library access improvements (#4362)
* fix: enable library access for headless processes

Fixed multi-library filtering to allow headless processes (shares, external providers) to access data by skipping library restrictions when no user context is present.

Previously, the library filtering system returned empty results (WHERE 1=0) for processes without user authentication, breaking functionality like public shares and external service integrations.

Key changes:
- Modified applyLibraryFilter methods to skip filtering when user.ID == invalidUserId
- Refactored tag repository to use helper method for library filtering logic
- Fixed SQL aggregation bug in tag statistics calculation across multiple libraries
- Added comprehensive test coverage for headless process scenarios
- Updated genre repository to support proper column mappings for aggregated data

This preserves the secure "safe by default" approach for authenticated users while restoring backward compatibility for background processes that need unrestricted data access.

Signed-off-by: Deluan <deluan@navidrome.org>

* fix: resolve SQL ambiguity errors in share queries

Fixed SQL ambiguity errors that were breaking share links after the Multi-library PR.
The Multi-library changes introduced JOINs between album and library tables,
both of which have 'id' columns, causing 'ambiguous column name: id' errors
when unqualified column references were used in WHERE clauses.

Changes made:
- Updated core/share.go to use 'album.id' instead of 'id' in contentsLabelFromAlbums
- Updated persistence/share_repository.go to use 'album.id' in album share loading
- Updated persistence/sql_participations.go to use 'artist.id' for consistency
- Added regression tests to prevent future SQL ambiguity issues

This resolves HTTP 500 errors that users experienced when accessing existing
share URLs after the Multi-library feature was merged.

Signed-off-by: Deluan <deluan@navidrome.org>

* fix: improve headless library access handling

Added proper user context validation and reordered joins in applyLibraryFilterToArtistQuery to ensure library filtering works correctly for both authenticated and headless operations. The user_library join is now only applied when a valid user context exists, while the library_artist join is always applied to maintain proper data relationships. (+1 squashed commit)
Squashed commits:
[a28c6965b] fix: remove headless library access guard

Removed the invalidUserId guard condition in applyLibraryFilterToArtistQuery that was preventing proper library filtering for headless operations. This fix ensures that library filtering joins are always applied consistently, allowing headless library access to work correctly with the library_artist junction table filtering.

The previous guard was skipping all library filtering when no user context was present, which could cause issues with headless operations that still need to respect library boundaries through the library_artist relationship.

* fix: simplify genre selection query in genre repository

Signed-off-by: Deluan <deluan@navidrome.org>

* fix: enhance tag library filtering tests for headless access

Signed-off-by: Deluan <deluan@navidrome.org>

* test: add comprehensive test coverage for headless library access

Added extensive test coverage for headless library access improvements including:

- Added 17 new tests across 4 test files covering headless access scenarios
- artist_repository_test.go: Added headless process tests for GetAll, Count,
  Get operations and explicit library_id filtering functionality
- genre_repository_test.go: Added library filtering tests for headless processes
  including GetAll, Count, ReadAll, and Read operations
- sql_base_repository_test.go: Added applyLibraryFilter method tests covering
  admin users, regular users, and headless processes with/without custom table names
- share_repository_test.go: Added headless access tests and SQL ambiguity
  verification for the album.id vs id fix in loadMedia function
- Cleaned up test setup by replacing log.NewContext usage with GinkgoT().Context()
  and removing unnecessary configtest.SetupConfig() calls for better test isolation

These tests ensure that headless processes (background operations without user context)
can access all libraries while respecting explicit filters, and verify that the SQL
ambiguity fixes work correctly without breaking existing functionality.

* revert: remove user context handling from scrobble buffer getParticipants

Reverts commit 5b8ef74f05.

The artist repository no longer requires user context for proper library
filtering, so the workaround of temporarily injecting user context into
the scrobbleBufferRepository.Next method is no longer needed.

This simplifies the code and removes the dependency on fetching user
information during background scrobbling operations.

* fix: improve library access filtering for artists

Enhanced artist repository filtering to properly handle library access restrictions
and prevent artists with no accessible content from appearing in results.

Backend changes:
- Modified roleFilter to use direct JSON_EXTRACT instead of EXISTS subquery for better performance
- Enhanced applyLibraryFilterToArtistQuery to filter out artists with empty stats (no content)
- Changed from LEFT JOIN to INNER JOIN with library_artist table for stricter filtering
- Added condition to exclude artists where library_artist.stats = '{}' (empty content)

Frontend changes:
- Added null-checking in getCounter function to prevent TypeError when accessing undefined records
- Improved optional chaining for safer property access in role-based statistics display

These changes ensure that users only see artists that have actual accessible content
in their permitted libraries, fixing issues where artists appeared in the list
despite having no albums or songs available to the user.

* fix: update library access logic for non-admin users and enhance test coverage

Signed-off-by: Deluan <deluan@navidrome.org>

* fix: refine library artist query and implement cleanup for empty entries

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor: consolidate artist repository tests to eliminate duplication

Significantly refactored artist_repository_test.go to reduce code duplication and
improve maintainability by ~27% (930 to 680 lines). Key improvements include:

- Added test helper functions createTestArtistWithMBID() and createUserWithLibraries()
  to eliminate repetitive test data creation
- Consolidated duplicate MBID search tests using DescribeTable for parameterized testing
- Removed entire 'Permission-Based Behavior Comparison' section (~150 lines) that
  duplicated functionality already covered in other test contexts
- Reorganized search tests into cohesive 'MBID and Text Search' section with proper
  setup/teardown and shared test infrastructure
- Streamlined missing artist tests and moved them to dedicated section
- Maintained 100% test coverage while eliminating redundant test patterns

All tests continue to pass with identical functionality and coverage.

---------

Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-20 15:58:21 -04:00