102 lines
3.3 KiB
Go
102 lines
3.3 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func testWebsite(t *testing.T, origin string) *API {
|
|
t.Helper()
|
|
dir := t.TempDir()
|
|
if err := os.WriteFile(filepath.Join(dir, "index.html"), []byte("<!doctype html><html lang=\"ru\"><div id=\"root\"></div></html>"), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(dir, "favicon.ico"), []byte{0, 0, 1, 0}, 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(dir, "seo-manifest.json"), []byte(`{"siteURL":"`+origin+`","services":[]}`), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
a := New(nil, "")
|
|
if err := a.WithWebsite(dir, origin); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return a
|
|
}
|
|
|
|
func TestCanonicalPagePath(t *testing.T) {
|
|
for input, expected := range map[string]string{"/": "/", "/contacts": "/contacts/", "/contacts/": "/contacts/", "/services/estetic/rinoplastika": "/services/estetic/rinoplastika/"} {
|
|
if got := canonicalPagePath(input); got != expected {
|
|
t.Errorf("%s: %s != %s", input, got, expected)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestWebsiteStatusCodes(t *testing.T) {
|
|
a := testWebsite(t, "https://example.org")
|
|
for _, tc := range []struct {
|
|
path string
|
|
status int
|
|
redirect string
|
|
}{
|
|
{"/", 200, ""}, {"/contacts/", 200, ""}, {"/contacts?utm_source=test", 301, "/contacts/?utm_source=test"},
|
|
{"/no-such-page/", 404, ""}, {"/news/", 200, ""}, {"/gallery/", 404, ""},
|
|
{"/company/history/", 301, "/company/"}, {"/company/docs/", 301, "/legaldocs/"}, {"/assets/no-such-file.js", 404, ""},
|
|
{"/seo-manifest.json", 404, ""}, {"/favicon.ico", 200, ""}, {"/privacy", 301, "/legaldocs/privacy/"},
|
|
} {
|
|
r := httptest.NewRequest(http.MethodGet, tc.path, nil)
|
|
w := httptest.NewRecorder()
|
|
a.Routes().ServeHTTP(w, r)
|
|
if w.Code != tc.status {
|
|
t.Errorf("%s: status %d, want %d", tc.path, w.Code, tc.status)
|
|
}
|
|
if tc.redirect != "" && w.Header().Get("Location") != tc.redirect {
|
|
t.Errorf("redirect %s", w.Header().Get("Location"))
|
|
}
|
|
if w.Code == 404 && tc.path == "/no-such-page/" && w.Header().Get("X-Robots-Tag") != "noindex" {
|
|
t.Error("404 should be noindex")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestRobots(t *testing.T) {
|
|
for _, origin := range []string{"https://example.org", "http://127.0.0.1:8080"} {
|
|
a := testWebsite(t, origin)
|
|
w := httptest.NewRecorder()
|
|
a.Routes().ServeHTTP(w, httptest.NewRequest(http.MethodGet, "/robots.txt", nil))
|
|
body := w.Body.String()
|
|
if a.website.local {
|
|
if body != "User-agent: *\nDisallow: /\n" {
|
|
t.Fatal(body)
|
|
}
|
|
} else {
|
|
for _, expected := range []string{"Disallow: /admin", "Disallow: /api/", "Sitemap: https://example.org/sitemap.xml"} {
|
|
if !strings.Contains(body, expected) {
|
|
t.Errorf("missing %s", expected)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestWebsiteCanonicalMismatch(t *testing.T) {
|
|
a := testWebsite(t, "https://example.org")
|
|
if err := a.WithWebsite(a.website.dir, "https://other.example.org"); err == nil {
|
|
t.Error("canonical mismatch must fail startup")
|
|
}
|
|
}
|
|
|
|
func TestWebsiteInvalidOrigin(t *testing.T) {
|
|
dir := t.TempDir()
|
|
_ = os.WriteFile(filepath.Join(dir, "index.html"), []byte("html"), 0600)
|
|
for _, origin := range []string{"javascript:alert(1)", "https://example.org/path", "https://user:secret@example.org", "https://example.org?q=test"} {
|
|
if err := New(nil, "").WithWebsite(dir, origin); err == nil {
|
|
t.Errorf("accepted %s", origin)
|
|
}
|
|
}
|
|
}
|