@sync-in/server
Version:
The secure, open-source platform for file storage, sharing, collaboration, and sync
135 lines (134 loc) • 4.83 kB
JavaScript
/*
* Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>
* This file is part of Sync-in | The open source file sync and share solution
* See the LICENSE file for licensing details
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
const _testing = require("@nestjs/testing");
const _rxjs = require("rxjs");
const _contextinterceptor = require("./context.interceptor");
const _contextmanagerservice = require("../services/context-manager.service");
// Helper to create a minimal ExecutionContext with Fastify-like request
function createHttpExecutionContext(request) {
return {
switchToHttp: ()=>({
getRequest: ()=>request,
getResponse: ()=>({}),
getNext: ()=>({})
}),
getType: ()=>'http',
getClass: ()=>({}),
getHandler: ()=>({}),
switchToRpc: ()=>({}),
switchToWs: ()=>({}),
getArgByIndex: ()=>({}),
getArgs: ()=>[]
};
}
describe('ContextInterceptor', ()=>{
let interceptor;
let contextManager;
beforeEach(async ()=>{
contextManager = {
// By default, run will execute the provided callback and return its result
run: jest.fn((_ctx, cb)=>cb())
};
const module = await _testing.Test.createTestingModule({
providers: [
_contextinterceptor.ContextInterceptor,
{
provide: _contextmanagerservice.ContextManager,
useValue: contextManager
}
]
}).compile();
interceptor = module.get(_contextinterceptor.ContextInterceptor);
});
it('should pass headerOriginUrl from Origin header to ContextManager.run and forward next.handle()', (done)=>{
const origin = 'https://example.com';
const request = {
headers: {
origin,
host: 'ignored-host'
},
protocol: 'http'
};
const context = createHttpExecutionContext(request);
const next = {
handle: jest.fn(()=>(0, _rxjs.of)('ok'))
};
const result$ = interceptor.intercept(context, next);
expect(contextManager.run).toHaveBeenCalledTimes(1);
const [ctxArg, cbArg] = contextManager.run.mock.calls[0];
expect(ctxArg).toEqual({
headerOriginUrl: origin
});
expect(typeof cbArg).toBe('function');
// next.handle is invoked synchronously by ContextManager.run; assert in subscription to keep flow consistent
result$.subscribe({
next: (val)=>{
expect(next.handle).toHaveBeenCalledTimes(1);
expect(val).toBe('ok');
done();
},
error: done
});
});
it('should build headerOriginUrl from protocol and host when Origin header is missing', (done)=>{
const request = {
headers: {
host: 'my-host.local:3000'
},
protocol: 'http'
};
const context = createHttpExecutionContext(request);
const next = {
handle: jest.fn(()=>(0, _rxjs.of)({
status: 'passed'
}))
};
const result$ = interceptor.intercept(context, next);
expect(contextManager.run).toHaveBeenCalledTimes(1);
const [ctxArg, cbArg] = contextManager.run.mock.calls[0];
expect(ctxArg).toEqual({
headerOriginUrl: 'http://my-host.local:3000'
});
expect(typeof cbArg).toBe('function');
result$.subscribe({
next: (val)=>{
expect(next.handle).toHaveBeenCalledTimes(1);
expect(val).toEqual({
status: 'passed'
});
done();
},
error: done
});
});
it('should return the observable produced by next.handle() within ContextManager.run callback', (done)=>{
// Ensure run executes the callback and returns its result
contextManager.run.mockImplementation((_ctx, cb)=>cb());
const request = {
headers: {
origin: 'https://origin.test'
},
protocol: 'https'
};
const context = createHttpExecutionContext(request);
const next = {
handle: jest.fn(()=>(0, _rxjs.of)(123))
};
const result$ = interceptor.intercept(context, next);
result$.subscribe({
next: (val)=>{
expect(val).toBe(123);
expect(next.handle).toHaveBeenCalledTimes(1);
done();
},
error: done
});
});
});
//# sourceMappingURL=context.interceptor.spec.js.map