package web
import (
"net/http"
"strings"
"testing"
)
// A file's history is the timeline narrowed to it (p=, fossil's own
// spelling): the check-ins that changed it, with a diff of that file
// and the file as it was on each card, and the controls carrying the
// path so a branch change or a live refresh keeps it.
func TestFileHistoryIsTheTimelineNarrowedToThePath(t *testing.T) {
srv := activityServer(t)
code, body := getPage(t, srv, "/r/alpha/timeline?p=src/a.c")
if code != 200 {
t.Fatalf("status %d", code)
}
// src/a.c changed in base, on the branch, and in the merge.
if n := strings.Count(body, `<div class="tl-card"`); n != 3 {
t.Errorf("FAIL: %d check-in cards, want 3", n)
}
if n := strings.Count(body, `data-hook="path-links"`); n != 3 {
t.Errorf("FAIL: %d cards with the file's diff and version links, want 3", n)
}
for _, want := range []string{
`class="hist-h"`,
`data-hook="path-filter"`,
`<input type="hidden" name="p" value="src/a.c">`,
// The heading's folder links to that folder's history.
`href="/r/alpha/timeline?p=src"`,
} {
if !strings.Contains(body, want) {
t.Errorf("FAIL: missing %s", want)
}
}
}
// A folder's history is every check-in that changed anything under it.
// Its cards carry no per-file links, which would name no one file.
func TestFolderHistoryListsChangesBelowIt(t *testing.T) {
srv := activityServer(t)
_, src := getPage(t, srv, "/r/alpha/timeline?p=src")
_, doc := getPage(t, srv, "/r/alpha/timeline?p=doc/")
if n := strings.Count(src, `<div class="tl-card"`); n != 3 {
t.Errorf("FAIL: src/ has %d check-ins, want 3", n)
}
if n := strings.Count(doc, `<div class="tl-card"`); n != 2 {
t.Errorf("FAIL: doc/ has %d check-ins, want 2", n)
}
if strings.Contains(src, `data-hook="path-links"`) {
t.Error("FAIL: a folder's history offers per-file links")
}
}
// Paging keeps the path, and so does the feed of the page.
func TestFileHistoryPagesAndFeedsKeepThePath(t *testing.T) {
srv := activityServer(t)
_, body := getPage(t, srv, "/r/alpha/timeline?p=src/a.c&n=1")
if !strings.Contains(body, "before=") || !strings.Contains(body, "&p=src") {
t.Error("FAIL: the older link drops the path")
}
_, all := getPage(t, srv, "/r/alpha/timeline.atom")
_, one := getPage(t, srv, "/r/alpha/timeline.atom?path=doc/x.md")
if c := strings.Count(one, "<entry>"); c != 2 || c >= strings.Count(all, "<entry>") {
t.Errorf("FAIL: the path's feed has %d entries, want 2 of the timeline's %d", c, strings.Count(all, "<entry>"))
}
}
// The old history page, a table nothing linked to, sends its readers on.
func TestOldFileHistoryAddressRedirects(t *testing.T) {
srv := activityServer(t)
c := &http.Client{CheckRedirect: func(*http.Request, []*http.Request) error { return http.ErrUseLastResponse }}
resp, err := c.Get(srv.URL + "/r/alpha/history/trunk/src/a.c")
if err != nil {
t.Fatal(err)
}
resp.Body.Close()
if resp.StatusCode != http.StatusMovedPermanently || resp.Header.Get("Location") != "/r/alpha/timeline?p=src%2Fa.c" {
t.Fatalf("FAIL: %d to %q", resp.StatusCode, resp.Header.Get("Location"))
}
}