]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-19197 Show code variants on hotspots
authorWouter Admiraal <wouter.admiraal@sonarsource.com>
Thu, 11 May 2023 14:53:01 +0000 (16:53 +0200)
committersonartech <sonartech@sonarsource.com>
Tue, 16 May 2023 20:02:50 +0000 (20:02 +0000)
server/sonar-web/src/main/js/api/mocks/SecurityHotspotServiceMock.ts
server/sonar-web/src/main/js/apps/security-hotspots/__tests__/SecurityHotspotsApp-it.tsx
server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotHeader.tsx
server/sonar-web/src/main/js/types/security-hotspots.ts

index 32ba90c04267bd456e08c788fc99f0f1bab4390b..849d45ed7a5970625e7fb1a25f503991ff32b8cf 100644 (file)
@@ -319,6 +319,7 @@ export default class SecurityHotspotServiceMock {
         key: 'test-2',
         status: HotspotStatus.TO_REVIEW,
         message: "'2' is a magic number.",
+        codeVariants: ['variant 1', 'variant 2'],
       }),
     ];
     this.canChangeStatus = true;
index 0ee7b5b5e7475d406f22a20538d879708619b3a3..9bfe9fb9085893f11916dd2956baa7a05c5cfa60 100644 (file)
@@ -17,7 +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 { screen, within } from '@testing-library/react';
+import { act, screen, within } from '@testing-library/react';
 import userEvent from '@testing-library/user-event';
 import React from 'react';
 import { Route } from 'react-router-dom';
@@ -82,6 +82,15 @@ afterEach(() => {
   handler.reset();
 });
 
+describe('rendering', () => {
+  it('should render code variants correctly', async () => {
+    renderSecurityHotspotsApp(
+      'security_hotspots?id=guillaume-peoch-sonarsource_benflix_AYGpXq2bd8qy4i0eO9ed&hotspots=test-2'
+    );
+    expect(await screen.findAllByText('variant 1, variant 2')).toHaveLength(2);
+  });
+});
+
 it('should navigate when comming from SonarLint', async () => {
   // On main branch
   const rtl = renderSecurityHotspotsApp(
@@ -188,7 +197,9 @@ it('should be able to change the status of a hotspot', async () => {
   await user.click(screen.getByRole('textbox', { name: 'hotspots.status.add_comment' }));
   await user.keyboard(comment);
 
-  await user.click(ui.changeStatus.get());
+  await act(async () => {
+    await user.click(ui.changeStatus.get());
+  });
 
   expect(setSecurityHotspotStatus).toHaveBeenLastCalledWith('test-1', {
     comment: 'COMMENT-TEXT',
@@ -218,7 +229,10 @@ it('should remember the comment when toggling change status panel for the same s
   await user.keyboard(comment);
 
   // Close the panel
-  await user.keyboard('{Escape}');
+  await act(async () => {
+    await user.keyboard('{Escape}');
+  });
+
   // Check panel is closed
   expect(ui.panel.query()).not.toBeInTheDocument();
 
index 07dacf5f64e03ba9625905388133015b4dba1ec6..9f1283cb2f6054a17a02d40f546b830414c916fa 100644 (file)
@@ -19,6 +19,7 @@
  */
 import React from 'react';
 import Link from '../../../components/common/Link';
+import Tooltip from '../../../components/controls/Tooltip';
 import { IssueMessageHighlighting } from '../../../components/issue/IssueMessageHighlighting';
 import { translate } from '../../../helpers/l10n';
 import { getRuleUrl } from '../../../helpers/urls';
@@ -52,9 +53,19 @@ export function HotspotHeader(props: HotspotHeaderProps) {
           hotspot={hotspot}
           onStatusChange={(statusOption) => props.onUpdateHotspot(true, statusOption)}
         />
-        <div className="display-flex-end">
-          <div className="display-inline-flex-center it__hs-assignee">
-            <div className="big-spacer-right">{`${translate('assignee')}: `}</div>
+        <div className="display-flex-end display-flex-column abs-width-240">
+          {hotspot.codeVariants && hotspot.codeVariants.length > 0 && (
+            <Tooltip overlay={hotspot.codeVariants.join(', ')}>
+              <div className="spacer-bottom display-flex-center">
+                <div>{translate('issues.facet.codeVariants')}:</div>
+                <div className="text-bold spacer-left spacer-right text-ellipsis">
+                  {hotspot.codeVariants.join(', ')}
+                </div>
+              </div>
+            </Tooltip>
+          )}
+          <div className="display-flex-center it__hs-assignee">
+            <div className="big-spacer-right">{translate('assignee')}:</div>
             <Assignee hotspot={hotspot} onAssigneeChange={props.onUpdateHotspot} />
           </div>
         </div>
index edeafdd8f91d98fb2a8afd6a4b8ec2b8db3262ac..f759c59ac21278ea0b2b53a764f03befdecb723f 100644 (file)
@@ -87,6 +87,7 @@ export interface Hotspot {
   authorUser: UserBase;
   canChangeStatus: boolean;
   changelog: IssueChangelog[];
+  codeVariants?: string[];
   comment: HotspotComment[];
   component: HotspotComponent;
   creationDate: string;