package e2e import ( "net/http" "net/url" "os/exec" "strings" "testing" ) // Chapter 35.5 is two commands, and what they produce has to appear on the thread page. func TestAReplyWrittenTheWayTheBookSaysAppearsOnThePage(t *testing.T) { if _, err := exec.LookPath("git"); err != nil { t.Skip("git is not installed") } in := newInstance(t) john := in.account("john") mark := in.account("mark") seed(t, in, john, "john", "johnbot") resp := post(t, in, "john", "/john/johnbot/threads", url.Values{ "title": {"the reconnect loop spins"}, "body": {"it retries with no delay"}, }) if resp.StatusCode != http.StatusFound { t.Fatalf("opening a thread answered %d", resp.StatusCode) } work := clone(t, in, mark, "/john/johnbot") // 35.4's fetch is the wildcard one, because that is the line the book hands out. run(t, work, "git", "fetch", "-q", in.url(mark, "/john/johnbot"), "refs/notes/*:refs/notes/*") // 35.5 verbatim: a message and nothing else, with no header a reader would have to know about. run(t, work, "git", "notes", "--ref=threads/1", "append", "-m", "I see the same problem.") run(t, work, "git", "push", "-q", in.url(mark, "/john/johnbot"), "refs/notes/threads/1") code, _, body := get(t, in.http.URL+"/john/johnbot/thread/1") if code != http.StatusOK { t.Fatalf("the thread answered %d", code) } if !strings.Contains(body, "I see the same problem.") { t.Error("a reply pushed the way chapter 35.5 documents is not on the thread page") } // And it is attributed to mark, or john is shown saying words mark wrote. if !strings.Contains(body, "mark") { t.Error("the reply is on the page with no author, and the push knew who pushed it") } // The two must be separate comments, since one of them belongs to somebody else. if strings.Count(body, `class="body"`) < 2 { t.Error("the reply was merged into the comment above it, under that person's name") } if i, j := strings.Index(body, "it retries with no delay"), strings.Index(body, "mark"); i > j { t.Error("the reply is above the comment it answers") } } // A reply from the web is already a proper record, so the repair must leave it exactly alone. func TestARepairDoesNotTouchAWellFormedReply(t *testing.T) { if _, err := exec.LookPath("git"); err != nil { t.Skip("git is not installed") } in := newInstance(t) john := in.account("john") mark := in.account("mark") seed(t, in, john, "john", "johnbot") post(t, in, "john", "/john/johnbot/threads", url.Values{ "title": {"a thread"}, "body": {"the first word"}}) post(t, in, "mark", "/john/johnbot/thread/1/reply", url.Values{"body": {"the second word"}}) // A mirror push of the whole ref changes nothing, so nothing may be re-attributed by it. work := clone(t, in, mark, "/john/johnbot") run(t, work, "git", "fetch", "-q", in.url(mark, "/john/johnbot"), "refs/notes/*:refs/notes/*") run(t, work, "git", "push", "-q", in.url(mark, "/john/johnbot"), "refs/notes/threads/1") _, _, body := get(t, in.http.URL+"/john/johnbot/thread/1") if strings.Count(body, "the second word") != 1 { t.Error("a push that changed nothing rewrote a comment") } if !strings.Contains(body, ">john") || !strings.Contains(body, ">mark") { t.Errorf("a push that changed nothing lost an author:\n%s", body) } } // A record that already names its author is kept as written, or chapter 40.3 cannot restore a repository. func TestARestoredNoteKeepsTheAuthorItCarries(t *testing.T) { if _, err := exec.LookPath("git"); err != nil { t.Skip("git is not installed") } in := newInstance(t) john := in.account("john") mark := in.account("mark") in.account("lisa") seed(t, in, john, "john", "johnbot") post(t, in, "john", "/john/johnbot/threads", url.Values{ "title": {"a thread"}, "body": {"the first word"}}) // Mark pushes a record lisa wrote, which is what restoring somebody else's repository is. work := clone(t, in, mark, "/john/johnbot") run(t, work, "git", "fetch", "-q", in.url(mark, "/john/johnbot"), "refs/notes/*:refs/notes/*") run(t, work, "git", "notes", "--ref=threads/1", "append", "-m", "--\nauthor: lisa\ntime: 1755000000\n\nlisa wrote this line") run(t, work, "git", "push", "-q", in.url(mark, "/john/johnbot"), "refs/notes/threads/1") _, _, body := get(t, in.http.URL+"/john/johnbot/thread/1") if !strings.Contains(body, "lisa wrote this line") { t.Fatalf("the pushed record is not on the page:\n%s", body) } if !strings.Contains(body, ">lisa") { t.Error("a record naming its own author was re-attributed to whoever pushed it") } }