Skip to content

Commit 8a09c9c

Browse files
authored
chore(connections): align multiple connections saving behavior with single connections mode COMPASS-8133 (#6097)
* chore(connections): align multiple connections saving behavior with single connection * chore(connections): run storage tests for both feature flag values
1 parent a163fa7 commit 8a09c9c

File tree

4 files changed

+50
-107
lines changed

4 files changed

+50
-107
lines changed

packages/compass-connections/src/stores/connections-store.spec.tsx

Lines changed: 41 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -304,95 +304,55 @@ describe('useConnections', function () {
304304
});
305305
});
306306

307-
describe('saving connections during connect in single connection mode', function () {
308-
it('should NOT update existing connection with new props when existing connection is successfull', async function () {
309-
await preferences.savePreferences({
310-
// We're testing multiple connections by default
311-
enableNewMultipleConnectionSystem: false,
307+
for (const multipleConnectionsEnabled of [true, false]) {
308+
describe(`when multiple connections ${
309+
multipleConnectionsEnabled ? 'enabled' : 'disabled'
310+
}`, function () {
311+
it('should NOT update existing connection with new props when existing connection is successfull', async function () {
312+
await preferences.savePreferences({
313+
enableNewMultipleConnectionSystem: multipleConnectionsEnabled,
314+
});
315+
316+
const connections = renderHookWithContext();
317+
const saveSpy = sinon.spy(mockConnectionStorage, 'save');
318+
319+
await connections.current.connect({
320+
...mockConnections[0],
321+
favorite: { name: 'foobar' },
322+
});
323+
324+
// Only once on success so that we're not updating existing connections if
325+
// they failed
326+
expect(saveSpy).to.have.been.calledOnce;
327+
expect(saveSpy.getCall(0)).to.have.nested.property(
328+
'args[0].connectionInfo.favorite.name',
329+
'turtles'
330+
);
312331
});
313332

314-
const connections = renderHookWithContext();
315-
const saveSpy = sinon.spy(mockConnectionStorage, 'save');
333+
it('should not update existing connection if connection failed', async function () {
334+
await preferences.savePreferences({
335+
enableNewMultipleConnectionSystem: multipleConnectionsEnabled,
336+
});
316337

317-
await connections.current.connect({
318-
...mockConnections[0],
319-
favorite: { name: 'foobar' },
320-
});
321-
322-
// Only once on success so that we're not updating existing connections if
323-
// they failed
324-
expect(saveSpy).to.have.been.calledOnce;
325-
expect(saveSpy.getCall(0)).to.have.nested.property(
326-
'args[0].connectionInfo.favorite.name',
327-
'turtles'
328-
);
329-
});
330-
331-
it('should not update existing connection if connection failed', async function () {
332-
await preferences.savePreferences({
333-
enableNewMultipleConnectionSystem: false,
334-
});
335-
336-
const saveSpy = sinon.spy(mockConnectionStorage, 'save');
337-
const onConnectionFailed = sinon.spy();
338-
const connections = renderHookWithContext({ onConnectionFailed });
339-
340-
sinon
341-
.stub(connectionsManager, 'connect')
342-
.rejects(new Error('Failed to connect'));
343-
344-
await connections.current.connect({
345-
...mockConnections[0],
346-
favorite: { name: 'foobar' },
347-
});
348-
349-
expect(onConnectionFailed).to.have.been.calledOnce;
350-
expect(saveSpy).to.not.have.been.called;
351-
});
352-
});
338+
const saveSpy = sinon.spy(mockConnectionStorage, 'save');
339+
const onConnectionFailed = sinon.spy();
340+
const connections = renderHookWithContext({ onConnectionFailed });
353341

354-
describe('saving connections during connect in multiple connections mode', function () {
355-
it('should update existing connection with new props when connection is successfull', async function () {
356-
const connections = renderHookWithContext();
357-
const saveSpy = sinon.spy(mockConnectionStorage, 'save');
342+
sinon
343+
.stub(connectionsManager, 'connect')
344+
.rejects(new Error('Failed to connect'));
358345

359-
await connections.current.connect({
360-
...mockConnections[0],
361-
favorite: { name: 'foobar' },
362-
});
346+
await connections.current.connect({
347+
...mockConnections[0],
348+
favorite: { name: 'foobar' },
349+
});
363350

364-
// Saved before and after in multiple connections mode
365-
expect(saveSpy).to.have.been.calledTwice;
366-
expect(saveSpy.getCall(0)).to.have.nested.property(
367-
'args[0].connectionInfo.favorite.name',
368-
'foobar'
369-
);
370-
expect(saveSpy.getCall(1)).to.have.nested.property(
371-
'args[0].connectionInfo.favorite.name',
372-
'foobar'
373-
);
374-
});
375-
376-
it('should always update existing connection even if conneciton will fail', async function () {
377-
const saveSpy = sinon.spy(mockConnectionStorage, 'save');
378-
const onConnectionFailed = sinon.spy();
379-
const connections = renderHookWithContext({ onConnectionFailed });
380-
381-
sinon
382-
.stub(connectionsManager, 'connect')
383-
.rejects(new Error('Failed to connect'));
384-
385-
await connections.current.connect({
386-
...mockConnections[0],
387-
connectionOptions: {
388-
connectionString: 'mongodb://super-broken-new-url',
389-
},
351+
expect(onConnectionFailed).to.have.been.calledOnce;
352+
expect(saveSpy).to.not.have.been.called;
390353
});
391-
392-
expect(onConnectionFailed).to.have.been.calledOnce;
393-
expect(saveSpy).to.have.been.calledOnce;
394354
});
395-
});
355+
}
396356
});
397357

398358
describe('#disconnect', function () {

packages/compass-connections/src/stores/connections-store.tsx

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useCallback, useEffect, useReducer, useRef } from 'react';
22
import type { DataService, connect } from 'mongodb-data-service';
33
import { useConnectionsManagerContext } from '../provider';
44
import { type ConnectionInfo } from '@mongodb-js/connection-storage/provider';
5-
import { cloneDeep, merge } from 'lodash';
5+
import { cloneDeep } from 'lodash';
66
import { UUID } from 'bson';
77
import { useToast } from '@mongodb-js/compass-components';
88
import { createLogger } from '@mongodb-js/compass-logging';
@@ -687,11 +687,6 @@ export function useConnections({
687687
// means to returning this info as part of the connections list for now
688688
if (!isAutoconnectAttempt) {
689689
if (
690-
// In single connection mode we only update existing connection when
691-
// we successfully connected. In multiple connections we don't care
692-
// if existing connection fails with errors and update it either way
693-
// before we finished connecting
694-
preferences.getPreferences().enableNewMultipleConnectionSystem ||
695690
// TODO(COMPASS-7397): The way the whole connection logic is set up
696691
// right now it is required that we save connection before starting
697692
// the connection process even if we don't need or want to so that
@@ -745,28 +740,16 @@ export function useConnections({
745740
});
746741

747742
try {
748-
const mergeConnectionInfo = preferences.getPreferences()
749-
.persistOIDCTokens
750-
? { connectionOptions: await dataService.getUpdatedSecrets() }
751-
: {};
752-
753743
// Auto-connect info should never be saved
754744
if (!isAutoconnectAttempt) {
745+
// After connection is established we only update lastUsed time and
746+
// maybe an OIDC token if preferences allow
755747
await saveConnectionInfo({
756-
...merge(
757-
// In single connection mode we only update the last used
758-
// timestamp and maybe an OIDC token, everything else is kept
759-
// as-is so that "Connect" and "Save" are distinct features (as
760-
// the button labels in the connection form suggest). In
761-
// multiple connections we update everything
762-
preferences.getPreferences().enableNewMultipleConnectionSystem
763-
? connectionInfo
764-
: // Existing connection info might be missing when connecting
765-
// to a new connection for the first time
766-
existingConnectionInfo ?? connectionInfo,
767-
mergeConnectionInfo
768-
),
748+
id: connectionInfo.id,
769749
lastUsed: new Date(),
750+
...(preferences.getPreferences().persistOIDCTokens
751+
? { connectionOptions: await dataService.getUpdatedSecrets() }
752+
: {}),
770753
});
771754
}
772755
} catch (err) {

packages/connection-form/src/components/connection-form-actions.spec.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ describe('<ConnectionFormModalActions />', function () {
3838
onSaveAndConnect={onSaveAndConnectSpy}
3939
></ConnectionFormModalActions>
4040
);
41-
const saveButton = screen.getByText('Save & Connect');
41+
const saveButton = screen.getByText('Connect');
4242
fireEvent(
4343
saveButton,
4444
new MouseEvent('click', {

packages/connection-form/src/components/connection-form-actions.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ export function ConnectionFormModalActions({
184184
variant={ButtonVariant.Primary}
185185
onClick={onSaveAndConnect}
186186
>
187-
Save &amp; Connect
187+
Connect
188188
</Button>
189189
</div>
190190
</div>

0 commit comments

Comments
 (0)