From 80d81eafae6e53b7a8361548633c5833c800f532 Mon Sep 17 00:00:00 2001 From: Janka Uryga Date: Fri, 11 Oct 2024 16:29:35 +0200 Subject: [PATCH] test: unit test for wrapWithMutableAccessCheck and phase checks --- .../adapters/request-cookies.test.ts | 54 ++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/packages/next/src/server/web/spec-extension/adapters/request-cookies.test.ts b/packages/next/src/server/web/spec-extension/adapters/request-cookies.test.ts index 62f6c8fb0ce65..0322f3cbc8d29 100644 --- a/packages/next/src/server/web/spec-extension/adapters/request-cookies.test.ts +++ b/packages/next/src/server/web/spec-extension/adapters/request-cookies.test.ts @@ -1,8 +1,13 @@ -import { RequestCookies } from '../cookies' +import { + workUnitAsyncStorage, + type RequestStore, +} from '../../../app-render/work-unit-async-storage.external' +import { RequestCookies, ResponseCookies } from '../cookies' import { ReadonlyRequestCookiesError, RequestCookiesAdapter, MutableRequestCookiesAdapter, + wrapWithMutableAccessCheck, } from './request-cookies' describe('RequestCookiesAdapter', () => { @@ -100,3 +105,50 @@ describe('MutableRequestCookiesAdapter', () => { ]) }) }) + +describe('wrapWithMutableAccessCheck', () => { + const createMockRequestStore = (phase: RequestStore['phase']) => + ({ type: 'request', phase }) as RequestStore + + it('prevents setting cookies in the render phase', () => { + const requestStore = createMockRequestStore('action') + workUnitAsyncStorage.run(requestStore, () => { + const headers = new Headers({}) + const underlyingCookies = new ResponseCookies(headers) + const wrappedCookies = wrapWithMutableAccessCheck(underlyingCookies) + + // simulate changing phases + requestStore.phase = 'render' + + const EXPECTED_ERROR = + /Cookies can only be modified in a Server Action or Route Handler\./ + + expect(() => { + wrappedCookies.set('foo', '1') + }).toThrow(EXPECTED_ERROR) + + expect(wrappedCookies.get('foo')).toBe(undefined) + }) + }) + + it('prevents deleting cookies in the render phase', () => { + const requestStore = createMockRequestStore('action') + workUnitAsyncStorage.run(requestStore, () => { + const headers = new Headers({}) + const underlyingCookies = new ResponseCookies(headers) + const wrappedCookies = wrapWithMutableAccessCheck(underlyingCookies) + wrappedCookies.set('foo', '1') + + // simulate changing phases + requestStore.phase = 'render' + + const EXPECTED_ERROR = + /Cookies can only be modified in a Server Action or Route Handler\./ + + expect(() => { + wrappedCookies.delete('foo') + }).toThrow(EXPECTED_ERROR) + expect(wrappedCookies.get('foo')?.value).toEqual('1') + }) + }) +})