diff options
| author | mihna123 <mihailonvojinovic@gmail.com> | 2026-09-04 01:13:26 +0200 |
|---|---|---|
| committer | mihna123 <mihailonvojinovic@gmail.com> | 2026-09-04 01:13:26 +0200 |
| commit | 2e227424ba3a5bcc703936c35bcadba8cda0931f (patch) | |
| tree | 922e199d9557eca9eba74e5525a1be8b2ee86061 /internal/server | |
| parent | 5907450d569c997809674a2abeec97ddf0afe4aa (diff) | |
| download | openstore-2e227424ba3a5bcc703936c35bcadba8cda0931f.tar.gz openstore-2e227424ba3a5bcc703936c35bcadba8cda0931f.zip | |
config: add tests for config loading and page handlers
Cover the defaults/system/user cascade, partial overrides, malformed
files and base-url validation, plus DefaultPath resolution. An empty
value in an ini file counts as unset, so that is pinned down too.
Add the first handlers tests: routing, the instance name reaching the
template, and escaping of operator-supplied config in the page.
Diffstat (limited to 'internal/server')
| -rw-r--r-- | internal/server/handlers/handlers_test.go | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/internal/server/handlers/handlers_test.go b/internal/server/handlers/handlers_test.go new file mode 100644 index 0000000..b2ae43e --- /dev/null +++ b/internal/server/handlers/handlers_test.go @@ -0,0 +1,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, "<script>") { + 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) + } +} |
