diff options
author | Wouter Admiraal <wouter.admiraal@sonarsource.com> | 2019-03-27 10:18:27 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2019-03-29 09:44:58 +0100 |
commit | 35625522ce5ef18b877f2828e18fff9ab5218a5c (patch) | |
tree | 2783a2e9fd05e554913eaa6e7127213e76d5be58 | |
parent | c7bfd7c962e66a039c8fb93592361c1810ee4ebc (diff) | |
download | sonarqube-35625522ce5ef18b877f2828e18fff9ab5218a5c.tar.gz sonarqube-35625522ce5ef18b877f2828e18fff9ab5218a5c.zip |
Fix potential bug in MetaQualityProfiles, add tests
3 files changed, 194 insertions, 5 deletions
diff --git a/server/sonar-web/src/main/js/apps/overview/meta/MetaQualityProfiles.tsx b/server/sonar-web/src/main/js/apps/overview/meta/MetaQualityProfiles.tsx index f5e666d5b87..ff3850cb1f4 100644 --- a/server/sonar-web/src/main/js/apps/overview/meta/MetaQualityProfiles.tsx +++ b/server/sonar-web/src/main/js/apps/overview/meta/MetaQualityProfiles.tsx @@ -41,7 +41,7 @@ interface State { deprecatedByKey: T.Dict<number>; } -class MetaQualityProfiles extends React.PureComponent<StateProps & OwnProps, State> { +export class MetaQualityProfiles extends React.PureComponent<StateProps & OwnProps, State> { mounted = false; state: State = { deprecatedByKey: {} }; @@ -55,15 +55,16 @@ class MetaQualityProfiles extends React.PureComponent<StateProps & OwnProps, Sta } loadDeprecatedRules() { - const requests = this.props.profiles - .filter(p => !p.deleted) - .map(profile => this.loadDeprecatedRulesForProfile(profile.key)); + const existingProfiles = this.props.profiles.filter(p => !p.deleted); + const requests = existingProfiles.map(profile => + this.loadDeprecatedRulesForProfile(profile.key) + ); Promise.all(requests).then( responses => { if (this.mounted) { const deprecatedByKey: T.Dict<number> = {}; responses.forEach((count, i) => { - const profileKey = this.props.profiles[i].key; + const profileKey = existingProfiles[i].key; deprecatedByKey[profileKey] = count; }); this.setState({ deprecatedByKey }); diff --git a/server/sonar-web/src/main/js/apps/overview/meta/__tests__/MetaQualityProfiles-test.tsx b/server/sonar-web/src/main/js/apps/overview/meta/__tests__/MetaQualityProfiles-test.tsx new file mode 100644 index 00000000000..034aa685747 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/overview/meta/__tests__/MetaQualityProfiles-test.tsx @@ -0,0 +1,60 @@ +/* + * 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 { MetaQualityProfiles } from '../MetaQualityProfiles'; +import { mockLanguage, mockQualityProfile } from '../../../../helpers/testMocks'; +import { searchRules } from '../../../../api/rules'; +import { waitAndUpdate } from '../../../../helpers/testUtils'; + +jest.mock('../../../../api/rules', () => { + return { + searchRules: jest.fn().mockResolvedValue({ + total: 10 + }) + }; +}); + +it('should render correctly', async () => { + const wrapper = shallowRender(); + expect(wrapper).toMatchSnapshot(); + + await waitAndUpdate(wrapper); + expect(wrapper).toMatchSnapshot(); + expect(wrapper.find('.overview-deprecated-rules').exists()).toBe(true); + expect(wrapper.find('.overview-deleted-profile').exists()).toBe(true); + expect(searchRules).toBeCalled(); +}); + +function shallowRender(props: Partial<MetaQualityProfiles['props']> = {}) { + return shallow( + <MetaQualityProfiles + languages={{ css: mockLanguage() }} + profiles={[ + { ...mockQualityProfile({ key: 'js' }), deleted: true }, + { + ...mockQualityProfile({ key: 'css', language: 'css', languageName: 'CSS' }), + deleted: false + } + ]} + {...props} + /> + ); +} diff --git a/server/sonar-web/src/main/js/apps/overview/meta/__tests__/__snapshots__/MetaQualityProfiles-test.tsx.snap b/server/sonar-web/src/main/js/apps/overview/meta/__tests__/__snapshots__/MetaQualityProfiles-test.tsx.snap new file mode 100644 index 00000000000..aeef836890a --- /dev/null +++ b/server/sonar-web/src/main/js/apps/overview/meta/__tests__/__snapshots__/MetaQualityProfiles-test.tsx.snap @@ -0,0 +1,128 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render correctly 1`] = ` +<Fragment> + <h4 + className="overview-meta-header" + > + overview.quality_profiles + </h4> + <ul + className="overview-meta-list" + > + <Tooltip + key="js" + overlay="overview.deleted_profile.name" + > + <li + className="overview-deleted-profile" + > + <div + className="text-ellipsis" + > + <span + className="note spacer-right" + > + (js) + </span> + name + </div> + </li> + </Tooltip> + <li + key="css" + > + <div + className="text-ellipsis" + > + <span + className="note spacer-right" + > + (CSS) + </span> + <Link + onlyActiveOnIndex={false} + style={Object {}} + to={ + Object { + "pathname": "/profiles/show", + "query": Object { + "language": "css", + "name": "name", + }, + } + } + > + name + </Link> + </div> + </li> + </ul> +</Fragment> +`; + +exports[`should render correctly 2`] = ` +<Fragment> + <h4 + className="overview-meta-header" + > + overview.quality_profiles + </h4> + <ul + className="overview-meta-list" + > + <Tooltip + key="js" + overlay="overview.deleted_profile.name" + > + <li + className="overview-deleted-profile" + > + <div + className="text-ellipsis" + > + <span + className="note spacer-right" + > + (js) + </span> + name + </div> + </li> + </Tooltip> + <Tooltip + key="css" + overlay="overview.deprecated_profile.10" + > + <li + className="overview-deprecated-rules" + > + <div + className="text-ellipsis" + > + <span + className="note spacer-right" + > + (CSS) + </span> + <Link + onlyActiveOnIndex={false} + style={Object {}} + to={ + Object { + "pathname": "/profiles/show", + "query": Object { + "language": "css", + "name": "name", + }, + } + } + > + name + </Link> + </div> + </li> + </Tooltip> + </ul> +</Fragment> +`; |