update
Some checks failed
Pipeline: Test, Lint, Build / Get version info (push) Has been cancelled
Pipeline: Test, Lint, Build / Lint Go code (push) Has been cancelled
Pipeline: Test, Lint, Build / Test Go code (push) Has been cancelled
Pipeline: Test, Lint, Build / Test JS code (push) Has been cancelled
Pipeline: Test, Lint, Build / Lint i18n files (push) Has been cancelled
Pipeline: Test, Lint, Build / Check Docker configuration (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (darwin/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (darwin/arm64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/386) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v5) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v6) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v7) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (windows/386) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (windows/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Push to GHCR (push) Has been cancelled
Pipeline: Test, Lint, Build / Push to Docker Hub (push) Has been cancelled
Pipeline: Test, Lint, Build / Cleanup digest artifacts (push) Has been cancelled
Pipeline: Test, Lint, Build / Build Windows installers (push) Has been cancelled
Pipeline: Test, Lint, Build / Package/Release (push) Has been cancelled
Pipeline: Test, Lint, Build / Upload Linux PKG (push) Has been cancelled
Close stale issues and PRs / stale (push) Has been cancelled
POEditor import / update-translations (push) Has been cancelled
Some checks failed
Pipeline: Test, Lint, Build / Get version info (push) Has been cancelled
Pipeline: Test, Lint, Build / Lint Go code (push) Has been cancelled
Pipeline: Test, Lint, Build / Test Go code (push) Has been cancelled
Pipeline: Test, Lint, Build / Test JS code (push) Has been cancelled
Pipeline: Test, Lint, Build / Lint i18n files (push) Has been cancelled
Pipeline: Test, Lint, Build / Check Docker configuration (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (darwin/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (darwin/arm64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/386) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v5) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v6) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm/v7) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (linux/arm64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (windows/386) (push) Has been cancelled
Pipeline: Test, Lint, Build / Build (windows/amd64) (push) Has been cancelled
Pipeline: Test, Lint, Build / Push to GHCR (push) Has been cancelled
Pipeline: Test, Lint, Build / Push to Docker Hub (push) Has been cancelled
Pipeline: Test, Lint, Build / Cleanup digest artifacts (push) Has been cancelled
Pipeline: Test, Lint, Build / Build Windows installers (push) Has been cancelled
Pipeline: Test, Lint, Build / Package/Release (push) Has been cancelled
Pipeline: Test, Lint, Build / Upload Linux PKG (push) Has been cancelled
Close stale issues and PRs / stale (push) Has been cancelled
POEditor import / update-translations (push) Has been cancelled
This commit is contained in:
364
core/external/provider_albumimage_test.go
vendored
Normal file
364
core/external/provider_albumimage_test.go
vendored
Normal file
@@ -0,0 +1,364 @@
|
||||
package external_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/url"
|
||||
|
||||
"github.com/navidrome/navidrome/conf"
|
||||
"github.com/navidrome/navidrome/conf/configtest"
|
||||
"github.com/navidrome/navidrome/core/agents"
|
||||
. "github.com/navidrome/navidrome/core/external"
|
||||
"github.com/navidrome/navidrome/model"
|
||||
"github.com/navidrome/navidrome/tests"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
var _ = Describe("Provider - AlbumImage", func() {
|
||||
var ds *tests.MockDataStore
|
||||
var provider Provider
|
||||
var mockArtistRepo *mockArtistRepo
|
||||
var mockAlbumRepo *mockAlbumRepo
|
||||
var mockMediaFileRepo *mockMediaFileRepo
|
||||
var mockAlbumAgent *mockAlbumInfoAgent
|
||||
var ctx context.Context
|
||||
|
||||
BeforeEach(func() {
|
||||
ctx = GinkgoT().Context()
|
||||
DeferCleanup(configtest.SetupConfig())
|
||||
conf.Server.Agents = "mockAlbum" // Configure mock agent
|
||||
|
||||
mockArtistRepo = newMockArtistRepo()
|
||||
mockAlbumRepo = newMockAlbumRepo()
|
||||
mockMediaFileRepo = newMockMediaFileRepo()
|
||||
|
||||
ds = &tests.MockDataStore{
|
||||
MockedArtist: mockArtistRepo,
|
||||
MockedAlbum: mockAlbumRepo,
|
||||
MockedMediaFile: mockMediaFileRepo,
|
||||
}
|
||||
|
||||
mockAlbumAgent = newMockAlbumInfoAgent()
|
||||
|
||||
agentsCombined := &mockAgents{albumInfoAgent: mockAlbumAgent}
|
||||
provider = NewProvider(ds, agentsCombined)
|
||||
|
||||
// Default mocks
|
||||
// Mocks for GetEntityByID sequence (initial failed lookups)
|
||||
mockArtistRepo.On("Get", "album-1").Return(nil, model.ErrNotFound).Once()
|
||||
mockArtistRepo.On("Get", "mf-1").Return(nil, model.ErrNotFound).Once()
|
||||
mockAlbumRepo.On("Get", "mf-1").Return(nil, model.ErrNotFound).Once()
|
||||
|
||||
// Default mock for non-existent entities - Use Maybe() for flexibility
|
||||
mockArtistRepo.On("Get", "not-found").Return(nil, model.ErrNotFound).Maybe()
|
||||
mockAlbumRepo.On("Get", "not-found").Return(nil, model.ErrNotFound).Maybe()
|
||||
mockMediaFileRepo.On("Get", "not-found").Return(nil, model.ErrNotFound).Maybe()
|
||||
})
|
||||
|
||||
It("returns the largest image URL when successful", func() {
|
||||
// Arrange
|
||||
mockArtistRepo.On("Get", "album-1").Return(nil, model.ErrNotFound).Once() // Expect GetEntityByID sequence
|
||||
mockAlbumRepo.On("Get", "album-1").Return(&model.Album{ID: "album-1", Name: "Album One", AlbumArtistID: "artist-1"}, nil).Once()
|
||||
// Explicitly mock agent call for this test
|
||||
mockAlbumAgent.On("GetAlbumImages", ctx, "Album One", "", "").
|
||||
Return([]agents.ExternalImage{
|
||||
{URL: "http://example.com/large.jpg", Size: 1000},
|
||||
{URL: "http://example.com/medium.jpg", Size: 500},
|
||||
{URL: "http://example.com/small.jpg", Size: 200},
|
||||
}, nil).Once()
|
||||
|
||||
expectedURL, _ := url.Parse("http://example.com/large.jpg")
|
||||
imgURL, err := provider.AlbumImage(ctx, "album-1")
|
||||
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(imgURL).To(Equal(expectedURL))
|
||||
mockArtistRepo.AssertCalled(GinkgoT(), "Get", "album-1") // From GetEntityByID
|
||||
mockAlbumRepo.AssertCalled(GinkgoT(), "Get", "album-1")
|
||||
mockArtistRepo.AssertNotCalled(GinkgoT(), "Get", "artist-1") // Artist lookup no longer happens in getAlbum
|
||||
mockAlbumAgent.AssertCalled(GinkgoT(), "GetAlbumImages", ctx, "Album One", "", "") // Expect empty artist name
|
||||
})
|
||||
|
||||
It("returns ErrNotFound if the album is not found in the DB", func() {
|
||||
// Arrange: Explicitly expect the full GetEntityByID sequence for "not-found"
|
||||
mockArtistRepo.On("Get", "not-found").Return(nil, model.ErrNotFound).Once()
|
||||
mockAlbumRepo.On("Get", "not-found").Return(nil, model.ErrNotFound).Once()
|
||||
mockMediaFileRepo.On("Get", "not-found").Return(nil, model.ErrNotFound).Once()
|
||||
|
||||
imgURL, err := provider.AlbumImage(ctx, "not-found")
|
||||
|
||||
Expect(err).To(MatchError("data not found"))
|
||||
Expect(imgURL).To(BeNil())
|
||||
mockArtistRepo.AssertCalled(GinkgoT(), "Get", "not-found")
|
||||
mockAlbumRepo.AssertCalled(GinkgoT(), "Get", "not-found")
|
||||
mockMediaFileRepo.AssertCalled(GinkgoT(), "Get", "not-found")
|
||||
mockAlbumAgent.AssertNotCalled(GinkgoT(), "GetAlbumImages", mock.Anything, mock.Anything, mock.Anything)
|
||||
})
|
||||
|
||||
It("returns the agent error if the agent fails", func() {
|
||||
// Arrange
|
||||
mockArtistRepo.On("Get", "album-1").Return(nil, model.ErrNotFound).Once() // Expect GetEntityByID sequence
|
||||
mockAlbumRepo.On("Get", "album-1").Return(&model.Album{ID: "album-1", Name: "Album One", AlbumArtistID: "artist-1"}, nil).Once()
|
||||
|
||||
agentErr := errors.New("agent failure")
|
||||
// Explicitly mock agent call for this test
|
||||
mockAlbumAgent.On("GetAlbumImages", ctx, "Album One", "", "").Return(nil, agentErr).Once() // Expect empty artist
|
||||
|
||||
imgURL, err := provider.AlbumImage(ctx, "album-1")
|
||||
|
||||
Expect(err).To(MatchError("agent failure"))
|
||||
Expect(imgURL).To(BeNil())
|
||||
mockArtistRepo.AssertCalled(GinkgoT(), "Get", "album-1")
|
||||
mockAlbumRepo.AssertCalled(GinkgoT(), "Get", "album-1")
|
||||
mockArtistRepo.AssertNotCalled(GinkgoT(), "Get", "artist-1")
|
||||
mockAlbumAgent.AssertCalled(GinkgoT(), "GetAlbumImages", ctx, "Album One", "", "") // Expect empty artist
|
||||
})
|
||||
|
||||
It("returns ErrNotFound if the agent returns ErrNotFound", func() {
|
||||
// Arrange
|
||||
mockArtistRepo.On("Get", "album-1").Return(nil, model.ErrNotFound).Once() // Expect GetEntityByID sequence
|
||||
mockAlbumRepo.On("Get", "album-1").Return(&model.Album{ID: "album-1", Name: "Album One", AlbumArtistID: "artist-1"}, nil).Once()
|
||||
|
||||
// Explicitly mock agent call for this test
|
||||
mockAlbumAgent.On("GetAlbumImages", ctx, "Album One", "", "").Return(nil, agents.ErrNotFound).Once() // Expect empty artist
|
||||
|
||||
imgURL, err := provider.AlbumImage(ctx, "album-1")
|
||||
|
||||
Expect(err).To(MatchError("data not found"))
|
||||
Expect(imgURL).To(BeNil())
|
||||
mockArtistRepo.AssertCalled(GinkgoT(), "Get", "album-1")
|
||||
mockAlbumRepo.AssertCalled(GinkgoT(), "Get", "album-1")
|
||||
mockAlbumAgent.AssertCalled(GinkgoT(), "GetAlbumImages", ctx, "Album One", "", "") // Expect empty artist
|
||||
})
|
||||
|
||||
It("returns ErrNotFound if the agent returns no images", func() {
|
||||
// Arrange
|
||||
mockArtistRepo.On("Get", "album-1").Return(nil, model.ErrNotFound).Once() // Expect GetEntityByID sequence
|
||||
mockAlbumRepo.On("Get", "album-1").Return(&model.Album{ID: "album-1", Name: "Album One", AlbumArtistID: "artist-1"}, nil).Once()
|
||||
|
||||
// Explicitly mock agent call for this test
|
||||
mockAlbumAgent.On("GetAlbumImages", ctx, "Album One", "", "").
|
||||
Return([]agents.ExternalImage{}, nil).Once() // Expect empty artist
|
||||
|
||||
imgURL, err := provider.AlbumImage(ctx, "album-1")
|
||||
|
||||
Expect(err).To(MatchError("data not found"))
|
||||
Expect(imgURL).To(BeNil())
|
||||
mockArtistRepo.AssertCalled(GinkgoT(), "Get", "album-1")
|
||||
mockAlbumRepo.AssertCalled(GinkgoT(), "Get", "album-1")
|
||||
mockAlbumAgent.AssertCalled(GinkgoT(), "GetAlbumImages", ctx, "Album One", "", "") // Expect empty artist
|
||||
})
|
||||
|
||||
It("returns context error if context is canceled", func() {
|
||||
// Arrange
|
||||
cctx, cancelCtx := context.WithCancel(ctx)
|
||||
// Mock the necessary DB calls *before* canceling the context
|
||||
mockArtistRepo.On("Get", "album-1").Return(nil, model.ErrNotFound).Once()
|
||||
mockAlbumRepo.On("Get", "album-1").Return(&model.Album{ID: "album-1", Name: "Album One", AlbumArtistID: "artist-1"}, nil).Once()
|
||||
// Expect the agent call even if context is cancelled, returning the context error
|
||||
mockAlbumAgent.On("GetAlbumImages", cctx, "Album One", "", "").Return(nil, context.Canceled).Once()
|
||||
// Cancel the context *before* calling the function under test
|
||||
cancelCtx()
|
||||
|
||||
imgURL, err := provider.AlbumImage(cctx, "album-1")
|
||||
|
||||
Expect(err).To(MatchError("context canceled"))
|
||||
Expect(imgURL).To(BeNil())
|
||||
mockArtistRepo.AssertCalled(GinkgoT(), "Get", "album-1")
|
||||
mockAlbumRepo.AssertCalled(GinkgoT(), "Get", "album-1")
|
||||
// Agent should now be called, verify this expectation
|
||||
mockAlbumAgent.AssertCalled(GinkgoT(), "GetAlbumImages", cctx, "Album One", "", "")
|
||||
})
|
||||
|
||||
It("derives album ID from MediaFile ID", func() {
|
||||
// Arrange: Mock full GetEntityByID for "mf-1" and recursive "album-1"
|
||||
mockArtistRepo.On("Get", "mf-1").Return(nil, model.ErrNotFound).Once()
|
||||
mockAlbumRepo.On("Get", "mf-1").Return(nil, model.ErrNotFound).Once()
|
||||
mockMediaFileRepo.On("Get", "mf-1").Return(&model.MediaFile{ID: "mf-1", Title: "Track One", ArtistID: "artist-1", AlbumID: "album-1"}, nil).Once()
|
||||
mockArtistRepo.On("Get", "album-1").Return(nil, model.ErrNotFound).Once()
|
||||
mockAlbumRepo.On("Get", "album-1").Return(&model.Album{ID: "album-1", Name: "Album One", AlbumArtistID: "artist-1"}, nil).Once()
|
||||
|
||||
// Explicitly mock agent call for this test
|
||||
mockAlbumAgent.On("GetAlbumImages", ctx, "Album One", "", "").
|
||||
Return([]agents.ExternalImage{
|
||||
{URL: "http://example.com/large.jpg", Size: 1000},
|
||||
{URL: "http://example.com/medium.jpg", Size: 500},
|
||||
{URL: "http://example.com/small.jpg", Size: 200},
|
||||
}, nil).Once()
|
||||
|
||||
expectedURL, _ := url.Parse("http://example.com/large.jpg")
|
||||
imgURL, err := provider.AlbumImage(ctx, "mf-1")
|
||||
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(imgURL).To(Equal(expectedURL))
|
||||
mockArtistRepo.AssertCalled(GinkgoT(), "Get", "mf-1")
|
||||
mockAlbumRepo.AssertCalled(GinkgoT(), "Get", "mf-1")
|
||||
mockMediaFileRepo.AssertCalled(GinkgoT(), "Get", "mf-1")
|
||||
mockArtistRepo.AssertCalled(GinkgoT(), "Get", "album-1")
|
||||
mockAlbumRepo.AssertCalled(GinkgoT(), "Get", "album-1")
|
||||
mockArtistRepo.AssertNotCalled(GinkgoT(), "Get", "artist-1")
|
||||
mockAlbumAgent.AssertCalled(GinkgoT(), "GetAlbumImages", ctx, "Album One", "", "")
|
||||
})
|
||||
|
||||
It("handles different image orders from agent", func() {
|
||||
// Arrange
|
||||
mockArtistRepo.On("Get", "album-1").Return(nil, model.ErrNotFound).Once() // Expect GetEntityByID sequence
|
||||
mockAlbumRepo.On("Get", "album-1").Return(&model.Album{ID: "album-1", Name: "Album One", AlbumArtistID: "artist-1"}, nil).Once()
|
||||
// Explicitly mock agent call for this test
|
||||
mockAlbumAgent.On("GetAlbumImages", ctx, "Album One", "", "").
|
||||
Return([]agents.ExternalImage{
|
||||
{URL: "http://example.com/small.jpg", Size: 200},
|
||||
{URL: "http://example.com/large.jpg", Size: 1000},
|
||||
{URL: "http://example.com/medium.jpg", Size: 500},
|
||||
}, nil).Once()
|
||||
|
||||
expectedURL, _ := url.Parse("http://example.com/large.jpg")
|
||||
imgURL, err := provider.AlbumImage(ctx, "album-1")
|
||||
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(imgURL).To(Equal(expectedURL)) // Should still pick the largest
|
||||
mockAlbumAgent.AssertCalled(GinkgoT(), "GetAlbumImages", ctx, "Album One", "", "")
|
||||
})
|
||||
|
||||
It("handles agent returning only one image", func() {
|
||||
// Arrange
|
||||
mockArtistRepo.On("Get", "album-1").Return(nil, model.ErrNotFound).Once() // Expect GetEntityByID sequence
|
||||
mockAlbumRepo.On("Get", "album-1").Return(&model.Album{ID: "album-1", Name: "Album One", AlbumArtistID: "artist-1"}, nil).Once()
|
||||
// Explicitly mock agent call for this test
|
||||
mockAlbumAgent.On("GetAlbumImages", ctx, "Album One", "", "").
|
||||
Return([]agents.ExternalImage{
|
||||
{URL: "http://example.com/single.jpg", Size: 700},
|
||||
}, nil).Once()
|
||||
|
||||
expectedURL, _ := url.Parse("http://example.com/single.jpg")
|
||||
imgURL, err := provider.AlbumImage(ctx, "album-1")
|
||||
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(imgURL).To(Equal(expectedURL))
|
||||
mockAlbumAgent.AssertCalled(GinkgoT(), "GetAlbumImages", ctx, "Album One", "", "")
|
||||
})
|
||||
|
||||
It("returns ErrNotFound if deriving album ID fails", func() {
|
||||
// Arrange: Mock full GetEntityByID for "mf-no-album" and recursive "not-found"
|
||||
mockArtistRepo.On("Get", "mf-no-album").Return(nil, model.ErrNotFound).Once()
|
||||
mockAlbumRepo.On("Get", "mf-no-album").Return(nil, model.ErrNotFound).Once()
|
||||
mockMediaFileRepo.On("Get", "mf-no-album").Return(&model.MediaFile{ID: "mf-no-album", Title: "Track No Album", ArtistID: "artist-1", AlbumID: "not-found"}, nil).Once()
|
||||
mockArtistRepo.On("Get", "not-found").Return(nil, model.ErrNotFound).Once()
|
||||
mockAlbumRepo.On("Get", "not-found").Return(nil, model.ErrNotFound).Once()
|
||||
mockMediaFileRepo.On("Get", "not-found").Return(nil, model.ErrNotFound).Once()
|
||||
|
||||
imgURL, err := provider.AlbumImage(ctx, "mf-no-album")
|
||||
|
||||
Expect(err).To(MatchError("data not found"))
|
||||
Expect(imgURL).To(BeNil())
|
||||
mockArtistRepo.AssertCalled(GinkgoT(), "Get", "mf-no-album")
|
||||
mockAlbumRepo.AssertCalled(GinkgoT(), "Get", "mf-no-album")
|
||||
mockMediaFileRepo.AssertCalled(GinkgoT(), "Get", "mf-no-album")
|
||||
mockArtistRepo.AssertCalled(GinkgoT(), "Get", "not-found")
|
||||
mockAlbumRepo.AssertCalled(GinkgoT(), "Get", "not-found")
|
||||
mockMediaFileRepo.AssertCalled(GinkgoT(), "Get", "not-found")
|
||||
mockAlbumAgent.AssertNotCalled(GinkgoT(), "GetAlbumImages", mock.Anything, mock.Anything, mock.Anything)
|
||||
})
|
||||
|
||||
Context("Unicode handling in album names", func() {
|
||||
var albumWithEnDash *model.Album
|
||||
var expectedURL *url.URL
|
||||
|
||||
const (
|
||||
originalAlbumName = "Raising Hell–Deluxe" // Album name with en dash
|
||||
normalizedAlbumName = "Raising Hell-Deluxe" // Normalized version with hyphen
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
// Test with en dash (–) in album name
|
||||
albumWithEnDash = &model.Album{ID: "album-endash", Name: originalAlbumName, AlbumArtistID: "artist-1"}
|
||||
mockArtistRepo.Mock = mock.Mock{} // Reset default expectations
|
||||
mockAlbumRepo.Mock = mock.Mock{} // Reset default expectations
|
||||
mockArtistRepo.On("Get", "album-endash").Return(nil, model.ErrNotFound).Once()
|
||||
mockAlbumRepo.On("Get", "album-endash").Return(albumWithEnDash, nil).Once()
|
||||
|
||||
expectedURL, _ = url.Parse("http://example.com/album.jpg")
|
||||
|
||||
// Mock the album agent to return an image for the album
|
||||
mockAlbumAgent.On("GetAlbumImages", ctx, mock.AnythingOfType("string"), "", "").
|
||||
Return([]agents.ExternalImage{
|
||||
{URL: "http://example.com/album.jpg", Size: 1000},
|
||||
}, nil).Once()
|
||||
})
|
||||
|
||||
When("DevPreserveUnicodeInExternalCalls is true", func() {
|
||||
BeforeEach(func() {
|
||||
conf.Server.DevPreserveUnicodeInExternalCalls = true
|
||||
})
|
||||
|
||||
It("preserves Unicode characters in album names", func() {
|
||||
// Act
|
||||
imgURL, err := provider.AlbumImage(ctx, "album-endash")
|
||||
|
||||
// Assert
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(imgURL).To(Equal(expectedURL))
|
||||
mockAlbumRepo.AssertCalled(GinkgoT(), "Get", "album-endash")
|
||||
// This is the key assertion: ensure the original Unicode name is used
|
||||
mockAlbumAgent.AssertCalled(GinkgoT(), "GetAlbumImages", ctx, originalAlbumName, "", "")
|
||||
})
|
||||
})
|
||||
|
||||
When("DevPreserveUnicodeInExternalCalls is false", func() {
|
||||
BeforeEach(func() {
|
||||
conf.Server.DevPreserveUnicodeInExternalCalls = false
|
||||
})
|
||||
|
||||
It("normalizes Unicode characters", func() {
|
||||
// Act
|
||||
imgURL, err := provider.AlbumImage(ctx, "album-endash")
|
||||
|
||||
// Assert
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(imgURL).To(Equal(expectedURL))
|
||||
mockAlbumRepo.AssertCalled(GinkgoT(), "Get", "album-endash")
|
||||
// This assertion ensures the normalized name is used (en dash → hyphen)
|
||||
mockAlbumAgent.AssertCalled(GinkgoT(), "GetAlbumImages", ctx, normalizedAlbumName, "", "")
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
// mockAlbumInfoAgent implementation
|
||||
type mockAlbumInfoAgent struct {
|
||||
mock.Mock
|
||||
agents.AlbumInfoRetriever
|
||||
agents.AlbumImageRetriever
|
||||
}
|
||||
|
||||
func newMockAlbumInfoAgent() *mockAlbumInfoAgent {
|
||||
m := new(mockAlbumInfoAgent)
|
||||
m.On("AgentName").Return("mockAlbum").Maybe()
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *mockAlbumInfoAgent) AgentName() string {
|
||||
args := m.Called()
|
||||
return args.String(0)
|
||||
}
|
||||
|
||||
func (m *mockAlbumInfoAgent) GetAlbumInfo(ctx context.Context, name, artist, mbid string) (*agents.AlbumInfo, error) {
|
||||
args := m.Called(ctx, name, artist, mbid)
|
||||
if args.Get(0) == nil {
|
||||
return nil, args.Error(1)
|
||||
}
|
||||
return args.Get(0).(*agents.AlbumInfo), args.Error(1)
|
||||
}
|
||||
|
||||
func (m *mockAlbumInfoAgent) GetAlbumImages(ctx context.Context, name, artist, mbid string) ([]agents.ExternalImage, error) {
|
||||
args := m.Called(ctx, name, artist, mbid)
|
||||
if args.Get(0) == nil {
|
||||
return nil, args.Error(1)
|
||||
}
|
||||
return args.Get(0).([]agents.ExternalImage), args.Error(1)
|
||||
}
|
||||
|
||||
// Ensure mockAgent implements the interfaces
|
||||
var _ agents.AlbumInfoRetriever = (*mockAlbumInfoAgent)(nil)
|
||||
var _ agents.AlbumImageRetriever = (*mockAlbumInfoAgent)(nil)
|
||||
Reference in New Issue
Block a user