package middleware_test import ( "context" "encoding/base64" "io" "log/slog" "net/http" "net/http/httptest" "os" "strings" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/fx/fxtest" "sneak.berlin/go/webhooker/internal/config" "sneak.berlin/go/webhooker/internal/database" "sneak.berlin/go/webhooker/internal/middleware" "sneak.berlin/go/webhooker/internal/middleware/middlewaretest" "sneak.berlin/go/webhooker/internal/session" ) const testKeySize = 32 // testMiddleware creates a Middleware with minimal dependencies // for testing. It uses a real session.Session. func testMiddleware( t *testing.T, env string, ) (*middleware.Middleware, *session.Session) { t.Helper() return testMiddlewareWithIdleTimeout(t, env, 0) } // testMiddlewareWithIdleTimeout is testMiddleware with a // configurable session idle timeout, for the session-expiry tests. func testMiddlewareWithIdleTimeout( t *testing.T, env string, idleTimeout time.Duration, ) (*middleware.Middleware, *session.Session) { t.Helper() log := slog.New(slog.NewTextHandler( os.Stderr, &slog.HandlerOptions{Level: slog.LevelDebug}, )) cfg := &config.Config{ Environment: env, SessionIdleTimeout: idleTimeout, } sessManager := newTestSessionManager(t, cfg) m := middlewaretest.New(t, log, cfg, sessManager) return m, sessManager } // newTestSessionManager builds the real session.Session the // middleware tests run against, through session.New, with its key // in a main database of its own. func newTestSessionManager( t *testing.T, cfg *config.Config, ) *session.Session { t.Helper() discard := slog.New(slog.DiscardHandler) db, err := database.Open(t.TempDir(), discard) require.NoError(t, err) t.Cleanup(func() { _ = db.Close() }) lc := fxtest.NewLifecycle(t) sessManager, err := session.New(lc, session.Params{ Config: cfg, Database: db, Logger: discard, }) require.NoError(t, err) // The start hook reads the key from db and builds the cookie // store. lc.RequireStart() t.Cleanup(lc.RequireStop) return sessManager } // --- Logging Middleware Tests --- func TestLogging_SetsStatusCode(t *testing.T) { t.Parallel() m, _ := testMiddleware(t, config.EnvironmentDev) handler := m.Logging()(http.HandlerFunc( func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusCreated) _, err := w.Write([]byte("created")) if err != nil { return } }, )) req := httptest.NewRequestWithContext( context.Background(), http.MethodGet, "/test", nil) w := httptest.NewRecorder() handler.ServeHTTP(w, req) assert.Equal(t, http.StatusCreated, w.Code) assert.Equal(t, "created", w.Body.String()) } func TestLogging_DefaultStatusOK(t *testing.T) { t.Parallel() m, _ := testMiddleware(t, config.EnvironmentDev) handler := m.Logging()(http.HandlerFunc( func(w http.ResponseWriter, _ *http.Request) { _, err := w.Write([]byte("ok")) if err != nil { return } }, )) req := httptest.NewRequestWithContext( context.Background(), http.MethodGet, "/", nil) w := httptest.NewRecorder() handler.ServeHTTP(w, req) // When no explicit WriteHeader is called, default is 200 assert.Equal(t, http.StatusOK, w.Code) } func TestLogging_PassesThroughToNext(t *testing.T) { t.Parallel() m, _ := testMiddleware(t, config.EnvironmentDev) var called bool handler := m.Logging()(http.HandlerFunc( func(w http.ResponseWriter, _ *http.Request) { called = true w.WriteHeader(http.StatusOK) }, )) req := httptest.NewRequestWithContext( context.Background(), http.MethodPost, "/api/webhook", nil, ) w := httptest.NewRecorder() handler.ServeHTTP(w, req) assert.True( t, called, "logging middleware should call the next handler", ) } // --- LoggingResponseWriter Tests --- func TestLoggingResponseWriter_CapturesStatusCode(t *testing.T) { t.Parallel() w := httptest.NewRecorder() lrw := middleware.NewLoggingResponseWriterForTest(w) // Default should be 200 assert.Equal( t, http.StatusOK, middleware.LoggingResponseWriterStatusCode(lrw), ) // WriteHeader should capture the status code lrw.WriteHeader(http.StatusNotFound) assert.Equal( t, http.StatusNotFound, middleware.LoggingResponseWriterStatusCode(lrw), ) // Underlying writer should also get the status code assert.Equal(t, http.StatusNotFound, w.Code) } func TestLoggingResponseWriter_WriteDelegatesToUnderlying( t *testing.T, ) { t.Parallel() w := httptest.NewRecorder() lrw := middleware.NewLoggingResponseWriterForTest(w) n, err := lrw.Write([]byte("hello world")) require.NoError(t, err) assert.Equal(t, 11, n) assert.Equal(t, "hello world", w.Body.String()) } // --- CORS Middleware Tests --- func TestCORS_DevMode_AllowsAnyOrigin(t *testing.T) { t.Parallel() m, _ := testMiddleware(t, config.EnvironmentDev) handler := m.CORS()(http.HandlerFunc( func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) }, )) // Preflight request req := httptest.NewRequestWithContext( context.Background(), http.MethodOptions, "/api/test", nil, ) req.Header.Set("Origin", "http://localhost:3000") req.Header.Set("Access-Control-Request-Method", "POST") w := httptest.NewRecorder() handler.ServeHTTP(w, req) // In dev mode, CORS should allow any origin assert.Equal( t, "*", w.Header().Get("Access-Control-Allow-Origin"), ) } func TestCORS_ProdMode_NoOp(t *testing.T) { t.Parallel() m, _ := testMiddleware(t, config.EnvironmentProd) var called bool handler := m.CORS()(http.HandlerFunc( func(w http.ResponseWriter, _ *http.Request) { called = true w.WriteHeader(http.StatusOK) }, )) req := httptest.NewRequestWithContext( context.Background(), http.MethodGet, "/api/test", nil, ) req.Header.Set("Origin", "http://evil.com") w := httptest.NewRecorder() handler.ServeHTTP(w, req) assert.True( t, called, "prod CORS middleware should pass through to handler", ) // In prod, no CORS headers should be set (no-op middleware) assert.Empty( t, w.Header().Get("Access-Control-Allow-Origin"), "prod mode should not set CORS headers", ) } // --- RequireAuth Middleware Tests --- func TestRequireAuth_NoSession_RedirectsToLogin(t *testing.T) { t.Parallel() m, _ := testMiddleware(t, config.EnvironmentDev) var called bool handler := m.RequireAuth()(http.HandlerFunc( func(_ http.ResponseWriter, _ *http.Request) { called = true }, )) req := httptest.NewRequestWithContext( context.Background(), http.MethodGet, "/dashboard", nil, ) w := httptest.NewRecorder() handler.ServeHTTP(w, req) assert.False( t, called, "handler should not be called for "+ "unauthenticated request", ) assert.Equal(t, http.StatusSeeOther, w.Code) assert.Equal( t, "/pages/login?next=%2Fdashboard", w.Header().Get("Location"), ) } // TestRequireAuth_LoginRedirectCarriesOnlyAGet pins what the login // redirect carries: a GET's path and query, so logging in can return // there, and nothing for a POST, which a redirect cannot repeat. func TestRequireAuth_LoginRedirectCarriesOnlyAGet(t *testing.T) { t.Parallel() m, _ := testMiddleware(t, config.EnvironmentDev) handler := m.RequireAuth()(http.HandlerFunc( func(_ http.ResponseWriter, _ *http.Request) {}, )) get := httptest.NewRequestWithContext( context.Background(), http.MethodGet, "/hook/abc/events?page=2", nil, ) w := httptest.NewRecorder() handler.ServeHTTP(w, get) assert.Equal( t, "/pages/login?next=%2Fhook%2Fabc%2Fevents%3Fpage%3D2", w.Header().Get("Location"), ) post := httptest.NewRequestWithContext( context.Background(), http.MethodPost, "/hook/abc/delete", nil, ) w = httptest.NewRecorder() handler.ServeHTTP(w, post) assert.Equal(t, "/pages/login", w.Header().Get("Location")) } // TestRequireAuth_LoginRedirectLeavesOutALongURL: a GET whose path // and query are longer than the login page accepts goes to the plain // login page, so a long URL does not make the redirect long. func TestRequireAuth_LoginRedirectLeavesOutALongURL(t *testing.T) { t.Parallel() m, _ := testMiddleware(t, config.EnvironmentDev) handler := m.RequireAuth()(http.HandlerFunc( func(_ http.ResponseWriter, _ *http.Request) {}, )) atLimit := "/" + strings.Repeat("a", middleware.MaxNextBytes-1) get := httptest.NewRequestWithContext( context.Background(), http.MethodGet, atLimit, nil, ) w := httptest.NewRecorder() handler.ServeHTTP(w, get) assert.Equal( t, "/pages/login?next=%2F"+atLimit[1:], w.Header().Get("Location"), ) get = httptest.NewRequestWithContext( context.Background(), http.MethodGet, atLimit+"a", nil, ) w = httptest.NewRecorder() handler.ServeHTTP(w, get) assert.Equal(t, "/pages/login", w.Header().Get("Location")) } func TestRequireAuth_AuthenticatedSession_PassesThrough( t *testing.T, ) { t.Parallel() m, sessManager := testMiddleware(t, config.EnvironmentDev) var called bool handler := m.RequireAuth()(http.HandlerFunc( func(_ http.ResponseWriter, _ *http.Request) { called = true }, )) // Create an authenticated session by making a request, // setting session data, and saving the session cookie setupReq := httptest.NewRequestWithContext( context.Background(), http.MethodGet, "/setup", nil, ) setupW := httptest.NewRecorder() sess, err := sessManager.Get(setupReq) require.NoError(t, err) sessManager.SetUser(sess, "user-123", "testuser") require.NoError(t, sessManager.Save(setupReq, setupW, sess)) // Extract the cookie from the setup response cookies := setupW.Result().Cookies() require.NotEmpty(t, cookies, "session cookie should be set") // Make the actual request with the session cookie req := httptest.NewRequestWithContext( context.Background(), http.MethodGet, "/dashboard", nil, ) for _, c := range cookies { req.AddCookie(c) } w := httptest.NewRecorder() handler.ServeHTTP(w, req) assert.True( t, called, "handler should be called for authenticated request", ) } func TestRequireAuth_UnauthenticatedSession_RedirectsToLogin( t *testing.T, ) { t.Parallel() m, sessManager := testMiddleware(t, config.EnvironmentDev) var called bool handler := m.RequireAuth()(http.HandlerFunc( func(_ http.ResponseWriter, _ *http.Request) { called = true }, )) // Create a session but don't authenticate it setupReq := httptest.NewRequestWithContext( context.Background(), http.MethodGet, "/setup", nil, ) setupW := httptest.NewRecorder() sess, err := sessManager.Get(setupReq) require.NoError(t, err) // Don't call SetUser -- session exists but is not // authenticated require.NoError(t, sessManager.Save(setupReq, setupW, sess)) cookies := setupW.Result().Cookies() require.NotEmpty(t, cookies) req := httptest.NewRequestWithContext( context.Background(), http.MethodGet, "/dashboard", nil, ) for _, c := range cookies { req.AddCookie(c) } w := httptest.NewRecorder() handler.ServeHTTP(w, req) assert.False( t, called, "handler should not be called for "+ "unauthenticated session", ) assert.Equal(t, http.StatusSeeOther, w.Code) assert.Equal( t, "/pages/login?next=%2Fdashboard", w.Header().Get("Location"), ) } // --- RequireAuth Session Expiry Tests --- // loginCookies authenticates a new session and returns the cookies // a browser would then send back. func loginCookies( t *testing.T, sessManager *session.Session, ) []*http.Cookie { t.Helper() req := httptest.NewRequestWithContext( context.Background(), http.MethodGet, "/login", nil) w := httptest.NewRecorder() sess, err := sessManager.Get(req) require.NoError(t, err) sessManager.SetUser(sess, "user-123", "testuser") require.NoError(t, sessManager.Save(req, w, sess)) cookies := w.Result().Cookies() require.NotEmpty(t, cookies, "session cookie should be set") return cookies } // runAuthed sends a request carrying cookies through RequireAuth // and reports whether the protected handler ran, plus the response. func runAuthed( t *testing.T, m *middleware.Middleware, cookies []*http.Cookie, ) (bool, *httptest.ResponseRecorder) { t.Helper() var called bool handler := m.RequireAuth()(http.HandlerFunc( func(_ http.ResponseWriter, _ *http.Request) { called = true }, )) req := httptest.NewRequestWithContext( context.Background(), http.MethodGet, "/dashboard", nil, ) for _, c := range cookies { req.AddCookie(c) } w := httptest.NewRecorder() handler.ServeHTTP(w, req) return called, w } // sessionCookies filters a response's cookies down to the session // cookie, so tests can tell whether the session was re-issued. func sessionCookies( w *httptest.ResponseRecorder, ) []*http.Cookie { var out []*http.Cookie for _, c := range w.Result().Cookies() { if c.Name == session.SessionName { out = append(out, c) } } return out } // aged re-issues the session cookie in cookies with both of its // timestamps moved back by d: the cookie as it stands once d has // passed, so session expiry can be tested without sleeping. func aged( t *testing.T, sessManager *session.Session, cookies []*http.Cookie, d time.Duration, ) []*http.Cookie { t.Helper() req := httptest.NewRequestWithContext( context.Background(), http.MethodGet, "/", nil) for _, c := range cookies { req.AddCookie(c) } sess, err := sessManager.Get(req) require.NoError(t, err) for _, key := range []string{session.CreatedAtKey, session.LastSeenKey} { at, ok := sess.Values[key].(int64) require.True(t, ok, "the session has no %s", key) sess.Values[key] = at - int64(d/time.Second) } w := httptest.NewRecorder() require.NoError(t, sessManager.Save(req, w, sess)) return sessionCookies(w) } func TestRequireAuth_IdleExpiredSession_RedirectsToLogin( t *testing.T, ) { t.Parallel() idle := time.Hour m, sessManager := testMiddlewareWithIdleTimeout( t, config.EnvironmentDev, idle, ) cookies := aged(t, sessManager, loginCookies(t, sessManager), idle) called, w := runAuthed(t, m, cookies) assert.False( t, called, "handler should not run for an idle-expired session", ) assert.Equal(t, http.StatusSeeOther, w.Code) assert.Equal( t, "/pages/login?next=%2Fdashboard", w.Header().Get("Location"), ) assert.Empty( t, sessionCookies(w), "an expired session must not be refreshed", ) } func TestRequireAuth_RefreshesIdleDeadlineOnActivity( t *testing.T, ) { t.Parallel() idle := time.Hour m, sessManager := testMiddlewareWithIdleTimeout( t, config.EnvironmentDev, idle, ) // Activity halfway through the idle window. cookies := aged(t, sessManager, loginCookies(t, sessManager), idle/2) called, w := runAuthed(t, m, cookies) require.True(t, called, "handler should run while valid") refreshed := sessionCookies(w) require.NotEmpty( t, refreshed, "activity should re-issue the session cookie", ) // Past the original deadline. The refreshed cookie is still // good; the original one is not. A minute short of the idle // window leaves room for the real clock, which the session // reads, to tick on while the test runs. later := idle - time.Minute calledRefreshed, _ := runAuthed( t, m, aged(t, sessManager, refreshed, later), ) assert.True( t, calledRefreshed, "refreshed session should outlive the original deadline", ) calledStale, staleW := runAuthed( t, m, aged(t, sessManager, cookies, later), ) assert.False( t, calledStale, "the pre-refresh cookie carries the old idle deadline", ) assert.Equal(t, http.StatusSeeOther, staleW.Code) } func TestRequireAuth_UnauthenticatedRequestDoesNotRefresh( t *testing.T, ) { t.Parallel() m, sessManager := testMiddlewareWithIdleTimeout( t, config.EnvironmentDev, time.Hour, ) // A session cookie that exists but was never authenticated. req := httptest.NewRequestWithContext( context.Background(), http.MethodGet, "/setup", nil) setupW := httptest.NewRecorder() sess, err := sessManager.Get(req) require.NoError(t, err) require.NoError(t, sessManager.Save(req, setupW, sess)) cookies := setupW.Result().Cookies() require.NotEmpty(t, cookies) called, w := runAuthed(t, m, cookies) assert.False(t, called) assert.Empty( t, sessionCookies(w), "an unauthenticated request must not stamp the session", ) } // --- NoCache Middleware Tests --- func TestNoCache_SetsHeaders(t *testing.T) { t.Parallel() m, _ := testMiddleware(t, config.EnvironmentDev) var called bool handler := m.NoCache()(http.HandlerFunc( func(w http.ResponseWriter, _ *http.Request) { called = true w.WriteHeader(http.StatusOK) }, )) req := httptest.NewRequestWithContext( context.Background(), http.MethodGet, "/hooks", nil, ) w := httptest.NewRecorder() handler.ServeHTTP(w, req) assert.True( t, called, "NoCache middleware should call the next handler", ) assert.Equal( t, "no-store", w.Header().Get("Cache-Control"), ) assert.Equal( t, "no-cache", w.Header().Get("Pragma"), ) } // --- MaxBodySize Middleware Tests --- const testBodyLimit int64 = 64 // maxBodySizeResult is what runMaxBodySize's sentinel handler saw, // together with the response. type maxBodySizeResult struct { called bool read int readErr error response *httptest.ResponseRecorder } // runMaxBodySize wraps a sentinel handler in MaxBodySize with // testBodyLimit and serves req through it. The sentinel records // whether it ran and how much of the body it managed to read, so // tests can distinguish "never reached" from "reached but truncated". func runMaxBodySize( t *testing.T, req *http.Request, ) *maxBodySizeResult { t.Helper() m, _ := testMiddleware(t, config.EnvironmentDev) res := &maxBodySizeResult{response: httptest.NewRecorder()} handler := m.MaxBodySize(testBodyLimit)(http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { res.called = true body, err := io.ReadAll(r.Body) res.read = len(body) res.readErr = err w.WriteHeader(http.StatusOK) }, )) handler.ServeHTTP(res.response, req) return res } // postWithBody builds a POST request whose Content-Length is // accurate for the given payload size. func postWithBody(size int) *http.Request { req := httptest.NewRequestWithContext( context.Background(), http.MethodPost, "/pages/login", strings.NewReader(strings.Repeat("a", size)), ) req.Header.Set( "Content-Type", "application/x-www-form-urlencoded", ) return req } func TestMaxBodySize_DeclaredOversize_413AndHandlerNotReached( t *testing.T, ) { t.Parallel() res := runMaxBodySize(t, postWithBody(int(testBodyLimit)+1)) assert.False( t, res.called, "handler must not be reached for an oversized body", ) assert.Equal( t, http.StatusRequestEntityTooLarge, res.response.Code, ) } func TestMaxBodySize_AtLimit_PassesThrough(t *testing.T) { t.Parallel() res := runMaxBodySize(t, postWithBody(int(testBodyLimit))) assert.True( t, res.called, "handler should be reached for a body at the limit", ) require.NoError(t, res.readErr) assert.Equal(t, int(testBodyLimit), res.read) assert.Equal(t, http.StatusOK, res.response.Code) } func TestMaxBodySize_UnderLimit_PassesThrough(t *testing.T) { t.Parallel() res := runMaxBodySize(t, postWithBody(1)) assert.True(t, res.called) require.NoError(t, res.readErr) assert.Equal(t, 1, res.read) assert.Equal(t, http.StatusOK, res.response.Code) } func TestMaxBodySize_GetWithOversizeBody_NotCapped(t *testing.T) { t.Parallel() req := httptest.NewRequestWithContext( context.Background(), http.MethodGet, "/pages/login", strings.NewReader( strings.Repeat("a", int(testBodyLimit)+1), ), ) res := runMaxBodySize(t, req) assert.True( t, res.called, "GET requests are not subject to the POST body cap", ) require.NoError(t, res.readErr) assert.Equal(t, int(testBodyLimit)+1, res.read) } // TestMaxBodySize_UndeclaredOversize_TruncatedAtCap covers the // chunked / lying-Content-Length case: there is nothing to check up // front, so the request reaches the handler but MaxBytesReader // hard-caps the body and the read fails at the limit. func TestMaxBodySize_UndeclaredOversize_TruncatedAtCap( t *testing.T, ) { t.Parallel() req := postWithBody(int(testBodyLimit) + 1) // Simulate a chunked request: no declared length. req.ContentLength = -1 res := runMaxBodySize(t, req) assert.True( t, res.called, "an undeclared oversize body cannot be rejected up front", ) require.Error( t, res.readErr, "reading past the cap must fail", ) assert.Equal( t, int(testBodyLimit), res.read, "the handler must not see more than the cap", ) } // --- Helper Tests --- func TestIpFromHostPort(t *testing.T) { t.Parallel() tests := []struct { name string input string expected string }{ {"ipv4 with port", "192.168.1.1:8080", "192.168.1.1"}, {"ipv6 with port", "[::1]:8080", "::1"}, {"invalid format", "not-a-host-port", ""}, {"empty string", "", ""}, {"localhost", "127.0.0.1:80", "127.0.0.1"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { t.Parallel() result := middleware.IPFromHostPort(tt.input) assert.Equal(t, tt.expected, result) }) } } // --- MetricsAuth Tests --- // metricsAuthMiddleware creates a Middleware configured for // metrics auth testing. This helper de-duplicates the setup in // metrics auth test functions. func metricsAuthMiddleware( t *testing.T, ) *middleware.Middleware { t.Helper() log := slog.New(slog.NewTextHandler( os.Stderr, &slog.HandlerOptions{Level: slog.LevelDebug}, )) cfg := &config.Config{ Environment: config.EnvironmentDev, MetricsUsername: "admin", MetricsPassword: "secret", } return middlewaretest.New( t, log, cfg, newTestSessionManager(t, cfg), ) } // runMetricsAuthRequest sends a GET /metrics request with the // given basic-auth password through MetricsAuth and reports // whether the wrapped handler ran plus the recorded response. func runMetricsAuthRequest( t *testing.T, password string, ) (bool, *httptest.ResponseRecorder) { t.Helper() m := metricsAuthMiddleware(t) var called bool handler := m.MetricsAuth()(http.HandlerFunc( func(w http.ResponseWriter, _ *http.Request) { called = true w.WriteHeader(http.StatusOK) }, )) req := httptest.NewRequestWithContext( context.Background(), http.MethodGet, "/metrics", nil, ) req.SetBasicAuth("admin", password) w := httptest.NewRecorder() handler.ServeHTTP(w, req) return called, w } func TestMetricsAuth_ValidCredentials(t *testing.T) { t.Parallel() called, w := runMetricsAuthRequest(t, "secret") assert.True( t, called, "handler should be called with valid basic auth", ) assert.Equal(t, http.StatusOK, w.Code) } func TestMetricsAuth_InvalidCredentials(t *testing.T) { t.Parallel() called, w := runMetricsAuthRequest(t, "wrong-password") assert.False( t, called, "handler should not be called with invalid basic auth", ) assert.Equal(t, http.StatusUnauthorized, w.Code) } func TestMetricsAuth_NoCredentials(t *testing.T) { t.Parallel() m := metricsAuthMiddleware(t) var called bool handler := m.MetricsAuth()(http.HandlerFunc( func(_ http.ResponseWriter, _ *http.Request) { called = true }, )) req := httptest.NewRequestWithContext( context.Background(), http.MethodGet, "/metrics", nil, ) // No basic auth header w := httptest.NewRecorder() handler.ServeHTTP(w, req) assert.False( t, called, "handler should not be called without credentials", ) assert.Equal(t, http.StatusUnauthorized, w.Code) } // --- CORS Dev Mode Detailed Tests --- func TestCORS_DevMode_AllowsMethods(t *testing.T) { t.Parallel() m, _ := testMiddleware(t, config.EnvironmentDev) handler := m.CORS()(http.HandlerFunc( func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) }, )) // Preflight for POST req := httptest.NewRequestWithContext( context.Background(), http.MethodOptions, "/api/webhooks", nil, ) req.Header.Set("Origin", "http://localhost:5173") req.Header.Set("Access-Control-Request-Method", "POST") w := httptest.NewRecorder() handler.ServeHTTP(w, req) allowMethods := w.Header().Get("Access-Control-Allow-Methods") assert.Contains(t, allowMethods, "POST") } // --- Base64 key validation for completeness --- func TestSessionKeyFormat(t *testing.T) { t.Parallel() // Verify that the session initialization correctly validates // key format. A proper 32-byte key encoded as base64 should // work. key := make([]byte, testKeySize) for i := range key { key[i] = byte(i + 1) } encoded := base64.StdEncoding.EncodeToString(key) decoded, err := base64.StdEncoding.DecodeString(encoded) require.NoError(t, err) assert.Len(t, decoded, testKeySize) }