]> source.dussan.org Git - sonarqube.git/commitdiff
Improve test coverage
authorWouter Admiraal <wouter.admiraal@sonarsource.com>
Mon, 6 Jan 2020 09:54:12 +0000 (10:54 +0100)
committerSonarTech <sonartech@sonarsource.com>
Wed, 8 Jan 2020 19:46:12 +0000 (20:46 +0100)
server/sonar-web/src/main/js/apps/account/components/Security.tsx
server/sonar-web/src/main/js/apps/account/components/__tests__/Security-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/account/components/__tests__/__snapshots__/Security-test.tsx.snap [new file with mode: 0644]
server/sonar-web/src/main/js/apps/marketplace/App.tsx
server/sonar-web/src/main/js/apps/marketplace/__tests__/App-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/marketplace/__tests__/__snapshots__/App-test.tsx.snap [new file with mode: 0644]
server/sonar-web/src/main/js/apps/settings/encryption/__tests__/EncryptionApp-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/settings/encryption/__tests__/__snapshots__/EncryptionApp-test.tsx.snap [new file with mode: 0644]
server/sonar-web/src/main/js/apps/system/components/App.tsx
server/sonar-web/src/main/js/apps/system/components/__tests__/App-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/system/components/__tests__/__snapshots__/App-test.tsx.snap [new file with mode: 0644]

index 704dee0c4a8f9fe0c130da5031cd3570abbf544b..49637c3ad6f8c5e9ada411bf4d2f515b6a84dfa5 100644 (file)
@@ -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')} />
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 (file)
index 0000000..eebc455
--- /dev/null
@@ -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} />);
+}
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 (file)
index 0000000..46d0817
--- /dev/null
@@ -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>
+`;
index fc0b4f8484cb5ab0b38d1279f8a7437fe7c32069..6f54f90f4c8f54228dcf2f7bddccdfadc1e4b413 100644 (file)
@@ -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: [] };
 
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 (file)
index 0000000..ed16e97
--- /dev/null
@@ -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}
+    />
+  );
+}
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 (file)
index 0000000..69364b9
--- /dev/null
@@ -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>
+`;
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 (file)
index 0000000..a10b569
--- /dev/null
@@ -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} />);
+}
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 (file)
index 0000000..4e03578
--- /dev/null
@@ -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>
+`;
index 205c98c0e1ce5cf7fee57af262b62d3a171efdb7..79b90e732882f738b2b06d44f66470fa97d049dc 100644 (file)
@@ -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 };
 
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 (file)
index 0000000..5de30ac
--- /dev/null
@@ -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} />
+  );
+}
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 (file)
index 0000000..aa0f496
--- /dev/null
@@ -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>
+`;