package main import ( "bytes" "context" "errors" "log" "path/filepath" "strings" "testing" "github.com/meshcore-analyzer/users" ) func TestRedactAddrs(t *testing.T) { cases := map[string]string{ `brevo 400 invalid_parameter: email "Bob.Smith+x@Mail.Example.org" is not valid`: `brevo 400 invalid_parameter: email "" is not valid`, "to a@b.co and c_d@e-f.example.net failed": "to and failed", "brevo 503 service unavailable": "brevo 503 service unavailable", "rejected john.smith&co@example.org": "rejected ", "rejected jörg.müller@x.de": "rejected ", "rejected bob@bücher.de": "rejected ", "rejected bob+newsletter@example.org": "rejected ", "rejected o'neil!#$*/=?^{|}~@example.org, retry": "rejected , retry", "recipient ; cc (bea@example.org)": "recipient <>; cc ()", } for in, want := range cases { if got := redactAddrs(errors.New(in)); got != want { t.Errorf("redactAddrs(%q) = %q, want %q", in, got, want) } } } func TestSendMailLogHasNoAddress(t *testing.T) { a, fake := newTestAuthService(t) fake.SetSendErr(errors.New(`brevo 400: invalid email victim@example.org`)) var buf bytes.Buffer prev := log.Writer() log.SetOutput(&buf) defer log.SetOutput(prev) u := &users.User{ID: 7, Email: "victim@example.org", DisplayName: "Vic"} if err := a.sendMail(context.Background(), u, "reset", a.resetMail(u, "tok")); err == nil { t.Fatal("sendMail returned nil on a send error") } out := buf.String() if strings.Contains(out, "victim@example.org") || !strings.Contains(out, "") || !strings.Contains(out, "#7") { t.Fatalf("log line = %q", out) } } // Activation needs the account password (handleActivate), so the mail says so. func TestActivationMailMentionsPassword(t *testing.T) { a, _ := newTestAuthService(t) u := &users.User{ID: 1, Email: "new@example.org", DisplayName: "New"} m := a.activationMail(u, "tok") for _, body := range []string{m.Text, m.HTML} { if !strings.Contains(body, "enter the password you chose") { t.Fatalf("activation mail does not mention the password: %q", body) } } } // The startup line shows the absolute users.db path, so a relative path // resolved against another working directory than the ingestor's is visible. func TestLogStartupShowsAbsoluteUsersDBPath(t *testing.T) { a, _ := newTestAuthService(t) a.set.dbPath = "users.db" var buf bytes.Buffer prev := log.Writer() log.SetOutput(&buf) defer log.SetOutput(prev) a.logStartup() want, err := filepath.Abs("users.db") if err != nil { t.Fatal(err) } if !strings.Contains(buf.String(), "[users] user management enabled: db="+want+",") { t.Fatalf("log line = %q, want the absolute path %q", buf.String(), want) } } func TestRenderLinesAndFooter(t *testing.T) { a, _ := newTestAuthService(t) m := a.render("x@example.org", "X", "notify", mailContent{subject: "S", greeting: "Hi", lines: []mailLine{{text: "n: offline", url: "https://e.org/#/nodes/ab"}}, footer: &mailLine{text: "Stop these mails:", url: "https://e.org/#/account/unsubscribe?token=t"}}) if !strings.Contains(m.HTML, ``) || !strings.Contains(m.Text, "- n: offline\n https://e.org/#/nodes/ab\n") || !strings.Contains(m.HTML, `Stop these mails: `) || !strings.Contains(m.Text, "Stop these mails:\nhttps://e.org/#/account/unsubscribe?token=t\n") || strings.Contains(m.Text, "If that was not you") { t.Fatalf("rendered = %q / %q", m.HTML, m.Text) } }