package web
import (
"bufio"
"context"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
)
type tickNotifier struct{ ch chan struct{} }
func (n tickNotifier) Watch(string) (<-chan struct{}, func()) { return n.ch, func() {} }
// A burst of index moves is one revision: a push used to make every open
// page fetch its fragments once per tick (jva saw two fetches 210 ms
// apart). A tick after the burst has settled is the next revision.
func TestABurstOfTicksIsOneRevision(t *testing.T) {
defer func(d time.Duration) { revCoalesce = d }(revCoalesce)
revCoalesce = 50 * time.Millisecond
n := tickNotifier{ch: make(chan struct{}, 8)}
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
req.SetPathValue("repo", "alpha")
timelineRevStream(n, w, req)
}))
defer srv.Close()
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
req, _ := http.NewRequestWithContext(ctx, "GET", srv.URL, nil)
resp, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatal(err)
}
defer resp.Body.Close()
lines := make(chan string, 16)
go func() {
sc := bufio.NewScanner(resp.Body)
for sc.Scan() {
if strings.HasPrefix(sc.Text(), "data: signals") {
lines <- sc.Text()
}
}
}()
n.ch <- struct{}{}
n.ch <- struct{}{}
n.ch <- struct{}{}
if got := <-lines; !strings.Contains(got, "tlRev: 1}") {
t.Fatalf("FAIL: first revision %q", got)
}
select {
case got := <-lines:
t.Fatalf("FAIL: the burst gave a second revision: %q", got)
case <-time.After(150 * time.Millisecond):
}
n.ch <- struct{}{}
if got := <-lines; !strings.Contains(got, "tlRev: 2}") {
t.Fatalf("FAIL: a later tick read %q", got)
}
}