oficina / docs Public

Clone
git clone https://amadan.net/oficina/docs

Plain git — no account needed to clone.

Download

Download this file

1package docs_test
2
3import (
4 "net/http"
5 "strings"
6 "testing"
7
8 "github.com/carlosframework/docs/internal/docs"
9)
10
11// A reader grantee must not be handed an editor. Found by the branch
12// review, and the worst defect on this branch: `show` used GetFor
13// (correct — a reader may read) and then rendered the owner's page
14// verbatim, so ProseMirror mounted, the toolbar enabled, and the document
15// became contenteditable for somebody the server will refuse.
16//
17// The server refusal was never in doubt: ApplyUpdate returns ErrNotWritable
18// and updatesPost answers 404. The damage is upstream of that. The browser
19// has already taken the keystrokes; the save queue classifies the 404 as
20// permanent, drops the batch, and keeps accepting typing. The person is
21// told "save failed" after writing a paragraph into a page that told them
22// they could.
23//
24// "It fails safely on the server" is not a defence when the cost is a
25// person's work.
26func TestAReaderIsNotGivenAnEditor(t *testing.T) {
27 app, _ := docs.NewForTest(t)
28 alice := signInCookies(t, app, "alice@example.com")
29 sqid := createDoc(t, app, alice, "Minutes")
30 bob := signInCookies(t, app, "bob@example.com")
31 post(t, app, alice, "/d/"+sqid+"/share", "address=bob@example.com&role=reader")
32
33 rec := get(t, app, bob, "/d/"+sqid)
34 if rec.Code != http.StatusOK {
35 t.Fatalf("GET /d/%s as a reader: status %d, want 200", sqid, rec.Code)
36 }
37 body := rec.Body.String()
38
39 // The mount ELEMENT, not the string: `[docs-editor]` also appears a
40 // dozen times in this page's own <style> block, so banning the bare
41 // word would fail on a page that is perfectly correct — and would
42 // have hidden whether the element itself was gone. `docs-text
43 // docs-editor` is the attribute pair the mount point carries and the
44 // stylesheet never does.
45 //
46 // data-sqid is the bundle's only way to learn where to post, and the
47 // editor script is checked by its real served path rather than a
48 // guessed substring: the review found this test's earlier sibling
49 // banning "editor-entry", a string that appears on no page in this
50 // app, which is a ban that could never fail.
51 for _, banned := range []string{"docs-text docs-editor", "data-sqid", docs.TestEditorScriptPath()} {
52 if strings.Contains(body, banned) {
53 t.Errorf("a reader's document page ships %q", banned)
54 }
55 }
56
57 // The content is still there. A read-only page that renders nothing is
58 // not the fix.
59 if !strings.Contains(body, "Minutes") {
60 t.Error("the reader's page does not show the document")
61 }
62}
63
64// The writer keeps everything. Without this the fix above passes on a
65// page that gives nobody an editor.
66func TestAWriterKeepsTheEditor(t *testing.T) {
67 app, _ := docs.NewForTest(t)
68 alice := signInCookies(t, app, "alice@example.com")
69 sqid := createDoc(t, app, alice, "Minutes")
70 bob := signInCookies(t, app, "bob@example.com")
71 post(t, app, alice, "/d/"+sqid+"/share", "address=bob@example.com&role=writer")
72
73 for who, cookies := range map[string][]*http.Cookie{"writer": bob, "owner": alice} {
74 body := get(t, app, cookies, "/d/"+sqid).Body.String()
75 for _, needed := range []string{"docs-text docs-editor", "data-sqid", docs.TestEditorScriptPath()} {
76 if !strings.Contains(body, needed) {
77 t.Errorf("the %s's page is missing %q", who, needed)
78 }
79 }
80 }
81}
82