| 1 | package sheets |
| 2 | |
| 3 | import ( |
| 4 | "net/http" |
| 5 | "net/url" |
| 6 | "strings" |
| 7 | "testing" |
| 8 | ) |
| 9 | |
| 10 | // Refusing an editor link is a real refusal with a real reason, and the |
| 11 | // person can act on it by picking another role. It keeps its own |
| 12 | // notice. |
| 13 | func TestAnEditorLinkIsRefusedByName(t *testing.T) { |
| 14 | app, cookies := signIn(t) |
| 15 | s, _ := newSheet(t, app, cookies, "Budget") |
| 16 | |
| 17 | form := url.Values{"role": {string(SheetEditor)}} |
| 18 | rec := do(t, app, as(postForm(sharePath(s)+"/link", form), cookies)) |
| 19 | if loc := rec.Header().Get("Location"); !strings.Contains(loc, "bad-link-role") { |
| 20 | t.Fatalf("asking for an editor link = %q, want the role refusal", loc) |
| 21 | } |
| 22 | } |
| 23 | |
| 24 | // Everything else that can go wrong inside createLink — the token |
| 25 | // generator, the insert, a missing database — was reported with that |
| 26 | // same notice. So an infrastructure fault was presented to the person |
| 27 | // as their own input mistake: they retry the identical form, get the |
| 28 | // identical sentence, and have no way to tell that the thing they are |
| 29 | // being blamed for is not the thing that went wrong. |
| 30 | func TestAFailedLinkMintDoesNotBlameTheRole(t *testing.T) { |
| 31 | app, cookies := signIn(t) |
| 32 | s, _ := newSheet(t, app, cookies, "Budget") |
| 33 | |
| 34 | // A real failure rather than a mocked one: with the table gone the |
| 35 | // insert fails inside createLink, past the role check, on the same |
| 36 | // path a disk or migration fault would take. |
| 37 | if err := app.db.Exec("DROP TABLE share_links").Error; err != nil { |
| 38 | t.Fatalf("drop share_links: %v", err) |
| 39 | } |
| 40 | |
| 41 | form := url.Values{"role": {string(SheetViewer)}} |
| 42 | rec := do(t, app, as(postForm(sharePath(s)+"/link", form), cookies)) |
| 43 | if loc := rec.Header().Get("Location"); strings.Contains(loc, "bad-link-role") { |
| 44 | t.Fatalf("a database failure was reported as the person's role choice: %q", loc) |
| 45 | } |
| 46 | if rec.Code != http.StatusInternalServerError { |
| 47 | t.Fatalf("a failed mint = %d, want 500 — the same answer every other "+ |
| 48 | "broken write on this screen gives", rec.Code) |
| 49 | } |
| 50 | } |
| 51 | |