Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@
ExtendedBeforeResultOut, ExtendedAfterResultOut, ExtendedErrorResultOut, ExtendedParams
>['cache'];

options.required = by.required;
options.required = typeof by.required === 'boolean' ? by.required : what.required;

options.logger = by.logger || what.logger;

Expand Down Expand Up @@ -485,7 +485,7 @@
blockCancel.throwIfCancelled();

if (typeof step.after === 'function') {
resultAfter = await step.after({ cancel, params, context, deps, result: (resultBefore || resultBlock) as any });

Check warning on line 488 in lib/block.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Unexpected any. Specify a different type
blockCancel.throwIfCancelled();

if (resultAfter instanceof BaseBlock) {
Expand Down
181 changes: 181 additions & 0 deletions tests/options.required.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
import http from 'node:http';

import * as de from '../lib';
import { DescriptError } from '../lib';
import { getPath } from './helpers';
import Server from './server';

const PORT = 10000;
const fake = new Server({
module: http,
listen_options: {
hostname: 'localhost',
port: PORT,
},
});

beforeAll(() => fake.start());
afterAll(() => fake.stop());

describe('options.required', () => {
it('not fail for required=false', async() => {
const block = de.object({
block: {
foo: de.func({
block: () => {
throw new Error('ERROR');
},
options: {
required: false,
},
}),
},
});

await expect(de.run(block))
.resolves.toMatchObject({
foo: expect.any(DescriptError),
});
});

it('fail for required=true', async() => {
const block = de.object({
block: {
foo: de.func({
block: () => {
throw new Error('ERROR');
},
options: {
required: true,
},
}),
},
});

await expect(de.run(block))
.rejects.toMatchObject({
error: { id: 'REQUIRED_BLOCK_FAILED' },
});
});

it('required=true for parent=undefined and child=true', async() => {
const path = getPath();
const spy = jest.fn((req, res) => res.end());
fake.add(path, spy);

const parent = de.http({
block: {
hostname: 'localhost',
port: 10000,
pathname: path,
prepareRequestOptions: (requestOptions, blockOptions) => {
requestOptions.headers = requestOptions.headers || {};
requestOptions.headers['x-required-header'] = blockOptions.required ? 'true' : 'false';
return requestOptions;
},
},
});
const child = parent.extend({
options: {
required: true,
},
});

await de.run(child);

const childHeaders = spy.mock.calls[ 0 ][ 0 ].headers;
expect(childHeaders[ 'x-required-header' ]).toBe('true');
});

it('required=false for parent=true and child=false', async() => {
const path = getPath();
const spy = jest.fn((req, res) => res.end());
fake.add(path, spy);

const parent = de.http({
block: {
hostname: 'localhost',
port: 10000,
pathname: path,
prepareRequestOptions: (requestOptions, blockOptions) => {
requestOptions.headers = requestOptions.headers || {};
requestOptions.headers['x-required-header'] = blockOptions.required ? 'true' : 'false';
return requestOptions;
},
},
options: {
required: true,
},
});
const child = parent.extend({
options: {
required: false,
},
});

await de.run(child);

const childHeaders = spy.mock.calls[ 0 ][ 0 ].headers;
expect(childHeaders[ 'x-required-header' ]).toBe('false');
});

it('required=true for parent=true and child=undefined', async() => {
const path = getPath();
const spy = jest.fn((req, res) => res.end());
fake.add(path, spy);

const parent = de.http({
block: {
hostname: 'localhost',
port: 10000,
pathname: path,
prepareRequestOptions: (requestOptions, blockOptions) => {
requestOptions.headers = requestOptions.headers || {};
requestOptions.headers['x-required-header'] = blockOptions.required ? 'true' : 'false';
return requestOptions;
},
},
options: {
required: true,
},
});
const child = parent.extend({});

await de.run(child);

const childHeaders = spy.mock.calls[ 0 ][ 0 ].headers;
expect(childHeaders[ 'x-required-header' ]).toBe('true');
});

it('required=true for parent=false and child=true', async() => {
const path = getPath();
const spy = jest.fn((req, res) => res.end());
fake.add(path, spy);

const parent = de.http({
block: {
hostname: 'localhost',
port: 10000,
pathname: path,
prepareRequestOptions: (requestOptions, blockOptions) => {
requestOptions.headers = requestOptions.headers || {};
requestOptions.headers['x-required-header'] = blockOptions.required ? 'true' : 'false';
return requestOptions;
},
},
options: {
required: false,
},
});
const child = parent.extend({
options: {
required: true,
},
});

await de.run(child);

const childHeaders = spy.mock.calls[ 0 ][ 0 ].headers;
expect(childHeaders[ 'x-required-header' ]).toBe('true');
});
});
Loading