package web
import (
"net/url"
"strings"
"testing"
"craftdesign.group/quarry/internal/api"
)
// The control exists only where there is somewhere to store what it
// says. A family notify reports no window for keeps the words it always
// had, because a select that stores nothing is worse than static text.
func TestCadenceControlOnlyWhereAFamilyBatches(t *testing.T) {
n := newFakeNotify()
n.windows = map[string]api.DigestWindow{
"quarry-activity": {Amount: 2, Unit: "hours", Chosen: false},
}
f := newPrefsForge(t, n)
_, body := f.get(t, "/me")
if !strings.Contains(body, `<select name="digest.activity">`) {
t.Error("FAIL: the family that batches has no cadence control")
}
for _, family := range []string{"mention", "reply", "landing"} {
if strings.Contains(body, `name="digest.`+family+`"`) {
t.Errorf("FAIL: %s has a cadence control and nowhere to store it", family)
}
}
// The default option names the window in force rather than leaving
// the reader to guess what "default" means today.
if !strings.Contains(body, "every 2 hours — the forge's own") {
t.Errorf("FAIL: the inherited window does not name itself:\n%s", body)
}
t.Log("ok: the control is drawn only where a window can be stored")
}
// A window this account chose is the one selected, and the default
// option stops claiming to be in force.
func TestCadenceShowsTheChosenWindow(t *testing.T) {
n := newFakeNotify()
n.windows = map[string]api.DigestWindow{
"quarry-activity": {Amount: 15, Unit: "minutes", Chosen: true},
}
f := newPrefsForge(t, n)
_, body := f.get(t, "/me")
if !strings.Contains(body, `<option value="15 minutes" selected>`) {
t.Errorf("FAIL: the chosen window is not selected:\n%s", body)
}
if strings.Contains(body, "the forge's own\n") && strings.Contains(body, "every 15 minutes — the forge") {
t.Error("FAIL: the default option claims a window somebody overrode")
}
t.Log("ok: a chosen window is what the control shows")
}
// Saving carries the cadence to the companion — and only for the
// families that posted one, because notify merges the digest map and an
// absent family must keep the window it has.
func TestSavingACadenceReachesTheCompanion(t *testing.T) {
n := newFakeNotify()
n.windows = map[string]api.DigestWindow{"quarry-activity": {Amount: 2, Unit: "hours"}}
f := newPrefsForge(t, n)
f.post(t, "/me/notifications", url.Values{
"activity.inapp": {"on"}, "digest.activity": {"1 days"},
})
got := n.setWindows
if len(got) != 1 {
t.Fatalf("FAIL: %d windows were written, want 1: %+v", len(got), got)
}
w, ok := got["quarry-activity"]
if !ok || w == nil {
t.Fatalf("FAIL: the activity window did not travel: %+v", got)
}
if w.Amount != 1 || w.Unit != "days" {
t.Errorf("FAIL: wrote %+v, want one day", w)
}
t.Log("ok: a chosen cadence reaches the companion, alone")
}
// "The forge's own window" is a CLEAR, not a value: it must arrive as an
// explicit null, since omitting the key would leave the override in
// place and the reader would watch their choice fail to take.
func TestChoosingTheDefaultClearsTheOverride(t *testing.T) {
n := newFakeNotify()
n.windows = map[string]api.DigestWindow{"quarry-activity": {Amount: 15, Unit: "minutes", Chosen: true}}
f := newPrefsForge(t, n)
f.post(t, "/me/notifications", url.Values{
"activity.inapp": {"on"}, "digest.activity": {"default"},
})
w, ok := n.setWindows["quarry-activity"]
if !ok {
t.Fatal("FAIL: choosing the default wrote nothing at all")
}
if w != nil {
t.Errorf("FAIL: the clear arrived as %+v, want an explicit null", w)
}
t.Log("ok: the default is written as a clear")
}