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