84 lines
2.3 KiB
Go
84 lines
2.3 KiB
Go
package api
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func fixtureRenderer(t *testing.T) *pageRenderer {
|
|
t.Helper()
|
|
node, err := exec.LookPath("node")
|
|
if err != nil {
|
|
t.Skip("Node.js unavailable")
|
|
}
|
|
script, err := filepath.Abs("testdata/render-fixture.mjs")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return &pageRenderer{node: node, script: script, slots: make(chan struct{}, 2), cache: map[string]renderCacheEntry{}}
|
|
}
|
|
|
|
func TestRendererRefreshesContent(t *testing.T) {
|
|
p := fixtureRenderer(t)
|
|
for _, step := range []struct {
|
|
text string
|
|
hit bool
|
|
}{{"old", false}, {"old", true}, {"new", false}, {"new", true}} {
|
|
out, hit, err := p.render(context.Background(), "/page/", []byte(fmt.Sprintf(`{"text":%q}`, step.text)))
|
|
if err != nil || hit != step.hit || !bytes.Contains(out, []byte(step.text)) {
|
|
t.Fatalf("step %+v: hit=%v err=%v", step, hit, err)
|
|
}
|
|
}
|
|
if p.cacheBytes != len(p.cache["/page/"].html) {
|
|
t.Fatal("replacement cache accounting is wrong")
|
|
}
|
|
}
|
|
|
|
func TestRendererRejectsBrokenOutput(t *testing.T) {
|
|
p := fixtureRenderer(t)
|
|
for _, input := range []string{`{"fail":true}`, `{"invalid":true}`} {
|
|
if _, _, err := p.render(context.Background(), "/page/", []byte(input)); err == nil {
|
|
t.Fatal("broken output accepted")
|
|
}
|
|
}
|
|
if len(p.cache) != 0 || len(p.slots) != 0 {
|
|
t.Fatal("failure cached or renderer slot leaked")
|
|
}
|
|
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
|
|
defer cancel()
|
|
if _, _, err := p.render(ctx, "/page/", []byte(`{"wait":5000}`)); err == nil {
|
|
t.Fatal("cancelled render succeeded")
|
|
}
|
|
if len(p.slots) != 0 {
|
|
t.Fatal("cancelled render leaked slot")
|
|
}
|
|
}
|
|
|
|
func TestRendererDoesNotCacheQueryVariants(t *testing.T) {
|
|
p := fixtureRenderer(t)
|
|
for i := 0; i < 2; i++ {
|
|
_, hit, err := p.render(context.Background(), "/page/?q=test", []byte(`{"text":"query"}`))
|
|
if err != nil || hit {
|
|
t.Fatalf("query variant: hit=%v err=%v", hit, err)
|
|
}
|
|
}
|
|
if len(p.cache) != 0 {
|
|
t.Fatal("query displaced canonical cache")
|
|
}
|
|
}
|
|
|
|
func TestCappedBuffer(t *testing.T) {
|
|
b := &cappedBuffer{limit: 4}
|
|
if n, err := b.Write([]byte("abcdef")); n != 6 || err != nil || b.String() != "abcd" || !b.overflow {
|
|
t.Fatal("output bound failed")
|
|
}
|
|
if _, err := b.Write([]byte("more")); err != nil || b.Len() != 4 {
|
|
t.Fatal("repeated overflow failed")
|
|
}
|
|
}
|