package audio_test import ( "context" "errors" "os" "path/filepath" "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "git.d-ma.be/mathias/tapir/internal/adapters/audio" ) func TestFFmpegToWAV_AsksForSixteenKilohertzMonoPCMAlways(t *testing.T) { // Always transcode, even when the input already is 16 kHz mono: a Teams export // often is, and the point is to not ASSUME (ADR-033). Records the argv. rec := filepath.Join(t.TempDir(), "argv") bin := stub(t, `printf '%s\n' "$@" > `+rec+`; : > "$(eval echo \${$#})"`) err := (&audio.FFmpeg{Bin: bin}).ToWAV(context.Background(), "/spool/in", filepath.Join(t.TempDir(), "out.wav")) require.NoError(t, err) raw, err := os.ReadFile(rec) require.NoError(t, err) argv := strings.Split(strings.TrimSpace(string(raw)), "\n") joined := " " + strings.Join(argv, " ") + " " for _, want := range []string{" -ac 1 ", " -ar 16000 ", " -c:a pcm_s16le ", " -vn ", " -i /spool/in "} { assert.Contains(t, joined, want) } assert.True(t, strings.HasSuffix(strings.TrimSpace(joined), "out.wav"), "the output path is the last argument") } func TestFFmpegToWAV_NonzeroExitIsAnErrorCarryingStderr(t *testing.T) { bin := stub(t, `echo "moov atom not found" >&2; exit 1`) err := (&audio.FFmpeg{Bin: bin}).ToWAV(context.Background(), "/in", filepath.Join(t.TempDir(), "o.wav")) require.Error(t, err) assert.Contains(t, err.Error(), "moov atom not found") } func TestFFmpegToWAV_ZeroExitWithNoOutputIsAnError(t *testing.T) { bin := stub(t, `exit 0`) err := (&audio.FFmpeg{Bin: bin}).ToWAV(context.Background(), "/in", filepath.Join(t.TempDir(), "never-written.wav")) require.Error(t, err) } func TestFFmpegToWAV_MissingBinaryIsAnError(t *testing.T) { err := (&audio.FFmpeg{Bin: filepath.Join(t.TempDir(), "no-ffmpeg")}).ToWAV(context.Background(), "/in", "/out.wav") require.Error(t, err) assert.False(t, errors.Is(err, context.Canceled)) }