mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-17 11:03:53 +08:00
This commit introduces the new hybrid rendering API for Angular's Server-Side Rendering (SSR). The API aims to enhance the flexibility of SSR as discussed in https://github.com/angular/angular/discussions/56785 - This API is currently not accessible. - Additional work is required in the Angular CLI to: - Wire up the manifest. - Integrate other necessary components.
111 lines
3.0 KiB
TypeScript
111 lines
3.0 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google LLC All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.dev/license
|
|
*/
|
|
|
|
import { IncomingMessage, Server, createServer, request as requestCb } from 'node:http';
|
|
import { AddressInfo } from 'node:net';
|
|
import { writeResponseToNodeResponse } from '../src/response';
|
|
|
|
describe('writeResponseToNodeResponse', () => {
|
|
let server: Server;
|
|
|
|
function simulateResponse(
|
|
res: Response,
|
|
): Promise<{ response: IncomingMessage; body: string | null }> {
|
|
server.once('request', (req, nodeResponse) => {
|
|
void writeResponseToNodeResponse(res, nodeResponse);
|
|
});
|
|
|
|
return new Promise<{
|
|
body: string | null;
|
|
response: IncomingMessage;
|
|
}>((resolve, reject) => {
|
|
const { port } = server.address() as AddressInfo;
|
|
const clientRequest = requestCb(
|
|
{
|
|
host: 'localhost',
|
|
port,
|
|
},
|
|
(response) => {
|
|
let body: string | null = null;
|
|
response
|
|
.on('data', (chunk) => {
|
|
body ??= '';
|
|
body += chunk;
|
|
})
|
|
.on('end', () => resolve({ response, body }))
|
|
.on('error', reject);
|
|
},
|
|
);
|
|
|
|
clientRequest.end();
|
|
});
|
|
}
|
|
|
|
beforeAll((done) => {
|
|
server = createServer();
|
|
server.listen(0, done);
|
|
});
|
|
|
|
afterAll((done) => {
|
|
server.close(done);
|
|
});
|
|
|
|
it('should write status, headers, and body to Node.js response', async () => {
|
|
const { response, body } = await simulateResponse(
|
|
new Response('Hello, world!', {
|
|
status: 201,
|
|
headers: {
|
|
'Content-Type': 'text/plain',
|
|
'X-Custom-Header': 'custom-value',
|
|
},
|
|
}),
|
|
);
|
|
|
|
expect(response.statusCode).toBe(201);
|
|
expect(response.headers['content-type']).toBe('text/plain');
|
|
expect(response.headers['x-custom-header']).toBe('custom-value');
|
|
expect(body).toBe('Hello, world!');
|
|
});
|
|
|
|
it('should handle empty body', async () => {
|
|
const { response, body } = await simulateResponse(
|
|
new Response(null, {
|
|
status: 204,
|
|
}),
|
|
);
|
|
|
|
expect(response.statusCode).toBe(204);
|
|
expect(body).toBeNull();
|
|
});
|
|
|
|
it('should handle JSON content types', async () => {
|
|
const jsonData = JSON.stringify({ message: 'Hello JSON' });
|
|
const { response, body } = await simulateResponse(
|
|
new Response(jsonData, {
|
|
headers: { 'Content-Type': 'application/json' },
|
|
}),
|
|
);
|
|
|
|
expect(response.statusCode).toBe(200);
|
|
expect(body).toBe(jsonData);
|
|
});
|
|
|
|
it('should set cookies on the ServerResponse', async () => {
|
|
const cookieValue: string[] = [
|
|
'myCookie=myValue; Path=/; HttpOnly',
|
|
'anotherCookie=anotherValue; Path=/test',
|
|
];
|
|
|
|
const headers = new Headers();
|
|
cookieValue.forEach((v) => headers.append('set-cookie', v));
|
|
const { response } = await simulateResponse(new Response(null, { headers }));
|
|
|
|
expect(response.headers['set-cookie']).toEqual(cookieValue);
|
|
});
|
|
});
|