diff options
Diffstat (limited to 'server/sonar-web/src/main/js/apps')
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> +`; |