mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
refactor: Replace RedirectAllHttpHandler usage with RedirectingHttpHandler
This commit is contained in:
@@ -1,53 +0,0 @@
|
||||
import type { TargetExtractor } from '../../../../src/http/input/identifier/TargetExtractor';
|
||||
import type { ResponseWriter } from '../../../../src/http/output/ResponseWriter';
|
||||
import type { ResourceIdentifier } from '../../../../src/http/representation/ResourceIdentifier';
|
||||
import type { HttpRequest } from '../../../../src/server/HttpRequest';
|
||||
import type { HttpResponse } from '../../../../src/server/HttpResponse';
|
||||
import { RedirectAllHttpHandler } from '../../../../src/server/util/RedirectAllHttpHandler';
|
||||
import { NotImplementedHttpError } from '../../../../src/util/errors/NotImplementedHttpError';
|
||||
import { joinUrl } from '../../../../src/util/PathUtil';
|
||||
import { SOLID_HTTP } from '../../../../src/util/Vocabularies';
|
||||
|
||||
describe('A RedirectAllHttpHandler', (): void => {
|
||||
const baseUrl = 'http://test.com/';
|
||||
const target = '/foo';
|
||||
const absoluteTarget = 'http://test.com/foo';
|
||||
let request: HttpRequest;
|
||||
const response: HttpResponse = {} as any;
|
||||
let targetExtractor: jest.Mocked<TargetExtractor>;
|
||||
let responseWriter: jest.Mocked<ResponseWriter>;
|
||||
let handler: RedirectAllHttpHandler;
|
||||
|
||||
beforeEach(async(): Promise<void> => {
|
||||
request = { url: '/foo' } as any;
|
||||
|
||||
targetExtractor = {
|
||||
handleSafe: jest.fn(({ request: req }): ResourceIdentifier => ({ path: joinUrl(baseUrl, req.url!) })),
|
||||
} as any;
|
||||
|
||||
responseWriter = { handleSafe: jest.fn() } as any;
|
||||
|
||||
handler = new RedirectAllHttpHandler({ baseUrl, target, targetExtractor, responseWriter });
|
||||
});
|
||||
|
||||
it('rejects requests for the target.', async(): Promise<void> => {
|
||||
request.url = target;
|
||||
await expect(handler.canHandle({ request, response })).rejects.toThrow(NotImplementedHttpError);
|
||||
});
|
||||
|
||||
it('accepts all other requests.', async(): Promise<void> => {
|
||||
request.url = '/otherPath';
|
||||
await expect(handler.canHandle({ request, response })).resolves.toBeUndefined();
|
||||
});
|
||||
|
||||
it('writes out a redirect response.', async(): Promise<void> => {
|
||||
await expect(handler.handle({ request, response })).resolves.toBeUndefined();
|
||||
expect(responseWriter.handleSafe).toHaveBeenCalledTimes(1);
|
||||
expect(responseWriter.handleSafe).toHaveBeenLastCalledWith({
|
||||
response,
|
||||
result: expect.objectContaining({ statusCode: 302 }),
|
||||
});
|
||||
const { metadata } = responseWriter.handleSafe.mock.calls[0][0].result;
|
||||
expect(metadata?.get(SOLID_HTTP.terms.location)?.value).toBe(absoluteTarget);
|
||||
});
|
||||
});
|
||||
97
test/unit/server/util/RedirectingHttpHandler.test.ts
Normal file
97
test/unit/server/util/RedirectingHttpHandler.test.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import type { TargetExtractor } from '../../../../src/http/input/identifier/TargetExtractor';
|
||||
import type { ResponseWriter } from '../../../../src/http/output/ResponseWriter';
|
||||
import type { ResourceIdentifier } from '../../../../src/http/representation/ResourceIdentifier';
|
||||
import type { HttpRequest } from '../../../../src/server/HttpRequest';
|
||||
import type { HttpResponse } from '../../../../src/server/HttpResponse';
|
||||
import { RedirectingHttpHandler } from '../../../../src/server/util/RedirectingHttpHandler';
|
||||
import { joinUrl } from '../../../../src/util/PathUtil';
|
||||
import { SOLID_HTTP } from '../../../../src/util/Vocabularies';
|
||||
|
||||
describe('A RedirectingHttpHandler', (): void => {
|
||||
const baseUrl = 'http://test.com/';
|
||||
const request = { method: 'GET' } as HttpRequest;
|
||||
const response = {} as HttpResponse;
|
||||
let targetExtractor: jest.Mocked<TargetExtractor>;
|
||||
let responseWriter: jest.Mocked<ResponseWriter>;
|
||||
let handler: RedirectingHttpHandler;
|
||||
|
||||
beforeEach(async(): Promise<void> => {
|
||||
targetExtractor = {
|
||||
handleSafe: jest.fn(({ request: req }): ResourceIdentifier => ({ path: joinUrl(baseUrl, req.url!) })),
|
||||
} as any;
|
||||
|
||||
responseWriter = { handleSafe: jest.fn() } as any;
|
||||
|
||||
handler = new RedirectingHttpHandler({
|
||||
'/one': '/two',
|
||||
'/from/(.*)': 'http://to/t$1',
|
||||
'/f([aeiou]+)/b([aeiou]+)r': '/f$2/b$1r',
|
||||
'/s(.)me': '/s$1me',
|
||||
}, baseUrl, targetExtractor, responseWriter);
|
||||
});
|
||||
|
||||
afterEach(jest.clearAllMocks);
|
||||
|
||||
it('does not handle requests without URL.', async(): Promise<void> => {
|
||||
await expect(handler.canHandle({ request, response }))
|
||||
.rejects.toThrow('Url must be a string. Received undefined');
|
||||
await expect(handler.handle({ request, response }))
|
||||
.rejects.toThrow('Url must be a string. Received undefined');
|
||||
});
|
||||
|
||||
it('does not handle requests with unconfigured URLs.', async(): Promise<void> => {
|
||||
request.url = '/other';
|
||||
await expect(handler.canHandle({ request, response }))
|
||||
.rejects.toThrow('No redirect configured for /other');
|
||||
await expect(handler.handle({ request, response }))
|
||||
.rejects.toThrow('No redirect configured for /other');
|
||||
});
|
||||
|
||||
it('does not handle requests redirecting to their own target URL.', async(): Promise<void> => {
|
||||
request.url = '/same';
|
||||
await expect(handler.canHandle({ request, response }))
|
||||
.rejects.toThrow('Target is already correct.');
|
||||
await expect(handler.handle({ request, response }))
|
||||
.rejects.toThrow('Target is already correct.');
|
||||
});
|
||||
|
||||
it('handles requests to a known URL.', async(): Promise<void> => {
|
||||
request.url = '/one';
|
||||
|
||||
await expect(handler.handle({ request, response })).resolves.toBeUndefined();
|
||||
expect(responseWriter.handleSafe).toHaveBeenCalledTimes(1);
|
||||
expect(responseWriter.handleSafe).toHaveBeenLastCalledWith({
|
||||
response,
|
||||
result: expect.objectContaining({ statusCode: 308 }),
|
||||
});
|
||||
const { metadata } = responseWriter.handleSafe.mock.calls[0][0].result;
|
||||
expect(metadata?.get(SOLID_HTTP.terms.location)?.value).toBe(joinUrl(baseUrl, '/two'));
|
||||
});
|
||||
|
||||
it('handles correctly substitutes group patterns.', async(): Promise<void> => {
|
||||
request.url = '/fa/boor';
|
||||
|
||||
await handler.handle({ request, response });
|
||||
const { metadata } = responseWriter.handleSafe.mock.calls[0][0].result;
|
||||
expect(metadata?.get(SOLID_HTTP.terms.location)?.value).toBe(joinUrl(baseUrl, '/foo/bar'));
|
||||
});
|
||||
|
||||
it('redirects to an absolute url if provided.', async(): Promise<void> => {
|
||||
request.url = '/from/here';
|
||||
|
||||
await handler.handle({ request, response });
|
||||
const { metadata } = responseWriter.handleSafe.mock.calls[0][0].result;
|
||||
expect(metadata?.get(SOLID_HTTP.terms.location)?.value).toBe('http://to/there');
|
||||
});
|
||||
|
||||
it.each([ 301, 302, 303, 307, 308 ])('redirects with the provided status code: %i.', async(code): Promise<void> => {
|
||||
request.url = '/one';
|
||||
(handler as any).statusCode = code;
|
||||
|
||||
await handler.handle({ request, response });
|
||||
expect(responseWriter.handleSafe).toHaveBeenLastCalledWith({
|
||||
response,
|
||||
result: expect.objectContaining({ statusCode: code }),
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user