summaryrefslogtreecommitdiffstats
path: root/internal/bot/format_test.go
blob: 56b8dda93c92b02d240ad9c153cf6a8991f2276e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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 <b>Fake</b> & Cia","localidade":"X","uf":"SP"}`))
	if strings.Contains(text, "<b>Fake</b>") {
		t.Fatalf("address data must be escaped:\n%s", text)
	}
	if !strings.Contains(text, "&lt;b&gt;Fake&lt;/b&gt; &amp; 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)
		}
	}
}