current commit
261023.3 · Wiki links
package main

import (
	"encoding/json"
	"os"
	"path/filepath"
	"testing"
	"time"
)

// A doc's backlinks name each doc that links to it, by any relative
// spelling, and follow edits, new files and deleted ones.
func TestBacklinks(t *testing.T) {
	s, _, dir := serveTree(t)
	write := func(name, body string) {
		p := filepath.Join(dir, name)
		os.MkdirAll(filepath.Dir(p), 0o755)
		if err := os.WriteFile(p, []byte(body), 0o644); err != nil {
			t.Fatal(err)
		}
	}
	write("a/c.md", "[up](../index.md) [self](c.md) [again](./../index.md#x)\n")
	write("d/e.md", "[ref][r]\n\n[r]: ../index.md\n")
	write("d/f.md", "[elsewhere](../a/b.go) and index.md in prose\n")
	write(".git/g.md", "[hidden](../index.md)\n")
	write("w.md", "[[index]]\n")
	links := func(name string) []string {
		t.Helper()
		w := get(s.handler(), name+"?backlinks")
		if w.Code != 200 {
			t.Fatalf("%s: status %d: %s", name, w.Code, w.Body)
		}
		var res backlinks
		if err := json.Unmarshal(w.Body.Bytes(), &res); err != nil {
			t.Fatal(err)
		}
		var out []string
		for _, h := range res.Links {
			out = append(out, h.Href)
		}
		return out
	}
	eq := func(got []string, want ...string) {
		t.Helper()
		if len(got) != len(want) {
			t.Fatalf("got %q, want %q", got, want)
		}
		for i := range got {
			if got[i] != want[i] {
				t.Fatalf("got %q, want %q", got, want)
			}
		}
	}
	eq(links("/index.md"), "/a/c.md", "/d/e.md", "/w.md")
	eq(links("/a/b.go"), "/d/f.md", "/index.md")
	eq(links("/a/c.md"))

	// An edit is read again by its time, a deletion drops the file.
	write("d/e.md", "no link now\n")
	os.Chtimes(filepath.Join(dir, "d/e.md"), time.Now(), time.Now().Add(time.Second))
	os.Remove(filepath.Join(dir, "a/c.md"))
	write("h.md", "[i](index.md)\n")
	eq(links("/index.md"), "/h.md", "/w.md")
}