mirror of
https://github.com/navidrome/navidrome.git
synced 2025-12-23 15:08:04 -05:00
161 lines
4.6 KiB
Go
161 lines
4.6 KiB
Go
package scanner
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/navidrome/navidrome/model"
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
)
|
|
|
|
var _ = Describe("targetArguments", func() {
|
|
var ctx context.Context
|
|
|
|
BeforeEach(func() {
|
|
ctx = GinkgoT().Context()
|
|
})
|
|
|
|
Context("with small target list", func() {
|
|
It("returns command-line arguments for single target", func() {
|
|
targets := []model.ScanTarget{
|
|
{LibraryID: 1, FolderPath: "Music/Rock"},
|
|
}
|
|
|
|
args, cleanup, err := targetArguments(ctx, targets, argLengthThreshold)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
defer cleanup()
|
|
Expect(args).To(Equal([]string{"-t", "1:Music/Rock"}))
|
|
})
|
|
|
|
It("returns command-line arguments for multiple targets", func() {
|
|
targets := []model.ScanTarget{
|
|
{LibraryID: 1, FolderPath: "Music/Rock"},
|
|
{LibraryID: 2, FolderPath: "Music/Jazz"},
|
|
{LibraryID: 3, FolderPath: "Classical"},
|
|
}
|
|
|
|
args, cleanup, err := targetArguments(ctx, targets, argLengthThreshold)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
defer cleanup()
|
|
Expect(args).To(Equal([]string{
|
|
"-t", "1:Music/Rock",
|
|
"-t", "2:Music/Jazz",
|
|
"-t", "3:Classical",
|
|
}))
|
|
})
|
|
|
|
It("handles targets with special characters", func() {
|
|
targets := []model.ScanTarget{
|
|
{LibraryID: 1, FolderPath: "Music/Rock & Roll"},
|
|
{LibraryID: 2, FolderPath: "Music/Jazz (Modern)"},
|
|
}
|
|
|
|
args, cleanup, err := targetArguments(ctx, targets, argLengthThreshold)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
defer cleanup()
|
|
Expect(args).To(Equal([]string{
|
|
"-t", "1:Music/Rock & Roll",
|
|
"-t", "2:Music/Jazz (Modern)",
|
|
}))
|
|
})
|
|
})
|
|
|
|
Context("with large target list exceeding threshold", func() {
|
|
It("returns --target-file argument when exceeding threshold", func() {
|
|
// Create enough targets to exceed the threshold
|
|
var targets []model.ScanTarget
|
|
for i := 1; i <= 600; i++ {
|
|
targets = append(targets, model.ScanTarget{
|
|
LibraryID: 1,
|
|
FolderPath: "Music/VeryLongFolderPathToSimulateRealScenario/SubFolder",
|
|
})
|
|
}
|
|
|
|
args, cleanup, err := targetArguments(ctx, targets, argLengthThreshold)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
defer cleanup()
|
|
Expect(args).To(HaveLen(2))
|
|
Expect(args[0]).To(Equal("--target-file"))
|
|
|
|
// Verify the file exists and has correct format
|
|
filePath := args[1]
|
|
Expect(filePath).To(ContainSubstring("navidrome-scan-targets-"))
|
|
Expect(filePath).To(HaveSuffix(".txt"))
|
|
|
|
// Verify file actually exists
|
|
_, err = os.Stat(filePath)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
})
|
|
|
|
It("creates temp file with correct format", func() {
|
|
// Use custom threshold to easily exceed it
|
|
targets := []model.ScanTarget{
|
|
{LibraryID: 1, FolderPath: "Music/Rock"},
|
|
{LibraryID: 2, FolderPath: "Music/Jazz"},
|
|
{LibraryID: 3, FolderPath: "Classical"},
|
|
}
|
|
|
|
// Set threshold very low to force file usage
|
|
args, cleanup, err := targetArguments(ctx, targets, 10)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
defer cleanup()
|
|
Expect(args[0]).To(Equal("--target-file"))
|
|
|
|
// Verify file exists with correct format
|
|
filePath := args[1]
|
|
Expect(filePath).To(ContainSubstring("navidrome-scan-targets-"))
|
|
Expect(filePath).To(HaveSuffix(".txt"))
|
|
|
|
// Verify file content
|
|
content, err := os.ReadFile(filePath)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
lines := strings.Split(strings.TrimSpace(string(content)), "\n")
|
|
Expect(lines).To(HaveLen(3))
|
|
Expect(lines[0]).To(Equal("1:Music/Rock"))
|
|
Expect(lines[1]).To(Equal("2:Music/Jazz"))
|
|
Expect(lines[2]).To(Equal("3:Classical"))
|
|
})
|
|
})
|
|
|
|
Context("edge cases", func() {
|
|
It("handles empty target list", func() {
|
|
var targets []model.ScanTarget
|
|
|
|
args, cleanup, err := targetArguments(ctx, targets, argLengthThreshold)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
defer cleanup()
|
|
Expect(args).To(BeEmpty())
|
|
})
|
|
|
|
It("uses command-line args when exactly at threshold", func() {
|
|
// Create targets that are exactly at threshold
|
|
targets := []model.ScanTarget{
|
|
{LibraryID: 1, FolderPath: "Music"},
|
|
}
|
|
|
|
// Estimate length should be 11 bytes
|
|
estimatedLength := estimateArgLength(targets)
|
|
|
|
args, cleanup, err := targetArguments(ctx, targets, estimatedLength)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
defer cleanup()
|
|
Expect(args).To(Equal([]string{"-t", "1:Music"}))
|
|
})
|
|
|
|
It("uses file when one byte over threshold", func() {
|
|
targets := []model.ScanTarget{
|
|
{LibraryID: 1, FolderPath: "Music"},
|
|
}
|
|
|
|
// Set threshold just below the estimated length
|
|
estimatedLength := estimateArgLength(targets)
|
|
args, cleanup, err := targetArguments(ctx, targets, estimatedLength-1)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
defer cleanup()
|
|
Expect(args[0]).To(Equal("--target-file"))
|
|
})
|
|
})
|
|
})
|