]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-15279 Enable bulk change for profile editors
authorWouter Admiraal <45544358+wouter-admiraal-sonarsource@users.noreply.github.com>
Tue, 24 Aug 2021 11:25:20 +0000 (13:25 +0200)
committersonartech <sonartech@sonarsource.com>
Tue, 24 Aug 2021 20:07:42 +0000 (20:07 +0000)
server/sonar-web/src/main/js/apps/coding-rules/components/App.tsx
server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/App-test.tsx
server/sonar-web/src/main/js/apps/coding-rules/components/__tests__/__snapshots__/App-test.tsx.snap

index db8c6cbb9e5db85242c21417ff86d92b46bc7a94..b1326f513417e0b78e3692cffdd270c18f25a2fd 100644 (file)
@@ -526,9 +526,10 @@ export class App extends React.PureComponent<Props, State> {
   renderBulkButton = () => {
     const { currentUser, languages } = this.props;
     const { canWrite, paging, query, referencedProfiles } = this.state;
+    const canUpdate = canWrite || Object.values(referencedProfiles).some(p => p.actions?.edit);
 
-    if (!isLoggedIn(currentUser) || !canWrite) {
-      return null;
+    if (!isLoggedIn(currentUser) || !canUpdate) {
+      return <div />;
     }
 
     return (
index c0299fee5f120ee335d217fdfba1369b61573cd2..78d7af610970ebee846c813983eb01761aa7ab6e 100644 (file)
  */
 import { shallow } from 'enzyme';
 import * as React from 'react';
+import { searchQualityProfiles } from '../../../../api/quality-profiles';
 import { getRulesApp } from '../../../../api/rules';
 import ScreenPositionHelper from '../../../../components/common/ScreenPositionHelper';
-import { mockCurrentUser, mockLocation, mockRouter, mockRule } from '../../../../helpers/testMocks';
+import {
+  mockCurrentUser,
+  mockLocation,
+  mockQualityProfile,
+  mockRouter,
+  mockRule
+} from '../../../../helpers/testMocks';
 import { waitAndUpdate } from '../../../../helpers/testUtils';
 import { App } from '../App';
 
@@ -78,18 +85,30 @@ describe('renderBulkButton', () => {
     const wrapper = shallowRender({
       currentUser: mockCurrentUser()
     });
-    expect(wrapper.instance().renderBulkButton()).toBeNull();
+    expect(wrapper.instance().renderBulkButton()).toMatchSnapshot();
   });
 
   it('should be null when the user does not have the sufficient permission', () => {
-    (getRulesApp as jest.Mock).mockReturnValue({ canWrite: false, repositories: [] });
+    (getRulesApp as jest.Mock).mockReturnValueOnce({ canWrite: false, repositories: [] });
+
+    const wrapper = shallowRender();
+    expect(wrapper.instance().renderBulkButton()).toMatchSnapshot();
+  });
 
+  it('should show bulk change button when user has global admin rights on quality profiles', async () => {
+    (getRulesApp as jest.Mock).mockReturnValueOnce({ canWrite: true, repositories: [] });
     const wrapper = shallowRender();
-    expect(wrapper.instance().renderBulkButton()).toBeNull();
+    await waitAndUpdate(wrapper);
+
+    expect(wrapper.instance().renderBulkButton()).toMatchSnapshot();
   });
 
-  it('should show bulk change button when everything is fine', async () => {
-    (getRulesApp as jest.Mock).mockReturnValue({ canWrite: true, repositories: [] });
+  it('should show bulk change button when user has edit rights on specific quality profile', async () => {
+    (getRulesApp as jest.Mock).mockReturnValueOnce({ canWrite: false, repositories: [] });
+    (searchQualityProfiles as jest.Mock).mockReturnValueOnce({
+      profiles: [mockQualityProfile({ key: 'foo', actions: { edit: true } }), mockQualityProfile()]
+    });
+
     const wrapper = shallowRender();
     await waitAndUpdate(wrapper);
 
index 032ad5545045dd8721db653da3bffe289ac1ecba..09a0e14f6fbd016ed70e9190528f965673109fca 100644 (file)
@@ -1,6 +1,82 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`renderBulkButton should show bulk change button when everything is fine 1`] = `
+exports[`renderBulkButton should be null when the user does not have the sufficient permission 1`] = `<div />`;
+
+exports[`renderBulkButton should be null when the user is not logged in 1`] = `<div />`;
+
+exports[`renderBulkButton should show bulk change button when user has edit rights on specific quality profile 1`] = `
+<BulkChange
+  languages={
+    Object {
+      "js": Object {
+        "key": "js",
+        "name": "JavaScript",
+      },
+    }
+  }
+  query={
+    Object {
+      "activation": undefined,
+      "activationSeverities": Array [],
+      "availableSince": undefined,
+      "compareToProfile": undefined,
+      "cwe": Array [],
+      "inheritance": undefined,
+      "languages": Array [],
+      "owaspTop10": Array [],
+      "profile": undefined,
+      "repositories": Array [],
+      "ruleKey": undefined,
+      "sansTop25": Array [],
+      "searchQuery": undefined,
+      "severities": Array [],
+      "sonarsourceSecurity": Array [],
+      "statuses": Array [],
+      "tags": Array [],
+      "template": undefined,
+      "types": Array [],
+    }
+  }
+  referencedProfiles={
+    Object {
+      "foo": Object {
+        "actions": Object {
+          "edit": true,
+        },
+        "activeDeprecatedRuleCount": 2,
+        "activeRuleCount": 10,
+        "childrenCount": 0,
+        "depth": 1,
+        "isBuiltIn": false,
+        "isDefault": false,
+        "isInherited": false,
+        "key": "foo",
+        "language": "js",
+        "languageName": "JavaScript",
+        "name": "name",
+        "projectCount": 3,
+      },
+      "key": Object {
+        "activeDeprecatedRuleCount": 2,
+        "activeRuleCount": 10,
+        "childrenCount": 0,
+        "depth": 1,
+        "isBuiltIn": false,
+        "isDefault": false,
+        "isInherited": false,
+        "key": "key",
+        "language": "js",
+        "languageName": "JavaScript",
+        "name": "name",
+        "projectCount": 3,
+      },
+    }
+  }
+  total={0}
+/>
+`;
+
+exports[`renderBulkButton should show bulk change button when user has global admin rights on quality profiles 1`] = `
 <BulkChange
   languages={
     Object {
@@ -322,6 +398,7 @@ exports[`should render correctly: loading 1`] = `
             <div
               className="display-flex-space-between"
             >
+              <div />
               <PageActions
                 loading={true}
                 onReload={[Function]}