package web // Review rounds 1 and 2, F1 and F3 (novox/hq ADR 0517 §3, §5: no act writes two lines; the page opened is // last looked): the page shown after an act — reached once, by the act's own short-lived cookie, or by the // script's refresh — records nothing; any other opening of that same address records as ever, and the // address carries no marker. import ( "net/http" "net/http/httptest" "net/url" "strings" "testing" ) // getWith is a GET of path carrying cookies and headers, answering the recorder. func getWith(s http.Handler, path string, cookies []*http.Cookie, header map[string]string) *httptest.ResponseRecorder { r := newGet(path, nil) for _, c := range cookies { r.AddCookie(c) } for k, v := range header { r.Header.Set(k, v) } return serve(s, r) } // postAct posts form to path with the session's cookie, answering the recorder. func postAct(s http.Handler, path string, form url.Values, cookie *http.Cookie) *httptest.ResponseRecorder { r := httptest.NewRequest(http.MethodPost, path, strings.NewReader(form.Encode())) r.Host = testHost r.Header.Set("Content-Type", "application/x-www-form-urlencoded") r.AddCookie(cookie) return serve(s, r) } func actedCookie(w *httptest.ResponseRecorder) *http.Cookie { for _, c := range w.Result().Cookies() { if c.Name == ActedCookie { return c } } return nil } // 1859/AC5, 1858/AC4, AC5: after a tick, a reminder, a correction or a mode chosen, the page it goes back to // records nothing, once; opening that same address again records page opened (or opened, for a mail). func TestThePageAfterAnActRecordsNothingOnceAndThenAsEver(t *testing.T) { for _, tc := range []struct { path, again string form url.Values }{ {"/item", "page opened", url.Values{"id": {"3"}, "item": {"task 1"}, "mode": {"everything"}, "act": {"handle"}}}, {"/item", "page opened", url.Values{"id": {"3"}, "item": {"task 1"}, "mode": {"everything"}, "act": {"remind"}}}, {"/mode", "page opened", url.Values{"mode": {"everything"}}}, {"/correct", "opened", url.Values{"id": {"3"}, "mode": {"everything"}, "read-later": {"on"}}}, } { reading, b := paneBundle(t) s, session, token := signedIn(t, b) tc.form.Set(FormTokenField, token) w := postAct(s, tc.path, tc.form, session) back := w.Header().Get("Location") if w.Code != http.StatusSeeOther || strings.Contains(back, "acted") { t.Fatalf("%s: status %d to %q; want 303 to an address with no marker", tc.path, w.Code, back) } acted := actedCookie(w) if acted == nil || acted.MaxAge <= 0 || acted.MaxAge > 60 || !acted.HttpOnly || acted.SameSite != http.SameSiteStrictMode { t.Fatalf("%s: the act's cookie %+v, want a short-lived, HttpOnly, SameSite=Strict one", tc.path, acted) } before := len(reading.callsOf("record")) // the mode chosen is its own one line shown := getWith(s, back, []*http.Cookie{session, acted}, nil) if shown.Code != http.StatusOK || len(reading.callsOf("record")) != before { t.Fatalf("%s: the page after it (%s): status %d, records %v; want nothing recorded", tc.path, back, shown.Code, reading.callsOf("record")) } if cleared := actedCookie(shown); cleared == nil || cleared.MaxAge >= 0 { t.Fatalf("%s: the page after it did not clear the act's cookie: %+v", tc.path, cleared) } // A reload, the tab restored the next morning, a bookmark: the same address, without the cookie. getWith(s, back, []*http.Cookie{session}, nil) rec := reading.callsOf("record") if len(rec) != before+1 || rec[len(rec)-1].Args["what"] != tc.again { t.Fatalf("%s: opening %s again recorded %v; want one %s more", tc.path, back, rec, tc.again) } } } // The script's own refresh after an act records nothing; opening the page and a mail record one line each. func TestTheScriptsRefreshRecordsNothing(t *testing.T) { reading, b := paneBundle(t) s, session, _ := signedIn(t, b) for _, path := range []string{"/?mode=everything", "/read?id=3&mode=everything"} { getWith(s, path, []*http.Cookie{session}, map[string]string{RefreshHeader: "1"}) } if rec := reading.callsOf("record"); len(rec) != 0 { t.Fatalf("the script's refreshes recorded %v, want nothing", rec) } getWith(s, "/?mode=everything", []*http.Cookie{session}, nil) getWith(s, "/read?id=3&mode=everything", []*http.Cookie{session}, nil) if rec := reading.callsOf("record"); len(rec) != 2 || rec[0].Args["what"] != "page opened" || rec[1].Args["what"] != "opened" { t.Fatalf("opening the page and a mail recorded %v, want page opened then opened", rec) } }