97 lines
2.6 KiB
Go
97 lines
2.6 KiB
Go
package server
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
"net/http/httptest"
|
|
"os"
|
|
"perler-beads-server/internal/domain"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestAnonymousPermissions(t *testing.T) {
|
|
r := (&Server{}).Router()
|
|
for _, path := range []string{"/api/me", "/api/my/patterns", "/api/favorites", "/api/tables", "/api/service-requests", "/api/admin/patterns"} {
|
|
w := httptest.NewRecorder()
|
|
r.ServeHTTP(w, httptest.NewRequest("GET", path, nil))
|
|
var v struct{ Code int }
|
|
if json.Unmarshal(w.Body.Bytes(), &v) != nil || w.Code != 200 || v.Code != 403 {
|
|
t.Fatalf("%s: %s", path, w.Body)
|
|
}
|
|
}
|
|
}
|
|
func TestPrintMillimetersEscapes(t *testing.T) {
|
|
code := "R"
|
|
p := domain.Pattern{Title: "<script>", Width: 1, Height: 1, Cells: []*string{&code}, Colors: []domain.Color{{Code: code, Hex: "#ff0000"}}, BeadCount: 1}
|
|
var b bytes.Buffer
|
|
if e := renderSVG(&b, p, 5); e != nil {
|
|
t.Fatal(e)
|
|
}
|
|
svg := b.String()
|
|
for _, want := range []string{`width="100.00mm"`, `height="100.00mm"`, "<script>", "50 mm calibration", "R: 1"} {
|
|
if !strings.Contains(svg, want) {
|
|
t.Fatalf("missing %s", want)
|
|
}
|
|
}
|
|
if strings.Contains(svg, "<script>") {
|
|
t.Fatal("unescaped title")
|
|
}
|
|
}
|
|
func TestPostgresPersistentIdempotency(t *testing.T) {
|
|
dsn := os.Getenv("TEST_DATABASE_URL")
|
|
if dsn == "" {
|
|
t.Skip("TEST_DATABASE_URL absent; dedicated PostgreSQL integration database required")
|
|
}
|
|
cfg, e := pgxpool.ParseConfig(dsn)
|
|
if e != nil {
|
|
t.Fatal(e)
|
|
}
|
|
if !strings.Contains(cfg.ConnConfig.Database, "test") {
|
|
t.Fatal("test database name must contain test")
|
|
}
|
|
ctx := context.Background()
|
|
db, e := pgxpool.NewWithConfig(ctx, cfg)
|
|
if e != nil {
|
|
t.Fatal(e)
|
|
}
|
|
defer db.Close()
|
|
if e = Migrate(ctx, db); e != nil {
|
|
t.Fatal(e)
|
|
}
|
|
tx, e := db.Begin(ctx)
|
|
if e != nil {
|
|
t.Fatal(e)
|
|
}
|
|
defer tx.Rollback(ctx)
|
|
id := "integration-" + t.Name()
|
|
_, e = tx.Exec(ctx, `INSERT INTO request_keys VALUES($1,'9e7aec78-f5a0-4f00-81fa-7606a8d9f7c0',$2,'{}')`, id, domain.Fingerprint("help", "a", ""))
|
|
if e != nil {
|
|
t.Fatal(e)
|
|
}
|
|
_, e = tx.Exec(ctx, `INSERT INTO request_keys VALUES($1,'9e7aec78-f5a0-4f00-81fa-7606a8d9f7c0',$2,'{}')`, id, domain.Fingerprint("help", "b", ""))
|
|
if e == nil {
|
|
t.Fatal("persistent unique key allowed duplicate")
|
|
}
|
|
}
|
|
func TestDemoFixtures(t *testing.T) {
|
|
cs := demoColors()
|
|
if len(cs) < 8 {
|
|
t.Fatal("too few demo colors")
|
|
}
|
|
ps := demoPatterns("store-001", cs)
|
|
if len(ps) != 4 {
|
|
t.Fatal("need four motifs")
|
|
}
|
|
for _, p := range ps {
|
|
if e := p.Validate(); e != nil {
|
|
t.Fatal(e)
|
|
}
|
|
if !p.Demo || p.BeadCount == 0 {
|
|
t.Fatal("demo must be marked and nonempty")
|
|
}
|
|
}
|
|
}
|