Skip to content

Commit

Permalink
chore: 404 headers test and a bit refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
nightnei committed Dec 16, 2021
1 parent 861cae2 commit c3153e1
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 21 deletions.
17 changes: 14 additions & 3 deletions src/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { IlcIntl } from './IlcIntl';
import defaultIntlAdapter from './defaultIntlAdapter';
import { IIlcAppSdk } from './interfaces/IIlcAppSdk';
import { Render404 } from './interfaces/common';
import ResponseStatus from './interfaces/ResponseStatus';

export * from './types';
export * from './GlobalBrowserApi';
Expand Down Expand Up @@ -75,18 +76,28 @@ export default class IlcAppSdk implements IIlcAppSdk {
}
/**
* Isomorphic method to render 404 page.
* GLOBAL 404:
* At SSR in processResponse it sets 404 status code to response.
* At CSR it triggers global event which ILC listens and renders 404 page.
*
* CUSTOM 404:
* At SSR in processResponse it sets 404 status code and "X-ILC-Override" header to response.
* At CSR it renders own not found component from fragment.
*/
render404: Render404 = (config) => {
// SSR
if (this.adapter.setStatus) {
const headers: Record<string, string> = {};
const status: ResponseStatus = {
code: 404,
};

if (config?.isCustomComponent) {
headers['X-ILC-Override'] = 'error-page-content';
status.headers = {
['X-ILC-Override']: 'error-page-content',
};
}
this.adapter.setStatus(404, { headers });
this.adapter.setStatus(status);
return;
}

// CSR
Expand Down
2 changes: 1 addition & 1 deletion src/app/interfaces/ResponseStatus.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
type ResponseStatus = {
code?: number;
headers: Record<string, string>;
headers?: Record<string, string>;
};

export default ResponseStatus;
4 changes: 2 additions & 2 deletions src/app/interfaces/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ export interface AppSdkAdapter {
/** Unique application ID, if same app will be rendered twice on a page - it will get different IDs */
appId: string;
intl: IntlAdapter | null;
setStatus: (code: number, config?: { headers: ResponseStatus['headers'] }) => void;
getStatus: () => ResponseStatus;
setStatus: (data: ResponseStatus) => void;
getStatus: () => ResponseStatus | undefined;
}

export type Render404 = (config?: { isCustomComponent: boolean }) => void;
Expand Down
19 changes: 6 additions & 13 deletions src/server/IlcSdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,7 @@ export class IlcSdk {
originalUri = '/';
}

const status: ResponseStatus = {
code: undefined,
headers: {}
};
let responseStatus: ResponseStatus;

return {
getCurrentReqHost: () => host,
Expand All @@ -69,14 +66,10 @@ export class IlcSdk {
getCurrentPathProps: () => passedProps,
appId,
intl: this.parseIntl(req),
setStatus: (code, config) => {
status.code = code;

if (config?.headers) {
status.headers = config.headers;
}
setStatus: (status) => {
responseStatus = status;
},
getStatus: () => status,
getStatus: () => responseStatus,
};
}

Expand All @@ -87,10 +80,10 @@ export class IlcSdk {
*/
public processResponse(reqData: types.RequestData, res: ServerResponse, data?: types.ResponseData): void {
const status = reqData.getStatus();
if (status.code) {
if (status?.code) {
res.statusCode = status.code;
}
if (status.headers) {
if (status?.headers) {
for (const [key, value] of Object.entries(status.headers)) {
res.setHeader(key, value);
}
Expand Down
25 changes: 23 additions & 2 deletions test/server/IlcSdk.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,19 +292,40 @@ describe('IlcSdk', () => {
);
});

it('should set 404 status code', () => {
it('should set 404 status code without headers', () => {
const NotFound = 404;

const req = new MockReq(merge({}, defReq));
const res = new MockRes();

const pRes = ilcSdk.processRequest(req);
pRes.setStatus(NotFound);
pRes.setStatus({ code: NotFound });
ilcSdk.processResponse(pRes, res);

expect(res.statusCode).to.eq(NotFound);
});

it('should set 404 status code and header for custom error', () => {
const NotFound = 404;
const NotFoundHeaderKey = 'X-ILC-Override';
const NotFoundHeaderValue = 'error-page-content';

const req = new MockReq(merge({}, defReq));
const res = new MockRes();

const pRes = ilcSdk.processRequest(req);
pRes.setStatus({
code: NotFound,
headers: {
[NotFoundHeaderKey]: NotFoundHeaderValue,
},
});
ilcSdk.processResponse(pRes, res);

expect(res.statusCode).to.eq(NotFound);
expect(res.getHeader(NotFoundHeaderKey)).to.eq(NotFoundHeaderValue);
});

describe('appAssets', () => {
it('should handle absolute URLs', () => {
const req = new MockReq(merge({}, defReq));
Expand Down

0 comments on commit c3153e1

Please sign in to comment.