aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorGuillaume Peoc'h <guillaume.peoch@sonarsource.com>2022-02-10 11:31:21 +0100
committersonartech <sonartech@sonarsource.com>2022-02-25 20:02:54 +0000
commit7ff077120c74f42fd55d1f2a33f1ee5cdf5ef735 (patch)
treee10c5f90e2f6adb4533a726588db04c84ea25a0b /server
parent0635374eb836f7994bf759fa4473f750c7b5a63b (diff)
downloadsonarqube-7ff077120c74f42fd55d1f2a33f1ee5cdf5ef735.tar.gz
sonarqube-7ff077120c74f42fd55d1f2a33f1ee5cdf5ef735.zip
SONAR-16008 Revamp Top Section
Diffstat (limited to 'server')
-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/components/HotspotHeader.tsx62
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotPrimaryLocationBox.tsx20
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetContainer.tsx3
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetContainerRenderer.tsx19
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetHeader.tsx116
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewer.tsx9
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewerRenderer.tsx102
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotHeader-test.tsx46
-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__/HotspotSnippetContainerRenderer-test.tsx3
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSnippetHeader-test.tsx49
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotViewer-test.tsx1
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotViewerRenderer-test.tsx16
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotHeader-test.tsx.snap236
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotPrimaryLocationBox-test.tsx.snap16
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotSnippetContainer-test.tsx.snap23
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotSnippetContainerRenderer-test.tsx.snap298
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotSnippetHeader-test.tsx.snap137
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotViewer-test.tsx.snap14
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotViewerRenderer-test.tsx.snap2268
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/AssigneeSelectionRenderer.tsx52
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/__snapshots__/AssigneeSelectionRenderer-test.tsx.snap100
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/status/Status.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/status/StatusDescription.tsx11
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/status/__tests__/__snapshots__/Status-test.tsx.snap18
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/status/__tests__/__snapshots__/StatusDescription-test.tsx.snap20
27 files changed, 1573 insertions, 2086 deletions
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 43f521eb9e4..deaf72093cd 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
@@ -172,13 +172,11 @@ export default function SecurityHotspotsAppRenderer(props: SecurityHotspotsAppRe
<div className="layout-page-main">
<HotspotViewer
- branchLike={branchLike}
component={component}
hotspotKey={selectedHotspot.key}
hotspotsReviewedMeasure={hotspotsReviewedMeasure}
onSwitchStatusFilter={props.onSwitchStatusFilter}
onUpdateHotspot={props.onUpdateHotspot}
- securityCategories={securityCategories}
/>
</div>
</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
new file mode 100644
index 00000000000..89c8d542147
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotHeader.tsx
@@ -0,0 +1,62 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+import React from 'react';
+import { Link } from 'react-router';
+import { translate } from '../../../helpers/l10n';
+import { getRuleUrl } from '../../../helpers/urls';
+import { Hotspot, HotspotStatusOption } from '../../../types/security-hotspots';
+import Assignee from './assignee/Assignee';
+import Status from './status/Status';
+
+export interface HotspotHeaderProps {
+ hotspot: Hotspot;
+ onUpdateHotspot: (statusUpdate?: boolean, statusOption?: HotspotStatusOption) => Promise<void>;
+}
+
+export function HotspotHeader(props: HotspotHeaderProps) {
+ const { hotspot } = props;
+ const { message, rule } = hotspot;
+ return (
+ <div className="big-spacer-bottom">
+ <div className="display-flex-column big-spacer-bottom">
+ <div className="big text-bold">{message}</div>
+ <div>
+ <span className="note padded-right">{rule.name}</span>
+ <Link className="small" to={getRuleUrl(rule.key)} target="_blank">
+ {rule.key}
+ </Link>
+ </div>
+ </div>
+ <div className="display-flex-space-between">
+ <Status
+ hotspot={hotspot}
+ onStatusChange={statusOption => props.onUpdateHotspot(true, statusOption)}
+ />
+ <div className="display-flex-end">
+ <div className="display-inline-flex-center it__hs-assignee">
+ <div className="text-bold big-spacer-right">{`${translate('assignee')}: `}</div>
+ <Assignee hotspot={hotspot} onAssigneeChange={props.onUpdateHotspot} />
+ </div>
+ </div>
+ </div>
+ </div>
+ );
+}
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 be0102264c9..f86ec0332cc 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
@@ -20,17 +20,21 @@
import classNames from 'classnames';
import * as React from 'react';
import { ButtonLink } from '../../../components/controls/buttons';
+import { withCurrentUser } from '../../../components/hoc/withCurrentUser';
import { translate } from '../../../helpers/l10n';
+import { isLoggedIn } from '../../../helpers/users';
import { Hotspot } from '../../../types/security-hotspots';
+import { CurrentUser } from '../../../types/types';
import './HotspotPrimaryLocationBox.css';
export interface HotspotPrimaryLocationBoxProps {
hotspot: Hotspot;
onCommentClick: () => void;
+ currentUser: CurrentUser;
}
-export default function HotspotPrimaryLocationBox(props: HotspotPrimaryLocationBoxProps) {
- const { hotspot } = props;
+export function HotspotPrimaryLocationBox(props: HotspotPrimaryLocationBoxProps) {
+ const { hotspot, currentUser } = props;
return (
<div
className={classNames(
@@ -39,9 +43,15 @@ export default function HotspotPrimaryLocationBox(props: HotspotPrimaryLocationB
`hotspot-risk-exposure-${hotspot.rule.vulnerabilityProbability}`
)}>
<div className="text-bold">{hotspot.message}</div>
- <ButtonLink className="nowrap big-spacer-left" onClick={props.onCommentClick}>
- {translate('hotspots.comment.open')}
- </ButtonLink>
+ {isLoggedIn(currentUser) && (
+ <ButtonLink
+ className="nowrap big-spacer-left it__hs-add-comment"
+ onClick={props.onCommentClick}>
+ {translate('hotspots.comment.open')}
+ </ButtonLink>
+ )}
</div>
);
}
+
+export default withCurrentUser(HotspotPrimaryLocationBox);
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 6318465460f..690f1047d1c 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
@@ -22,7 +22,6 @@ import { getSources } from '../../../api/components';
import { locationsByLine } from '../../../components/SourceViewer/helpers/indexing';
import { getBranchLikeQuery } from '../../../helpers/branch-like';
import { BranchLike } from '../../../types/branch-like';
-import { ComponentQualifier } from '../../../types/component';
import { Hotspot } from '../../../types/security-hotspots';
import { Component, ExpandDirection, FlowLocation, SourceLine } from '../../../types/types';
import { constructSourceViewerFile, getLocations } from '../utils';
@@ -207,7 +206,7 @@ export default class HotspotSnippetContainer extends React.Component<Props, Stat
return (
<HotspotSnippetContainerRenderer
branchLike={branchLike}
- displayProjectName={component.qualifier === ComponentQualifier.Application}
+ component={component}
highlightedSymbols={highlightedSymbols}
hotspot={hotspot}
loading={loading}
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 dfe5c696eb4..87b83cc6610 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
@@ -18,12 +18,12 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import SourceViewerHeaderSlim from '../../../components/SourceViewer/SourceViewerHeaderSlim';
import DeferredSpinner from '../../../components/ui/DeferredSpinner';
import { translate } from '../../../helpers/l10n';
import { BranchLike } from '../../../types/branch-like';
import { Hotspot } from '../../../types/security-hotspots';
import {
+ Component,
ExpandDirection,
FlowLocation,
LinearIssueLocation,
@@ -32,10 +32,10 @@ import {
} from '../../../types/types';
import SnippetViewer from '../../issues/crossComponentSourceViewer/SnippetViewer';
import HotspotPrimaryLocationBox from './HotspotPrimaryLocationBox';
+import HotspotSnippetHeader from './HotspotSnippetHeader';
export interface HotspotSnippetContainerRendererProps {
branchLike?: BranchLike;
- displayProjectName?: boolean;
highlightedSymbols: string[];
hotspot: Hotspot;
loading: boolean;
@@ -46,6 +46,7 @@ export interface HotspotSnippetContainerRendererProps {
sourceLines: SourceLine[];
sourceViewerFile: SourceViewerFile;
secondaryLocations: FlowLocation[];
+ component: Component;
}
const noop = () => undefined;
@@ -55,14 +56,14 @@ export default function HotspotSnippetContainerRenderer(
) {
const {
branchLike,
- displayProjectName,
highlightedSymbols,
hotspot,
loading,
locations: primaryLocations,
sourceLines,
sourceViewerFile,
- secondaryLocations
+ secondaryLocations,
+ component
} = props;
const renderHotspotBoxInLine = (lineNumber: number) =>
@@ -77,16 +78,8 @@ export default function HotspotSnippetContainerRenderer(
{!loading && sourceLines.length === 0 && (
<p className="spacer-bottom">{translate('hotspots.no_associated_lines')}</p>
)}
+ <HotspotSnippetHeader hotspot={hotspot} component={component} branchLike={branchLike} />
<div className="bordered big-spacer-bottom">
- <SourceViewerHeaderSlim
- branchLike={branchLike}
- expandable={false}
- displayProjectName={displayProjectName}
- linkToProject={false}
- loading={loading}
- onExpand={noop}
- sourceViewerFile={sourceViewerFile}
- />
<DeferredSpinner className="big-spacer" loading={loading}>
{sourceLines.length > 0 && (
<SnippetViewer
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
new file mode 100644
index 00000000000..a79ed7659fc
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotSnippetHeader.tsx
@@ -0,0 +1,116 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+import styled from '@emotion/styled';
+import React from 'react';
+import { colors, sizes } from '../../../app/theme';
+import { ClipboardButton, ClipboardIconButton } from '../../../components/controls/clipboard';
+import { withCurrentUser } from '../../../components/hoc/withCurrentUser';
+import LinkIcon from '../../../components/icons/LinkIcon';
+import QualifierIcon from '../../../components/icons/QualifierIcon';
+import { getBranchLikeQuery } from '../../../helpers/branch-like';
+import { translate } from '../../../helpers/l10n';
+import { collapsedDirFromPath, fileFromPath } from '../../../helpers/path';
+import { getComponentSecurityHotspotsUrl, getPathUrlAsString } from '../../../helpers/urls';
+import { isLoggedIn } from '../../../helpers/users';
+import { BranchLike } from '../../../types/branch-like';
+import { ComponentQualifier } from '../../../types/component';
+import { Hotspot } from '../../../types/security-hotspots';
+import { Component, CurrentUser } from '../../../types/types';
+import HotspotOpenInIdeButton from './HotspotOpenInIdeButton';
+
+export interface HotspotSnippetHeaderProps {
+ hotspot: Hotspot;
+ currentUser: CurrentUser;
+ component: Component;
+ branchLike?: BranchLike;
+}
+
+export function HotspotSnippetHeader(props: HotspotSnippetHeaderProps) {
+ const { hotspot, currentUser, component, branchLike } = props;
+ const {
+ project,
+ component: { qualifier, path }
+ } = hotspot;
+
+ const displayProjectName = component.qualifier === ComponentQualifier.Application;
+
+ const permalink = getPathUrlAsString(
+ getComponentSecurityHotspotsUrl(component.key, {
+ ...getBranchLikeQuery(branchLike),
+ hotspots: hotspot?.key
+ }),
+ false
+ );
+
+ return (
+ <Container>
+ <div className="display-flex-row">
+ <FilePath>
+ {displayProjectName && (
+ <>
+ <QualifierIcon
+ className="little-spacer-right"
+ qualifier={ComponentQualifier.Project}
+ />
+ <span className="little-spacer-right">{project.name}</span>
+ </>
+ )}
+ <QualifierIcon qualifier={qualifier} /> <span>{collapsedDirFromPath(path)}</span>
+ <span className="little-spacer-right">{fileFromPath(path)}</span>
+ <ClipboardIconButton className="button-link link-no-underline" copyValue={path} />
+ </FilePath>
+
+ {isLoggedIn(currentUser) && (
+ <div className="dropdown spacer-right">
+ <HotspotOpenInIdeButton hotspotKey={hotspot.key} projectKey={project.key} />
+ </div>
+ )}
+ </div>
+
+ <ClipboardButton copyValue={permalink}>
+ <span>{translate('hotspots.get_permalink')}</span>
+ <LinkIcon className="spacer-left" />
+ </ClipboardButton>
+ </Container>
+ );
+}
+
+const Container = styled.div`
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ height: 40px;
+ padding: 0 ${sizes.gridSize};
+ border: 1px solid ${colors.barBorderColor};
+ background-color: ${colors.barBackgroundColor};
+`;
+
+const FilePath = styled.div`
+ display: flex;
+ align-items: center;
+ margin-right: 40px;
+ color: ${colors.secondFontColor};
+ svg {
+ margin: 0 ${sizes.gridSize};
+ }
+`;
+
+export default withCurrentUser(HotspotSnippetHeader);
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 fa9ed13f9ce..860c97f2bbb 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
@@ -20,24 +20,21 @@
import * as React from 'react';
import { getSecurityHotspotDetails } from '../../../api/security-hotspots';
import { scrollToElement } from '../../../helpers/scrolling';
-import { BranchLike } from '../../../types/branch-like';
import {
Hotspot,
HotspotStatusFilter,
HotspotStatusOption
} from '../../../types/security-hotspots';
-import { Component, StandardSecurityCategories } from '../../../types/types';
+import { Component } from '../../../types/types';
import { getStatusFilterFromStatusOption } from '../utils';
import HotspotViewerRenderer from './HotspotViewerRenderer';
interface Props {
- branchLike?: BranchLike;
component: Component;
hotspotKey: string;
hotspotsReviewedMeasure?: string;
onSwitchStatusFilter: (option: HotspotStatusFilter) => void;
onUpdateHotspot: (hotspotKey: string) => Promise<void>;
- securityCategories: StandardSecurityCategories;
}
interface State {
@@ -119,12 +116,11 @@ export default class HotspotViewer extends React.PureComponent<Props, State> {
};
render() {
- const { branchLike, component, hotspotsReviewedMeasure, securityCategories } = this.props;
+ const { component, hotspotsReviewedMeasure } = this.props;
const { hotspot, lastStatusChangedTo, loading, showStatusUpdateSuccessModal } = this.state;
return (
<HotspotViewerRenderer
- branchLike={branchLike}
component={component}
commentTextRef={this.commentTextRef}
hotspot={hotspot}
@@ -136,7 +132,6 @@ export default class HotspotViewer extends React.PureComponent<Props, State> {
onShowCommentForm={this.handleScrollToCommentForm}
onUpdateHotspot={this.handleHotspotUpdate}
showStatusUpdateSuccessModal={showStatusUpdateSuccessModal}
- securityCategories={securityCategories}
/>
);
}
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 c8256ead7a5..000f7077b2b 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
@@ -17,36 +17,20 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import classNames from 'classnames';
import * as React from 'react';
-import { Link } from 'react-router';
-import { Button } from '../../../components/controls/buttons';
-import { ClipboardButton } from '../../../components/controls/clipboard';
import { withCurrentUser } from '../../../components/hoc/withCurrentUser';
-import LinkIcon from '../../../components/icons/LinkIcon';
import DeferredSpinner from '../../../components/ui/DeferredSpinner';
-import { fillBranchLike, getBranchLikeQuery } from '../../../helpers/branch-like';
-import { translate } from '../../../helpers/l10n';
-import {
- getComponentSecurityHotspotsUrl,
- getPathUrlAsString,
- getRuleUrl
-} from '../../../helpers/urls';
-import { isLoggedIn } from '../../../helpers/users';
-import { BranchLike } from '../../../types/branch-like';
+import { fillBranchLike } from '../../../helpers/branch-like';
import { Hotspot, HotspotStatusOption } from '../../../types/security-hotspots';
-import { Component, CurrentUser, StandardSecurityCategories } from '../../../types/types';
-import Assignee from './assignee/Assignee';
-import HotspotOpenInIdeButton from './HotspotOpenInIdeButton';
+import { Component, CurrentUser } from '../../../types/types';
+import { HotspotHeader } from './HotspotHeader';
import HotspotReviewHistoryAndComments from './HotspotReviewHistoryAndComments';
import HotspotSnippetContainer from './HotspotSnippetContainer';
import './HotspotViewer.css';
import HotspotViewerTabs from './HotspotViewerTabs';
-import Status from './status/Status';
import StatusUpdateSuccessModal from './StatusUpdateSuccessModal';
export interface HotspotViewerRendererProps {
- branchLike?: BranchLike;
component: Component;
currentUser: CurrentUser;
hotspot?: Hotspot;
@@ -59,12 +43,10 @@ export interface HotspotViewerRendererProps {
onShowCommentForm: () => void;
onSwitchFilterToStatusOfUpdatedHotspot: () => void;
showStatusUpdateSuccessModal: boolean;
- securityCategories: StandardSecurityCategories;
}
export function HotspotViewerRenderer(props: HotspotViewerRendererProps) {
const {
- branchLike,
component,
currentUser,
hotspot,
@@ -72,18 +54,9 @@ export function HotspotViewerRenderer(props: HotspotViewerRendererProps) {
loading,
lastStatusChangedTo,
showStatusUpdateSuccessModal,
- securityCategories,
commentTextRef
} = props;
- const permalink = getPathUrlAsString(
- getComponentSecurityHotspotsUrl(component.key, {
- ...getBranchLikeQuery(branchLike),
- hotspots: hotspot?.key
- }),
- false
- );
-
return (
<DeferredSpinner className="big-spacer-left big-spacer-top" loading={loading}>
{showStatusUpdateSuccessModal && (
@@ -97,74 +70,7 @@ export function HotspotViewerRenderer(props: HotspotViewerRendererProps) {
{hotspot && (
<div className="big-padded hotspot-content">
- <div className="huge-spacer-bottom display-flex-space-between">
- <div className="display-flex-column">
- <strong className="big big-spacer-right little-spacer-bottom">
- {hotspot.message}
- </strong>
- <div>
- <span className="note padded-right">{hotspot.rule.name}</span>
- <Link className="small" to={getRuleUrl(hotspot.rule.key)} target="_blank">
- {hotspot.rule.key}
- </Link>
- </div>
- </div>
- <div className="display-flex-row flex-0">
- {isLoggedIn(currentUser) && (
- <>
- <div className="dropdown spacer-right flex-1-0-auto">
- <Button className="it__hs-add-comment" onClick={props.onShowCommentForm}>
- {translate('hotspots.comment.open')}
- </Button>
- </div>
- <div className="dropdown spacer-right flex-1-0-auto">
- <HotspotOpenInIdeButton
- hotspotKey={hotspot.key}
- projectKey={hotspot.project.key}
- />
- </div>
- </>
- )}
- <ClipboardButton className="flex-1-0-auto" copyValue={permalink}>
- <LinkIcon className="spacer-right" />
- <span>{translate('hotspots.get_permalink')}</span>
- </ClipboardButton>
- </div>
- </div>
-
- <div className="huge-spacer-bottom display-flex-row display-flex-space-between">
- <div className="hotspot-information display-flex-column display-flex-space-between">
- <div className="display-flex-center">
- <span className="big-spacer-right">{translate('category')}</span>
- <strong className="nowrap">
- {securityCategories[hotspot.rule.securityCategory].title}
- </strong>
- </div>
- <div className="display-flex-center">
- <span className="big-spacer-right">{translate('hotspots.risk_exposure')}</span>
- <div
- className={classNames(
- 'hotspot-risk-badge',
- hotspot.rule.vulnerabilityProbability
- )}>
- {translate('risk_exposure', hotspot.rule.vulnerabilityProbability)}
- </div>
- </div>
- <div className="display-flex-center it__hs-assignee">
- <span className="big-spacer-right">{translate('assignee')}</span>
- <div>
- <Assignee hotspot={hotspot} onAssigneeChange={props.onUpdateHotspot} />
- </div>
- </div>
- </div>
- <div className="huge-spacer-left abs-width-400">
- <Status
- hotspot={hotspot}
- onStatusChange={statusOption => props.onUpdateHotspot(true, statusOption)}
- />
- </div>
- </div>
-
+ <HotspotHeader hotspot={hotspot} onUpdateHotspot={props.onUpdateHotspot} />
<HotspotSnippetContainer
branchLike={fillBranchLike(hotspot.project.branch, hotspot.project.pullRequest)}
component={component}
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
new file mode 100644
index 00000000000..b285f794897
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotHeader-test.tsx
@@ -0,0 +1,46 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+import { shallow } from 'enzyme';
+import React from 'react';
+import { mockHotspot } from '../../../../helpers/mocks/security-hotspots';
+import { HotspotStatusOption } from '../../../../types/security-hotspots';
+import { HotspotHeader, HotspotHeaderProps } from '../HotspotHeader';
+import Status from '../status/Status';
+
+it('should render correctly', () => {
+ expect(shallowRender()).toMatchSnapshot();
+});
+
+it('correctly propagates the status change', () => {
+ const onUpdateHotspot = jest.fn();
+ const wrapper = shallowRender({ onUpdateHotspot });
+
+ wrapper
+ .find(Status)
+ .props()
+ .onStatusChange(HotspotStatusOption.FIXED);
+
+ expect(onUpdateHotspot).toHaveBeenCalledWith(true, HotspotStatusOption.FIXED);
+});
+
+function shallowRender(props: Partial<HotspotHeaderProps> = {}) {
+ return shallow(<HotspotHeader hotspot={mockHotspot()} onUpdateHotspot={jest.fn()} {...props} />);
+}
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 2c9cec0485c..753344b9235 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
@@ -21,13 +21,16 @@ import { shallow } from 'enzyme';
import * as React from 'react';
import { ButtonLink } from '../../../../components/controls/buttons';
import { mockHotspot, mockHotspotRule } from '../../../../helpers/mocks/security-hotspots';
+import { mockCurrentUser, mockLoggedInUser } from '../../../../helpers/testMocks';
import { RiskExposure } from '../../../../types/security-hotspots';
-import HotspotPrimaryLocationBox, {
+import {
+ HotspotPrimaryLocationBox,
HotspotPrimaryLocationBoxProps
} from '../HotspotPrimaryLocationBox';
it('should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot();
+ expect(shallowRender()).toMatchSnapshot('User logged in');
+ expect(shallowRender({ currentUser: mockCurrentUser() })).toMatchSnapshot('User not logged in ');
});
it.each([[RiskExposure.HIGH], [RiskExposure.MEDIUM], [RiskExposure.LOW]])(
@@ -52,6 +55,11 @@ it('should handle click', () => {
function shallowRender(props: Partial<HotspotPrimaryLocationBoxProps> = {}) {
return shallow(
- <HotspotPrimaryLocationBox hotspot={mockHotspot()} onCommentClick={jest.fn()} {...props} />
+ <HotspotPrimaryLocationBox
+ currentUser={mockLoggedInUser()}
+ hotspot={mockHotspot()}
+ onCommentClick={jest.fn()}
+ {...props}
+ />
);
}
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 7f1151397b0..2b36ee19b29 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
@@ -20,6 +20,7 @@
import { shallow } from 'enzyme';
import * as React from 'react';
import { mockMainBranch } from '../../../../helpers/mocks/branch-like';
+import { mockComponent } from '../../../../helpers/mocks/component';
import { mockHotspot } from '../../../../helpers/mocks/security-hotspots';
import { mockSourceLine, mockSourceViewerFile } from '../../../../helpers/testMocks';
import SnippetViewer from '../../../issues/crossComponentSourceViewer/SnippetViewer';
@@ -48,7 +49,6 @@ function shallowRender(props?: Partial<HotspotSnippetContainerRendererProps>) {
return shallow(
<HotspotSnippetContainerRenderer
branchLike={mockMainBranch()}
- displayProjectName={true}
highlightedSymbols={[]}
hotspot={mockHotspot()}
loading={false}
@@ -59,6 +59,7 @@ function shallowRender(props?: Partial<HotspotSnippetContainerRendererProps>) {
secondaryLocations={[]}
sourceLines={[]}
sourceViewerFile={mockSourceViewerFile()}
+ component={mockComponent()}
{...props}
/>
);
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
new file mode 100644
index 00000000000..1a99931e45b
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/HotspotSnippetHeader-test.tsx
@@ -0,0 +1,49 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+import { shallow } from 'enzyme';
+import React from 'react';
+import { mockComponent } from '../../../../helpers/mocks/component';
+import { mockHotspot } from '../../../../helpers/mocks/security-hotspots';
+import { mockCurrentUser, mockLoggedInUser } from '../../../../helpers/testMocks';
+import { ComponentQualifier } from '../../../../types/component';
+import { HotspotSnippetHeader, HotspotSnippetHeaderProps } from '../HotspotSnippetHeader';
+
+it('should render correctly', () => {
+ expect(shallowRender()).toMatchSnapshot('user not logged in');
+ expect(shallowRender({ currentUser: mockLoggedInUser() })).toMatchSnapshot('user logged in');
+ expect(
+ shallowRender({
+ currentUser: mockLoggedInUser(),
+ component: mockComponent({ qualifier: ComponentQualifier.Application })
+ })
+ ).toMatchSnapshot('user logged in with project Name');
+});
+
+function shallowRender(props: Partial<HotspotSnippetHeaderProps> = {}) {
+ return shallow(
+ <HotspotSnippetHeader
+ hotspot={mockHotspot()}
+ currentUser={mockCurrentUser()}
+ component={mockComponent()}
+ {...props}
+ />
+ );
+}
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 56d5d2f02d6..31a07d26364 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
@@ -143,7 +143,6 @@ function shallowRender(props?: Partial<HotspotViewer['props']>) {
hotspotKey={hotspotKey}
onSwitchStatusFilter={jest.fn()}
onUpdateHotspot={jest.fn()}
- securityCategories={{ cat1: { title: 'cat1' } }}
{...props}
/>
);
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 126e874e8b6..d99c07fc360 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
@@ -19,13 +19,11 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { mockBranch } from '../../../../helpers/mocks/branch-like';
import { mockComponent } from '../../../../helpers/mocks/component';
import { mockHotspot } from '../../../../helpers/mocks/security-hotspots';
import { mockCurrentUser, mockUser } from '../../../../helpers/testMocks';
import { HotspotStatusOption } from '../../../../types/security-hotspots';
import { HotspotViewerRenderer, HotspotViewerRendererProps } from '../HotspotViewerRenderer';
-import Status from '../status/Status';
jest.mock('../../../../helpers/users', () => ({ isLoggedIn: jest.fn(() => true) }));
@@ -51,22 +49,9 @@ it('should render correctly', () => {
expect(shallowRender()).toMatchSnapshot('anonymous user');
});
-it('correctly propagates the status change', () => {
- const onUpdateHotspot = jest.fn();
- const wrapper = shallowRender({ onUpdateHotspot });
-
- wrapper
- .find(Status)
- .props()
- .onStatusChange(HotspotStatusOption.FIXED);
-
- expect(onUpdateHotspot).toHaveBeenCalledWith(true, HotspotStatusOption.FIXED);
-});
-
function shallowRender(props?: Partial<HotspotViewerRendererProps>) {
return shallow(
<HotspotViewerRenderer
- branchLike={mockBranch()}
component={mockComponent()}
commentTextRef={React.createRef()}
currentUser={mockCurrentUser()}
@@ -78,7 +63,6 @@ function shallowRender(props?: Partial<HotspotViewerRendererProps>) {
onSwitchFilterToStatusOfUpdatedHotspot={jest.fn()}
onShowCommentForm={jest.fn()}
onUpdateHotspot={jest.fn()}
- securityCategories={{ 'sql-injection': { title: 'SQL injection' } }}
showStatusUpdateSuccessModal={false}
{...props}
/>
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotHeader-test.tsx.snap b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotHeader-test.tsx.snap
new file mode 100644
index 00000000000..79b27dcc3b2
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotHeader-test.tsx.snap
@@ -0,0 +1,236 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<div
+ className="big-spacer-bottom"
+>
+ <div
+ className="display-flex-column big-spacer-bottom"
+ >
+ <div
+ className="big text-bold"
+ >
+ '3' is a magic number.
+ </div>
+ <div>
+ <span
+ className="note padded-right"
+ >
+ That rule
+ </span>
+ <Link
+ className="small"
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ target="_blank"
+ to={
+ Object {
+ "pathname": "/coding_rules",
+ "query": Object {
+ "open": "squid:S2077",
+ "rule_key": "squid:S2077",
+ },
+ }
+ }
+ >
+ squid:S2077
+ </Link>
+ </div>
+ </div>
+ <div
+ className="display-flex-space-between"
+ >
+ <Connect(withCurrentUser(Status))
+ hotspot={
+ Object {
+ "assignee": "assignee",
+ "assigneeUser": Object {
+ "active": true,
+ "local": true,
+ "login": "assignee",
+ "name": "John Doe",
+ },
+ "author": "author",
+ "authorUser": Object {
+ "active": true,
+ "local": true,
+ "login": "author",
+ "name": "John Doe",
+ },
+ "canChangeStatus": true,
+ "changelog": Array [],
+ "comment": Array [],
+ "component": Object {
+ "key": "hotspot-component",
+ "longName": "Hotspot component long name",
+ "name": "Hotspot Component",
+ "path": "path/to/component",
+ "qualifier": "FIL",
+ },
+ "creationDate": "2013-05-13T17:55:41+0200",
+ "flows": Array [
+ Object {
+ "locations": Array [
+ Object {
+ "component": "main.js",
+ "textRange": Object {
+ "endLine": 2,
+ "endOffset": 2,
+ "startLine": 1,
+ "startOffset": 1,
+ },
+ },
+ ],
+ },
+ ],
+ "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123",
+ "line": 142,
+ "message": "'3' is a magic number.",
+ "project": Object {
+ "key": "hotspot-component",
+ "longName": "Hotspot component long name",
+ "name": "Hotspot Component",
+ "path": "path/to/component",
+ "qualifier": "TRK",
+ },
+ "resolution": "FIXED",
+ "rule": Object {
+ "fixRecommendations": "<p>This a <strong>strong</strong> message about fixing !</p>",
+ "key": "squid:S2077",
+ "name": "That rule",
+ "riskDescription": "<p>This a <strong>strong</strong> message about risk !</p>",
+ "securityCategory": "sql-injection",
+ "vulnerabilityDescription": "<p>This a <strong>strong</strong> message about vulnerability !</p>",
+ "vulnerabilityProbability": "HIGH",
+ },
+ "status": "REVIEWED",
+ "textRange": Object {
+ "endLine": 142,
+ "endOffset": 83,
+ "startLine": 142,
+ "startOffset": 26,
+ },
+ "updateDate": "2013-05-13T17:55:42+0200",
+ "users": Array [
+ Object {
+ "active": true,
+ "local": true,
+ "login": "assignee",
+ "name": "John Doe",
+ },
+ Object {
+ "active": true,
+ "local": true,
+ "login": "author",
+ "name": "John Doe",
+ },
+ ],
+ }
+ }
+ onStatusChange={[Function]}
+ />
+ <div
+ className="display-flex-end"
+ >
+ <div
+ className="display-inline-flex-center it__hs-assignee"
+ >
+ <div
+ className="text-bold big-spacer-right"
+ >
+ assignee:
+ </div>
+ <Connect(withCurrentUser(Assignee))
+ hotspot={
+ Object {
+ "assignee": "assignee",
+ "assigneeUser": Object {
+ "active": true,
+ "local": true,
+ "login": "assignee",
+ "name": "John Doe",
+ },
+ "author": "author",
+ "authorUser": Object {
+ "active": true,
+ "local": true,
+ "login": "author",
+ "name": "John Doe",
+ },
+ "canChangeStatus": true,
+ "changelog": Array [],
+ "comment": Array [],
+ "component": Object {
+ "key": "hotspot-component",
+ "longName": "Hotspot component long name",
+ "name": "Hotspot Component",
+ "path": "path/to/component",
+ "qualifier": "FIL",
+ },
+ "creationDate": "2013-05-13T17:55:41+0200",
+ "flows": Array [
+ Object {
+ "locations": Array [
+ Object {
+ "component": "main.js",
+ "textRange": Object {
+ "endLine": 2,
+ "endOffset": 2,
+ "startLine": 1,
+ "startOffset": 1,
+ },
+ },
+ ],
+ },
+ ],
+ "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123",
+ "line": 142,
+ "message": "'3' is a magic number.",
+ "project": Object {
+ "key": "hotspot-component",
+ "longName": "Hotspot component long name",
+ "name": "Hotspot Component",
+ "path": "path/to/component",
+ "qualifier": "TRK",
+ },
+ "resolution": "FIXED",
+ "rule": Object {
+ "fixRecommendations": "<p>This a <strong>strong</strong> message about fixing !</p>",
+ "key": "squid:S2077",
+ "name": "That rule",
+ "riskDescription": "<p>This a <strong>strong</strong> message about risk !</p>",
+ "securityCategory": "sql-injection",
+ "vulnerabilityDescription": "<p>This a <strong>strong</strong> message about vulnerability !</p>",
+ "vulnerabilityProbability": "HIGH",
+ },
+ "status": "REVIEWED",
+ "textRange": Object {
+ "endLine": 142,
+ "endOffset": 83,
+ "startLine": 142,
+ "startOffset": 26,
+ },
+ "updateDate": "2013-05-13T17:55:42+0200",
+ "users": Array [
+ Object {
+ "active": true,
+ "local": true,
+ "login": "assignee",
+ "name": "John Doe",
+ },
+ Object {
+ "active": true,
+ "local": true,
+ "login": "author",
+ "name": "John Doe",
+ },
+ ],
+ }
+ }
+ onAssigneeChange={[MockFunction]}
+ />
+ </div>
+ </div>
+ </div>
+</div>
+`;
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotPrimaryLocationBox-test.tsx.snap b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotPrimaryLocationBox-test.tsx.snap
index ed9097dff9f..ca9f922a126 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotPrimaryLocationBox-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotPrimaryLocationBox-test.tsx.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`should render correctly 1`] = `
+exports[`should render correctly: User logged in 1`] = `
<div
className="hotspot-primary-location display-flex-space-between display-flex-center padded-top padded-bottom big-padded-left big-padded-right hotspot-risk-exposure-HIGH"
>
@@ -10,10 +10,22 @@ exports[`should render correctly 1`] = `
'3' is a magic number.
</div>
<ButtonLink
- className="nowrap big-spacer-left"
+ className="nowrap big-spacer-left it__hs-add-comment"
onClick={[MockFunction]}
>
hotspots.comment.open
</ButtonLink>
</div>
`;
+
+exports[`should render correctly: User not logged in 1`] = `
+<div
+ className="hotspot-primary-location display-flex-space-between display-flex-center padded-top padded-bottom big-padded-left big-padded-right hotspot-risk-exposure-HIGH"
+>
+ <div
+ className="text-bold"
+ >
+ '3' is a magic number.
+ </div>
+</div>
+`;
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotSnippetContainer-test.tsx.snap b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotSnippetContainer-test.tsx.snap
index b2254d3d659..eae97ea5a08 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotSnippetContainer-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotSnippetContainer-test.tsx.snap
@@ -10,7 +10,28 @@ exports[`should render correctly 1`] = `
"name": "branch-6.7",
}
}
- displayProjectName={false}
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "my-project",
+ "name": "MyProject",
+ "qualifier": "TRK",
+ "qualityGate": Object {
+ "isDefault": true,
+ "key": "30",
+ "name": "Sonar way",
+ },
+ "qualityProfiles": Array [
+ Object {
+ "deleted": false,
+ "key": "my-qp",
+ "language": "ts",
+ "name": "Sonar way",
+ },
+ ],
+ "tags": Array [],
+ }
+ }
highlightedSymbols={Array []}
hotspot={
Object {
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotSnippetContainerRenderer-test.tsx.snap b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotSnippetContainerRenderer-test.tsx.snap
index 615601d690d..344601d5eb7 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotSnippetContainerRenderer-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotSnippetContainerRenderer-test.tsx.snap
@@ -7,40 +7,127 @@ exports[`should render correctly 1`] = `
>
hotspots.no_associated_lines
</p>
- <div
- className="bordered big-spacer-bottom"
- >
- <SourceViewerHeaderSlim
- branchLike={
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": true,
- "name": "master",
- }
+ <Connect(withCurrentUser(HotspotSnippetHeader))
+ branchLike={
+ Object {
+ "analysisDate": "2018-01-01",
+ "excludedFromPurge": true,
+ "isMain": true,
+ "name": "master",
}
- displayProjectName={true}
- expandable={false}
- linkToProject={false}
- loading={false}
- onExpand={[Function]}
- sourceViewerFile={
- Object {
- "key": "foo",
- "measures": Object {
- "coverage": "85.2",
- "duplicationDensity": "1.0",
- "issues": "12",
- "lines": "56",
+ }
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "my-project",
+ "name": "MyProject",
+ "qualifier": "TRK",
+ "qualityGate": Object {
+ "isDefault": true,
+ "key": "30",
+ "name": "Sonar way",
+ },
+ "qualityProfiles": Array [
+ Object {
+ "deleted": false,
+ "key": "my-qp",
+ "language": "ts",
+ "name": "Sonar way",
},
- "path": "foo/bar.ts",
- "project": "my-project",
- "projectName": "MyProject",
- "q": "FIL",
- "uuid": "foo-bar",
- }
+ ],
+ "tags": Array [],
}
- />
+ }
+ hotspot={
+ Object {
+ "assignee": "assignee",
+ "assigneeUser": Object {
+ "active": true,
+ "local": true,
+ "login": "assignee",
+ "name": "John Doe",
+ },
+ "author": "author",
+ "authorUser": Object {
+ "active": true,
+ "local": true,
+ "login": "author",
+ "name": "John Doe",
+ },
+ "canChangeStatus": true,
+ "changelog": Array [],
+ "comment": Array [],
+ "component": Object {
+ "key": "hotspot-component",
+ "longName": "Hotspot component long name",
+ "name": "Hotspot Component",
+ "path": "path/to/component",
+ "qualifier": "FIL",
+ },
+ "creationDate": "2013-05-13T17:55:41+0200",
+ "flows": Array [
+ Object {
+ "locations": Array [
+ Object {
+ "component": "main.js",
+ "textRange": Object {
+ "endLine": 2,
+ "endOffset": 2,
+ "startLine": 1,
+ "startOffset": 1,
+ },
+ },
+ ],
+ },
+ ],
+ "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123",
+ "line": 142,
+ "message": "'3' is a magic number.",
+ "project": Object {
+ "key": "hotspot-component",
+ "longName": "Hotspot component long name",
+ "name": "Hotspot Component",
+ "path": "path/to/component",
+ "qualifier": "TRK",
+ },
+ "resolution": "FIXED",
+ "rule": Object {
+ "fixRecommendations": "<p>This a <strong>strong</strong> message about fixing !</p>",
+ "key": "squid:S2077",
+ "name": "That rule",
+ "riskDescription": "<p>This a <strong>strong</strong> message about risk !</p>",
+ "securityCategory": "sql-injection",
+ "vulnerabilityDescription": "<p>This a <strong>strong</strong> message about vulnerability !</p>",
+ "vulnerabilityProbability": "HIGH",
+ },
+ "status": "REVIEWED",
+ "textRange": Object {
+ "endLine": 142,
+ "endOffset": 83,
+ "startLine": 142,
+ "startOffset": 26,
+ },
+ "updateDate": "2013-05-13T17:55:42+0200",
+ "users": Array [
+ Object {
+ "active": true,
+ "local": true,
+ "login": "assignee",
+ "name": "John Doe",
+ },
+ Object {
+ "active": true,
+ "local": true,
+ "login": "author",
+ "name": "John Doe",
+ },
+ ],
+ }
+ }
+ />
+ <div
+ className="bordered big-spacer-bottom"
+ >
<DeferredSpinner
className="big-spacer"
loading={false}
@@ -51,40 +138,127 @@ exports[`should render correctly 1`] = `
exports[`should render correctly: with sourcelines 1`] = `
<Fragment>
- <div
- className="bordered big-spacer-bottom"
- >
- <SourceViewerHeaderSlim
- branchLike={
- Object {
- "analysisDate": "2018-01-01",
- "excludedFromPurge": true,
- "isMain": true,
- "name": "master",
- }
+ <Connect(withCurrentUser(HotspotSnippetHeader))
+ branchLike={
+ Object {
+ "analysisDate": "2018-01-01",
+ "excludedFromPurge": true,
+ "isMain": true,
+ "name": "master",
}
- displayProjectName={true}
- expandable={false}
- linkToProject={false}
- loading={false}
- onExpand={[Function]}
- sourceViewerFile={
- Object {
- "key": "foo",
- "measures": Object {
- "coverage": "85.2",
- "duplicationDensity": "1.0",
- "issues": "12",
- "lines": "56",
+ }
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "my-project",
+ "name": "MyProject",
+ "qualifier": "TRK",
+ "qualityGate": Object {
+ "isDefault": true,
+ "key": "30",
+ "name": "Sonar way",
+ },
+ "qualityProfiles": Array [
+ Object {
+ "deleted": false,
+ "key": "my-qp",
+ "language": "ts",
+ "name": "Sonar way",
},
- "path": "foo/bar.ts",
- "project": "my-project",
- "projectName": "MyProject",
- "q": "FIL",
- "uuid": "foo-bar",
- }
+ ],
+ "tags": Array [],
}
- />
+ }
+ hotspot={
+ Object {
+ "assignee": "assignee",
+ "assigneeUser": Object {
+ "active": true,
+ "local": true,
+ "login": "assignee",
+ "name": "John Doe",
+ },
+ "author": "author",
+ "authorUser": Object {
+ "active": true,
+ "local": true,
+ "login": "author",
+ "name": "John Doe",
+ },
+ "canChangeStatus": true,
+ "changelog": Array [],
+ "comment": Array [],
+ "component": Object {
+ "key": "hotspot-component",
+ "longName": "Hotspot component long name",
+ "name": "Hotspot Component",
+ "path": "path/to/component",
+ "qualifier": "FIL",
+ },
+ "creationDate": "2013-05-13T17:55:41+0200",
+ "flows": Array [
+ Object {
+ "locations": Array [
+ Object {
+ "component": "main.js",
+ "textRange": Object {
+ "endLine": 2,
+ "endOffset": 2,
+ "startLine": 1,
+ "startOffset": 1,
+ },
+ },
+ ],
+ },
+ ],
+ "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123",
+ "line": 142,
+ "message": "'3' is a magic number.",
+ "project": Object {
+ "key": "hotspot-component",
+ "longName": "Hotspot component long name",
+ "name": "Hotspot Component",
+ "path": "path/to/component",
+ "qualifier": "TRK",
+ },
+ "resolution": "FIXED",
+ "rule": Object {
+ "fixRecommendations": "<p>This a <strong>strong</strong> message about fixing !</p>",
+ "key": "squid:S2077",
+ "name": "That rule",
+ "riskDescription": "<p>This a <strong>strong</strong> message about risk !</p>",
+ "securityCategory": "sql-injection",
+ "vulnerabilityDescription": "<p>This a <strong>strong</strong> message about vulnerability !</p>",
+ "vulnerabilityProbability": "HIGH",
+ },
+ "status": "REVIEWED",
+ "textRange": Object {
+ "endLine": 142,
+ "endOffset": 83,
+ "startLine": 142,
+ "startOffset": 26,
+ },
+ "updateDate": "2013-05-13T17:55:42+0200",
+ "users": Array [
+ Object {
+ "active": true,
+ "local": true,
+ "login": "assignee",
+ "name": "John Doe",
+ },
+ Object {
+ "active": true,
+ "local": true,
+ "login": "author",
+ "name": "John Doe",
+ },
+ ],
+ }
+ }
+ />
+ <div
+ className="bordered big-spacer-bottom"
+ >
<DeferredSpinner
className="big-spacer"
loading={false}
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotSnippetHeader-test.tsx.snap b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotSnippetHeader-test.tsx.snap
new file mode 100644
index 00000000000..8d201200035
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotSnippetHeader-test.tsx.snap
@@ -0,0 +1,137 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly: user logged in 1`] = `
+<Styled(div)>
+ <div
+ className="display-flex-row"
+ >
+ <Styled(div)>
+ <QualifierIcon
+ qualifier="FIL"
+ />
+
+ <span>
+ path/to/
+ </span>
+ <span
+ className="little-spacer-right"
+ >
+ component
+ </span>
+ <ClipboardIconButton
+ className="button-link link-no-underline"
+ copyValue="path/to/component"
+ />
+ </Styled(div)>
+ <div
+ className="dropdown spacer-right"
+ >
+ <HotspotOpenInIdeButton
+ hotspotKey="01fc972e-2a3c-433e-bcae-0bd7f88f5123"
+ projectKey="hotspot-component"
+ />
+ </div>
+ </div>
+ <ClipboardButton
+ copyValue="http://localhost/security_hotspots?id=my-project&hotspots=01fc972e-2a3c-433e-bcae-0bd7f88f5123"
+ >
+ <span>
+ hotspots.get_permalink
+ </span>
+ <LinkIcon
+ className="spacer-left"
+ />
+ </ClipboardButton>
+</Styled(div)>
+`;
+
+exports[`should render correctly: user logged in with project Name 1`] = `
+<Styled(div)>
+ <div
+ className="display-flex-row"
+ >
+ <Styled(div)>
+ <QualifierIcon
+ className="little-spacer-right"
+ qualifier="TRK"
+ />
+ <span
+ className="little-spacer-right"
+ >
+ Hotspot Component
+ </span>
+ <QualifierIcon
+ qualifier="FIL"
+ />
+
+ <span>
+ path/to/
+ </span>
+ <span
+ className="little-spacer-right"
+ >
+ component
+ </span>
+ <ClipboardIconButton
+ className="button-link link-no-underline"
+ copyValue="path/to/component"
+ />
+ </Styled(div)>
+ <div
+ className="dropdown spacer-right"
+ >
+ <HotspotOpenInIdeButton
+ hotspotKey="01fc972e-2a3c-433e-bcae-0bd7f88f5123"
+ projectKey="hotspot-component"
+ />
+ </div>
+ </div>
+ <ClipboardButton
+ copyValue="http://localhost/security_hotspots?id=my-project&hotspots=01fc972e-2a3c-433e-bcae-0bd7f88f5123"
+ >
+ <span>
+ hotspots.get_permalink
+ </span>
+ <LinkIcon
+ className="spacer-left"
+ />
+ </ClipboardButton>
+</Styled(div)>
+`;
+
+exports[`should render correctly: user not logged in 1`] = `
+<Styled(div)>
+ <div
+ className="display-flex-row"
+ >
+ <Styled(div)>
+ <QualifierIcon
+ qualifier="FIL"
+ />
+
+ <span>
+ path/to/
+ </span>
+ <span
+ className="little-spacer-right"
+ >
+ component
+ </span>
+ <ClipboardIconButton
+ className="button-link link-no-underline"
+ copyValue="path/to/component"
+ />
+ </Styled(div)>
+ </div>
+ <ClipboardButton
+ copyValue="http://localhost/security_hotspots?id=my-project&hotspots=01fc972e-2a3c-433e-bcae-0bd7f88f5123"
+ >
+ <span>
+ hotspots.get_permalink
+ </span>
+ <LinkIcon
+ className="spacer-left"
+ />
+ </ClipboardButton>
+</Styled(div)>
+`;
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotViewer-test.tsx.snap b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotViewer-test.tsx.snap
index e9d02356247..0b61ad710a4 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotViewer-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotViewer-test.tsx.snap
@@ -34,13 +34,6 @@ exports[`should render correctly 1`] = `
onShowCommentForm={[Function]}
onSwitchFilterToStatusOfUpdatedHotspot={[Function]}
onUpdateHotspot={[Function]}
- securityCategories={
- Object {
- "cat1": Object {
- "title": "cat1",
- },
- }
- }
showStatusUpdateSuccessModal={false}
/>
`;
@@ -84,13 +77,6 @@ exports[`should render correctly 2`] = `
onShowCommentForm={[Function]}
onSwitchFilterToStatusOfUpdatedHotspot={[Function]}
onUpdateHotspot={[Function]}
- securityCategories={
- Object {
- "cat1": Object {
- "title": "cat1",
- },
- }
- }
showStatusUpdateSuccessModal={false}
/>
`;
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotViewerRenderer-test.tsx.snap b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotViewerRenderer-test.tsx.snap
index 780f88703c2..9947b643609 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotViewerRenderer-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotViewerRenderer-test.tsx.snap
@@ -8,305 +8,95 @@ exports[`should render correctly: anonymous user 1`] = `
<div
className="big-padded hotspot-content"
>
- <div
- className="huge-spacer-bottom display-flex-space-between"
- >
- <div
- className="display-flex-column"
- >
- <strong
- className="big big-spacer-right little-spacer-bottom"
- >
- '3' is a magic number.
- </strong>
- <div>
- <span
- className="note padded-right"
- >
- That rule
- </span>
- <Link
- className="small"
- onlyActiveOnIndex={false}
- style={Object {}}
- target="_blank"
- to={
- Object {
- "pathname": "/coding_rules",
- "query": Object {
- "open": "squid:S2077",
- "rule_key": "squid:S2077",
- },
- }
- }
- >
- squid:S2077
- </Link>
- </div>
- </div>
- <div
- className="display-flex-row flex-0"
- >
- <div
- className="dropdown spacer-right flex-1-0-auto"
- >
- <Button
- className="it__hs-add-comment"
- onClick={[MockFunction]}
- >
- hotspots.comment.open
- </Button>
- </div>
- <div
- className="dropdown spacer-right flex-1-0-auto"
- >
- <HotspotOpenInIdeButton
- hotspotKey="01fc972e-2a3c-433e-bcae-0bd7f88f5123"
- projectKey="hotspot-component"
- />
- </div>
- <ClipboardButton
- className="flex-1-0-auto"
- copyValue="http://localhost/security_hotspots?id=my-project&branch=branch-6.7&hotspots=01fc972e-2a3c-433e-bcae-0bd7f88f5123"
- >
- <LinkIcon
- className="spacer-right"
- />
- <span>
- hotspots.get_permalink
- </span>
- </ClipboardButton>
- </div>
- </div>
- <div
- className="huge-spacer-bottom display-flex-row display-flex-space-between"
- >
- <div
- className="hotspot-information display-flex-column display-flex-space-between"
- >
- <div
- className="display-flex-center"
- >
- <span
- className="big-spacer-right"
- >
- category
- </span>
- <strong
- className="nowrap"
- >
- SQL injection
- </strong>
- </div>
- <div
- className="display-flex-center"
- >
- <span
- className="big-spacer-right"
- >
- hotspots.risk_exposure
- </span>
- <div
- className="hotspot-risk-badge HIGH"
- >
- risk_exposure.HIGH
- </div>
- </div>
- <div
- className="display-flex-center it__hs-assignee"
- >
- <span
- className="big-spacer-right"
- >
- assignee
- </span>
- <div>
- <Connect(withCurrentUser(Assignee))
- hotspot={
+ <HotspotHeader
+ hotspot={
+ Object {
+ "assignee": "assignee",
+ "assigneeUser": Object {
+ "active": true,
+ "local": true,
+ "login": "assignee",
+ "name": "John Doe",
+ },
+ "author": "author",
+ "authorUser": Object {
+ "active": true,
+ "local": true,
+ "login": "author",
+ "name": "John Doe",
+ },
+ "canChangeStatus": true,
+ "changelog": Array [],
+ "comment": Array [],
+ "component": Object {
+ "key": "hotspot-component",
+ "longName": "Hotspot component long name",
+ "name": "Hotspot Component",
+ "path": "path/to/component",
+ "qualifier": "FIL",
+ },
+ "creationDate": "2013-05-13T17:55:41+0200",
+ "flows": Array [
+ Object {
+ "locations": Array [
Object {
- "assignee": "assignee",
- "assigneeUser": Object {
- "active": true,
- "local": true,
- "login": "assignee",
- "name": "John Doe",
- },
- "author": "author",
- "authorUser": Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
- },
- "canChangeStatus": true,
- "changelog": Array [],
- "comment": Array [],
- "component": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "FIL",
- },
- "creationDate": "2013-05-13T17:55:41+0200",
- "flows": Array [
- Object {
- "locations": Array [
- Object {
- "component": "main.js",
- "textRange": Object {
- "endLine": 2,
- "endOffset": 2,
- "startLine": 1,
- "startOffset": 1,
- },
- },
- ],
- },
- ],
- "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123",
- "line": 142,
- "message": "'3' is a magic number.",
- "project": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "TRK",
- },
- "resolution": "FIXED",
- "rule": Object {
- "fixRecommendations": "<p>This a <strong>strong</strong> message about fixing !</p>",
- "key": "squid:S2077",
- "name": "That rule",
- "riskDescription": "<p>This a <strong>strong</strong> message about risk !</p>",
- "securityCategory": "sql-injection",
- "vulnerabilityDescription": "<p>This a <strong>strong</strong> message about vulnerability !</p>",
- "vulnerabilityProbability": "HIGH",
- },
- "status": "REVIEWED",
+ "component": "main.js",
"textRange": Object {
- "endLine": 142,
- "endOffset": 83,
- "startLine": 142,
- "startOffset": 26,
+ "endLine": 2,
+ "endOffset": 2,
+ "startLine": 1,
+ "startOffset": 1,
},
- "updateDate": "2013-05-13T17:55:42+0200",
- "users": Array [
- Object {
- "active": true,
- "local": true,
- "login": "assignee",
- "name": "John Doe",
- },
- Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
- },
- ],
- }
- }
- onAssigneeChange={[MockFunction]}
- />
- </div>
- </div>
- </div>
- <div
- className="huge-spacer-left abs-width-400"
- >
- <Connect(withCurrentUser(Status))
- hotspot={
- Object {
- "assignee": "assignee",
- "assigneeUser": Object {
- "active": true,
- "local": true,
- "login": "assignee",
- "name": "John Doe",
- },
- "author": "author",
- "authorUser": Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
- },
- "canChangeStatus": true,
- "changelog": Array [],
- "comment": Array [],
- "component": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "FIL",
- },
- "creationDate": "2013-05-13T17:55:41+0200",
- "flows": Array [
- Object {
- "locations": Array [
- Object {
- "component": "main.js",
- "textRange": Object {
- "endLine": 2,
- "endOffset": 2,
- "startLine": 1,
- "startOffset": 1,
- },
- },
- ],
- },
- ],
- "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123",
- "line": 142,
- "message": "'3' is a magic number.",
- "project": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "TRK",
- },
- "resolution": "FIXED",
- "rule": Object {
- "fixRecommendations": "<p>This a <strong>strong</strong> message about fixing !</p>",
- "key": "squid:S2077",
- "name": "That rule",
- "riskDescription": "<p>This a <strong>strong</strong> message about risk !</p>",
- "securityCategory": "sql-injection",
- "vulnerabilityDescription": "<p>This a <strong>strong</strong> message about vulnerability !</p>",
- "vulnerabilityProbability": "HIGH",
- },
- "status": "REVIEWED",
- "textRange": Object {
- "endLine": 142,
- "endOffset": 83,
- "startLine": 142,
- "startOffset": 26,
- },
- "updateDate": "2013-05-13T17:55:42+0200",
- "users": Array [
- Object {
- "active": true,
- "local": true,
- "login": "assignee",
- "name": "John Doe",
- },
- Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
},
],
- }
- }
- onStatusChange={[Function]}
- />
- </div>
- </div>
+ },
+ ],
+ "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123",
+ "line": 142,
+ "message": "'3' is a magic number.",
+ "project": Object {
+ "key": "hotspot-component",
+ "longName": "Hotspot component long name",
+ "name": "Hotspot Component",
+ "path": "path/to/component",
+ "qualifier": "TRK",
+ },
+ "resolution": "FIXED",
+ "rule": Object {
+ "fixRecommendations": "<p>This a <strong>strong</strong> message about fixing !</p>",
+ "key": "squid:S2077",
+ "name": "That rule",
+ "riskDescription": "<p>This a <strong>strong</strong> message about risk !</p>",
+ "securityCategory": "sql-injection",
+ "vulnerabilityDescription": "<p>This a <strong>strong</strong> message about vulnerability !</p>",
+ "vulnerabilityProbability": "HIGH",
+ },
+ "status": "REVIEWED",
+ "textRange": Object {
+ "endLine": 142,
+ "endOffset": 83,
+ "startLine": 142,
+ "startOffset": 26,
+ },
+ "updateDate": "2013-05-13T17:55:42+0200",
+ "users": Array [
+ Object {
+ "active": true,
+ "local": true,
+ "login": "assignee",
+ "name": "John Doe",
+ },
+ Object {
+ "active": true,
+ "local": true,
+ "login": "author",
+ "name": "John Doe",
+ },
+ ],
+ }
+ }
+ onUpdateHotspot={[MockFunction]}
+ />
<HotspotSnippetContainer
component={
Object {
@@ -617,305 +407,95 @@ exports[`should render correctly: assignee without name 1`] = `
<div
className="big-padded hotspot-content"
>
- <div
- className="huge-spacer-bottom display-flex-space-between"
- >
- <div
- className="display-flex-column"
- >
- <strong
- className="big big-spacer-right little-spacer-bottom"
- >
- '3' is a magic number.
- </strong>
- <div>
- <span
- className="note padded-right"
- >
- That rule
- </span>
- <Link
- className="small"
- onlyActiveOnIndex={false}
- style={Object {}}
- target="_blank"
- to={
- Object {
- "pathname": "/coding_rules",
- "query": Object {
- "open": "squid:S2077",
- "rule_key": "squid:S2077",
- },
- }
- }
- >
- squid:S2077
- </Link>
- </div>
- </div>
- <div
- className="display-flex-row flex-0"
- >
- <div
- className="dropdown spacer-right flex-1-0-auto"
- >
- <Button
- className="it__hs-add-comment"
- onClick={[MockFunction]}
- >
- hotspots.comment.open
- </Button>
- </div>
- <div
- className="dropdown spacer-right flex-1-0-auto"
- >
- <HotspotOpenInIdeButton
- hotspotKey="01fc972e-2a3c-433e-bcae-0bd7f88f5123"
- projectKey="hotspot-component"
- />
- </div>
- <ClipboardButton
- className="flex-1-0-auto"
- copyValue="http://localhost/security_hotspots?id=my-project&branch=branch-6.7&hotspots=01fc972e-2a3c-433e-bcae-0bd7f88f5123"
- >
- <LinkIcon
- className="spacer-right"
- />
- <span>
- hotspots.get_permalink
- </span>
- </ClipboardButton>
- </div>
- </div>
- <div
- className="huge-spacer-bottom display-flex-row display-flex-space-between"
- >
- <div
- className="hotspot-information display-flex-column display-flex-space-between"
- >
- <div
- className="display-flex-center"
- >
- <span
- className="big-spacer-right"
- >
- category
- </span>
- <strong
- className="nowrap"
- >
- SQL injection
- </strong>
- </div>
- <div
- className="display-flex-center"
- >
- <span
- className="big-spacer-right"
- >
- hotspots.risk_exposure
- </span>
- <div
- className="hotspot-risk-badge HIGH"
- >
- risk_exposure.HIGH
- </div>
- </div>
- <div
- className="display-flex-center it__hs-assignee"
- >
- <span
- className="big-spacer-right"
- >
- assignee
- </span>
- <div>
- <Connect(withCurrentUser(Assignee))
- hotspot={
+ <HotspotHeader
+ hotspot={
+ Object {
+ "assignee": "assignee",
+ "assigneeUser": Object {
+ "active": true,
+ "local": true,
+ "login": "assignee_login",
+ "name": undefined,
+ },
+ "author": "author",
+ "authorUser": Object {
+ "active": true,
+ "local": true,
+ "login": "author",
+ "name": "John Doe",
+ },
+ "canChangeStatus": true,
+ "changelog": Array [],
+ "comment": Array [],
+ "component": Object {
+ "key": "hotspot-component",
+ "longName": "Hotspot component long name",
+ "name": "Hotspot Component",
+ "path": "path/to/component",
+ "qualifier": "FIL",
+ },
+ "creationDate": "2013-05-13T17:55:41+0200",
+ "flows": Array [
+ Object {
+ "locations": Array [
Object {
- "assignee": "assignee",
- "assigneeUser": Object {
- "active": true,
- "local": true,
- "login": "assignee_login",
- "name": undefined,
- },
- "author": "author",
- "authorUser": Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
- },
- "canChangeStatus": true,
- "changelog": Array [],
- "comment": Array [],
- "component": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "FIL",
- },
- "creationDate": "2013-05-13T17:55:41+0200",
- "flows": Array [
- Object {
- "locations": Array [
- Object {
- "component": "main.js",
- "textRange": Object {
- "endLine": 2,
- "endOffset": 2,
- "startLine": 1,
- "startOffset": 1,
- },
- },
- ],
- },
- ],
- "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123",
- "line": 142,
- "message": "'3' is a magic number.",
- "project": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "TRK",
- },
- "resolution": "FIXED",
- "rule": Object {
- "fixRecommendations": "<p>This a <strong>strong</strong> message about fixing !</p>",
- "key": "squid:S2077",
- "name": "That rule",
- "riskDescription": "<p>This a <strong>strong</strong> message about risk !</p>",
- "securityCategory": "sql-injection",
- "vulnerabilityDescription": "<p>This a <strong>strong</strong> message about vulnerability !</p>",
- "vulnerabilityProbability": "HIGH",
- },
- "status": "REVIEWED",
+ "component": "main.js",
"textRange": Object {
- "endLine": 142,
- "endOffset": 83,
- "startLine": 142,
- "startOffset": 26,
+ "endLine": 2,
+ "endOffset": 2,
+ "startLine": 1,
+ "startOffset": 1,
},
- "updateDate": "2013-05-13T17:55:42+0200",
- "users": Array [
- Object {
- "active": true,
- "local": true,
- "login": "assignee",
- "name": "John Doe",
- },
- Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
- },
- ],
- }
- }
- onAssigneeChange={[MockFunction]}
- />
- </div>
- </div>
- </div>
- <div
- className="huge-spacer-left abs-width-400"
- >
- <Connect(withCurrentUser(Status))
- hotspot={
- Object {
- "assignee": "assignee",
- "assigneeUser": Object {
- "active": true,
- "local": true,
- "login": "assignee_login",
- "name": undefined,
- },
- "author": "author",
- "authorUser": Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
- },
- "canChangeStatus": true,
- "changelog": Array [],
- "comment": Array [],
- "component": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "FIL",
- },
- "creationDate": "2013-05-13T17:55:41+0200",
- "flows": Array [
- Object {
- "locations": Array [
- Object {
- "component": "main.js",
- "textRange": Object {
- "endLine": 2,
- "endOffset": 2,
- "startLine": 1,
- "startOffset": 1,
- },
- },
- ],
- },
- ],
- "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123",
- "line": 142,
- "message": "'3' is a magic number.",
- "project": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "TRK",
- },
- "resolution": "FIXED",
- "rule": Object {
- "fixRecommendations": "<p>This a <strong>strong</strong> message about fixing !</p>",
- "key": "squid:S2077",
- "name": "That rule",
- "riskDescription": "<p>This a <strong>strong</strong> message about risk !</p>",
- "securityCategory": "sql-injection",
- "vulnerabilityDescription": "<p>This a <strong>strong</strong> message about vulnerability !</p>",
- "vulnerabilityProbability": "HIGH",
- },
- "status": "REVIEWED",
- "textRange": Object {
- "endLine": 142,
- "endOffset": 83,
- "startLine": 142,
- "startOffset": 26,
- },
- "updateDate": "2013-05-13T17:55:42+0200",
- "users": Array [
- Object {
- "active": true,
- "local": true,
- "login": "assignee",
- "name": "John Doe",
- },
- Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
},
],
- }
- }
- onStatusChange={[Function]}
- />
- </div>
- </div>
+ },
+ ],
+ "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123",
+ "line": 142,
+ "message": "'3' is a magic number.",
+ "project": Object {
+ "key": "hotspot-component",
+ "longName": "Hotspot component long name",
+ "name": "Hotspot Component",
+ "path": "path/to/component",
+ "qualifier": "TRK",
+ },
+ "resolution": "FIXED",
+ "rule": Object {
+ "fixRecommendations": "<p>This a <strong>strong</strong> message about fixing !</p>",
+ "key": "squid:S2077",
+ "name": "That rule",
+ "riskDescription": "<p>This a <strong>strong</strong> message about risk !</p>",
+ "securityCategory": "sql-injection",
+ "vulnerabilityDescription": "<p>This a <strong>strong</strong> message about vulnerability !</p>",
+ "vulnerabilityProbability": "HIGH",
+ },
+ "status": "REVIEWED",
+ "textRange": Object {
+ "endLine": 142,
+ "endOffset": 83,
+ "startLine": 142,
+ "startOffset": 26,
+ },
+ "updateDate": "2013-05-13T17:55:42+0200",
+ "users": Array [
+ Object {
+ "active": true,
+ "local": true,
+ "login": "assignee",
+ "name": "John Doe",
+ },
+ Object {
+ "active": true,
+ "local": true,
+ "login": "author",
+ "name": "John Doe",
+ },
+ ],
+ }
+ }
+ onUpdateHotspot={[MockFunction]}
+ />
<HotspotSnippetContainer
component={
Object {
@@ -1226,305 +806,95 @@ exports[`should render correctly: default 1`] = `
<div
className="big-padded hotspot-content"
>
- <div
- className="huge-spacer-bottom display-flex-space-between"
- >
- <div
- className="display-flex-column"
- >
- <strong
- className="big big-spacer-right little-spacer-bottom"
- >
- '3' is a magic number.
- </strong>
- <div>
- <span
- className="note padded-right"
- >
- That rule
- </span>
- <Link
- className="small"
- onlyActiveOnIndex={false}
- style={Object {}}
- target="_blank"
- to={
- Object {
- "pathname": "/coding_rules",
- "query": Object {
- "open": "squid:S2077",
- "rule_key": "squid:S2077",
- },
- }
- }
- >
- squid:S2077
- </Link>
- </div>
- </div>
- <div
- className="display-flex-row flex-0"
- >
- <div
- className="dropdown spacer-right flex-1-0-auto"
- >
- <Button
- className="it__hs-add-comment"
- onClick={[MockFunction]}
- >
- hotspots.comment.open
- </Button>
- </div>
- <div
- className="dropdown spacer-right flex-1-0-auto"
- >
- <HotspotOpenInIdeButton
- hotspotKey="01fc972e-2a3c-433e-bcae-0bd7f88f5123"
- projectKey="hotspot-component"
- />
- </div>
- <ClipboardButton
- className="flex-1-0-auto"
- copyValue="http://localhost/security_hotspots?id=my-project&branch=branch-6.7&hotspots=01fc972e-2a3c-433e-bcae-0bd7f88f5123"
- >
- <LinkIcon
- className="spacer-right"
- />
- <span>
- hotspots.get_permalink
- </span>
- </ClipboardButton>
- </div>
- </div>
- <div
- className="huge-spacer-bottom display-flex-row display-flex-space-between"
- >
- <div
- className="hotspot-information display-flex-column display-flex-space-between"
- >
- <div
- className="display-flex-center"
- >
- <span
- className="big-spacer-right"
- >
- category
- </span>
- <strong
- className="nowrap"
- >
- SQL injection
- </strong>
- </div>
- <div
- className="display-flex-center"
- >
- <span
- className="big-spacer-right"
- >
- hotspots.risk_exposure
- </span>
- <div
- className="hotspot-risk-badge HIGH"
- >
- risk_exposure.HIGH
- </div>
- </div>
- <div
- className="display-flex-center it__hs-assignee"
- >
- <span
- className="big-spacer-right"
- >
- assignee
- </span>
- <div>
- <Connect(withCurrentUser(Assignee))
- hotspot={
+ <HotspotHeader
+ hotspot={
+ Object {
+ "assignee": "assignee",
+ "assigneeUser": Object {
+ "active": true,
+ "local": true,
+ "login": "assignee",
+ "name": "John Doe",
+ },
+ "author": "author",
+ "authorUser": Object {
+ "active": true,
+ "local": true,
+ "login": "author",
+ "name": "John Doe",
+ },
+ "canChangeStatus": true,
+ "changelog": Array [],
+ "comment": Array [],
+ "component": Object {
+ "key": "hotspot-component",
+ "longName": "Hotspot component long name",
+ "name": "Hotspot Component",
+ "path": "path/to/component",
+ "qualifier": "FIL",
+ },
+ "creationDate": "2013-05-13T17:55:41+0200",
+ "flows": Array [
+ Object {
+ "locations": Array [
Object {
- "assignee": "assignee",
- "assigneeUser": Object {
- "active": true,
- "local": true,
- "login": "assignee",
- "name": "John Doe",
- },
- "author": "author",
- "authorUser": Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
- },
- "canChangeStatus": true,
- "changelog": Array [],
- "comment": Array [],
- "component": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "FIL",
- },
- "creationDate": "2013-05-13T17:55:41+0200",
- "flows": Array [
- Object {
- "locations": Array [
- Object {
- "component": "main.js",
- "textRange": Object {
- "endLine": 2,
- "endOffset": 2,
- "startLine": 1,
- "startOffset": 1,
- },
- },
- ],
- },
- ],
- "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123",
- "line": 142,
- "message": "'3' is a magic number.",
- "project": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "TRK",
- },
- "resolution": "FIXED",
- "rule": Object {
- "fixRecommendations": "<p>This a <strong>strong</strong> message about fixing !</p>",
- "key": "squid:S2077",
- "name": "That rule",
- "riskDescription": "<p>This a <strong>strong</strong> message about risk !</p>",
- "securityCategory": "sql-injection",
- "vulnerabilityDescription": "<p>This a <strong>strong</strong> message about vulnerability !</p>",
- "vulnerabilityProbability": "HIGH",
- },
- "status": "REVIEWED",
+ "component": "main.js",
"textRange": Object {
- "endLine": 142,
- "endOffset": 83,
- "startLine": 142,
- "startOffset": 26,
+ "endLine": 2,
+ "endOffset": 2,
+ "startLine": 1,
+ "startOffset": 1,
},
- "updateDate": "2013-05-13T17:55:42+0200",
- "users": Array [
- Object {
- "active": true,
- "local": true,
- "login": "assignee",
- "name": "John Doe",
- },
- Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
- },
- ],
- }
- }
- onAssigneeChange={[MockFunction]}
- />
- </div>
- </div>
- </div>
- <div
- className="huge-spacer-left abs-width-400"
- >
- <Connect(withCurrentUser(Status))
- hotspot={
- Object {
- "assignee": "assignee",
- "assigneeUser": Object {
- "active": true,
- "local": true,
- "login": "assignee",
- "name": "John Doe",
- },
- "author": "author",
- "authorUser": Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
- },
- "canChangeStatus": true,
- "changelog": Array [],
- "comment": Array [],
- "component": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "FIL",
- },
- "creationDate": "2013-05-13T17:55:41+0200",
- "flows": Array [
- Object {
- "locations": Array [
- Object {
- "component": "main.js",
- "textRange": Object {
- "endLine": 2,
- "endOffset": 2,
- "startLine": 1,
- "startOffset": 1,
- },
- },
- ],
},
],
- "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123",
- "line": 142,
- "message": "'3' is a magic number.",
- "project": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "TRK",
- },
- "resolution": "FIXED",
- "rule": Object {
- "fixRecommendations": "<p>This a <strong>strong</strong> message about fixing !</p>",
- "key": "squid:S2077",
- "name": "That rule",
- "riskDescription": "<p>This a <strong>strong</strong> message about risk !</p>",
- "securityCategory": "sql-injection",
- "vulnerabilityDescription": "<p>This a <strong>strong</strong> message about vulnerability !</p>",
- "vulnerabilityProbability": "HIGH",
- },
- "status": "REVIEWED",
- "textRange": Object {
- "endLine": 142,
- "endOffset": 83,
- "startLine": 142,
- "startOffset": 26,
- },
- "updateDate": "2013-05-13T17:55:42+0200",
- "users": Array [
- Object {
- "active": true,
- "local": true,
- "login": "assignee",
- "name": "John Doe",
- },
- Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
- },
- ],
- }
- }
- onStatusChange={[Function]}
- />
- </div>
- </div>
+ },
+ ],
+ "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123",
+ "line": 142,
+ "message": "'3' is a magic number.",
+ "project": Object {
+ "key": "hotspot-component",
+ "longName": "Hotspot component long name",
+ "name": "Hotspot Component",
+ "path": "path/to/component",
+ "qualifier": "TRK",
+ },
+ "resolution": "FIXED",
+ "rule": Object {
+ "fixRecommendations": "<p>This a <strong>strong</strong> message about fixing !</p>",
+ "key": "squid:S2077",
+ "name": "That rule",
+ "riskDescription": "<p>This a <strong>strong</strong> message about risk !</p>",
+ "securityCategory": "sql-injection",
+ "vulnerabilityDescription": "<p>This a <strong>strong</strong> message about vulnerability !</p>",
+ "vulnerabilityProbability": "HIGH",
+ },
+ "status": "REVIEWED",
+ "textRange": Object {
+ "endLine": 142,
+ "endOffset": 83,
+ "startLine": 142,
+ "startOffset": 26,
+ },
+ "updateDate": "2013-05-13T17:55:42+0200",
+ "users": Array [
+ Object {
+ "active": true,
+ "local": true,
+ "login": "assignee",
+ "name": "John Doe",
+ },
+ Object {
+ "active": true,
+ "local": true,
+ "login": "author",
+ "name": "John Doe",
+ },
+ ],
+ }
+ }
+ onUpdateHotspot={[MockFunction]}
+ />
<HotspotSnippetContainer
component={
Object {
@@ -1835,305 +1205,95 @@ exports[`should render correctly: deleted assignee 1`] = `
<div
className="big-padded hotspot-content"
>
- <div
- className="huge-spacer-bottom display-flex-space-between"
- >
- <div
- className="display-flex-column"
- >
- <strong
- className="big big-spacer-right little-spacer-bottom"
- >
- '3' is a magic number.
- </strong>
- <div>
- <span
- className="note padded-right"
- >
- That rule
- </span>
- <Link
- className="small"
- onlyActiveOnIndex={false}
- style={Object {}}
- target="_blank"
- to={
- Object {
- "pathname": "/coding_rules",
- "query": Object {
- "open": "squid:S2077",
- "rule_key": "squid:S2077",
- },
- }
- }
- >
- squid:S2077
- </Link>
- </div>
- </div>
- <div
- className="display-flex-row flex-0"
- >
- <div
- className="dropdown spacer-right flex-1-0-auto"
- >
- <Button
- className="it__hs-add-comment"
- onClick={[MockFunction]}
- >
- hotspots.comment.open
- </Button>
- </div>
- <div
- className="dropdown spacer-right flex-1-0-auto"
- >
- <HotspotOpenInIdeButton
- hotspotKey="01fc972e-2a3c-433e-bcae-0bd7f88f5123"
- projectKey="hotspot-component"
- />
- </div>
- <ClipboardButton
- className="flex-1-0-auto"
- copyValue="http://localhost/security_hotspots?id=my-project&branch=branch-6.7&hotspots=01fc972e-2a3c-433e-bcae-0bd7f88f5123"
- >
- <LinkIcon
- className="spacer-right"
- />
- <span>
- hotspots.get_permalink
- </span>
- </ClipboardButton>
- </div>
- </div>
- <div
- className="huge-spacer-bottom display-flex-row display-flex-space-between"
- >
- <div
- className="hotspot-information display-flex-column display-flex-space-between"
- >
- <div
- className="display-flex-center"
- >
- <span
- className="big-spacer-right"
- >
- category
- </span>
- <strong
- className="nowrap"
- >
- SQL injection
- </strong>
- </div>
- <div
- className="display-flex-center"
- >
- <span
- className="big-spacer-right"
- >
- hotspots.risk_exposure
- </span>
- <div
- className="hotspot-risk-badge HIGH"
- >
- risk_exposure.HIGH
- </div>
- </div>
- <div
- className="display-flex-center it__hs-assignee"
- >
- <span
- className="big-spacer-right"
- >
- assignee
- </span>
- <div>
- <Connect(withCurrentUser(Assignee))
- hotspot={
+ <HotspotHeader
+ hotspot={
+ Object {
+ "assignee": "assignee",
+ "assigneeUser": Object {
+ "active": false,
+ "local": true,
+ "login": "john.doe",
+ "name": "John Doe",
+ },
+ "author": "author",
+ "authorUser": Object {
+ "active": true,
+ "local": true,
+ "login": "author",
+ "name": "John Doe",
+ },
+ "canChangeStatus": true,
+ "changelog": Array [],
+ "comment": Array [],
+ "component": Object {
+ "key": "hotspot-component",
+ "longName": "Hotspot component long name",
+ "name": "Hotspot Component",
+ "path": "path/to/component",
+ "qualifier": "FIL",
+ },
+ "creationDate": "2013-05-13T17:55:41+0200",
+ "flows": Array [
+ Object {
+ "locations": Array [
Object {
- "assignee": "assignee",
- "assigneeUser": Object {
- "active": false,
- "local": true,
- "login": "john.doe",
- "name": "John Doe",
- },
- "author": "author",
- "authorUser": Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
- },
- "canChangeStatus": true,
- "changelog": Array [],
- "comment": Array [],
- "component": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "FIL",
- },
- "creationDate": "2013-05-13T17:55:41+0200",
- "flows": Array [
- Object {
- "locations": Array [
- Object {
- "component": "main.js",
- "textRange": Object {
- "endLine": 2,
- "endOffset": 2,
- "startLine": 1,
- "startOffset": 1,
- },
- },
- ],
- },
- ],
- "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123",
- "line": 142,
- "message": "'3' is a magic number.",
- "project": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "TRK",
- },
- "resolution": "FIXED",
- "rule": Object {
- "fixRecommendations": "<p>This a <strong>strong</strong> message about fixing !</p>",
- "key": "squid:S2077",
- "name": "That rule",
- "riskDescription": "<p>This a <strong>strong</strong> message about risk !</p>",
- "securityCategory": "sql-injection",
- "vulnerabilityDescription": "<p>This a <strong>strong</strong> message about vulnerability !</p>",
- "vulnerabilityProbability": "HIGH",
- },
- "status": "REVIEWED",
+ "component": "main.js",
"textRange": Object {
- "endLine": 142,
- "endOffset": 83,
- "startLine": 142,
- "startOffset": 26,
+ "endLine": 2,
+ "endOffset": 2,
+ "startLine": 1,
+ "startOffset": 1,
},
- "updateDate": "2013-05-13T17:55:42+0200",
- "users": Array [
- Object {
- "active": true,
- "local": true,
- "login": "assignee",
- "name": "John Doe",
- },
- Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
- },
- ],
- }
- }
- onAssigneeChange={[MockFunction]}
- />
- </div>
- </div>
- </div>
- <div
- className="huge-spacer-left abs-width-400"
- >
- <Connect(withCurrentUser(Status))
- hotspot={
- Object {
- "assignee": "assignee",
- "assigneeUser": Object {
- "active": false,
- "local": true,
- "login": "john.doe",
- "name": "John Doe",
- },
- "author": "author",
- "authorUser": Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
- },
- "canChangeStatus": true,
- "changelog": Array [],
- "comment": Array [],
- "component": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "FIL",
- },
- "creationDate": "2013-05-13T17:55:41+0200",
- "flows": Array [
- Object {
- "locations": Array [
- Object {
- "component": "main.js",
- "textRange": Object {
- "endLine": 2,
- "endOffset": 2,
- "startLine": 1,
- "startOffset": 1,
- },
- },
- ],
- },
- ],
- "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123",
- "line": 142,
- "message": "'3' is a magic number.",
- "project": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "TRK",
- },
- "resolution": "FIXED",
- "rule": Object {
- "fixRecommendations": "<p>This a <strong>strong</strong> message about fixing !</p>",
- "key": "squid:S2077",
- "name": "That rule",
- "riskDescription": "<p>This a <strong>strong</strong> message about risk !</p>",
- "securityCategory": "sql-injection",
- "vulnerabilityDescription": "<p>This a <strong>strong</strong> message about vulnerability !</p>",
- "vulnerabilityProbability": "HIGH",
- },
- "status": "REVIEWED",
- "textRange": Object {
- "endLine": 142,
- "endOffset": 83,
- "startLine": 142,
- "startOffset": 26,
- },
- "updateDate": "2013-05-13T17:55:42+0200",
- "users": Array [
- Object {
- "active": true,
- "local": true,
- "login": "assignee",
- "name": "John Doe",
- },
- Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
},
],
- }
- }
- onStatusChange={[Function]}
- />
- </div>
- </div>
+ },
+ ],
+ "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123",
+ "line": 142,
+ "message": "'3' is a magic number.",
+ "project": Object {
+ "key": "hotspot-component",
+ "longName": "Hotspot component long name",
+ "name": "Hotspot Component",
+ "path": "path/to/component",
+ "qualifier": "TRK",
+ },
+ "resolution": "FIXED",
+ "rule": Object {
+ "fixRecommendations": "<p>This a <strong>strong</strong> message about fixing !</p>",
+ "key": "squid:S2077",
+ "name": "That rule",
+ "riskDescription": "<p>This a <strong>strong</strong> message about risk !</p>",
+ "securityCategory": "sql-injection",
+ "vulnerabilityDescription": "<p>This a <strong>strong</strong> message about vulnerability !</p>",
+ "vulnerabilityProbability": "HIGH",
+ },
+ "status": "REVIEWED",
+ "textRange": Object {
+ "endLine": 142,
+ "endOffset": 83,
+ "startLine": 142,
+ "startOffset": 26,
+ },
+ "updateDate": "2013-05-13T17:55:42+0200",
+ "users": Array [
+ Object {
+ "active": true,
+ "local": true,
+ "login": "assignee",
+ "name": "John Doe",
+ },
+ Object {
+ "active": true,
+ "local": true,
+ "login": "author",
+ "name": "John Doe",
+ },
+ ],
+ }
+ }
+ onUpdateHotspot={[MockFunction]}
+ />
<HotspotSnippetContainer
component={
Object {
@@ -2457,305 +1617,95 @@ exports[`should render correctly: show success modal 1`] = `
<div
className="big-padded hotspot-content"
>
- <div
- className="huge-spacer-bottom display-flex-space-between"
- >
- <div
- className="display-flex-column"
- >
- <strong
- className="big big-spacer-right little-spacer-bottom"
- >
- '3' is a magic number.
- </strong>
- <div>
- <span
- className="note padded-right"
- >
- That rule
- </span>
- <Link
- className="small"
- onlyActiveOnIndex={false}
- style={Object {}}
- target="_blank"
- to={
- Object {
- "pathname": "/coding_rules",
- "query": Object {
- "open": "squid:S2077",
- "rule_key": "squid:S2077",
- },
- }
- }
- >
- squid:S2077
- </Link>
- </div>
- </div>
- <div
- className="display-flex-row flex-0"
- >
- <div
- className="dropdown spacer-right flex-1-0-auto"
- >
- <Button
- className="it__hs-add-comment"
- onClick={[MockFunction]}
- >
- hotspots.comment.open
- </Button>
- </div>
- <div
- className="dropdown spacer-right flex-1-0-auto"
- >
- <HotspotOpenInIdeButton
- hotspotKey="01fc972e-2a3c-433e-bcae-0bd7f88f5123"
- projectKey="hotspot-component"
- />
- </div>
- <ClipboardButton
- className="flex-1-0-auto"
- copyValue="http://localhost/security_hotspots?id=my-project&branch=branch-6.7&hotspots=01fc972e-2a3c-433e-bcae-0bd7f88f5123"
- >
- <LinkIcon
- className="spacer-right"
- />
- <span>
- hotspots.get_permalink
- </span>
- </ClipboardButton>
- </div>
- </div>
- <div
- className="huge-spacer-bottom display-flex-row display-flex-space-between"
- >
- <div
- className="hotspot-information display-flex-column display-flex-space-between"
- >
- <div
- className="display-flex-center"
- >
- <span
- className="big-spacer-right"
- >
- category
- </span>
- <strong
- className="nowrap"
- >
- SQL injection
- </strong>
- </div>
- <div
- className="display-flex-center"
- >
- <span
- className="big-spacer-right"
- >
- hotspots.risk_exposure
- </span>
- <div
- className="hotspot-risk-badge HIGH"
- >
- risk_exposure.HIGH
- </div>
- </div>
- <div
- className="display-flex-center it__hs-assignee"
- >
- <span
- className="big-spacer-right"
- >
- assignee
- </span>
- <div>
- <Connect(withCurrentUser(Assignee))
- hotspot={
+ <HotspotHeader
+ hotspot={
+ Object {
+ "assignee": "assignee",
+ "assigneeUser": Object {
+ "active": true,
+ "local": true,
+ "login": "assignee",
+ "name": "John Doe",
+ },
+ "author": "author",
+ "authorUser": Object {
+ "active": true,
+ "local": true,
+ "login": "author",
+ "name": "John Doe",
+ },
+ "canChangeStatus": true,
+ "changelog": Array [],
+ "comment": Array [],
+ "component": Object {
+ "key": "hotspot-component",
+ "longName": "Hotspot component long name",
+ "name": "Hotspot Component",
+ "path": "path/to/component",
+ "qualifier": "FIL",
+ },
+ "creationDate": "2013-05-13T17:55:41+0200",
+ "flows": Array [
+ Object {
+ "locations": Array [
Object {
- "assignee": "assignee",
- "assigneeUser": Object {
- "active": true,
- "local": true,
- "login": "assignee",
- "name": "John Doe",
- },
- "author": "author",
- "authorUser": Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
- },
- "canChangeStatus": true,
- "changelog": Array [],
- "comment": Array [],
- "component": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "FIL",
- },
- "creationDate": "2013-05-13T17:55:41+0200",
- "flows": Array [
- Object {
- "locations": Array [
- Object {
- "component": "main.js",
- "textRange": Object {
- "endLine": 2,
- "endOffset": 2,
- "startLine": 1,
- "startOffset": 1,
- },
- },
- ],
- },
- ],
- "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123",
- "line": 142,
- "message": "'3' is a magic number.",
- "project": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "TRK",
- },
- "resolution": "FIXED",
- "rule": Object {
- "fixRecommendations": "<p>This a <strong>strong</strong> message about fixing !</p>",
- "key": "squid:S2077",
- "name": "That rule",
- "riskDescription": "<p>This a <strong>strong</strong> message about risk !</p>",
- "securityCategory": "sql-injection",
- "vulnerabilityDescription": "<p>This a <strong>strong</strong> message about vulnerability !</p>",
- "vulnerabilityProbability": "HIGH",
- },
- "status": "REVIEWED",
+ "component": "main.js",
"textRange": Object {
- "endLine": 142,
- "endOffset": 83,
- "startLine": 142,
- "startOffset": 26,
+ "endLine": 2,
+ "endOffset": 2,
+ "startLine": 1,
+ "startOffset": 1,
},
- "updateDate": "2013-05-13T17:55:42+0200",
- "users": Array [
- Object {
- "active": true,
- "local": true,
- "login": "assignee",
- "name": "John Doe",
- },
- Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
- },
- ],
- }
- }
- onAssigneeChange={[MockFunction]}
- />
- </div>
- </div>
- </div>
- <div
- className="huge-spacer-left abs-width-400"
- >
- <Connect(withCurrentUser(Status))
- hotspot={
- Object {
- "assignee": "assignee",
- "assigneeUser": Object {
- "active": true,
- "local": true,
- "login": "assignee",
- "name": "John Doe",
- },
- "author": "author",
- "authorUser": Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
- },
- "canChangeStatus": true,
- "changelog": Array [],
- "comment": Array [],
- "component": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "FIL",
- },
- "creationDate": "2013-05-13T17:55:41+0200",
- "flows": Array [
- Object {
- "locations": Array [
- Object {
- "component": "main.js",
- "textRange": Object {
- "endLine": 2,
- "endOffset": 2,
- "startLine": 1,
- "startOffset": 1,
- },
- },
- ],
- },
- ],
- "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123",
- "line": 142,
- "message": "'3' is a magic number.",
- "project": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "TRK",
- },
- "resolution": "FIXED",
- "rule": Object {
- "fixRecommendations": "<p>This a <strong>strong</strong> message about fixing !</p>",
- "key": "squid:S2077",
- "name": "That rule",
- "riskDescription": "<p>This a <strong>strong</strong> message about risk !</p>",
- "securityCategory": "sql-injection",
- "vulnerabilityDescription": "<p>This a <strong>strong</strong> message about vulnerability !</p>",
- "vulnerabilityProbability": "HIGH",
- },
- "status": "REVIEWED",
- "textRange": Object {
- "endLine": 142,
- "endOffset": 83,
- "startLine": 142,
- "startOffset": 26,
- },
- "updateDate": "2013-05-13T17:55:42+0200",
- "users": Array [
- Object {
- "active": true,
- "local": true,
- "login": "assignee",
- "name": "John Doe",
- },
- Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
},
],
- }
- }
- onStatusChange={[Function]}
- />
- </div>
- </div>
+ },
+ ],
+ "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123",
+ "line": 142,
+ "message": "'3' is a magic number.",
+ "project": Object {
+ "key": "hotspot-component",
+ "longName": "Hotspot component long name",
+ "name": "Hotspot Component",
+ "path": "path/to/component",
+ "qualifier": "TRK",
+ },
+ "resolution": "FIXED",
+ "rule": Object {
+ "fixRecommendations": "<p>This a <strong>strong</strong> message about fixing !</p>",
+ "key": "squid:S2077",
+ "name": "That rule",
+ "riskDescription": "<p>This a <strong>strong</strong> message about risk !</p>",
+ "securityCategory": "sql-injection",
+ "vulnerabilityDescription": "<p>This a <strong>strong</strong> message about vulnerability !</p>",
+ "vulnerabilityProbability": "HIGH",
+ },
+ "status": "REVIEWED",
+ "textRange": Object {
+ "endLine": 142,
+ "endOffset": 83,
+ "startLine": 142,
+ "startOffset": 26,
+ },
+ "updateDate": "2013-05-13T17:55:42+0200",
+ "users": Array [
+ Object {
+ "active": true,
+ "local": true,
+ "login": "assignee",
+ "name": "John Doe",
+ },
+ Object {
+ "active": true,
+ "local": true,
+ "login": "author",
+ "name": "John Doe",
+ },
+ ],
+ }
+ }
+ onUpdateHotspot={[MockFunction]}
+ />
<HotspotSnippetContainer
component={
Object {
@@ -3066,305 +2016,95 @@ exports[`should render correctly: unassigned 1`] = `
<div
className="big-padded hotspot-content"
>
- <div
- className="huge-spacer-bottom display-flex-space-between"
- >
- <div
- className="display-flex-column"
- >
- <strong
- className="big big-spacer-right little-spacer-bottom"
- >
- '3' is a magic number.
- </strong>
- <div>
- <span
- className="note padded-right"
- >
- That rule
- </span>
- <Link
- className="small"
- onlyActiveOnIndex={false}
- style={Object {}}
- target="_blank"
- to={
- Object {
- "pathname": "/coding_rules",
- "query": Object {
- "open": "squid:S2077",
- "rule_key": "squid:S2077",
- },
- }
- }
- >
- squid:S2077
- </Link>
- </div>
- </div>
- <div
- className="display-flex-row flex-0"
- >
- <div
- className="dropdown spacer-right flex-1-0-auto"
- >
- <Button
- className="it__hs-add-comment"
- onClick={[MockFunction]}
- >
- hotspots.comment.open
- </Button>
- </div>
- <div
- className="dropdown spacer-right flex-1-0-auto"
- >
- <HotspotOpenInIdeButton
- hotspotKey="01fc972e-2a3c-433e-bcae-0bd7f88f5123"
- projectKey="hotspot-component"
- />
- </div>
- <ClipboardButton
- className="flex-1-0-auto"
- copyValue="http://localhost/security_hotspots?id=my-project&branch=branch-6.7&hotspots=01fc972e-2a3c-433e-bcae-0bd7f88f5123"
- >
- <LinkIcon
- className="spacer-right"
- />
- <span>
- hotspots.get_permalink
- </span>
- </ClipboardButton>
- </div>
- </div>
- <div
- className="huge-spacer-bottom display-flex-row display-flex-space-between"
- >
- <div
- className="hotspot-information display-flex-column display-flex-space-between"
- >
- <div
- className="display-flex-center"
- >
- <span
- className="big-spacer-right"
- >
- category
- </span>
- <strong
- className="nowrap"
- >
- SQL injection
- </strong>
- </div>
- <div
- className="display-flex-center"
- >
- <span
- className="big-spacer-right"
- >
- hotspots.risk_exposure
- </span>
- <div
- className="hotspot-risk-badge HIGH"
- >
- risk_exposure.HIGH
- </div>
- </div>
- <div
- className="display-flex-center it__hs-assignee"
- >
- <span
- className="big-spacer-right"
- >
- assignee
- </span>
- <div>
- <Connect(withCurrentUser(Assignee))
- hotspot={
+ <HotspotHeader
+ hotspot={
+ Object {
+ "assignee": undefined,
+ "assigneeUser": Object {
+ "active": true,
+ "local": true,
+ "login": "assignee",
+ "name": "John Doe",
+ },
+ "author": "author",
+ "authorUser": Object {
+ "active": true,
+ "local": true,
+ "login": "author",
+ "name": "John Doe",
+ },
+ "canChangeStatus": true,
+ "changelog": Array [],
+ "comment": Array [],
+ "component": Object {
+ "key": "hotspot-component",
+ "longName": "Hotspot component long name",
+ "name": "Hotspot Component",
+ "path": "path/to/component",
+ "qualifier": "FIL",
+ },
+ "creationDate": "2013-05-13T17:55:41+0200",
+ "flows": Array [
+ Object {
+ "locations": Array [
Object {
- "assignee": undefined,
- "assigneeUser": Object {
- "active": true,
- "local": true,
- "login": "assignee",
- "name": "John Doe",
- },
- "author": "author",
- "authorUser": Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
- },
- "canChangeStatus": true,
- "changelog": Array [],
- "comment": Array [],
- "component": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "FIL",
- },
- "creationDate": "2013-05-13T17:55:41+0200",
- "flows": Array [
- Object {
- "locations": Array [
- Object {
- "component": "main.js",
- "textRange": Object {
- "endLine": 2,
- "endOffset": 2,
- "startLine": 1,
- "startOffset": 1,
- },
- },
- ],
- },
- ],
- "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123",
- "line": 142,
- "message": "'3' is a magic number.",
- "project": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "TRK",
- },
- "resolution": "FIXED",
- "rule": Object {
- "fixRecommendations": "<p>This a <strong>strong</strong> message about fixing !</p>",
- "key": "squid:S2077",
- "name": "That rule",
- "riskDescription": "<p>This a <strong>strong</strong> message about risk !</p>",
- "securityCategory": "sql-injection",
- "vulnerabilityDescription": "<p>This a <strong>strong</strong> message about vulnerability !</p>",
- "vulnerabilityProbability": "HIGH",
- },
- "status": "REVIEWED",
+ "component": "main.js",
"textRange": Object {
- "endLine": 142,
- "endOffset": 83,
- "startLine": 142,
- "startOffset": 26,
+ "endLine": 2,
+ "endOffset": 2,
+ "startLine": 1,
+ "startOffset": 1,
},
- "updateDate": "2013-05-13T17:55:42+0200",
- "users": Array [
- Object {
- "active": true,
- "local": true,
- "login": "assignee",
- "name": "John Doe",
- },
- Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
- },
- ],
- }
- }
- onAssigneeChange={[MockFunction]}
- />
- </div>
- </div>
- </div>
- <div
- className="huge-spacer-left abs-width-400"
- >
- <Connect(withCurrentUser(Status))
- hotspot={
- Object {
- "assignee": undefined,
- "assigneeUser": Object {
- "active": true,
- "local": true,
- "login": "assignee",
- "name": "John Doe",
- },
- "author": "author",
- "authorUser": Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
- },
- "canChangeStatus": true,
- "changelog": Array [],
- "comment": Array [],
- "component": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "FIL",
- },
- "creationDate": "2013-05-13T17:55:41+0200",
- "flows": Array [
- Object {
- "locations": Array [
- Object {
- "component": "main.js",
- "textRange": Object {
- "endLine": 2,
- "endOffset": 2,
- "startLine": 1,
- "startOffset": 1,
- },
- },
- ],
},
],
- "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123",
- "line": 142,
- "message": "'3' is a magic number.",
- "project": Object {
- "key": "hotspot-component",
- "longName": "Hotspot component long name",
- "name": "Hotspot Component",
- "path": "path/to/component",
- "qualifier": "TRK",
- },
- "resolution": "FIXED",
- "rule": Object {
- "fixRecommendations": "<p>This a <strong>strong</strong> message about fixing !</p>",
- "key": "squid:S2077",
- "name": "That rule",
- "riskDescription": "<p>This a <strong>strong</strong> message about risk !</p>",
- "securityCategory": "sql-injection",
- "vulnerabilityDescription": "<p>This a <strong>strong</strong> message about vulnerability !</p>",
- "vulnerabilityProbability": "HIGH",
- },
- "status": "REVIEWED",
- "textRange": Object {
- "endLine": 142,
- "endOffset": 83,
- "startLine": 142,
- "startOffset": 26,
- },
- "updateDate": "2013-05-13T17:55:42+0200",
- "users": Array [
- Object {
- "active": true,
- "local": true,
- "login": "assignee",
- "name": "John Doe",
- },
- Object {
- "active": true,
- "local": true,
- "login": "author",
- "name": "John Doe",
- },
- ],
- }
- }
- onStatusChange={[Function]}
- />
- </div>
- </div>
+ },
+ ],
+ "key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123",
+ "line": 142,
+ "message": "'3' is a magic number.",
+ "project": Object {
+ "key": "hotspot-component",
+ "longName": "Hotspot component long name",
+ "name": "Hotspot Component",
+ "path": "path/to/component",
+ "qualifier": "TRK",
+ },
+ "resolution": "FIXED",
+ "rule": Object {
+ "fixRecommendations": "<p>This a <strong>strong</strong> message about fixing !</p>",
+ "key": "squid:S2077",
+ "name": "That rule",
+ "riskDescription": "<p>This a <strong>strong</strong> message about risk !</p>",
+ "securityCategory": "sql-injection",
+ "vulnerabilityDescription": "<p>This a <strong>strong</strong> message about vulnerability !</p>",
+ "vulnerabilityProbability": "HIGH",
+ },
+ "status": "REVIEWED",
+ "textRange": Object {
+ "endLine": 142,
+ "endOffset": 83,
+ "startLine": 142,
+ "startOffset": 26,
+ },
+ "updateDate": "2013-05-13T17:55:42+0200",
+ "users": Array [
+ Object {
+ "active": true,
+ "local": true,
+ "login": "assignee",
+ "name": "John Doe",
+ },
+ Object {
+ "active": true,
+ "local": true,
+ "login": "author",
+ "name": "John Doe",
+ },
+ ],
+ }
+ }
+ onUpdateHotspot={[MockFunction]}
+ />
<HotspotSnippetContainer
component={
Object {
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 e11b207841a..30f2c0838ec 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
@@ -42,7 +42,7 @@ export default function AssigneeSelectionRenderer(props: HotspotAssigneeSelectRe
const { highlighted, loading, query, suggestedUsers } = props;
return (
- <>
+ <div className="dropdown">
<div className="display-flex-center">
<SearchBox
autoFocus={true}
@@ -55,32 +55,30 @@ export default function AssigneeSelectionRenderer(props: HotspotAssigneeSelectRe
</div>
{!loading && (
- <div className="position-relative">
- <DropdownOverlay noPadding={true} placement={PopupPlacement.BottomLeft}>
- <ul className="hotspot-assignee-search-results">
- {suggestedUsers &&
- suggestedUsers.map(suggestion => (
- <li
- className={classNames('padded', {
- active: highlighted && highlighted.login === suggestion.login
- })}
- key={suggestion.login}
- onClick={() => props.onSelect(suggestion)}>
- {suggestion.login && (
- <Avatar
- className="spacer-right"
- hash={suggestion.avatar}
- name={suggestion.name}
- size={16}
- />
- )}
- {suggestion.name}
- </li>
- ))}
- </ul>
- </DropdownOverlay>
- </div>
+ <DropdownOverlay noPadding={true} placement={PopupPlacement.BottomLeft}>
+ <ul className="hotspot-assignee-search-results">
+ {suggestedUsers &&
+ suggestedUsers.map(suggestion => (
+ <li
+ className={classNames('padded', {
+ active: highlighted && highlighted.login === suggestion.login
+ })}
+ key={suggestion.login}
+ onClick={() => props.onSelect(suggestion)}>
+ {suggestion.login && (
+ <Avatar
+ className="spacer-right"
+ hash={suggestion.avatar}
+ name={suggestion.name}
+ size={16}
+ />
+ )}
+ {suggestion.name}
+ </li>
+ ))}
+ </ul>
+ </DropdownOverlay>
)}
- </>
+ </div>
);
}
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/__snapshots__/AssigneeSelectionRenderer-test.tsx.snap b/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/__snapshots__/AssigneeSelectionRenderer-test.tsx.snap
index ee9b3ab78e3..087a963a423 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/__snapshots__/AssigneeSelectionRenderer-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/assignee/__tests__/__snapshots__/AssigneeSelectionRenderer-test.tsx.snap
@@ -1,7 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render correctly 1`] = `
-<Fragment>
+<div
+ className="dropdown"
+>
<div
className="display-flex-center"
>
@@ -12,23 +14,21 @@ exports[`should render correctly 1`] = `
placeholder="hotspots.assignee.select_user"
/>
</div>
- <div
- className="position-relative"
+ <DropdownOverlay
+ noPadding={true}
+ placement="bottom-left"
>
- <DropdownOverlay
- noPadding={true}
- placement="bottom-left"
- >
- <ul
- className="hotspot-assignee-search-results"
- />
- </DropdownOverlay>
- </div>
-</Fragment>
+ <ul
+ className="hotspot-assignee-search-results"
+ />
+ </DropdownOverlay>
+</div>
`;
exports[`should render correctly: loading 1`] = `
-<Fragment>
+<div
+ className="dropdown"
+>
<div
className="display-flex-center"
>
@@ -42,11 +42,13 @@ exports[`should render correctly: loading 1`] = `
className="spacer-left"
/>
</div>
-</Fragment>
+</div>
`;
exports[`should render correctly: open with results 1`] = `
-<Fragment>
+<div
+ className="dropdown"
+>
<div
className="display-flex-center"
>
@@ -57,42 +59,38 @@ exports[`should render correctly: open with results 1`] = `
placeholder="hotspots.assignee.select_user"
/>
</div>
- <div
- className="position-relative"
+ <DropdownOverlay
+ noPadding={true}
+ placement="bottom-left"
>
- <DropdownOverlay
- noPadding={true}
- placement="bottom-left"
+ <ul
+ className="hotspot-assignee-search-results"
>
- <ul
- className="hotspot-assignee-search-results"
+ <li
+ className="padded"
+ key="john.doe"
+ onClick={[Function]}
>
- <li
- className="padded"
- key="john.doe"
- onClick={[Function]}
- >
- <Connect(Avatar)
- className="spacer-right"
- name="John Doe"
- size={16}
- />
- John Doe
- </li>
- <li
- className="padded active"
- key="highlighted"
- onClick={[Function]}
- >
- <Connect(Avatar)
- className="spacer-right"
- name="John Doe"
- size={16}
- />
- John Doe
- </li>
- </ul>
- </DropdownOverlay>
- </div>
-</Fragment>
+ <Connect(Avatar)
+ className="spacer-right"
+ name="John Doe"
+ size={16}
+ />
+ John Doe
+ </li>
+ <li
+ className="padded active"
+ key="highlighted"
+ onClick={[Function]}
+ >
+ <Connect(Avatar)
+ className="spacer-right"
+ name="John Doe"
+ size={16}
+ />
+ John Doe
+ </li>
+ </ul>
+ </DropdownOverlay>
+</div>
`;
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 e14bafe3a64..15d0c8c918a 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
@@ -49,13 +49,13 @@ export function Status(props: StatusProps) {
const readonly = !hotspot.canChangeStatus || !isLoggedIn(currentUser);
return (
- <div>
+ <div className="display-flex-row display-flex-end">
<StatusDescription showTitle={true} statusOption={statusOption} />
<div className="spacer-top">
<Tooltip
overlay={readonly ? translate('hotspots.status.cannot_change_status') : null}
placement="bottom">
- <div className="dropdown display-inline-block">
+ <div className="dropdown">
<Toggler
closeOnClickOutside={true}
closeOnEscape={true}
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/status/StatusDescription.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/status/StatusDescription.tsx
index 0305d6245f7..53e6e2d83ec 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/status/StatusDescription.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/status/StatusDescription.tsx
@@ -17,6 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import styled from '@emotion/styled';
import * as React from 'react';
import { translate } from '../../../../helpers/l10n';
import { HotspotStatusOption } from '../../../../types/security-hotspots';
@@ -30,12 +31,16 @@ export default function StatusDescription(props: StatusDescriptionProps) {
const { statusOption, showTitle } = props;
return (
- <div>
+ <Container>
<h3>
{showTitle && `${translate('status')}: `}
- {translate('hotspots.status_option', statusOption)}
+ <div className="badge">{translate('hotspots.status_option', statusOption)}</div>
</h3>
<span>{translate('hotspots.status_option', statusOption, 'description')}</span>
- </div>
+ </Container>
);
}
+
+const Container = styled.div`
+ width: 350px;
+`;
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/status/__tests__/__snapshots__/Status-test.tsx.snap b/server/sonar-web/src/main/js/apps/security-hotspots/components/status/__tests__/__snapshots__/Status-test.tsx.snap
index 3dc6f22b2ce..9c014099366 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/status/__tests__/__snapshots__/Status-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/status/__tests__/__snapshots__/Status-test.tsx.snap
@@ -1,7 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render correctly: closed 1`] = `
-<div>
+<div
+ className="display-flex-row display-flex-end"
+>
<StatusDescription
showTitle={true}
statusOption="FIXED"
@@ -14,7 +16,7 @@ exports[`should render correctly: closed 1`] = `
placement="bottom"
>
<div
- className="dropdown display-inline-block"
+ className="dropdown"
>
<Toggler
closeOnClickOutside={true}
@@ -139,7 +141,9 @@ exports[`should render correctly: closed 1`] = `
`;
exports[`should render correctly: open 1`] = `
-<div>
+<div
+ className="display-flex-row display-flex-end"
+>
<StatusDescription
showTitle={true}
statusOption="FIXED"
@@ -152,7 +156,7 @@ exports[`should render correctly: open 1`] = `
placement="bottom"
>
<div
- className="dropdown display-inline-block"
+ className="dropdown"
>
<Toggler
closeOnClickOutside={true}
@@ -277,7 +281,9 @@ exports[`should render correctly: open 1`] = `
`;
exports[`should render correctly: readonly 1`] = `
-<div>
+<div
+ className="display-flex-row display-flex-end"
+>
<StatusDescription
showTitle={true}
statusOption="FIXED"
@@ -290,7 +296,7 @@ exports[`should render correctly: readonly 1`] = `
placement="bottom"
>
<div
- className="dropdown display-inline-block"
+ className="dropdown"
>
<Toggler
closeOnClickOutside={true}
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/status/__tests__/__snapshots__/StatusDescription-test.tsx.snap b/server/sonar-web/src/main/js/apps/security-hotspots/components/status/__tests__/__snapshots__/StatusDescription-test.tsx.snap
index b77051910de..1422872bae4 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/status/__tests__/__snapshots__/StatusDescription-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/status/__tests__/__snapshots__/StatusDescription-test.tsx.snap
@@ -1,24 +1,32 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render correctly 1`] = `
-<div>
+<Styled(div)>
<h3>
- hotspots.status_option.TO_REVIEW
+ <div
+ className="badge"
+ >
+ hotspots.status_option.TO_REVIEW
+ </div>
</h3>
<span>
hotspots.status_option.TO_REVIEW.description
</span>
-</div>
+</Styled(div)>
`;
exports[`should render correctly: with title 1`] = `
-<div>
+<Styled(div)>
<h3>
status:
- hotspots.status_option.TO_REVIEW
+ <div
+ className="badge"
+ >
+ hotspots.status_option.TO_REVIEW
+ </div>
</h3>
<span>
hotspots.status_option.TO_REVIEW.description
</span>
-</div>
+</Styled(div)>
`;