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 "strings"
8 "testing"
9)
10
11func postSize(t *testing.T, app *App, cookies []*http.Cookie, s SheetSummary, body string) *httptest.ResponseRecorder {
12 t.Helper()
13 path := fmt.Sprintf("/api/sheets/%d/tabs/%d/size", s.ID, s.TabID)
14 req := httptest.NewRequest(http.MethodPost, path, strings.NewReader(body))
15 req.Header.Set("Content-Type", "application/json")
16 return do(t, app, as(req, cookies))
17}
18
19func TestAColumnWidthSurvivesAReload(t *testing.T) {
20 app, cookies := signIn(t)
21 s, cells := newSheet(t, app, cookies, "Budget")
22
23 rec := postSize(t, app, cookies, s, `{"col":2,"size":220}`)
24 if rec.Code != http.StatusOK {
25 t.Fatalf("POST size = %d: %s", rec.Code, rec.Body.String())
26 }
27 if g := decodeGrid(t, rec); g.Sizes == nil || g.Sizes.Cols["2"] != 220 {
28 t.Fatalf("the write did not echo the width: %+v", g.Sizes)
29 }
30
31 // The window GET must carry it too. Fetching sizes separately would
32 // make every page visibly reflow its columns once after load.
33 read := decodeGrid(t, do(t, app,
34 as(httptest.NewRequest(http.MethodGet, cells, nil), cookies)))
35 if read.Sizes == nil || read.Sizes.Cols["2"] != 220 {
36 t.Errorf("the window does not carry the width: %+v", read.Sizes)
37 }
38}
39
40func TestARowHeightIsStoredSeparatelyFromAColumnWidth(t *testing.T) {
41 app, cookies := signIn(t)
42 s, _ := newSheet(t, app, cookies, "Budget")
43
44 if rec := postSize(t, app, cookies, s, `{"col":0,"size":180}`); rec.Code != http.StatusOK {
45 t.Fatalf("width = %d", rec.Code)
46 }
47 rec := postSize(t, app, cookies, s, `{"row":0,"size":48}`)
48 if rec.Code != http.StatusOK {
49 t.Fatalf("height = %d: %s", rec.Code, rec.Body.String())
50 }
51 g := decodeGrid(t, rec)
52 if g.Sizes == nil {
53 t.Fatal("no sizes came back")
54 }
55 // Both, from one response: the payload is the whole table, so a tab
56 // that missed a frame converges on the next one it sees rather than
57 // staying one resize behind for ever.
58 if g.Sizes.Cols["0"] != 180 {
59 t.Errorf("setting a row height lost the column width: %+v", g.Sizes.Cols)
60 }
61 if g.Sizes.Rows["0"] != 48 {
62 t.Errorf("row height = %+v", g.Sizes.Rows)
63 }
64}
65
66func TestSizeRefusesWhatItCannotStore(t *testing.T) {
67 app, cookies := signIn(t)
68 s, _ := newSheet(t, app, cookies, "Budget")
69
70 for name, body := range map[string]string{
71 // A column dragged to nothing is one nobody can find again to
72 // drag back, and this app hides nothing and so unhides nothing.
73 "zero width": `{"col":0,"size":0}`,
74 "negative": `{"col":0,"size":-40}`,
75 "absurdly wide": `{"col":0,"size":99999}`,
76 "neither axis": `{"size":100}`,
77 "both axes": `{"col":0,"row":0,"size":100}`,
78 "column too far": `{"col":100000,"size":100}`,
79 } {
80 t.Run(name, func(t *testing.T) {
81 if rec := postSize(t, app, cookies, s, body); rec.Code != http.StatusBadRequest {
82 t.Errorf("= %d, want 400: %s", rec.Code, rec.Body.String())
83 }
84 })
85 }
86}
87
88func TestSizeIsRefusedForAViewer(t *testing.T) {
89 app, owner := signIn(t)
90 s, _ := newSheet(t, app, owner, "Budget")
91 guestOn(t, app, s.ID, "ada@elsewhere.example", SheetViewer)
92
93 viewer := signInAs(t, app, "ada@elsewhere.example")
94 // 404, never 403 — anything else lets somebody enumerate the team's
95 // sheets by status code.
96 if rec := postSize(t, app, viewer, s, `{"col":0,"size":200}`); rec.Code != http.StatusNotFound {
97 t.Errorf("= %d, want 404", rec.Code)
98 }
99}
100
101// TestAnUnsizedTabSendsNoSizes keeps the common case free.
102//
103// Every sheet in this app has no sizes until somebody drags something,
104// so an empty object on every window response would be a claim about
105// layout nobody made — and the client would have to know that "{}"
106// means "leave the library's defaults alone".
107func TestAnUnsizedTabSendsNoSizes(t *testing.T) {
108 app, cookies := signIn(t)
109 _, cells := newSheet(t, app, cookies, "Budget")
110
111 g := decodeGrid(t, do(t, app,
112 as(httptest.NewRequest(http.MethodGet, cells, nil), cookies)))
113 if g.Sizes != nil {
114 t.Errorf("an untouched tab sent sizes: %+v", g.Sizes)
115 }
116}
117