test(07-01): add failing tests for passwords, locale, and validation
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
46
bouncer/password_test.go
Normal file
46
bouncer/password_test.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package bouncer
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestPasswordHashAndCheck(t *testing.T) {
|
||||
hash, err := HashPassword(10, "secret")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !CheckPassword(hash, "secret") {
|
||||
t.Fatal("matching password rejected")
|
||||
}
|
||||
if CheckPassword(hash, "wrong") {
|
||||
t.Fatal("wrong password accepted")
|
||||
}
|
||||
if CheckPassword("not-a-hash", "secret") {
|
||||
t.Fatal("malformed hash must not panic or match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPasswordAcceptsPHPHash(t *testing.T) {
|
||||
// php -r 'echo password_hash("golem15-a1-check", PASSWORD_BCRYPT, ["cost"=>10]);'
|
||||
const phpHash = "$2y$10$vvjEAuqFJXs6lWVy1eo5FuTZZr84LrP8Oz2c6pzAw4f2pk6u2xV5W"
|
||||
if !CheckPassword(phpHash, "golem15-a1-check") {
|
||||
t.Fatal("PHP $2y$ hash rejected")
|
||||
}
|
||||
if CheckPassword(phpHash, "other") {
|
||||
t.Fatal("PHP hash matched the wrong password")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNeedsRehash(t *testing.T) {
|
||||
hash, err := HashPassword(10, "secret")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !NeedsRehash(hash, 12) {
|
||||
t.Fatal("lower cost must need rehash")
|
||||
}
|
||||
if NeedsRehash(hash, 10) || NeedsRehash(hash, 8) {
|
||||
t.Fatal("equal or higher cost must not need rehash")
|
||||
}
|
||||
if !NeedsRehash("not-a-hash", 10) {
|
||||
t.Fatal("unparseable hash must need rehash")
|
||||
}
|
||||
}
|
||||
@@ -135,6 +135,61 @@ func TestValidateBooleanNoop(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateEmailConfirmedDifferentMimes(t *testing.T) {
|
||||
errs, err := Validate(t.Context(), nil, nil, map[string]string{"email": "email"}, map[string]any{"email": "not-an-email"}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(errs["email"]) == 0 {
|
||||
t.Fatal("not-an-email must fail")
|
||||
}
|
||||
errs, err = Validate(t.Context(), nil, nil, map[string]string{"email": "email"}, map[string]any{"email": "a@b.com"}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(errs) != 0 {
|
||||
t.Fatalf("a@b.com = %v", errs)
|
||||
}
|
||||
|
||||
rules := map[string]string{"password": "confirmed"}
|
||||
errs, err = Validate(t.Context(), nil, nil, rules, map[string]any{
|
||||
"password": "secret", "password_confirmation": "secret",
|
||||
}, nil)
|
||||
if err != nil || len(errs) != 0 {
|
||||
t.Fatalf("confirmed match: %v %v", errs, err)
|
||||
}
|
||||
errs, err = Validate(t.Context(), nil, nil, rules, map[string]any{
|
||||
"password": "secret", "password_confirmation": "other",
|
||||
}, nil)
|
||||
if err != nil || len(errs["password"]) == 0 {
|
||||
t.Fatalf("confirmed mismatch: %v %v", errs, err)
|
||||
}
|
||||
|
||||
rules = map[string]string{"password": "different:current_password"}
|
||||
errs, err = Validate(t.Context(), nil, nil, rules, map[string]any{
|
||||
"password": "same", "current_password": "same",
|
||||
}, nil)
|
||||
if err != nil || len(errs["password"]) == 0 {
|
||||
t.Fatalf("different equal: %v %v", errs, err)
|
||||
}
|
||||
errs, err = Validate(t.Context(), nil, nil, rules, map[string]any{
|
||||
"password": "new", "current_password": "old",
|
||||
}, nil)
|
||||
if err != nil || len(errs) != 0 {
|
||||
t.Fatalf("different distinct: %v %v", errs, err)
|
||||
}
|
||||
|
||||
rules = map[string]string{"avatar": "mimes:jpeg,jpg,png,webp,gif"}
|
||||
errs, err = Validate(t.Context(), nil, nil, rules, map[string]any{"avatar": "PNG"}, nil)
|
||||
if err != nil || len(errs) != 0 {
|
||||
t.Fatalf("png: %v %v", errs, err)
|
||||
}
|
||||
errs, err = Validate(t.Context(), nil, nil, rules, map[string]any{"avatar": "svg"}, nil)
|
||||
if err != nil || len(errs["avatar"]) == 0 {
|
||||
t.Fatalf("svg: %v %v", errs, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateUnrecognizedRule(t *testing.T) {
|
||||
_, err := Validate(t.Context(), nil, nil, map[string]string{"name": "required|nope"}, map[string]any{"name": "x"}, nil)
|
||||
if err == nil || !strings.Contains(err.Error(), "nope") {
|
||||
|
||||
53
surf/locale_from_principal_test.go
Normal file
53
surf/locale_from_principal_test.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package surf
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"git.golem15.com/golem15/summercms/bouncer"
|
||||
"git.golem15.com/golem15/summercms/towel"
|
||||
)
|
||||
|
||||
func TestLocaleFromPrincipal(t *testing.T) {
|
||||
var got string
|
||||
var ok bool
|
||||
h := LocaleFromPrincipal(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
got, ok = towel.Locale(r.Context())
|
||||
}))
|
||||
|
||||
ctx := towel.WithLocale(t.Context(), "en")
|
||||
ctx = bouncer.WithUser(ctx, &bouncer.Principal{PreferredLocale: "pl"})
|
||||
req := httptest.NewRequest(http.MethodGet, "/", nil).WithContext(ctx)
|
||||
h.ServeHTTP(httptest.NewRecorder(), req)
|
||||
if !ok || got != "pl" {
|
||||
t.Fatalf("locale = %q ok=%t", got, ok)
|
||||
}
|
||||
|
||||
got, ok = "", false
|
||||
ctx = towel.WithLocale(t.Context(), "en")
|
||||
ctx = bouncer.WithUser(ctx, &bouncer.Principal{})
|
||||
req = httptest.NewRequest(http.MethodGet, "/", nil).WithContext(ctx)
|
||||
h.ServeHTTP(httptest.NewRecorder(), req)
|
||||
if !ok || got != "en" {
|
||||
t.Fatalf("empty preferred locale = %q ok=%t", got, ok)
|
||||
}
|
||||
|
||||
got, ok = "", false
|
||||
req = httptest.NewRequest(http.MethodGet, "/", nil).WithContext(towel.WithLocale(t.Context(), "de"))
|
||||
h.ServeHTTP(httptest.NewRecorder(), req)
|
||||
if !ok || got != "de" {
|
||||
t.Fatalf("no principal locale = %q ok=%t", got, ok)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildRouterRegistersLocaleFromPrincipal(t *testing.T) {
|
||||
r, err := BuildRouter(nil, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
mw, ok := r.named["locale.from-principal"]
|
||||
if !ok || mw.pluginID != "surf" || mw.fn == nil {
|
||||
t.Fatalf("registration ok=%t mw=%+v", ok, mw)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user