summaryrefslogtreecommitdiff
path: root/internal/server/handlers/handlers_test.go
blob: b2ae43ec8111d88e6f8a9e564768ed1a3fa8e582 (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
package handlers

import (
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"

	"codeberg.org/mihna123/openstore/internal/config"
)

func newTestConfig() *config.Config {
	return &config.Config{
		Serve: config.Serve{Addr: ":3000"},
		Instance: config.Instance{
			Name:         "TestStore",
			ContactEmail: "test@store.com",
			BaseURL:      "https://test.store.com",
		},
	}
}

func get(t *testing.T, mux *http.ServeMux, method, path string) *httptest.ResponseRecorder {
	t.Helper()
	rec := httptest.NewRecorder()
	mux.ServeHTTP(rec, httptest.NewRequest(method, path, nil))
	return rec
}

func TestRoutes(t *testing.T) {
	mux := Routes(newTestConfig())

	tests := []struct {
		name   string
		method string
		path   string
		want   int
	}{
		{"home", http.MethodGet, "/", http.StatusOK},
		{"unknown path", http.MethodGet, "/nonsense", http.StatusNotFound},
		{"wrong method on home", http.MethodPost, "/", http.StatusMethodNotAllowed},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			rec := get(t, mux, tt.method, tt.path)
			if rec.Code != tt.want {
				t.Errorf("%s %s: got status %d, want %d", tt.method, tt.path, rec.Code, tt.want)
			}
		})
	}
}

func TestHomeRendersInstanceName(t *testing.T) {
	cfg := newTestConfig()
	cfg.Instance.Name = "Prodavnica123"
	mux := Routes(cfg)

	rec := get(t, mux, http.MethodGet, "/")
	if rec.Code != http.StatusOK {
		t.Fatalf("got status %d, want 200", rec.Code)
	}

	body := rec.Body.String()
	if strings.Count(body, "Prodavnica123") != 2 {
		t.Errorf("instance name should appear in title and heading, got:\n%s", body)
	}

	if ct := rec.Header().Get("Content-Type"); !strings.HasPrefix(ct, "text/html") {
		t.Errorf("got Content-Type %q, want text/html", ct)
	}
}

func TestHomeEscapesInstanceName(t *testing.T) {
	cfg := newTestConfig()
	cfg.Instance.Name = `<script>alert("xss")</script>`
	mux := Routes(cfg)

	body := get(t, mux, http.MethodGet, "/").Body.String()

	if strings.Contains(body, "<script>") {
		t.Errorf("instance name rendered unescaped, got:\n%s", body)
	}
	if !strings.Contains(body, "&lt;script&gt;") {
		t.Errorf("expected escaped instance name in body, got:\n%s", body)
	}
}

func TestHomeUsesConfiguredNameNotDefault(t *testing.T) {
	cfg := newTestConfig()
	cfg.Instance.Name = "ConfiguredName"
	mux := Routes(cfg)

	body := get(t, mux, http.MethodGet, "/").Body.String()

	if strings.Contains(body, "Openstore") {
		t.Errorf("handler rendered a hardcoded name instead of the config, got:\n%s", body)
	}
}