94 lines
2.7 KiB
Go
94 lines
2.7 KiB
Go
package mujica
|
|
|
|
import (
|
|
"bytes"
|
|
"log/slog"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/egoist/mygo/ui"
|
|
)
|
|
|
|
// accountLogs records every debug log until the test ends.
|
|
func accountLogs(t *testing.T) *bytes.Buffer {
|
|
t.Helper()
|
|
var b bytes.Buffer
|
|
saved := slog.Default()
|
|
slog.SetDefault(slog.New(slog.NewTextHandler(&b, &slog.HandlerOptions{Level: slog.LevelDebug})))
|
|
t.Cleanup(func() { slog.SetDefault(saved) })
|
|
return &b
|
|
}
|
|
|
|
type loginCall struct {
|
|
account, password string
|
|
remember bool
|
|
}
|
|
|
|
func loginTester(s *LoginFormState, calls *[]loginCall, disabled *bool) *ui.Tester {
|
|
return accountTester(420, 400, func(c *ui.Context) {
|
|
LoginForm(c, s, LoginFormOptions{Disabled: *disabled, OnSubmit: func(a, p string, r bool) {
|
|
*calls = append(*calls, loginCall{a, p, r})
|
|
}})
|
|
})
|
|
}
|
|
|
|
func TestLoginFormSubmitsOnceThroughCallback(t *testing.T) {
|
|
logs := accountLogs(t)
|
|
const secret = "s3cret-Sakiko"
|
|
var s LoginFormState
|
|
var calls []loginCall
|
|
disabled := false
|
|
tt := loginTester(&s, &calls, &disabled)
|
|
_ = tt.Click("Email or username")
|
|
tt.Type(" sakiko@court ")
|
|
_ = tt.Click("Password")
|
|
tt.Type(secret)
|
|
_ = tt.Click("Remember me")
|
|
tt.Key(ui.Shift, ui.KeyTab)
|
|
tt.Key(ui.Shift, ui.KeyTab)
|
|
tt.Key(0, ui.KeyEnter)
|
|
_ = tt.Click("Sign in")
|
|
if len(calls) != 1 || calls[0].account != "sakiko@court" || calls[0].password != secret || !calls[0].remember {
|
|
t.Fatalf("%d calls", len(calls))
|
|
}
|
|
if strings.Contains(logs.String(), secret) {
|
|
t.Fatal("the password reached the log")
|
|
}
|
|
s.EndSubmit("Too many attempts. Try again in 5 minutes.")
|
|
tt.Frame()
|
|
if !tt.HasText("Too many attempts. Try again in 5 minutes.") || s.password != "" || s.Account != " sakiko@court " {
|
|
t.Fatalf("shown %v wiped %v account %q", tt.HasText("Too many attempts. Try again in 5 minutes."), s.password == "", s.Account)
|
|
}
|
|
}
|
|
|
|
func TestLoginFormRequiresBothAndBlocksDisabled(t *testing.T) {
|
|
var s LoginFormState
|
|
var calls []loginCall
|
|
disabled := false
|
|
tt := loginTester(&s, &calls, &disabled)
|
|
_ = tt.Click("Sign in")
|
|
if len(calls) != 0 || !tt.HasText("Required") || !tt.Focused("Email or username") {
|
|
t.Fatalf("empty submit: %d calls", len(calls))
|
|
}
|
|
tt.Type("uika")
|
|
tt.Key(0, ui.KeyEnter)
|
|
if len(calls) != 0 || !tt.Focused("Password") {
|
|
t.Fatal("submitted without a password")
|
|
}
|
|
disabled = true
|
|
tt.Type("pw")
|
|
_ = tt.Click("Sign in")
|
|
if len(calls) != 0 || s.password != "" {
|
|
t.Fatal("disabled form took input or submitted")
|
|
}
|
|
}
|
|
|
|
func TestLoginFormSnapshot(t *testing.T) {
|
|
snapshot(t, "login_form", 400, 330, func(c *ui.Context) {
|
|
s := ui.Local(c.Root(), "s", func() LoginFormState {
|
|
return LoginFormState{Account: "sakiko@court", err: "Wrong account or password."}
|
|
})
|
|
LoginForm(c, s, LoginFormOptions{OnSubmit: func(string, string, bool) {}})
|
|
})
|
|
}
|