package bot import ( "encoding/json" "errors" "strings" "testing" cepis "cep.is/go" ) func decodeAddress(t *testing.T, body string) *cepis.Address { t.Helper() var address cepis.Address if err := json.Unmarshal([]byte(body), &address); err != nil { t.Fatalf("decode: %v", err) } return &address } const streetJSON = `{"cep":"01001000","logradouro":"Praça da Sé","complemento":"lado ímpar", "unidade":"","bairro":"Sé","localidade":"São Paulo","uf":"SP","estado":"São Paulo", "regiao":"Sudeste","ibge":"3550308","gia":"1004","ddd":"11","siafi":"7107", "geo":{"lat":-23.567202,"lon":-46.649659,"raio_m":128,"precisao":"logradouro"}}` const municipalityJSON = `{"cep":"76200000","logradouro":"","complemento":"","unidade":"", "bairro":"","localidade":"Iporá","uf":"GO","estado":"Goiás","regiao":"Centro-Oeste", "ibge":"5210000","gia":"","ddd":"64","siafi":"9439", "geo":{"lat":-16.441,"lon":-51.118,"raio_m":18400,"precisao":"localidade"}}` func TestFormatStreetLevelCEP(t *testing.T) { text := FormatAddress(decodeAddress(t, streetJSON)) for _, needed := range []string{"01001-000", "Praça da Sé", "lado ímpar", "Sé — São Paulo/SP", "DDD 11", "128 m"} { if !strings.Contains(text, needed) { t.Fatalf("reply is missing %q:\n%s", needed, text) } } if !strings.Contains(text, "openstreetmap.org/?mlat=-23.567202&mlon=-46.649659") { t.Fatalf("a street-level CEP should link to the point:\n%s", text) } } func TestFormatMunicipalityCEP(t *testing.T) { text := FormatAddress(decodeAddress(t, municipalityJSON)) if strings.Contains(text, "openstreetmap.org") { t.Fatalf("a municipality CEP must not offer a pin:\n%s", text) } for _, needed := range []string{"CEP geral de município", "centroide de Iporá", "18,4 km", "não serve", "Iporá/GO"} { if !strings.Contains(strings.ToLower(text), strings.ToLower(needed)) { t.Fatalf("reply is missing %q:\n%s", needed, text) } } } func TestFormatDiffersByPrecision(t *testing.T) { street := FormatAddress(decodeAddress(t, streetJSON)) municipality := FormatAddress(decodeAddress(t, municipalityJSON)) if street == municipality { t.Fatal("the two precisions produced the same reply") } } func TestFormatWithoutGeo(t *testing.T) { text := FormatAddress(decodeAddress(t, `{"cep":"29902000","logradouro":"Rua X","localidade":"Linhares","uf":"ES"}`)) if !strings.Contains(text, "Sem coordenada") { t.Fatalf("reply should say there is no coordinate:\n%s", text) } if strings.Contains(text, "openstreetmap.org") { t.Fatalf("no coordinate must mean no link:\n%s", text) } } func TestFormatEscapesHTML(t *testing.T) { text := FormatAddress(decodeAddress(t, `{"cep":"12345678","logradouro":"Rua Fake & Cia","localidade":"X","uf":"SP"}`)) if strings.Contains(text, "Fake") { t.Fatalf("address data must be escaped:\n%s", text) } if !strings.Contains(text, "<b>Fake</b> & Cia") { t.Fatalf("escaping is wrong:\n%s", text) } } func TestInlineDescriptionWarnsAboutMunicipality(t *testing.T) { description := InlineDescription(decodeAddress(t, municipalityJSON)) if !strings.Contains(description, "CEP geral do município") { t.Fatalf("description = %q", description) } if street := InlineDescription(decodeAddress(t, streetJSON)); strings.Contains(street, "geral do município") { t.Fatalf("street description = %q", street) } } func TestErrorMessagesAreDistinct(t *testing.T) { cases := map[string]error{ "not found": cepis.ErrCEPNotFound, "invalid": cepis.ErrInvalidCEP, "rate limited": cepis.ErrRateLimited, "server": cepis.ErrServer, "network": cepis.ErrNetwork, "invalid response": cepis.ErrInvalidResponse, "unknown": errors.New("something else"), } seen := make(map[string]string, len(cases)) for name, err := range cases { message := ErrorMessage(err) if message == "" { t.Fatalf("%s produced no message", name) } if other, clash := seen[message]; clash { t.Fatalf("%s and %s share a message: %q", name, other, message) } seen[message] = name } } func TestHelpMentionsEveryEntryPoint(t *testing.T) { text := HelpMessage("cepisbot") for _, needed := range []string{"01001-000", "/cep 01001000", "@cepisbot 01001000", "https://cep.is"} { if !strings.Contains(text, needed) { t.Fatalf("help is missing %q:\n%s", needed, text) } } }