xtablo-source/backend/templates/auth_components_test.go
Arthur Belleville dcbc05b642
test(14): add Nyquist validation tests for AUTH-UI-01/02/03
auth_login_test.go: LoginPage renders AuthLayout structure (login-screen,
auth-card-shell, brand-logo, h1, auth-body, divider-pill), HTMX form
attributes, password not echoed.

auth_components_test.go: AnimatedBackground exactly 35 elements,
GoogleButton configured/unconfigured variants, AuthDivider or-pill.

handlers_auth_test.go: extend configured provider tests to assert
class="gsi-material-button" on the anchor element (AUTH-UI-03).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-16 20:43:31 +02:00

90 lines
2.7 KiB
Go

package templates
import (
"bytes"
"context"
"strings"
"testing"
)
// TestAnimatedBackground_Exactly35Elements verifies that AnimatedBackground
// renders exactly 35 decorative logo elements (AUTH-UI-03, T-14-01-03).
func TestAnimatedBackground_Exactly35Elements(t *testing.T) {
var buf bytes.Buffer
err := AnimatedBackground().Render(context.Background(), &buf)
if err != nil {
t.Fatalf("AnimatedBackground.Render: %v", err)
}
body := buf.String()
count := strings.Count(body, "background-logo")
if count != 35 {
t.Errorf("AnimatedBackground: got %d background-logo elements; want exactly 35", count)
}
}
// TestGoogleButton_ConfiguredRendersLink verifies that a configured GoogleButton
// renders a clickable anchor with the Material Design CSS class and start URL
// (AUTH-UI-03, D-G03).
func TestGoogleButton_ConfiguredRendersLink(t *testing.T) {
var buf bytes.Buffer
err := GoogleButton("/auth/google/start", true).Render(context.Background(), &buf)
if err != nil {
t.Fatalf("GoogleButton.Render (configured): %v", err)
}
body := buf.String()
for _, want := range []string{
`class="gsi-material-button"`,
`href="/auth/google/start"`,
"Sign in with Google",
} {
if !strings.Contains(body, want) {
t.Errorf("configured GoogleButton missing %q; body: %s", want, body)
}
}
if strings.Contains(body, "disabled") {
t.Errorf("configured GoogleButton must not contain 'disabled'; body: %s", body)
}
}
// TestGoogleButton_UnconfiguredRendersDisabledButton verifies that an
// unconfigured GoogleButton renders a disabled button element (no href)
// (AUTH-UI-03).
func TestGoogleButton_UnconfiguredRendersDisabledButton(t *testing.T) {
var buf bytes.Buffer
err := GoogleButton("", false).Render(context.Background(), &buf)
if err != nil {
t.Fatalf("GoogleButton.Render (unconfigured): %v", err)
}
body := buf.String()
for _, want := range []string{
`class="gsi-material-button" disabled`,
`aria-disabled="true"`,
} {
if !strings.Contains(body, want) {
t.Errorf("unconfigured GoogleButton missing %q; body: %s", want, body)
}
}
if strings.Contains(body, "href=") {
t.Errorf("unconfigured GoogleButton must not contain href=; body: %s", body)
}
}
// TestAuthDivider_RendersOrPill verifies that AuthDivider renders the "or"
// separator pill used between OAuth buttons and the email form (AUTH-UI-03).
func TestAuthDivider_RendersOrPill(t *testing.T) {
var buf bytes.Buffer
err := AuthDivider().Render(context.Background(), &buf)
if err != nil {
t.Fatalf("AuthDivider.Render: %v", err)
}
body := buf.String()
if !strings.Contains(body, "divider-pill") {
t.Errorf("AuthDivider missing 'divider-pill' CSS class; body: %s", body)
}
if !strings.Contains(body, "or") {
t.Errorf("AuthDivider missing 'or' label text; body: %s", body)
}
}