diff --git a/model/get_entity.go b/model/get_entity.go index 26f718396..b50f336e6 100644 --- a/model/get_entity.go +++ b/model/get_entity.go @@ -6,6 +6,10 @@ import ( // TODO: Should the type be encoded in the ID? func GetEntityByID(ctx context.Context, ds DataStore, id string) (any, error) { + f, err := ds.Folder(ctx).Get(id) + if err == nil { + return f, nil + } ar, err := ds.Artist(ctx).Get(id) if err == nil { return ar, nil diff --git a/model/get_entity_test.go b/model/get_entity_test.go new file mode 100644 index 000000000..6fcb91547 --- /dev/null +++ b/model/get_entity_test.go @@ -0,0 +1,66 @@ +package model_test + +import ( + "context" + + "github.com/navidrome/navidrome/model" + "github.com/navidrome/navidrome/tests" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = Describe("GetEntityByID", func() { + var ( + ctx context.Context + ds *tests.MockDataStore + ) + + BeforeEach(func() { + ctx = context.Background() + ds = &tests.MockDataStore{} + }) + + It("returns a Folder when found", func() { + folder := model.Folder{ID: "folder-1", Name: "Jazz"} + ds.Folder(ctx).(*tests.MockFolderRepo).SetData([]model.Folder{folder}) + + entity, err := model.GetEntityByID(ctx, ds, "folder-1") + Expect(err).ToNot(HaveOccurred()) + Expect(entity).To(BeAssignableToTypeOf(&model.Folder{})) + Expect(entity.(*model.Folder).ID).To(Equal("folder-1")) + }) + + It("returns a Folder before trying Artist for the same ID", func() { + folder := model.Folder{ID: "shared-id", Name: "Folder"} + artist := model.Artist{ID: "shared-id", Name: "Artist"} + ds.Folder(ctx).(*tests.MockFolderRepo).SetData([]model.Folder{folder}) + ds.Artist(ctx).(*tests.MockArtistRepo).SetData(model.Artists{artist}) + + entity, err := model.GetEntityByID(ctx, ds, "shared-id") + Expect(err).ToNot(HaveOccurred()) + Expect(entity).To(BeAssignableToTypeOf(&model.Folder{})) + }) + + It("returns an Artist when no Folder matches", func() { + artist := model.Artist{ID: "artist-1", Name: "Kraftwerk"} + ds.Artist(ctx).(*tests.MockArtistRepo).SetData(model.Artists{artist}) + + entity, err := model.GetEntityByID(ctx, ds, "artist-1") + Expect(err).ToNot(HaveOccurred()) + Expect(entity).To(BeAssignableToTypeOf(&model.Artist{})) + }) + + It("returns an Album when no Folder or Artist matches", func() { + album := model.Album{ID: "album-1", Name: "Radioactivity"} + ds.Album(ctx).(*tests.MockAlbumRepo).SetData(model.Albums{album}) + + entity, err := model.GetEntityByID(ctx, ds, "album-1") + Expect(err).ToNot(HaveOccurred()) + Expect(entity).To(BeAssignableToTypeOf(&model.Album{})) + }) + + It("returns an error when no entity is found", func() { + _, err := model.GetEntityByID(ctx, ds, "nonexistent") + Expect(err).To(MatchError(model.ErrNotFound)) + }) +}) diff --git a/tests/mock_data_store.go b/tests/mock_data_store.go index 754f0c084..26586d8e1 100644 --- a/tests/mock_data_store.go +++ b/tests/mock_data_store.go @@ -54,7 +54,7 @@ func (db *MockDataStore) Folder(ctx context.Context) model.FolderRepository { if db.RealDS != nil { return db.RealDS.Folder(ctx) } - db.MockedFolder = struct{ model.FolderRepository }{} + db.MockedFolder = CreateMockFolderRepo() return db.MockedFolder } diff --git a/tests/mock_folder_repo.go b/tests/mock_folder_repo.go new file mode 100644 index 000000000..360ce9210 --- /dev/null +++ b/tests/mock_folder_repo.go @@ -0,0 +1,55 @@ +package tests + +import ( + "errors" + + "github.com/navidrome/navidrome/model" +) + +func CreateMockFolderRepo() *MockFolderRepo { + return &MockFolderRepo{ + Data: make(map[string]*model.Folder), + } +} + +type MockFolderRepo struct { + model.FolderRepository + Data map[string]*model.Folder + Err bool + Options model.QueryOptions +} + +func (m *MockFolderRepo) SetError(err bool) { + m.Err = err +} + +func (m *MockFolderRepo) SetData(folders []model.Folder) { + m.Data = make(map[string]*model.Folder) + for i, f := range folders { + m.Data[f.ID] = &folders[i] + } +} + +func (m *MockFolderRepo) Get(id string) (*model.Folder, error) { + if m.Err { + return nil, errors.New("Error!") + } + if d, ok := m.Data[id]; ok { + return d, nil + } + return nil, model.ErrNotFound +} + +func (m *MockFolderRepo) GetAll(opts ...model.QueryOptions) ([]model.Folder, error) { + if m.Err { + return nil, errors.New("Error!") + } + if len(opts) > 0 { + m.Options = opts[0] + } + var result []model.Folder + for _, f := range m.Data { + result = append(result, *f) + } + return result, nil +}