@@ -188,16 +188,15 @@ describe('getHotspotReviewHistory', () => { | |||
}); | |||
const reviewHistory = getHotspotReviewHistory(hotspot); | |||
expect(reviewHistory.history.length).toBe(4); | |||
expect(reviewHistory.functionalCount).toBe(3); | |||
expect(reviewHistory.history[0]).toEqual( | |||
expect(reviewHistory.length).toBe(4); | |||
expect(reviewHistory[0]).toEqual( | |||
expect.objectContaining({ | |||
type: ReviewHistoryType.Creation, | |||
date: hotspot.creationDate, | |||
user: hotspot.authorUser | |||
}) | |||
); | |||
expect(reviewHistory.history[1]).toEqual( | |||
expect(reviewHistory[1]).toEqual( | |||
expect.objectContaining({ | |||
type: ReviewHistoryType.Comment, | |||
date: commentElement.createdAt, | |||
@@ -205,7 +204,7 @@ describe('getHotspotReviewHistory', () => { | |||
html: commentElement.htmlText | |||
}) | |||
); | |||
expect(reviewHistory.history[2]).toEqual( | |||
expect(reviewHistory[2]).toEqual( | |||
expect.objectContaining({ | |||
type: ReviewHistoryType.Comment, | |||
date: commentElement1.createdAt, | |||
@@ -213,7 +212,7 @@ describe('getHotspotReviewHistory', () => { | |||
html: commentElement1.htmlText | |||
}) | |||
); | |||
expect(reviewHistory.history[3]).toEqual( | |||
expect(reviewHistory[3]).toEqual( | |||
expect.objectContaining({ | |||
type: ReviewHistoryType.Diff, | |||
date: changelogElement.creationDate, |
@@ -17,83 +17,76 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as classNames from 'classnames'; | |||
import { sanitize } from 'dompurify'; | |||
import * as React from 'react'; | |||
import { translate, translateWithParameters } from 'sonar-ui-common/helpers/l10n'; | |||
import DateTimeFormatter from '../../../components/intl/DateTimeFormatter'; | |||
import IssueChangelogDiff from '../../../components/issue/components/IssueChangelogDiff'; | |||
import Avatar from '../../../components/ui/Avatar'; | |||
import { Hotspot, ReviewHistoryElement, ReviewHistoryType } from '../../../types/security-hotspots'; | |||
import HotspotViewerReviewHistoryTabCommentBox from './HotspotViewerReviewHistoryTabCommentBox'; | |||
import { Hotspot, ReviewHistoryType } from '../../../types/security-hotspots'; | |||
import { getHotspotReviewHistory } from '../utils'; | |||
export interface HotspotViewerReviewHistoryTabProps { | |||
history: ReviewHistoryElement[]; | |||
export interface HotspotReviewHistoryProps { | |||
hotspot: Hotspot; | |||
onUpdateHotspot: () => void; | |||
} | |||
export default function HotspotViewerReviewHistoryTab(props: HotspotViewerReviewHistoryTabProps) { | |||
const { history, hotspot } = props; | |||
export default function HotspotReviewHistory(props: HotspotReviewHistoryProps) { | |||
const reviewHistory = getHotspotReviewHistory(props.hotspot); | |||
return ( | |||
<div className="padded"> | |||
{history.map((elt, historyIndex) => ( | |||
<React.Fragment key={historyIndex}> | |||
{historyIndex > 0 && <hr />} | |||
<div className="padded"> | |||
<> | |||
{reviewHistory.map((historyElt, historyIndex) => { | |||
const { user, type, diffs, date, html } = historyElt; | |||
return ( | |||
<div | |||
className={classNames('padded', { 'bordered-top': historyIndex > 0 })} | |||
key={historyIndex}> | |||
<div className="display-flex-center"> | |||
{elt.user.name && ( | |||
{user.name && ( | |||
<> | |||
<Avatar | |||
className="little-spacer-right" | |||
hash={elt.user.avatar} | |||
name={elt.user.name} | |||
hash={user.avatar} | |||
name={user.name} | |||
size={20} | |||
/> | |||
<strong> | |||
{elt.user.active | |||
? elt.user.name | |||
: translateWithParameters('user.x_deleted', elt.user.name)} | |||
{user.active ? user.name : translateWithParameters('user.x_deleted', user.name)} | |||
</strong> | |||
{elt.type === ReviewHistoryType.Creation && ( | |||
{type === ReviewHistoryType.Creation && ( | |||
<span className="little-spacer-left"> | |||
{translate('hotspots.tabs.review_history.created')} | |||
{translate('hotspots.review_history.created')} | |||
</span> | |||
)} | |||
{elt.type === ReviewHistoryType.Comment && ( | |||
{type === ReviewHistoryType.Comment && ( | |||
<span className="little-spacer-left"> | |||
{translate('hotspots.tabs.review_history.comment.added')} | |||
{translate('hotspots.review_history.comment_added')} | |||
</span> | |||
)} | |||
<span className="little-spacer-left little-spacer-right">-</span> | |||
</> | |||
)} | |||
<DateTimeFormatter date={elt.date} /> | |||
<DateTimeFormatter date={date} /> | |||
</div> | |||
{elt.type === ReviewHistoryType.Diff && elt.diffs && ( | |||
{type === ReviewHistoryType.Diff && diffs && ( | |||
<div className="spacer-top"> | |||
{elt.diffs.map((diff, diffIndex) => ( | |||
{diffs.map((diff, diffIndex) => ( | |||
<IssueChangelogDiff diff={diff} key={diffIndex} /> | |||
))} | |||
</div> | |||
)} | |||
{elt.type === ReviewHistoryType.Comment && elt.html && ( | |||
{type === ReviewHistoryType.Comment && html && ( | |||
<div | |||
className="spacer-top markdown" | |||
dangerouslySetInnerHTML={{ __html: sanitize(elt.html) }} | |||
dangerouslySetInnerHTML={{ __html: sanitize(html) }} | |||
/> | |||
)} | |||
</div> | |||
</React.Fragment> | |||
))} | |||
<hr /> | |||
<HotspotViewerReviewHistoryTabCommentBox | |||
hotspot={hotspot} | |||
onUpdateHotspot={props.onUpdateHotspot} | |||
/> | |||
</div> | |||
); | |||
})} | |||
</> | |||
); | |||
} |
@@ -0,0 +1,131 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as classNames from 'classnames'; | |||
import * as React from 'react'; | |||
import { Button, ResetButtonLink } from 'sonar-ui-common/components/controls/buttons'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { commentSecurityHotspot } from '../../../api/security-hotspots'; | |||
import MarkdownTips from '../../../components/common/MarkdownTips'; | |||
import { isLoggedIn } from '../../../helpers/users'; | |||
import { Hotspot } from '../../../types/security-hotspots'; | |||
import HotspotReviewHistory from './HotspotReviewHistory'; | |||
interface Props { | |||
currentUser: T.CurrentUser; | |||
hotspot: Hotspot; | |||
commentTextRef: React.RefObject<HTMLTextAreaElement>; | |||
commentVisible: boolean; | |||
onCommentUpdate: () => void; | |||
onOpenComment: () => void; | |||
onCloseComment: () => void; | |||
} | |||
interface State { | |||
comment: string; | |||
} | |||
export default class HotspotReviewHistoryAndComments extends React.PureComponent<Props, State> { | |||
constructor(props: Props) { | |||
super(props); | |||
this.state = { | |||
comment: '' | |||
}; | |||
} | |||
componentDidUpdate(prevProps: Props) { | |||
if (prevProps.hotspot !== this.props.hotspot) { | |||
this.setState({ | |||
comment: '' | |||
}); | |||
} | |||
} | |||
handleCommentChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => { | |||
this.setState({ comment: event.target.value }); | |||
}; | |||
handleCloseComment = () => { | |||
this.setState({ comment: '' }); | |||
this.props.onCloseComment(); | |||
}; | |||
handleSubmitComment = () => { | |||
return commentSecurityHotspot(this.props.hotspot.key, this.state.comment).then(() => { | |||
this.setState({ comment: '' }); | |||
this.props.onCloseComment(); | |||
this.props.onCommentUpdate(); | |||
}); | |||
}; | |||
render() { | |||
const { currentUser, hotspot, commentTextRef, commentVisible } = this.props; | |||
const { comment } = this.state; | |||
return ( | |||
<> | |||
<h1>{translate('hotspot.section.activity')}</h1> | |||
<div className="padded"> | |||
<HotspotReviewHistory hotspot={hotspot} /> | |||
{isLoggedIn(currentUser) && ( | |||
<> | |||
<hr /> | |||
<div className="big-spacer-top"> | |||
<Button | |||
className={classNames({ invisible: commentVisible })} | |||
id="hotspot-comment-box-display" | |||
onClick={this.props.onOpenComment}> | |||
{translate('hotspots.comment.open')} | |||
</Button> | |||
<div className={classNames({ invisible: !commentVisible })}> | |||
<div className="little-spacer-bottom">{translate('hotspots.comment.field')}</div> | |||
<textarea | |||
className="form-field fixed-width width-100 spacer-bottom" | |||
onChange={this.handleCommentChange} | |||
ref={commentTextRef} | |||
rows={2} | |||
value={comment} | |||
/> | |||
<div className="display-flex-space-between display-flex-center "> | |||
<MarkdownTips className="huge-spacer-bottom" /> | |||
<div> | |||
<Button | |||
className="huge-spacer-bottom" | |||
id="hotspot-comment-box-submit" | |||
onClick={this.handleSubmitComment}> | |||
{translate('hotspots.comment.submit')} | |||
</Button> | |||
<ResetButtonLink | |||
className="spacer-left huge-spacer-bottom" | |||
id="hotspot-comment-box-cancel" | |||
onClick={this.handleCloseComment}> | |||
{translate('cancel')} | |||
</ResetButtonLink> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</> | |||
)} | |||
</div> | |||
</> | |||
); | |||
} | |||
} |
@@ -19,6 +19,7 @@ | |||
*/ | |||
import * as React from 'react'; | |||
import { scrollToElement } from 'sonar-ui-common/helpers/scrolling'; | |||
import { getSecurityHotspotDetails } from '../../../api/security-hotspots'; | |||
import { BranchLike } from '../../../types/branch-like'; | |||
import { Hotspot } from '../../../types/security-hotspots'; | |||
@@ -35,21 +36,34 @@ interface Props { | |||
interface State { | |||
hotspot?: Hotspot; | |||
loading: boolean; | |||
commentVisible: boolean; | |||
} | |||
export default class HotspotViewer extends React.PureComponent<Props, State> { | |||
mounted = false; | |||
state: State = { loading: false }; | |||
state: State; | |||
commentTextRef: React.RefObject<HTMLTextAreaElement>; | |||
parentScrollRef: React.RefObject<HTMLDivElement>; | |||
constructor(props: Props) { | |||
super(props); | |||
this.commentTextRef = React.createRef<HTMLTextAreaElement>(); | |||
this.parentScrollRef = React.createRef<HTMLDivElement>(); | |||
this.state = { loading: false, commentVisible: false }; | |||
} | |||
componentDidMount() { | |||
this.mounted = true; | |||
this.fetchHotspot(); | |||
} | |||
componentDidUpdate(prevProps: Props) { | |||
componentDidUpdate(prevProps: Props, prevState: State) { | |||
if (prevProps.hotspotKey !== this.props.hotspotKey) { | |||
this.fetchHotspot(); | |||
} | |||
if (this.commentTextRef.current && !prevState.commentVisible && this.state.commentVisible) { | |||
this.commentTextRef.current.focus({ preventScroll: true }); | |||
} | |||
} | |||
componentWillUnmount() { | |||
@@ -76,17 +90,40 @@ export default class HotspotViewer extends React.PureComponent<Props, State> { | |||
}); | |||
}; | |||
handleOpenComment = () => { | |||
this.setState({ commentVisible: true }); | |||
if (this.commentTextRef.current) { | |||
// Edge case when the comment is already open and unfocus. | |||
this.commentTextRef.current.focus({ preventScroll: true }); | |||
} | |||
if (this.commentTextRef.current && this.parentScrollRef.current) { | |||
scrollToElement(this.commentTextRef.current, { | |||
parent: this.parentScrollRef.current, | |||
bottomOffset: 100 | |||
}); | |||
} | |||
}; | |||
handleCloseComment = () => { | |||
this.setState({ commentVisible: false }); | |||
}; | |||
render() { | |||
const { branchLike, component, securityCategories } = this.props; | |||
const { hotspot, loading } = this.state; | |||
const { hotspot, loading, commentVisible } = this.state; | |||
return ( | |||
<HotspotViewerRenderer | |||
branchLike={branchLike} | |||
component={component} | |||
commentTextRef={this.commentTextRef} | |||
commentVisible={commentVisible} | |||
hotspot={hotspot} | |||
loading={loading} | |||
onCloseComment={this.handleCloseComment} | |||
onOpenComment={this.handleOpenComment} | |||
onUpdateHotspot={this.handleHotspotUpdate} | |||
parentScrollRef={this.parentScrollRef} | |||
securityCategories={securityCategories} | |||
/> | |||
); |
@@ -19,16 +19,20 @@ | |||
*/ | |||
import * as classNames from 'classnames'; | |||
import * as React from 'react'; | |||
import { Button } from 'sonar-ui-common/components/controls/buttons'; | |||
import { ClipboardButton } from 'sonar-ui-common/components/controls/clipboard'; | |||
import LinkIcon from 'sonar-ui-common/components/icons/LinkIcon'; | |||
import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { getPathUrlAsString } from 'sonar-ui-common/helpers/urls'; | |||
import { withCurrentUser } from '../../../components/hoc/withCurrentUser'; | |||
import { getBranchLikeQuery } from '../../../helpers/branch-like'; | |||
import { getComponentSecurityHotspotsUrl } from '../../../helpers/urls'; | |||
import { isLoggedIn } from '../../../helpers/users'; | |||
import { BranchLike } from '../../../types/branch-like'; | |||
import { Hotspot } from '../../../types/security-hotspots'; | |||
import Assignee from './assignee/Assignee'; | |||
import HotspotReviewHistoryAndComments from './HotspotReviewHistoryAndComments'; | |||
import HotspotSnippetContainer from './HotspotSnippetContainer'; | |||
import './HotspotViewer.css'; | |||
import HotspotViewerTabs from './HotspotViewerTabs'; | |||
@@ -37,14 +41,30 @@ import Status from './status/Status'; | |||
export interface HotspotViewerRendererProps { | |||
branchLike?: BranchLike; | |||
component: T.Component; | |||
currentUser: T.CurrentUser; | |||
hotspot?: Hotspot; | |||
loading: boolean; | |||
commentVisible: boolean; | |||
commentTextRef: React.RefObject<HTMLTextAreaElement>; | |||
onOpenComment: () => void; | |||
onCloseComment: () => void; | |||
onUpdateHotspot: () => Promise<void>; | |||
parentScrollRef: React.RefObject<HTMLDivElement>; | |||
securityCategories: T.StandardSecurityCategories; | |||
} | |||
export default function HotspotViewerRenderer(props: HotspotViewerRendererProps) { | |||
const { branchLike, component, hotspot, loading, securityCategories } = props; | |||
export function HotspotViewerRenderer(props: HotspotViewerRendererProps) { | |||
const { | |||
branchLike, | |||
component, | |||
currentUser, | |||
hotspot, | |||
loading, | |||
securityCategories, | |||
commentTextRef, | |||
commentVisible, | |||
parentScrollRef | |||
} = props; | |||
const permalink = getPathUrlAsString( | |||
getComponentSecurityHotspotsUrl(component.key, { | |||
@@ -57,13 +77,22 @@ export default function HotspotViewerRenderer(props: HotspotViewerRendererProps) | |||
return ( | |||
<DeferredSpinner loading={loading}> | |||
{hotspot && ( | |||
<div className="big-padded"> | |||
<div className="big-padded hotspot-content" ref={parentScrollRef}> | |||
<div className="huge-spacer-bottom display-flex-space-between"> | |||
<strong className="big big-spacer-right">{hotspot.message}</strong> | |||
<ClipboardButton copyValue={permalink}> | |||
<LinkIcon className="spacer-right" /> | |||
<span>{translate('hotspots.get_permalink')}</span> | |||
</ClipboardButton> | |||
<div className="display-flex-row flex-0"> | |||
{isLoggedIn(currentUser) && ( | |||
<div className="dropdown spacer-right flex-1-0-auto"> | |||
<Button onClick={props.onOpenComment}> | |||
{translate('hotspots.comment.open')} | |||
</Button> | |||
</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"> | |||
@@ -97,9 +126,20 @@ export default function HotspotViewerRenderer(props: HotspotViewerRendererProps) | |||
</div> | |||
<HotspotSnippetContainer branchLike={branchLike} hotspot={hotspot} /> | |||
<HotspotViewerTabs hotspot={hotspot} onUpdateHotspot={props.onUpdateHotspot} /> | |||
<HotspotViewerTabs hotspot={hotspot} /> | |||
<HotspotReviewHistoryAndComments | |||
commentTextRef={commentTextRef} | |||
commentVisible={commentVisible} | |||
currentUser={currentUser} | |||
hotspot={hotspot} | |||
onCloseComment={props.onCloseComment} | |||
onCommentUpdate={props.onUpdateHotspot} | |||
onOpenComment={props.onOpenComment} | |||
/> | |||
</div> | |||
)} | |||
</DeferredSpinner> | |||
); | |||
} | |||
export default withCurrentUser(HotspotViewerRenderer); |
@@ -1,89 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { Button, ResetButtonLink } from 'sonar-ui-common/components/controls/buttons'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { commentSecurityHotspot } from '../../../api/security-hotspots'; | |||
import MarkdownTips from '../../../components/common/MarkdownTips'; | |||
import { Hotspot } from '../../../types/security-hotspots'; | |||
export interface HotspotViewerReviewHistoryTabCommentBoxProps { | |||
hotspot: Hotspot; | |||
onUpdateHotspot: () => void; | |||
} | |||
export default function HotspotViewerReviewHistoryTabCommentBox( | |||
props: HotspotViewerReviewHistoryTabCommentBoxProps | |||
) { | |||
const { hotspot } = props; | |||
const [comment, setComment] = React.useState(); | |||
const [isCommentBoxVisible, setCommentBoxVisibility] = React.useState(false); | |||
const onCancel = () => { | |||
setComment(null); | |||
setCommentBoxVisibility(false); | |||
}; | |||
const onComment = () => { | |||
return commentSecurityHotspot(hotspot.key, comment).then(() => { | |||
onCancel(); | |||
props.onUpdateHotspot(); | |||
}); | |||
}; | |||
return ( | |||
<div className="big-spacer-top"> | |||
{!isCommentBoxVisible ? ( | |||
<Button id="hotspot-comment-box-display" onClick={() => setCommentBoxVisibility(true)}> | |||
{translate('hotspots.tabs.review_history.comment.add')} | |||
</Button> | |||
) : ( | |||
<> | |||
<div className="little-spacer-bottom"> | |||
{translate('hotspots.tabs.review_history.comment.field')} | |||
</div> | |||
<textarea | |||
autoFocus={true} | |||
className="form-field fixed-width width-100 spacer-bottom" | |||
onChange={(event: React.ChangeEvent<HTMLTextAreaElement>) => | |||
setComment(event.target.value) | |||
} | |||
rows={2} | |||
/> | |||
<div className="display-flex-space-between display-flex-center"> | |||
<MarkdownTips /> | |||
<div> | |||
<Button id="hotspot-comment-box-submit" onClick={onComment}> | |||
{translate('hotspots.tabs.review_history.comment.submit')} | |||
</Button> | |||
<ResetButtonLink | |||
className="spacer-left" | |||
id="hotspot-comment-box-cancel" | |||
onClick={onCancel}> | |||
{translate('cancel')} | |||
</ResetButtonLink> | |||
</div> | |||
</div> | |||
</> | |||
)} | |||
</div> | |||
); | |||
} |
@@ -23,12 +23,9 @@ import BoxedTabs from 'sonar-ui-common/components/controls/BoxedTabs'; | |||
import Tab from 'sonar-ui-common/components/controls/Tabs'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { Hotspot } from '../../../types/security-hotspots'; | |||
import { getHotspotReviewHistory } from '../utils'; | |||
import HotspotViewerReviewHistoryTab from './HotspotViewerReviewHistoryTab'; | |||
interface Props { | |||
hotspot: Hotspot; | |||
onUpdateHotspot: () => void; | |||
} | |||
interface State { | |||
@@ -39,14 +36,13 @@ interface State { | |||
interface Tab { | |||
key: TabKeys; | |||
label: React.ReactNode; | |||
content: React.ReactNode; | |||
content: string; | |||
} | |||
export enum TabKeys { | |||
RiskDescription = 'risk', | |||
VulnerabilityDescription = 'vulnerability', | |||
FixRecommendation = 'fix', | |||
ReviewHistory = 'review' | |||
FixRecommendation = 'fix' | |||
} | |||
export default class HotspotViewerTabs extends React.PureComponent<Props, State> { | |||
@@ -77,7 +73,6 @@ export default class HotspotViewerTabs extends React.PureComponent<Props, State> | |||
computeTabs() { | |||
const { hotspot } = this.props; | |||
const hotspotReviewHistory = getHotspotReviewHistory(hotspot); | |||
return [ | |||
{ | |||
key: TabKeys.RiskDescription, | |||
@@ -93,26 +88,6 @@ export default class HotspotViewerTabs extends React.PureComponent<Props, State> | |||
key: TabKeys.FixRecommendation, | |||
label: translate('hotspots.tabs.fix_recommendations'), | |||
content: hotspot.rule.fixRecommendations || '' | |||
}, | |||
{ | |||
key: TabKeys.ReviewHistory, | |||
label: ( | |||
<> | |||
<span>{translate('hotspots.tabs.review_history')}</span> | |||
{hotspotReviewHistory.functionalCount > 0 && ( | |||
<span className="counter-badge spacer-left"> | |||
{hotspotReviewHistory.functionalCount} | |||
</span> | |||
)} | |||
</> | |||
), | |||
content: hotspotReviewHistory.history.length > 0 && ( | |||
<HotspotViewerReviewHistoryTab | |||
history={hotspotReviewHistory.history} | |||
hotspot={hotspot} | |||
onUpdateHotspot={this.props.onUpdateHotspot} | |||
/> | |||
) | |||
} | |||
].filter(tab => Boolean(tab.content)); | |||
} | |||
@@ -127,14 +102,10 @@ export default class HotspotViewerTabs extends React.PureComponent<Props, State> | |||
<> | |||
<BoxedTabs onSelect={this.handleSelectTabs} selected={currentTab.key} tabs={tabs} /> | |||
<div className="bordered huge-spacer-bottom"> | |||
{typeof currentTab.content === 'string' ? ( | |||
<div | |||
className="markdown big-padded" | |||
dangerouslySetInnerHTML={{ __html: sanitize(currentTab.content) }} | |||
/> | |||
) : ( | |||
<>{currentTab.content}</> | |||
)} | |||
<div | |||
className="markdown big-padded" | |||
dangerouslySetInnerHTML={{ __html: sanitize(currentTab.content) }} | |||
/> | |||
</div> | |||
</> | |||
); |
@@ -0,0 +1,69 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { mockHotspot } from '../../../../helpers/mocks/security-hotspots'; | |||
import { mockUser } from '../../../../helpers/testMocks'; | |||
import HotspotReviewHistory, { HotspotReviewHistoryProps } from '../HotspotReviewHistory'; | |||
it('should render correctly', () => { | |||
const wrapper = shallowRender(); | |||
expect(wrapper).toMatchSnapshot(); | |||
}); | |||
function shallowRender(props?: Partial<HotspotReviewHistoryProps>) { | |||
const changelogElement: T.IssueChangelog = { | |||
creationDate: '2018-10-01', | |||
isUserActive: true, | |||
user: 'me', | |||
userName: 'me-name', | |||
diffs: [ | |||
{ | |||
key: 'assign', | |||
newValue: 'me', | |||
oldValue: 'him' | |||
} | |||
] | |||
}; | |||
const commentElement = { | |||
key: 'comment-1', | |||
createdAt: '2018-09-10', | |||
htmlText: '<strong>TEST</strong>', | |||
markdown: '*TEST*', | |||
updatable: true, | |||
login: 'dude-1', | |||
user: mockUser({ login: 'dude-1' }) | |||
}; | |||
const commentElement1 = { | |||
key: 'comment-2', | |||
createdAt: '2018-09-11', | |||
htmlText: '<strong>TEST</strong>', | |||
markdown: '*TEST*', | |||
updatable: true, | |||
login: 'dude-2', | |||
user: mockUser({ login: 'dude-2' }) | |||
}; | |||
const hotspot = mockHotspot({ | |||
creationDate: '2018-09-01', | |||
changelog: [changelogElement], | |||
comment: [commentElement, commentElement1] | |||
}); | |||
return shallow(<HotspotReviewHistory hotspot={hotspot} {...props} />); | |||
} |
@@ -0,0 +1,111 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; | |||
import { commentSecurityHotspot } from '../../../../api/security-hotspots'; | |||
import { mockHotspot } from '../../../../helpers/mocks/security-hotspots'; | |||
import { mockCurrentUser } from '../../../../helpers/testMocks'; | |||
import { isLoggedIn } from '../../../../helpers/users'; | |||
import HotspotReviewHistoryAndComments from '../HotspotReviewHistoryAndComments'; | |||
jest.mock('../../../../api/security-hotspots', () => ({ | |||
commentSecurityHotspot: jest.fn().mockResolvedValue({}) | |||
})); | |||
jest.mock('../../../../helpers/users', () => ({ isLoggedIn: jest.fn(() => true) })); | |||
it('should render correctly', () => { | |||
const wrapper = shallowRender(); | |||
expect(wrapper).toMatchSnapshot(); | |||
}); | |||
it('should render correctly without user', () => { | |||
((isLoggedIn as any) as jest.Mock<boolean, [boolean]>).mockReturnValueOnce(false); | |||
const wrapper = shallowRender(); | |||
expect(wrapper).toMatchSnapshot(); | |||
}); | |||
it('should open comment form', () => { | |||
const wrapper = shallowRender(); | |||
wrapper.find('#hotspot-comment-box-display').simulate('click'); | |||
expect(wrapper.instance().props.onOpenComment).toHaveBeenCalled(); | |||
}); | |||
it('should submit comment', async () => { | |||
const mockApi = commentSecurityHotspot as jest.Mock; | |||
const hotspot = mockHotspot(); | |||
const wrapper = shallowRender({ hotspot, commentVisible: true }); | |||
mockApi.mockClear(); | |||
wrapper.instance().setState({ comment: 'Comment' }); | |||
wrapper.find('#hotspot-comment-box-submit').simulate('click'); | |||
await waitAndUpdate(wrapper); | |||
expect(mockApi).toHaveBeenCalledWith(hotspot.key, 'Comment'); | |||
expect(wrapper.state().comment).toBe(''); | |||
expect(wrapper.instance().props.onCloseComment).toHaveBeenCalledTimes(1); | |||
expect(wrapper.instance().props.onCommentUpdate).toHaveBeenCalledTimes(1); | |||
}); | |||
it('should cancel comment', () => { | |||
const mockApi = commentSecurityHotspot as jest.Mock; | |||
const hotspot = mockHotspot(); | |||
const wrapper = shallowRender({ hotspot, commentVisible: true }); | |||
wrapper.instance().setState({ comment: 'Comment' }); | |||
mockApi.mockClear(); | |||
wrapper.find('#hotspot-comment-box-cancel').simulate('click'); | |||
expect(mockApi).not.toHaveBeenCalled(); | |||
expect(wrapper.state().comment).toBe(''); | |||
expect(wrapper.instance().props.onCloseComment).toHaveBeenCalledTimes(1); | |||
}); | |||
it('should change comment', () => { | |||
const wrapper = shallowRender({ commentVisible: true }); | |||
wrapper.instance().setState({ comment: 'Comment' }); | |||
wrapper.find('textarea').simulate('change', { target: { value: 'Foo' } }); | |||
expect(wrapper.state().comment).toBe('Foo'); | |||
}); | |||
it('should reset on change hotspot', () => { | |||
const wrapper = shallowRender(); | |||
wrapper.setState({ comment: 'NOP' }); | |||
wrapper.setProps({ hotspot: mockHotspot() }); | |||
expect(wrapper.state().comment).toBe(''); | |||
}); | |||
function shallowRender(props?: Partial<HotspotReviewHistoryAndComments['props']>) { | |||
return shallow<HotspotReviewHistoryAndComments>( | |||
<HotspotReviewHistoryAndComments | |||
commentTextRef={React.createRef()} | |||
commentVisible={false} | |||
currentUser={mockCurrentUser()} | |||
hotspot={mockHotspot()} | |||
onCloseComment={jest.fn()} | |||
onCommentUpdate={jest.fn()} | |||
onOpenComment={jest.fn()} | |||
{...props} | |||
/> | |||
); | |||
} |
@@ -18,11 +18,14 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import { clone } from 'lodash'; | |||
import * as React from 'react'; | |||
import { scrollToElement } from 'sonar-ui-common/helpers/scrolling'; | |||
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; | |||
import { getSecurityHotspotDetails } from '../../../../api/security-hotspots'; | |||
import { mockComponent } from '../../../../helpers/testMocks'; | |||
import HotspotViewer from '../HotspotViewer'; | |||
import HotspotViewerRenderer from '../HotspotViewerRenderer'; | |||
const hotspotKey = 'hotspot-key'; | |||
@@ -30,6 +33,8 @@ jest.mock('../../../../api/security-hotspots', () => ({ | |||
getSecurityHotspotDetails: jest.fn().mockResolvedValue({ id: `I am a detailled hotspot` }) | |||
})); | |||
jest.mock('sonar-ui-common/helpers/scrolling', () => ({ scrollToElement: jest.fn() })); | |||
it('should render correctly', async () => { | |||
const wrapper = shallowRender(); | |||
expect(wrapper).toMatchSnapshot(); | |||
@@ -46,6 +51,56 @@ it('should render correctly', async () => { | |||
expect(getSecurityHotspotDetails).toHaveBeenCalledWith(newHotspotKey); | |||
}); | |||
it('should update refresh hotspot on update', () => { | |||
const wrapper = shallowRender(); | |||
const mockGetHostpot = getSecurityHotspotDetails as jest.Mock; | |||
mockGetHostpot.mockClear(); | |||
wrapper.find(HotspotViewerRenderer).simulate('updateHotspot'); | |||
expect(mockGetHostpot).toHaveBeenCalledTimes(1); | |||
}); | |||
it('should open comment form when scroll to comment', () => { | |||
const wrapper = shallowRender(); | |||
const mockTextRef = ({ current: { focus: jest.fn() } } as any) as React.RefObject< | |||
HTMLTextAreaElement | |||
>; | |||
const mockParentRef = ({ current: {} } as any) as React.RefObject<HTMLDivElement>; | |||
wrapper.instance().parentScrollRef = mockParentRef; | |||
wrapper.instance().commentTextRef = mockTextRef; | |||
wrapper.find(HotspotViewerRenderer).simulate('openComment'); | |||
expect(wrapper.state().commentVisible).toBe(true); | |||
expect(mockTextRef.current?.focus).toHaveBeenCalled(); | |||
expect(scrollToElement).toHaveBeenCalledWith(mockTextRef.current, expect.anything()); | |||
}); | |||
it('should close comment', () => { | |||
const wrapper = shallowRender(); | |||
wrapper.setState({ commentVisible: true }); | |||
wrapper.find(HotspotViewerRenderer).simulate('closeComment'); | |||
expect(wrapper.state().commentVisible).toBe(false); | |||
}); | |||
it('should reset loading even on fetch error', async () => { | |||
const mockGetHostpot = getSecurityHotspotDetails as jest.Mock; | |||
mockGetHostpot.mockRejectedValueOnce({}); | |||
const wrapper = shallowRender(); | |||
await waitAndUpdate(wrapper); | |||
expect(wrapper.state().loading).toBe(false); | |||
}); | |||
it('should keep state on unmoint', () => { | |||
const wrapper = shallowRender(); | |||
wrapper.instance().componentWillUnmount(); | |||
const prevState = clone(wrapper.state()); | |||
wrapper.find(HotspotViewerRenderer).simulate('updateHotspot'); | |||
expect(wrapper.state()).toStrictEqual(prevState); | |||
}); | |||
function shallowRender(props?: Partial<HotspotViewer['props']>) { | |||
return shallow<HotspotViewer>( | |||
<HotspotViewer |
@@ -21,8 +21,10 @@ import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { mockBranch } from '../../../../helpers/mocks/branch-like'; | |||
import { mockHotspot } from '../../../../helpers/mocks/security-hotspots'; | |||
import { mockComponent, mockUser } from '../../../../helpers/testMocks'; | |||
import HotspotViewerRenderer, { HotspotViewerRendererProps } from '../HotspotViewerRenderer'; | |||
import { mockComponent, mockCurrentUser, mockUser } from '../../../../helpers/testMocks'; | |||
import { HotspotViewerRenderer, HotspotViewerRendererProps } from '../HotspotViewerRenderer'; | |||
jest.mock('../../../../helpers/users', () => ({ isLoggedIn: jest.fn(() => true) })); | |||
it('should render correctly', () => { | |||
const wrapper = shallowRender(); | |||
@@ -49,9 +51,15 @@ function shallowRender(props?: Partial<HotspotViewerRendererProps>) { | |||
<HotspotViewerRenderer | |||
branchLike={mockBranch()} | |||
component={mockComponent()} | |||
commentTextRef={React.createRef()} | |||
commentVisible={false} | |||
currentUser={mockCurrentUser()} | |||
hotspot={mockHotspot()} | |||
loading={false} | |||
onCloseComment={jest.fn()} | |||
onOpenComment={jest.fn()} | |||
onUpdateHotspot={jest.fn()} | |||
parentScrollRef={React.createRef()} | |||
securityCategories={{ 'sql-injection': { title: 'SQL injection' } }} | |||
{...props} | |||
/> |
@@ -1,73 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { | |||
mockHotspot, | |||
mockHotspotReviewHistoryElement | |||
} from '../../../../helpers/mocks/security-hotspots'; | |||
import { mockUser } from '../../../../helpers/testMocks'; | |||
import { ReviewHistoryType } from '../../../../types/security-hotspots'; | |||
import HotspotViewerReviewHistoryTab, { | |||
HotspotViewerReviewHistoryTabProps | |||
} from '../HotspotViewerReviewHistoryTab'; | |||
import HotspotViewerReviewHistoryTabCommentBox from '../HotspotViewerReviewHistoryTabCommentBox'; | |||
it('should render correctly', () => { | |||
const wrapper = shallowRender(); | |||
expect(wrapper).toMatchSnapshot(); | |||
}); | |||
it('should propagate onHotspotUpdate correctly', () => { | |||
const onUpdateHotspot = jest.fn(); | |||
const wrapper = shallowRender({ onUpdateHotspot }); | |||
wrapper | |||
.find(HotspotViewerReviewHistoryTabCommentBox) | |||
.props() | |||
.onUpdateHotspot(); | |||
expect(onUpdateHotspot).toHaveBeenCalled(); | |||
}); | |||
function shallowRender(props?: Partial<HotspotViewerReviewHistoryTabProps>) { | |||
return shallow<HotspotViewerReviewHistoryTabProps>( | |||
<HotspotViewerReviewHistoryTab | |||
history={[ | |||
mockHotspotReviewHistoryElement({ user: mockUser({ avatar: 'with-avatar' }) }), | |||
mockHotspotReviewHistoryElement({ user: mockUser({ active: false }) }), | |||
mockHotspotReviewHistoryElement({ user: mockUser({ login: undefined, name: undefined }) }), | |||
mockHotspotReviewHistoryElement({ | |||
type: ReviewHistoryType.Diff, | |||
diffs: [ | |||
{ key: 'test', oldValue: 'old', newValue: 'new' }, | |||
{ key: 'test-1', oldValue: 'old-1', newValue: 'new-1' } | |||
] | |||
}), | |||
mockHotspotReviewHistoryElement({ | |||
type: ReviewHistoryType.Comment, | |||
html: '<strong>bold text</strong>' | |||
}) | |||
]} | |||
hotspot={mockHotspot()} | |||
onUpdateHotspot={jest.fn()} | |||
{...props} | |||
/> | |||
); | |||
} |
@@ -1,72 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; | |||
import { commentSecurityHotspot } from '../../../../api/security-hotspots'; | |||
import { mockHotspot } from '../../../../helpers/mocks/security-hotspots'; | |||
import HotspotViewerReviewHistoryTabCommentBox, { | |||
HotspotViewerReviewHistoryTabCommentBoxProps | |||
} from '../HotspotViewerReviewHistoryTabCommentBox'; | |||
jest.mock('../../../../api/security-hotspots', () => ({ | |||
commentSecurityHotspot: jest.fn().mockResolvedValue(null) | |||
})); | |||
it('should render correctly', () => { | |||
const wrapper = shallowRender(); | |||
expect(wrapper).toMatchSnapshot(); | |||
// Show the comment box | |||
wrapper.find('#hotspot-comment-box-display').simulate('click'); | |||
expect(wrapper).toMatchSnapshot('with comment box'); | |||
// Cancel comment | |||
wrapper.find('#hotspot-comment-box-cancel').simulate('click'); | |||
expect(wrapper).toMatchSnapshot('without comment box'); | |||
}); | |||
it('should properly submit a comment', async () => { | |||
const hotspot = mockHotspot(); | |||
const onUpdateHotspot = jest.fn(); | |||
const wrapper = shallowRender({ hotspot, onUpdateHotspot }); | |||
wrapper.find('#hotspot-comment-box-display').simulate('click'); | |||
wrapper.find('textarea').simulate('change', { target: { value: 'tata' } }); | |||
wrapper.find('#hotspot-comment-box-submit').simulate('click'); | |||
await waitAndUpdate(wrapper); | |||
expect(commentSecurityHotspot).toHaveBeenCalledWith(hotspot.key, 'tata'); | |||
expect(onUpdateHotspot).toHaveBeenCalled(); | |||
expect(wrapper).toMatchSnapshot('without comment box'); | |||
}); | |||
function shallowRender(props?: Partial<HotspotViewerReviewHistoryTabCommentBoxProps>) { | |||
return shallow<HotspotViewerReviewHistoryTabCommentBoxProps>( | |||
<HotspotViewerReviewHistoryTabCommentBox | |||
hotspot={mockHotspot()} | |||
onUpdateHotspot={jest.fn()} | |||
{...props} | |||
/> | |||
); | |||
} |
@@ -22,7 +22,6 @@ import * as React from 'react'; | |||
import BoxedTabs from 'sonar-ui-common/components/controls/BoxedTabs'; | |||
import { mockHotspot, mockHotspotRule } from '../../../../helpers/mocks/security-hotspots'; | |||
import { mockUser } from '../../../../helpers/testMocks'; | |||
import HotspotViewerReviewHistoryTab from '../HotspotViewerReviewHistoryTab'; | |||
import HotspotViewerTabs, { TabKeys } from '../HotspotViewerTabs'; | |||
it('should render correctly', () => { | |||
@@ -37,9 +36,6 @@ it('should render correctly', () => { | |||
onSelect(TabKeys.FixRecommendation); | |||
expect(wrapper).toMatchSnapshot('fix'); | |||
onSelect(TabKeys.ReviewHistory); | |||
expect(wrapper).toMatchSnapshot('review'); | |||
expect( | |||
shallowRender({ | |||
hotspot: mockHotspot({ | |||
@@ -88,31 +84,16 @@ it('should filter empty tab', () => { | |||
).toBe(count - 1); | |||
}); | |||
it('should propagate onHotspotUpdate correctly', () => { | |||
const onUpdateHotspot = jest.fn(); | |||
const wrapper = shallowRender({ onUpdateHotspot }); | |||
const onSelect = wrapper.find(BoxedTabs).prop('onSelect') as (tab: TabKeys) => void; | |||
onSelect(TabKeys.ReviewHistory); | |||
wrapper | |||
.find(HotspotViewerReviewHistoryTab) | |||
.props() | |||
.onUpdateHotspot(); | |||
expect(onUpdateHotspot).toHaveBeenCalled(); | |||
}); | |||
it('should select first tab on hotspot update', () => { | |||
const wrapper = shallowRender(); | |||
const onSelect = wrapper.find(BoxedTabs).prop('onSelect') as (tab: TabKeys) => void; | |||
onSelect(TabKeys.ReviewHistory); | |||
expect(wrapper.state().currentTab.key).toBe(TabKeys.ReviewHistory); | |||
onSelect(TabKeys.VulnerabilityDescription); | |||
expect(wrapper.state().currentTab.key).toBe(TabKeys.VulnerabilityDescription); | |||
wrapper.setProps({ hotspot: mockHotspot({ key: 'new_key' }) }); | |||
expect(wrapper.state().currentTab.key).toBe(TabKeys.RiskDescription); | |||
}); | |||
function shallowRender(props?: Partial<HotspotViewerTabs['props']>) { | |||
return shallow<HotspotViewerTabs>( | |||
<HotspotViewerTabs hotspot={mockHotspot()} onUpdateHotspot={jest.fn()} {...props} /> | |||
); | |||
return shallow<HotspotViewerTabs>(<HotspotViewerTabs hotspot={mockHotspot()} {...props} />); | |||
} |
@@ -0,0 +1,151 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<Fragment> | |||
<div | |||
className="padded" | |||
key="0" | |||
> | |||
<div | |||
className="display-flex-center" | |||
> | |||
<Connect(Avatar) | |||
className="little-spacer-right" | |||
name="John Doe" | |||
size={20} | |||
/> | |||
<strong> | |||
John Doe | |||
</strong> | |||
<span | |||
className="little-spacer-left" | |||
> | |||
hotspots.review_history.created | |||
</span> | |||
<span | |||
className="little-spacer-left little-spacer-right" | |||
> | |||
- | |||
</span> | |||
<DateTimeFormatter | |||
date="2018-09-01" | |||
/> | |||
</div> | |||
</div> | |||
<div | |||
className="padded bordered-top" | |||
key="1" | |||
> | |||
<div | |||
className="display-flex-center" | |||
> | |||
<Connect(Avatar) | |||
className="little-spacer-right" | |||
name="John Doe" | |||
size={20} | |||
/> | |||
<strong> | |||
John Doe | |||
</strong> | |||
<span | |||
className="little-spacer-left" | |||
> | |||
hotspots.review_history.comment_added | |||
</span> | |||
<span | |||
className="little-spacer-left little-spacer-right" | |||
> | |||
- | |||
</span> | |||
<DateTimeFormatter | |||
date="2018-09-10" | |||
/> | |||
</div> | |||
<div | |||
className="spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "<strong>TEST</strong>", | |||
} | |||
} | |||
/> | |||
</div> | |||
<div | |||
className="padded bordered-top" | |||
key="2" | |||
> | |||
<div | |||
className="display-flex-center" | |||
> | |||
<Connect(Avatar) | |||
className="little-spacer-right" | |||
name="John Doe" | |||
size={20} | |||
/> | |||
<strong> | |||
John Doe | |||
</strong> | |||
<span | |||
className="little-spacer-left" | |||
> | |||
hotspots.review_history.comment_added | |||
</span> | |||
<span | |||
className="little-spacer-left little-spacer-right" | |||
> | |||
- | |||
</span> | |||
<DateTimeFormatter | |||
date="2018-09-11" | |||
/> | |||
</div> | |||
<div | |||
className="spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "<strong>TEST</strong>", | |||
} | |||
} | |||
/> | |||
</div> | |||
<div | |||
className="padded bordered-top" | |||
key="3" | |||
> | |||
<div | |||
className="display-flex-center" | |||
> | |||
<Connect(Avatar) | |||
className="little-spacer-right" | |||
name="me-name" | |||
size={20} | |||
/> | |||
<strong> | |||
me-name | |||
</strong> | |||
<span | |||
className="little-spacer-left little-spacer-right" | |||
> | |||
- | |||
</span> | |||
<DateTimeFormatter | |||
date="2018-10-01" | |||
/> | |||
</div> | |||
<div | |||
className="spacer-top" | |||
> | |||
<IssueChangelogDiff | |||
diff={ | |||
Object { | |||
"key": "assign", | |||
"newValue": "me", | |||
"oldValue": "him", | |||
} | |||
} | |||
key="0" | |||
/> | |||
</div> | |||
</div> | |||
</Fragment> | |||
`; |
@@ -0,0 +1,277 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<Fragment> | |||
<h1> | |||
hotspot.section.activity | |||
</h1> | |||
<div | |||
className="padded" | |||
> | |||
<HotspotReviewHistory | |||
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 { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "FIL", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
}, | |||
"creationDate": "2013-05-13T17:55:41+0200", | |||
"key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123", | |||
"line": 142, | |||
"message": "'3' is a magic number.", | |||
"project": Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"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 [], | |||
}, | |||
"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", | |||
}, | |||
], | |||
} | |||
} | |||
/> | |||
<hr /> | |||
<div | |||
className="big-spacer-top" | |||
> | |||
<Button | |||
className="" | |||
id="hotspot-comment-box-display" | |||
onClick={[MockFunction]} | |||
> | |||
hotspots.comment.open | |||
</Button> | |||
<div | |||
className="invisible" | |||
> | |||
<div | |||
className="little-spacer-bottom" | |||
> | |||
hotspots.comment.field | |||
</div> | |||
<textarea | |||
className="form-field fixed-width width-100 spacer-bottom" | |||
onChange={[Function]} | |||
rows={2} | |||
value="" | |||
/> | |||
<div | |||
className="display-flex-space-between display-flex-center " | |||
> | |||
<MarkdownTips | |||
className="huge-spacer-bottom" | |||
/> | |||
<div> | |||
<Button | |||
className="huge-spacer-bottom" | |||
id="hotspot-comment-box-submit" | |||
onClick={[Function]} | |||
> | |||
hotspots.comment.submit | |||
</Button> | |||
<ResetButtonLink | |||
className="spacer-left huge-spacer-bottom" | |||
id="hotspot-comment-box-cancel" | |||
onClick={[Function]} | |||
> | |||
cancel | |||
</ResetButtonLink> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</Fragment> | |||
`; | |||
exports[`should render correctly without user 1`] = ` | |||
<Fragment> | |||
<h1> | |||
hotspot.section.activity | |||
</h1> | |||
<div | |||
className="padded" | |||
> | |||
<HotspotReviewHistory | |||
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 { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "FIL", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
}, | |||
"creationDate": "2013-05-13T17:55:41+0200", | |||
"key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123", | |||
"line": 142, | |||
"message": "'3' is a magic number.", | |||
"project": Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"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 [], | |||
}, | |||
"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> | |||
</Fragment> | |||
`; |
@@ -1,7 +1,13 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<HotspotViewerRenderer | |||
<Connect(withCurrentUser(HotspotViewerRenderer)) | |||
commentTextRef={ | |||
Object { | |||
"current": null, | |||
} | |||
} | |||
commentVisible={false} | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
@@ -26,7 +32,14 @@ exports[`should render correctly 1`] = ` | |||
} | |||
} | |||
loading={true} | |||
onCloseComment={[Function]} | |||
onOpenComment={[Function]} | |||
onUpdateHotspot={[Function]} | |||
parentScrollRef={ | |||
Object { | |||
"current": null, | |||
} | |||
} | |||
securityCategories={ | |||
Object { | |||
"cat1": Object { | |||
@@ -38,7 +51,13 @@ exports[`should render correctly 1`] = ` | |||
`; | |||
exports[`should render correctly 2`] = ` | |||
<HotspotViewerRenderer | |||
<Connect(withCurrentUser(HotspotViewerRenderer)) | |||
commentTextRef={ | |||
Object { | |||
"current": null, | |||
} | |||
} | |||
commentVisible={false} | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
@@ -68,7 +87,14 @@ exports[`should render correctly 2`] = ` | |||
} | |||
} | |||
loading={false} | |||
onCloseComment={[Function]} | |||
onOpenComment={[Function]} | |||
onUpdateHotspot={[Function]} | |||
parentScrollRef={ | |||
Object { | |||
"current": null, | |||
} | |||
} | |||
securityCategories={ | |||
Object { | |||
"cat1": Object { |
@@ -6,7 +6,7 @@ exports[`should render correctly 1`] = ` | |||
timeout={100} | |||
> | |||
<div | |||
className="big-padded" | |||
className="big-padded hotspot-content" | |||
> | |||
<div | |||
className="huge-spacer-bottom display-flex-space-between" | |||
@@ -16,16 +16,30 @@ exports[`should render correctly 1`] = ` | |||
> | |||
'3' is a magic number. | |||
</strong> | |||
<ClipboardButton | |||
copyValue="http://localhost/security_hotspots?id=my-project&branch=branch-6.7&hotspots=01fc972e-2a3c-433e-bcae-0bd7f88f5123" | |||
<div | |||
className="display-flex-row flex-0" | |||
> | |||
<LinkIcon | |||
className="spacer-right" | |||
/> | |||
<span> | |||
hotspots.get_permalink | |||
</span> | |||
</ClipboardButton> | |||
<div | |||
className="dropdown spacer-right flex-1-0-auto" | |||
> | |||
<Button | |||
onClick={[MockFunction]} | |||
> | |||
hotspots.comment.open | |||
</Button> | |||
</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" | |||
@@ -491,7 +505,121 @@ exports[`should render correctly 1`] = ` | |||
], | |||
} | |||
} | |||
onUpdateHotspot={[MockFunction]} | |||
/> | |||
<HotspotReviewHistoryAndComments | |||
commentTextRef={ | |||
Object { | |||
"current": null, | |||
} | |||
} | |||
commentVisible={false} | |||
currentUser={ | |||
Object { | |||
"isLoggedIn": false, | |||
} | |||
} | |||
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 { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "FIL", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
}, | |||
"creationDate": "2013-05-13T17:55:41+0200", | |||
"key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123", | |||
"line": 142, | |||
"message": "'3' is a magic number.", | |||
"project": Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"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 [], | |||
}, | |||
"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", | |||
}, | |||
], | |||
} | |||
} | |||
onCloseComment={[MockFunction]} | |||
onCommentUpdate={[MockFunction]} | |||
onOpenComment={[MockFunction]} | |||
/> | |||
</div> | |||
</DeferredSpinner> | |||
@@ -503,7 +631,7 @@ exports[`should render correctly: anonymous user 1`] = ` | |||
timeout={100} | |||
> | |||
<div | |||
className="big-padded" | |||
className="big-padded hotspot-content" | |||
> | |||
<div | |||
className="huge-spacer-bottom display-flex-space-between" | |||
@@ -513,16 +641,30 @@ exports[`should render correctly: anonymous user 1`] = ` | |||
> | |||
'3' is a magic number. | |||
</strong> | |||
<ClipboardButton | |||
copyValue="http://localhost/security_hotspots?id=my-project&branch=branch-6.7&hotspots=01fc972e-2a3c-433e-bcae-0bd7f88f5123" | |||
<div | |||
className="display-flex-row flex-0" | |||
> | |||
<LinkIcon | |||
className="spacer-right" | |||
/> | |||
<span> | |||
hotspots.get_permalink | |||
</span> | |||
</ClipboardButton> | |||
<div | |||
className="dropdown spacer-right flex-1-0-auto" | |||
> | |||
<Button | |||
onClick={[MockFunction]} | |||
> | |||
hotspots.comment.open | |||
</Button> | |||
</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" | |||
@@ -988,7 +1130,121 @@ exports[`should render correctly: anonymous user 1`] = ` | |||
], | |||
} | |||
} | |||
onUpdateHotspot={[MockFunction]} | |||
/> | |||
<HotspotReviewHistoryAndComments | |||
commentTextRef={ | |||
Object { | |||
"current": null, | |||
} | |||
} | |||
commentVisible={false} | |||
currentUser={ | |||
Object { | |||
"isLoggedIn": false, | |||
} | |||
} | |||
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 { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "FIL", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
}, | |||
"creationDate": "2013-05-13T17:55:41+0200", | |||
"key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123", | |||
"line": 142, | |||
"message": "'3' is a magic number.", | |||
"project": Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"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 [], | |||
}, | |||
"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", | |||
}, | |||
], | |||
} | |||
} | |||
onCloseComment={[MockFunction]} | |||
onCommentUpdate={[MockFunction]} | |||
onOpenComment={[MockFunction]} | |||
/> | |||
</div> | |||
</DeferredSpinner> | |||
@@ -1000,7 +1256,7 @@ exports[`should render correctly: assignee without name 1`] = ` | |||
timeout={100} | |||
> | |||
<div | |||
className="big-padded" | |||
className="big-padded hotspot-content" | |||
> | |||
<div | |||
className="huge-spacer-bottom display-flex-space-between" | |||
@@ -1010,16 +1266,30 @@ exports[`should render correctly: assignee without name 1`] = ` | |||
> | |||
'3' is a magic number. | |||
</strong> | |||
<ClipboardButton | |||
copyValue="http://localhost/security_hotspots?id=my-project&branch=branch-6.7&hotspots=01fc972e-2a3c-433e-bcae-0bd7f88f5123" | |||
<div | |||
className="display-flex-row flex-0" | |||
> | |||
<LinkIcon | |||
className="spacer-right" | |||
/> | |||
<span> | |||
hotspots.get_permalink | |||
</span> | |||
</ClipboardButton> | |||
<div | |||
className="dropdown spacer-right flex-1-0-auto" | |||
> | |||
<Button | |||
onClick={[MockFunction]} | |||
> | |||
hotspots.comment.open | |||
</Button> | |||
</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" | |||
@@ -1485,38 +1755,166 @@ exports[`should render correctly: assignee without name 1`] = ` | |||
], | |||
} | |||
} | |||
onUpdateHotspot={[MockFunction]} | |||
/> | |||
</div> | |||
</DeferredSpinner> | |||
`; | |||
exports[`should render correctly: deleted assignee 1`] = ` | |||
<DeferredSpinner | |||
loading={false} | |||
timeout={100} | |||
> | |||
<div | |||
className="big-padded" | |||
> | |||
<div | |||
className="huge-spacer-bottom display-flex-space-between" | |||
> | |||
<strong | |||
className="big big-spacer-right" | |||
> | |||
<HotspotReviewHistoryAndComments | |||
commentTextRef={ | |||
Object { | |||
"current": null, | |||
} | |||
} | |||
commentVisible={false} | |||
currentUser={ | |||
Object { | |||
"isLoggedIn": false, | |||
} | |||
} | |||
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 { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "FIL", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
}, | |||
"creationDate": "2013-05-13T17:55:41+0200", | |||
"key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123", | |||
"line": 142, | |||
"message": "'3' is a magic number.", | |||
"project": Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"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 [], | |||
}, | |||
"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", | |||
}, | |||
], | |||
} | |||
} | |||
onCloseComment={[MockFunction]} | |||
onCommentUpdate={[MockFunction]} | |||
onOpenComment={[MockFunction]} | |||
/> | |||
</div> | |||
</DeferredSpinner> | |||
`; | |||
exports[`should render correctly: deleted assignee 1`] = ` | |||
<DeferredSpinner | |||
loading={false} | |||
timeout={100} | |||
> | |||
<div | |||
className="big-padded hotspot-content" | |||
> | |||
<div | |||
className="huge-spacer-bottom display-flex-space-between" | |||
> | |||
<strong | |||
className="big big-spacer-right" | |||
> | |||
'3' is a magic number. | |||
</strong> | |||
<ClipboardButton | |||
copyValue="http://localhost/security_hotspots?id=my-project&branch=branch-6.7&hotspots=01fc972e-2a3c-433e-bcae-0bd7f88f5123" | |||
<div | |||
className="display-flex-row flex-0" | |||
> | |||
<LinkIcon | |||
className="spacer-right" | |||
/> | |||
<span> | |||
hotspots.get_permalink | |||
</span> | |||
</ClipboardButton> | |||
<div | |||
className="dropdown spacer-right flex-1-0-auto" | |||
> | |||
<Button | |||
onClick={[MockFunction]} | |||
> | |||
hotspots.comment.open | |||
</Button> | |||
</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" | |||
@@ -1982,7 +2380,121 @@ exports[`should render correctly: deleted assignee 1`] = ` | |||
], | |||
} | |||
} | |||
onUpdateHotspot={[MockFunction]} | |||
/> | |||
<HotspotReviewHistoryAndComments | |||
commentTextRef={ | |||
Object { | |||
"current": null, | |||
} | |||
} | |||
commentVisible={false} | |||
currentUser={ | |||
Object { | |||
"isLoggedIn": false, | |||
} | |||
} | |||
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 { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "FIL", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
}, | |||
"creationDate": "2013-05-13T17:55:41+0200", | |||
"key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123", | |||
"line": 142, | |||
"message": "'3' is a magic number.", | |||
"project": Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"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 [], | |||
}, | |||
"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", | |||
}, | |||
], | |||
} | |||
} | |||
onCloseComment={[MockFunction]} | |||
onCommentUpdate={[MockFunction]} | |||
onOpenComment={[MockFunction]} | |||
/> | |||
</div> | |||
</DeferredSpinner> | |||
@@ -2001,7 +2513,7 @@ exports[`should render correctly: unassigned 1`] = ` | |||
timeout={100} | |||
> | |||
<div | |||
className="big-padded" | |||
className="big-padded hotspot-content" | |||
> | |||
<div | |||
className="huge-spacer-bottom display-flex-space-between" | |||
@@ -2011,16 +2523,30 @@ exports[`should render correctly: unassigned 1`] = ` | |||
> | |||
'3' is a magic number. | |||
</strong> | |||
<ClipboardButton | |||
copyValue="http://localhost/security_hotspots?id=my-project&branch=branch-6.7&hotspots=01fc972e-2a3c-433e-bcae-0bd7f88f5123" | |||
<div | |||
className="display-flex-row flex-0" | |||
> | |||
<LinkIcon | |||
className="spacer-right" | |||
/> | |||
<span> | |||
hotspots.get_permalink | |||
</span> | |||
</ClipboardButton> | |||
<div | |||
className="dropdown spacer-right flex-1-0-auto" | |||
> | |||
<Button | |||
onClick={[MockFunction]} | |||
> | |||
hotspots.comment.open | |||
</Button> | |||
</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" | |||
@@ -2486,7 +3012,121 @@ exports[`should render correctly: unassigned 1`] = ` | |||
], | |||
} | |||
} | |||
onUpdateHotspot={[MockFunction]} | |||
/> | |||
<HotspotReviewHistoryAndComments | |||
commentTextRef={ | |||
Object { | |||
"current": null, | |||
} | |||
} | |||
commentVisible={false} | |||
currentUser={ | |||
Object { | |||
"isLoggedIn": false, | |||
} | |||
} | |||
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 { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "FIL", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
}, | |||
"creationDate": "2013-05-13T17:55:41+0200", | |||
"key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123", | |||
"line": 142, | |||
"message": "'3' is a magic number.", | |||
"project": Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"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 [], | |||
}, | |||
"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", | |||
}, | |||
], | |||
} | |||
} | |||
onCloseComment={[MockFunction]} | |||
onCommentUpdate={[MockFunction]} | |||
onOpenComment={[MockFunction]} | |||
/> | |||
</div> | |||
</DeferredSpinner> |
@@ -1,270 +0,0 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<div | |||
className="padded" | |||
> | |||
<div | |||
className="padded" | |||
> | |||
<div | |||
className="display-flex-center" | |||
> | |||
<Connect(Avatar) | |||
className="little-spacer-right" | |||
hash="with-avatar" | |||
name="John Doe" | |||
size={20} | |||
/> | |||
<strong> | |||
John Doe | |||
</strong> | |||
<span | |||
className="little-spacer-left" | |||
> | |||
hotspots.tabs.review_history.created | |||
</span> | |||
<span | |||
className="little-spacer-left little-spacer-right" | |||
> | |||
- | |||
</span> | |||
<DateTimeFormatter | |||
date="2019-09-13T17:55:42+0200" | |||
/> | |||
</div> | |||
</div> | |||
<hr /> | |||
<div | |||
className="padded" | |||
> | |||
<div | |||
className="display-flex-center" | |||
> | |||
<Connect(Avatar) | |||
className="little-spacer-right" | |||
name="John Doe" | |||
size={20} | |||
/> | |||
<strong> | |||
user.x_deleted.John Doe | |||
</strong> | |||
<span | |||
className="little-spacer-left" | |||
> | |||
hotspots.tabs.review_history.created | |||
</span> | |||
<span | |||
className="little-spacer-left little-spacer-right" | |||
> | |||
- | |||
</span> | |||
<DateTimeFormatter | |||
date="2019-09-13T17:55:42+0200" | |||
/> | |||
</div> | |||
</div> | |||
<hr /> | |||
<div | |||
className="padded" | |||
> | |||
<div | |||
className="display-flex-center" | |||
> | |||
<DateTimeFormatter | |||
date="2019-09-13T17:55:42+0200" | |||
/> | |||
</div> | |||
</div> | |||
<hr /> | |||
<div | |||
className="padded" | |||
> | |||
<div | |||
className="display-flex-center" | |||
> | |||
<Connect(Avatar) | |||
className="little-spacer-right" | |||
name="John Doe" | |||
size={20} | |||
/> | |||
<strong> | |||
John Doe | |||
</strong> | |||
<span | |||
className="little-spacer-left little-spacer-right" | |||
> | |||
- | |||
</span> | |||
<DateTimeFormatter | |||
date="2019-09-13T17:55:42+0200" | |||
/> | |||
</div> | |||
<div | |||
className="spacer-top" | |||
> | |||
<IssueChangelogDiff | |||
diff={ | |||
Object { | |||
"key": "test", | |||
"newValue": "new", | |||
"oldValue": "old", | |||
} | |||
} | |||
key="0" | |||
/> | |||
<IssueChangelogDiff | |||
diff={ | |||
Object { | |||
"key": "test-1", | |||
"newValue": "new-1", | |||
"oldValue": "old-1", | |||
} | |||
} | |||
key="1" | |||
/> | |||
</div> | |||
</div> | |||
<hr /> | |||
<div | |||
className="padded" | |||
> | |||
<div | |||
className="display-flex-center" | |||
> | |||
<Connect(Avatar) | |||
className="little-spacer-right" | |||
name="John Doe" | |||
size={20} | |||
/> | |||
<strong> | |||
John Doe | |||
</strong> | |||
<span | |||
className="little-spacer-left" | |||
> | |||
hotspots.tabs.review_history.comment.added | |||
</span> | |||
<span | |||
className="little-spacer-left little-spacer-right" | |||
> | |||
- | |||
</span> | |||
<DateTimeFormatter | |||
date="2019-09-13T17:55:42+0200" | |||
/> | |||
</div> | |||
<div | |||
className="spacer-top markdown" | |||
dangerouslySetInnerHTML={ | |||
Object { | |||
"__html": "<strong>bold text</strong>", | |||
} | |||
} | |||
/> | |||
</div> | |||
<hr /> | |||
<HotspotViewerReviewHistoryTabCommentBox | |||
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 { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "FIL", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
}, | |||
"creationDate": "2013-05-13T17:55:41+0200", | |||
"key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123", | |||
"line": 142, | |||
"message": "'3' is a magic number.", | |||
"project": Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"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 [], | |||
}, | |||
"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]} | |||
/> | |||
</div> | |||
`; |
@@ -1,78 +0,0 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should properly submit a comment: without comment box 1`] = ` | |||
<div | |||
className="big-spacer-top" | |||
> | |||
<Button | |||
id="hotspot-comment-box-display" | |||
onClick={[Function]} | |||
> | |||
hotspots.tabs.review_history.comment.add | |||
</Button> | |||
</div> | |||
`; | |||
exports[`should render correctly 1`] = ` | |||
<div | |||
className="big-spacer-top" | |||
> | |||
<Button | |||
id="hotspot-comment-box-display" | |||
onClick={[Function]} | |||
> | |||
hotspots.tabs.review_history.comment.add | |||
</Button> | |||
</div> | |||
`; | |||
exports[`should render correctly: with comment box 1`] = ` | |||
<div | |||
className="big-spacer-top" | |||
> | |||
<div | |||
className="little-spacer-bottom" | |||
> | |||
hotspots.tabs.review_history.comment.field | |||
</div> | |||
<textarea | |||
autoFocus={true} | |||
className="form-field fixed-width width-100 spacer-bottom" | |||
onChange={[Function]} | |||
rows={2} | |||
/> | |||
<div | |||
className="display-flex-space-between display-flex-center" | |||
> | |||
<MarkdownTips /> | |||
<div> | |||
<Button | |||
id="hotspot-comment-box-submit" | |||
onClick={[Function]} | |||
> | |||
hotspots.tabs.review_history.comment.submit | |||
</Button> | |||
<ResetButtonLink | |||
className="spacer-left" | |||
id="hotspot-comment-box-cancel" | |||
onClick={[Function]} | |||
> | |||
cancel | |||
</ResetButtonLink> | |||
</div> | |||
</div> | |||
</div> | |||
`; | |||
exports[`should render correctly: without comment box 1`] = ` | |||
<div | |||
className="big-spacer-top" | |||
> | |||
<Button | |||
id="hotspot-comment-box-display" | |||
onClick={[Function]} | |||
> | |||
hotspots.tabs.review_history.comment.add | |||
</Button> | |||
</div> | |||
`; |
@@ -22,130 +22,6 @@ exports[`should render correctly: fix 1`] = ` | |||
"key": "fix", | |||
"label": "hotspots.tabs.fix_recommendations", | |||
}, | |||
Object { | |||
"content": <HotspotViewerReviewHistoryTab | |||
history={ | |||
Array [ | |||
Object { | |||
"date": "2013-05-13T17:55:41+0200", | |||
"type": 0, | |||
"user": Object { | |||
"active": true, | |||
"local": true, | |||
"login": "author", | |||
"name": "John Doe", | |||
}, | |||
}, | |||
] | |||
} | |||
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 { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "FIL", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
}, | |||
"creationDate": "2013-05-13T17:55:41+0200", | |||
"key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123", | |||
"line": 142, | |||
"message": "'3' is a magic number.", | |||
"project": Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"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 [], | |||
}, | |||
"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]} | |||
/>, | |||
"key": "review", | |||
"label": <React.Fragment> | |||
<span> | |||
hotspots.tabs.review_history | |||
</span> | |||
</React.Fragment>, | |||
}, | |||
] | |||
} | |||
/> | |||
@@ -164,278 +40,6 @@ exports[`should render correctly: fix 1`] = ` | |||
</Fragment> | |||
`; | |||
exports[`should render correctly: review 1`] = ` | |||
<Fragment> | |||
<BoxedTabs | |||
onSelect={[Function]} | |||
selected="review" | |||
tabs={ | |||
Array [ | |||
Object { | |||
"content": "<p>This a <strong>strong</strong> message about risk !</p>", | |||
"key": "risk", | |||
"label": "hotspots.tabs.risk_description", | |||
}, | |||
Object { | |||
"content": "<p>This a <strong>strong</strong> message about vulnerability !</p>", | |||
"key": "vulnerability", | |||
"label": "hotspots.tabs.vulnerability_description", | |||
}, | |||
Object { | |||
"content": "<p>This a <strong>strong</strong> message about fixing !</p>", | |||
"key": "fix", | |||
"label": "hotspots.tabs.fix_recommendations", | |||
}, | |||
Object { | |||
"content": <HotspotViewerReviewHistoryTab | |||
history={ | |||
Array [ | |||
Object { | |||
"date": "2013-05-13T17:55:41+0200", | |||
"type": 0, | |||
"user": Object { | |||
"active": true, | |||
"local": true, | |||
"login": "author", | |||
"name": "John Doe", | |||
}, | |||
}, | |||
] | |||
} | |||
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 { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "FIL", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
}, | |||
"creationDate": "2013-05-13T17:55:41+0200", | |||
"key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123", | |||
"line": 142, | |||
"message": "'3' is a magic number.", | |||
"project": Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"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 [], | |||
}, | |||
"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]} | |||
/>, | |||
"key": "review", | |||
"label": <React.Fragment> | |||
<span> | |||
hotspots.tabs.review_history | |||
</span> | |||
</React.Fragment>, | |||
}, | |||
] | |||
} | |||
/> | |||
<div | |||
className="bordered huge-spacer-bottom" | |||
> | |||
<HotspotViewerReviewHistoryTab | |||
history={ | |||
Array [ | |||
Object { | |||
"date": "2013-05-13T17:55:41+0200", | |||
"type": 0, | |||
"user": Object { | |||
"active": true, | |||
"local": true, | |||
"login": "author", | |||
"name": "John Doe", | |||
}, | |||
}, | |||
] | |||
} | |||
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 { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "FIL", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
}, | |||
"creationDate": "2013-05-13T17:55:41+0200", | |||
"key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123", | |||
"line": 142, | |||
"message": "'3' is a magic number.", | |||
"project": Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"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 [], | |||
}, | |||
"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]} | |||
/> | |||
</div> | |||
</Fragment> | |||
`; | |||
exports[`should render correctly: risk 1`] = ` | |||
<Fragment> | |||
<BoxedTabs | |||
@@ -458,130 +62,6 @@ exports[`should render correctly: risk 1`] = ` | |||
"key": "fix", | |||
"label": "hotspots.tabs.fix_recommendations", | |||
}, | |||
Object { | |||
"content": <HotspotViewerReviewHistoryTab | |||
history={ | |||
Array [ | |||
Object { | |||
"date": "2013-05-13T17:55:41+0200", | |||
"type": 0, | |||
"user": Object { | |||
"active": true, | |||
"local": true, | |||
"login": "author", | |||
"name": "John Doe", | |||
}, | |||
}, | |||
] | |||
} | |||
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 { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "FIL", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
}, | |||
"creationDate": "2013-05-13T17:55:41+0200", | |||
"key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123", | |||
"line": 142, | |||
"message": "'3' is a magic number.", | |||
"project": Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"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 [], | |||
}, | |||
"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]} | |||
/>, | |||
"key": "review", | |||
"label": <React.Fragment> | |||
<span> | |||
hotspots.tabs.review_history | |||
</span> | |||
</React.Fragment>, | |||
}, | |||
] | |||
} | |||
/> | |||
@@ -622,130 +102,6 @@ exports[`should render correctly: vulnerability 1`] = ` | |||
"key": "fix", | |||
"label": "hotspots.tabs.fix_recommendations", | |||
}, | |||
Object { | |||
"content": <HotspotViewerReviewHistoryTab | |||
history={ | |||
Array [ | |||
Object { | |||
"date": "2013-05-13T17:55:41+0200", | |||
"type": 0, | |||
"user": Object { | |||
"active": true, | |||
"local": true, | |||
"login": "author", | |||
"name": "John Doe", | |||
}, | |||
}, | |||
] | |||
} | |||
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 { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "FIL", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
}, | |||
"creationDate": "2013-05-13T17:55:41+0200", | |||
"key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123", | |||
"line": 142, | |||
"message": "'3' is a magic number.", | |||
"project": Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"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 [], | |||
}, | |||
"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]} | |||
/>, | |||
"key": "review", | |||
"label": <React.Fragment> | |||
<span> | |||
hotspots.tabs.review_history | |||
</span> | |||
</React.Fragment>, | |||
}, | |||
] | |||
} | |||
/> | |||
@@ -786,161 +142,6 @@ exports[`should render correctly: with comments or changelog element 1`] = ` | |||
"key": "fix", | |||
"label": "hotspots.tabs.fix_recommendations", | |||
}, | |||
Object { | |||
"content": <HotspotViewerReviewHistoryTab | |||
history={ | |||
Array [ | |||
Object { | |||
"date": "2013-05-13T17:55:41+0200", | |||
"type": 0, | |||
"user": Object { | |||
"active": true, | |||
"local": true, | |||
"login": "author", | |||
"name": "John Doe", | |||
}, | |||
}, | |||
Object { | |||
"date": "2019-01-01", | |||
"html": "<strong>test</strong>", | |||
"type": 2, | |||
"user": Object { | |||
"active": true, | |||
"local": true, | |||
"login": "john.doe", | |||
"name": "John Doe", | |||
}, | |||
}, | |||
] | |||
} | |||
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 [ | |||
Object { | |||
"createdAt": "2019-01-01", | |||
"htmlText": "<strong>test</strong>", | |||
"key": "comment-key", | |||
"login": "me", | |||
"markdown": "*test*", | |||
"updatable": false, | |||
"user": Object { | |||
"active": true, | |||
"local": true, | |||
"login": "john.doe", | |||
"name": "John Doe", | |||
}, | |||
}, | |||
], | |||
"component": Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "FIL", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
}, | |||
"creationDate": "2013-05-13T17:55:41+0200", | |||
"key": "01fc972e-2a3c-433e-bcae-0bd7f88f5123", | |||
"line": 142, | |||
"message": "'3' is a magic number.", | |||
"project": Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"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 [], | |||
}, | |||
"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]} | |||
/>, | |||
"key": "review", | |||
"label": <React.Fragment> | |||
<span> | |||
hotspots.tabs.review_history | |||
</span> | |||
<span | |||
className="counter-badge spacer-left" | |||
> | |||
1 | |||
</span> | |||
</React.Fragment>, | |||
}, | |||
] | |||
} | |||
/> |
@@ -48,6 +48,17 @@ | |||
#security_hotspots .main { | |||
flex: 1 1 auto; | |||
overflow-y: auto; | |||
background-color: white; | |||
/* Force flex to take parent width. */ | |||
overflow-x: auto; | |||
} | |||
#security_hotspots .main .hotspot-content { | |||
overflow-y: auto; | |||
height: 100%; | |||
box-sizing: border-box; | |||
} | |||
.invisible { | |||
visibility: hidden; | |||
} |
@@ -81,14 +81,8 @@ export function constructSourceViewerFile( | |||
}; | |||
} | |||
export function getHotspotReviewHistory( | |||
hotspot: Hotspot | |||
): { | |||
history: ReviewHistoryElement[]; | |||
functionalCount: number; | |||
} { | |||
export function getHotspotReviewHistory(hotspot: Hotspot): ReviewHistoryElement[] { | |||
const history: ReviewHistoryElement[] = []; | |||
let functionalCount = 0; | |||
if (hotspot.creationDate) { | |||
history.push({ | |||
@@ -102,7 +96,6 @@ export function getHotspotReviewHistory( | |||
} | |||
if (hotspot.changelog && hotspot.changelog.length > 0) { | |||
functionalCount += hotspot.changelog.length; | |||
history.push( | |||
...hotspot.changelog.map(log => ({ | |||
type: ReviewHistoryType.Diff, | |||
@@ -118,7 +111,6 @@ export function getHotspotReviewHistory( | |||
} | |||
if (hotspot.comment && hotspot.comment.length > 0) { | |||
functionalCount += hotspot.comment.length; | |||
history.push( | |||
...hotspot.comment.map(comment => ({ | |||
type: ReviewHistoryType.Comment, | |||
@@ -132,10 +124,7 @@ export function getHotspotReviewHistory( | |||
); | |||
} | |||
return { | |||
history: sortBy(history, elt => elt.date), | |||
functionalCount | |||
}; | |||
return sortBy(history, elt => elt.date); | |||
} | |||
const STATUS_AND_RESOLUTION_TO_STATUS_OPTION = { |
@@ -667,12 +667,11 @@ hotspots.risk_exposure=Review priority | |||
hotspots.tabs.risk_description=What's the risk? | |||
hotspots.tabs.vulnerability_description=Are you at risk? | |||
hotspots.tabs.fix_recommendations=How can you fix it? | |||
hotspots.tabs.review_history=Review history | |||
hotspots.tabs.review_history.created=created Security Hotspot | |||
hotspots.tabs.review_history.comment.added=added a comment | |||
hotspots.tabs.review_history.comment.add=Add a comment | |||
hotspots.tabs.review_history.comment.field=Comment: | |||
hotspots.tabs.review_history.comment.submit=Comment | |||
hotspots.review_history.created=created Security Hotspot | |||
hotspots.review_history.comment_added=added a comment | |||
hotspots.comment.field=Comment: | |||
hotspots.comment.open=Add Comment | |||
hotspots.comment.submit=Comment | |||
hotspots.assignee.select_user=Select a user... | |||
hotspots.status.cannot_change_status=Changing a hotspot's status requires permission. | |||
@@ -696,6 +695,7 @@ hotspot.filters.period.since_leak_period=New code | |||
hotspot.filters.period.overall=Overall code | |||
hotspot.filters.status.safe=Reviewed as safe | |||
hotspot.filters.show_all=Show all hotspots | |||
hotspot.section.activity=Activity: | |||
hotspots.reviewed.tooltip=Percentage of Security Hotspots reviewed (fixed or safe) among all non-closed Security Hotspots. | |||
hotspots.review_hotspot=Review Hotspot |