From bbd5aa7ead5f1554a0872963f957effc26d8c630 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 17 Aug 2022 15:25:58 +0200 Subject: [PATCH] Reimplement a typed omit function --- server/helpers/logger.ts | 4 ++-- server/tests/api/check-params/config.ts | 7 +++---- server/tests/api/check-params/live.ts | 6 ++---- server/tests/api/check-params/metrics.ts | 15 +++++++-------- server/tests/api/check-params/users-admin.ts | 11 +++++------ server/tests/api/check-params/users.ts | 6 ++---- server/tests/api/check-params/video-channels.ts | 12 ++++-------- server/tests/api/check-params/video-imports.ts | 16 +++++++--------- server/tests/api/check-params/videos.ts | 12 ++++-------- server/tests/api/moderation/video-blacklist.ts | 8 ++++---- server/tests/api/transcoding/transcoder.ts | 8 ++------ server/tests/client.ts | 4 ++-- shared/core-utils/common/object.ts | 14 ++++++++++++++ shared/server-commands/users/users-command.ts | 5 ++--- shared/server-commands/videos/live-command.ts | 5 ++--- .../server-commands/videos/playlists-command.ts | 7 +++---- shared/server-commands/videos/videos-command.ts | 5 ++--- 17 files changed, 67 insertions(+), 78 deletions(-) diff --git a/server/helpers/logger.ts b/server/helpers/logger.ts index 9625c1b33..6649db40f 100644 --- a/server/helpers/logger.ts +++ b/server/helpers/logger.ts @@ -1,11 +1,11 @@ import { stat } from 'fs-extra' -import { omit } from 'lodash' import { join } from 'path' import { format as sqlFormat } from 'sql-formatter' import { createLogger, format, transports } from 'winston' import { FileTransportOptions } from 'winston/lib/winston/transports' import { context } from '@opentelemetry/api' import { getSpanContext } from '@opentelemetry/api/build/src/trace/context-utils' +import { omit } from '@shared/core-utils' import { CONFIG } from '../initializers/config' import { LOG_FILENAME } from '../initializers/constants' @@ -204,5 +204,5 @@ function removeCyclicValues () { function getAdditionalInfo (info: any) { const toOmit = [ 'label', 'timestamp', 'level', 'message', 'sql', 'tags' ] - return omit(info, ...toOmit) + return omit(info, toOmit) } diff --git a/server/tests/api/check-params/config.ts b/server/tests/api/check-params/config.ts index d67e51123..3415625ca 100644 --- a/server/tests/api/check-params/config.ts +++ b/server/tests/api/check-params/config.ts @@ -1,7 +1,6 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ - -import 'mocha' -import { merge, omit } from 'lodash' +import { merge } from 'lodash' +import { omit } from '@shared/core-utils' import { CustomConfig, HttpStatusCode } from '@shared/models' import { cleanupTests, @@ -277,7 +276,7 @@ describe('Test config API validators', function () { }) it('Should fail if it misses a key', async function () { - const newUpdateParams = omit(updateParams, 'admin.email') + const newUpdateParams = { ...updateParams, admin: omit(updateParams.admin, [ 'email' ]) } await makePutBodyRequest({ url: server.url, diff --git a/server/tests/api/check-params/live.ts b/server/tests/api/check-params/live.ts index b092f16f9..3f553c42b 100644 --- a/server/tests/api/check-params/live.ts +++ b/server/tests/api/check-params/live.ts @@ -1,9 +1,7 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ -import 'mocha' import { expect } from 'chai' -import { omit } from 'lodash' -import { buildAbsoluteFixturePath } from '@shared/core-utils' +import { buildAbsoluteFixturePath, omit } from '@shared/core-utils' import { HttpStatusCode, LiveVideoLatencyMode, VideoCreateResult, VideoPrivacy } from '@shared/models' import { cleanupTests, @@ -132,7 +130,7 @@ describe('Test video lives API validator', function () { }) it('Should fail without a channel', async function () { - const fields = omit(baseCorrectParams, 'channelId') + const fields = omit(baseCorrectParams, [ 'channelId' ]) await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) }) diff --git a/server/tests/api/check-params/metrics.ts b/server/tests/api/check-params/metrics.ts index 2d4509406..be8253217 100644 --- a/server/tests/api/check-params/metrics.ts +++ b/server/tests/api/check-params/metrics.ts @@ -1,7 +1,6 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ -import 'mocha' -import { omit } from 'lodash' +import { omit } from '@shared/core-utils' import { HttpStatusCode, PlaybackMetricCreate, VideoResolution } from '@shared/models' import { cleanupTests, createSingleServer, makePostBodyRequest, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands' @@ -66,7 +65,7 @@ describe('Test metrics API validators', function () { await makePostBodyRequest({ url: server.url, path, - fields: omit(baseParams, 'playerMode') + fields: omit(baseParams, [ 'playerMode' ]) }) await makePostBodyRequest({ @@ -80,7 +79,7 @@ describe('Test metrics API validators', function () { await makePostBodyRequest({ url: server.url, path, - fields: omit(baseParams, 'resolutionChanges') + fields: omit(baseParams, [ 'resolutionChanges' ]) }) await makePostBodyRequest({ @@ -98,7 +97,7 @@ describe('Test metrics API validators', function () { await makePostBodyRequest({ url: server.url, path, - fields: omit(baseParams, 'errors') + fields: omit(baseParams, [ 'errors' ]) }) await makePostBodyRequest({ @@ -112,7 +111,7 @@ describe('Test metrics API validators', function () { await makePostBodyRequest({ url: server.url, path, - fields: omit(baseParams, 'downloadedBytesP2P') + fields: omit(baseParams, [ 'downloadedBytesP2P' ]) }) await makePostBodyRequest({ @@ -126,7 +125,7 @@ describe('Test metrics API validators', function () { await makePostBodyRequest({ url: server.url, path, - fields: omit(baseParams, 'downloadedBytesHTTP') + fields: omit(baseParams, [ 'downloadedBytesHTTP' ]) }) await makePostBodyRequest({ @@ -140,7 +139,7 @@ describe('Test metrics API validators', function () { await makePostBodyRequest({ url: server.url, path, - fields: omit(baseParams, 'uploadedBytesP2P') + fields: omit(baseParams, [ 'uploadedBytesP2P' ]) }) await makePostBodyRequest({ diff --git a/server/tests/api/check-params/users-admin.ts b/server/tests/api/check-params/users-admin.ts index 716c22556..d941ca024 100644 --- a/server/tests/api/check-params/users-admin.ts +++ b/server/tests/api/check-params/users-admin.ts @@ -1,8 +1,7 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ -import 'mocha' -import { omit } from 'lodash' import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination, MockSmtpServer } from '@server/tests/shared' +import { omit } from '@shared/core-utils' import { HttpStatusCode, UserAdminFlag, UserRole } from '@shared/models' import { cleanupTests, @@ -123,7 +122,7 @@ describe('Test users admin API validators', function () { }) it('Should fail with a missing email', async function () { - const fields = omit(baseCorrectParams, 'email') + const fields = omit(baseCorrectParams, [ 'email' ]) await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) }) @@ -223,13 +222,13 @@ describe('Test users admin API validators', function () { }) it('Should fail without a videoQuota', async function () { - const fields = omit(baseCorrectParams, 'videoQuota') + const fields = omit(baseCorrectParams, [ 'videoQuota' ]) await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) }) it('Should fail without a videoQuotaDaily', async function () { - const fields = omit(baseCorrectParams, 'videoQuotaDaily') + const fields = omit(baseCorrectParams, [ 'videoQuotaDaily' ]) await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) }) @@ -247,7 +246,7 @@ describe('Test users admin API validators', function () { }) it('Should fail without a user role', async function () { - const fields = omit(baseCorrectParams, 'role') + const fields = omit(baseCorrectParams, [ 'role' ]) await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) }) diff --git a/server/tests/api/check-params/users.ts b/server/tests/api/check-params/users.ts index 4c4f54958..7acfd8c2c 100644 --- a/server/tests/api/check-params/users.ts +++ b/server/tests/api/check-params/users.ts @@ -1,8 +1,6 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ - -import 'mocha' -import { omit } from 'lodash' import { MockSmtpServer } from '@server/tests/shared' +import { omit } from '@shared/core-utils' import { HttpStatusCode, UserRole } from '@shared/models' import { cleanupTests, createSingleServer, makePostBodyRequest, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands' @@ -57,7 +55,7 @@ describe('Test users API validators', function () { }) it('Should fail with a missing email', async function () { - const fields = omit(baseCorrectParams, 'email') + const fields = omit(baseCorrectParams, [ 'email' ]) await makePostBodyRequest({ url: server.url, path: registrationPath, token: server.accessToken, fields }) }) diff --git a/server/tests/api/check-params/video-channels.ts b/server/tests/api/check-params/video-channels.ts index 9024126c0..1782474fd 100644 --- a/server/tests/api/check-params/video-channels.ts +++ b/server/tests/api/check-params/video-channels.ts @@ -1,10 +1,8 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ -import 'mocha' -import * as chai from 'chai' -import { omit } from 'lodash' +import { expect } from 'chai' import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '@server/tests/shared' -import { buildAbsoluteFixturePath } from '@shared/core-utils' +import { buildAbsoluteFixturePath, omit } from '@shared/core-utils' import { HttpStatusCode, VideoChannelUpdate } from '@shared/models' import { ChannelsCommand, @@ -18,8 +16,6 @@ import { setAccessTokensToServers } from '@shared/server-commands' -const expect = chai.expect - describe('Test video channels API validator', function () { const videoChannelPath = '/api/v1/video-channels' let server: PeerTubeServer @@ -121,7 +117,7 @@ describe('Test video channels API validator', function () { }) it('Should fail without a name', async function () { - const fields = omit(baseCorrectParams, 'name') + const fields = omit(baseCorrectParams, [ 'name' ]) await makePostBodyRequest({ url: server.url, path: videoChannelPath, token: server.accessToken, fields }) }) @@ -131,7 +127,7 @@ describe('Test video channels API validator', function () { }) it('Should fail without a name', async function () { - const fields = omit(baseCorrectParams, 'displayName') + const fields = omit(baseCorrectParams, [ 'displayName' ]) await makePostBodyRequest({ url: server.url, path: videoChannelPath, token: server.accessToken, fields }) }) diff --git a/server/tests/api/check-params/video-imports.ts b/server/tests/api/check-params/video-imports.ts index 85382b261..7f19b9ee9 100644 --- a/server/tests/api/check-params/video-imports.ts +++ b/server/tests/api/check-params/video-imports.ts @@ -1,9 +1,7 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ -import 'mocha' -import { omit } from 'lodash' import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination, FIXTURE_URLS } from '@server/tests/shared' -import { buildAbsoluteFixturePath } from '@shared/core-utils' +import { buildAbsoluteFixturePath, omit } from '@shared/core-utils' import { HttpStatusCode, VideoPrivacy } from '@shared/models' import { cleanupTests, @@ -107,7 +105,7 @@ describe('Test video imports API validator', function () { }) it('Should fail without a target url', async function () { - const fields = omit(baseCorrectParams, 'targetUrl') + const fields = omit(baseCorrectParams, [ 'targetUrl' ]) await makePostBodyRequest({ url: server.url, path, @@ -189,7 +187,7 @@ describe('Test video imports API validator', function () { }) it('Should fail without a channel', async function () { - const fields = omit(baseCorrectParams, 'channelId') + const fields = omit(baseCorrectParams, [ 'channelId' ]) await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) }) @@ -271,7 +269,7 @@ describe('Test video imports API validator', function () { }) it('Should fail with an invalid torrent file', async function () { - const fields = omit(baseCorrectParams, 'targetUrl') + const fields = omit(baseCorrectParams, [ 'targetUrl' ]) const attaches = { torrentfile: buildAbsoluteFixturePath('avatar-big.png') } @@ -280,7 +278,7 @@ describe('Test video imports API validator', function () { }) it('Should fail with an invalid magnet URI', async function () { - let fields = omit(baseCorrectParams, 'targetUrl') + let fields = omit(baseCorrectParams, [ 'targetUrl' ]) fields = { ...fields, magnetUri: 'blabla' } await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) @@ -339,7 +337,7 @@ describe('Test video imports API validator', function () { } }) - let fields = omit(baseCorrectParams, 'targetUrl') + let fields = omit(baseCorrectParams, [ 'targetUrl' ]) fields = { ...fields, magnetUri: FIXTURE_URLS.magnet } await makePostBodyRequest({ @@ -350,7 +348,7 @@ describe('Test video imports API validator', function () { expectedStatus: HttpStatusCode.CONFLICT_409 }) - fields = omit(fields, 'magnetUri') + fields = omit(fields, [ 'magnetUri' ]) const attaches = { torrentfile: buildAbsoluteFixturePath('video-720p.torrent') } diff --git a/server/tests/api/check-params/videos.ts b/server/tests/api/check-params/videos.ts index e5c9b90c4..572ca8997 100644 --- a/server/tests/api/check-params/videos.ts +++ b/server/tests/api/check-params/videos.ts @@ -1,11 +1,9 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ -import 'mocha' -import * as chai from 'chai' -import { omit } from 'lodash' +import { expect } from 'chai' import { join } from 'path' import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination, checkUploadVideoParam } from '@server/tests/shared' -import { randomInt, root } from '@shared/core-utils' +import { omit, randomInt, root } from '@shared/core-utils' import { HttpStatusCode, PeerTubeProblemDocument, VideoCreateResult, VideoPrivacy } from '@shared/models' import { cleanupTests, @@ -18,8 +16,6 @@ import { setAccessTokensToServers } from '@shared/server-commands' -const expect = chai.expect - describe('Test videos API validator', function () { const path = '/api/v1/videos/' let server: PeerTubeServer @@ -219,7 +215,7 @@ describe('Test videos API validator', function () { }) it('Should fail without name', async function () { - const fields = omit(baseCorrectParams, 'name') + const fields = omit(baseCorrectParams, [ 'name' ]) const attaches = baseCorrectAttaches await checkUploadVideoParam(server, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) @@ -268,7 +264,7 @@ describe('Test videos API validator', function () { }) it('Should fail without a channel', async function () { - const fields = omit(baseCorrectParams, 'channelId') + const fields = omit(baseCorrectParams, [ 'channelId' ]) const attaches = baseCorrectAttaches await checkUploadVideoParam(server, server.accessToken, { ...fields, ...attaches }, HttpStatusCode.BAD_REQUEST_400, mode) diff --git a/server/tests/api/moderation/video-blacklist.ts b/server/tests/api/moderation/video-blacklist.ts index 1790210ff..a7620b071 100644 --- a/server/tests/api/moderation/video-blacklist.ts +++ b/server/tests/api/moderation/video-blacklist.ts @@ -2,8 +2,8 @@ import 'mocha' import * as chai from 'chai' -import { orderBy } from 'lodash' import { FIXTURE_URLS } from '@server/tests/shared' +import { sortObjectComparator } from '@shared/core-utils' import { UserAdminFlag, UserRole, VideoBlacklist, VideoBlacklistType } from '@shared/models' import { BlacklistCommand, @@ -138,7 +138,7 @@ describe('Test video blacklist', function () { expect(blacklistedVideos).to.be.an('array') expect(blacklistedVideos.length).to.equal(2) - const result = orderBy(body.data, [ 'id' ], [ 'desc' ]) + const result = [ ...body.data ].sort(sortObjectComparator('id', 'desc')) expect(blacklistedVideos).to.deep.equal(result) }) @@ -150,7 +150,7 @@ describe('Test video blacklist', function () { expect(blacklistedVideos).to.be.an('array') expect(blacklistedVideos.length).to.equal(2) - const result = orderBy(body.data, [ 'name' ], [ 'desc' ]) + const result = [ ...body.data ].sort(sortObjectComparator('name', 'desc')) expect(blacklistedVideos).to.deep.equal(result) }) @@ -162,7 +162,7 @@ describe('Test video blacklist', function () { expect(blacklistedVideos).to.be.an('array') expect(blacklistedVideos.length).to.equal(2) - const result = orderBy(body.data, [ 'createdAt' ]) + const result = [ ...body.data ].sort(sortObjectComparator('createdAt', 'asc')) expect(blacklistedVideos).to.deep.equal(result) }) }) diff --git a/server/tests/api/transcoding/transcoder.ts b/server/tests/api/transcoding/transcoder.ts index 48a20e1d5..db0127805 100644 --- a/server/tests/api/transcoding/transcoder.ts +++ b/server/tests/api/transcoding/transcoder.ts @@ -1,11 +1,9 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ -import 'mocha' -import * as chai from 'chai' -import { omit } from 'lodash' +import { expect } from 'chai' import { canDoQuickTranscode } from '@server/helpers/ffmpeg' import { generateHighBitrateVideo, generateVideoWithFramerate, getAllFiles } from '@server/tests/shared' -import { buildAbsoluteFixturePath, getMaxBitrate, getMinLimitBitrate } from '@shared/core-utils' +import { buildAbsoluteFixturePath, getMaxBitrate, getMinLimitBitrate, omit } from '@shared/core-utils' import { buildFileMetadata, getAudioStream, @@ -26,8 +24,6 @@ import { webtorrentAdd } from '@shared/server-commands' -const expect = chai.expect - function updateConfigForTranscoding (server: PeerTubeServer) { return server.config.updateCustomSubConfig({ newConfig: { diff --git a/server/tests/client.ts b/server/tests/client.ts index a8a697f99..35b472d76 100644 --- a/server/tests/client.ts +++ b/server/tests/client.ts @@ -2,7 +2,7 @@ import 'mocha' import * as chai from 'chai' -import { omit } from 'lodash' +import { omit } from '@shared/core-utils' import { Account, HTMLServerConfig, @@ -31,7 +31,7 @@ function checkIndexTags (html: string, title: string, description: string, css: expect(html).to.contain('') expect(html).to.contain('') - const htmlConfig: HTMLServerConfig = omit(config, 'signup') + const htmlConfig: HTMLServerConfig = omit(config, [ 'signup' ]) const configObjectString = JSON.stringify(htmlConfig) const configEscapedString = JSON.stringify(configObjectString) diff --git a/shared/core-utils/common/object.ts b/shared/core-utils/common/object.ts index 49d209819..2330c9403 100644 --- a/shared/core-utils/common/object.ts +++ b/shared/core-utils/common/object.ts @@ -10,6 +10,19 @@ function pick (object: O, keys: K[]): Pick return result } +function omit (object: O, keys: K[]): Exclude { + const result: any = {} + const keysSet = new Set(keys) as Set + + for (const [ key, value ] of Object.entries(object)) { + if (keysSet.has(key)) continue + + result[key] = value + } + + return result +} + function getKeys (object: O, keys: K[]): K[] { return (Object.keys(object) as K[]).filter(k => keys.includes(k)) } @@ -30,6 +43,7 @@ function sortObjectComparator (key: string, order: 'asc' | 'desc') { export { pick, + omit, getKeys, sortObjectComparator } diff --git a/shared/server-commands/users/users-command.ts b/shared/server-commands/users/users-command.ts index b5ae9008e..d8303848d 100644 --- a/shared/server-commands/users/users-command.ts +++ b/shared/server-commands/users/users-command.ts @@ -1,5 +1,4 @@ -import { omit } from 'lodash' -import { pick } from '@shared/core-utils' +import { omit, pick } from '@shared/core-utils' import { HttpStatusCode, MyUser, @@ -298,7 +297,7 @@ export class UsersCommand extends AbstractCommand { updateMe (options: OverrideCommandOptions & UserUpdateMe) { const path = '/api/v1/users/me' - const toSend: UserUpdateMe = omit(options, 'url', 'accessToken') + const toSend: UserUpdateMe = omit(options, [ 'expectedStatus', 'token' ]) return this.putBodyRequest({ ...options, diff --git a/shared/server-commands/videos/live-command.ts b/shared/server-commands/videos/live-command.ts index 3df47ed4d..d804fd883 100644 --- a/shared/server-commands/videos/live-command.ts +++ b/shared/server-commands/videos/live-command.ts @@ -1,9 +1,8 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ import { readdir } from 'fs-extra' -import { omit } from 'lodash' import { join } from 'path' -import { wait } from '@shared/core-utils' +import { omit, wait } from '@shared/core-utils' import { HttpStatusCode, LiveVideo, @@ -103,7 +102,7 @@ export class LiveCommand extends AbstractCommand { path, attaches, - fields: omit(fields, 'thumbnailfile', 'previewfile'), + fields: omit(fields, [ 'thumbnailfile', 'previewfile' ]), implicitToken: true, defaultExpectedStatus: HttpStatusCode.OK_200 })) diff --git a/shared/server-commands/videos/playlists-command.ts b/shared/server-commands/videos/playlists-command.ts index ce23900d3..516da0bf7 100644 --- a/shared/server-commands/videos/playlists-command.ts +++ b/shared/server-commands/videos/playlists-command.ts @@ -1,5 +1,4 @@ -import { omit } from 'lodash' -import { pick } from '@shared/core-utils' +import { omit, pick } from '@shared/core-utils' import { BooleanBothQuery, HttpStatusCode, @@ -136,7 +135,7 @@ export class PlaylistsCommand extends AbstractCommand { }) { const path = '/api/v1/video-playlists' - const fields = omit(options.attributes, 'thumbnailfile') + const fields = omit(options.attributes, [ 'thumbnailfile' ]) const attaches = options.attributes.thumbnailfile ? { thumbnailfile: options.attributes.thumbnailfile } @@ -161,7 +160,7 @@ export class PlaylistsCommand extends AbstractCommand { }) { const path = '/api/v1/video-playlists/' + options.playlistId - const fields = omit(options.attributes, 'thumbnailfile') + const fields = omit(options.attributes, [ 'thumbnailfile' ]) const attaches = options.attributes.thumbnailfile ? { thumbnailfile: options.attributes.thumbnailfile } diff --git a/shared/server-commands/videos/videos-command.ts b/shared/server-commands/videos/videos-command.ts index c0b36d95b..168391523 100644 --- a/shared/server-commands/videos/videos-command.ts +++ b/shared/server-commands/videos/videos-command.ts @@ -3,9 +3,8 @@ import { expect } from 'chai' import { createReadStream, stat } from 'fs-extra' import got, { Response as GotResponse } from 'got' -import { omit } from 'lodash' import validator from 'validator' -import { buildAbsoluteFixturePath, pick, wait } from '@shared/core-utils' +import { buildAbsoluteFixturePath, omit, pick, wait } from '@shared/core-utils' import { buildUUID } from '@shared/extra-utils' import { HttpStatusCode, @@ -484,7 +483,7 @@ export class VideosCommand extends AbstractCommand { }, // Fixture will be sent later - attaches: this.buildUploadAttaches(omit(options.attributes, 'fixture')), + attaches: this.buildUploadAttaches(omit(options.attributes, [ 'fixture' ])), implicitToken: true, defaultExpectedStatus: null -- 2.41.0