package web
import "testing"
// An attach action returns to the page it was taken from, including the
// OWNER-PREFIXED page URL, which is the canonical one.
//
// /r/<repo>/... redirects to /r/<owner>/<repo>/..., so every page a
// person actually has open carries the owner. attachBack accepted only
// the un-prefixed shape, so every upload, vouch, reject and remove from
// a real page failed the check and was sent to the repository home. The
// file uploaded and the reader was moved somewhere it was not, which
// reads exactly like nothing happened — which is how it was reported.
//
// The negative rows are the point of the function and must keep
// failing: another repository, a scheme, a host, a protocol-relative
// path, a header split.
func TestAnAttachActionReturnsToItsOwnPage(t *testing.T) {
const repo = "quarry"
home := "/r/quarry"
kept := []string{
"/r/quarry/ticket/abab#attachments",
"/r/quarry/landing/53540dc12400#attachments",
// The canonical, owner-prefixed form.
"/r/dmestas/quarry/landing/53540dc12400#attachments",
"/r/dmestas/quarry/ticket/abab",
"/r/dmestas/quarry/wiki/Home",
}
for _, back := range kept {
if got := attachBack(repo, back); got != back {
t.Errorf("FAIL: %q was not returned to; went to %q", back, got)
}
}
sent := []string{
"", // nothing asked for
"/r/other/ticket/abab", // a different repository
"/r/dmestas/other/ticket/abab", // ditto, owner-prefixed
"//evil.example/r/quarry/x", // protocol-relative
"https://evil.example/r/quarry", // absolute
"/r/quarry/x\r\nX-Evil: 1", // header split
"/quarry/ticket/abab", // not a repository path at all
}
for _, back := range sent {
if got := attachBack(repo, back); got != home {
t.Errorf("FAIL: %q was accepted as a return target, giving %q", back, got)
}
}
}