Files
navidrome-meilisearch/plugins/base_capability_test.go
Dongho Kim c251f174ed
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
update
2025-12-08 16:16:23 +01:00

286 lines
7.7 KiB
Go

package plugins
import (
"context"
"errors"
"github.com/navidrome/navidrome/plugins/api"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
type nilInstance struct{}
var _ = Describe("baseCapability", func() {
var ctx = context.Background()
It("should load instance using loadFunc", func() {
called := false
plugin := &baseCapability[*nilInstance, any]{
wasmPath: "",
id: "test",
capability: "test",
loadFunc: func(ctx context.Context, _ any, path string) (*nilInstance, error) {
called = true
return &nilInstance{}, nil
},
}
inst, done, err := plugin.getInstance(ctx, "test")
defer done()
Expect(err).To(BeNil())
Expect(inst).ToNot(BeNil())
Expect(called).To(BeTrue())
})
})
var _ = Describe("checkErr", func() {
Context("when resp is nil", func() {
It("should return nil error when both resp and err are nil", func() {
var resp *testErrorResponse
result, err := checkErr(resp, nil)
Expect(result).To(BeNil())
Expect(err).To(BeNil())
})
It("should return original error unchanged for non-API errors", func() {
var resp *testErrorResponse
originalErr := errors.New("original error")
result, err := checkErr(resp, originalErr)
Expect(result).To(BeNil())
Expect(err).To(Equal(originalErr))
})
It("should return mapped API error for ErrNotImplemented", func() {
var resp *testErrorResponse
err := errors.New("plugin:not_implemented")
result, mappedErr := checkErr(resp, err)
Expect(result).To(BeNil())
Expect(mappedErr).To(Equal(api.ErrNotImplemented))
})
It("should return mapped API error for ErrNotFound", func() {
var resp *testErrorResponse
err := errors.New("plugin:not_found")
result, mappedErr := checkErr(resp, err)
Expect(result).To(BeNil())
Expect(mappedErr).To(Equal(api.ErrNotFound))
})
})
Context("when resp is a typed nil that implements errorResponse", func() {
It("should not panic and return original error", func() {
var resp *testErrorResponse // typed nil
originalErr := errors.New("original error")
// This should not panic
result, err := checkErr(resp, originalErr)
Expect(result).To(BeNil())
Expect(err).To(Equal(originalErr))
})
It("should handle typed nil with nil error gracefully", func() {
var resp *testErrorResponse // typed nil
// This should not panic
result, err := checkErr(resp, nil)
Expect(result).To(BeNil())
Expect(err).To(BeNil())
})
})
Context("when resp implements errorResponse with non-empty error", func() {
It("should create new error when original error is nil", func() {
resp := &testErrorResponse{errorMsg: "plugin error"}
result, err := checkErr(resp, nil)
Expect(result).To(Equal(resp))
Expect(err).To(MatchError("plugin error"))
})
It("should wrap original error when both exist", func() {
resp := &testErrorResponse{errorMsg: "plugin error"}
originalErr := errors.New("original error")
result, err := checkErr(resp, originalErr)
Expect(result).To(Equal(resp))
Expect(err).To(HaveOccurred())
// Check that both error messages are present in the joined error
errStr := err.Error()
Expect(errStr).To(ContainSubstring("plugin error"))
Expect(errStr).To(ContainSubstring("original error"))
})
It("should return mapped API error for ErrNotImplemented when no original error", func() {
resp := &testErrorResponse{errorMsg: "plugin:not_implemented"}
result, err := checkErr(resp, nil)
Expect(result).To(Equal(resp))
Expect(err).To(MatchError(api.ErrNotImplemented))
})
It("should return mapped API error for ErrNotFound when no original error", func() {
resp := &testErrorResponse{errorMsg: "plugin:not_found"}
result, err := checkErr(resp, nil)
Expect(result).To(Equal(resp))
Expect(err).To(MatchError(api.ErrNotFound))
})
It("should return mapped API error for ErrNotImplemented even with original error", func() {
resp := &testErrorResponse{errorMsg: "plugin:not_implemented"}
originalErr := errors.New("original error")
result, err := checkErr(resp, originalErr)
Expect(result).To(Equal(resp))
Expect(err).To(MatchError(api.ErrNotImplemented))
})
It("should return mapped API error for ErrNotFound even with original error", func() {
resp := &testErrorResponse{errorMsg: "plugin:not_found"}
originalErr := errors.New("original error")
result, err := checkErr(resp, originalErr)
Expect(result).To(Equal(resp))
Expect(err).To(MatchError(api.ErrNotFound))
})
})
Context("when resp implements errorResponse with empty error", func() {
It("should return original error unchanged", func() {
resp := &testErrorResponse{errorMsg: ""}
originalErr := errors.New("original error")
result, err := checkErr(resp, originalErr)
Expect(result).To(Equal(resp))
Expect(err).To(MatchError(originalErr))
})
It("should return nil error when both are empty/nil", func() {
resp := &testErrorResponse{errorMsg: ""}
result, err := checkErr(resp, nil)
Expect(result).To(Equal(resp))
Expect(err).To(BeNil())
})
It("should map original API error when response error is empty", func() {
resp := &testErrorResponse{errorMsg: ""}
originalErr := errors.New("plugin:not_implemented")
result, err := checkErr(resp, originalErr)
Expect(result).To(Equal(resp))
Expect(err).To(MatchError(api.ErrNotImplemented))
})
})
Context("when resp does not implement errorResponse", func() {
It("should return original error unchanged", func() {
resp := &testNonErrorResponse{data: "some data"}
originalErr := errors.New("original error")
result, err := checkErr(resp, originalErr)
Expect(result).To(Equal(resp))
Expect(err).To(Equal(originalErr))
})
It("should return nil error when original error is nil", func() {
resp := &testNonErrorResponse{data: "some data"}
result, err := checkErr(resp, nil)
Expect(result).To(Equal(resp))
Expect(err).To(BeNil())
})
It("should map original API error when response doesn't implement errorResponse", func() {
resp := &testNonErrorResponse{data: "some data"}
originalErr := errors.New("plugin:not_found")
result, err := checkErr(resp, originalErr)
Expect(result).To(Equal(resp))
Expect(err).To(MatchError(api.ErrNotFound))
})
})
Context("when resp is a value type (not pointer)", func() {
It("should handle value types that implement errorResponse", func() {
resp := testValueErrorResponse{errorMsg: "value error"}
originalErr := errors.New("original error")
result, err := checkErr(resp, originalErr)
Expect(result).To(Equal(resp))
Expect(err).To(HaveOccurred())
// Check that both error messages are present in the joined error
errStr := err.Error()
Expect(errStr).To(ContainSubstring("value error"))
Expect(errStr).To(ContainSubstring("original error"))
})
It("should handle value types with empty error", func() {
resp := testValueErrorResponse{errorMsg: ""}
originalErr := errors.New("original error")
result, err := checkErr(resp, originalErr)
Expect(result).To(Equal(resp))
Expect(err).To(MatchError(originalErr))
})
It("should handle value types with API error", func() {
resp := testValueErrorResponse{errorMsg: "plugin:not_implemented"}
originalErr := errors.New("original error")
result, err := checkErr(resp, originalErr)
Expect(result).To(Equal(resp))
Expect(err).To(MatchError(api.ErrNotImplemented))
})
})
})
// Test helper types
type testErrorResponse struct {
errorMsg string
}
func (t *testErrorResponse) GetError() string {
if t == nil {
return "" // This is what would typically happen with a typed nil
}
return t.errorMsg
}
type testNonErrorResponse struct {
data string
}
type testValueErrorResponse struct {
errorMsg string
}
func (t testValueErrorResponse) GetError() string {
return t.errorMsg
}