test(@angular-devkit/build-angular): add dev-server execute and fetch unit test helper

This change extracts common test code into a helper function to reduce complexity of the dev-server builder unit tests.
This commit is contained in:
Charles Lyding 2021-03-06 09:17:41 -05:00 committed by Filipe Silva
parent 06a354fb93
commit a51eb6e864
4 changed files with 59 additions and 61 deletions

View File

@ -266,6 +266,7 @@ ts_library(
"//packages/angular_devkit/architect/testing", "//packages/angular_devkit/architect/testing",
"//packages/angular_devkit/core", "//packages/angular_devkit/core",
"//packages/angular_devkit/core/node", "//packages/angular_devkit/core/node",
"@npm//@types/node-fetch",
"@npm//rxjs", "@npm//rxjs",
], ],
) )

View File

@ -5,9 +5,8 @@
* Use of this source code is governed by an MIT-style license that can be * Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import fetch from 'node-fetch'; // tslint:disable-line:no-implicit-dependencies
import { mergeMap, take, timeout } from 'rxjs/operators';
import { serveWebpackBrowser } from '../../index'; import { serveWebpackBrowser } from '../../index';
import { executeOnceAndFetch } from '../execute-fetch';
import { import {
BASE_OPTIONS, BASE_OPTIONS,
DEV_SERVER_BUILDER_INFO, DEV_SERVER_BUILDER_INFO,
@ -41,21 +40,10 @@ describeBuilder(serveWebpackBrowser, DEV_SERVER_BUILDER_INFO, (harness) => {
...BASE_OPTIONS, ...BASE_OPTIONS,
}); });
await harness const { result, response } = await executeOnceAndFetch(harness, '/');
.execute()
.pipe(
timeout(39000),
mergeMap(async ({ result }) => {
expect(result?.success).toBeTrue();
if (result?.success) { expect(result?.success).toBeTrue();
const response = await fetch(`${result.baseUrl}index.html`); expect(await response?.text()).toContain('body{color:#000;}');
expect(await response.text()).toContain(`body{color:#000;}`);
}
}),
take(1),
)
.toPromise();
}); });
}); });
}); });

View File

@ -0,0 +1,38 @@
/**
* @license
* Copyright Google Inc. 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.io/license
*/
import fetch, { RequestInit, Response } from 'node-fetch'; // tslint:disable-line:no-implicit-dependencies
import { mergeMap, take, timeout } from 'rxjs/operators';
import { URL } from 'url';
import {
BuilderHarness,
BuilderHarnessExecutionOptions,
BuilderHarnessExecutionResult,
} from '../../testing/builder-harness';
export async function executeOnceAndFetch<T>(
harness: BuilderHarness<T>,
url: string,
options?: Partial<BuilderHarnessExecutionOptions> & { request?: RequestInit },
): Promise<BuilderHarnessExecutionResult & { response?: Response }> {
return harness
.execute()
.pipe(
timeout(30000),
mergeMap(async (executionResult) => {
let response = undefined;
if (executionResult.result?.success) {
const resolvedUrl = new URL(url, executionResult.result.baseUrl as string);
response = await fetch(resolvedUrl, options?.request);
}
return { ...executionResult, response };
}),
take(1),
)
.toPromise();
}

View File

@ -5,12 +5,10 @@
* Use of this source code is governed by an MIT-style license that can be * Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import fetch from 'node-fetch'; // tslint:disable-line:no-implicit-dependencies
import { mergeMap, take, timeout } from 'rxjs/operators';
import { serveWebpackBrowser } from '../../index'; import { serveWebpackBrowser } from '../../index';
import { executeOnceAndFetch } from '../execute-fetch';
import { import {
BASE_OPTIONS, BASE_OPTIONS,
BUILD_TIMEOUT,
DEV_SERVER_BUILDER_INFO, DEV_SERVER_BUILDER_INFO,
describeBuilder, describeBuilder,
setupBrowserTarget, setupBrowserTarget,
@ -32,21 +30,12 @@ describeBuilder(serveWebpackBrowser, DEV_SERVER_BUILDER_INFO, (harness) => {
...BASE_OPTIONS, ...BASE_OPTIONS,
}); });
await harness const { result, response } = await executeOnceAndFetch(harness, '/', {
.execute() request: { headers: FETCH_HEADERS },
.pipe( });
timeout(BUILD_TIMEOUT),
mergeMap(async ({ result }) => {
expect(result?.success).toBeTrue();
if (result?.success) { expect(result?.success).toBeTrue();
const response = await fetch(`${result.baseUrl}`, { headers: FETCH_HEADERS }); expect(await response?.text()).toBe('Invalid Host header');
expect(await response.text()).toBe('Invalid Host header');
}
}),
take(1),
)
.toPromise();
}); });
it('does not allow an invalid host when option is an empty array', async () => { it('does not allow an invalid host when option is an empty array', async () => {
@ -55,21 +44,12 @@ describeBuilder(serveWebpackBrowser, DEV_SERVER_BUILDER_INFO, (harness) => {
allowedHosts: [], allowedHosts: [],
}); });
await harness const { result, response } = await executeOnceAndFetch(harness, '/', {
.execute() request: { headers: FETCH_HEADERS },
.pipe( });
timeout(BUILD_TIMEOUT),
mergeMap(async ({ result }) => {
expect(result?.success).toBeTrue();
if (result?.success) { expect(result?.success).toBeTrue();
const response = await fetch(`${result.baseUrl}`, { headers: FETCH_HEADERS }); expect(await response?.text()).toBe('Invalid Host header');
expect(await response.text()).toBe('Invalid Host header');
}
}),
take(1),
)
.toPromise();
}); });
it('allows a host when specified in the option', async () => { it('allows a host when specified in the option', async () => {
@ -78,21 +58,12 @@ describeBuilder(serveWebpackBrowser, DEV_SERVER_BUILDER_INFO, (harness) => {
allowedHosts: ['example.com'], allowedHosts: ['example.com'],
}); });
await harness const { result, response } = await executeOnceAndFetch(harness, '/', {
.execute() request: { headers: FETCH_HEADERS },
.pipe( });
timeout(BUILD_TIMEOUT),
mergeMap(async ({ result }) => {
expect(result?.success).toBeTrue();
if (result?.success) { expect(result?.success).toBeTrue();
const response = await fetch(`${result.baseUrl}`, { headers: FETCH_HEADERS }); expect(await response?.text()).toContain('<title>');
expect(await response.text()).toContain('<title>');
}
}),
take(1),
)
.toPromise();
}); });
}); });
}); });