diff --git a/src/connection_string.ts b/src/connection_string.ts index 5b3da011ed4..bac2a13207f 100644 --- a/src/connection_string.ts +++ b/src/connection_string.ts @@ -33,7 +33,6 @@ import type { TagSet } from './sdam/server_description'; import { DEFAULT_PK_FACTORY, emitWarning, - emitWarningOnce, HostAddress, isRecord, matchesParentDomain, @@ -162,29 +161,16 @@ function checkTLSOptions(allOptions: CaseInsensitiveMap): void { check('tlsAllowInvalidCertificates', 'tlsDisableOCSPEndpointCheck'); check('tlsDisableCertificateRevocationCheck', 'tlsDisableOCSPEndpointCheck'); } - -const TRUTHS = new Set(['true', 't', '1', 'y', 'yes']); -const FALSEHOODS = new Set(['false', 'f', '0', 'n', 'no', '-1']); function getBoolean(name: string, value: unknown): boolean { if (typeof value === 'boolean') return value; - const valueString = String(value).toLowerCase(); - if (TRUTHS.has(valueString)) { - if (valueString !== 'true') { - emitWarningOnce( - `deprecated value for ${name} : ${valueString} - please update to ${name} : true instead` - ); - } - return true; - } - if (FALSEHOODS.has(valueString)) { - if (valueString !== 'false') { - emitWarningOnce( - `deprecated value for ${name} : ${valueString} - please update to ${name} : false instead` - ); - } - return false; + switch (value) { + case 'true': + return true; + case 'false': + return false; + default: + throw new MongoParseError(`${name} must be either "true" or "false"`); } - throw new MongoParseError(`Expected ${name} to be stringified boolean value, got: ${value}`); } function getIntFromOptions(name: string, value: unknown): number { diff --git a/test/unit/assorted/uri_options.spec.test.ts b/test/unit/assorted/uri_options.spec.test.ts index 8420ff38709..f6ac356df9f 100644 --- a/test/unit/assorted/uri_options.spec.test.ts +++ b/test/unit/assorted/uri_options.spec.test.ts @@ -14,16 +14,18 @@ describe('URI option spec tests', function () { 'tlsDisableCertificateRevocationCheck can be set to true', 'tlsDisableCertificateRevocationCheck can be set to false', 'tlsDisableOCSPEndpointCheck can be set to true', - 'tlsDisableOCSPEndpointCheck can be set to false' + 'tlsDisableOCSPEndpointCheck can be set to false', + + // NOTE(NODE-3989): Skipped because we now only accept true/false for boolean options. The spec expects us to + // warn on other accepted but deprecated values, but as of NODE-3989, we now throw on these + // values + 'Invalid loadBalanced value' ]; const testsThatDoNotThrowOnWarn = [ // TODO(NODE-3923): compression option validation 'Too high zlibCompressionLevel causes a warning', - 'Too low zlibCompressionLevel causes a warning', - - // TODO(NODE-3989): Fix legacy boolean parsing - 'Invalid loadBalanced value' + 'Too low zlibCompressionLevel causes a warning' ]; for (const suite of suites) { diff --git a/test/unit/connection_string.test.ts b/test/unit/connection_string.test.ts index 54c4733aa2f..98866db767e 100644 --- a/test/unit/connection_string.test.ts +++ b/test/unit/connection_string.test.ts @@ -211,13 +211,38 @@ describe('Connection String', function () { }); }); - it('should parse boolean values', function () { - let options = parseOptions('mongodb://hostname?retryWrites=1'); - expect(options.retryWrites).to.equal(true); - options = parseOptions('mongodb://hostname?retryWrites=false'); - expect(options.retryWrites).to.equal(false); - options = parseOptions('mongodb://hostname?retryWrites=t'); - expect(options.retryWrites).to.equal(true); + context('boolean options', function () { + const valuesExpectations: { value: string; expectation: 'error' | boolean }[] = [ + { value: 'true', expectation: true }, + { value: 'false', expectation: false }, + { value: '-1', expectation: 'error' }, + { value: '1', expectation: 'error' }, + { value: '0', expectation: 'error' }, + { value: 't', expectation: 'error' }, + { value: 'f', expectation: 'error' }, + { value: 'n', expectation: 'error' }, + { value: 'y', expectation: 'error' }, + { value: 'yes', expectation: 'error' }, + { value: 'no', expectation: 'error' }, + { value: 'unknown', expectation: 'error' } + ]; + for (const { value, expectation } of valuesExpectations) { + const connString = `mongodb://hostname?retryWrites=${value}`; + context(`when provided '${value}'`, function () { + if (expectation === 'error') { + it('throws MongoParseError', function () { + expect(() => { + parseOptions(connString); + }).to.throw(MongoParseError); + }); + } else { + it(`parses as ${expectation}`, function () { + const options = parseOptions(connString); + expect(options).to.have.property('retryWrites', expectation); + }); + } + }); + } }); it('should parse compression options', function () {