package app import ( "context" "errors" "os" "path/filepath" "testing" "gitea.maximumdirect.net/eric/weatherreporter/internal/collect" "gitea.maximumdirect.net/eric/weatherreporter/internal/promptdebug" "gitea.maximumdirect.net/eric/weatherreporter/internal/promptexec" ) func TestExecutePreparedProfileRendersWithoutPublishing(t *testing.T) { prepared, inspection := preparedDailyProfile(t) executor := &generationExecutor{} outputPath := filepath.Join(t.TempDir(), "report.md") outcome, rendered, err := executePreparedProfile(context.Background(), profileExecutionRequest{ Prepared: prepared, Prompt: inspection, Profile: promptexec.ProfileInspection{ProfileID: inspection.ProfileID, BackendID: inspection.BackendID, ModelName: inspection.ModelName}, Executor: executor, }) if err != nil { t.Fatalf("executePreparedProfile() error = %v", err) } if len(rendered) == 0 || outcome.ValidationStatus != promptexec.ValidationPassed || outcome.ProfileID != inspection.ProfileID || executor.executeCalls != 1 { t.Fatalf("outcome/rendered/execution calls = %#v/%q/%d", outcome, rendered, executor.executeCalls) } if _, statErr := os.Stat(outputPath); !os.IsNotExist(statErr) { t.Fatalf("execution unexpectedly published %q: %v", outputPath, statErr) } } func TestExecutePreparedProfileKeepsDebugCallbackFailureLocal(t *testing.T) { prepared, inspection := preparedDailyProfile(t) debugWriter, err := promptdebug.NewPromptDebugWriter(t.TempDir()) if err != nil { t.Fatalf("NewPromptDebugWriter() error = %v", err) } executor := &generationExecutor{} outcome, rendered, err := executePreparedProfile(context.Background(), profileExecutionRequest{ Prepared: prepared, Prompt: inspection, Profile: promptexec.ProfileInspection{ProfileID: inspection.ProfileID, BackendID: inspection.BackendID, ModelName: inspection.ModelName}, Executor: executor, DebugWriter: debugWriter, DebugRef: &promptdebug.PromptDebugRef{ReportID: inspectionResolved(t).Definition.ID, ValidDate: "2026-05-29", RunID: "invalid/path"}, }) var executionErr *profileExecutionError if err == nil || !errors.As(err, &executionErr) || !executionErr.callbackFailure || promptexec.CategoryOf(err) != promptexec.InvalidConfiguration || len(rendered) != 0 || executor.executeCalls != 0 || outcome.LLMDebugPath != "" { t.Fatalf("outcome/rendered/error/execution calls = %#v/%q/%v/%d", outcome, rendered, err, executor.executeCalls) } } func preparedDailyProfile(t *testing.T) (preparedReport, PromptInspectionResult) { t.Helper() cfg := generationConfig() resolved, err := ResolveGenerate(GenerateRequest{ Config: cfg, Report: ReportDaily, Date: generationTime("2026-05-29T12:00:00-05:00"), Now: generationTime("2026-05-29T08:30:00-05:00"), }, generationTime("2026-05-29T08:30:00-05:00")) if err != nil { t.Fatalf("ResolveGenerate() error = %v", err) } bundle := generationBundle(t) prepared, err := prepareReport(prepareReportRequest{Config: cfg, Resolved: resolved, Collection: collect.Result{Bundle: &bundle}}) if err != nil { t.Fatalf("prepareReport() error = %v", err) } return prepared, PromptInspectionResult{PromptID: resolved.Definition.PromptID, PromptVersion: resolved.Definition.PromptVersion, PromptHash: "prompt-hash", ProfileID: "fixture", BackendID: "fixture", ModelName: "fixture-model"} }