Files
mesh-catalog/modules/mesh-mail-reader/cmd/mesh-mail-reader/pgstore_test.go
T

85 lines
2.8 KiB
Go

package main
// Unit tests for the schema (novox/hq ADR 0459 §4, issue 1517): the migrations are read with no gap and a
// bad name is refused (AC1), and no table holds a mail body or text taken from one (AC3). AC2 (the manifest
// requires postgres-database, binds it, renders database-url and runs prepare) is manifest_test.go's; AC4
// (against a real postgres) is pgstore_integration_test.go, compiled but never run from here.
import (
"strings"
"testing"
"testing/fstest"
)
// 1517/AC1: Migrations() reads migrations/0001-*.sql onward with no gap.
func TestMigrationsReadsTheRealOnesWithNoGap(t *testing.T) {
ms, err := Migrations()
if err != nil {
t.Fatal(err)
}
if len(ms) == 0 {
t.Fatal("no migrations found")
}
for i, m := range ms {
if m.Number != i+1 {
t.Fatalf("migration %d is numbered %04d, want %04d", i, m.Number, i+1)
}
}
}
// 1517/AC1: a gap in the numbering is refused.
func TestMigrationsRefusesAGap(t *testing.T) {
fsys := fstest.MapFS{
"m/0001-first.sql": {Data: []byte("create table a (id int);")},
"m/0003-third.sql": {Data: []byte("create table b (id int);")},
}
if _, err := migrationsFrom(fsys, "m"); err == nil || !strings.Contains(err.Error(), "gap") {
t.Fatalf("migrationsFrom with a gap: %v, want an error naming the gap", err)
}
}
// 1517/AC1: a file whose name is not NNNN-what-it-does.sql is refused by name.
func TestMigrationsRefusesABadName(t *testing.T) {
fsys := fstest.MapFS{
"m/0001-first.sql": {Data: []byte("create table a (id int);")},
"m/not-a-migration.sql": {Data: []byte("create table b (id int);")},
}
if _, err := migrationsFrom(fsys, "m"); err == nil || !strings.Contains(err.Error(), "not a migration's name") {
t.Fatalf("migrationsFrom with a bad name: %v, want an error naming it", err)
}
}
// forbiddenColumn is 1517/AC3: no table in schema.sql or any migration has a column for a mail body or text.
var forbiddenColumns = []string{"body", "text", "content", "snippet"}
// 1517/AC3: no table in schema.sql or any migration has a column named body, text, content or snippet, and
// summary is bounded to 160 characters by a CHECK.
func TestTheSchemaKeepsNoMailBodyOrText(t *testing.T) {
for _, sql := range allSchemaSQL(t) {
for _, line := range strings.Split(sql, "\n") {
word := strings.ToLower(strings.TrimSpace(strings.Fields(line + " x")[0]))
for _, forbidden := range forbiddenColumns {
if word == forbidden {
t.Fatalf("a column is named %q, which may hold a mail body or text taken from one: %q", forbidden, line)
}
}
}
}
if !strings.Contains(consolidated, "char_length(summary) <= 160") {
t.Fatal("summary has no CHECK bounding it to 160 characters")
}
}
func allSchemaSQL(t *testing.T) []string {
t.Helper()
ms, err := Migrations()
if err != nil {
t.Fatal(err)
}
out := []string{consolidated}
for _, m := range ms {
out = append(out, m.SQL)
}
return out
}