package mapping import ( "testing" "time" "qctextbuilder/internal/domain" ) func TestSuggestFieldValues_FillsEmptyMappedFields(t *testing.T) { t.Parallel() fields := []domain.TemplateField{ {Path: "text.textTitle_m1710_1", KeyName: "textTitle_m1710_1", FieldKind: "text", IsEnabled: true, WebsiteSection: domain.WebsiteSectionHero}, {Path: "services.servicesTitle_r4830_8", KeyName: "servicesTitle_r4830_8", FieldKind: "text", IsEnabled: true, WebsiteSection: domain.WebsiteSectionServices}, {Path: "services.servicesDescription_r4830_9", KeyName: "servicesDescription_r4830_9", FieldKind: "text", IsEnabled: true, WebsiteSection: domain.WebsiteSectionServices}, {Path: "text.buttonText_c1165_1", KeyName: "buttonText_c1165_1", FieldKind: "text", IsEnabled: true, WebsiteSection: domain.WebsiteSectionCTA}, } result := SuggestFieldValues(SuggestionRequest{ Fields: fields, GlobalData: map[string]any{ "companyName": "Muster AG", "businessType": "Solar", }, DraftContext: &domain.DraftContext{ LLM: domain.DraftLLMContext{ WebsiteSummary: "Wir planen und installieren Solaranlagen fuer KMU und Privatkunden.", StyleProfile: domain.DraftStyleProfile{ ContentTone: "professionell", }, }, }, Existing: map[string]string{}, }) if _, ok := result.ByFieldPath["text.textTitle_m1710_1"]; !ok { t.Fatalf("expected hero title suggestion") } if got := result.ByFieldPath["text.buttonText_c1165_1"].Value; got == "" { t.Fatalf("expected cta suggestion") } if got := result.ByFieldPath["services.servicesDescription_r4830_9"].Slot; got != "service_items[0].description" { t.Fatalf("unexpected slot: %q", got) } } func TestSuggestFieldValues_RespectsExistingValues(t *testing.T) { t.Parallel() fields := []domain.TemplateField{ {Path: "text.textTitle_m1710_1", KeyName: "textTitle_m1710_1", FieldKind: "text", IsEnabled: true, WebsiteSection: domain.WebsiteSectionHero}, } result := SuggestFieldValues(SuggestionRequest{ Fields: fields, GlobalData: map[string]any{ "companyName": "Muster AG", }, Existing: map[string]string{ "text.textTitle_m1710_1": "Schon gesetzt", }, }) if len(result.Suggestions) != 0 { t.Fatalf("expected no suggestions, got %d", len(result.Suggestions)) } } func TestGenerateAllSuggestions_IncludesFilledFields(t *testing.T) { t.Parallel() fields := []domain.TemplateField{ {Path: "text.textTitle_m1710_1", KeyName: "textTitle_m1710_1", FieldKind: "text", IsEnabled: true, WebsiteSection: domain.WebsiteSectionHero}, } state := GenerateAllSuggestions(SuggestionRequest{ Fields: fields, GlobalData: map[string]any{ "companyName": "Muster AG", }, Existing: map[string]string{ "text.textTitle_m1710_1": "Bereits gesetzt", }, }, domain.DraftSuggestionState{}, time.Now().UTC()) if _, ok := state.ByFieldPath["text.textTitle_m1710_1"]; !ok { t.Fatalf("expected suggestion for filled field") } } func TestApplySuggestionsToEmptyFields_DoesNotOverwriteExisting(t *testing.T) { t.Parallel() now := time.Now().UTC() values, state := ApplySuggestionsToEmptyFields(map[string]string{ "field.hero": "Custom", }, domain.DraftSuggestionState{ ByFieldPath: map[string]domain.DraftSuggestion{ "field.hero": { FieldPath: "field.hero", Value: "Suggestion", Status: domain.DraftSuggestionStatusSuggested, }, "field.cta": { FieldPath: "field.cta", Value: "Jetzt anfragen", Status: domain.DraftSuggestionStatusSuggested, }, }, }, now) if got := values["field.hero"]; got != "Custom" { t.Fatalf("expected existing value unchanged, got %q", got) } if got := values["field.cta"]; got != "Jetzt anfragen" { t.Fatalf("expected empty value filled, got %q", got) } if got := state.ByFieldPath["field.hero"].Status; got != domain.DraftSuggestionStatusSuggested { t.Fatalf("expected hero status unchanged, got %q", got) } if got := state.ByFieldPath["field.cta"].Status; got != domain.DraftSuggestionStatusApplied { t.Fatalf("expected cta status applied, got %q", got) } } func TestApplyAllSuggestions_OverwritesExisting(t *testing.T) { t.Parallel() now := time.Now().UTC() values, state := ApplyAllSuggestions(map[string]string{ "field.hero": "Custom", }, domain.DraftSuggestionState{ ByFieldPath: map[string]domain.DraftSuggestion{ "field.hero": { FieldPath: "field.hero", Value: "Suggestion", Status: domain.DraftSuggestionStatusSuggested, }, "field.cta": { FieldPath: "field.cta", Value: "Jetzt anfragen", Status: domain.DraftSuggestionStatusSuggested, }, }, }, now) if got := values["field.hero"]; got != "Suggestion" { t.Fatalf("expected existing value overwritten, got %q", got) } if got := values["field.cta"]; got != "Jetzt anfragen" { t.Fatalf("expected cta applied, got %q", got) } if got := state.ByFieldPath["field.hero"].Status; got != domain.DraftSuggestionStatusApplied { t.Fatalf("expected hero status applied, got %q", got) } if got := state.ByFieldPath["field.cta"].Status; got != domain.DraftSuggestionStatusApplied { t.Fatalf("expected cta status applied, got %q", got) } } func TestRegenerateFieldSuggestion_OnlyChangesTargetField(t *testing.T) { t.Parallel() fields := []domain.TemplateField{ {Path: "text.textTitle_m1710_1", KeyName: "textTitle_m1710_1", FieldKind: "text", IsEnabled: true, WebsiteSection: domain.WebsiteSectionHero}, {Path: "text.buttonText_c1165_1", KeyName: "buttonText_c1165_1", FieldKind: "text", IsEnabled: true, WebsiteSection: domain.WebsiteSectionCTA}, } current := domain.DraftSuggestionState{ ByFieldPath: map[string]domain.DraftSuggestion{ "text.textTitle_m1710_1": {FieldPath: "text.textTitle_m1710_1", Value: "Old Hero"}, "text.buttonText_c1165_1": {FieldPath: "text.buttonText_c1165_1", Value: "Old CTA"}, }, } updated := RegenerateFieldSuggestion(SuggestionRequest{ Fields: fields, GlobalData: map[string]any{ "companyName": "Muster AG", }, }, current, "text.buttonText_c1165_1", time.Now().UTC()) if got := updated.ByFieldPath["text.textTitle_m1710_1"].Value; got != "Old Hero" { t.Fatalf("expected untargeted field unchanged, got %q", got) } if got := updated.ByFieldPath["text.buttonText_c1165_1"].Value; got == "" || got == "Old CTA" { t.Fatalf("expected target field regenerated, got %q", got) } }