aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps
diff options
context:
space:
mode:
Diffstat (limited to 'server/sonar-web/src/main/js/apps')
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/ResolutionFacet.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/StatusFacet.tsx18
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/__tests__/StatusFacet-test.tsx81
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/__tests__/__snapshots__/StatusFacet-test.tsx.snap163
4 files changed, 258 insertions, 6 deletions
diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/ResolutionFacet.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/ResolutionFacet.tsx
index 5e069b27e14..958245f1ad6 100644
--- a/server/sonar-web/src/main/js/apps/issues/sidebar/ResolutionFacet.tsx
+++ b/server/sonar-web/src/main/js/apps/issues/sidebar/ResolutionFacet.tsx
@@ -38,7 +38,7 @@ interface Props {
stats: T.Dict<number> | undefined;
}
-const RESOLUTIONS = ['', 'FIXED', 'FALSE-POSITIVE', 'WONTFIX', 'REMOVED'];
+const RESOLUTIONS = ['', 'FALSE-POSITIVE', 'FIXED', 'REMOVED', 'WONTFIX'];
export default class ResolutionFacet extends React.PureComponent<Props> {
property = 'resolutions';
diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/StatusFacet.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/StatusFacet.tsx
index 03d6864947a..ea83e7a20c2 100644
--- a/server/sonar-web/src/main/js/apps/issues/sidebar/StatusFacet.tsx
+++ b/server/sonar-web/src/main/js/apps/issues/sidebar/StatusFacet.tsx
@@ -38,14 +38,14 @@ interface Props {
statuses: string[];
}
-const STATUSES = ['OPEN', 'RESOLVED', 'REOPENED', 'CLOSED', 'CONFIRMED'];
+const STATUSES = ['OPEN', 'CONFIRMED', 'REOPENED', 'RESOLVED'];
+const HOTSPOT_STATUSES = ['TO_REVIEW', 'REVIEWED', 'IN_REVIEW'];
+const COMMON_STATUSES = ['CLOSED'];
export default class StatusFacet extends React.PureComponent<Props> {
property = 'statuses';
- static defaultProps = {
- open: true
- };
+ static defaultProps = { open: true };
handleItemClick = (itemValue: string, multiple: boolean) => {
const { statuses } = this.props;
@@ -110,7 +110,15 @@ export default class StatusFacet extends React.PureComponent<Props> {
<DeferredSpinner loading={this.props.fetching} />
{this.props.open && (
<>
- <FacetItemsList>{STATUSES.map(this.renderItem)}</FacetItemsList>
+ <FacetItemsList title={translate('issues')}>
+ {STATUSES.map(this.renderItem)}
+ </FacetItemsList>
+ <FacetItemsList title={translate('issue.type.SECURITY_HOTSPOT.plural')}>
+ {HOTSPOT_STATUSES.map(this.renderItem)}
+ </FacetItemsList>
+ <FacetItemsList title={translate('issues.issues_and_hotspots')}>
+ {COMMON_STATUSES.map(this.renderItem)}
+ </FacetItemsList>
<MultipleSelectionHint options={Object.keys(stats).length} values={statuses.length} />
</>
)}
diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/__tests__/StatusFacet-test.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/__tests__/StatusFacet-test.tsx
new file mode 100644
index 00000000000..3b7b1482d35
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/issues/sidebar/__tests__/StatusFacet-test.tsx
@@ -0,0 +1,81 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 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 * as React from 'react';
+import { shallow } from 'enzyme';
+import StatusFacet from '../StatusFacet';
+import { click } from '../../../../helpers/testUtils';
+
+it('should render correctly', () => {
+ expect(shallowRender()).toMatchSnapshot();
+});
+
+it('should toggle status facet', () => {
+ const onToggle = jest.fn();
+ const wrapper = shallowRender({ onToggle });
+ click(wrapper.children('FacetHeader'));
+ expect(onToggle).toBeCalledWith('statuses');
+});
+
+it('should clear status facet', () => {
+ const onChange = jest.fn();
+ const wrapper = shallowRender({ onChange, statuses: ['TO_REVIEW'] });
+ wrapper.children('FacetHeader').prop<Function>('onClear')();
+ expect(onChange).toBeCalledWith({ statuses: [] });
+});
+
+it('should select a status', () => {
+ const onChange = jest.fn();
+ const wrapper = shallowRender({ onChange });
+ clickAndCheck('TO_REVIEW');
+ clickAndCheck('OPEN', true, ['OPEN', 'TO_REVIEW']);
+ clickAndCheck('CONFIRMED');
+
+ function clickAndCheck(status: string, multiple = false, expected = [status]) {
+ wrapper
+ .find(`FacetItemsList`)
+ .find(`FacetItem[value="${status}"]`)
+ .prop<Function>('onClick')(status, multiple);
+ expect(onChange).lastCalledWith({ statuses: expected });
+ wrapper.setProps({ statuses: expected });
+ }
+});
+
+function shallowRender(props: Partial<StatusFacet['props']> = {}) {
+ return shallow(
+ <StatusFacet
+ fetching={false}
+ onChange={jest.fn()}
+ onToggle={jest.fn()}
+ open={true}
+ stats={{
+ OPEN: 104,
+ CONFIRMED: 8,
+ REOPENED: 0,
+ RESOLVED: 0,
+ CLOSED: 8,
+ TO_REVIEW: 150,
+ IN_REVIEW: 7,
+ REVIEWED: 1105
+ }}
+ statuses={[]}
+ {...props}
+ />
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/__tests__/__snapshots__/StatusFacet-test.tsx.snap b/server/sonar-web/src/main/js/apps/issues/sidebar/__tests__/__snapshots__/StatusFacet-test.tsx.snap
new file mode 100644
index 00000000000..9d01da1c88e
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/issues/sidebar/__tests__/__snapshots__/StatusFacet-test.tsx.snap
@@ -0,0 +1,163 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<FacetBox
+ property="statuses"
+>
+ <FacetHeader
+ name="issues.facet.statuses"
+ onClear={[Function]}
+ onClick={[Function]}
+ open={true}
+ values={Array []}
+ />
+ <DeferredSpinner
+ loading={false}
+ timeout={100}
+ />
+ <FacetItemsList
+ title="issues"
+ >
+ <FacetItem
+ active={false}
+ disabled={false}
+ halfWidth={true}
+ key="OPEN"
+ loading={false}
+ name={
+ <StatusHelper
+ status="OPEN"
+ />
+ }
+ onClick={[Function]}
+ stat="104"
+ tooltip="issue.status.OPEN"
+ value="OPEN"
+ />
+ <FacetItem
+ active={false}
+ disabled={false}
+ halfWidth={true}
+ key="CONFIRMED"
+ loading={false}
+ name={
+ <StatusHelper
+ status="CONFIRMED"
+ />
+ }
+ onClick={[Function]}
+ stat="8"
+ tooltip="issue.status.CONFIRMED"
+ value="CONFIRMED"
+ />
+ <FacetItem
+ active={false}
+ disabled={true}
+ halfWidth={true}
+ key="REOPENED"
+ loading={false}
+ name={
+ <StatusHelper
+ status="REOPENED"
+ />
+ }
+ onClick={[Function]}
+ stat={0}
+ tooltip="issue.status.REOPENED"
+ value="REOPENED"
+ />
+ <FacetItem
+ active={false}
+ disabled={true}
+ halfWidth={true}
+ key="RESOLVED"
+ loading={false}
+ name={
+ <StatusHelper
+ status="RESOLVED"
+ />
+ }
+ onClick={[Function]}
+ stat={0}
+ tooltip="issue.status.RESOLVED"
+ value="RESOLVED"
+ />
+ </FacetItemsList>
+ <FacetItemsList
+ title="issue.type.SECURITY_HOTSPOT.plural"
+ >
+ <FacetItem
+ active={false}
+ disabled={false}
+ halfWidth={true}
+ key="TO_REVIEW"
+ loading={false}
+ name={
+ <StatusHelper
+ status="TO_REVIEW"
+ />
+ }
+ onClick={[Function]}
+ stat="150"
+ tooltip="issue.status.TO_REVIEW"
+ value="TO_REVIEW"
+ />
+ <FacetItem
+ active={false}
+ disabled={false}
+ halfWidth={true}
+ key="REVIEWED"
+ loading={false}
+ name={
+ <StatusHelper
+ status="REVIEWED"
+ />
+ }
+ onClick={[Function]}
+ stat="1.1short_number_suffix.k"
+ tooltip="issue.status.REVIEWED"
+ value="REVIEWED"
+ />
+ <FacetItem
+ active={false}
+ disabled={false}
+ halfWidth={true}
+ key="IN_REVIEW"
+ loading={false}
+ name={
+ <StatusHelper
+ status="IN_REVIEW"
+ />
+ }
+ onClick={[Function]}
+ stat="7"
+ tooltip="issue.status.IN_REVIEW"
+ value="IN_REVIEW"
+ />
+ </FacetItemsList>
+ <FacetItemsList
+ title="issues.issues_and_hotspots"
+ >
+ <FacetItem
+ active={false}
+ disabled={false}
+ halfWidth={true}
+ key="CLOSED"
+ loading={false}
+ name={
+ <StatusHelper
+ status="CLOSED"
+ />
+ }
+ onClick={[Function]}
+ stat="8"
+ tooltip="issue.status.CLOSED"
+ value="CLOSED"
+ />
+ </FacetItemsList>
+ <MultipleSelectionHint
+ options={8}
+ values={0}
+ />
+</FacetBox>
+`;