Prefix replacement of the old application-nested module path in go.mod and every import. No identifier, string, table, migration ID, config key or comment changes.
113 lines
3.9 KiB
Go
113 lines
3.9 KiB
Go
package user
|
|
|
|
import (
|
|
"context"
|
|
"net/url"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.golem15.com/golem15/sm-user-plugin/controllers"
|
|
"git.golem15.com/golem15/sm-user-plugin/models"
|
|
"git.golem15.com/golem15/summercms/modules/backpack"
|
|
"git.golem15.com/golem15/summercms/modules/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)
|
|
}
|
|
}
|