Skip to content

Commit

Permalink
refactor: Add validation for serverApi version and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dariakp committed May 17, 2021
1 parent 393ba90 commit f420e36
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 6 deletions.
23 changes: 19 additions & 4 deletions src/connection_string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ import {
MongoClientOptions,
MongoOptions,
PkFactory,
ServerApi
ServerApi,
ServerApiVersion
} from './mongo_client';
import { MongoCredentials } from './cmap/auth/mongo_credentials';
import type { TagSet } from './sdam/server_description';
Expand Down Expand Up @@ -590,10 +591,24 @@ export const OPTIONS = {
serverApi: {
target: 'serverApi',
transform({ values: [version] }): ServerApi {
if (typeof version === 'string') {
return { version };
const serverApiToValidate =
typeof version === 'string' ? ({ version } as ServerApi) : (version as ServerApi);
const versionToValidate = serverApiToValidate && serverApiToValidate.version;
if (!versionToValidate) {
throw new MongoParseError(
`Invalid \`serverApi\` property; must specify a version as one of the following strings: "${Object.values(
ServerApiVersion
).join('", "')}"`
);
}
if (!Object.values(ServerApiVersion).some(v => v === versionToValidate)) {
throw new MongoParseError(
`Invalid server API version=${versionToValidate}; must be one of the following strings: "${Object.values(
ServerApiVersion
).join('", "')}"`
);
}
return version as ServerApi;
return serverApiToValidate;
}
},
checkKeys: {
Expand Down
2 changes: 1 addition & 1 deletion src/mongo_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export type ServerApiVersion = typeof ServerApiVersion[keyof typeof ServerApiVer

/** @public */
export interface ServerApi {
version: string | ServerApiVersion;
version: ServerApiVersion;
strict?: boolean;
deprecationErrors?: boolean;
}
Expand Down
70 changes: 69 additions & 1 deletion test/unit/mongo_client_options.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const { WriteConcern } = require('../../src/write_concern');
const { ReadPreference } = require('../../src/read_preference');
const { Logger } = require('../../src/logger');
const { MongoCredentials } = require('../../src/cmap/auth/mongo_credentials');
const { MongoClient, MongoParseError } = require('../../src');
const { MongoClient, MongoParseError, ServerApiVersion } = require('../../src');

describe('MongoOptions', function () {
it('MongoClient should always freeze public options', function () {
Expand Down Expand Up @@ -122,6 +122,7 @@ describe('MongoOptions', function () {
serializeFunctions: true,
serverSelectionTimeoutMS: 3,
servername: 'some tls option',
serverApi: { version: '1' },
socketTimeoutMS: 3,
ssl: true,
sslPass: 'pass',
Expand Down Expand Up @@ -369,4 +370,71 @@ describe('MongoOptions', function () {
expect(optionsUndefined.rejectUnauthorized).to.equal(undefined);
expect(optionsUndefined.checkServerIdentity).to.equal(undefined);
});

describe('serverApi', function () {
it('is supported as a client option when it is a valid ServerApiVersion string', function () {
const validVersions = Object.values(ServerApiVersion);
expect(validVersions.length).to.be.at.least(1);
for (const version of validVersions) {
const result = parseOptions('mongodb://localhost/', {
serverApi: version
});
expect(result).to.have.property('serverApi').deep.equal({ version });
}
});

it('is supported as a client option when it is an object with a valid version property', function () {
const validVersions = Object.values(ServerApiVersion);
expect(validVersions.length).to.be.at.least(1);
for (const version of validVersions) {
const result = parseOptions('mongodb://localhost/', {
serverApi: { version }
});
expect(result).to.have.property('serverApi').deep.equal({ version });
}
});

it('is not supported as a client option when it is an invalid string', function () {
expect(() =>
parseOptions('mongodb://localhost/', {
serverApi: 'bad'
})
).to.throw(/^Invalid server API version=bad;/);
});

it('is not supported as a client option when it is a number', function () {
expect(() =>
parseOptions('mongodb://localhost/', {
serverApi: 1
})
).to.throw(/^Invalid `serverApi` property;/);
});

it('is not supported as a client option when it is an object without a specified version', function () {
expect(() =>
parseOptions('mongodb://localhost/', {
serverApi: {}
})
).to.throw(/^Invalid `serverApi` property;/);
});

it('is not supported as a client option when it is an object with an invalid specified version', function () {
expect(() =>
parseOptions('mongodb://localhost/', {
serverApi: { version: 1 }
})
).to.throw(/^Invalid server API version=1;/);
expect(() =>
parseOptions('mongodb://localhost/', {
serverApi: { version: 'bad' }
})
).to.throw(/^Invalid server API version=bad;/);
});

it('is not supported as a URI option even when it is a valid ServerApiVersion string', function () {
expect(() => parseOptions('mongodb://localhost/?serverApi=1')).to.throw(
'URI cannot contain `serverApi`, it can only be passed to the client'
);
});
});
});

0 comments on commit f420e36

Please sign in to comment.