Skip to content

Commit dc01b32

Browse files
committed
Add connection-id support to the auto-connect feature
1 parent 95c01fb commit dc01b32

File tree

4 files changed

+88
-1
lines changed

4 files changed

+88
-1
lines changed

packages/compass-e2e-tests/tests/auto-connect.test.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import * as Selectors from '../helpers/selectors';
1212
import os from 'os';
1313
import path from 'path';
1414
import { promises as fs } from 'fs';
15+
import { DEFAULT_CONNECTION_NAMES } from '../helpers/test-runner-context';
1516

1617
const connectionStringSuccess = 'mongodb://127.0.0.1:27091/test';
1718
const connectionNameSuccess = 'Success';
@@ -21,6 +22,22 @@ const connectionNameUnreachable = 'Unreachable';
2122
const connectionStringInvalid = 'http://example.com';
2223
const connectionNameInvalid = 'Invalid';
2324

25+
async function createDefaultConnectionAndClose(name: string | undefined) {
26+
const compass = await init(name);
27+
try {
28+
const { browser } = compass;
29+
await browser.setupDefaultConnections();
30+
const connectionName = DEFAULT_CONNECTION_NAMES[0];
31+
const connectionId = await browser.getConnectionIdByName(connectionName);
32+
if (!connectionId) {
33+
throw new Error('Expected a connection id');
34+
}
35+
return { connectionName, connectionId };
36+
} finally {
37+
await cleanup(compass);
38+
}
39+
}
40+
2441
describe('Automatically connecting from the command line', function () {
2542
let tmpdir: string;
2643
let i = 0;
@@ -127,6 +144,22 @@ describe('Automatically connecting from the command line', function () {
127144
}
128145
});
129146

147+
it('works with a connection id on the command line', async function () {
148+
// Create the connection
149+
const { connectionId, connectionName } =
150+
await createDefaultConnectionAndClose(this.test?.fullTitle());
151+
const compass = await init(this.test?.fullTitle(), {
152+
wrapBinary: positionalArgs([connectionId]),
153+
// reuse the same user directory so we'd get the same connections
154+
firstRun: false,
155+
});
156+
try {
157+
await waitForConnectionSuccessAndCheckConnection(compass, connectionName);
158+
} finally {
159+
await cleanup(compass);
160+
}
161+
});
162+
130163
it('fails with an unreachable URL', async function () {
131164
const args = [
132165
`--file=${path.join(tmpdir, 'exported.json')}`,

packages/compass/src/main/auto-connect.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { hasDisallowedConnectionStringOptions } from './validate-connection-stri
55
import COMPASS_ICON from './icon';
66
import { createLogger, mongoLogId } from '@mongodb-js/compass-logging';
77
import { redactConnectionString } from 'mongodb-connection-string-url';
8+
import { UUID } from 'mongodb';
89
const { log } = createLogger('COMPASS-AUTO-CONNECT-MAIN');
910

1011
export type AutoConnectPreferences = Partial<
@@ -22,7 +23,7 @@ export type AutoConnectPreferences = Partial<
2223
let autoConnectWindow: BrowserWindow['id'] | undefined = undefined;
2324
const browserWindowStates = new Map<
2425
BrowserWindow['id'],
25-
{ url?: string; disconnected?: boolean }
26+
{ url?: string; connectionId?: string; disconnected?: boolean }
2627
>();
2728

2829
export function resetForTesting(): void {
@@ -73,6 +74,16 @@ export function registerMongoDbUrlForBrowserWindow(
7374
browserWindowStates.set(bw.id, { url });
7475
}
7576

77+
export function registerConnectionIdForBrowserWindow(
78+
bw: Pick<BrowserWindow, 'id'> | undefined | null,
79+
connectionId: string
80+
): void {
81+
if (!bw) {
82+
return;
83+
}
84+
browserWindowStates.set(bw.id, { connectionId });
85+
}
86+
7687
export const getConnectionStringFromArgs = (args?: string[]) => args?.[0];
7788

7889
const shouldPreventAutoConnect = async ({
@@ -111,6 +122,14 @@ export async function getWindowAutoConnectPreferences(
111122

112123
const windowState = browserWindowStates.get(id);
113124

125+
// Auto connect to any connection ID, right away
126+
if (windowState?.connectionId) {
127+
return Promise.resolve({
128+
positionalArguments: [windowState.connectionId],
129+
shouldAutoConnect: true,
130+
});
131+
}
132+
114133
// Do not auto-connect in Compass windows other than the primary/first-created one.
115134
// Do auto-connect if this is a new window on macos that has been opened via open-url.
116135
if (autoConnectWindow !== id && !windowState?.url) {
@@ -148,6 +167,17 @@ export async function getWindowAutoConnectPreferences(
148167
trustedConnectionString,
149168
} = preferences.getPreferences();
150169

170+
// Auto connect to any connection ID, right away
171+
if (
172+
positionalArguments?.length === 1 &&
173+
UUID.isValid(positionalArguments[0])
174+
) {
175+
return Promise.resolve({
176+
positionalArguments: [positionalArguments[0]],
177+
shouldAutoConnect: true,
178+
});
179+
}
180+
151181
// The about: accounts for webdriverio in the e2e tests appending the argument for every run
152182
if (
153183
!file &&

packages/connection-storage/src/compass-main-connection-storage.spec.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,6 +1379,19 @@ describe('ConnectionStorage', function () {
13791379
);
13801380
});
13811381

1382+
it('should return autoConnectInfo when an existing connection id is provided', async function () {
1383+
const connectionInfo = getConnectionInfo({ lastUsed: new Date() });
1384+
await writeFakeConnection(tmpDir, { connectionInfo });
1385+
const info = await connectionStorage.getAutoConnectInfo({
1386+
shouldAutoConnect: true,
1387+
positionalArguments: [connectionInfo.id],
1388+
});
1389+
expect(info?.id).to.equal(connectionInfo.id);
1390+
expect(info?.connectionOptions).to.deep.equal(
1391+
connectionInfo.connectionOptions
1392+
);
1393+
});
1394+
13821395
context('when autoConnectInfo is available', function () {
13831396
beforeEach(async function () {
13841397
await connectionStorage.getAutoConnectInfo({

packages/connection-storage/src/compass-main-connection-storage.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,17 @@ class CompassMainConnectionStorage implements ConnectionStorage {
298298
password,
299299
});
300300
} else {
301+
// Assuming the positional argument refers to an existing connection id
302+
if (positionalArguments.length === 1) {
303+
// Attempt to load it and return if found
304+
const possibleConnection = await this.load({
305+
id: positionalArguments[0],
306+
});
307+
if (possibleConnection) {
308+
return possibleConnection;
309+
}
310+
}
311+
// Determine if this is a valid connection string or a connection ID
301312
const connectionString = getConnectionStringFromArgs(positionalArguments);
302313
if (!connectionString) {
303314
throw new Error('Could not find a connection string');

0 commit comments

Comments
 (0)