Skip to content

Commit

Permalink
feat: adds a new overview screen based on LeafyGreen components VSCOD…
Browse files Browse the repository at this point in the history
…E-485 (#617)

* feat: added a new overview screen using LG components

* fix: checking webpack fix on webview config

* chore: path/crypto-browserify are dev deps

* chore: added a small msg in reference to new webpack plugin

* Update src/test/suite/views/webview-app/connect-helper.test.tsx

Co-authored-by: Rhys <[email protected]>

* fix: colors based on dark/light mode of vscode theme

* Update src/views/webview-app/use-connection-status.ts

Co-authored-by: Rhys <[email protected]>

* fix: dispose the theme change subscription on deactivate

* chore: adds a focusRing for better accessibility of resources button

---------

Co-authored-by: Rhys <[email protected]>
  • Loading branch information
himanshusinghs and Anemy authored Dec 1, 2023
1 parent 76f57f0 commit 12bc65a
Show file tree
Hide file tree
Showing 29 changed files with 22,470 additions and 14,921 deletions.
35,920 changes: 21,005 additions & 14,915 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -979,6 +979,7 @@
"@iconify-icons/codicon": "^1.2.25",
"@iconify/react": "^1.1.4",
"@leafygreen-ui/logo": "^8.0.4",
"@mongodb-js/compass-components": "^1.19.0",
"@mongodb-js/mongodb-constants": "^0.7.1",
"@mongosh/browser-runtime-electron": "^2.0.2",
"@mongosh/i18n": "^2.0.2",
Expand Down Expand Up @@ -1047,6 +1048,7 @@
"chalk": "^4.1.2",
"cli-ux": "^5.6.7",
"cross-env": "^7.0.3",
"crypto-browserify": "^3.12.0",
"css-loader": "^6.8.1",
"depcheck": "^1.4.3",
"download": "^8.0.0",
Expand All @@ -1056,6 +1058,7 @@
"eslint-config-mongodb-js": "^5.0.3",
"eslint-plugin-mocha": "^10.1.0",
"execa": "^1.0.0",
"fork-ts-checker-webpack-plugin": "^9.0.2",
"glob": "^7.2.3",
"jest": "^26.6.3",
"jest-junit": "^12.3.0",
Expand All @@ -1071,6 +1074,7 @@
"node-loader": "^0.6.0",
"npm-run-all": "^4.1.5",
"ora": "^5.4.1",
"path-browserify": "^1.0.1",
"postcss-loader": "^7.3.3",
"pre-commit": "^1.2.2",
"prettier": "^2.8.8",
Expand Down
1 change: 1 addition & 0 deletions src/mdbExtensionController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -696,5 +696,6 @@ export default class MDBExtensionController implements vscode.Disposable {
this._playgroundController.deactivate();
this._telemetryService.deactivate();
this._editorsController.deactivate();
this._webviewController.deactivate();
}
}
2 changes: 1 addition & 1 deletion src/test/suite/views/webview-app/app.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ describe('App Component Test Suite', () => {
test('it renders the new overview page when useNewConnectionForm is truthy', () => {
sinon.stub(featureFlags, 'getFeatureFlag').returns(true);
render(<App />);
expect(() => screen.getAllByTestId('legacy-app')).to.throw;
expect(screen.queryByTestId('legacy-app')).to.be.null;
});
});
44 changes: 44 additions & 0 deletions src/test/suite/views/webview-app/atlas-cta.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from 'react';
import { cleanup, render, screen } from '@testing-library/react';
import AtlasCta from '../../../../views/webview-app/atlas-cta';
import { expect } from 'chai';
import Sinon from 'sinon';
import vscode from '../../../../views/webview-app/vscode-api';
import { MESSAGE_TYPES } from '../../../../views/webview-app/extension-app-message-constants';

describe('AtlasCta test suite', function () {
afterEach(function () {
cleanup();
Sinon.restore();
});

test('it should render Atlas CTA', function () {
render(<AtlasCta />);
expect(screen.getByText('Create free cluster')).to.not.be.null;
expect(screen.getByTestId('link-atlas')).to.not.be.null;
});

test('it should track clicks on MongoDB Atlas link', function () {
const postMessageStub = Sinon.stub(vscode, 'postMessage');
render(<AtlasCta />);
screen.getByTestId('link-atlas').click();
expect(postMessageStub).to.be.calledWithExactly({
command: MESSAGE_TYPES.EXTENSION_LINK_CLICKED,
screen: 'overviewPage',
linkId: 'atlasLanding',
});
});

test('when clicked on "Create free cluster" button, it should open create account page on atlas and also track the link', function () {
const postMessageStub = Sinon.stub(vscode, 'postMessage');
render(<AtlasCta />);
screen.getByText('Create free cluster').click();
expect(postMessageStub).calledTwice;
expect(postMessageStub.firstCall.args[0].command).to.equal(
MESSAGE_TYPES.OPEN_TRUSTED_LINK
);
expect(postMessageStub.secondCall.args[0].command).to.equal(
MESSAGE_TYPES.EXTENSION_LINK_CLICKED
);
});
});
29 changes: 29 additions & 0 deletions src/test/suite/views/webview-app/connect-helper.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import { expect } from 'chai';
import { render, screen } from '@testing-library/react';
import ConnectHelper from '../../../../views/webview-app/connect-helper';
import Sinon from 'sinon';
import vscode from '../../../../views/webview-app/vscode-api';
import { MESSAGE_TYPES } from '../../../../views/webview-app/extension-app-message-constants';

describe('ConnectHelper test suite', function () {
test('when rendered it should show both connection options', function () {
render(<ConnectHelper />);
expect(screen.getByLabelText('Connect with connection string')).to.not.be
.null;
expect(screen.getByLabelText('Open connection form')).to.not.be.null;
});

test('when connecting with string, it should call vscode to open connection string input', function () {
const postMessageStub = Sinon.stub(vscode, 'postMessage');
render(<ConnectHelper />);
screen.getByLabelText('Connect with connection string').click();
expect(postMessageStub).to.have.been.calledWithExactly({
command: MESSAGE_TYPES.OPEN_CONNECTION_STRING_INPUT,
});
});

test.skip('when clicked on open connection form, it should open connection form', function () {
// TODO(VSCODE-488)
});
});
124 changes: 124 additions & 0 deletions src/test/suite/views/webview-app/connection-status.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import Sinon from 'sinon';
import { expect } from 'chai';
import * as React from 'react';
import { act, cleanup, render, screen } from '@testing-library/react';
import ConnectionStatus from '../../../../views/webview-app/connection-status';
import {
CONNECTION_STATUS,
MESSAGE_TYPES,
} from '../../../../views/webview-app/extension-app-message-constants';
import vscode from '../../../../views/webview-app/vscode-api';

describe('ConnectionStatus test suite', function () {
afterEach(function () {
cleanup();
Sinon.restore();
});

test('it should show a loading status by default', function () {
render(<ConnectionStatus />);
expect(screen.getByText('Loading...')).to.not.be.null;
});

test('it should periodically request connection status', function () {
const postMessageStub = Sinon.stub(vscode, 'postMessage');
render(<ConnectionStatus />);
expect(postMessageStub).to.have.been.calledWithExactly({
command: MESSAGE_TYPES.GET_CONNECTION_STATUS,
});
});

describe('when GET_CONNECTION_STATUS gets responded with a disconnecting state', function () {
test('it should show a disconnecting status', function () {
render(<ConnectionStatus />);
act(() => {
window.dispatchEvent(
new MessageEvent('message', {
data: {
command: MESSAGE_TYPES.CONNECTION_STATUS_MESSAGE,
connectionStatus: CONNECTION_STATUS.DISCONNECTING,
activeConnectionName: '',
},
})
);
});
expect(screen.getByText('Disconnecting...')).to.not.be.null;
});
});

describe('when GET_CONNECTION_STATUS gets responded with a disconnected state', function () {
test('it should show a disconnected status', function () {
render(<ConnectionStatus />);
act(() => {
window.dispatchEvent(
new MessageEvent('message', {
data: {
command: MESSAGE_TYPES.CONNECTION_STATUS_MESSAGE,
connectionStatus: CONNECTION_STATUS.DISCONNECTED,
activeConnectionName: '',
},
})
);
});
expect(screen.getByText('Not connected.')).to.not.be.null;
});
});

describe('when GET_CONNECTION_STATUS gets responded with a connecting state', function () {
test('it should show a connecting status', function () {
render(<ConnectionStatus />);
act(() => {
window.dispatchEvent(
new MessageEvent('message', {
data: {
command: MESSAGE_TYPES.CONNECTION_STATUS_MESSAGE,
connectionStatus: CONNECTION_STATUS.CONNECTING,
activeConnectionName: '',
},
})
);
});
expect(screen.getByText('Connecting...')).to.not.be.null;
});
});

describe('when GET_CONNECTION_STATUS gets responded with a connected state', function () {
beforeEach(function () {
render(<ConnectionStatus />);
act(() => {
window.dispatchEvent(
new MessageEvent('message', {
data: {
command: MESSAGE_TYPES.CONNECTION_STATUS_MESSAGE,
connectionStatus: CONNECTION_STATUS.CONNECTED,
activeConnectionName: 'vscode-connection',
},
})
);
});
});

test('it should show a connected status', function () {
expect(screen.getByText('Connected to:')).to.not.be.null;
expect(screen.getByText('vscode-connection')).to.not.be.null;
});

test('it should allow editing the name of the connection', function () {
const postMessageStub = Sinon.stub(vscode, 'postMessage');
screen.getByLabelText('Rename connection').click();

expect(postMessageStub).to.be.calledWithExactly({
command: MESSAGE_TYPES.RENAME_ACTIVE_CONNECTION,
});
});

test('it should allow creating new playground', function () {
const postMessageStub = Sinon.stub(vscode, 'postMessage');
screen.getByLabelText('Create playground').click();

expect(postMessageStub).to.be.calledWithExactly({
command: MESSAGE_TYPES.CREATE_NEW_PLAYGROUND,
});
});
});
});
2 changes: 2 additions & 0 deletions src/test/suite/views/webview-app/jest-setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

const Enzyme = require('enzyme');
const Adapter = require('@wojtekmaj/enzyme-adapter-react-17');
const chai = require('chai');
chai.use(require('sinon-chai'));
Enzyme.configure({ adapter: new Adapter() });

// eslint-disable-next-line no-undef
Expand Down
29 changes: 29 additions & 0 deletions src/test/suite/views/webview-app/overview-page.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import { expect } from 'chai';
import { cleanup, render, screen } from '@testing-library/react';
import OverviewPage from '../../../../views/webview-app/overview-page';

describe('OverviewPage test suite', function () {
afterEach(cleanup);
test('it should render OverviewPage', function () {
render(<OverviewPage />);
expect(
screen.getByText(
'Navigate your databases and collections, use playgrounds for exploring and transforming your data'
)
).to.exist;
});

test('on click of resources, it should open resources panel', function () {
render(<OverviewPage />);
screen.getByText('Resources').click();
expect(screen.getByText('Product overview')).to.exist;
});

test('on click of close button on resources panel, it should close resources panel', function () {
render(<OverviewPage />);
screen.getByText('Resources').click();
screen.getByLabelText('Close').click();
expect(screen.queryByText('Product overview')).to.be.null;
});
});
67 changes: 67 additions & 0 deletions src/test/suite/views/webview-app/resources-panel.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import Sinon from 'sinon';
import { expect } from 'chai';
import * as React from 'react';
import { cleanup, render, screen } from '@testing-library/react';
import ResourcesPanel, {
TELEMETRY_SCREEN_ID,
} from '../../../../views/webview-app/resources-panel/panel';
import { MESSAGE_TYPES } from '../../../../views/webview-app/extension-app-message-constants';
import vscode from '../../../../views/webview-app/vscode-api';

describe('Resources panel test suite', function () {
afterEach(function () {
cleanup();
});

test('it should render resources panel', function () {
render(<ResourcesPanel onClose={() => {}} />);
expect(() => screen.getByLabelText('Close')).to.not.throw;
expect(screen.getAllByTestId(/link-\w+/)).to.have.length.greaterThan(0);
expect(
screen.getAllByTestId(/footer-feature-\w+/)
).to.have.length.greaterThan(0);
expect(screen.getAllByTestId(/footer-link-\w+/)).to.have.length.greaterThan(
0
);
});

test('it should call onClose on close btn click', function () {
const onCloseFake = Sinon.fake();
render(<ResourcesPanel onClose={onCloseFake} />);
screen.getByLabelText('Close').click();
expect(onCloseFake).to.have.been.calledOnce;
});

test('it should track link clicked event on click of any link', function () {
const postMessageStub = Sinon.stub(vscode, 'postMessage');
render(<ResourcesPanel onClose={() => {}} />);
screen.getAllByTestId(/^link-\w+/).forEach((link) => {
link.click();
expect(postMessageStub).to.have.been.calledWithExactly({
command: MESSAGE_TYPES.EXTENSION_LINK_CLICKED,
screen: TELEMETRY_SCREEN_ID,
linkId: link.getAttribute('data-testid')?.replace('link-', ''),
});
});

screen.getAllByTestId(/^footer-feature-\w+/).forEach((link) => {
link.click();
expect(postMessageStub).to.have.been.calledWithExactly({
command: MESSAGE_TYPES.EXTENSION_LINK_CLICKED,
screen: TELEMETRY_SCREEN_ID,
linkId: link
.getAttribute('data-testid')
?.replace('footer-feature-', ''),
});
});

screen.getAllByTestId(/^footer-link-\w+/).forEach((link) => {
link.click();
expect(postMessageStub).to.have.been.calledWithExactly({
command: MESSAGE_TYPES.EXTENSION_LINK_CLICKED,
screen: TELEMETRY_SCREEN_ID,
linkId: link.getAttribute('data-testid')?.replace('footer-link-', ''),
});
});
});
});
Loading

0 comments on commit 12bc65a

Please sign in to comment.