12de5a230a
- suggestion_service: fix scorer (stringList unmarshal accepts scalar|array; anchor scoring on base universal score so bool matches no longer tie); add localizeReasons for human-readable, Accept-Language-localized match reasons - lookup_i18n: localize lookup display names, home-profile options, document types/categories via internal/i18n - static_data_handler: per-locale seeded-data response (display_name, home profile options, document types/categories) with per-locale cache + ETag - settings_handler: invalidate per-locale seeded-data cache on lookup change instead of pre-warming a single non-localized blob - cache_service: per-locale seeded-data keys + ETag - DTOs: add DisplayName fields (task/residence/contractor) - translations: add suggestion.reason.* and lookup.* keys across all 10 langs - cmd/api: extract startup helpers + tests Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
89 lines
3.2 KiB
Go
89 lines
3.2 KiB
Go
package services
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/treytartt/honeydue-api/internal/dto/responses"
|
|
"github.com/treytartt/honeydue-api/internal/i18n"
|
|
)
|
|
|
|
func init() {
|
|
// Load the embedded translation bundle for the localization tests.
|
|
_ = i18n.Init()
|
|
}
|
|
|
|
func TestLookupSlug(t *testing.T) {
|
|
cases := map[string]string{
|
|
"Pest Control": "pest_control",
|
|
"Bi-Weekly": "bi_weekly",
|
|
"Semi-Annually": "semi_annually",
|
|
"Mobile Home": "mobile_home",
|
|
"HVAC": "hvac",
|
|
"tank_gas": "tank_gas",
|
|
"Tankless (Gas)": "tankless_gas",
|
|
" Trailing/Punct ": "trailing_punct",
|
|
}
|
|
for in, want := range cases {
|
|
assert.Equalf(t, want, lookupSlug(in), "slug(%q)", in)
|
|
}
|
|
}
|
|
|
|
func TestLocalizeLookup_EnglishAndSpanish(t *testing.T) {
|
|
en := i18n.NewLocalizer("en")
|
|
es := i18n.NewLocalizer("es")
|
|
|
|
// Known value: localizes per locale.
|
|
assert.Equal(t, "Plumbing", localizeLookup(en, lookupKindTaskCategory, "Plumbing"))
|
|
assert.Equal(t, "Fontanería", localizeLookup(es, lookupKindTaskCategory, "Plumbing"))
|
|
|
|
// Frequency with separators (regression on the bi_weekly/semi_annually slug).
|
|
assert.Equal(t, "Bi-Weekly", localizeLookup(en, lookupKindTaskFrequency, "Bi-Weekly"))
|
|
assert.Equal(t, "Quincenal", localizeLookup(es, lookupKindTaskFrequency, "Bi-Weekly"))
|
|
}
|
|
|
|
func TestLocalizeLookup_NilLocalizerFallsBackToEnglish(t *testing.T) {
|
|
assert.Equal(t, "House", localizeLookup(nil, lookupKindResidenceType, "House"))
|
|
}
|
|
|
|
func TestLocalizeLookup_UnknownValueFallsBackToName(t *testing.T) {
|
|
// No translation key exists -> return the stable English name, never a key.
|
|
got := localizeLookup(i18n.NewLocalizer("es"), lookupKindTaskCategory, "Totally Unknown Value")
|
|
assert.Equal(t, "Totally Unknown Value", got)
|
|
}
|
|
|
|
func TestBuildHomeProfileOptions(t *testing.T) {
|
|
opts := BuildHomeProfileOptions(i18n.NewLocalizer("es"))
|
|
|
|
// All 7 fields present.
|
|
for _, field := range []string{"heating_type", "cooling_type", "water_heater_type", "roof_type", "exterior_type", "flooring_primary", "landscaping_type"} {
|
|
require.Containsf(t, opts, field, "missing field %s", field)
|
|
require.NotEmpty(t, opts[field])
|
|
}
|
|
|
|
// Values are stable; display_name is localized.
|
|
heating := opts["heating_type"]
|
|
assert.Equal(t, "gas_furnace", heating[0].Value)
|
|
assert.Equal(t, "Calefactor de gas", heating[0].DisplayName)
|
|
}
|
|
|
|
func TestLocalizeLookups_FillsDisplayName(t *testing.T) {
|
|
cats := []responses.TaskCategoryResponse{{Name: "Plumbing"}, {Name: "HVAC"}}
|
|
prios := []responses.TaskPriorityResponse{{Name: "High"}}
|
|
freqs := []responses.TaskFrequencyResponse{{Name: "Monthly"}}
|
|
specs := []responses.ContractorSpecialtyResponse{{Name: "Plumber"}}
|
|
types := []responses.ResidenceTypeResponse{{Name: "House"}}
|
|
|
|
LocalizeLookups(i18n.NewLocalizer("es"), types, cats, prios, freqs, specs)
|
|
|
|
assert.Equal(t, "Fontanería", cats[0].DisplayName)
|
|
assert.Equal(t, "Plumbing", cats[0].Name) // name stays stable
|
|
assert.Equal(t, "Climatización", cats[1].DisplayName)
|
|
assert.Equal(t, "Alta", prios[0].DisplayName)
|
|
assert.Equal(t, "Mensual", freqs[0].DisplayName)
|
|
assert.Equal(t, "Fontanero", specs[0].DisplayName)
|
|
assert.Equal(t, "Casa", types[0].DisplayName)
|
|
}
|