Skip to content
quarry Artifact [aff2268375]
Login

Artifact [aff2268375]

Artifact aff2268375bd98ebceec3108baee8a0150a5d1cb298e5545f4ca17299e65495d:


package web

import (
	"strings"
	"testing"

	"craftdesign.group/quarry/internal/diff"
	"craftdesign.group/quarry/internal/index"
)

func noteDiff() *diffDetail {
	return &diffDetail{Structured: []diff.FileDiff{{Path: "a.go", Change: "change", Hunks: []diff.Hunk{{
		OldStart: 1, NewStart: 1, Lines: []diff.Line{
			{Kind: "context", OldNum: 1, NewNum: 1, Tokens: []diff.Token{{Text: "package a"}}},
			{Kind: "deletion", OldNum: 2, Tokens: []diff.Token{{Text: "old()"}}},
			{Kind: "addition", NewNum: 2, Tokens: []diff.Token{{Text: "new()"}}},
		}}}}}}
}

// LINE NOTES LAND UNDER THEIR LINE, AND ONLY WHILE THE LINE IS THE SAME.
//
// A note written at the branch's current tip sits under its line; one
// written at an earlier tip is marked stale and stays in the discussion
// only, because its number may now name another line. A reader who may
// speak gets line links, and ?line= opens the composer only on a line
// the diff actually shows.
func TestLineNotesSitUnderTheirLine(t *testing.T) {
	det := &landingDetail{CanSpeak: true, Diff: noteDiff()}
	det.State, det.ID = "open", "abcdef123456"
	det.Comments = []forumPostRow{
		{Hash: "n1aaaaaaaaaa", User: "ada", HTML: "on the new line", Line: &index.LineNote{File: "a.go", Side: "new", Line: 2, At: "cafe12"}},
		{Hash: "n2bbbbbbbbbb", User: "bob", HTML: "on the removed line", Line: &index.LineNote{File: "a.go", Side: "old", Line: 2, At: "cafe12"}},
		{Hash: "n3cccccccccc", User: "cy", HTML: "written before the branch moved", Line: &index.LineNote{File: "a.go", Side: "new", Line: 1, At: "0ld000"}},
	}
	data := pageData{Repo: "r", Diff: *det.Diff, Landing: det}
	lineNotesFor(&data, det, "cafe12deadbeef", "a.go:new:2")
	if !data.LineLinks || data.LineCompose == nil || data.LineCompose.Line != 2 || data.LineCompose.At != "cafe12deadbeef" {
		t.Fatalf("FAIL: links %v, composer %+v", data.LineLinks, data.LineCompose)
	}
	if !det.Comments[2].LineStale || det.Comments[0].LineStale {
		t.Error("FAIL: staleness is wrong: only the note from before the branch moved is stale")
	}
	var buf strings.Builder
	if err := diffPage.ExecuteTemplate(&buf, "diff-more", data); err != nil {
		t.Fatal(err)
	}
	page := buf.String()
	for _, want := range []string{"on the new line", "on the removed line", `data-hook="line-compose"`, `name="side" value="new"`, `href="?line=a.go%3aold%3a2#lc"`} {
		if !strings.Contains(page, want) {
			t.Errorf("FAIL: the diff is missing %q", want)
		}
	}
	if strings.Contains(page, "written before the branch moved") {
		t.Error("FAIL: a stale note was drawn under a line it may no longer name")
	}

	other := pageData{Repo: "r", Diff: *det.Diff, Landing: det}
	lineNotesFor(&other, det, "cafe12deadbeef", "a.go:new:99")
	if other.LineCompose != nil {
		t.Error("FAIL: ?line= opened a composer on a line the diff does not show")
	}
	reader := &landingDetail{CanSpeak: false, Diff: noteDiff()}
	reader.State = "open"
	quiet := pageData{Repo: "r", Diff: *reader.Diff, Landing: reader}
	lineNotesFor(&quiet, reader, "cafe12", "a.go:new:2")
	if quiet.LineLinks || quiet.LineCompose != nil {
		t.Error("FAIL: a reader who may not speak got line links or a composer")
	}
}