Skip to content

Commit 00a875e

Browse files
authored
chore: close connection string input when opening form VSCODE-507 (#656)
1 parent dab9c53 commit 00a875e

File tree

7 files changed

+91
-24
lines changed

7 files changed

+91
-24
lines changed

src/connectionController.ts

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ export default class ConnectionController {
9090
private _currentConnectionId: null | string = null;
9191

9292
_connectionAttempt: null | ConnectionAttempt = null;
93+
_connectionStringInputCancellationToken: null | vscode.CancellationTokenSource =
94+
null;
9395
private _connectingConnectionId: null | string = null;
9496
private _disconnecting = false;
9597

@@ -144,33 +146,44 @@ export default class ConnectionController {
144146

145147
log.info('connectWithURI command called');
146148

147-
try {
148-
connectionString = await vscode.window.showInputBox({
149-
value: '',
150-
ignoreFocusOut: true,
151-
placeHolder:
152-
'e.g. mongodb+srv://username:[email protected]/admin',
153-
prompt: 'Enter your connection string (SRV or standard)',
154-
validateInput: (uri: string) => {
155-
if (
156-
!uri.startsWith('mongodb://') &&
157-
!uri.startsWith('mongodb+srv://')
158-
) {
159-
return 'MongoDB connection strings begin with "mongodb://" or "mongodb+srv://"';
160-
}
149+
const cancellationToken = new vscode.CancellationTokenSource();
150+
this._connectionStringInputCancellationToken = cancellationToken;
161151

162-
try {
163-
// eslint-disable-next-line no-new
164-
new ConnectionString(uri);
165-
} catch (error) {
166-
return formatError(error).message;
167-
}
168-
169-
return null;
152+
try {
153+
connectionString = await vscode.window.showInputBox(
154+
{
155+
value: '',
156+
ignoreFocusOut: true,
157+
placeHolder:
158+
'e.g. mongodb+srv://username:[email protected]/admin',
159+
prompt: 'Enter your connection string (SRV or standard)',
160+
validateInput: (uri: string) => {
161+
if (
162+
!uri.startsWith('mongodb://') &&
163+
!uri.startsWith('mongodb+srv://')
164+
) {
165+
return 'MongoDB connection strings begin with "mongodb://" or "mongodb+srv://"';
166+
}
167+
168+
try {
169+
// eslint-disable-next-line no-new
170+
new ConnectionString(uri);
171+
} catch (error) {
172+
return formatError(error).message;
173+
}
174+
175+
return null;
176+
},
170177
},
171-
});
178+
cancellationToken.token
179+
);
172180
} catch (e) {
173181
return false;
182+
} finally {
183+
if (this._connectionStringInputCancellationToken === cancellationToken) {
184+
this._connectionStringInputCancellationToken.dispose();
185+
this._connectionStringInputCancellationToken = null;
186+
}
174187
}
175188

176189
if (!connectionString) {
@@ -687,6 +700,10 @@ export default class ConnectionController {
687700
this.eventEmitter.removeListener(eventType, listener);
688701
}
689702

703+
closeConnectionStringInput() {
704+
this._connectionStringInputCancellationToken?.cancel();
705+
}
706+
690707
isConnecting(): boolean {
691708
return !!this._connectionAttempt;
692709
}

src/test/suite/connectionController.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,27 @@ suite('Connection Controller Test Suite', function () {
593593
assert.strictEqual(name, 'new connection name');
594594
});
595595

596+
test('close connection string input calls to cancel the cancellation token', function (done) {
597+
const inputBoxResolvesStub = sandbox.stub();
598+
inputBoxResolvesStub.callsFake(() => {
599+
try {
600+
const cancellationToken = inputBoxResolvesStub.firstCall.args[1];
601+
assert.strictEqual(cancellationToken.isCancellationRequested, false);
602+
603+
testConnectionController.closeConnectionStringInput();
604+
605+
assert.strictEqual(cancellationToken.isCancellationRequested, true);
606+
} catch (err) {
607+
done(err);
608+
}
609+
610+
done();
611+
});
612+
sandbox.replace(vscode.window, 'showInputBox', inputBoxResolvesStub);
613+
614+
void testConnectionController.connectWithURI();
615+
});
616+
596617
test('ConnectionQuickPicks workspace connections list is displayed in the alphanumerical case insensitive order', async () => {
597618
await vscode.workspace
598619
.getConfiguration('mdb.connectionSaving')

src/test/suite/views/webview-app/overview-page.test.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,15 @@ describe('OverviewPage test suite', function () {
4141
render(<OverviewPage />);
4242

4343
expect(screen.queryByTestId(connectionFormTestId)).to.not.exist;
44+
const postMessageSpy = Sinon.spy(vscode, 'postMessage');
45+
expect(postMessageSpy).to.not.be.called;
4446

4547
screen.getByText('Open form').click();
4648
expect(screen.getByTestId(connectionFormTestId)).to.exist;
49+
const message = postMessageSpy.firstCall.args[0];
50+
expect(message).to.deep.equal({
51+
command: MESSAGE_TYPES.CONNECTION_FORM_OPENED,
52+
});
4753

4854
screen.getByLabelText('Close modal').click();
4955
expect(screen.queryByTestId(connectionFormTestId)).to.not.exist;

src/views/webview-app/extension-app-message-constants.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export enum MESSAGE_TYPES {
1515
CONNECT = 'CONNECT',
1616
CANCEL_CONNECT = 'CANCEL_CONNECT',
1717
CONNECT_RESULT = 'CONNECT_RESULT',
18+
CONNECTION_FORM_OPENED = 'CONNECTION_FORM_OPENED',
1819
CONNECTION_STATUS_MESSAGE = 'CONNECTION_STATUS_MESSAGE',
1920
EXTENSION_LINK_CLICKED = 'EXTENSION_LINK_CLICKED',
2021
CREATE_NEW_PLAYGROUND = 'CREATE_NEW_PLAYGROUND',
@@ -33,6 +34,10 @@ export interface CreateNewPlaygroundMessage extends BasicWebviewMessage {
3334
command: MESSAGE_TYPES.CREATE_NEW_PLAYGROUND;
3435
}
3536

37+
export interface ConnectionFormOpenedMessage extends BasicWebviewMessage {
38+
command: MESSAGE_TYPES.CONNECTION_FORM_OPENED;
39+
}
40+
3641
export interface ConnectionStatusMessage extends BasicWebviewMessage {
3742
command: MESSAGE_TYPES.CONNECTION_STATUS_MESSAGE;
3843
connectionStatus: CONNECTION_STATUS;
@@ -90,6 +95,7 @@ export interface ThemeChangedMessage extends BasicWebviewMessage {
9095
export type MESSAGE_FROM_WEBVIEW_TO_EXTENSION =
9196
| ConnectMessage
9297
| CancelConnectMessage
98+
| ConnectionFormOpenedMessage
9399
| CreateNewPlaygroundMessage
94100
| GetConnectionStatusMessage
95101
| LinkClickedMessage

src/views/webview-app/use-connection-form.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { ConnectionOptions } from 'mongodb-data-service';
44
import {
55
sendConnectToExtension,
66
sendCancelConnectToExtension,
7+
sendFormOpenedToExtension,
78
} from './vscode-api';
89
import { MESSAGE_TYPES } from './extension-app-message-constants';
910
import type { MESSAGE_FROM_EXTENSION_TO_WEBVIEW } from './extension-app-message-constants';
@@ -37,7 +38,10 @@ export default function useConnectionForm() {
3738
connectionFormOpened,
3839
isConnecting,
3940
connectionErrorMessage,
40-
openConnectionForm: () => setConnectionFormOpened(true),
41+
openConnectionForm: () => {
42+
setConnectionFormOpened(true);
43+
sendFormOpenedToExtension();
44+
},
4145
closeConnectionForm: () => {
4246
setConnectionFormOpened(false);
4347
setConnectionErrorMessage('');

src/views/webview-app/vscode-api.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ export const sendCancelConnectToExtension = () => {
2828
});
2929
};
3030

31+
// When the form is opened we want to close the connection string
32+
// input if it's open, so we message the extension.
33+
export const sendFormOpenedToExtension = () => {
34+
vscode.postMessage({
35+
command: MESSAGE_TYPES.CONNECTION_FORM_OPENED,
36+
});
37+
};
38+
3139
export const renameActiveConnection = () => {
3240
vscode.postMessage({
3341
command: MESSAGE_TYPES.RENAME_ACTIVE_CONNECTION,

src/views/webviewController.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,11 @@ export default class WebviewController {
159159
EXTENSION_COMMANDS.MDB_CREATE_PLAYGROUND_FROM_OVERVIEW_PAGE
160160
);
161161
return;
162+
case MESSAGE_TYPES.CONNECTION_FORM_OPENED:
163+
// If the connection string input is open we want to close it
164+
// when the user opens the form.
165+
this._connectionController.closeConnectionStringInput();
166+
return;
162167
case MESSAGE_TYPES.GET_CONNECTION_STATUS:
163168
void panel.webview.postMessage({
164169
command: MESSAGE_TYPES.CONNECTION_STATUS_MESSAGE,

0 commit comments

Comments
 (0)