package test import ( "RenewCMS/api/handlers/auth" validator "RenewCMS/api/pkg/validator" "RenewCMS/internal/domain/user" "RenewCMS/internal/infrastructure/useCases" "bytes" "net/http" "net/http/httptest" "testing" "time" "github.com/go-chi/chi/v5" "github.com/go-chi/jwtauth/v5" ) func newLoginLogoutCookieRouter(userRepo *mockUserRepo, mailRepo *mockMailRepo, token *jwtauth.JWTAuth) *chi.Mux { hasher := &stubHasher{} loginHandler := auth.NewLoginHandler( token, useCases.NewCreateUserUseCase(userRepo, hasher, mailRepo, "https://cms.example.com", discardRecorder), useCases.NewAuthenticateUserUseCase(userRepo, hasher, discardRecorder), true, ) r := chi.NewRouter() r.Post("/login", loginHandler.Login) r.Post("/logout", loginHandler.Logout) return r } func TestLoginSetsA24HourJwtCookieAndLogoutClearsIt(t *testing.T) { validator.InitValidator() token := jwtauth.New("HS256", []byte("test-secret"), nil) t.Run("Login sets a jwt cookie that expires about 24 hours from now", func(t *testing.T) { repo := newMockUserRepo() repo.users[1] = user.User{ID: 1, Username: "alice", Email: "alice@example.com", Password: "hashed:hunter2example12", IsVerified: true} repo.nextID = 1 router := newLoginLogoutCookieRouter(repo, newMockMailRepo(), token) req := httptest.NewRequest(http.MethodPost, "/login", bytes.NewBufferString(`{"username":"alice","password":"hunter2example12"}`)) req.Header.Set("Content-Type", "application/json") rec := httptest.NewRecorder() router.ServeHTTP(rec, req) if rec.Code != http.StatusOK { t.Fatalf("expected status 200, got %d: %s", rec.Code, rec.Body.String()) } cookie, ok := jwtSetCookie(t, rec) if !ok { t.Fatalf("expected a jwt Set-Cookie header") } untilExpiry := time.Until(cookie.Expires) if untilExpiry < 23*time.Hour || untilExpiry > 25*time.Hour { t.Errorf("expected the jwt cookie to expire about 24 hours from now, got %v from now", untilExpiry) } }) t.Run("Logout clears the jwt cookie by expiring it immediately", func(t *testing.T) { repo := newMockUserRepo() router := newLoginLogoutCookieRouter(repo, newMockMailRepo(), token) req := httptest.NewRequest(http.MethodPost, "/logout", bytes.NewBufferString(`{}`)) req.Header.Set("Content-Type", "application/json") rec := httptest.NewRecorder() router.ServeHTTP(rec, req) if rec.Code != http.StatusOK { t.Fatalf("expected status 200, got %d: %s", rec.Code, rec.Body.String()) } cookie, ok := jwtSetCookie(t, rec) if !ok { t.Fatalf("expected a jwt Set-Cookie header") } if cookie.Value != "" || cookie.MaxAge >= 0 { t.Errorf("expected the jwt cookie to be cleared, got %+v", cookie) } }) }