From 24dd98eaa9759884b17f18c729d498af6ec70e9e Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Wed, 22 Apr 2026 08:48:10 +0300 Subject: Fix prompt mode validation and readiness --- internal/comic/artist.go | 2 +- internal/comic/comic_test.go | 71 ++++++++++++++++++++++++++++++++++++++++++++ internal/comic/runner.go | 3 ++ 3 files changed, 75 insertions(+), 1 deletion(-) (limited to 'internal') diff --git a/internal/comic/artist.go b/internal/comic/artist.go index 7ccf084..e1717d3 100644 --- a/internal/comic/artist.go +++ b/internal/comic/artist.go @@ -218,7 +218,7 @@ func (a *Artist) generatePromptImage(ctx context.Context, prompt, outputFile str if err != nil { return fmt.Errorf("render manual prompt: %w", err) } - return a.generateWithRetryAndValidation(ctx, renderedPrompt, outputFile, "manual prompt image", nil, nil) + return a.generateWithRetryAndValidation(ctx, renderedPrompt, outputFile, "manual prompt image", nil, validateImagePromptLeakageFn) } type imageOutputValidator func(context.Context, string, string, string) error diff --git a/internal/comic/comic_test.go b/internal/comic/comic_test.go index 866df64..65343e6 100644 --- a/internal/comic/comic_test.go +++ b/internal/comic/comic_test.go @@ -373,6 +373,12 @@ func TestDrawComicPagesReturnsErrorWhenRenderFails(t *testing.T) { func TestArtistAndRunnerEndToEndWithFakes(t *testing.T) { t.Parallel() + originalSleep := sleep + sleep = func(time.Duration) {} + t.Cleanup(func() { + sleep = originalSleep + }) + originalLeakValidation := validateImagePromptLeakageFn validateImagePromptLeakageFn = func(context.Context, string, string, string) error { return nil } t.Cleanup(func() { @@ -471,6 +477,50 @@ func TestRunnerRunPromptWritesSingleAsset(t *testing.T) { } } +func TestRunnerRunPromptValidatesImageOutput(t *testing.T) { + originalLeakValidation := validateImagePromptLeakageFn + defer func() { + validateImagePromptLeakageFn = originalLeakValidation + }() + + var calls int + var gotLabel string + var gotScript string + validateImagePromptLeakageFn = func(_ context.Context, outputFile, label, script string) error { + calls++ + if outputFile == "" { + t.Fatal("validator received empty output file") + } + gotLabel = label + gotScript = script + return nil + } + + tmpDir := t.TempDir() + runner := NewRunner(&RunnerConfig{ + ImageProvider: fakeImageProvider{t: t}, + Prompts: fakePromptRenderer{}, + OutputDir: tmpDir, + Slug: "manual-robot", + UltraRealistic: boolPtr(false), + PageMaxRetries: 1, + PageRetryBase: time.Second, + }) + + if err := runner.RunPrompt(context.Background(), "a robot reading a newspaper"); err != nil { + t.Fatalf("RunPrompt() error = %v", err) + } + if calls != 1 { + t.Fatalf("validator calls = %d, want 1", calls) + } + if gotLabel != "manual prompt image" { + t.Fatalf("validator label = %q, want %q", gotLabel, "manual prompt image") + } + if gotScript == "" { + t.Fatal("validator script was empty") + } +} + func TestRunnerRunPromptRejectsEmptyPrompt(t *testing.T) { t.Parallel() @@ -486,6 +536,27 @@ func TestRunnerRunPromptRejectsEmptyPrompt(t *testing.T) { } } +func TestRunnerRunPromptReturnsErrorWhenPromptRendererMissing(t *testing.T) { + runner := NewRunner(&RunnerConfig{ + ImageProvider: fakeImageProvider{t: t}, + OutputDir: t.TempDir(), + Slug: "manual-robot", + UltraRealistic: boolPtr(false), + PageMaxRetries: 1, + PageRetryBase: time.Second, + }) + + defer func() { + if r := recover(); r != nil { + t.Fatalf("RunPrompt() panicked: %v", r) + } + }() + + if err := runner.RunPrompt(context.Background(), "a robot reading a newspaper"); err == nil { + t.Fatal("RunPrompt() error = nil, want readiness failure") + } +} + func TestRunnerRunPromptAppliesStyleThemeAndUltraContext(t *testing.T) { t.Parallel() diff --git a/internal/comic/runner.go b/internal/comic/runner.go index a9411ef..a5d89e6 100644 --- a/internal/comic/runner.go +++ b/internal/comic/runner.go @@ -200,6 +200,9 @@ func (r *Runner) RunPrompt(ctx context.Context, prompt string) error { if r.artist == nil { return fmt.Errorf("runner providers are not configured") } + if err := r.artist.ready(); err != nil { + return err + } if ctx == nil { ctx = context.Background() } -- cgit v1.2.3