import { CurrencyCode, LanguageCode } from '@vendure/common/lib/generated-types'; import { beforeAll, describe, expect, it } from 'vitest'; import { CachedSession } from '../../config/session-cache/session-cache-strategy'; import { Channel } from '../../entity/channel/channel.entity'; import { Order } from '../../entity/order/order.entity'; import { Zone } from '../../entity/zone/zone.entity'; import { RequestContext, SerializedRequestContext } from './request-context'; describe('RequestContext', () => { describe('serialize/deserialize', () => { let serializedCtx: SerializedRequestContext; let original: RequestContext; beforeAll(() => { original = createRequestContext(); serializedCtx = original.serialize(); }); it('apiType', () => { const result = RequestContext.deserialize(serializedCtx); expect(result.apiType).toBe(original.apiType); }); it('channelId', () => { const result = RequestContext.deserialize(serializedCtx); expect(result.channelId).toBe(original.channelId); }); it('languageCode', () => { const result = RequestContext.deserialize(serializedCtx); expect(result.languageCode).toBe(original.languageCode); }); it('activeUserId', () => { const result = RequestContext.deserialize(serializedCtx); expect(result.activeUserId).toBe(original.activeUserId); }); it('isAuthorized', () => { const result = RequestContext.deserialize(serializedCtx); expect(result.isAuthorized).toBe(original.isAuthorized); }); it('authorizedAsOwnerOnly', () => { const result = RequestContext.deserialize(serializedCtx); expect(result.authorizedAsOwnerOnly).toBe(original.authorizedAsOwnerOnly); }); it('channel', () => { const result = RequestContext.deserialize(serializedCtx); expect(result.channel).toEqual(original.channel); }); it('session', () => { const result = RequestContext.deserialize(serializedCtx); expect(result.session).toEqual(original.session); }); // https://github.com/vendure-ecommerce/vendure/issues/864 it('serialize request context with circular refs', () => { const cyclic: any = {}; const cyclic1: any = { prop: cyclic, }; cyclic.prop = cyclic1; const requestContext = createRequestContext({ simple: 'foo', arr: [1, 2, 3], cycle: cyclic, cycleArr: [cyclic, cyclic], }); const serialized = requestContext.serialize(); expect(serialized._req).toEqual({ simple: 'foo', arr: [1, 2, 3], cycle: {}, cycleArr: [{}, {}], }); }); }); describe('copy', () => { let original: RequestContext; beforeAll(() => { original = createRequestContext(); }); it('is a RequestContext instance', () => { const copy = original.copy(); expect(copy instanceof RequestContext).toBe(true); }); it('is not identical to original', () => { const copy = original.copy(); expect(copy === original).toBe(false); }); it('getters work', () => { const copy = original.copy(); expect(copy.apiType).toEqual(original.apiType); expect(copy.channelId).toEqual(original.channelId); expect(copy.languageCode).toEqual(original.languageCode); expect(copy.activeUserId).toEqual(original.activeUserId); expect(copy.isAuthorized).toEqual(original.isAuthorized); expect(copy.authorizedAsOwnerOnly).toEqual(original.authorizedAsOwnerOnly); expect(copy.channel).toEqual(original.channel); expect(copy.session).toEqual(original.session); }); it('mutating copy leaves original intact', () => { const copy = original.copy(); (copy as any).foo = 'bar'; expect((copy as any).foo).toBe('bar'); expect((original as any).foo).toBeUndefined(); }); it('mutating deep property affects both', () => { const copy = original.copy(); copy.channel.code = 'changed'; expect(copy.channel.code).toBe('changed'); expect(original.channel.code).toBe('changed'); }); }); function createRequestContext(req?: any) { const activeOrder = new Order({ id: '55555', active: true, code: 'ADAWDJAWD', }); const session = { cacheExpiry: Number.MAX_SAFE_INTEGER, expires: new Date(), id: '1234', token: '2d37187e9e8fc47807fe4f58ca', activeOrderId: '123', user: { id: '8833774', identifier: 'user', verified: true, channelPermissions: [], }, } satisfies CachedSession; const zone = new Zone({ id: '62626', name: 'Europe', }); const channel = new Channel({ token: 'oiajwodij09au3r', id: '995859', code: '__default_channel__', defaultCurrencyCode: CurrencyCode.EUR, pricesIncludeTax: true, defaultLanguageCode: LanguageCode.en, defaultShippingZone: zone, defaultTaxZone: zone, }); return new RequestContext({ apiType: 'admin', languageCode: LanguageCode.en, channel, session, req: req ?? {}, isAuthorized: true, authorizedAsOwnerOnly: false, }); } });