test(web): cover the /welcome landing page and its routing
Add a configurable fakeAuth (StubAuth can't express the logged-out case) and assert: /welcome renders the logged-out CTA with no session and the logged-in controls with one, unauthenticated / redirects to /welcome, unauthenticated deep links redirect to /auth/login, and an authenticated root still renders the list. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,92 @@
|
|||||||
|
package web_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"gitea.d-ma.be/mathias/tapir/internal/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
// fakeAuth is a configurable web.Auth for the landing-page tests: it reports a
|
||||||
|
// fixed (user, ok) from CurrentUser and, when logged out, replicates DexAuth's
|
||||||
|
// redirect split in Middleware — bare root → /welcome, deeper paths → login.
|
||||||
|
// StubAuth can't express the logged-out case (it allows everything), so the
|
||||||
|
// welcome routing needs this.
|
||||||
|
type fakeAuth struct {
|
||||||
|
user web.User
|
||||||
|
ok bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f fakeAuth) CurrentUser(*http.Request) (web.User, bool) { return f.user, f.ok }
|
||||||
|
func (f fakeAuth) Routes() http.Handler { return http.NewServeMux() }
|
||||||
|
|
||||||
|
func (f fakeAuth) Middleware(h http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if f.ok {
|
||||||
|
h.ServeHTTP(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if r.URL.Path == "/" {
|
||||||
|
http.Redirect(w, r, "/welcome", http.StatusFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
http.Redirect(w, r, "/auth/login", http.StatusFound)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// appWithAuth builds an App with a given Auth but no store wiring — enough for
|
||||||
|
// the /welcome page (which never touches the store) and the unauthenticated
|
||||||
|
// redirect paths (which never reach a handler).
|
||||||
|
func appWithAuth(auth web.Auth) *web.App {
|
||||||
|
return &web.App{Auth: auth}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWelcomeLoggedOut(t *testing.T) {
|
||||||
|
app := appWithAuth(fakeAuth{ok: false})
|
||||||
|
rec := do(t, app, httptest.NewRequest(http.MethodGet, "/welcome", nil))
|
||||||
|
|
||||||
|
require.Equal(t, http.StatusOK, rec.Code)
|
||||||
|
html := body(t, rec)
|
||||||
|
require.Contains(t, html, "Get Started", "logged-out CTA present")
|
||||||
|
require.Contains(t, html, `href="/auth/login"`, "CTA links into the Dex flow")
|
||||||
|
require.NotContains(t, html, "Go to my Tapir", "no logged-in controls")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWelcomeLoggedIn(t *testing.T) {
|
||||||
|
app := appWithAuth(fakeAuth{user: web.User{Subject: "s", Email: "me@d-ma.be"}, ok: true})
|
||||||
|
rec := do(t, app, httptest.NewRequest(http.MethodGet, "/welcome", nil))
|
||||||
|
|
||||||
|
require.Equal(t, http.StatusOK, rec.Code)
|
||||||
|
html := body(t, rec)
|
||||||
|
require.Contains(t, html, "Go to my Tapir", "logged-in CTA present")
|
||||||
|
require.Contains(t, html, `href="/"`, "links back into the app")
|
||||||
|
require.Contains(t, html, "me@d-ma.be", "greets by email")
|
||||||
|
require.NotContains(t, html, "Get Started", "no logged-out CTA")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnauthenticatedRootRedirectsToWelcome(t *testing.T) {
|
||||||
|
app := appWithAuth(fakeAuth{ok: false})
|
||||||
|
rec := do(t, app, httptest.NewRequest(http.MethodGet, "/", nil))
|
||||||
|
|
||||||
|
require.Equal(t, http.StatusFound, rec.Code)
|
||||||
|
require.Equal(t, "/welcome", rec.Header().Get("Location"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnauthenticatedDeepLinkRedirectsToLogin(t *testing.T) {
|
||||||
|
app := appWithAuth(fakeAuth{ok: false})
|
||||||
|
rec := do(t, app, httptest.NewRequest(http.MethodGet, "/v/some-id", nil))
|
||||||
|
|
||||||
|
require.Equal(t, http.StatusFound, rec.Code)
|
||||||
|
require.Equal(t, "/auth/login", rec.Header().Get("Location"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAuthenticatedRootRendersList(t *testing.T) {
|
||||||
|
app := newApp(t)
|
||||||
|
resetDB(t, rawPool(t))
|
||||||
|
rec := do(t, app, httptest.NewRequest(http.MethodGet, "/", nil))
|
||||||
|
require.Equal(t, http.StatusOK, rec.Code)
|
||||||
|
require.Contains(t, body(t, rec), "<html", "authenticated root still renders the list page")
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user