@@ -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 }); |
@@ -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} | |||
/> | |||
); | |||
} |
@@ -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> | |||
`; |