From ada6e0b07e735a8d7eecd3d0a5e105bda78350b2 Mon Sep 17 00:00:00 2001 From: Aleksei Androsov Date: Thu, 20 Feb 2025 19:32:05 +0300 Subject: [PATCH] Tests for options.required --- lib/block.ts | 2 +- tests/options.required.test.ts | 181 +++++++++++++++++++++++++++++++++ 2 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 tests/options.required.test.ts diff --git a/lib/block.ts b/lib/block.ts index a6dafe7..014de3d 100644 --- a/lib/block.ts +++ b/lib/block.ts @@ -193,7 +193,7 @@ abstract class BaseBlock< 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; diff --git a/tests/options.required.test.ts b/tests/options.required.test.ts new file mode 100644 index 0000000..06d816f --- /dev/null +++ b/tests/options.required.test.ts @@ -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'); + }); +});