package view import ( "strings" "testing" "time" ) // ---- The log // The log is the whole of what the journal holds about the viewer's mail: the // filters offer what the viewer reaches, the head says how long rows live and // where to change it, and every row leads to its own page. func TestOutLogShowsTheRowsAndTheirFilters(t *testing.T) { out := renderSignedIn(t, "out-log", outLogFixture()) pageHas(t, "Outbound log", out, `

Outbound log

`, `Rows older than 30 days are deleted — change that in Settings.`, `
`, ``, `Time, UTC`, `09-21 14:01:52`, `shop@shop.example.org`, `m.keller@gmx.de`, `title="[FIRING] disk usage above 90 % on db-2"`, `sent`, `deferred`, `bounced`, `rate-limited`, `wrong From`, `href="/outbound/log/184220">Details`, `Page 1 of 412`, `Older →`, `New rows appear on their own`, ) pageLacks(t, "Outbound log", out, `← Newer`) // Without the global role there is nowhere to change the retention. p := NewOutLog(Meta{User: "ops", HasOutbound: true}, 7, false, []string{"example.org"}, nil, "", "") out = renderSignedIn(t, "out-log", p.WithRows(nil, 1, 1)) pageHas(t, "Outbound log", out, `Rows older than 7 days are deleted.`) pageLacks(t, "Outbound log", out, `/server/settings`) pageLacks(t, "Outbound log", renderSignedIn(t, "out-log", NewOutLog(Meta{User: "ops", HasOutbound: true}, 1, false, nil, nil, "", "").WithRows(nil, 1, 1)), `older than 1 days`) } // The filter in force is the one selected, and the poll, the paging and the // links of the rows all carry it — and say nothing for a filter that is not set. func TestOutLogCarriesItsFilters(t *testing.T) { p := NewOutLog(admin(), 30, true, []string{"example.org", "shop.example.org"}, []string{"alerts"}, "shop.example.org", "alerts") p.WithRows([]OutLogRow{{Time: "09-21 14:01:52", From: "a@example.org", To: "b@example.org", Subject: "Hi", Status: Tag{Status: "sent"}, Href: p.DetailHref(7, 3)}}, 3, 5) out := renderSignedIn(t, "out-log", p) pageHas(t, "Outbound log", out, ``, ``, `hx-get="/outbound/log/fragment?app=alerts&domain=shop.example.org&p=3"`, `href="/outbound/log/7?app=alerts&domain=shop.example.org&p=3"`, `Page 3 of 5 · ← Newer`, `Older →`, ) if got := LogHref("", "", 1); got != "/outbound/log" { t.Errorf("the first unfiltered page is %q", got) } if got := LogHref("a b&c", "", 2); got != "/outbound/log?domain=a+b%26c&p=2" { t.Errorf("a filter is not encoded: %q", got) } } // The last page has nothing older, and a page with no rows says so and still // polls: a log that is empty now is the one that fills while the page is open. func TestOutLogLastPageAndEmptyPage(t *testing.T) { p := NewOutLog(admin(), 30, true, nil, nil, "", "") out := renderSignedIn(t, "out-log", p.WithRows([]OutLogRow{{Subject: "x", Status: Tag{Status: "sent"}, Href: "/outbound/log/1"}}, 2, 2)) pageHas(t, "Outbound log", out, `Page 2 of 2`, `← Newer`) pageLacks(t, "Outbound log", out, `Older →`) out = renderSignedIn(t, "out-log", NewOutLog(admin(), 30, true, nil, nil, "", "").WithRows(nil, 1, 1)) pageHas(t, "Outbound log", out, `No messages logged yet.`, `id="out-log-rows"`, `data-poll`, `id="out-log-foot"`, `New rows appear on their own`) pageLacks(t, "Outbound log", out, ``) pageLacks(t, "fragment", frag, ``) if strings.Count(frag, `d`}, []string{`">`}, "", "") p.WithRows([]OutLogRow{{Time: "t", From: `">@a`, To: `@b`, Subject: ``, Status: Tag{Status: ``}, Href: "/outbound/log/1"}}, 1, 1) out := renderSignedIn(t, "out-log", p) pageLacks(t, "Outbound log", out, ``, Status: "sent", Accepted: at, Reported: at, BackHref: "/outbound/log"}). WithHistory([]Step{{Time: "t", Strong: `s`, Text: Plain(`x`)}}). WithDeliveryLog([]LogLine{{Time: ``, Text: ``}}, "") out := renderSignedIn(t, "out-message", p) pageLacks(t, "Message", out, `