oficina / sheets Public

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

Plain git — no account needed to clone.

Download

Download this file

1package sheets
2
3import (
4 "fmt"
5 "net/http"
6 "net/http/httptest"
7 "net/url"
8 "strings"
9 "testing"
10)
11
12// PRODUCT.md's second principle: the scriptless path is the product,
13// not the fallback. An affordance in the grid and not in the table view
14// means the table view is unfinished — and column width was the last of
15// the seven that had no form behind it.
16func TestAColumnCanBeWidenedWithNoScriptAtAll(t *testing.T) {
17 app, cookies := signIn(t)
18 s, _ := newSheet(t, app, cookies, "Budget")
19
20 form := url.Values{"col": {"2"}, "size": {"180"}, "page": {"1"}}
21 req := postForm(fmt.Sprintf("/api/sheets/%d/tabs/%d/size", s.ID, s.TabID), form)
22 rec := do(t, app, as(req, cookies))
23 if rec.Code != http.StatusSeeOther {
24 t.Fatalf("scriptless resize = %d, want 303: %s", rec.Code, rec.Body.String())
25 }
26 // Back to the table, never to a target the caller chose.
27 if loc := rec.Header().Get("Location"); loc != fmt.Sprintf("/sheets/%d/table?page=1", s.ID) {
28 t.Fatalf("Location = %q", loc)
29 }
30
31 h, err := app.openTabFor(s)
32 if err != nil {
33 t.Fatalf("open tab: %v", err)
34 }
35 defer h.Release()
36 cols, _, err := h.Sizes()
37 if err != nil {
38 t.Fatalf("Sizes: %v", err)
39 }
40 if cols[2] != 180 {
41 t.Fatalf("column 2 is %d wide, want 180 — the form did not reach the store", cols[2])
42 }
43}
44
45// The JSON route refuses both-or-neither rather than guessing. The form
46// path must refuse the same way, or the two decoders are two rule sets.
47func TestTheResizeFormRefusesBothOrNeither(t *testing.T) {
48 app, cookies := signIn(t)
49 s, _ := newSheet(t, app, cookies, "Budget")
50 path := fmt.Sprintf("/api/sheets/%d/tabs/%d/size", s.ID, s.TabID)
51
52 for _, form := range []url.Values{
53 {"col": {"1"}, "row": {"1"}, "size": {"100"}},
54 {"size": {"100"}},
55 {"col": {"notanumber"}, "size": {"100"}},
56 {"col": {"1"}, "size": {"notanumber"}},
57 } {
58 rec := do(t, app, as(postForm(path, form), cookies))
59 if rec.Code == http.StatusSeeOther {
60 t.Errorf("the form %v was accepted", form)
61 }
62 }
63}
64
65// A viewer must not resize: it is a layout change everybody watching
66// the sheet sees.
67func TestAViewerCannotResizeThroughTheForm(t *testing.T) {
68 app, cookies := signIn(t)
69 s, _ := newSheet(t, app, cookies, "Budget")
70 guestOn(t, app, s.ID, "ada@elsewhere.example", SheetViewer)
71 adaCookies := signInAs(t, app, "ada@elsewhere.example")
72
73 form := url.Values{"col": {"0"}, "size": {"200"}, "page": {"1"}}
74 rec := do(t, app, as(postForm(fmt.Sprintf("/api/sheets/%d/tabs/%d/size", s.ID, s.TabID), form), adaCookies))
75 if rec.Code == http.StatusSeeOther {
76 t.Fatalf("a viewer resized a column: %d", rec.Code)
77 }
78}
79
80// The control itself, with every script stripped out.
81func TestTheTableViewOffersAWidthControlWithoutScript(t *testing.T) {
82 app, cookies := signIn(t)
83 s, _ := newSheet(t, app, cookies, "Budget")
84
85 body := withoutScript(do(t, app,
86 as(httptest.NewRequest(http.MethodGet, tablePath(s), nil), cookies)).Body.String())
87 for _, want := range []string{
88 fmt.Sprintf(`action="/api/sheets/%d/tabs/%d/size"`, s.ID, s.TabID),
89 `name="col"`,
90 `name="size"`,
91 } {
92 if !strings.Contains(body, want) {
93 t.Errorf("with scripts stripped, %q is gone — the table view cannot resize", want)
94 }
95 }
96}
97