113 lines
4.0 KiB
Go
113 lines
4.0 KiB
Go
package user
|
|
|
|
import (
|
|
"context"
|
|
"net/url"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.golem15.com/golem15/fonoteka/plugins/golem15/user/controllers"
|
|
"git.golem15.com/golem15/fonoteka/plugins/golem15/user/models"
|
|
"git.golem15.com/golem15/summercms/backpack"
|
|
"git.golem15.com/golem15/summercms/postcard"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type recordingMail struct {
|
|
inner postcard.Mailer
|
|
msgs []postcard.Message
|
|
}
|
|
|
|
func (r *recordingMail) Send(ctx context.Context, msg postcard.Message) error {
|
|
r.msgs = append(r.msgs, msg)
|
|
if r.inner == nil {
|
|
return nil
|
|
}
|
|
return r.inner.Send(ctx, msg)
|
|
}
|
|
|
|
func TestMail(t *testing.T) {
|
|
app, gdb := sessionApp(t, "0s")
|
|
disableRegisterThrottle(t, app)
|
|
if err := app.Config.Set("golem15.user.activation.activate_mode", "user"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
rec, mem := publishMemoryMail(t, app)
|
|
|
|
postRegister(t, app, "198.51.100.10", `{"email":"mail-pl@example.test","password":"correct-horse","name":"Ada","preferred_locale":"pl"}`)
|
|
postRegister(t, app, "198.51.100.11", `{"email":"mail-en@example.test","password":"correct-horse","name":"Grace","preferred_locale":"en"}`)
|
|
assertTemplate(t, rec, "golem15.user::mail.activate", "mail-pl@example.test")
|
|
assertTemplate(t, rec, "golem15.user::mail.activate-en", "mail-en@example.test")
|
|
for _, msg := range rec.msgs {
|
|
if !strings.HasPrefix(msg.Template, "golem15.user::mail.activate") {
|
|
continue
|
|
}
|
|
link, _ := msg.Vars["link"].(string)
|
|
code, _ := msg.Vars["code"].(string)
|
|
decoded, err := url.QueryUnescape(link)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if link == "" || code == "" || !strings.Contains(decoded, code) {
|
|
t.Fatalf("activate vars template=%s link=%q code=%q", msg.Template, link, code)
|
|
}
|
|
}
|
|
if len(mem.Messages()) < 2 {
|
|
t.Fatalf("memory driver recorded %d messages", len(mem.Messages()))
|
|
}
|
|
|
|
before := len(rec.msgs)
|
|
postJSON(t, controllers.ForgotPassword(app), "/_user/api/v1/forgot-password", `{"email":"mail-pl@example.test"}`)
|
|
postJSON(t, controllers.ForgotPassword(app), "/_user/api/v1/forgot-password", `{"email":"mail-en@example.test"}`)
|
|
assertTemplate(t, rec, "golem15.user::mail.restore", "mail-pl@example.test")
|
|
assertTemplate(t, rec, "golem15.user::mail.restore-en", "mail-en@example.test")
|
|
if len(mem.Messages()) < before+2 {
|
|
t.Fatalf("memory driver recorded %d messages after restore", len(mem.Messages()))
|
|
}
|
|
|
|
softDelete(t, gdb, "react-pl@example.test", "pl")
|
|
softDelete(t, gdb, "react-en@example.test", "en")
|
|
postJSON(t, controllers.Login(app), "/_user/api/v1/login", `{"email":"react-pl@example.test","password":"correct-horse"}`)
|
|
postJSON(t, controllers.Login(app), "/_user/api/v1/login", `{"email":"react-en@example.test","password":"correct-horse"}`)
|
|
assertTemplate(t, rec, "golem15.user::mail.reactivate", "react-pl@example.test")
|
|
assertTemplate(t, rec, "golem15.user::mail.reactivate-en", "react-en@example.test")
|
|
}
|
|
|
|
func publishMemoryMail(t *testing.T, app *backpack.App) (*recordingMail, *postcard.MemoryDriver) {
|
|
t.Helper()
|
|
cat := postcard.NewCatalog()
|
|
p := &Plugin{}
|
|
if err := cat.Register(p.ID(), p.MailTemplatesFS(), p.MailTemplates(), p.MailLayouts()); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
mem := postcard.NewMemoryDriver()
|
|
inner := postcard.NewMailer(cat, mem, postcard.Options{From: "noreply@example.test"})
|
|
rec := &recordingMail{inner: inner}
|
|
if err := app.Publish[postcard.Mailer](rec); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return rec, mem
|
|
}
|
|
|
|
func assertTemplate(t *testing.T, rec *recordingMail, template, to string) {
|
|
t.Helper()
|
|
for _, msg := range rec.msgs {
|
|
if msg.Template == template && len(msg.To) == 1 && msg.To[0] == to {
|
|
return
|
|
}
|
|
}
|
|
t.Fatalf("missing send %s to %s in %d messages", template, to, len(rec.msgs))
|
|
}
|
|
|
|
func softDelete(t *testing.T, gdb *gorm.DB, email, locale string) {
|
|
t.Helper()
|
|
user := insertUser(t, gdb, email, "correct-horse")
|
|
if err := gdb.Model(user).Update("preferred_locale", locale).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := gdb.Model(&models.User{}).Where("id = ?", user.ID).Update("deleted_at", time.Now()).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|