Skip to content

Commit

Permalink
chore: close connection string input when opening form VSCODE-507 (#656)
Browse files Browse the repository at this point in the history
  • Loading branch information
Anemy authored Jan 12, 2024
1 parent dab9c53 commit 00a875e
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 24 deletions.
63 changes: 40 additions & 23 deletions src/connectionController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ export default class ConnectionController {
private _currentConnectionId: null | string = null;

_connectionAttempt: null | ConnectionAttempt = null;
_connectionStringInputCancellationToken: null | vscode.CancellationTokenSource =
null;
private _connectingConnectionId: null | string = null;
private _disconnecting = false;

Expand Down Expand Up @@ -144,33 +146,44 @@ export default class ConnectionController {

log.info('connectWithURI command called');

try {
connectionString = await vscode.window.showInputBox({
value: '',
ignoreFocusOut: true,
placeHolder:
'e.g. mongodb+srv://username:[email protected]/admin',
prompt: 'Enter your connection string (SRV or standard)',
validateInput: (uri: string) => {
if (
!uri.startsWith('mongodb://') &&
!uri.startsWith('mongodb+srv://')
) {
return 'MongoDB connection strings begin with "mongodb://" or "mongodb+srv://"';
}
const cancellationToken = new vscode.CancellationTokenSource();
this._connectionStringInputCancellationToken = cancellationToken;

try {
// eslint-disable-next-line no-new
new ConnectionString(uri);
} catch (error) {
return formatError(error).message;
}

return null;
try {
connectionString = await vscode.window.showInputBox(
{
value: '',
ignoreFocusOut: true,
placeHolder:
'e.g. mongodb+srv://username:[email protected]/admin',
prompt: 'Enter your connection string (SRV or standard)',
validateInput: (uri: string) => {
if (
!uri.startsWith('mongodb://') &&
!uri.startsWith('mongodb+srv://')
) {
return 'MongoDB connection strings begin with "mongodb://" or "mongodb+srv://"';
}

try {
// eslint-disable-next-line no-new
new ConnectionString(uri);
} catch (error) {
return formatError(error).message;
}

return null;
},
},
});
cancellationToken.token
);
} catch (e) {
return false;
} finally {
if (this._connectionStringInputCancellationToken === cancellationToken) {
this._connectionStringInputCancellationToken.dispose();
this._connectionStringInputCancellationToken = null;
}
}

if (!connectionString) {
Expand Down Expand Up @@ -687,6 +700,10 @@ export default class ConnectionController {
this.eventEmitter.removeListener(eventType, listener);
}

closeConnectionStringInput() {
this._connectionStringInputCancellationToken?.cancel();
}

isConnecting(): boolean {
return !!this._connectionAttempt;
}
Expand Down
21 changes: 21 additions & 0 deletions src/test/suite/connectionController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,27 @@ suite('Connection Controller Test Suite', function () {
assert.strictEqual(name, 'new connection name');
});

test('close connection string input calls to cancel the cancellation token', function (done) {
const inputBoxResolvesStub = sandbox.stub();
inputBoxResolvesStub.callsFake(() => {
try {
const cancellationToken = inputBoxResolvesStub.firstCall.args[1];
assert.strictEqual(cancellationToken.isCancellationRequested, false);

testConnectionController.closeConnectionStringInput();

assert.strictEqual(cancellationToken.isCancellationRequested, true);
} catch (err) {
done(err);
}

done();
});
sandbox.replace(vscode.window, 'showInputBox', inputBoxResolvesStub);

void testConnectionController.connectWithURI();
});

test('ConnectionQuickPicks workspace connections list is displayed in the alphanumerical case insensitive order', async () => {
await vscode.workspace
.getConfiguration('mdb.connectionSaving')
Expand Down
6 changes: 6 additions & 0 deletions src/test/suite/views/webview-app/overview-page.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,15 @@ describe('OverviewPage test suite', function () {
render(<OverviewPage />);

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

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

screen.getByLabelText('Close modal').click();
expect(screen.queryByTestId(connectionFormTestId)).to.not.exist;
Expand Down
6 changes: 6 additions & 0 deletions src/views/webview-app/extension-app-message-constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export enum MESSAGE_TYPES {
CONNECT = 'CONNECT',
CANCEL_CONNECT = 'CANCEL_CONNECT',
CONNECT_RESULT = 'CONNECT_RESULT',
CONNECTION_FORM_OPENED = 'CONNECTION_FORM_OPENED',
CONNECTION_STATUS_MESSAGE = 'CONNECTION_STATUS_MESSAGE',
EXTENSION_LINK_CLICKED = 'EXTENSION_LINK_CLICKED',
CREATE_NEW_PLAYGROUND = 'CREATE_NEW_PLAYGROUND',
Expand All @@ -33,6 +34,10 @@ export interface CreateNewPlaygroundMessage extends BasicWebviewMessage {
command: MESSAGE_TYPES.CREATE_NEW_PLAYGROUND;
}

export interface ConnectionFormOpenedMessage extends BasicWebviewMessage {
command: MESSAGE_TYPES.CONNECTION_FORM_OPENED;
}

export interface ConnectionStatusMessage extends BasicWebviewMessage {
command: MESSAGE_TYPES.CONNECTION_STATUS_MESSAGE;
connectionStatus: CONNECTION_STATUS;
Expand Down Expand Up @@ -90,6 +95,7 @@ export interface ThemeChangedMessage extends BasicWebviewMessage {
export type MESSAGE_FROM_WEBVIEW_TO_EXTENSION =
| ConnectMessage
| CancelConnectMessage
| ConnectionFormOpenedMessage
| CreateNewPlaygroundMessage
| GetConnectionStatusMessage
| LinkClickedMessage
Expand Down
6 changes: 5 additions & 1 deletion src/views/webview-app/use-connection-form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { ConnectionOptions } from 'mongodb-data-service';
import {
sendConnectToExtension,
sendCancelConnectToExtension,
sendFormOpenedToExtension,
} from './vscode-api';
import { MESSAGE_TYPES } from './extension-app-message-constants';
import type { MESSAGE_FROM_EXTENSION_TO_WEBVIEW } from './extension-app-message-constants';
Expand Down Expand Up @@ -37,7 +38,10 @@ export default function useConnectionForm() {
connectionFormOpened,
isConnecting,
connectionErrorMessage,
openConnectionForm: () => setConnectionFormOpened(true),
openConnectionForm: () => {
setConnectionFormOpened(true);
sendFormOpenedToExtension();
},
closeConnectionForm: () => {
setConnectionFormOpened(false);
setConnectionErrorMessage('');
Expand Down
8 changes: 8 additions & 0 deletions src/views/webview-app/vscode-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ export const sendCancelConnectToExtension = () => {
});
};

// When the form is opened we want to close the connection string
// input if it's open, so we message the extension.
export const sendFormOpenedToExtension = () => {
vscode.postMessage({
command: MESSAGE_TYPES.CONNECTION_FORM_OPENED,
});
};

export const renameActiveConnection = () => {
vscode.postMessage({
command: MESSAGE_TYPES.RENAME_ACTIVE_CONNECTION,
Expand Down
5 changes: 5 additions & 0 deletions src/views/webviewController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ export default class WebviewController {
EXTENSION_COMMANDS.MDB_CREATE_PLAYGROUND_FROM_OVERVIEW_PAGE
);
return;
case MESSAGE_TYPES.CONNECTION_FORM_OPENED:
// If the connection string input is open we want to close it
// when the user opens the form.
this._connectionController.closeConnectionStringInput();
return;
case MESSAGE_TYPES.GET_CONNECTION_STATUS:
void panel.webview.postMessage({
command: MESSAGE_TYPES.CONNECTION_STATUS_MESSAGE,
Expand Down

0 comments on commit 00a875e

Please sign in to comment.