Files
felhom.eu/hub/internal/web/selfbind_waiting_test.go
T

91 lines
3.2 KiB
Go

package web
import (
"net/http/httptest"
"net/url"
"strings"
"testing"
"gitea.dooplex.hu/admin/felhom-hub/internal/store"
)
// R-509 (operator decision A, 2026-09-15) — the connect e-mail goes out by itself whenever a customer
// is left WAITING FOR A BOX. BIGNIGHT: tester-1 had its e-mail added after creation and its previous
// host deleted; the box's console promised a mail; the mailbox held 0 messages ten minutes later.
func updateEmail(t *testing.T, s *Server, id, email string) {
t.Helper()
form := url.Values{"customer_name": {id}, "domain": {id + ".hu"}, "email": {email}}
req := httptest.NewRequest("POST", "/configs/"+id, strings.NewReader(form.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
rr := httptest.NewRecorder()
s.handleConfigUpdate(rr, req, id)
if rr.Code != 303 {
t.Fatalf("config update = %d (%s)", rr.Code, rr.Body.String())
}
}
// RED-PROOF (run 2026-09-15, recorded in REPORT.md): with the autoMintSelfBindIfWaiting call removed
// from handleConfigUpdate, no link went out and this failed at "e-mail set on a customer with no box
// sent no link".
func TestSelfBind_EmailSetOnWaitingCustomerSendsLink(t *testing.T) {
s, st := newTestServer(t)
m := &stubMailer{}
s.SetSelfBindMailer(m)
seedForMint(t, st, "tester", "")
updateEmail(t, s, "tester", "tester1@felhom.example")
if m.link == "" {
t.Fatal("e-mail set on a customer with no box sent no link")
}
ev, _ := st.GetLatestEventByType("tester", selfBindSentEvent)
if ev == nil || !strings.Contains(ev.DetailsJSON, "no box") {
t.Fatalf("the send was not recorded with its occasion: %+v", ev)
}
// The same address saved again → no second mail.
m.link = ""
updateEmail(t, s, "tester", "tester1@felhom.example")
if m.link != "" {
t.Fatal("an unchanged e-mail re-sent the link on every save")
}
}
func TestSelfBind_CustomerWithBoxGetsNoLink(t *testing.T) {
s, st := newTestServer(t)
m := &stubMailer{}
s.SetSelfBindMailer(m)
seedForMint(t, st, "hasbox", "")
if err := st.UpsertHost(&store.Host{HostID: "hasbox-01", CustomerID: "hasbox", APIKey: "h"}); err != nil {
t.Fatal(err)
}
updateEmail(t, s, "hasbox", "owner@hasbox.example")
if m.link != "" {
t.Fatal("a customer that has a box was mailed a pairing link")
}
}
func TestSelfBind_HostDeleteSendsLink(t *testing.T) {
s, st := newTestServer(t)
m := &stubMailer{}
s.SetSelfBindMailer(m)
seedForMint(t, st, "rebuilt", "owner@rebuilt.example")
if err := st.UpsertHost(&store.Host{HostID: "rebuilt-01", CustomerID: "rebuilt", APIKey: "h"}); err != nil {
t.Fatal(err)
}
form := url.Values{"confirm_host_id": {"rebuilt-01"}}
req := httptest.NewRequest("POST", "/hosts/rebuilt-01/delete", strings.NewReader(form.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
rr := httptest.NewRecorder()
s.handleHostDelete(rr, req, "rebuilt-01")
if rr.Code != 303 {
t.Fatalf("host delete = %d (%s)", rr.Code, rr.Body.String())
}
if m.link == "" {
t.Fatal("host delete kept the customer waiting for a box and sent no link")
}
if ev, _ := st.GetLatestEventByType("rebuilt", selfBindSentEvent); ev == nil || !strings.Contains(ev.DetailsJSON, "host delete") {
t.Fatalf("host-delete send not recorded: %+v", ev)
}
}