From 685b65da29d3f089f9effad10f2bc38f91d59617 Mon Sep 17 00:00:00 2001 From: Wouter Admiraal Date: Mon, 6 Jan 2020 10:54:12 +0100 Subject: [PATCH] Improve test coverage --- .../js/apps/account/components/Security.tsx | 4 +- .../components/__tests__/Security-test.tsx | 34 ++ .../__snapshots__/Security-test.tsx.snap | 43 +++ .../src/main/js/apps/marketplace/App.tsx | 4 +- .../apps/marketplace/__tests__/App-test.tsx | 78 +++++ .../__tests__/__snapshots__/App-test.tsx.snap | 93 ++++++ .../__tests__/EncryptionApp-test.tsx | 59 ++++ .../__snapshots__/EncryptionApp-test.tsx.snap | 85 +++++ .../main/js/apps/system/components/App.tsx | 2 +- .../system/components/__tests__/App-test.tsx | 86 +++++ .../__tests__/__snapshots__/App-test.tsx.snap | 299 ++++++++++++++++++ 11 files changed, 782 insertions(+), 5 deletions(-) create mode 100644 server/sonar-web/src/main/js/apps/account/components/__tests__/Security-test.tsx create mode 100644 server/sonar-web/src/main/js/apps/account/components/__tests__/__snapshots__/Security-test.tsx.snap create mode 100644 server/sonar-web/src/main/js/apps/marketplace/__tests__/App-test.tsx create mode 100644 server/sonar-web/src/main/js/apps/marketplace/__tests__/__snapshots__/App-test.tsx.snap create mode 100644 server/sonar-web/src/main/js/apps/settings/encryption/__tests__/EncryptionApp-test.tsx create mode 100644 server/sonar-web/src/main/js/apps/settings/encryption/__tests__/__snapshots__/EncryptionApp-test.tsx.snap create mode 100644 server/sonar-web/src/main/js/apps/system/components/__tests__/App-test.tsx create mode 100644 server/sonar-web/src/main/js/apps/system/components/__tests__/__snapshots__/App-test.tsx.snap diff --git a/server/sonar-web/src/main/js/apps/account/components/Security.tsx b/server/sonar-web/src/main/js/apps/account/components/Security.tsx index 704dee0c4a8..49637c3ad6f 100644 --- a/server/sonar-web/src/main/js/apps/account/components/Security.tsx +++ b/server/sonar-web/src/main/js/apps/account/components/Security.tsx @@ -25,11 +25,11 @@ import { getCurrentUser, Store } from '../../../store/rootReducer'; import Password from './Password'; import Tokens from './Tokens'; -interface Props { +export interface SecurityProps { user: T.LoggedInUser; } -function Security({ user }: Props) { +export function Security({ user }: SecurityProps) { return (
diff --git a/server/sonar-web/src/main/js/apps/account/components/__tests__/Security-test.tsx b/server/sonar-web/src/main/js/apps/account/components/__tests__/Security-test.tsx new file mode 100644 index 00000000000..eebc455a098 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/account/components/__tests__/Security-test.tsx @@ -0,0 +1,34 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import { shallow } from 'enzyme'; +import * as React from 'react'; +import { mockLoggedInUser } from '../../../../helpers/testMocks'; +import { Security, SecurityProps } from '../Security'; + +it('should render correctly', () => { + expect(shallowRender()).toMatchSnapshot('local user'); + expect(shallowRender({ user: mockLoggedInUser({ local: false }) })).toMatchSnapshot( + 'non-local user' + ); +}); + +function shallowRender(props: Partial = {}) { + return shallow(); +} diff --git a/server/sonar-web/src/main/js/apps/account/components/__tests__/__snapshots__/Security-test.tsx.snap b/server/sonar-web/src/main/js/apps/account/components/__tests__/__snapshots__/Security-test.tsx.snap new file mode 100644 index 00000000000..46d08174e68 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/account/components/__tests__/__snapshots__/Security-test.tsx.snap @@ -0,0 +1,43 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render correctly: local user 1`] = ` +
+ + + +
+`; + +exports[`should render correctly: non-local user 1`] = ` +
+ + +
+`; diff --git a/server/sonar-web/src/main/js/apps/marketplace/App.tsx b/server/sonar-web/src/main/js/apps/marketplace/App.tsx index fc0b4f8484c..6f54f90f4c8 100644 --- a/server/sonar-web/src/main/js/apps/marketplace/App.tsx +++ b/server/sonar-web/src/main/js/apps/marketplace/App.tsx @@ -40,7 +40,7 @@ import Search from './Search'; import './style.css'; import { filterPlugins, parseQuery, Query, serializeQuery } from './utils'; -export interface Props { +interface Props { currentEdition?: EditionKey; fetchPendingPlugins: () => void; pendingPlugins: PluginPendingResult; @@ -55,7 +55,7 @@ interface State { plugins: Plugin[]; } -class App extends React.PureComponent { +export class App extends React.PureComponent { mounted = false; state: State = { loadingPlugins: true, plugins: [] }; diff --git a/server/sonar-web/src/main/js/apps/marketplace/__tests__/App-test.tsx b/server/sonar-web/src/main/js/apps/marketplace/__tests__/App-test.tsx new file mode 100644 index 00000000000..ed16e97c189 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/marketplace/__tests__/App-test.tsx @@ -0,0 +1,78 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import { shallow } from 'enzyme'; +import * as React from 'react'; +import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; +import { + getAvailablePlugins, + getInstalledPlugins, + getInstalledPluginsWithUpdates, + getPluginUpdates +} from '../../../api/plugins'; +import { mockLocation, mockRouter } from '../../../helpers/testMocks'; +import { App } from '../App'; + +jest.mock('../../../api/plugins', () => ({ + getAvailablePlugins: jest.fn().mockResolvedValue({ plugins: [] }), + getInstalledPlugins: jest.fn().mockResolvedValue([]), + getInstalledPluginsWithUpdates: jest.fn().mockResolvedValue([]), + getPluginUpdates: jest.fn().mockResolvedValue([]) +})); + +beforeEach(jest.clearAllMocks); + +it('should render correctly', () => { + const wrapper = shallowRender(); + expect(wrapper).toMatchSnapshot('loading'); + expect(wrapper.setState({ loadingPlugins: false })).toMatchSnapshot('loaded'); +}); + +it('should fetch plugin info', async () => { + const wrapper = shallowRender(); + + await waitAndUpdate(wrapper); + expect(getInstalledPluginsWithUpdates).toBeCalled(); + expect(getAvailablePlugins).toBeCalled(); + + wrapper.setProps({ location: mockLocation({ query: { filter: 'updates' } }) }); + await waitAndUpdate(wrapper); + expect(getPluginUpdates).toBeCalled(); + + wrapper.setProps({ location: mockLocation({ query: { filter: 'installed' } }) }); + await waitAndUpdate(wrapper); + expect(getInstalledPlugins).toBeCalled(); +}); + +function shallowRender(props: Partial = {}) { + return shallow( + + ); +} diff --git a/server/sonar-web/src/main/js/apps/marketplace/__tests__/__snapshots__/App-test.tsx.snap b/server/sonar-web/src/main/js/apps/marketplace/__tests__/__snapshots__/App-test.tsx.snap new file mode 100644 index 00000000000..69364b95ded --- /dev/null +++ b/server/sonar-web/src/main/js/apps/marketplace/__tests__/__snapshots__/App-test.tsx.snap @@ -0,0 +1,93 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render correctly: loaded 1`] = ` +
+ + +
+ +
+

+ marketplace.page.open_source_plugins +

+
+ + +
+
+`; + +exports[`should render correctly: loading 1`] = ` +
+ + +
+ +
+

+ marketplace.page.open_source_plugins +

+
+ + +
+`; diff --git a/server/sonar-web/src/main/js/apps/settings/encryption/__tests__/EncryptionApp-test.tsx b/server/sonar-web/src/main/js/apps/settings/encryption/__tests__/EncryptionApp-test.tsx new file mode 100644 index 00000000000..a10b569a9eb --- /dev/null +++ b/server/sonar-web/src/main/js/apps/settings/encryption/__tests__/EncryptionApp-test.tsx @@ -0,0 +1,59 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import { shallow } from 'enzyme'; +import * as React from 'react'; +import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; +import { checkSecretKey, generateSecretKey } from '../../../../api/settings'; +import EncryptionApp from '../EncryptionApp'; + +jest.mock('../../../../api/settings', () => ({ + checkSecretKey: jest.fn().mockResolvedValue({ secretKeyAvailable: true }), + generateSecretKey: jest.fn().mockResolvedValue({ secretKey: 'secret' }) +})); + +it('should render correctly', () => { + const wrapper = shallowRender(); + expect(wrapper).toMatchSnapshot('loading'); + expect(wrapper.setState({ loading: false, secretKeyAvailable: false })).toMatchSnapshot( + 'generate form' + ); + expect(wrapper.setState({ secretKeyAvailable: true })).toMatchSnapshot('encryption form'); +}); + +it('should correctly check a key', async () => { + const wrapper = shallowRender(); + wrapper.instance().checkSecretKey(); + await waitAndUpdate(wrapper); + expect(checkSecretKey).toBeCalled(); + expect(wrapper.state().secretKeyAvailable).toBe(true); +}); + +it('should correctly generate a key', async () => { + const wrapper = shallowRender(); + wrapper.instance().generateSecretKey(); + await waitAndUpdate(wrapper); + expect(generateSecretKey).toBeCalled(); + expect(wrapper.state().secretKey).toBe('secret'); + expect(wrapper.state().secretKeyAvailable).toBe(false); +}); + +function shallowRender(props: Partial = {}) { + return shallow(); +} diff --git a/server/sonar-web/src/main/js/apps/settings/encryption/__tests__/__snapshots__/EncryptionApp-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/encryption/__tests__/__snapshots__/EncryptionApp-test.tsx.snap new file mode 100644 index 00000000000..4e03578fb4b --- /dev/null +++ b/server/sonar-web/src/main/js/apps/settings/encryption/__tests__/__snapshots__/EncryptionApp-test.tsx.snap @@ -0,0 +1,85 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render correctly: encryption form 1`] = ` +
+ +
+

+ property.category.security.encryption +

+ +
+ +
+`; + +exports[`should render correctly: generate form 1`] = ` +
+ +
+

+ property.category.security.encryption +

+ +
+ +
+`; + +exports[`should render correctly: loading 1`] = ` +
+ +
+

+ property.category.security.encryption +

+ +
+
+`; diff --git a/server/sonar-web/src/main/js/apps/system/components/App.tsx b/server/sonar-web/src/main/js/apps/system/components/App.tsx index 205c98c0e1c..79b90e73288 100644 --- a/server/sonar-web/src/main/js/apps/system/components/App.tsx +++ b/server/sonar-web/src/main/js/apps/system/components/App.tsx @@ -46,7 +46,7 @@ interface State { sysInfoData?: T.SysInfoCluster | T.SysInfoStandalone; } -class App extends React.PureComponent { +export class App extends React.PureComponent { mounted = false; state: State = { loading: true }; diff --git a/server/sonar-web/src/main/js/apps/system/components/__tests__/App-test.tsx b/server/sonar-web/src/main/js/apps/system/components/__tests__/App-test.tsx new file mode 100644 index 00000000000..5de30ac395a --- /dev/null +++ b/server/sonar-web/src/main/js/apps/system/components/__tests__/App-test.tsx @@ -0,0 +1,86 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import { shallow } from 'enzyme'; +import * as React from 'react'; +import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; +import { getSystemInfo } from '../../../../api/system'; +import { + mockClusterSysInfo, + mockLocation, + mockRouter, + mockStandaloneSysInfo +} from '../../../../helpers/testMocks'; +import { App } from '../App'; + +jest.mock('../../../../api/system', () => ({ + getSystemInfo: jest.fn().mockResolvedValue(null) +})); + +beforeEach(jest.clearAllMocks); + +it('should render correctly', () => { + const wrapper = shallowRender(); + expect(wrapper).toMatchSnapshot('loading'); + expect( + wrapper.setState({ loading: false, sysInfoData: mockStandaloneSysInfo() }) + ).toMatchSnapshot('stand-alone sysinfo'); + expect(wrapper.setState({ loading: false, sysInfoData: mockClusterSysInfo() })).toMatchSnapshot( + 'cluster sysinfo' + ); +}); + +it('should fetch system info', async () => { + const sysInfoData = mockStandaloneSysInfo(); + (getSystemInfo as jest.Mock).mockResolvedValue(sysInfoData); + + const wrapper = shallowRender(); + await waitAndUpdate(wrapper); + expect(getSystemInfo).toBeCalled(); + expect(wrapper.state().sysInfoData).toBe(sysInfoData); +}); + +it('should toggle cards and update the URL', () => { + const replace = jest.fn(); + const wrapper = shallowRender({ router: mockRouter({ replace }) }); + + // Open + wrapper.instance().toggleSysInfoCards('foo'); + expect(replace).toBeCalledWith( + expect.objectContaining({ + query: { expand: 'foo' } + }) + ); + + // Close. + replace.mockClear(); + wrapper.setProps({ location: mockLocation({ query: { expand: 'foo,bar' } }) }); + wrapper.instance().toggleSysInfoCards('foo'); + expect(replace).toBeCalledWith( + expect.objectContaining({ + query: { expand: 'bar' } + }) + ); +}); + +function shallowRender(props: Partial = {}) { + return shallow( + + ); +} diff --git a/server/sonar-web/src/main/js/apps/system/components/__tests__/__snapshots__/App-test.tsx.snap b/server/sonar-web/src/main/js/apps/system/components/__tests__/__snapshots__/App-test.tsx.snap new file mode 100644 index 00000000000..aa0f496acbf --- /dev/null +++ b/server/sonar-web/src/main/js/apps/system/components/__tests__/__snapshots__/App-test.tsx.snap @@ -0,0 +1,299 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render correctly: cluster sysinfo 1`] = ` +
+ + + + + +
+`; + +exports[`should render correctly: loading 1`] = ` +
+ + + +
+`; + +exports[`should render correctly: stand-alone sysinfo 1`] = ` +
+ + + + + +
+`; -- 2.39.5