quosdolorem
Version:
The MongoDB Shell
351 lines (298 loc) • 13 kB
text/typescript
import { CommonErrors, MongoshInvalidInputError } from '@mongosh/errors';
import { expect } from 'chai';
import generateUri from './uri-generator';
describe('uri-generator.generate-uri', () => {
context('when no arguments are provided', () => {
const options = { _: [] };
it('returns the default uri', () => {
expect(generateUri(options)).to.equal('mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000');
});
});
context('when no URI is provided', () => {
it('handles host', () => {
expect(generateUri({ _: [], host: 'localhost' })).to.equal('mongodb://localhost:27017/?directConnection=true&serverSelectionTimeoutMS=2000');
});
it('handles port', () => {
expect(generateUri({ _: [], port: '27018' })).to.equal('mongodb://127.0.0.1:27018/?directConnection=true&serverSelectionTimeoutMS=2000');
});
it('handles both host and port', () => {
expect(generateUri({ _: [], host: 'localhost', port: '27018' })).to.equal('mongodb://localhost:27018/?directConnection=true&serverSelectionTimeoutMS=2000');
});
it('handles host with port included', () => {
expect(generateUri({ _: [], host: 'localhost:27018' })).to.equal('mongodb://localhost:27018/?directConnection=true&serverSelectionTimeoutMS=2000');
});
it('throws if host has port AND port set to other value', () => {
try {
generateUri({ _: [], host: 'localhost:27018', port: '27019' });
expect.fail('expected error');
} catch (e) {
expect(e).to.be.instanceOf(MongoshInvalidInputError);
expect(e.code).to.equal(CommonErrors.InvalidArgument);
}
});
it('handles host has port AND port set to equal value', () => {
expect(generateUri({ _: [], host: 'localhost:27018', port: '27018' })).to.equal('mongodb://localhost:27018/?directConnection=true&serverSelectionTimeoutMS=2000');
});
});
context('when a full URI is provided', () => {
context('when no additional options are provided', () => {
const options = { _: ['mongodb://192.0.0.1:27018/foo'] };
it('returns the uri', () => {
expect(generateUri(options)).to.equal('mongodb://192.0.0.1:27018/foo?directConnection=true');
});
});
context('when additional options are provided', () => {
context('when providing host with URI', () => {
const uri = 'mongodb://192.0.0.1:27018/foo';
const options = { _: [uri], host: '127.0.0.1' };
it('throws an exception', () => {
try {
generateUri(options);
expect.fail('expected error');
} catch (e) {
expect(e).to.be.instanceOf(MongoshInvalidInputError);
expect(e.code).to.equal(CommonErrors.InvalidArgument);
}
});
});
context('when providing port with URI', () => {
const uri = 'mongodb://192.0.0.1:27018/foo';
const options = { _: [uri], port: '27018' };
it('throws an exception', () => {
try {
generateUri(options);
expect.fail('expected error');
} catch (e) {
expect(e.name).to.equal('MongoshInvalidInputError');
expect(e.code).to.equal(CommonErrors.InvalidArgument);
}
});
});
});
context('when providing a URI with query parameters', () => {
context('that do not conflict with directConnection', () => {
const uri = 'mongodb://192.0.0.1:27018?readPreference=primary';
const options = { _: [uri] };
it('still includes directConnection', () => {
expect(generateUri(options)).to.equal('mongodb://192.0.0.1:27018/?readPreference=primary&directConnection=true');
});
});
context('including replicaSet', () => {
const uri = 'mongodb://192.0.0.1:27018/db?replicaSet=replicaset';
const options = { _: [uri] };
it('does not add the directConnection parameter', () => {
expect(generateUri(options)).to.equal(uri);
});
});
context('including explicit directConnection', () => {
const uri = 'mongodb://192.0.0.1:27018/db?directConnection=false';
const options = { _: [uri] };
it('does not change the directConnection parameter', () => {
expect(generateUri(options)).to.equal(uri);
});
});
});
context('when providing a URI with SRV record', () => {
const uri = 'mongodb+srv://somehost/?readPreference=primary';
const options = { _: [uri] };
it('no directConnection is added', () => {
expect(generateUri(options)).to.equal(uri);
});
});
context('when providing a URI with multiple seeds', () => {
const uri = 'mongodb://192.42.42.42:27017,192.0.0.1:27018/db?readPreference=primary';
const options = { _: [uri] };
it('no directConnection is added', () => {
expect(generateUri(options)).to.equal(uri);
});
});
});
context('when a URI is provided without a scheme', () => {
context('when providing host', () => {
const uri = '192.0.0.1';
const options = { _: [uri] };
it('returns the uri with the scheme', () => {
expect(generateUri(options)).to.equal(`mongodb://${uri}:27017/test?directConnection=true`);
});
});
context('when providing host:port', () => {
const uri = '192.0.0.1:27018';
const options = { _: [uri] };
it('returns the uri with the scheme', () => {
expect(generateUri(options)).to.equal(`mongodb://${uri}/test?directConnection=true`);
});
});
context('when proving host + port option', () => {
const uri = '192.0.0.1';
const options = { _: [uri], port: '27018' };
it('throws an exception', () => {
try {
generateUri(options);
expect.fail('expected error');
} catch (e) {
expect(e).to.be.instanceOf(MongoshInvalidInputError);
expect(e.code).to.equal(CommonErrors.InvalidArgument);
}
});
});
context('when no additional options are provided without db', () => {
const uri = '192.0.0.1:27018';
const options = { _: [uri] };
it('returns the uri with the scheme', () => {
expect(generateUri(options)).to.equal(`mongodb://${uri}/test?directConnection=true`);
});
});
context('when no additional options are provided with empty db', () => {
const uri = '192.0.0.1:27018/';
const options = { _: [uri] };
it('returns the uri with the scheme', () => {
expect(generateUri(options)).to.equal(`mongodb://${uri}test?directConnection=true`);
});
});
context('when no additional options are provided with db', () => {
const uri = '192.0.0.1:27018/foo';
const options = { _: [uri] };
it('returns the uri with the scheme', () => {
expect(generateUri(options)).to.equal(`mongodb://${uri}?directConnection=true`);
});
});
context('when additional options are provided', () => {
context('when providing host with URI', () => {
const uri = '192.0.0.1:27018/foo';
const options = { _: [uri], host: '127.0.0.1' };
it('throws an exception', () => {
try {
generateUri(options);
expect.fail('expected error');
} catch (e) {
expect(e).to.be.instanceOf(MongoshInvalidInputError);
expect(e.code).to.equal(CommonErrors.InvalidArgument);
}
});
});
context('when providing host with db', () => {
const uri = 'foo';
const options = { _: [uri], host: '127.0.0.2' };
it('uses the provided host with default port', () => {
expect(generateUri(options)).to.equal('mongodb://127.0.0.2:27017/foo?directConnection=true');
});
});
context('when providing port with URI', () => {
const uri = '192.0.0.1:27018/foo';
const options = { _: [uri], port: '27018' };
it('throws an exception', () => {
try {
generateUri(options);
expect.fail('expected error');
} catch (e) {
expect(e).to.be.instanceOf(MongoshInvalidInputError);
expect(e.code).to.equal(CommonErrors.InvalidArgument);
}
});
});
context('when providing port with db', () => {
const uri = 'foo';
const options = { _: [uri], port: '27018' };
it('uses the provided host with default port', () => {
expect(generateUri(options)).to.equal('mongodb://127.0.0.1:27018/foo?directConnection=true&serverSelectionTimeoutMS=2000');
});
});
context('when providing port with only a host URI', () => {
const uri = '127.0.0.2/foo';
const options = { _: [uri], port: '27018' };
it('throws an exception', () => {
try {
generateUri(options);
expect.fail('expected error');
} catch (e) {
expect(e).to.be.instanceOf(MongoshInvalidInputError);
expect(e.code).to.equal(CommonErrors.InvalidArgument);
}
});
});
context('when providing nodb', () => {
const uri = 'mongodb://127.0.0.2/foo';
const options = { _: [uri], nodb: true };
it('returns an empty string', () => {
expect(generateUri(options)).to.equal('');
});
});
context('when providing explicit serverSelectionTimeoutMS', () => {
const uri = 'mongodb://127.0.0.2/foo?serverSelectionTimeoutMS=10';
const options = { _: [uri] };
it('does not override the existing value', () => {
expect(generateUri(options)).to.equal('mongodb://127.0.0.2/foo?serverSelectionTimeoutMS=10&directConnection=true');
});
});
context('when providing explicit serverSelectionTimeoutMS (different case)', () => {
const uri = 'mongodb://127.0.0.2/foo?SERVERSELECTIONTIMEOUTMS=10';
const options = { _: [uri] };
it('does not override the existing value', () => {
expect(generateUri(options)).to.equal('mongodb://127.0.0.2/foo?SERVERSELECTIONTIMEOUTMS=10&directConnection=true');
});
});
});
context('when providing a URI with query parameters', () => {
context('that do not conflict with directConnection', () => {
const uri = '192.0.0.1:27018?readPreference=primary';
const options = { _: [uri] };
it('still includes directConnection', () => {
expect(generateUri(options)).to.equal('mongodb://192.0.0.1:27018/?readPreference=primary&directConnection=true');
});
});
context('including replicaSet', () => {
const uri = '192.0.0.1:27018/db?replicaSet=replicaset';
const options = { _: [uri] };
it('does not add the directConnection parameter', () => {
expect(generateUri(options)).to.equal(`mongodb://${uri}`);
});
});
context('including explicit directConnection', () => {
const uri = '192.0.0.1:27018?directConnection=false';
const options = { _: [uri] };
it('does not change the directConnection parameter', () => {
expect(generateUri(options)).to.equal('mongodb://192.0.0.1:27018/?directConnection=false');
});
});
});
});
context('when an invalid URI is provided', () => {
const uri = '/x';
const options = { _: [uri] };
it('returns the uri', () => {
try {
generateUri(options);
} catch (e) {
expect(e.message).to.contain('Invalid URI: /x');
expect(e).to.be.instanceOf(MongoshInvalidInputError);
expect(e.code).to.equal(CommonErrors.InvalidArgument);
return;
}
expect.fail('expected error');
});
});
context('when the --host option contains invalid characters', () => {
const options = { host: 'a,b,c' };
it('returns the uri', () => {
try {
generateUri(options);
} catch (e) {
expect(e.message).to.contain('The --host argument contains an invalid character: ,');
expect(e).to.be.instanceOf(MongoshInvalidInputError);
expect(e.code).to.equal(CommonErrors.InvalidArgument);
return;
}
expect.fail('expected error');
});
});
context('when the --host option contains a replica set', () => {
it('returns a URI for the hosts and ports specified in --host', () => {
const options = { host: 'replsetname/host1:123,host2,host3:456,' };
expect(generateUri(options)).to.equal('mongodb://host1:123,host2,host3:456/test?replicaSet=replsetname');
});
it('returns a URI for the hosts and ports specified in --host and database name', () => {
const options = { host: 'replsetname/host1:123,host2,host3:456', _: ['admin'] };
expect(generateUri(options)).to.equal('mongodb://host1:123,host2,host3:456/admin?replicaSet=replsetname');
});
});
});