瀏覽代碼

Improve test coverage

tags/8.2.0.32929
Wouter Admiraal 4 年之前
父節點
當前提交
685b65da29

+ 2
- 2
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 (
<div className="account-body account-container">
<Helmet defer={false} title={translate('my_account.security')} />

+ 34
- 0
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<SecurityProps> = {}) {
return shallow(<Security user={mockLoggedInUser({ local: true })} {...props} />);
}

+ 43
- 0
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`] = `
<div
className="account-body account-container"
>
<Helmet
defer={false}
encodeSpecialCharacters={true}
title="my_account.security"
/>
<Tokens
login="luke"
/>
<Password
user={
Object {
"groups": Array [],
"isLoggedIn": true,
"local": true,
"login": "luke",
"name": "Skywalker",
"scmAccounts": Array [],
}
}
/>
</div>
`;

exports[`should render correctly: non-local user 1`] = `
<div
className="account-body account-container"
>
<Helmet
defer={false}
encodeSpecialCharacters={true}
title="my_account.security"
/>
<Tokens
login="luke"
/>
</div>
`;

+ 2
- 2
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<Props, State> {
export class App extends React.PureComponent<Props, State> {
mounted = false;
state: State = { loadingPlugins: true, plugins: [] };


+ 78
- 0
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<App['props']> = {}) {
return shallow<App>(
<App
fetchPendingPlugins={jest.fn()}
location={mockLocation()}
pendingPlugins={{
installing: [],
updating: [],
removing: []
}}
router={mockRouter()}
updateCenterActive={false}
{...props}
/>
);
}

+ 93
- 0
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`] = `
<div
className="page page-limited"
id="marketplace-page"
>
<Suggestions
suggestions="marketplace"
/>
<Helmet
defer={true}
encodeSpecialCharacters={true}
title="marketplace.page"
/>
<Header />
<EditionBoxes />
<header
className="page-header"
>
<h1
className="page-title"
>
marketplace.page.open_source_plugins
</h1>
</header>
<Search
query={
Object {
"filter": "all",
"search": "",
}
}
updateCenterActive={false}
updateQuery={[Function]}
/>
<PluginsList
pending={
Object {
"installing": Array [],
"removing": Array [],
"updating": Array [],
}
}
plugins={Array []}
readOnly={true}
refreshPending={[MockFunction]}
/>
<Footer
total={0}
/>
</div>
`;

exports[`should render correctly: loading 1`] = `
<div
className="page page-limited"
id="marketplace-page"
>
<Suggestions
suggestions="marketplace"
/>
<Helmet
defer={true}
encodeSpecialCharacters={true}
title="marketplace.page"
/>
<Header />
<EditionBoxes />
<header
className="page-header"
>
<h1
className="page-title"
>
marketplace.page.open_source_plugins
</h1>
</header>
<Search
query={
Object {
"filter": "all",
"search": "",
}
}
updateCenterActive={false}
updateQuery={[Function]}
/>
<i
className="spinner"
/>
</div>
`;

+ 59
- 0
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<EncryptionApp['props']> = {}) {
return shallow<EncryptionApp>(<EncryptionApp {...props} />);
}

+ 85
- 0
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`] = `
<div
className="page page-limited"
id="encryption-page"
>
<Helmet
defer={false}
encodeSpecialCharacters={true}
title="property.category.security.encryption"
/>
<header
className="page-header"
>
<h1
className="page-title"
>
property.category.security.encryption
</h1>
<DeferredSpinner
loading={false}
timeout={100}
/>
</header>
<EncryptionForm
generateSecretKey={[Function]}
/>
</div>
`;

exports[`should render correctly: generate form 1`] = `
<div
className="page page-limited"
id="encryption-page"
>
<Helmet
defer={false}
encodeSpecialCharacters={true}
title="property.category.security.encryption"
/>
<header
className="page-header"
>
<h1
className="page-title"
>
property.category.security.encryption
</h1>
<DeferredSpinner
loading={false}
timeout={100}
/>
</header>
<GenerateSecretKeyForm
generateSecretKey={[Function]}
/>
</div>
`;

exports[`should render correctly: loading 1`] = `
<div
className="page page-limited"
id="encryption-page"
>
<Helmet
defer={false}
encodeSpecialCharacters={true}
title="property.category.security.encryption"
/>
<header
className="page-header"
>
<h1
className="page-title"
>
property.category.security.encryption
</h1>
<DeferredSpinner
loading={true}
timeout={100}
/>
</header>
</div>
`;

+ 1
- 1
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<Props, State> {
export class App extends React.PureComponent<Props, State> {
mounted = false;
state: State = { loading: true };


+ 86
- 0
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<App['props']> = {}) {
return shallow<App>(
<App location={mockLocation()} params={{}} router={mockRouter()} routes={[]} {...props} />
);
}

+ 299
- 0
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`] = `
<div
className="page page-limited"
>
<Suggestions
suggestions="system_info"
/>
<Helmet
defer={false}
encodeSpecialCharacters={true}
title="system_info.page"
/>
<SystemUpgradeNotif />
<PageHeader
isCluster={true}
loading={false}
logLevel="DEBUG"
onLogLevelChange={[Function]}
serverId="asd564-asd54a-5dsfg45"
showActions={true}
version="7.8"
/>
<ClusterSysInfos
expandedCards={Array []}
sysInfoData={
Object {
"Application Nodes": Array [
Object {
"Compute Engine Database Connection": Object {
"Pool Active Connections": 0,
"Pool Initial Size": 0,
},
"Compute Engine JVM Properties": Object {
"file.encoding": "UTF-8",
"file.separator": "/",
},
"Compute Engine JVM State": Object {
"Free Memory (MB)": 78,
"Max Memory (MB)": 1024,
},
"Compute Engine Logging": Object {
"Logs Level": "INFO",
},
"Compute Engine Tasks": Object {
"In Progress": 0,
"Pending": 0,
},
"Health": "GREEN",
"Health Causes": Array [],
"Host": "10.0.0.0",
"Name": "server9.example.com",
"Plugins": Object {
"java": "5.13.0.17924 [SonarJava]",
},
"System": Object {
"Version": "7.8",
},
"Web Database Connection": Object {
"Pool Active Connections": 1,
},
"Web JVM Properties": Object {
"file.encoding": "UTF-8",
"file.separator": "/",
},
"Web JVM State": Object {
"Free Memory (MB)": 122,
"Max Memory (MB)": 1024,
},
"Web Logging": Object {
"Logs Level": "DEBUG",
},
},
Object {
"Compute Engine Database Connection": Object {
"Pool Active Connections": 0,
"Pool Initial Size": 0,
},
"Compute Engine JVM Properties": Object {
"file.encoding": "UTF-8",
"file.separator": "/",
},
"Compute Engine JVM State": Object {
"Free Memory (MB)": 89,
"Max Memory (MB)": 1024,
},
"Compute Engine Logging": Object {
"Logs Level": "INFO",
},
"Compute Engine Tasks": Object {
"In Progress": 0,
"Pending": 0,
},
"Health": "GREEN",
"Health Causes": Array [],
"Host": "10.0.0.0",
"Name": "server9.example.com",
"Plugins": Object {
"java": "5.13.0.17924 [SonarJava]",
},
"System": Object {
"Version": "7.8",
},
"Web Database Connection": Object {
"Pool Active Connections": 0,
"Pool Max Connections": 60,
},
"Web JVM Properties": Object {
"file.encoding": "UTF-8",
"file.separator": "/",
},
"Web JVM State": Object {
"Free Memory (MB)": 111,
"Max Memory (MB)": 1024,
},
"Web Logging": Object {
"Logs Level": "INFO",
},
},
],
"Compute Engine Tasks": Object {
"Total In Progress": 0,
"Total Pending": 0,
},
"Database": Object {
"Database": "PostgreSQL",
"Database Version": "10.3",
"Driver": "PostgreSQL JDBC Driver",
"Driver Version": "42.2.5",
"URL": "jdbc:postgresql://localhost/sonar",
"Username": "sonar",
},
"Health": "GREEN",
"Health Causes": Array [],
"Search Indexes": Object {
"Index components - Docs": 30445,
"Index components - Shards": 10,
},
"Search Nodes": Array [
Object {
"Host": "10.0.0.0",
"Name": "server.example.com",
"Search State": Object {
"CPU Usage (%)": 0,
"Disk Available": "93 GB",
},
},
Object {
"Host": "10.0.0.0",
"Name": "server.example.com",
"Search State": Object {
"CPU Usage (%)": 0,
"Disk Available": "93 GB",
},
},
Object {
"Host": "10.0.0.0",
"Name": "server.example.com",
"Search State": Object {
"CPU Usage (%)": 0,
"Disk Available": "93 GB",
},
},
],
"Search State": Object {
"Nodes": 3,
"State": "GREEN",
},
"Settings": Object {
"sonar.cluster.enabled": "true",
"sonar.cluster.node.name": "server9.example.com",
},
"Statistics": Object {
"ncloc": 989880,
},
"System": Object {
"High Availability": true,
"Server ID": "asd564-asd54a-5dsfg45",
"Version": "7.8",
},
}
}
toggleCard={[Function]}
/>
</div>
`;

exports[`should render correctly: loading 1`] = `
<div
className="page page-limited"
>
<Suggestions
suggestions="system_info"
/>
<Helmet
defer={false}
encodeSpecialCharacters={true}
title="system_info.page"
/>
<SystemUpgradeNotif />
</div>
`;

exports[`should render correctly: stand-alone sysinfo 1`] = `
<div
className="page page-limited"
>
<Suggestions
suggestions="system_info"
/>
<Helmet
defer={false}
encodeSpecialCharacters={true}
title="system_info.page"
/>
<SystemUpgradeNotif />
<PageHeader
isCluster={false}
loading={false}
logLevel="DEBUG"
onLogLevelChange={[Function]}
serverId="asd564-asd54a-5dsfg45"
showActions={true}
version="7.8"
/>
<StandAloneSysInfos
expandedCards={Array []}
sysInfoData={
Object {
"Compute Engine Database Connection": Object {
"Pool Active Connections": 0,
"Pool Initial Size": 0,
},
"Compute Engine JVM Properties": Object {
"file.encoding": "UTF-8",
"file.separator": "/",
},
"Compute Engine JVM State": Object {
"Free Memory (MB)": 89,
"Max Memory (MB)": 1024,
},
"Compute Engine Logging": Object {
"Logs Dir": "/logs",
"Logs Level": "DEBUG",
},
"Compute Engine Tasks": Object {
"In Progress": 0,
"Pending": 0,
},
"Database": Object {
"Database": "PostgreSQL",
"Database Version": "10.3",
"Driver": "PostgreSQL JDBC Driver",
"Driver Version": "42.2.5",
"URL": "jdbc:postgresql://localhost/sonar",
"Username": "sonar",
},
"Health": "GREEN",
"Health Causes": Array [],
"Search Indexes": Object {
"Index components - Docs": 30445,
"Index components - Shards": 10,
},
"Search State": Object {
"Nodes": 3,
"State": "GREEN",
},
"Settings": Object {
"sonar.cluster.enabled": "true",
"sonar.cluster.node.name": "server9.example.com",
},
"System": Object {
"High Availability": false,
"Server ID": "asd564-asd54a-5dsfg45",
"Version": "7.8",
},
"Web Database Connection": Object {
"Pool Active Connections": 0,
"Pool Max Connections": 60,
},
"Web JVM Properties": Object {
"file.encoding": "UTF-8",
"file.separator": "/",
},
"Web JVM State": Object {
"Free Memory (MB)": 111,
"Max Memory (MB)": 1024,
},
"Web Logging": Object {
"Logs Dir": "/logs",
"Logs Level": "INFO",
},
}
}
toggleCard={[Function]}
/>
</div>
`;

Loading…
取消
儲存