package audio
import (
"context"
"os"
"os/exec"
"path/filepath"
"testing"
)
// makeFLAC writes a short tone, and a truncated copy of it. Truncation is the
// shape a half-finished download arrives in.
func makeFLAC(t *testing.T, dir string) (good, cut string) {
t.Helper()
if _, err := exec.LookPath("ffmpeg"); err != nil {
t.Skip("ffmpeg is needed to build the fixture")
}
good = filepath.Join(dir, "good.flac")
cmd := exec.Command("ffmpeg", "-hide_banner", "-loglevel", "error", "-y",
"-f", "lavfi", "-i", "sine=frequency=440:duration=2", good)
if out, err := cmd.CombinedOutput(); err != nil {
t.Skipf("could not build a flac: %v %s", err, out)
}
data, err := os.ReadFile(good)
if err != nil {
t.Fatal(err)
}
cut = filepath.Join(dir, "cut.flac")
if err := os.WriteFile(cut, data[:len(data)/2], 0o600); err != nil {
t.Fatal(err)
}
return good, cut
}
// ffmpeg decodes a truncated flac without complaint, so it cannot be what the
// archive relies on: a partial file would be promoted and only discovered later.
func TestTestFLACCatchesTruncation(t *testing.T) {
if _, err := exec.LookPath("flac"); err != nil {
t.Skip("flac is not installed")
}
good, cut := makeFLAC(t, t.TempDir())
if err := TestFLAC(context.Background(), good); err != nil {
t.Errorf("an intact flac should pass: %v", err)
}
if err := TestFLAC(context.Background(), cut); err == nil {
t.Error("a truncated flac passed the integrity test")
}
// The same file that ffmpeg is happy with.
if err := DecodeOK(context.Background(), cut); err != nil {
t.Logf("ffmpeg also rejected it: %v", err)
} else {
t.Log("ffmpeg accepted the truncated file, which is why TestFLAC exists")
}
}
// macOS writes an AppleDouble sidecar beside each file it touches on a foreign
// filesystem, named "._" plus the original. It keeps the audio extension, so by
// extension alone it looks like a track, and it was left behind in staging after
// everything else had been cleaned up.
func TestAppleDoubleFilesAreNotAudio(t *testing.T) {
if IsAudio("._01 track.flac") {
t.Error("an AppleDouble sidecar should not count as a track")
}
if IsAudio("._song.mp3") {
t.Error("an AppleDouble sidecar should not count as a track")
}
if !IsAudio("01 track.flac") {
t.Error("a real track should still count")
}
if !IsAudio("SONG.MP3") {
t.Error("the extension check should stay case insensitive")
}
}