diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-21 10:22:06 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-21 10:22:06 +0300 |
| commit | 5c2d6e68838aad0dad8e67b7934b6b255b95e1e1 (patch) | |
| tree | b756fbbca166e217bc190e24f4c9c252d0cf8073 | |
| parent | 494104af3d9b09db422a09173391e7f10997d1df (diff) | |
m7: fail closed on conclusion concat fallback
| -rw-r--r-- | internal/comic/comic_test.go | 40 | ||||
| -rw-r--r-- | internal/comic/narrator.go | 2 |
2 files changed, 41 insertions, 1 deletions
diff --git a/internal/comic/comic_test.go b/internal/comic/comic_test.go index b1ea5ab..ca1ef71 100644 --- a/internal/comic/comic_test.go +++ b/internal/comic/comic_test.go @@ -355,6 +355,35 @@ func TestConvertToStereoFallsBackToCopyWhenFFmpegMissing(t *testing.T) { } } +func TestNarrateConclusionDoesNotAcceptPartialConcatFallback(t *testing.T) { + originalLookPath := lookPath + lookPath = func(string) (string, error) { + return "", errors.New("missing ffmpeg") + } + t.Cleanup(func() { + lookPath = originalLookPath + }) + + provider := &recordingTTSProvider{} + n := NewNarrator(&NarratorConfig{ + TextProvider: fakeTextProvider{text: strings.Join([]string{strings.Repeat("алфа ", 60), strings.Repeat("бета ", 60)}, "\n\n")}, + MainProvider: fakeTTSProvider{}, + ConclusionProvider: provider, + Prompts: fakePromptRenderer{}, + }) + + path, ok := n.narrateConclusion(context.Background(), "story", t.TempDir()) + if ok { + t.Fatalf("narrateConclusion() ok = true, want false") + } + if path != "" { + t.Fatalf("narrateConclusion() path = %q, want empty", path) + } + if got, want := len(provider.calls), 2; got != want { + t.Fatalf("conclusion provider calls = %d, want %d", got, want) + } +} + type fakePromptRenderer struct{} func (fakePromptRenderer) RenderPrompt(name string, data any) (string, error) { @@ -485,3 +514,14 @@ func (fakeTTSProvider) IsAvailable() error { return nil } func (fakeTTSProvider) GenerateAudio(_ context.Context, _ string, outputFile string) error { return os.WriteFile(outputFile, []byte("mp3"), 0o644) } + +type recordingTTSProvider struct { + calls []string +} + +func (p *recordingTTSProvider) Name() string { return "recording-tts" } +func (p *recordingTTSProvider) IsAvailable() error { return nil } +func (p *recordingTTSProvider) GenerateAudio(_ context.Context, text, outputFile string) error { + p.calls = append(p.calls, text) + return os.WriteFile(outputFile, []byte("mp3"), 0o644) +} diff --git a/internal/comic/narrator.go b/internal/comic/narrator.go index 7aedd7c..24a523b 100644 --- a/internal/comic/narrator.go +++ b/internal/comic/narrator.go @@ -172,7 +172,7 @@ func (n *Narrator) narrateConclusion(ctx context.Context, storyText, tmpDir stri conclusionNarration = paths[0] } else if err := concatenateMP3s(paths, conclusionNarration, tmpDir); err != nil { fmt.Printf(" Warning: conclusion concat failed: %v\n", err) - return paths[len(paths)-1], true + return "", false } conclusionWithMusic := filepath.Join(tmpDir, "conclusion_with_music.mp3") |
