Browse Source

SONAR-17806 Empty issue location message is now navigable

tags/10.0.0.68432
Mathieu Suen 1 year ago
parent
commit
c8807b0963

+ 57
- 0
server/sonar-web/src/main/js/api/mocks/IssuesServiceMock.ts View File

@@ -98,6 +98,63 @@ export default class IssuesServiceMock {

constructor() {
this.defaultList = [
{
issue: mockRawIssue(false, {
key: 'issue101',
component: 'foo:test1.js',
message: 'Issue with no location message',
rule: 'simpleRuleId',
textRange: {
startLine: 10,
endLine: 10,
startOffset: 0,
endOffset: 2,
},
flows: [
{
locations: [
{
component: 'foo:test1.js',
textRange: {
startLine: 1,
endLine: 1,
startOffset: 0,
endOffset: 1,
},
},
],
},
{
locations: [
{
component: 'foo:test2.js',
textRange: {
startLine: 20,
endLine: 20,
startOffset: 0,
endOffset: 1,
},
},
],
},
],
}),
snippets: keyBy(
[
mockSnippetsByComponent(
'test1.js',
'foo',
times(40, (i) => i + 1)
),
mockSnippetsByComponent(
'test2.js',
'foo',
times(40, (i) => i + 1)
),
],
'component.key'
),
},
{
issue: mockRawIssue(false, {
key: 'issue11',

+ 7
- 0
server/sonar-web/src/main/js/apps/issues/__tests__/IssuesApp-it.tsx View File

@@ -121,6 +121,13 @@ it('should show warning when not all issues are accessible', async () => {
expect(await screen.findByRole('alert', { name: 'alert.tooltip.warning' })).toBeInTheDocument();
});

it('should show secondary location even when no message is present', async () => {
renderProjectIssuesApp('project/issues?issues=issue101&open=issue101&id=myproject');

expect(await screen.findByRole('button', { name: '1 issue.location_x.1' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: '2 issue.location_x.2' })).toBeInTheDocument();
});

it('should interact with flows and locations', async () => {
const user = userEvent.setup();
renderProjectIssuesApp('project/issues?issues=issue11&open=issue11&id=myproject');

+ 1
- 1
server/sonar-web/src/main/js/components/locations/LocationsList.tsx View File

@@ -38,7 +38,7 @@ export default class LocationsList extends React.PureComponent<Props> {
const locationComponents = [componentKey, ...locations.map((location) => location.component)];
const isCrossFile = uniq(locationComponents).length > 1;

if (!locations || locations.length === 0 || locations.every((location) => !location.msg)) {
if (!locations || locations.length === 0) {
return null;
}


+ 6
- 1
server/sonar-web/src/main/js/components/locations/SingleFileLocationNavigator.tsx View File

@@ -19,6 +19,7 @@
*/
import classNames from 'classnames';
import * as React from 'react';
import { translateWithParameters } from '../../helpers/l10n';
import { MessageFormatting } from '../../types/issues';
import LocationIndex from '../common/LocationIndex';
import LocationMessage from '../common/LocationMessage';
@@ -77,7 +78,11 @@ export default class SingleFileLocationNavigator extends React.PureComponent<Pro
>
<LocationIndex>{index + 1}</LocationIndex>
<LocationMessage>
{<IssueMessageHighlighting message={message} messageFormattings={messageFormattings} />}
{message ? (
<IssueMessageHighlighting message={message} messageFormattings={messageFormattings} />
) : (
translateWithParameters('issue.location_x', index + 1)
)}
</LocationMessage>
</ButtonPlain>
);

+ 0
- 39
server/sonar-web/src/main/js/components/locations/__tests__/SingleFileLocationsNavigator-test.tsx View File

@@ -1,39 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2023 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 SingleFileLocationNavigator from '../SingleFileLocationNavigator';

it('should render correctly', () => {
expect(shallowRender()).toMatchSnapshot('index 1');
expect(shallowRender({ index: 1 })).toMatchSnapshot('index 2');
});

function shallowRender(props: Partial<SingleFileLocationNavigator['props']> = {}) {
return shallow(
<SingleFileLocationNavigator
index={0}
message=""
onClick={jest.fn()}
selected={true}
{...props}
/>
);
}

+ 0
- 41
server/sonar-web/src/main/js/components/locations/__tests__/__snapshots__/SingleFileLocationsNavigator-test.tsx.snap View File

@@ -1,41 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should render correctly: index 1 1`] = `
<ButtonPlain
aria-current="location"
className="locations-navigator selected"
innerRef={[Function]}
onClick={[Function]}
preventDefault={true}
stopPropagation={true}
>
<LocationIndex>
1
</LocationIndex>
<LocationMessage>
<IssueMessageHighlighting
message=""
/>
</LocationMessage>
</ButtonPlain>
`;

exports[`should render correctly: index 2 1`] = `
<ButtonPlain
aria-current="location"
className="locations-navigator selected"
innerRef={[Function]}
onClick={[Function]}
preventDefault={true}
stopPropagation={true}
>
<LocationIndex>
2
</LocationIndex>
<LocationMessage>
<IssueMessageHighlighting
message=""
/>
</LocationMessage>
</ButtonPlain>
`;

+ 1
- 0
sonar-core/src/main/resources/org/sonar/l10n/core.properties View File

@@ -878,6 +878,7 @@ issue.transition.resetastoreview.description=The Security Hotspot should be anal
issue.tabs.code=Where is the issue?
issue.x_data_flows={0} data flow(s)
issue.execution_flow=Full execution flow
issue.location_x=Location {0}
issue.closed.file_level=This issue is {status}. It was detected in the file below and is no longer being detected.
issue.closed.project_level=This issue is {status}. It was detected in the project below and is no longer being detected.


Loading…
Cancel
Save