aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps/security-hotspots
diff options
context:
space:
mode:
Diffstat (limited to 'server/sonar-web/src/main/js/apps/security-hotspots')
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsApp.tsx58
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsAppRenderer.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/__tests__/SecurityHotspotsApp-it.tsx12
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/__tests__/SecurityHotspotsApp-test.tsx89
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/__tests__/SecurityHotspotsAppRenderer-test.tsx23
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/__tests__/utils-test.ts92
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/FilterBar.tsx19
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotCategory.tsx7
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotCommentPopup.tsx8
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotHeader.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotList.tsx14
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotListItem.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotOpenInIdeButton.tsx5
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotOpenInIdeOverlay.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotPrimaryLocationBox.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotReviewHistory.tsx16
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotReviewHistoryAndComments.tsx9
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSimpleList.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetContainer.tsx30
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetContainerRenderer.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetHeader.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewer.tsx10
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewerRenderer.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewerTabs.tsx31
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/StatusUpdateSuccessModal.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/FilterBar-test.tsx16
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotCategory-test.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotCommentPopup-test.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotHeader-test.tsx5
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotList-test.tsx10
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotOpenInIdeButton-test.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotOpenInIdeOverlay-test.tsx5
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotPrimaryLocationBox-test.tsx14
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotReviewHistory-test.tsx64
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotReviewHistoryAndComments-test.tsx11
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSimpleList-test.tsx8
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSnippetContainer-test.tsx58
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSnippetContainerRenderer-test.tsx16
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSnippetHeader-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotViewer-test.tsx47
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotViewerRenderer-test.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotViewerTabs-test.tsx42
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/StatusUpdateSuccessModal-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/Assignee.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/AssigneeSelection.tsx10
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/AssigneeSelectionRenderer.tsx7
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/Assignee-test.tsx25
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/AssigneeRenderer-test.tsx10
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/AssigneeSelection-test.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/AssigneeSelectionRenderer-test.tsx11
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/status/Status.tsx11
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/status/StatusSelection.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/status/StatusSelectionRenderer.tsx3
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/status/__tests__/Status-test.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/utils.ts74
55 files changed, 445 insertions, 509 deletions
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsApp.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsApp.tsx
index 3854bc3e60d..beaccb76e96 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsApp.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsApp.tsx
@@ -36,7 +36,7 @@ import {
HotspotResolution,
HotspotStatus,
HotspotStatusFilter,
- RawHotspot
+ RawHotspot,
} from '../../types/security-hotspots';
import { Component, Dict } from '../../types/types';
import { CurrentUser, isLoggedIn } from '../../types/users';
@@ -100,12 +100,12 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
[SecurityStandard.CWE]: {},
[SecurityStandard.PCI_DSS_3_2]: {},
[SecurityStandard.PCI_DSS_4_0]: {},
- [SecurityStandard.OWASP_ASVS_4_0]: {}
+ [SecurityStandard.OWASP_ASVS_4_0]: {},
},
filters: {
...this.constructFiltersFromProps(props),
- status: HotspotStatusFilter.TO_REVIEW
- }
+ status: HotspotStatusFilter.TO_REVIEW,
+ },
};
}
@@ -119,7 +119,7 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
if (
this.props.component.key !== previous.component.key ||
this.props.location.query.hotspots !== previous.location.query.hotspots ||
- SECURITY_STANDARDS.some(s => this.props.location.query[s] !== previous.location.query[s]) ||
+ SECURITY_STANDARDS.some((s) => this.props.location.query[s] !== previous.location.query[s]) ||
this.props.location.query.files !== previous.location.query.files
) {
this.fetchInitialData();
@@ -132,7 +132,7 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
this.props.location.query.inNewCodePeriod !== previous.location.query.inNewCodePeriod
) {
this.setState(({ filters }) => ({
- filters: { ...this.constructFiltersFromProps, ...filters }
+ filters: { ...this.constructFiltersFromProps, ...filters },
}));
}
}
@@ -211,12 +211,12 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
selectNeighboringHotspot = (shift: number) => {
this.setState({ selectedHotspotLocationIndex: undefined });
this.setState(({ hotspots, selectedHotspot }) => {
- const index = selectedHotspot && hotspots.findIndex(h => h.key === selectedHotspot.key);
+ const index = selectedHotspot && hotspots.findIndex((h) => h.key === selectedHotspot.key);
if (index !== undefined && index > -1) {
const newIndex = Math.max(0, Math.min(hotspots.length - 1, index + shift));
return {
- selectedHotspot: hotspots[newIndex]
+ selectedHotspot: hotspots[newIndex],
};
}
@@ -234,7 +234,7 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
return {
assignedToMe: props.location.query.assignedToMe === 'true' && isLoggedIn(props.currentUser),
inNewCodePeriod:
- isPullRequest(props.branchLike) || props.location.query.inNewCodePeriod === 'true'
+ isPullRequest(props.branchLike) || props.location.query.inNewCodePeriod === 'true',
};
}
@@ -248,7 +248,7 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
return Promise.all([
getStandards(),
this.fetchSecurityHotspots(),
- this.fetchSecurityHotspotsReviewed()
+ this.fetchSecurityHotspotsReviewed(),
])
.then(([standards, { hotspots, paging }]) => {
if (!this.mounted) {
@@ -262,7 +262,7 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
hotspotsTotal: paging.total,
loading: false,
selectedHotspot,
- standards
+ standards,
});
})
.catch(this.handleCallFailure);
@@ -280,9 +280,9 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
return getMeasures({
component: component.key,
metricKeys: reviewedHotspotsMetricKey,
- ...getBranchLikeQuery(branchLike)
+ ...getBranchLikeQuery(branchLike),
})
- .then(measures => {
+ .then((measures) => {
if (!this.mounted) {
return;
}
@@ -309,7 +309,7 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
: undefined;
const standard = SECURITY_STANDARDS.find(
- stnd => stnd !== SecurityStandard.CWE && location.query[stnd] !== undefined
+ (stnd) => stnd !== SecurityStandard.CWE && location.query[stnd] !== undefined
);
const filterByCategory = standard
? { standard, category: location.query[standard] }
@@ -324,7 +324,7 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
if (hotspotKeys && hotspotKeys.length > 0) {
return getSecurityHotspotList(hotspotKeys, {
projectKey: component.key,
- ...getBranchLikeQuery(branchLike)
+ ...getBranchLikeQuery(branchLike),
});
}
@@ -350,7 +350,7 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
ps: PAGE_SIZE,
status: HotspotStatus.TO_REVIEW, // we're only interested in unresolved hotspots
inNewCodePeriod: filters.inNewCodePeriod && Boolean(filterByFile), // only add leak period when filtering by file
- ...getBranchLikeQuery(branchLike)
+ ...getBranchLikeQuery(branchLike),
});
}
@@ -372,7 +372,7 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
resolution,
onlyMine: filters.assignedToMe,
inNewCodePeriod: filters.inNewCodePeriod,
- ...getBranchLikeQuery(branchLike)
+ ...getBranchLikeQuery(branchLike),
});
}
@@ -390,7 +390,7 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
hotspotsPageIndex: 1,
hotspotsTotal: paging.total,
loading: false,
- selectedHotspot: hotspots.length > 0 ? hotspots[0] : undefined
+ selectedHotspot: hotspots.length > 0 ? hotspots[0] : undefined,
});
})
.catch(this.handleCallFailure);
@@ -418,16 +418,18 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
handleHotspotUpdate = (hotspotKey: string) => {
const { hotspots, hotspotsPageIndex } = this.state;
const { branchLike, component } = this.props;
- const index = hotspots.findIndex(h => h.key === hotspotKey);
+ const index = hotspots.findIndex((h) => h.key === hotspotKey);
if (isPullRequest(branchLike)) {
this.props.fetchBranchStatus(branchLike, component.key);
}
return Promise.all(
- range(hotspotsPageIndex).map(p => this.fetchSecurityHotspots(p + 1 /* pages are 1-indexed */))
+ range(hotspotsPageIndex).map((p) =>
+ this.fetchSecurityHotspots(p + 1 /* pages are 1-indexed */)
+ )
)
- .then(hotspotPages => {
+ .then((hotspotPages) => {
const allHotspots = flatMap(hotspotPages, 'hotspots');
const { paging } = hotspotPages[hotspotPages.length - 1];
@@ -438,7 +440,7 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
hotspots: allHotspots,
hotspotsPageIndex: paging.pageIndex,
hotspotsTotal: paging.total,
- selectedHotspot: selectedHotspot?.key === hotspotKey ? nextHotspot : selectedHotspot
+ selectedHotspot: selectedHotspot?.key === hotspotKey ? nextHotspot : selectedHotspot,
}));
})
.then(this.fetchSecurityHotspotsReviewed);
@@ -458,8 +460,8 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
[SecurityStandard.PCI_DSS_3_2]: undefined,
[SecurityStandard.PCI_DSS_4_0]: undefined,
[SecurityStandard.OWASP_ASVS_4_0]: undefined,
- file: undefined
- }
+ file: undefined,
+ },
});
};
@@ -477,7 +479,7 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
this.setState({
hotspots: [...hotspots, ...additionalHotspots],
hotspotsPageIndex: hotspotPages + 1,
- loadingMore: false
+ loadingMore: false,
});
})
.catch(this.handleCallFailure);
@@ -488,11 +490,11 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
if (locationIndex === undefined || locationIndex === selectedHotspotLocationIndex) {
this.setState({
- selectedHotspotLocationIndex: undefined
+ selectedHotspotLocationIndex: undefined,
});
} else {
this.setState({
- selectedHotspotLocationIndex: locationIndex
+ selectedHotspotLocationIndex: locationIndex,
});
}
};
@@ -513,7 +515,7 @@ export class SecurityHotspotsApp extends React.PureComponent<Props, State> {
loadingMore,
selectedHotspot,
selectedHotspotLocationIndex,
- standards
+ standards,
} = this.state;
return (
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsAppRenderer.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsAppRenderer.tsx
index 5de54085163..fc27424a6b6 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsAppRenderer.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/SecurityHotspotsAppRenderer.tsx
@@ -85,7 +85,7 @@ export default function SecurityHotspotsAppRenderer(props: SecurityHotspotsAppRe
securityCategories,
selectedHotspot,
selectedHotspotLocation,
- standards
+ standards,
} = props;
const scrollableRef = React.useRef(null);
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/__tests__/SecurityHotspotsApp-it.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/__tests__/SecurityHotspotsApp-it.tsx
index 9bff505526e..922b3deb7f7 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/__tests__/SecurityHotspotsApp-it.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/__tests__/SecurityHotspotsApp-it.tsx
@@ -35,9 +35,9 @@ jest.mock('../../../api/components');
const ui = {
selectStatusButton: byRole('button', {
- name: 'hotspots.status.select_status'
+ name: 'hotspots.status.select_status',
}),
- panel: byTestId('security-hotspot-test')
+ panel: byTestId('security-hotspot-test'),
};
let handler: SecurityHotspotServiceMock;
@@ -80,8 +80,8 @@ function renderSecurityHotspotsApp(navigateTo?: string) {
navigateTo,
currentUser: mockLoggedInUser({
login: 'foo',
- name: 'foo'
- })
+ name: 'foo',
+ }),
},
{
branchLikes: [],
@@ -89,8 +89,8 @@ function renderSecurityHotspotsApp(navigateTo?: string) {
onComponentChange: jest.fn(),
component: mockComponent({
key: 'guillaume-peoch-sonarsource_benflix_AYGpXq2bd8qy4i0eO9ed',
- name: 'benflix'
- })
+ name: 'benflix',
+ }),
}
);
}
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/__tests__/SecurityHotspotsApp-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/__tests__/SecurityHotspotsApp-test.tsx
index b22b3c6b1d5..1a3b82c8a98 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/__tests__/SecurityHotspotsApp-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/__tests__/SecurityHotspotsApp-test.tsx
@@ -31,14 +31,14 @@ import {
mockFlowLocation,
mockLocation,
mockLoggedInUser,
- mockRouter
+ mockRouter,
} from '../../../helpers/testMocks';
import { mockEvent, waitAndUpdate } from '../../../helpers/testUtils';
import { SecurityStandard } from '../../../types/security';
import {
HotspotResolution,
HotspotStatus,
- HotspotStatusFilter
+ HotspotStatusFilter,
} from '../../../types/security-hotspots';
import { SecurityHotspotsApp } from '../SecurityHotspotsApp';
import SecurityHotspotsAppRenderer from '../SecurityHotspotsAppRenderer';
@@ -48,20 +48,20 @@ beforeEach(() => {
});
jest.mock('../../../api/measures', () => ({
- getMeasures: jest.fn().mockResolvedValue([])
+ getMeasures: jest.fn().mockResolvedValue([]),
}));
jest.mock('../../../api/security-hotspots', () => ({
getSecurityHotspots: jest.fn().mockResolvedValue({ hotspots: [], paging: { total: 0 } }),
- getSecurityHotspotList: jest.fn().mockResolvedValue({ hotspots: [], rules: [] })
+ getSecurityHotspotList: jest.fn().mockResolvedValue({ hotspots: [], rules: [] }),
}));
jest.mock('../../../helpers/security-standard', () => ({
- getStandards: jest.fn().mockResolvedValue({ sonarsourceSecurity: { cat1: { title: 'cat 1' } } })
+ getStandards: jest.fn().mockResolvedValue({ sonarsourceSecurity: { cat1: { title: 'cat 1' } } }),
}));
jest.mock('../../../helpers/scrolling', () => ({
- scrollToElement: jest.fn()
+ scrollToElement: jest.fn(),
}));
const branch = mockBranch();
@@ -75,8 +75,8 @@ it('should load data correctly', async () => {
(getSecurityHotspots as jest.Mock).mockResolvedValue({
hotspots,
paging: {
- total: 1
- }
+ total: 1,
+ },
});
(getMeasures as jest.Mock).mockResolvedValue([{ value: '86.6' }]);
@@ -88,12 +88,12 @@ it('should load data correctly', async () => {
expect(getStandards).toHaveBeenCalled();
expect(getSecurityHotspots).toHaveBeenCalledWith(
expect.objectContaining({
- branch: branch.name
+ branch: branch.name,
})
);
expect(getMeasures).toHaveBeenCalledWith(
expect.objectContaining({
- branch: branch.name
+ branch: branch.name,
})
);
@@ -104,8 +104,8 @@ it('should load data correctly', async () => {
expect(wrapper.state().selectedHotspot).toBe(hotspots[0]);
expect(wrapper.state().standards).toEqual({
sonarsourceSecurity: {
- cat1: { title: 'cat 1' }
- }
+ cat1: { title: 'cat 1' },
+ },
});
expect(wrapper.state().loadingMeasure).toBe(false);
expect(wrapper.state().hotspotsReviewedMeasure).toBe('86.6');
@@ -116,7 +116,7 @@ it('should handle category request', () => {
(getMeasures as jest.Mock).mockResolvedValue([{ value: '86.6' }]);
shallowRender({
- location: mockLocation({ query: { [SecurityStandard.OWASP_TOP10]: 'a1' } })
+ location: mockLocation({ query: { [SecurityStandard.OWASP_TOP10]: 'a1' } }),
});
expect(getSecurityHotspots).toHaveBeenCalledWith(
@@ -129,7 +129,7 @@ it('should handle cwe request', () => {
(getMeasures as jest.Mock).mockResolvedValue([{ value: '86.6' }]);
shallowRender({
- location: mockLocation({ query: { [SecurityStandard.CWE]: '1004' } })
+ location: mockLocation({ query: { [SecurityStandard.CWE]: '1004' } }),
});
expect(getSecurityHotspots).toHaveBeenCalledWith(
@@ -144,7 +144,7 @@ it('should handle file request', () => {
const filepath = 'src/path/to/file.java';
shallowRender({
- location: mockLocation({ query: { files: filepath } })
+ location: mockLocation({ query: { files: filepath } }),
});
expect(getSecurityHotspots).toHaveBeenCalledWith(expect.objectContaining({ files: filepath }));
@@ -154,24 +154,24 @@ it('should load data correctly when hotspot key list is forced', async () => {
const hotspots = [
mockRawHotspot({ key: 'test1' }),
mockRawHotspot({ key: 'test2' }),
- mockRawHotspot({ key: 'test3' })
+ mockRawHotspot({ key: 'test3' }),
];
- const hotspotKeys = hotspots.map(h => h.key);
+ const hotspotKeys = hotspots.map((h) => h.key);
(getSecurityHotspotList as jest.Mock).mockResolvedValueOnce({
- hotspots
+ hotspots,
});
const location = mockLocation({ query: { hotspots: hotspotKeys.join() } });
const router = mockRouter();
const wrapper = shallowRender({
location,
- router
+ router,
});
await waitAndUpdate(wrapper);
expect(getSecurityHotspotList).toHaveBeenCalledWith(hotspotKeys, {
projectKey: 'my-project',
- branch: 'branch-6.7'
+ branch: 'branch-6.7',
});
expect(wrapper.state().hotspotKeys).toEqual(hotspotKeys);
expect(wrapper.find(SecurityHotspotsAppRenderer).props().isStaticListOfHotspots).toBe(true);
@@ -179,18 +179,15 @@ it('should load data correctly when hotspot key list is forced', async () => {
// Reset
(getSecurityHotspots as jest.Mock).mockClear();
(getSecurityHotspotList as jest.Mock).mockClear();
- wrapper
- .find(SecurityHotspotsAppRenderer)
- .props()
- .onShowAllHotspots();
+ wrapper.find(SecurityHotspotsAppRenderer).props().onShowAllHotspots();
expect(router.push).toHaveBeenCalledWith({
...location,
- query: { ...location.query, hotspots: undefined }
+ query: { ...location.query, hotspots: undefined },
});
// Simulate a new location
wrapper.setProps({
- location: { ...location, query: { ...location.query, hotspots: undefined } }
+ location: { ...location, query: { ...location.query, hotspots: undefined } },
});
await waitAndUpdate(wrapper);
expect(wrapper.state().hotspotKeys).toBeUndefined();
@@ -222,7 +219,7 @@ it('should set "assigned to me" filter according to context (logged in & explici
expect(
shallowRender({
location: mockLocation({ query: { assignedToMe: 'true' } }),
- currentUser: mockLoggedInUser()
+ currentUser: mockLoggedInUser(),
}).state().filters.assignedToMe
).toBe(true);
});
@@ -233,11 +230,11 @@ it('should handle loading more', async () => {
(getSecurityHotspots as jest.Mock)
.mockResolvedValueOnce({
hotspots,
- paging: { total: 5 }
+ paging: { total: 5 },
})
.mockResolvedValueOnce({
hotspots: hotspots2,
- paging: { total: 5 }
+ paging: { total: 5 },
});
const wrapper = shallowRender();
@@ -266,7 +263,7 @@ it('should handle hotspot update', async () => {
(getSecurityHotspots as jest.Mock).mockResolvedValueOnce({
hotspots,
- paging: { pageIndex: 1, total: 1252 }
+ paging: { pageIndex: 1, total: 1252 },
});
let wrapper = shallowRender();
@@ -277,21 +274,18 @@ it('should handle hotspot update', async () => {
(getSecurityHotspots as jest.Mock)
.mockResolvedValueOnce({
hotspots: [mockRawHotspot()],
- paging: { pageIndex: 1, total: 1251 }
+ paging: { pageIndex: 1, total: 1251 },
})
.mockResolvedValueOnce({
hotspots: [mockRawHotspot()],
- paging: { pageIndex: 2, total: 1251 }
+ paging: { pageIndex: 2, total: 1251 },
});
const selectedHotspotIndex = wrapper
.state()
- .hotspots.findIndex(h => h.key === wrapper.state().selectedHotspot?.key);
+ .hotspots.findIndex((h) => h.key === wrapper.state().selectedHotspot?.key);
- await wrapper
- .find(SecurityHotspotsAppRenderer)
- .props()
- .onUpdateHotspot(key);
+ await wrapper.find(SecurityHotspotsAppRenderer).props().onUpdateHotspot(key);
expect(getSecurityHotspots).toHaveBeenCalledTimes(2);
@@ -299,25 +293,22 @@ it('should handle hotspot update', async () => {
expect(wrapper.state().hotspotsPageIndex).toBe(2);
expect(wrapper.state().hotspotsTotal).toBe(1251);
expect(
- wrapper.state().hotspots.findIndex(h => h.key === wrapper.state().selectedHotspot?.key)
+ wrapper.state().hotspots.findIndex((h) => h.key === wrapper.state().selectedHotspot?.key)
).toBe(selectedHotspotIndex);
expect(getMeasures).toHaveBeenCalled();
(getSecurityHotspots as jest.Mock).mockResolvedValueOnce({
hotspots,
- paging: { pageIndex: 1, total: 1252 }
+ paging: { pageIndex: 1, total: 1252 },
});
wrapper = shallowRender({
branchLike,
fetchBranchStatus: fetchBranchStatusMock,
- component: mockComponent({ key: componentKey })
+ component: mockComponent({ key: componentKey }),
});
- await wrapper
- .find(SecurityHotspotsAppRenderer)
- .props()
- .onUpdateHotspot(key);
+ await wrapper.find(SecurityHotspotsAppRenderer).props().onUpdateHotspot(key);
expect(fetchBranchStatusMock).toHaveBeenCalledWith(branchLike, componentKey);
});
@@ -418,10 +409,10 @@ describe('keyboard navigation', () => {
const hotspots = [
mockRawHotspot({ key: 'k1' }),
mockRawHotspot({ key: 'k2' }),
- mockRawHotspot({ key: 'k3' })
+ mockRawHotspot({ key: 'k3' }),
];
const flowsData = {
- flows: [{ locations: [mockFlowLocation(), mockFlowLocation(), mockFlowLocation()] }]
+ flows: [{ locations: [mockFlowLocation(), mockFlowLocation(), mockFlowLocation()] }],
};
const hotspotsForLocation = mockRawHotspot(flowsData);
@@ -436,7 +427,7 @@ describe('keyboard navigation', () => {
['selecting next, non-existent', 2, 1, 2],
['jumping down', 0, 18, 2],
['jumping up', 2, -18, 0],
- ['none selected', 4, -2, 4]
+ ['none selected', 4, -2, 4],
])('should work when %s', (_, start, shift, expected) => {
wrapper.setState({ selectedHotspot: hotspots[start] });
wrapper.instance().selectNeighboringHotspot(shift);
@@ -447,7 +438,7 @@ describe('keyboard navigation', () => {
it.each([
['selecting next locations when nothing is selected', undefined, 0],
['selecting next locations', 0, 1],
- ['selecting next locations, non-existent', 2, undefined]
+ ['selecting next locations, non-existent', 2, undefined],
])('should work when %s', (_, start, expected) => {
wrapper.setState({ selectedHotspotLocationIndex: start, selectedHotspot: hotspotsForLocation });
wrapper.instance().handleKeyDown(mockEvent({ altKey: true, key: KeyboardKeys.DownArrow }));
@@ -458,7 +449,7 @@ describe('keyboard navigation', () => {
it.each([
['selecting previous locations when nothing is selected', undefined, undefined],
['selecting previous locations', 1, 0],
- ['selecting previous locations, non-existent', 0, undefined]
+ ['selecting previous locations, non-existent', 0, undefined],
])('should work when %s', (_, start, expected) => {
wrapper.setState({ selectedHotspotLocationIndex: start, selectedHotspot: hotspotsForLocation });
wrapper.instance().handleKeyDown(mockEvent({ altKey: true, key: KeyboardKeys.UpArrow }));
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/__tests__/SecurityHotspotsAppRenderer-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/__tests__/SecurityHotspotsAppRenderer-test.tsx
index e0e592c6f63..d5484ee24ee 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/__tests__/SecurityHotspotsAppRenderer-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/__tests__/SecurityHotspotsAppRenderer-test.tsx
@@ -27,11 +27,11 @@ import { SecurityStandard } from '../../../types/security';
import { HotspotStatusFilter } from '../../../types/security-hotspots';
import FilterBar from '../components/FilterBar';
import SecurityHotspotsAppRenderer, {
- SecurityHotspotsAppRendererProps
+ SecurityHotspotsAppRendererProps,
} from '../SecurityHotspotsAppRenderer';
jest.mock('../../../helpers/scrolling', () => ({
- scrollToElement: jest.fn()
+ scrollToElement: jest.fn(),
}));
jest.mock('../../../components/common/ScreenPositionHelper');
@@ -44,7 +44,7 @@ jest.mock('react', () => {
return {
...jest.requireActual('react'),
useRef: jest.fn(),
- useEffect: jest.fn()
+ useEffect: jest.fn(),
};
});
@@ -52,7 +52,11 @@ it('should render correctly', () => {
expect(shallowRender()).toMatchSnapshot();
expect(
shallowRender({
- filters: { assignedToMe: true, inNewCodePeriod: false, status: HotspotStatusFilter.TO_REVIEW }
+ filters: {
+ assignedToMe: true,
+ inNewCodePeriod: false,
+ status: HotspotStatusFilter.TO_REVIEW,
+ },
})
).toMatchSnapshot('no hotspots with filters');
expect(shallowRender({ loading: true })).toMatchSnapshot('loading');
@@ -81,7 +85,7 @@ it('should render correctly when filtered by category or cwe', () => {
filterByCategory: { category: 'a1', standard: SecurityStandard.OWASP_TOP10 },
hotspots,
hotspotsTotal: 2,
- selectedHotspot: hotspots[0]
+ selectedHotspot: hotspots[0],
})
.find(ScreenPositionHelper)
.dive()
@@ -92,10 +96,7 @@ it('should properly propagate the "show all" call', () => {
const onShowAllHotspots = jest.fn();
const wrapper = shallowRender({ onShowAllHotspots });
- wrapper
- .find(FilterBar)
- .props()
- .onShowAllHotspots();
+ wrapper.find(FilterBar).props().onShowAllHotspots();
expect(onShowAllHotspots).toHaveBeenCalled();
});
@@ -105,7 +106,7 @@ describe('side effect', () => {
const fakeParent = document.createElement('div');
beforeEach(() => {
- (React.useEffect as jest.Mock).mockImplementationOnce(f => f());
+ (React.useEffect as jest.Mock).mockImplementationOnce((f) => f());
jest.spyOn(document, 'querySelector').mockImplementationOnce(() => fakeElement);
(React.useRef as jest.Mock).mockImplementationOnce(() => ({ current: fakeParent }));
});
@@ -140,7 +141,7 @@ function shallowRender(props: Partial<SecurityHotspotsAppRendererProps> = {}) {
filters={{
assignedToMe: false,
inNewCodePeriod: false,
- status: HotspotStatusFilter.TO_REVIEW
+ status: HotspotStatusFilter.TO_REVIEW,
}}
hotspots={[]}
hotspotsTotal={0}
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/__tests__/utils-test.ts b/server/sonar-web/src/main/js/apps/security-hotspots/__tests__/utils-test.ts
index 12856d774dd..2090d30ea9d 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/__tests__/utils-test.ts
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/__tests__/utils-test.ts
@@ -26,7 +26,7 @@ import {
HotspotStatusOption,
RawHotspot,
ReviewHistoryType,
- RiskExposure
+ RiskExposure,
} from '../../../types/security-hotspots';
import { FlowLocation, IssueChangelog } from '../../../types/types';
import {
@@ -37,7 +37,7 @@ import {
getStatusOptionFromStatusAndResolution,
groupByCategory,
mapRules,
- sortHotspots
+ sortHotspots,
} from '../utils';
const hotspots = [
@@ -45,87 +45,87 @@ const hotspots = [
key: '3',
vulnerabilityProbability: RiskExposure.HIGH,
securityCategory: 'object-injection',
- message: 'tfdh'
+ message: 'tfdh',
}),
mockRawHotspot({
key: '5',
vulnerabilityProbability: RiskExposure.MEDIUM,
securityCategory: 'xpath-injection',
- message: 'asdf'
+ message: 'asdf',
}),
mockRawHotspot({
key: '1',
vulnerabilityProbability: RiskExposure.HIGH,
securityCategory: 'dos',
- message: 'a'
+ message: 'a',
}),
mockRawHotspot({
key: '7',
vulnerabilityProbability: RiskExposure.LOW,
securityCategory: 'ssrf',
- message: 'rrrr'
+ message: 'rrrr',
}),
mockRawHotspot({
key: '2',
vulnerabilityProbability: RiskExposure.HIGH,
securityCategory: 'dos',
- message: 'b'
+ message: 'b',
}),
mockRawHotspot({
key: '8',
vulnerabilityProbability: RiskExposure.LOW,
securityCategory: 'ssrf',
- message: 'sssss'
+ message: 'sssss',
}),
mockRawHotspot({
key: '4',
vulnerabilityProbability: RiskExposure.MEDIUM,
securityCategory: 'log-injection',
- message: 'asdf'
+ message: 'asdf',
}),
mockRawHotspot({
key: '9',
vulnerabilityProbability: RiskExposure.LOW,
securityCategory: 'xxe',
- message: 'aaa'
+ message: 'aaa',
}),
mockRawHotspot({
key: '6',
vulnerabilityProbability: RiskExposure.LOW,
securityCategory: 'xss',
- message: 'zzz'
- })
+ message: 'zzz',
+ }),
];
const categories = {
'object-injection': {
- title: 'Object Injection'
+ title: 'Object Injection',
},
'xpath-injection': {
- title: 'XPath Injection'
+ title: 'XPath Injection',
},
'log-injection': {
- title: 'Log Injection'
+ title: 'Log Injection',
},
dos: {
- title: 'Denial of Service (DoS)'
+ title: 'Denial of Service (DoS)',
},
ssrf: {
- title: 'Server-Side Request Forgery (SSRF)'
+ title: 'Server-Side Request Forgery (SSRF)',
},
xxe: {
- title: 'XML External Entity (XXE)'
+ title: 'XML External Entity (XXE)',
},
xss: {
- title: 'Cross-Site Scripting (XSS)'
- }
+ title: 'Cross-Site Scripting (XSS)',
+ },
};
describe('sortHotspots', () => {
it('should sort properly', () => {
const result = sortHotspots(hotspots, categories);
- expect(result.map(h => h.key)).toEqual(['1', '2', '3', '4', '5', '6', '7', '8', '9']);
+ expect(result.map((h) => h.key)).toEqual(['1', '2', '3', '4', '5', '6', '7', '8', '9']);
});
});
@@ -142,13 +142,13 @@ describe('mapRules', () => {
const rules = [
{ key: 'a', name: 'A rule' },
{ key: 'b', name: 'B rule' },
- { key: 'c', name: 'C rule' }
+ { key: 'c', name: 'C rule' },
];
expect(mapRules(rules)).toEqual({
a: 'A rule',
b: 'B rule',
- c: 'C rule'
+ c: 'C rule',
});
});
});
@@ -164,9 +164,9 @@ describe('getHotspotReviewHistory', () => {
{
key: 'assign',
newValue: 'me',
- oldValue: 'him'
- }
- ]
+ oldValue: 'him',
+ },
+ ],
};
const commentElement = {
key: 'comment-1',
@@ -175,7 +175,7 @@ describe('getHotspotReviewHistory', () => {
markdown: '*TEST*',
updatable: true,
login: 'dude-1',
- user: mockUser({ login: 'dude-1' })
+ user: mockUser({ login: 'dude-1' }),
};
const commentElement1 = {
key: 'comment-2',
@@ -184,12 +184,12 @@ describe('getHotspotReviewHistory', () => {
markdown: '*TEST*',
updatable: true,
login: 'dude-2',
- user: mockUser({ login: 'dude-2' })
+ user: mockUser({ login: 'dude-2' }),
};
const hotspot = mockHotspot({
creationDate: '2018-09-01',
changelog: [changelogElement],
- comment: [commentElement, commentElement1]
+ comment: [commentElement, commentElement1],
});
const reviewHistory = getHotspotReviewHistory(hotspot);
@@ -198,7 +198,7 @@ describe('getHotspotReviewHistory', () => {
expect.objectContaining({
type: ReviewHistoryType.Creation,
date: hotspot.creationDate,
- user: hotspot.authorUser
+ user: hotspot.authorUser,
})
);
expect(reviewHistory[2]).toEqual(
@@ -206,7 +206,7 @@ describe('getHotspotReviewHistory', () => {
type: ReviewHistoryType.Comment,
date: commentElement.createdAt,
user: commentElement.user,
- html: commentElement.htmlText
+ html: commentElement.htmlText,
})
);
expect(reviewHistory[1]).toEqual(
@@ -214,7 +214,7 @@ describe('getHotspotReviewHistory', () => {
type: ReviewHistoryType.Comment,
date: commentElement1.createdAt,
user: commentElement1.user,
- html: commentElement1.htmlText
+ html: commentElement1.htmlText,
})
);
expect(reviewHistory[0]).toEqual(
@@ -224,9 +224,9 @@ describe('getHotspotReviewHistory', () => {
user: {
avatar: changelogElement.avatar,
name: changelogElement.userName,
- active: changelogElement.isUserActive
+ active: changelogElement.isUserActive,
},
- diffs: changelogElement.diffs
+ diffs: changelogElement.diffs,
})
);
});
@@ -253,15 +253,15 @@ describe('getStatusAndResolutionFromStatusOption', () => {
it('should return the correct values', () => {
expect(getStatusAndResolutionFromStatusOption(HotspotStatusOption.TO_REVIEW)).toEqual({
status: HotspotStatus.TO_REVIEW,
- resolution: undefined
+ resolution: undefined,
});
expect(getStatusAndResolutionFromStatusOption(HotspotStatusOption.FIXED)).toEqual({
status: HotspotStatus.REVIEWED,
- resolution: HotspotResolution.FIXED
+ resolution: HotspotResolution.FIXED,
});
expect(getStatusAndResolutionFromStatusOption(HotspotStatusOption.SAFE)).toEqual({
status: HotspotStatus.REVIEWED,
- resolution: HotspotResolution.SAFE
+ resolution: HotspotResolution.SAFE,
});
});
});
@@ -285,36 +285,36 @@ describe('getLocations', () => {
const location1: FlowLocation = {
component: 'foo',
msg: 'Do not use foo',
- textRange: { startLine: 7, endLine: 7, startOffset: 5, endOffset: 8 }
+ textRange: { startLine: 7, endLine: 7, startOffset: 5, endOffset: 8 },
};
const location2: FlowLocation = {
component: 'foo2',
msg: 'Do not use foo2',
- textRange: { startLine: 7, endLine: 7, startOffset: 5, endOffset: 8 }
+ textRange: { startLine: 7, endLine: 7, startOffset: 5, endOffset: 8 },
};
let rawFlows: RawHotspot['flows'] = [
{
- locations: [location1]
- }
+ locations: [location1],
+ },
];
expect(getLocations(rawFlows, undefined)).toEqual([location1]);
rawFlows = [
{
- locations: [location1, location2]
- }
+ locations: [location1, location2],
+ },
];
expect(getLocations(rawFlows, undefined)).toEqual([location2, location1]);
rawFlows = [
{
- locations: [location1, location2]
+ locations: [location1, location2],
},
{
- locations: []
- }
+ locations: [],
+ },
];
expect(getLocations(rawFlows, 0)).toEqual([location2, location1]);
});
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/FilterBar.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/FilterBar.tsx
index 91409b6441a..40ff52e37c2 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/FilterBar.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/FilterBar.tsx
@@ -47,25 +47,25 @@ const statusOptions: Array<{ label: string; value: HotspotStatusFilter }> = [
{ value: HotspotStatusFilter.TO_REVIEW, label: translate('hotspot.filters.status.to_review') },
{
value: HotspotStatusFilter.ACKNOWLEDGED,
- label: translate('hotspot.filters.status.acknowledged')
+ label: translate('hotspot.filters.status.acknowledged'),
},
{ value: HotspotStatusFilter.FIXED, label: translate('hotspot.filters.status.fixed') },
- { value: HotspotStatusFilter.SAFE, label: translate('hotspot.filters.status.safe') }
+ { value: HotspotStatusFilter.SAFE, label: translate('hotspot.filters.status.safe') },
];
const periodOptions = [
{ value: true, label: translate('hotspot.filters.period.since_leak_period') },
- { value: false, label: translate('hotspot.filters.period.overall') }
+ { value: false, label: translate('hotspot.filters.period.overall') },
];
export enum AssigneeFilterOption {
ALL = 'all',
- ME = 'me'
+ ME = 'me',
}
const assigneeFilterOptions = [
{ value: AssigneeFilterOption.ME, label: translate('hotspot.filters.assignee.assigned_to_me') },
- { value: AssigneeFilterOption.ALL, label: translate('hotspot.filters.assignee.all') }
+ { value: AssigneeFilterOption.ALL, label: translate('hotspot.filters.assignee.all') },
];
export function FilterBar(props: FilterBarProps) {
@@ -76,7 +76,7 @@ export function FilterBar(props: FilterBarProps) {
hotspotsReviewedMeasure,
isStaticListOfHotspots,
loadingMeasure,
- onBranch
+ onBranch,
} = props;
const isProject = component.qualifier === ComponentQualifier.Project;
@@ -89,7 +89,8 @@ export function FilterBar(props: FilterBarProps) {
id="show_all_hotspot"
onClick={() => props.onShowAllHotspots()}
role="link"
- tabIndex={0}>
+ tabIndex={0}
+ >
{translate('hotspot.filters.show_all')}
</a>
) : (
@@ -120,7 +121,7 @@ export function FilterBar(props: FilterBarProps) {
}
options={statusOptions}
isSearchable={false}
- value={statusOptions.find(status => status.value === filters.status)}
+ value={statusOptions.find((status) => status.value === filters.status)}
/>
{onBranch && (
@@ -132,7 +133,7 @@ export function FilterBar(props: FilterBarProps) {
}
options={periodOptions}
isSearchable={false}
- value={periodOptions.find(period => period.value === filters.inNewCodePeriod)}
+ value={periodOptions.find((period) => period.value === filters.inNewCodePeriod)}
/>
)}
</div>
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotCategory.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotCategory.tsx
index 8197e305607..3a475d06c48 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotCategory.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotCategory.tsx
@@ -46,7 +46,7 @@ export default function HotspotCategory(props: HotspotCategoryProps) {
selectedHotspot,
title,
isLastAndIncomplete,
- selectedHotspotLocation
+ selectedHotspotLocation,
} = props;
if (hotspots.length < 1) {
@@ -64,7 +64,8 @@ export default function HotspotCategory(props: HotspotCategoryProps) {
{ 'contains-selected-hotspot': selectedHotspot.securityCategory === categoryKey }
)}
onClick={() => props.onToggleExpand && props.onToggleExpand(categoryKey, !expanded)}
- aria-expanded={expanded}>
+ aria-expanded={expanded}
+ >
<strong className="flex-1 spacer-right break-word">{title}</strong>
<span>
<span className="counter-badge">
@@ -85,7 +86,7 @@ export default function HotspotCategory(props: HotspotCategoryProps) {
)}
{expanded && (
<ul>
- {hotspots.map(h => (
+ {hotspots.map((h) => (
<li data-hotspot-key={h.key} key={h.key}>
<HotspotListItem
hotspot={h}
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotCommentPopup.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotCommentPopup.tsx
index eaaf49af299..bbc2e01417d 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotCommentPopup.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotCommentPopup.tsx
@@ -36,7 +36,7 @@ export default function HotspotCommentPopup(props: HotspotCommentPopupProps) {
<div className="issue-comment-form-text">
<textarea
autoFocus={true}
- onChange={event => setComment(event.target.value)}
+ onChange={(event) => setComment(event.target.value)}
rows={2}
value={comment}
/>
@@ -48,14 +48,16 @@ export default function HotspotCommentPopup(props: HotspotCommentPopupProps) {
<div className="">
<Button
className="little-spacer-right"
- onClick={() => props.onCommentEditSubmit(comment)}>
+ onClick={() => props.onCommentEditSubmit(comment)}
+ >
{translate('save')}
</Button>
<ResetButtonLink
onClick={() => {
setComment('');
props.onCancelEdit();
- }}>
+ }}
+ >
{translate('cancel')}
</ResetButtonLink>
</div>
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotHeader.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotHeader.tsx
index d9402440b4c..c35fa0359f9 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotHeader.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotHeader.tsx
@@ -48,7 +48,7 @@ export function HotspotHeader(props: HotspotHeaderProps) {
<div className="display-flex-space-between">
<Status
hotspot={hotspot}
- onStatusChange={statusOption => props.onUpdateHotspot(true, statusOption)}
+ onStatusChange={(statusOption) => props.onUpdateHotspot(true, statusOption)}
/>
<div className="display-flex-end">
<div className="display-inline-flex-center it__hs-assignee">
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotList.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotList.tsx
index a8d298b0d04..47ec65eef17 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotList.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotList.tsx
@@ -58,7 +58,7 @@ export default class HotspotList extends React.Component<Props, State> {
this.state = {
expandedCategories: { [props.selectedHotspot.securityCategory]: true },
- groupedHotspots: this.groupHotspots(props.hotspots, props.securityCategories)
+ groupedHotspots: this.groupHotspots(props.hotspots, props.securityCategories),
};
}
@@ -100,17 +100,17 @@ export default class HotspotList extends React.Component<Props, State> {
}
groupHotspots = (hotspots: RawHotspot[], securityCategories: StandardSecurityCategories) => {
- const risks = groupBy(hotspots, h => h.vulnerabilityProbability);
+ const risks = groupBy(hotspots, (h) => h.vulnerabilityProbability);
- return RISK_EXPOSURE_LEVELS.map(risk => ({
+ return RISK_EXPOSURE_LEVELS.map((risk) => ({
risk,
- categories: groupByCategory(risks[risk], securityCategories)
- })).filter(risk => risk.categories.length > 0);
+ categories: groupByCategory(risks[risk], securityCategories),
+ })).filter((risk) => risk.categories.length > 0);
};
handleToggleCategory = (categoryKey: string, value: boolean) => {
this.setState(({ expandedCategories }) => ({
- expandedCategories: { ...expandedCategories, [categoryKey]: value }
+ expandedCategories: { ...expandedCategories, [categoryKey]: value },
}));
};
@@ -122,7 +122,7 @@ export default class HotspotList extends React.Component<Props, State> {
loadingMore,
selectedHotspot,
selectedHotspotLocation,
- statusFilter
+ statusFilter,
} = this.props;
const { expandedCategories, groupedHotspots } = this.state;
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotListItem.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotListItem.tsx
index 81ed5460eda..df0e499d2e6 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotListItem.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotListItem.tsx
@@ -43,12 +43,14 @@ export default function HotspotListItem(props: HotspotListItemProps) {
<ButtonPlain
aria-current={selected}
className={classNames('hotspot-item', { highlight: selected })}
- onClick={() => !selected && props.onClick(hotspot)}>
+ onClick={() => !selected && props.onClick(hotspot)}
+ >
{/* This is not a real interaction it is only for scrolling */
/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
<div
className={classNames('little-spacer-left text-bold', { 'cursor-pointer': selected })}
- onClick={selected ? () => props.onLocationClick() : undefined}>
+ onClick={selected ? () => props.onLocationClick() : undefined}
+ >
{hotspot.message}
</div>
<div className="display-flex-center big-spacer-top">
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotOpenInIdeButton.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotOpenInIdeButton.tsx
index c7f5bfbe1b5..efae47c0da9 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotOpenInIdeButton.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotOpenInIdeButton.tsx
@@ -43,7 +43,7 @@ export default class HotspotOpenInIdeButton extends React.PureComponent<Props, S
state = {
loading: false,
- ides: []
+ ides: [],
};
componentDidMount() {
@@ -97,7 +97,8 @@ export default class HotspotOpenInIdeButton extends React.PureComponent<Props, S
<DropdownOverlay>
<HotspotOpenInIdeOverlay ides={this.state.ides} onIdeSelected={this.openHotspot} />
</DropdownOverlay>
- }>
+ }
+ >
<Button onClick={this.handleOnClick}>
{translate('hotspots.open_in_ide.open')}
<DeferredSpinner loading={this.state.loading} className="spacer-left" />
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotOpenInIdeOverlay.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotOpenInIdeOverlay.tsx
index de395abe329..d3511a7a8e8 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotOpenInIdeOverlay.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotOpenInIdeOverlay.tsx
@@ -22,14 +22,14 @@ import { Ide } from '../../../types/sonarlint';
export const HotspotOpenInIdeOverlay = ({
ides,
- onIdeSelected
+ onIdeSelected,
}: {
ides: Array<Ide>;
onIdeSelected: (ide: Ide) => Promise<void>;
}) =>
ides.length > 1 ? (
<ul className="menu">
- {ides.map(ide => {
+ {ides.map((ide) => {
const { ideName, description } = ide;
const label = ideName + (description ? ` - ${description}` : '');
return (
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotPrimaryLocationBox.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotPrimaryLocationBox.tsx
index 1720cd7d77e..bc297c01249 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotPrimaryLocationBox.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotPrimaryLocationBox.tsx
@@ -53,12 +53,14 @@ export function HotspotPrimaryLocationBox(props: HotspotPrimaryLocationBoxProps)
'display-flex-space-between display-flex-center padded-top padded-bottom big-padded-left big-padded-right',
`hotspot-risk-exposure-${hotspot.rule.vulnerabilityProbability}`
)}
- ref={locationRef}>
+ ref={locationRef}
+ >
<div className="text-bold">{hotspot.message}</div>
{isLoggedIn(currentUser) && (
<ButtonLink
className="nowrap big-spacer-left it__hs-add-comment"
- onClick={props.onCommentClick}>
+ onClick={props.onCommentClick}
+ >
{translate('hotspots.comment.open')}
</ButtonLink>
)}
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotReviewHistory.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotReviewHistory.tsx
index 4941f12ce08..87a55a8b372 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotReviewHistory.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotReviewHistory.tsx
@@ -59,9 +59,10 @@ export default function HotspotReviewHistory(props: HotspotReviewHistoryProps) {
return (
<li
className={classNames('padded-top padded-bottom', {
- 'bordered-top': historyIndex > 0
+ 'bordered-top': historyIndex > 0,
})}
- key={historyIndex}>
+ key={historyIndex}
+ >
<div className="display-flex-center">
{user.name && (
<>
@@ -120,13 +121,14 @@ export default function HotspotReviewHistory(props: HotspotReviewHistoryProps) {
<HotspotCommentPopup
markdownComment={markdown}
onCancelEdit={() => setEditedCommentKey('')}
- onCommentEditSubmit={comment => {
+ onCommentEditSubmit={(comment) => {
setEditedCommentKey('');
props.onEditComment(key, comment);
}}
/>
</DropdownOverlay>
- }>
+ }
+ >
<EditButton
className="button-small"
onClick={() => setEditedCommentKey(key)}
@@ -140,12 +142,14 @@ export default function HotspotReviewHistory(props: HotspotReviewHistoryProps) {
<p>{translate('issue.comment.delete_confirm_message')}</p>
<Button
className="button-red big-spacer-top pull-right"
- onClick={() => props.onDeleteComment(key)}>
+ onClick={() => props.onDeleteComment(key)}
+ >
{translate('delete')}
</Button>
</div>
}
- overlayPlacement={PopupPlacement.BottomRight}>
+ overlayPlacement={PopupPlacement.BottomRight}
+ >
<DeleteButton className="button-small" />
</Dropdown>
</div>
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotReviewHistoryAndComments.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotReviewHistoryAndComments.tsx
index 32e8ec99959..3f638901089 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotReviewHistoryAndComments.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotReviewHistoryAndComments.tsx
@@ -21,7 +21,7 @@ import * as React from 'react';
import {
commentSecurityHotspot,
deleteSecurityHotspotComment,
- editSecurityHotspotComment
+ editSecurityHotspotComment,
} from '../../../api/security-hotspots';
import FormattingTips from '../../../components/common/FormattingTips';
import { Button } from '../../../components/controls/buttons';
@@ -47,7 +47,7 @@ export default class HotspotReviewHistoryAndComments extends React.PureComponent
super(props);
this.state = {
comment: '',
- showFullHistory: false
+ showFullHistory: false,
};
}
@@ -55,7 +55,7 @@ export default class HotspotReviewHistoryAndComments extends React.PureComponent
if (prevProps.hotspot.key !== this.props.hotspot.key) {
this.setState({
comment: '',
- showFullHistory: false
+ showFullHistory: false,
});
}
}
@@ -109,7 +109,8 @@ export default class HotspotReviewHistoryAndComments extends React.PureComponent
<Button
className="huge-spacer-bottom"
id="hotspot-comment-box-submit"
- onClick={this.handleSubmitComment}>
+ onClick={this.handleSubmitComment}
+ >
{translate('hotspots.comment.submit')}
</Button>
</div>
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSimpleList.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSimpleList.tsx
index 98128701214..ed432da965e 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSimpleList.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSimpleList.tsx
@@ -68,7 +68,7 @@ export default class HotspotSimpleList extends React.Component<HotspotSimpleList
loadingMore,
selectedHotspot,
selectedHotspotLocation,
- standards
+ standards,
} = this.props;
const categoryLabel =
@@ -108,7 +108,7 @@ export default class HotspotSimpleList extends React.Component<HotspotSimpleList
</strong>
</div>
<ul>
- {hotspots.map(h => (
+ {hotspots.map((h) => (
<li data-hotspot-key={h.key} key={h.key}>
<HotspotListItem
hotspot={h}
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetContainer.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetContainer.tsx
index 01f7f6821f5..8699d2c7de3 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetContainer.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetContainer.tsx
@@ -53,7 +53,7 @@ export default class HotspotSnippetContainer extends React.Component<Props, Stat
highlightedSymbols: [],
loading: true,
sourceLines: [],
- secondaryLocations: []
+ secondaryLocations: [],
};
async componentDidMount() {
@@ -87,7 +87,7 @@ export default class HotspotSnippetContainer extends React.Component<Props, Stat
async fetchSources() {
const {
branchLike,
- hotspot: { component, textRange }
+ hotspot: { component, textRange },
} = this.props;
const { secondaryLocations } = this.state;
@@ -102,16 +102,16 @@ export default class HotspotSnippetContainer extends React.Component<Props, Stat
const from = Math.max(
1,
Math.min(
- ...[textRange, ...secondaryLocations.map(l => l.textRange)].map(
- t => t.startLine - BUFFER_LINES
+ ...[textRange, ...secondaryLocations.map((l) => l.textRange)].map(
+ (t) => t.startLine - BUFFER_LINES
)
)
);
// Search for the max endLine within primary and secondary locations
const to = Math.max(
- ...[textRange, ...secondaryLocations.map(l => l.textRange)].map(
+ ...[textRange, ...secondaryLocations.map((l) => l.textRange)].map(
// Add 1 to check for end-of-file
- t => t.endLine + BUFFER_LINES + 1
+ (t) => t.endLine + BUFFER_LINES + 1
)
);
@@ -121,7 +121,7 @@ export default class HotspotSnippetContainer extends React.Component<Props, Stat
key: component.key,
from,
to,
- ...getBranchLikeQuery(branchLike)
+ ...getBranchLikeQuery(branchLike),
}).catch(() => [] as SourceLine[]);
if (this.mounted) {
@@ -136,14 +136,14 @@ export default class HotspotSnippetContainer extends React.Component<Props, Stat
initializeSecondaryLocations() {
const { hotspot } = this.props;
- return new Promise(resolve => {
+ return new Promise((resolve) => {
this.setState(
{
secondaryLocations: getLocations(hotspot.flows, undefined).map((location, index) => ({
...location,
index,
- text: location.msg
- }))
+ text: location.msg,
+ })),
},
() => resolve(undefined)
);
@@ -158,19 +158,19 @@ export default class HotspotSnippetContainer extends React.Component<Props, Stat
direction === 'up'
? {
from: Math.max(1, sourceLines[0].line - EXPAND_BY_LINES),
- to: sourceLines[0].line - 1
+ to: sourceLines[0].line - 1,
}
: {
from: sourceLines[sourceLines.length - 1].line + 1,
// Add 1 to check for end-of-file:
- to: sourceLines[sourceLines.length - 1].line + EXPAND_BY_LINES + 1
+ to: sourceLines[sourceLines.length - 1].line + EXPAND_BY_LINES + 1,
};
return getSources({
key: hotspot.component.key,
...range,
- ...getBranchLikeQuery(branchLike)
- }).then(additionalLines => {
+ ...getBranchLikeQuery(branchLike),
+ }).then((additionalLines) => {
const { lastLine: previousLastLine } = this.state;
const lastLine =
@@ -188,7 +188,7 @@ export default class HotspotSnippetContainer extends React.Component<Props, Stat
this.setState({
lastLine,
- sourceLines: concatSourceLines
+ sourceLines: concatSourceLines,
});
});
};
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetContainerRenderer.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetContainerRenderer.tsx
index 3c8f12e0557..1d5b6485ce1 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetContainerRenderer.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetContainerRenderer.tsx
@@ -29,7 +29,7 @@ import {
FlowLocation,
LinearIssueLocation,
SourceLine,
- SourceViewerFile
+ SourceViewerFile,
} from '../../../types/types';
import SnippetViewer from '../../issues/crossComponentSourceViewer/SnippetViewer';
import HotspotPrimaryLocationBox from './HotspotPrimaryLocationBox';
@@ -70,7 +70,7 @@ export function getScrollHandler(scrollableRef: React.RefObject<HTMLDivElement>)
parent,
topOffset: offset ?? TOP_OFFSET,
bottomOffset: offset ?? BOTTOM_OFFSET,
- smooth
+ smooth,
});
}
}, SCROLL_DELAY);
@@ -141,7 +141,7 @@ export default function HotspotSnippetContainerRenderer(
sourceViewerFile,
secondaryLocations,
component,
- selectedHotspotLocation
+ selectedHotspotLocation,
} = props;
const scrollableRef = React.useRef<HTMLDivElement>(null);
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetHeader.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetHeader.tsx
index 1ed19a6a947..ab4a739a34f 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetHeader.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetHeader.tsx
@@ -47,7 +47,7 @@ export function HotspotSnippetHeader(props: HotspotSnippetHeaderProps) {
const { hotspot, currentUser, component, branchLike } = props;
const {
project,
- component: { qualifier, path }
+ component: { qualifier, path },
} = hotspot;
const displayProjectName = component.qualifier === ComponentQualifier.Application;
@@ -55,7 +55,7 @@ export function HotspotSnippetHeader(props: HotspotSnippetHeaderProps) {
const permalink = getPathUrlAsString(
getComponentSecurityHotspotsUrl(component.key, {
...getBranchLikeQuery(branchLike),
- hotspots: hotspot?.key
+ hotspots: hotspot?.key,
}),
false
);
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewer.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewer.tsx
index 85763e86b7b..b2bcf81952c 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewer.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewer.tsx
@@ -24,7 +24,7 @@ import { scrollToElement } from '../../../helpers/scrolling';
import {
Hotspot,
HotspotStatusFilter,
- HotspotStatusOption
+ HotspotStatusOption,
} from '../../../types/security-hotspots';
import { Component } from '../../../types/types';
import { RuleDescriptionSection } from '../../coding-rules/rule';
@@ -81,13 +81,13 @@ export default class HotspotViewer extends React.PureComponent<Props, State> {
this.setState({ loading: true });
try {
const hotspot = await getSecurityHotspotDetails(this.props.hotspotKey);
- const ruleDetails = await getRuleDetails({ key: hotspot.rule.key }).then(r => r.rule);
+ const ruleDetails = await getRuleDetails({ key: hotspot.rule.key }).then((r) => r.rule);
if (this.mounted) {
this.setState({
hotspot,
loading: false,
- ruleDescriptionSections: ruleDetails.descriptionSections
+ ruleDescriptionSections: ruleDetails.descriptionSections,
});
}
} catch (error) {
@@ -112,7 +112,7 @@ export default class HotspotViewer extends React.PureComponent<Props, State> {
if (this.commentTextRef.current) {
this.commentTextRef.current.focus({ preventScroll: true });
scrollToElement(this.commentTextRef.current, {
- bottomOffset: SCROLL_TO_COMMENT_BOTTOM_OFFSET
+ bottomOffset: SCROLL_TO_COMMENT_BOTTOM_OFFSET,
});
}
};
@@ -135,7 +135,7 @@ export default class HotspotViewer extends React.PureComponent<Props, State> {
ruleDescriptionSections,
lastStatusChangedTo,
loading,
- showStatusUpdateSuccessModal
+ showStatusUpdateSuccessModal,
} = this.state;
return (
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewerRenderer.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewerRenderer.tsx
index f4c1d8d06b3..0e46d5d5ded 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewerRenderer.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewerRenderer.tsx
@@ -61,7 +61,7 @@ export function HotspotViewerRenderer(props: HotspotViewerRendererProps) {
showStatusUpdateSuccessModal,
commentTextRef,
selectedHotspotLocation,
- ruleDescriptionSections
+ ruleDescriptionSections,
} = props;
return (
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewerTabs.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewerTabs.tsx
index 5b0bd74fb42..fa63cc0a484 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewerTabs.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewerTabs.tsx
@@ -49,7 +49,7 @@ export enum TabKeys {
Code = 'code',
RiskDescription = 'risk',
VulnerabilityDescription = 'vulnerability',
- FixRecommendation = 'fix'
+ FixRecommendation = 'fix',
}
export default class HotspotViewerTabs extends React.PureComponent<Props, State> {
@@ -58,7 +58,7 @@ export default class HotspotViewerTabs extends React.PureComponent<Props, State>
const tabs = this.computeTabs();
this.state = {
currentTab: tabs[0],
- tabs
+ tabs,
};
}
@@ -74,7 +74,7 @@ export default class HotspotViewerTabs extends React.PureComponent<Props, State>
const tabs = this.computeTabs();
this.setState({
currentTab: tabs[0],
- tabs
+ tabs,
});
} else if (
this.props.selectedHotspotLocation !== undefined &&
@@ -82,7 +82,7 @@ export default class HotspotViewerTabs extends React.PureComponent<Props, State>
) {
const { tabs } = this.state;
this.setState({
- currentTab: tabs[0]
+ currentTab: tabs[0],
});
}
}
@@ -114,13 +114,13 @@ export default class HotspotViewerTabs extends React.PureComponent<Props, State>
handleSelectTabs = (tabKey: TabKeys) => {
const { tabs } = this.state;
- const currentTab = tabs.find(tab => tab.key === tabKey)!;
+ const currentTab = tabs.find((tab) => tab.key === tabKey)!;
this.setState({ currentTab });
};
computeTabs() {
const { ruleDescriptionSections, codeTabContent } = this.props;
- const descriptionSectionsByKey = groupBy(ruleDescriptionSections, section => section.key);
+ const descriptionSectionsByKey = groupBy(ruleDescriptionSections, (section) => section.key);
const rootCauseDescriptionSections =
descriptionSectionsByKey[RuleDescriptionSections.DEFAULT] ||
descriptionSectionsByKey[RuleDescriptionSections.ROOT_CAUSE];
@@ -129,7 +129,7 @@ export default class HotspotViewerTabs extends React.PureComponent<Props, State>
{
key: TabKeys.Code,
label: translate('hotspots.tabs.code'),
- content: <div className="padded">{codeTabContent}</div>
+ content: <div className="padded">{codeTabContent}</div>,
},
{
key: TabKeys.RiskDescription,
@@ -140,7 +140,7 @@ export default class HotspotViewerTabs extends React.PureComponent<Props, State>
sections={rootCauseDescriptionSections}
isDefault={true}
/>
- )
+ ),
},
{
key: TabKeys.VulnerabilityDescription,
@@ -151,7 +151,7 @@ export default class HotspotViewerTabs extends React.PureComponent<Props, State>
sections={descriptionSectionsByKey[RuleDescriptionSections.ASSESS_THE_PROBLEM]}
isDefault={true}
/>
- )
+ ),
},
{
key: TabKeys.FixRecommendation,
@@ -162,19 +162,19 @@ export default class HotspotViewerTabs extends React.PureComponent<Props, State>
sections={descriptionSectionsByKey[RuleDescriptionSections.HOW_TO_FIX]}
isDefault={true}
/>
- )
- }
- ].filter(tab => tab.content);
+ ),
+ },
+ ].filter((tab) => tab.content);
}
selectNeighboringTab(shift: number) {
this.setState(({ tabs, currentTab }) => {
- const index = currentTab && tabs.findIndex(tab => tab.key === currentTab.key);
+ const index = currentTab && tabs.findIndex((tab) => tab.key === currentTab.key);
if (index !== undefined && index > -1) {
const newIndex = Math.max(0, Math.min(tabs.length - 1, index + shift));
return {
- currentTab: tabs[newIndex]
+ currentTab: tabs[newIndex],
};
}
@@ -191,7 +191,8 @@ export default class HotspotViewerTabs extends React.PureComponent<Props, State>
className="bordered huge-spacer-bottom"
role="tabpanel"
aria-labelledby={getTabId(currentTab.key)}
- id={getTabPanelId(currentTab.key)}>
+ id={getTabPanelId(currentTab.key)}
+ >
{currentTab.content}
</div>
</>
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/StatusUpdateSuccessModal.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/StatusUpdateSuccessModal.tsx
index 3cfd92e294d..6c8e3c9d932 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/StatusUpdateSuccessModal.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/StatusUpdateSuccessModal.tsx
@@ -56,7 +56,7 @@ export default function StatusUpdateSuccessModal(props: StatusUpdateSuccessModal
id="hotspots.successfully_changed_to_x"
defaultMessage={translate('hotspots.find_in_status_filter_x')}
values={{
- status_label: <strong>{statusLabel}</strong>
+ status_label: <strong>{statusLabel}</strong>,
}}
/>
{closingHotspots && (
@@ -68,10 +68,10 @@ export default function StatusUpdateSuccessModal(props: StatusUpdateSuccessModal
percentage: (
<strong>
{formatMeasure(hotspotsReviewedMeasure, 'PERCENT', {
- omitExtraDecimalZeros: true
+ omitExtraDecimalZeros: true,
})}
</strong>
- )
+ ),
}}
/>
</p>
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/FilterBar-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/FilterBar-test.tsx
index acaa4c993f6..4e1e145ad22 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/FilterBar-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/FilterBar-test.tsx
@@ -37,7 +37,7 @@ it('should render correctly', () => {
expect(
shallowRender({
currentUser: mockLoggedInUser(),
- component: mockComponent({ qualifier: ComponentQualifier.Application })
+ component: mockComponent({ qualifier: ComponentQualifier.Application }),
})
).toMatchSnapshot('non-project');
});
@@ -47,7 +47,7 @@ it('should render correctly when the list of hotspot is static', () => {
const wrapper = shallowRender({
isStaticListOfHotspots: true,
- onShowAllHotspots
+ onShowAllHotspots,
});
expect(wrapper).toMatchSnapshot();
@@ -59,10 +59,7 @@ it('should trigger onChange for status', () => {
const onChangeFilters = jest.fn();
const wrapper = shallowRender({ onChangeFilters });
- const { onChange } = wrapper
- .find(Select)
- .at(0)
- .props();
+ const { onChange } = wrapper.find(Select).at(0).props();
onChange({ value: HotspotStatusFilter.SAFE });
expect(onChangeFilters).toHaveBeenCalledWith({ status: HotspotStatusFilter.SAFE });
@@ -82,10 +79,7 @@ it('should trigger onChange for leak period', () => {
const onChangeFilters = jest.fn();
const wrapper = shallowRender({ onChangeFilters });
- const { onChange } = wrapper
- .find(Select)
- .at(1)
- .props();
+ const { onChange } = wrapper.find(Select).at(1).props();
onChange({ value: true });
expect(onChangeFilters).toHaveBeenCalledWith({ inNewCodePeriod: true });
@@ -99,7 +93,7 @@ function shallowRender(props: Partial<FilterBarProps> = {}) {
filters={{
assignedToMe: false,
inNewCodePeriod: false,
- status: HotspotStatusFilter.TO_REVIEW
+ status: HotspotStatusFilter.TO_REVIEW,
}}
isStaticListOfHotspots={false}
loadingMeasure={false}
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotCategory-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotCategory-test.tsx
index d06f2f67b8b..050f84dfee0 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotCategory-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotCategory-test.tsx
@@ -30,7 +30,7 @@ it('should render correctly with hotspots', () => {
const securityCategory = 'command-injection';
const hotspots = [
mockRawHotspot({ key: 'h1', securityCategory }),
- mockRawHotspot({ key: 'h2', securityCategory })
+ mockRawHotspot({ key: 'h2', securityCategory }),
];
expect(shallowRender({ hotspots })).toMatchSnapshot();
expect(shallowRender({ hotspots, expanded: false })).toMatchSnapshot('collapsed');
@@ -51,7 +51,7 @@ it('should handle collapse and expand', () => {
categoryKey,
expanded: true,
hotspots: [mockRawHotspot()],
- onToggleExpand
+ onToggleExpand,
});
wrapper.find('.hotspot-category-header').simulate('click');
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotCommentPopup-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotCommentPopup-test.tsx
index e04b4033888..666201b6bfc 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotCommentPopup-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotCommentPopup-test.tsx
@@ -29,7 +29,7 @@ it('should render correclty', () => {
it('should trigger update comment', () => {
const props = {
- onCommentEditSubmit: jest.fn()
+ onCommentEditSubmit: jest.fn(),
};
const wrapper = shallowRender(props);
wrapper.find('textarea').simulate('change', { target: { value: 'foo' } });
@@ -40,7 +40,7 @@ it('should trigger update comment', () => {
it('should trigger cancel update comment', () => {
const props = {
- onCancelEdit: jest.fn()
+ onCancelEdit: jest.fn(),
};
const wrapper = shallowRender(props);
wrapper.find(ResetButtonLink).simulate('click');
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotHeader-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotHeader-test.tsx
index b285f794897..42e19038993 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotHeader-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotHeader-test.tsx
@@ -33,10 +33,7 @@ it('correctly propagates the status change', () => {
const onUpdateHotspot = jest.fn();
const wrapper = shallowRender({ onUpdateHotspot });
- wrapper
- .find(Status)
- .props()
- .onStatusChange(HotspotStatusOption.FIXED);
+ wrapper.find(Status).props().onStatusChange(HotspotStatusOption.FIXED);
expect(onUpdateHotspot).toHaveBeenCalledWith(true, HotspotStatusOption.FIXED);
});
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotList-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotList-test.tsx
index 2876fa8dfa9..3094c3ea8b0 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotList-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotList-test.tsx
@@ -27,7 +27,7 @@ import HotspotList from '../HotspotList';
jest.mock('../../../../helpers/pages', () => ({
addSideBarClass: jest.fn(),
- removeSideBarClass: jest.fn()
+ removeSideBarClass: jest.fn(),
}));
it('should render correctly', () => {
@@ -57,18 +57,18 @@ const hotspots = [
mockRawHotspot({
key: 'h3',
securityCategory: 'cat1',
- vulnerabilityProbability: RiskExposure.MEDIUM
+ vulnerabilityProbability: RiskExposure.MEDIUM,
}),
mockRawHotspot({
key: 'h4',
securityCategory: 'cat1',
- vulnerabilityProbability: RiskExposure.MEDIUM
+ vulnerabilityProbability: RiskExposure.MEDIUM,
}),
mockRawHotspot({
key: 'h5',
securityCategory: 'cat2',
- vulnerabilityProbability: RiskExposure.MEDIUM
- })
+ vulnerabilityProbability: RiskExposure.MEDIUM,
+ }),
];
it('should render correctly with hotspots', () => {
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotOpenInIdeButton-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotOpenInIdeButton-test.tsx
index ef7dce2d793..6cabfb01a28 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotOpenInIdeButton-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotOpenInIdeButton-test.tsx
@@ -39,7 +39,7 @@ describe('HotspotOpenInIdeButton', () => {
expect(wrapper).toMatchSnapshot();
(sonarlint.probeSonarLintServers as jest.Mock).mockResolvedValue([
- { port, ideName: 'BlueJ IDE', description: 'Hello World' }
+ { port, ideName: 'BlueJ IDE', description: 'Hello World' },
]);
(sonarlint.openHotspot as jest.Mock).mockResolvedValue(null);
@@ -71,7 +71,7 @@ describe('HotspotOpenInIdeButton', () => {
(sonarlint.probeSonarLintServers as jest.Mock).mockResolvedValue([
{ port: port1, ideName: 'BlueJ IDE', description: 'Hello World' },
- { port: port2, ideName: 'Arduino IDE', description: 'Blink' }
+ { port: port2, ideName: 'Arduino IDE', description: 'Blink' },
]);
wrapper.find(Button).simulate('click');
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotOpenInIdeOverlay-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotOpenInIdeOverlay-test.tsx
index a81b6cee33e..da90459e72f 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotOpenInIdeOverlay-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotOpenInIdeOverlay-test.tsx
@@ -45,9 +45,6 @@ it('should render menu and select the right IDE', () => {
);
expect(wrapper).toMatchSnapshot();
- wrapper
- .find('a')
- .last()
- .simulate('click');
+ wrapper.find('a').last().simulate('click');
expect(onIdeSelected).toHaveBeenCalledWith(ide2);
});
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotPrimaryLocationBox-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotPrimaryLocationBox-test.tsx
index 8c05746529b..10099bd653a 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotPrimaryLocationBox-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotPrimaryLocationBox-test.tsx
@@ -25,14 +25,14 @@ import { mockCurrentUser, mockLoggedInUser } from '../../../../helpers/testMocks
import { RiskExposure } from '../../../../types/security-hotspots';
import {
HotspotPrimaryLocationBox,
- HotspotPrimaryLocationBoxProps
+ HotspotPrimaryLocationBoxProps,
} from '../HotspotPrimaryLocationBox';
jest.mock('react', () => {
return {
...jest.requireActual('react'),
useRef: jest.fn(),
- useEffect: jest.fn()
+ useEffect: jest.fn(),
};
});
@@ -43,9 +43,9 @@ it('should render correctly', () => {
it.each([[RiskExposure.HIGH], [RiskExposure.MEDIUM], [RiskExposure.LOW]])(
'should indicate risk exposure: %s',
- vulnerabilityProbability => {
+ (vulnerabilityProbability) => {
const wrapper = shallowRender({
- hotspot: mockHotspot({ rule: mockHotspotRule({ vulnerabilityProbability }) })
+ hotspot: mockHotspot({ rule: mockHotspotRule({ vulnerabilityProbability }) }),
});
expect(wrapper.hasClass(`hotspot-risk-exposure-${vulnerabilityProbability}`)).toBe(true);
@@ -64,7 +64,7 @@ it('should handle click', () => {
it('should scroll on load if no secondary locations selected', () => {
const node = document.createElement('div');
(React.useRef as jest.Mock).mockImplementationOnce(() => ({ current: node }));
- (React.useEffect as jest.Mock).mockImplementationOnce(f => f());
+ (React.useEffect as jest.Mock).mockImplementationOnce((f) => f());
const scroll = jest.fn();
shallowRender({ scroll });
@@ -75,7 +75,7 @@ it('should scroll on load if no secondary locations selected', () => {
it('should not scroll on load if a secondary location is selected', () => {
const node = document.createElement('div');
(React.useRef as jest.Mock).mockImplementationOnce(() => ({ current: node }));
- (React.useEffect as jest.Mock).mockImplementationOnce(f => f());
+ (React.useEffect as jest.Mock).mockImplementationOnce((f) => f());
const scroll = jest.fn();
shallowRender({ scroll, secondaryLocationSelected: true });
@@ -85,7 +85,7 @@ it('should not scroll on load if a secondary location is selected', () => {
it('should not scroll on load if node is not defined', () => {
(React.useRef as jest.Mock).mockImplementationOnce(() => ({ current: undefined }));
- (React.useEffect as jest.Mock).mockImplementationOnce(f => f());
+ (React.useEffect as jest.Mock).mockImplementationOnce((f) => f());
const scroll = jest.fn();
shallowRender({ scroll });
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotReviewHistory-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotReviewHistory-test.tsx
index 86b9fefe76d..b2b46b00547 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotReviewHistory-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotReviewHistory-test.tsx
@@ -31,23 +31,19 @@ import HotspotReviewHistory, { HotspotReviewHistoryProps } from '../HotspotRevie
jest.mock('react', () => {
return {
...jest.requireActual('react'),
- useState: jest.fn().mockImplementation(() => ['', jest.fn()])
+ useState: jest.fn().mockImplementation(() => ['', jest.fn()]),
};
});
it('should render correctly', () => {
expect(shallowRender()).toMatchSnapshot('default');
expect(shallowRender({ showFullHistory: true })).toMatchSnapshot('show full list');
- expect(
- shallowRender({ showFullHistory: true })
- .find(Toggler)
- .props().overlay
- ).toMatchSnapshot('edit comment overlay');
- expect(
- shallowRender({ showFullHistory: true })
- .find(Dropdown)
- .props().overlay
- ).toMatchSnapshot('delete comment overlay');
+ expect(shallowRender({ showFullHistory: true }).find(Toggler).props().overlay).toMatchSnapshot(
+ 'edit comment overlay'
+ );
+ expect(shallowRender({ showFullHistory: true }).find(Dropdown).props().overlay).toMatchSnapshot(
+ 'delete comment overlay'
+ );
});
it('should correctly handle comment updating', () => {
@@ -59,17 +55,10 @@ it('should correctly handle comment updating', () => {
const wrapper = shallowRender({ onEditComment, showFullHistory: true });
// Closing the Toggler sets the edited key back to an empty string.
- wrapper
- .find(Toggler)
- .at(0)
- .props()
- .onRequestClose();
+ wrapper.find(Toggler).at(0).props().onRequestClose();
expect(setEditedCommentKey).toHaveBeenCalledWith('');
- const editOnClick = wrapper
- .find(EditButton)
- .at(0)
- .props().onClick;
+ const editOnClick = wrapper.find(EditButton).at(0).props().onClick;
if (!editOnClick) {
reject();
return;
@@ -81,23 +70,14 @@ it('should correctly handle comment updating', () => {
// Cancelling an edit sets the edited key back to an empty string
const dropdownOverlay = shallow(
- wrapper
- .find(Toggler)
- .at(0)
- .props().overlay as React.ReactElement<DropdownOverlay>
+ wrapper.find(Toggler).at(0).props().overlay as React.ReactElement<DropdownOverlay>
);
- dropdownOverlay
- .find(HotspotCommentPopup)
- .props()
- .onCancelEdit();
+ dropdownOverlay.find(HotspotCommentPopup).props().onCancelEdit();
expect(setEditedCommentKey).toHaveBeenLastCalledWith('');
// Updating the comment sets the edited key back to an empty string, and calls the
// prop to update the comment value.
- dropdownOverlay
- .find(HotspotCommentPopup)
- .props()
- .onCommentEditSubmit('comment');
+ dropdownOverlay.find(HotspotCommentPopup).props().onCommentEditSubmit('comment');
expect(onEditComment).toHaveBeenLastCalledWith('comment-1', 'comment');
expect(setEditedCommentKey).toHaveBeenLastCalledWith('');
expect(setEditedCommentKey).toHaveBeenCalledTimes(4);
@@ -115,10 +95,7 @@ it('should correctly handle comment deleting', () => {
const wrapper = shallowRender({ onDeleteComment, showFullHistory: true });
// Opening the deletion Dropdown sets the edited key back to an empty string.
- const dropdownOnOpen = wrapper
- .find(Dropdown)
- .at(0)
- .props().onOpen;
+ const dropdownOnOpen = wrapper.find(Dropdown).at(0).props().onOpen;
if (!dropdownOnOpen) {
reject();
return;
@@ -128,10 +105,7 @@ it('should correctly handle comment deleting', () => {
// Confirming deletion calls the prop to delete the comment.
const dropdownOverlay = shallow(
- wrapper
- .find(Dropdown)
- .at(0)
- .props().overlay as React.ReactElement<HTMLDivElement>
+ wrapper.find(Dropdown).at(0).props().overlay as React.ReactElement<HTMLDivElement>
);
const deleteButtonOnClick = dropdownOverlay.find(Button).props().onClick;
if (!deleteButtonOnClick) {
@@ -154,19 +128,19 @@ function shallowRender(props?: Partial<HotspotReviewHistoryProps>) {
changelog: [
mockIssueChangelog(),
mockIssueChangelog({
- creationDate: '2018-10-12'
- })
+ creationDate: '2018-10-12',
+ }),
],
comment: [
mockHotspotComment({
key: 'comment-1',
- updatable: true
+ updatable: true,
}),
mockHotspotComment({ key: 'comment-2', user: mockUser({ name: undefined }) }),
mockHotspotComment({ key: 'comment-3', user: mockUser({ active: false }) }),
mockHotspotComment({ key: 'comment-4' }),
- mockHotspotComment({ key: 'comment-5' })
- ]
+ mockHotspotComment({ key: 'comment-5' }),
+ ],
})}
onDeleteComment={jest.fn()}
onEditComment={jest.fn()}
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotReviewHistoryAndComments-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotReviewHistoryAndComments-test.tsx
index 64ed9acdec8..efc48cb25ac 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotReviewHistoryAndComments-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotReviewHistoryAndComments-test.tsx
@@ -22,7 +22,7 @@ import * as React from 'react';
import {
commentSecurityHotspot,
deleteSecurityHotspotComment,
- editSecurityHotspotComment
+ editSecurityHotspotComment,
} from '../../../../api/security-hotspots';
import { mockHotspot } from '../../../../helpers/mocks/security-hotspots';
import { mockCurrentUser } from '../../../../helpers/testMocks';
@@ -34,7 +34,7 @@ import HotspotReviewHistoryAndComments from '../HotspotReviewHistoryAndComments'
jest.mock('../../../../api/security-hotspots', () => ({
commentSecurityHotspot: jest.fn().mockResolvedValue({}),
deleteSecurityHotspotComment: jest.fn().mockResolvedValue({}),
- editSecurityHotspotComment: jest.fn().mockResolvedValue({})
+ editSecurityHotspotComment: jest.fn().mockResolvedValue({}),
}));
jest.mock('../../../../types/users', () => ({ isLoggedIn: jest.fn(() => true) }));
@@ -45,7 +45,7 @@ it('should render correctly', () => {
});
it('should render correctly without user', () => {
- ((isLoggedIn as any) as jest.Mock<boolean, [boolean]>).mockReturnValueOnce(false);
+ (isLoggedIn as any as jest.Mock<boolean, [boolean]>).mockReturnValueOnce(false);
const wrapper = shallowRender();
expect(wrapper).toMatchSnapshot();
});
@@ -104,10 +104,7 @@ it('should edit comment', async () => {
it('should correctly toggle the show full history state', () => {
const wrapper = shallowRender();
expect(wrapper.state().showFullHistory).toBe(false);
- wrapper
- .find(HotspotReviewHistory)
- .props()
- .onShowFullHistory();
+ wrapper.find(HotspotReviewHistory).props().onShowFullHistory();
expect(wrapper.state().showFullHistory).toBe(true);
});
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSimpleList-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSimpleList-test.tsx
index 29a57bf93fb..9f652d0fed3 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSimpleList-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSimpleList-test.tsx
@@ -27,7 +27,7 @@ import HotspotSimpleList, { HotspotSimpleListProps } from '../HotspotSimpleList'
jest.mock('../../../../helpers/pages', () => ({
addSideBarClass: jest.fn(),
- removeSideBarClass: jest.fn()
+ removeSideBarClass: jest.fn(),
}));
it('should render correctly', () => {
@@ -70,17 +70,17 @@ function shallowRender(props: Partial<HotspotSimpleListProps> = {}) {
cwe: { 327: { title: 'Use of a Broken or Risky Cryptographic Algorithm' } },
owaspTop10: {
a1: { title: 'A1 - SQL Injection' },
- a3: { title: 'A3 - Sensitive Data Exposure' }
+ a3: { title: 'A3 - Sensitive Data Exposure' },
},
'owaspTop10-2021': {
a1: { title: 'A1 - SQL Injection' },
- a3: { title: 'A3 - Sensitive Data Exposure' }
+ a3: { title: 'A3 - Sensitive Data Exposure' },
},
sansTop25: {},
sonarsourceSecurity: {},
'pciDss-3.2': {},
'pciDss-4.0': {},
- 'owaspAsvs-4.0': {}
+ 'owaspAsvs-4.0': {},
}}
{...props}
/>
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSnippetContainer-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSnippetContainer-test.tsx
index a0207becc7d..331accc1d89 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSnippetContainer-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSnippetContainer-test.tsx
@@ -32,11 +32,11 @@ import HotspotSnippetContainer from '../HotspotSnippetContainer';
import HotspotSnippetContainerRenderer from '../HotspotSnippetContainerRenderer';
jest.mock('../../../../api/components', () => ({
- getSources: jest.fn().mockResolvedValue([])
+ getSources: jest.fn().mockResolvedValue([]),
}));
jest.mock('../../../../helpers/scrolling', () => ({
- scrollToElement: jest.fn()
+ scrollToElement: jest.fn(),
}));
beforeEach(() => jest.clearAllMocks());
@@ -49,7 +49,7 @@ it('should render correctly', () => {
it('should load sources on mount', async () => {
(getSources as jest.Mock).mockResolvedValueOnce(
- range(1, 25).map(line => mockSourceLine({ line }))
+ range(1, 25).map((line) => mockSourceLine({ line }))
);
const hotspot = mockHotspot({
@@ -59,14 +59,14 @@ it('should load sources on mount', async () => {
{
locations: [
mockFlowLocation({
- textRange: { startLine: 8, endLine: 8, startOffset: 0, endOffset: 1 }
+ textRange: { startLine: 8, endLine: 8, startOffset: 0, endOffset: 1 },
}),
mockFlowLocation({
- textRange: { startLine: 13, endLine: 13, startOffset: 0, endOffset: 1 }
- })
- ]
- }
- ]
+ textRange: { startLine: 13, endLine: 13, startOffset: 0, endOffset: 1 },
+ }),
+ ],
+ },
+ ],
});
const wrapper = shallowRender({ hotspot });
@@ -78,7 +78,7 @@ it('should load sources on mount', async () => {
key: hotspot.component.key,
branch: branch.name,
from: 1,
- to: 24
+ to: 24,
})
);
expect(wrapper.state().lastLine).toBeUndefined();
@@ -101,7 +101,7 @@ it('should handle load sources failure', async () => {
it('should not load sources on mount when the hotspot is not associated to any loc', async () => {
const hotspot = mockHotspot({
line: undefined,
- textRange: undefined
+ textRange: undefined,
});
const wrapper = shallowRender({ hotspot });
@@ -115,11 +115,11 @@ it('should not load sources on mount when the hotspot is not associated to any l
it('should handle end-of-file on mount', async () => {
(getSources as jest.Mock).mockResolvedValueOnce(
- range(5, 15).map(line => mockSourceLine({ line }))
+ range(5, 15).map((line) => mockSourceLine({ line }))
);
const hotspot = mockHotspot({
- textRange: { startLine: 10, endLine: 11, startOffset: 0, endOffset: 12 }
+ textRange: { startLine: 10, endLine: 11, startOffset: 0, endOffset: 12 },
});
const wrapper = shallowRender({ hotspot });
@@ -134,33 +134,30 @@ it('should handle end-of-file on mount', async () => {
describe('Expansion', () => {
beforeEach(() => {
(getSources as jest.Mock).mockResolvedValueOnce(
- range(10, 32).map(line => mockSourceLine({ line }))
+ range(10, 32).map((line) => mockSourceLine({ line }))
);
});
const hotspot = mockHotspot({
project: mockHotspotComponent({ branch: branch.name, qualifier: ComponentQualifier.Project }),
- textRange: { startLine: 20, endLine: 21, startOffset: 0, endOffset: 12 }
+ textRange: { startLine: 20, endLine: 21, startOffset: 0, endOffset: 12 },
});
it('up should work', async () => {
(getSources as jest.Mock).mockResolvedValueOnce(
- range(1, 10).map(line => mockSourceLine({ line }))
+ range(1, 10).map((line) => mockSourceLine({ line }))
);
const wrapper = shallowRender({ hotspot });
await waitAndUpdate(wrapper);
- wrapper
- .find(HotspotSnippetContainerRenderer)
- .props()
- .onExpandBlock('up');
+ wrapper.find(HotspotSnippetContainerRenderer).props().onExpandBlock('up');
await waitAndUpdate(wrapper);
expect(getSources).toHaveBeenCalledWith(
expect.objectContaining({
- branch: branch.name
+ branch: branch.name,
})
);
expect(wrapper.state().sourceLines).toHaveLength(31);
@@ -170,16 +167,13 @@ describe('Expansion', () => {
(getSources as jest.Mock).mockResolvedValueOnce(
// lastLine + expand + extra for EOF check + range end is excluded
// 31 + 50 + 1 + 1
- range(32, 83).map(line => mockSourceLine({ line }))
+ range(32, 83).map((line) => mockSourceLine({ line }))
);
const wrapper = shallowRender({ hotspot });
await waitAndUpdate(wrapper);
- wrapper
- .find(HotspotSnippetContainerRenderer)
- .props()
- .onExpandBlock('down');
+ wrapper.find(HotspotSnippetContainerRenderer).props().onExpandBlock('down');
await waitAndUpdate(wrapper);
@@ -191,16 +185,13 @@ describe('Expansion', () => {
(getSources as jest.Mock).mockResolvedValueOnce(
// lastLine + expand + extra for EOF check + range end is excluded - 1 to trigger end-of-file
// 26 + 50 + 1 + 1 - 1
- range(27, 77).map(line => mockSourceLine({ line }))
+ range(27, 77).map((line) => mockSourceLine({ line }))
);
const wrapper = shallowRender({ hotspot });
await waitAndUpdate(wrapper);
- wrapper
- .find(HotspotSnippetContainerRenderer)
- .props()
- .onExpandBlock('down');
+ wrapper.find(HotspotSnippetContainerRenderer).props().onExpandBlock('down');
await waitAndUpdate(wrapper);
@@ -212,10 +203,7 @@ describe('Expansion', () => {
it('should handle symbol click', () => {
const wrapper = shallowRender();
const symbols = ['symbol'];
- wrapper
- .find(HotspotSnippetContainerRenderer)
- .props()
- .onSymbolClick(symbols);
+ wrapper.find(HotspotSnippetContainerRenderer).props().onSymbolClick(symbols);
expect(wrapper.state().highlightedSymbols).toBe(symbols);
});
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSnippetContainerRenderer-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSnippetContainerRenderer-test.tsx
index c062d19dda4..3764137be73 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSnippetContainerRenderer-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSnippetContainerRenderer-test.tsx
@@ -28,15 +28,15 @@ import SnippetViewer from '../../../issues/crossComponentSourceViewer/SnippetVie
import HotspotSnippetContainerRenderer, {
animateExpansion,
getScrollHandler,
- HotspotSnippetContainerRendererProps
+ HotspotSnippetContainerRendererProps,
} from '../HotspotSnippetContainerRenderer';
jest.mock('../../../../helpers/scrolling', () => ({
- scrollToElement: jest.fn()
+ scrollToElement: jest.fn(),
}));
beforeEach(() => {
- jest.spyOn(React, 'useMemo').mockImplementationOnce(f => f());
+ jest.spyOn(React, 'useMemo').mockImplementationOnce((f) => f());
});
it('should render correctly', () => {
@@ -47,7 +47,7 @@ it('should render correctly', () => {
it('should render a HotspotPrimaryLocationBox', () => {
const wrapper = shallowRender({
hotspot: mockHotspot({ line: 42 }),
- sourceLines: [mockSourceLine()]
+ sourceLines: [mockSourceLine()],
});
const { renderAdditionalChildInLine } = wrapper.find(SnippetViewer).props();
@@ -58,7 +58,7 @@ it('should render a HotspotPrimaryLocationBox', () => {
it('should render correctly when secondary location is selected', () => {
const wrapper = shallowRender({
- selectedHotspotLocation: 1
+ selectedHotspotLocation: 1,
});
expect(wrapper).toMatchSnapshot('with selected hotspot location');
});
@@ -78,7 +78,7 @@ describe('scrolling', () => {
it('should scroll to element if parent is defined', () => {
const ref: RefObject<HTMLDivElement> = {
- current: document.createElement('div')
+ current: document.createElement('div'),
};
const scrollHandler = getScrollHandler(ref);
@@ -93,7 +93,7 @@ describe('scrolling', () => {
it('should not scroll if parent is undefined', () => {
const ref: RefObject<HTMLDivElement> = {
- current: null
+ current: null,
};
const scrollHandler = getScrollHandler(ref);
@@ -115,7 +115,7 @@ describe('expand', () => {
const scrollableNode = document.createElement('div');
scrollableNode.scrollTo = jest.fn();
const ref: RefObject<HTMLDivElement> = {
- current: scrollableNode
+ current: scrollableNode,
};
jest.spyOn(React, 'useRef').mockReturnValue(ref);
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSnippetHeader-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSnippetHeader-test.tsx
index 1a99931e45b..41ec8c1a201 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSnippetHeader-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSnippetHeader-test.tsx
@@ -32,7 +32,7 @@ it('should render correctly', () => {
expect(
shallowRender({
currentUser: mockLoggedInUser(),
- component: mockComponent({ qualifier: ComponentQualifier.Application })
+ component: mockComponent({ qualifier: ComponentQualifier.Application }),
})
).toMatchSnapshot('user logged in with project Name');
});
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotViewer-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotViewer-test.tsx
index 47b69bf671c..03538f3bba0 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotViewer-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotViewer-test.tsx
@@ -36,15 +36,15 @@ const hotspotKey = 'hotspot-key';
jest.mock('../../../../api/security-hotspots', () => ({
getSecurityHotspotDetails: jest
.fn()
- .mockResolvedValue({ id: `I am a detailled hotspot`, rule: {} })
+ .mockResolvedValue({ id: `I am a detailled hotspot`, rule: {} }),
}));
jest.mock('../../../../api/rules', () => ({
- getRuleDetails: jest.fn().mockResolvedValue({ rule: { descriptionSections: [] } })
+ getRuleDetails: jest.fn().mockResolvedValue({ rule: { descriptionSections: [] } }),
}));
jest.mock('../../../../helpers/scrolling', () => ({
- scrollToElement: jest.fn()
+ scrollToElement: jest.fn(),
}));
it('should render correctly', async () => {
@@ -69,18 +69,18 @@ it('should render fetch rule details', async () => {
descriptionSections: [
{
key: RuleDescriptionSections.ASSESS_THE_PROBLEM,
- content: 'assess'
+ content: 'assess',
},
{
key: RuleDescriptionSections.ROOT_CAUSE,
- content: 'cause'
+ content: 'cause',
},
{
key: RuleDescriptionSections.HOW_TO_FIX,
- content: 'how'
- }
- ]
- })
+ content: 'how',
+ },
+ ],
+ }),
});
const wrapper = shallowRender();
await waitAndUpdate(wrapper);
@@ -88,26 +88,23 @@ it('should render fetch rule details', async () => {
expect(wrapper.state().ruleDescriptionSections).toStrictEqual([
{
key: RuleDescriptionSections.ASSESS_THE_PROBLEM,
- content: 'assess'
+ content: 'assess',
},
{
key: RuleDescriptionSections.ROOT_CAUSE,
- content: 'cause'
+ content: 'cause',
},
{
key: RuleDescriptionSections.HOW_TO_FIX,
- content: 'how'
- }
+ content: 'how',
+ },
]);
});
it('should refresh hotspot list on status update', () => {
const onUpdateHotspot = jest.fn();
const wrapper = shallowRender({ onUpdateHotspot });
- wrapper
- .find(HotspotViewerRenderer)
- .props()
- .onUpdateHotspot(true);
+ wrapper.find(HotspotViewerRenderer).props().onUpdateHotspot(true);
expect(onUpdateHotspot).toHaveBeenCalled();
});
@@ -115,10 +112,7 @@ it('should store last status selected when updating a hotspot status', () => {
const wrapper = shallowRender();
expect(wrapper.state().lastStatusChangedTo).toBeUndefined();
- wrapper
- .find(HotspotViewerRenderer)
- .props()
- .onUpdateHotspot(true, HotspotStatusOption.FIXED);
+ wrapper.find(HotspotViewerRenderer).props().onUpdateHotspot(true, HotspotStatusOption.FIXED);
expect(wrapper.state().lastStatusChangedTo).toBe(HotspotStatusOption.FIXED);
});
@@ -144,18 +138,15 @@ it('should correctly close the success modal', () => {
it('should NOT refresh hotspot list on assignee/comment updates', () => {
const onUpdateHotspot = jest.fn();
const wrapper = shallowRender({ onUpdateHotspot });
- wrapper
- .find(HotspotViewerRenderer)
- .props()
- .onUpdateHotspot();
+ wrapper.find(HotspotViewerRenderer).props().onUpdateHotspot();
expect(onUpdateHotspot).not.toHaveBeenCalled();
});
it('should scroll to comment form', () => {
const wrapper = shallowRender();
- const mockTextRef = ({ current: { focus: jest.fn() } } as any) as React.RefObject<
- HTMLTextAreaElement
- >;
+ const mockTextRef = {
+ current: { focus: jest.fn() },
+ } as any as React.RefObject<HTMLTextAreaElement>;
wrapper.instance().commentTextRef = mockTextRef;
wrapper.find(HotspotViewerRenderer).simulate('showCommentForm');
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotViewerRenderer-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotViewerRenderer-test.tsx
index 391389ef308..b6abb00995d 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotViewerRenderer-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotViewerRenderer-test.tsx
@@ -42,8 +42,8 @@ it('should render correctly', () => {
expect(
shallowRender({
hotspot: mockHotspot({
- assigneeUser: mockUser({ name: undefined, login: 'assignee_login' })
- })
+ assigneeUser: mockUser({ name: undefined, login: 'assignee_login' }),
+ }),
})
).toMatchSnapshot('assignee without name');
expect(shallowRender()).toMatchSnapshot('anonymous user');
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotViewerTabs-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotViewerTabs-test.tsx
index 80edf167c92..1675cfd4f05 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotViewerTabs-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotViewerTabs-test.tsx
@@ -32,19 +32,19 @@ const originalRemoveEventListener = window.removeEventListener;
beforeEach(() => {
Object.defineProperty(window, 'addEventListener', {
- value: jest.fn()
+ value: jest.fn(),
});
Object.defineProperty(window, 'removeEventListener', {
- value: jest.fn()
+ value: jest.fn(),
});
});
afterEach(() => {
Object.defineProperty(window, 'addEventListener', {
- value: originalAddEventListener
+ value: originalAddEventListener,
});
Object.defineProperty(window, 'removeEventListener', {
- value: originalRemoveEventListener
+ value: originalRemoveEventListener,
});
});
@@ -63,9 +63,9 @@ it('should render correctly', () => {
expect(
shallowRender({
hotspot: mockHotspot({
- creationDate: undefined
+ creationDate: undefined,
}),
- ruleDescriptionSections: undefined
+ ruleDescriptionSections: undefined,
})
.find<BoxedTabsProps<string>>(BoxedTabs)
.props().tabs
@@ -82,17 +82,17 @@ it('should render correctly', () => {
login: 'me',
markdown: '*test*',
updatable: false,
- user: mockUser()
- }
- ]
- })
+ user: mockUser(),
+ },
+ ],
+ }),
})
).toMatchSnapshot('with comments or changelog element');
});
it('should filter empty tab', () => {
const count = shallowRender({
- hotspot: mockHotspot()
+ hotspot: mockHotspot(),
}).state().tabs.length;
expect(
@@ -100,13 +100,13 @@ it('should filter empty tab', () => {
ruleDescriptionSections: [
{
key: RuleDescriptionSections.ROOT_CAUSE,
- content: 'cause'
+ content: 'cause',
},
{
key: RuleDescriptionSections.HOW_TO_FIX,
- content: 'how'
- }
- ]
+ content: 'how',
+ },
+ ],
}).state().tabs.length
).toBe(count - 1);
});
@@ -143,7 +143,7 @@ describe('keyboard navigation', () => {
TabKeys.Code,
TabKeys.RiskDescription,
TabKeys.VulnerabilityDescription,
- TabKeys.FixRecommendation
+ TabKeys.FixRecommendation,
];
const wrapper = shallowRender();
@@ -151,7 +151,7 @@ describe('keyboard navigation', () => {
['selecting next', 0, KeyboardKeys.RightArrow, 1],
['selecting previous', 1, KeyboardKeys.LeftArrow, 0],
['selecting previous, non-existent', 0, KeyboardKeys.LeftArrow, 0],
- ['selecting next, non-existent', 3, KeyboardKeys.RightArrow, 3]
+ ['selecting next, non-existent', 3, KeyboardKeys.RightArrow, 3],
])('should work when %s', (_, start, key, expected) => {
wrapper.setState({ currentTab: wrapper.state().tabs[start] });
wrapper.instance().handleKeyboardNavigation(mockEvent({ key }));
@@ -193,16 +193,16 @@ function shallowRender(props?: Partial<HotspotViewerTabs['props']>) {
ruleDescriptionSections={[
{
key: RuleDescriptionSections.ASSESS_THE_PROBLEM,
- content: 'assess'
+ content: 'assess',
},
{
key: RuleDescriptionSections.ROOT_CAUSE,
- content: 'cause'
+ content: 'cause',
},
{
key: RuleDescriptionSections.HOW_TO_FIX,
- content: 'how'
- }
+ content: 'how',
+ },
]}
{...props}
/>
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/StatusUpdateSuccessModal-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/StatusUpdateSuccessModal-test.tsx
index 883f25b1b21..c53b605b4a5 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/StatusUpdateSuccessModal-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/StatusUpdateSuccessModal-test.tsx
@@ -21,7 +21,7 @@ import { shallow } from 'enzyme';
import * as React from 'react';
import { HotspotStatusOption } from '../../../../types/security-hotspots';
import StatusUpdateSuccessModal, {
- StatusUpdateSuccessModalProps
+ StatusUpdateSuccessModalProps,
} from '../StatusUpdateSuccessModal';
it('should render correctly', () => {
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/Assignee.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/Assignee.tsx
index 642e7a0ca2f..04b619a35d5 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/Assignee.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/Assignee.tsx
@@ -42,7 +42,7 @@ export class Assignee extends React.PureComponent<Props, State> {
mounted = false;
state = {
editing: false,
- loading: false
+ loading: false,
};
componentDidMount() {
@@ -64,7 +64,7 @@ export class Assignee extends React.PureComponent<Props, State> {
handleAssign = (newAssignee: UserActive) => {
this.setState({ loading: true });
assignSecurityHotspot(this.props.hotspot.key, {
- assignee: newAssignee?.login
+ assignee: newAssignee?.login,
})
.then(() => {
if (this.mounted) {
@@ -85,7 +85,7 @@ export class Assignee extends React.PureComponent<Props, State> {
render() {
const {
currentUser,
- hotspot: { assigneeUser, status, resolution }
+ hotspot: { assigneeUser, status, resolution },
} = this.props;
const { editing, loading } = this.state;
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/AssigneeSelection.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/AssigneeSelection.tsx
index 8aef280c182..60c2544539c 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/AssigneeSelection.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/AssigneeSelection.tsx
@@ -50,7 +50,7 @@ export default class AssigneeSelection extends React.PureComponent<Props, State>
loading: false,
suggestedUsers: props.allowCurrentUserSelection
? [props.loggedInUser, UNASSIGNED]
- : [UNASSIGNED]
+ : [UNASSIGNED],
};
this.handleSearch = debounce(this.handleSearch, 250);
@@ -80,19 +80,19 @@ export default class AssigneeSelection extends React.PureComponent<Props, State>
this.setState({
loading: false,
query,
- suggestedUsers: allowCurrentUserSelection ? [loggedInUser, UNASSIGNED] : [UNASSIGNED]
+ suggestedUsers: allowCurrentUserSelection ? [loggedInUser, UNASSIGNED] : [UNASSIGNED],
});
};
handleActualSearch = (query: string) => {
this.setState({ loading: true, query });
searchUsers({ q: query })
- .then(result => {
+ .then((result) => {
if (this.mounted) {
this.setState({
loading: false,
query,
- suggestedUsers: (result.users.filter(isUserActive) as UserActive[]).concat(UNASSIGNED)
+ suggestedUsers: (result.users.filter(isUserActive) as UserActive[]).concat(UNASSIGNED),
});
}
})
@@ -126,7 +126,7 @@ export default class AssigneeSelection extends React.PureComponent<Props, State>
const { highlighted, suggestedUsers } = this.state;
return highlighted
- ? suggestedUsers.findIndex(suggestion => suggestion.login === highlighted.login)
+ ? suggestedUsers.findIndex((suggestion) => suggestion.login === highlighted.login)
: -1;
};
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/AssigneeSelectionRenderer.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/AssigneeSelectionRenderer.tsx
index 3610cfdc376..6f20cecc9f5 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/AssigneeSelectionRenderer.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/AssigneeSelectionRenderer.tsx
@@ -58,13 +58,14 @@ export default function AssigneeSelectionRenderer(props: HotspotAssigneeSelectRe
<DropdownOverlay noPadding={true} placement={PopupPlacement.BottomLeft}>
<ul className="hotspot-assignee-search-results">
{suggestedUsers &&
- suggestedUsers.map(suggestion => (
+ suggestedUsers.map((suggestion) => (
<li
className={classNames('padded', {
- active: highlighted && highlighted.login === suggestion.login
+ active: highlighted && highlighted.login === suggestion.login,
})}
key={suggestion.login}
- onClick={() => props.onSelect(suggestion)}>
+ onClick={() => props.onSelect(suggestion)}
+ >
{suggestion.login && (
<Avatar
className="spacer-right"
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/Assignee-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/Assignee-test.tsx
index cc9839ef45d..03aa5ded385 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/Assignee-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/Assignee-test.tsx
@@ -30,11 +30,11 @@ import { Assignee } from '../Assignee';
import AssigneeRenderer from '../AssigneeRenderer';
jest.mock('../../../../../api/security-hotspots', () => ({
- assignSecurityHotspot: jest.fn()
+ assignSecurityHotspot: jest.fn(),
}));
jest.mock('../../../../../helpers/globalMessages', () => ({
- addGlobalSuccessMessage: jest.fn()
+ addGlobalSuccessMessage: jest.fn(),
}));
it('should render correctly', () => {
@@ -45,7 +45,7 @@ it.each([
[HotspotStatus.TO_REVIEW, undefined, true],
[HotspotStatus.REVIEWED, HotspotResolution.FIXED, false],
[HotspotStatus.REVIEWED, HotspotResolution.SAFE, false],
- [HotspotStatus.REVIEWED, HotspotResolution.ACKNOWLEDGED, true]
+ [HotspotStatus.REVIEWED, HotspotResolution.ACKNOWLEDGED, true],
])('should allow edition properly', (status, resolution, canEdit) => {
expect(
shallowRender({ hotspot: mockHotspot({ status, resolution }) })
@@ -57,22 +57,16 @@ it.each([
it('should handle edition event correctly', () => {
const wrapper = shallowRender();
- wrapper
- .find(AssigneeRenderer)
- .props()
- .onEnterEditionMode();
+ wrapper.find(AssigneeRenderer).props().onEnterEditionMode();
expect(wrapper.state().editing).toBe(true);
- wrapper
- .find(AssigneeRenderer)
- .props()
- .onExitEditionMode();
+ wrapper.find(AssigneeRenderer).props().onExitEditionMode();
expect(wrapper.state().editing).toBe(false);
});
it.each([
['assign to user', mockUser() as UserActive],
- ['unassign', { login: '', name: 'unassigned' } as UserActive]
+ ['unassign', { login: '', name: 'unassigned' } as UserActive],
])('should handle %s event', async (_, user: UserActive) => {
const hotspot = mockHotspot();
const onAssigneeChange = jest.fn();
@@ -80,10 +74,7 @@ it.each([
const wrapper = shallowRender({ hotspot, onAssigneeChange });
(assignSecurityHotspot as jest.Mock).mockResolvedValueOnce({});
- wrapper
- .find(AssigneeRenderer)
- .props()
- .onAssign(user);
+ wrapper.find(AssigneeRenderer).props().onAssign(user);
expect(wrapper.state().loading).toBe(true);
expect(assignSecurityHotspot).toHaveBeenCalledWith(hotspot.key, { assignee: user?.login });
@@ -92,7 +83,7 @@ it.each([
expect(wrapper.state()).toEqual({
editing: false,
- loading: false
+ loading: false,
});
expect(onAssigneeChange).toHaveBeenCalled();
expect(addGlobalSuccessMessage).toHaveBeenCalled();
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/AssigneeRenderer-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/AssigneeRenderer-test.tsx
index 32e3de350ee..326d7cad18f 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/AssigneeRenderer-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/AssigneeRenderer-test.tsx
@@ -38,9 +38,8 @@ it('should render correctly', () => {
expect(shallowRender({ loggedInUser: undefined }).find(EditButton).length).toBe(0);
expect(shallowRender({ canEdit: false }).find(EditButton).length).toBe(0);
expect(
- shallowRender({ editing: true, assignee: mockUser() })
- .find(AssigneeSelection)
- .props().allowCurrentUserSelection
+ shallowRender({ editing: true, assignee: mockUser() }).find(AssigneeSelection).props()
+ .allowCurrentUserSelection
).toBe(true);
});
@@ -61,10 +60,7 @@ it('should propagate calls correctly', () => {
.onSelect(newAssignee as UserActive);
expect(onAssign).toHaveBeenCalledWith(newAssignee);
- wrapper
- .find(OutsideClickHandler)
- .props()
- .onClickOutside();
+ wrapper.find(OutsideClickHandler).props().onClickOutside();
expect(onExitEditionMode).toHaveBeenCalled();
});
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/AssigneeSelection-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/AssigneeSelection-test.tsx
index cb412eb9dd6..d341a86271a 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/AssigneeSelection-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/AssigneeSelection-test.tsx
@@ -27,7 +27,7 @@ import { UserActive } from '../../../../../types/users';
import AssigneeSelection from '../AssigneeSelection';
jest.mock('../../../../../api/users', () => ({
- searchUsers: jest.fn().mockResolvedValue([])
+ searchUsers: jest.fn().mockResolvedValue([]),
}));
it('should render correctly', () => {
@@ -38,7 +38,7 @@ it('should handle keydown', () => {
const suggestedUsers = [
mockUser({ login: '1' }) as UserActive,
mockUser({ login: '2' }) as UserActive,
- mockUser({ login: '3' }) as UserActive
+ mockUser({ login: '3' }) as UserActive,
];
const onSelect = jest.fn();
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/AssigneeSelectionRenderer-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/AssigneeSelectionRenderer-test.tsx
index 044572d300b..c9d581af313 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/AssigneeSelectionRenderer-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/AssigneeSelectionRenderer-test.tsx
@@ -22,7 +22,7 @@ import * as React from 'react';
import { mockUser } from '../../../../../helpers/testMocks';
import { UserActive } from '../../../../../types/users';
import AssigneeSelectionRenderer, {
- HotspotAssigneeSelectRendererProps
+ HotspotAssigneeSelectRendererProps,
} from '../AssigneeSelectionRenderer';
it('should render correctly', () => {
@@ -33,7 +33,7 @@ it('should render correctly', () => {
expect(
shallowRender({
highlighted: highlightedUser,
- suggestedUsers: [mockUser() as UserActive, highlightedUser]
+ suggestedUsers: [mockUser() as UserActive, highlightedUser],
})
).toMatchSnapshot('open with results');
});
@@ -43,13 +43,10 @@ it('should call onSelect when clicked', () => {
const onSelect = jest.fn();
const wrapper = shallowRender({
onSelect,
- suggestedUsers: [user]
+ suggestedUsers: [user],
});
- wrapper
- .find('li')
- .at(0)
- .simulate('click');
+ wrapper.find('li').at(0).simulate('click');
expect(onSelect).toHaveBeenCalledWith(user);
});
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/status/Status.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/status/Status.tsx
index 94465cdbcb8..49e6dd0b8e9 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/status/Status.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/status/Status.tsx
@@ -58,7 +58,8 @@ export function Status(props: StatusProps) {
<div className="spacer-top">
<Tooltip
overlay={readonly ? translate('hotspots.status.cannot_change_status') : null}
- placement="bottom">
+ placement="bottom"
+ >
<div className="dropdown">
<Toggler
closeOnClickOutside={true}
@@ -69,7 +70,7 @@ export function Status(props: StatusProps) {
<DropdownOverlay noPadding={true} placement={PopupPlacement.Bottom}>
<StatusSelection
hotspot={hotspot}
- onStatusOptionChange={async status => {
+ onStatusOptionChange={async (status) => {
await props.onStatusChange(status);
setIsOpen(false);
}}
@@ -77,12 +78,14 @@ export function Status(props: StatusProps) {
setComment={setComment}
/>
</DropdownOverlay>
- }>
+ }
+ >
<Button
className="dropdown-toggle big-spacer-left"
id="status-trigger"
onClick={() => setIsOpen(true)}
- disabled={readonly}>
+ disabled={readonly}
+ >
<span>{translate('hotspots.status.select_status')}</span>
<DropdownIcon className="little-spacer-left" />
</Button>
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/status/StatusSelection.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/status/StatusSelection.tsx
index 02835044110..9cdb58e63db 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/status/StatusSelection.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/status/StatusSelection.tsx
@@ -22,7 +22,7 @@ import { setSecurityHotspotStatus } from '../../../../api/security-hotspots';
import { Hotspot, HotspotStatusOption } from '../../../../types/security-hotspots';
import {
getStatusAndResolutionFromStatusOption,
- getStatusOptionFromStatusAndResolution
+ getStatusOptionFromStatusAndResolution,
} from '../../utils';
import StatusSelectionRenderer from './StatusSelectionRenderer';
@@ -53,7 +53,7 @@ export default class StatusSelection extends React.PureComponent<Props, State> {
this.state = {
loading: false,
initialStatus,
- selectedStatus: initialStatus
+ selectedStatus: initialStatus,
};
}
@@ -81,7 +81,7 @@ export default class StatusSelection extends React.PureComponent<Props, State> {
this.setState({ loading: true });
setSecurityHotspotStatus(hotspot.key, {
...getStatusAndResolutionFromStatusOption(selectedStatus),
- comment: comment || undefined
+ comment: comment || undefined,
})
.then(async () => {
await this.props.onStatusOptionChange(selectedStatus);
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/status/StatusSelectionRenderer.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/status/StatusSelectionRenderer.tsx
index 7db97ba0fdc..0b8ccf7ffb4 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/status/StatusSelectionRenderer.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/status/StatusSelectionRenderer.tsx
@@ -48,7 +48,8 @@ export default function StatusSelectionRenderer(props: StatusSelectionRendererPr
className="big-spacer-bottom status-radio"
alignLabel={true}
onCheck={props.onStatusChange}
- value={status}>
+ value={status}
+ >
<StatusDescription statusOption={status} statusInBadge={false} />
</Radio>
);
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/status/__tests__/Status-test.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/status/__tests__/Status-test.tsx
index 3274b16a9c9..73fc3f7a001 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/status/__tests__/Status-test.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/status/__tests__/Status-test.tsx
@@ -28,7 +28,7 @@ import { setSecurityHotspotStatus } from '../../../../../api/security-hotspots';
import { HotspotResolution, HotspotStatus } from '../../../../../types/security-hotspots';
jest.mock('../../../../../api/security-hotspots', () => ({
- setSecurityHotspotStatus: jest.fn().mockResolvedValue({})
+ setSecurityHotspotStatus: jest.fn().mockResolvedValue({}),
}));
it('should properly deal with comment/status/submit events', async () => {
@@ -41,7 +41,7 @@ it('should properly deal with comment/status/submit events', async () => {
await user.click(
screen.getByRole('radio', {
- name: 'hotspots.status_option.SAFE hotspots.status_option.SAFE.description'
+ name: 'hotspots.status_option.SAFE hotspots.status_option.SAFE.description',
})
);
@@ -53,7 +53,7 @@ it('should properly deal with comment/status/submit events', async () => {
expect(setSecurityHotspotStatus).toHaveBeenCalledWith(hotspot.key, {
status: HotspotStatus.REVIEWED,
resolution: HotspotResolution.SAFE,
- comment
+ comment,
});
});
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/utils.ts b/server/sonar-web/src/main/js/apps/security-hotspots/utils.ts
index e425b2e8d94..faa901cc33d 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/utils.ts
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/utils.ts
@@ -26,7 +26,7 @@ import {
renderPciDss32Category,
renderPciDss40Category,
renderSansTop25Category,
- renderSonarSourceSecurityCategory
+ renderSonarSourceSecurityCategory,
} from '../../helpers/security-standard';
import { SecurityStandard } from '../../types/security';
import {
@@ -38,13 +38,13 @@ import {
RawHotspot,
ReviewHistoryElement,
ReviewHistoryType,
- RiskExposure
+ RiskExposure,
} from '../../types/security-hotspots';
import {
Dict,
FlowLocation,
SourceViewerFile,
- StandardSecurityCategories
+ StandardSecurityCategories,
} from '../../types/types';
const OTHERS_SECURITY_CATEGORY = 'others';
@@ -58,7 +58,7 @@ export const SECURITY_STANDARDS = [
SecurityStandard.CWE,
SecurityStandard.PCI_DSS_3_2,
SecurityStandard.PCI_DSS_4_0,
- SecurityStandard.OWASP_ASVS_4_0
+ SecurityStandard.OWASP_ASVS_4_0,
];
export const SECURITY_STANDARD_RENDERER = {
@@ -69,7 +69,7 @@ export const SECURITY_STANDARD_RENDERER = {
[SecurityStandard.CWE]: renderCWECategory,
[SecurityStandard.PCI_DSS_3_2]: renderPciDss32Category,
[SecurityStandard.PCI_DSS_4_0]: renderPciDss40Category,
- [SecurityStandard.OWASP_ASVS_4_0]: renderOwaspAsvs40Category
+ [SecurityStandard.OWASP_ASVS_4_0]: renderOwaspAsvs40Category,
};
export function mapRules(rules: Array<{ key: string; name: string }>): Dict<string> {
@@ -83,28 +83,28 @@ export function groupByCategory(
hotspots: RawHotspot[] = [],
securityCategories: StandardSecurityCategories
) {
- const groups = groupBy(hotspots, h => h.securityCategory);
+ const groups = groupBy(hotspots, (h) => h.securityCategory);
- const groupList = Object.keys(groups).map(key => ({
+ const groupList = Object.keys(groups).map((key) => ({
key,
title: getCategoryTitle(key, securityCategories),
- hotspots: groups[key]
+ hotspots: groups[key],
}));
return [
...sortBy(
- groupList.filter(group => group.key !== OTHERS_SECURITY_CATEGORY),
- group => group.title
+ groupList.filter((group) => group.key !== OTHERS_SECURITY_CATEGORY),
+ (group) => group.title
),
- ...groupList.filter(({ key }) => key === OTHERS_SECURITY_CATEGORY)
+ ...groupList.filter(({ key }) => key === OTHERS_SECURITY_CATEGORY),
];
}
export function sortHotspots(hotspots: RawHotspot[], securityCategories: Dict<{ title: string }>) {
return sortBy(hotspots, [
- h => RISK_EXPOSURE_LEVELS.indexOf(h.vulnerabilityProbability),
- h => getCategoryTitle(h.securityCategory, securityCategories),
- h => h.message
+ (h) => RISK_EXPOSURE_LEVELS.indexOf(h.vulnerabilityProbability),
+ (h) => getCategoryTitle(h.securityCategory, securityCategories),
+ (h) => h.message,
]);
}
@@ -123,7 +123,7 @@ export function constructSourceViewerFile(
project: project.key,
projectName: project.name,
q: component.qualifier,
- uuid: ''
+ uuid: '',
};
}
@@ -136,44 +136,44 @@ export function getHotspotReviewHistory(hotspot: Hotspot): ReviewHistoryElement[
date: hotspot.creationDate,
user: {
...hotspot.authorUser,
- name: hotspot.authorUser.name || hotspot.authorUser.login
- }
+ name: hotspot.authorUser.name || hotspot.authorUser.login,
+ },
});
}
if (hotspot.changelog && hotspot.changelog.length > 0) {
history.push(
- ...hotspot.changelog.map(log => ({
+ ...hotspot.changelog.map((log) => ({
type: ReviewHistoryType.Diff,
date: log.creationDate,
user: {
active: log.isUserActive,
avatar: log.avatar,
- name: log.userName || log.user
+ name: log.userName || log.user,
},
- diffs: log.diffs
+ diffs: log.diffs,
}))
);
}
if (hotspot.comment && hotspot.comment.length > 0) {
history.push(
- ...hotspot.comment.map(comment => ({
+ ...hotspot.comment.map((comment) => ({
type: ReviewHistoryType.Comment,
date: comment.createdAt,
updatable: comment.updatable,
user: {
...comment.user,
- name: comment.user.name || comment.user.login
+ name: comment.user.name || comment.user.login,
},
html: comment.htmlText,
key: comment.key,
- markdown: comment.markdown
+ markdown: comment.markdown,
}))
);
}
- return sortBy(history, elt => elt.date).reverse();
+ return sortBy(history, (elt) => elt.date).reverse();
}
const STATUS_AND_RESOLUTION_TO_STATUS_OPTION = {
@@ -181,7 +181,7 @@ const STATUS_AND_RESOLUTION_TO_STATUS_OPTION = {
[HotspotStatus.REVIEWED]: HotspotStatusOption.FIXED,
[HotspotResolution.ACKNOWLEDGED]: HotspotStatusOption.ACKNOWLEDGED,
[HotspotResolution.FIXED]: HotspotStatusOption.FIXED,
- [HotspotResolution.SAFE]: HotspotStatusOption.SAFE
+ [HotspotResolution.SAFE]: HotspotStatusOption.SAFE,
};
export function getStatusOptionFromStatusAndResolution(
@@ -197,16 +197,16 @@ const STATUS_OPTION_TO_STATUS_AND_RESOLUTION_MAP = {
[HotspotStatusOption.TO_REVIEW]: { status: HotspotStatus.TO_REVIEW, resolution: undefined },
[HotspotStatusOption.ACKNOWLEDGED]: {
status: HotspotStatus.REVIEWED,
- resolution: HotspotResolution.ACKNOWLEDGED
+ resolution: HotspotResolution.ACKNOWLEDGED,
},
[HotspotStatusOption.FIXED]: {
status: HotspotStatus.REVIEWED,
- resolution: HotspotResolution.FIXED
+ resolution: HotspotResolution.FIXED,
},
[HotspotStatusOption.SAFE]: {
status: HotspotStatus.REVIEWED,
- resolution: HotspotResolution.SAFE
- }
+ resolution: HotspotResolution.SAFE,
+ },
};
export function getStatusAndResolutionFromStatusOption(statusOption: HotspotStatusOption) {
@@ -217,7 +217,7 @@ const STATUS_OPTION_TO_STATUS_FILTER = {
[HotspotStatusOption.TO_REVIEW]: HotspotStatusFilter.TO_REVIEW,
[HotspotStatusOption.ACKNOWLEDGED]: HotspotStatusFilter.ACKNOWLEDGED,
[HotspotStatusOption.FIXED]: HotspotStatusFilter.FIXED,
- [HotspotStatusOption.SAFE]: HotspotStatusFilter.SAFE
+ [HotspotStatusOption.SAFE]: HotspotStatusFilter.SAFE,
};
export function getStatusFilterFromStatusOption(statusOption: HotspotStatusOption) {
@@ -226,15 +226,15 @@ export function getStatusFilterFromStatusOption(statusOption: HotspotStatusOptio
function getSecondaryLocations(flows: RawHotspot['flows']) {
const parsedFlows: FlowLocation[][] = (flows || [])
- .filter(flow => flow.locations !== undefined)
- .map(flow => flow.locations!.filter(location => location.textRange != null))
- .map(flow =>
- flow.map(location => {
+ .filter((flow) => flow.locations !== undefined)
+ .map((flow) => flow.locations!.filter((location) => location.textRange != null))
+ .map((flow) =>
+ flow.map((location) => {
return { ...location };
})
);
- const onlySecondaryLocations = parsedFlows.every(flow => flow.length === 1);
+ const onlySecondaryLocations = parsedFlows.every((flow) => flow.length === 1);
return onlySecondaryLocations
? { secondaryLocations: orderLocations(flatten(parsedFlows)), flows: [] }
@@ -252,8 +252,8 @@ export function getLocations(rawFlows: RawHotspot['flows'], selectedFlowIndex: n
function orderLocations(locations: FlowLocation[]) {
return sortBy(
locations,
- location => location.textRange && location.textRange.startLine,
- location => location.textRange && location.textRange.startOffset
+ (location) => location.textRange && location.textRange.startLine,
+ (location) => location.textRange && location.textRange.startOffset
);
}