]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-11369 Update UI using WS mock
authorPascal Mugnier <pascal.mugnier@sonarsource.com>
Mon, 22 Oct 2018 12:40:40 +0000 (14:40 +0200)
committerSonarTech <sonartech@sonarsource.com>
Thu, 25 Oct 2018 18:21:01 +0000 (20:21 +0200)
server/sonar-web/src/main/js/api/security-reports.ts
server/sonar-web/src/main/js/app/types.ts
server/sonar-web/src/main/js/apps/securityReports/components/VulnerabilityList.tsx
server/sonar-web/src/main/js/apps/securityReports/components/__tests__/App-test.tsx
server/sonar-web/src/main/js/apps/securityReports/components/__tests__/VulnerabilityList-test.tsx
server/sonar-web/src/main/js/apps/securityReports/components/__tests__/__snapshots__/App-test.tsx.snap
server/sonar-web/src/main/js/apps/securityReports/components/__tests__/__snapshots__/VulnerabilityList-test.tsx.snap

index 2747ea7536ffd2765d29ea71178cfc19e0e5d671..74006076097c3fe384505110001e513c8c04b17f 100644 (file)
@@ -27,5 +27,15 @@ export function getSecurityHotspots(data: {
   includeDistribution?: boolean;
   branch?: string;
 }): Promise<{ categories: Array<SecurityHotspot> }> {
-  return getJSON('/api/security_reports/show', data).catch(throwGlobalError);
+  return getJSON('/api/security_reports/show', data)
+    .then(data => {
+      /* MOCK, must be removed after backend implementation */
+      data.categories = data.categories.map((v: SecurityHotspot, index: number) => {
+        v.activeRules = index;
+        v.totalRules = 200;
+        return v;
+      });
+      return data;
+    })
+    .catch(throwGlobalError);
 }
index 658d67ebed82d3fac20cd9fdbae1b3595ad67ac1..20827b40e4ebc448e9748749f097e3afcbfdcab2 100644 (file)
@@ -298,11 +298,13 @@ export function isSameHomePage(a: HomePage, b: HomePage) {
 }
 
 export interface SecurityHotspot {
+  activeRules: number;
   category?: string;
   cwe?: string;
   distribution?: Array<SecurityHotspot>;
   openSecurityHotspots: number;
   toReviewSecurityHotspots: number;
+  totalRules: number;
   vulnerabilities: number;
   vulnerabilityRating?: number;
   wontFixSecurityHotspots: number;
index d3cbb28a78d9b0da10de3f2fd3681cae49c1fb08..e566a2405fb58b16be8cedc8f4b8b32e9b66ea63 100755 (executable)
@@ -41,7 +41,7 @@ import { getRatingTooltip } from '../../../helpers/measures';
 interface Props {
   branchLike?: BranchLike;
   component: Component;
-  findings: Array<SecurityHotspot>;
+  findings: SecurityHotspot[];
   showCWE: boolean;
   type: 'owaspTop10' | 'sansTop25' | 'cwe';
 }
@@ -140,6 +140,7 @@ export default class VulnerabilityList extends React.PureComponent<Props, State>
         : null;
 
     const title = getRatingTooltip('security_rating', finding.vulnerabilityRating || 1);
+    const hasActiveRules = finding.activeRules > 0;
     return (
       <React.Fragment key={finding.category || finding.cwe}>
         <tr>
@@ -147,60 +148,72 @@ export default class VulnerabilityList extends React.PureComponent<Props, State>
             {this.getName(finding, isCWE ? 'cwe' : type)}
           </td>
           <td className="text-right">
-            <div className="display-inline-flex-center">
-              <Link
-                to={getComponentIssuesUrl(component.key, {
-                  ...params,
-                  types: IssueType.Vulnerability,
-                  resolved: 'false'
-                })}>
-                {finding.vulnerabilities}
-              </Link>
-              <Tooltip overlay={title}>
+            {!hasActiveRules && '-'}
+            {hasActiveRules && (
+              <div className="display-inline-flex-center">
                 <Link
-                  className="link-no-underline spacer-left"
                   to={getComponentIssuesUrl(component.key, {
                     ...params,
                     types: IssueType.Vulnerability,
                     resolved: 'false'
                   })}>
-                  <Rating value={finding.vulnerabilityRating || 1} />
+                  {finding.vulnerabilities}
                 </Link>
-              </Tooltip>
-            </div>
+                <Tooltip overlay={title}>
+                  <Link
+                    className="link-no-underline spacer-left"
+                    to={getComponentIssuesUrl(component.key, {
+                      ...params,
+                      types: IssueType.Vulnerability,
+                      resolved: 'false'
+                    })}>
+                    <Rating value={finding.vulnerabilityRating || 1} />
+                  </Link>
+                </Tooltip>
+              </div>
+            )}
           </td>
           <td className="text-right security-column-separator">
-            <Link
-              to={getComponentIssuesUrl(component.key, {
-                ...params,
-                types: IssueType.Hotspot,
-                resolved: 'false',
-                statuses: 'OPEN,REOPENED'
-              })}>
-              {finding.openSecurityHotspots}
-            </Link>
+            {!hasActiveRules && '-'}
+            {hasActiveRules && (
+              <Link
+                to={getComponentIssuesUrl(component.key, {
+                  ...params,
+                  types: IssueType.Hotspot,
+                  resolved: 'false',
+                  statuses: 'OPEN,REOPENED'
+                })}>
+                {finding.openSecurityHotspots}
+              </Link>
+            )}
           </td>
           <td className="text-right">
-            <Link
-              to={getComponentIssuesUrl(component.key, {
-                ...params,
-                types: IssueType.Hotspot,
-                resolutions: 'FIXED',
-                statuses: 'RESOLVED'
-              })}>
-              {finding.toReviewSecurityHotspots}
-            </Link>
+            {!hasActiveRules && '-'}
+            {hasActiveRules && (
+              <Link
+                to={getComponentIssuesUrl(component.key, {
+                  ...params,
+                  types: IssueType.Hotspot,
+                  resolutions: 'FIXED',
+                  statuses: 'RESOLVED'
+                })}>
+                {finding.toReviewSecurityHotspots}
+              </Link>
+            )}
           </td>
           <td className="text-right">
-            <Link
-              to={getComponentIssuesUrl(component.key, {
-                ...params,
-                types: IssueType.Hotspot,
-                resolutions: 'WONTFIX',
-                statuses: 'RESOLVED'
-              })}>
-              {finding.wontFixSecurityHotspots}
-            </Link>
+            {!hasActiveRules && '-'}
+            {hasActiveRules && (
+              <Link
+                to={getComponentIssuesUrl(component.key, {
+                  ...params,
+                  types: IssueType.Hotspot,
+                  resolutions: 'WONTFIX',
+                  statuses: 'RESOLVED'
+                })}>
+                {finding.wontFixSecurityHotspots}
+              </Link>
+            )}
           </td>
         </tr>
         {subFindings}
index f2ed70898637137078882ba9135bfb31482121fb..cdc43e9abdfe70c7cd43eba15722208fb0470e57 100644 (file)
@@ -41,6 +41,8 @@ jest.mock('../../../../api/security-reports', () => ({
     return Promise.resolve({
       categories: [
         {
+          activeRules: 1,
+          totalRules: 1,
           category: 'a1',
           vulnerabilities: 2,
           vulnerabiliyRating: 5,
@@ -50,6 +52,8 @@ jest.mock('../../../../api/security-reports', () => ({
           distribution
         },
         {
+          activeRules: 1,
+          totalRules: 1,
           category: 'a2',
           vulnerabilities: 3,
           vulnerabiliyRating: 3,
index 32f1efeaa98d85a271ba370aaac20c0b46c3bcfe..06f6ed58ae1d9d5252538b4de506dcf5169b53f5 100644 (file)
@@ -33,6 +33,8 @@ jest.mock('../../../../helpers/standards.json', () => ({
 const component = { key: 'foo', name: 'Foo', qualifier: 'TRK' } as Component;
 const findings = [
   {
+    activeRules: 1,
+    totalRules: 1,
     category: 'a1',
     vulnerabilities: 2,
     vulnerabilityRating: 5,
@@ -41,6 +43,8 @@ const findings = [
     wontFixSecurityHotspots: 0,
     distribution: [
       {
+        activeRules: 1,
+        totalRules: 1,
         cwe: '42',
         vulnerabilities: 1,
         vulnerabilityRating: 1,
@@ -51,6 +55,52 @@ const findings = [
     ]
   },
   {
+    activeRules: 1,
+    totalRules: 2,
+    category: 'a2',
+    vulnerabilities: 2,
+    vulnerabilityRating: 5,
+    toReviewSecurityHotspots: 2,
+    openSecurityHotspots: 10,
+    wontFixSecurityHotspots: 0,
+    distribution: [
+      {
+        activeRules: 1,
+        totalRules: 1,
+        cwe: '42',
+        vulnerabilities: 1,
+        vulnerabilityRating: 1,
+        toReviewSecurityHotspots: 2,
+        openSecurityHotspots: 10,
+        wontFixSecurityHotspots: 0
+      }
+    ]
+  },
+  {
+    activeRules: 0,
+    totalRules: 1,
+    category: 'a3',
+    vulnerabilities: 2,
+    vulnerabilityRating: 5,
+    toReviewSecurityHotspots: 2,
+    openSecurityHotspots: 10,
+    wontFixSecurityHotspots: 0,
+    distribution: [
+      {
+        activeRules: 1,
+        totalRules: 1,
+        cwe: '42',
+        vulnerabilities: 1,
+        vulnerabilityRating: 1,
+        toReviewSecurityHotspots: 2,
+        openSecurityHotspots: 10,
+        wontFixSecurityHotspots: 0
+      }
+    ]
+  },
+  {
+    activeRules: 1,
+    totalRules: 1,
     category: 'unknown',
     vulnerabilities: 3,
     vulnerabilityRating: 3,
@@ -69,7 +119,7 @@ it('renders', () => {
       type="owaspTop10"
     />
   );
-  expect(wrapper.find('tr').length).toBe(4);
+  expect(wrapper.find('tr').length).toBe(6);
   expect(wrapper).toMatchSnapshot();
 });
 
@@ -77,6 +127,6 @@ it('renders with cwe', () => {
   const wrapper = shallow(
     <VulnerabilityList component={component} findings={findings} showCWE={true} type="owaspTop10" />
   );
-  expect(wrapper.find('tr').length).toBe(5);
+  expect(wrapper.find('tr').length).toBe(9);
   expect(wrapper).toMatchSnapshot();
 });
index abab05f553e6cc710f613b6efb7cdca0f44321e9..f61e0fc1a5d336d550c5848b26e069c9cf304bc9 100644 (file)
@@ -215,6 +215,7 @@ exports[`handle checkbox for cwe display 2`] = `
       findings={
         Array [
           Object {
+            "activeRules": 1,
             "category": "a1",
             "distribution": Array [
               Object {
@@ -236,14 +237,17 @@ exports[`handle checkbox for cwe display 2`] = `
             ],
             "openSecurityHotspots": 10,
             "toReviewSecurityHotspots": 2,
+            "totalRules": 1,
             "vulnerabilities": 2,
             "vulnerabiliyRating": 5,
             "wontFixSecurityHotspots": 0,
           },
           Object {
+            "activeRules": 1,
             "category": "a2",
             "openSecurityHotspots": 100,
             "toReviewSecurityHotspots": 8,
+            "totalRules": 1,
             "vulnerabilities": 3,
             "vulnerabiliyRating": 3,
             "wontFixSecurityHotspots": 10,
index d296ead10a74c3c3be48307b442dfe6193ca3ae9..5c19bde0e7c125b8a319f59ce7333ef485f78df3 100644 (file)
@@ -192,6 +192,167 @@ exports[`renders 1`] = `
           </td>
         </tr>
       </React.Fragment>
+      <React.Fragment
+        key="a2"
+      >
+        <tr>
+          <td
+            className=""
+          >
+            <React.Fragment>
+              A2
+            </React.Fragment>
+          </td>
+          <td
+            className="text-right"
+          >
+            <div
+              className="display-inline-flex-center"
+            >
+              <Link
+                onlyActiveOnIndex={false}
+                style={Object {}}
+                to={
+                  Object {
+                    "pathname": "/project/issues",
+                    "query": Object {
+                      "id": "foo",
+                      "owaspTop10": "a2",
+                      "resolved": "false",
+                      "types": "VULNERABILITY",
+                    },
+                  }
+                }
+              >
+                2
+              </Link>
+              <Tooltip
+                overlay="metric.security_rating.tooltip.E"
+              >
+                <Link
+                  className="link-no-underline spacer-left"
+                  onlyActiveOnIndex={false}
+                  style={Object {}}
+                  to={
+                    Object {
+                      "pathname": "/project/issues",
+                      "query": Object {
+                        "id": "foo",
+                        "owaspTop10": "a2",
+                        "resolved": "false",
+                        "types": "VULNERABILITY",
+                      },
+                    }
+                  }
+                >
+                  <Rating
+                    value={5}
+                  />
+                </Link>
+              </Tooltip>
+            </div>
+          </td>
+          <td
+            className="text-right security-column-separator"
+          >
+            <Link
+              onlyActiveOnIndex={false}
+              style={Object {}}
+              to={
+                Object {
+                  "pathname": "/project/issues",
+                  "query": Object {
+                    "id": "foo",
+                    "owaspTop10": "a2",
+                    "resolved": "false",
+                    "statuses": "OPEN,REOPENED",
+                    "types": "SECURITY_HOTSPOT",
+                  },
+                }
+              }
+            >
+              10
+            </Link>
+          </td>
+          <td
+            className="text-right"
+          >
+            <Link
+              onlyActiveOnIndex={false}
+              style={Object {}}
+              to={
+                Object {
+                  "pathname": "/project/issues",
+                  "query": Object {
+                    "id": "foo",
+                    "owaspTop10": "a2",
+                    "resolutions": "FIXED",
+                    "statuses": "RESOLVED",
+                    "types": "SECURITY_HOTSPOT",
+                  },
+                }
+              }
+            >
+              2
+            </Link>
+          </td>
+          <td
+            className="text-right"
+          >
+            <Link
+              onlyActiveOnIndex={false}
+              style={Object {}}
+              to={
+                Object {
+                  "pathname": "/project/issues",
+                  "query": Object {
+                    "id": "foo",
+                    "owaspTop10": "a2",
+                    "resolutions": "WONTFIX",
+                    "statuses": "RESOLVED",
+                    "types": "SECURITY_HOTSPOT",
+                  },
+                }
+              }
+            >
+              0
+            </Link>
+          </td>
+        </tr>
+      </React.Fragment>
+      <React.Fragment
+        key="a3"
+      >
+        <tr>
+          <td
+            className=""
+          >
+            <React.Fragment>
+              A3
+            </React.Fragment>
+          </td>
+          <td
+            className="text-right"
+          >
+            -
+          </td>
+          <td
+            className="text-right security-column-separator"
+          >
+            -
+          </td>
+          <td
+            className="text-right"
+          >
+            -
+          </td>
+          <td
+            className="text-right"
+          >
+            -
+          </td>
+        </tr>
+      </React.Fragment>
       <React.Fragment
         key="unknown"
       >
@@ -650,6 +811,433 @@ exports[`renders with cwe 1`] = `
           </tr>
         </React.Fragment>
       </React.Fragment>
+      <React.Fragment
+        key="a2"
+      >
+        <tr>
+          <td
+            className=""
+          >
+            <React.Fragment>
+              A2
+            </React.Fragment>
+          </td>
+          <td
+            className="text-right"
+          >
+            <div
+              className="display-inline-flex-center"
+            >
+              <Link
+                onlyActiveOnIndex={false}
+                style={Object {}}
+                to={
+                  Object {
+                    "pathname": "/project/issues",
+                    "query": Object {
+                      "id": "foo",
+                      "owaspTop10": "a2",
+                      "resolved": "false",
+                      "types": "VULNERABILITY",
+                    },
+                  }
+                }
+              >
+                2
+              </Link>
+              <Tooltip
+                overlay="metric.security_rating.tooltip.E"
+              >
+                <Link
+                  className="link-no-underline spacer-left"
+                  onlyActiveOnIndex={false}
+                  style={Object {}}
+                  to={
+                    Object {
+                      "pathname": "/project/issues",
+                      "query": Object {
+                        "id": "foo",
+                        "owaspTop10": "a2",
+                        "resolved": "false",
+                        "types": "VULNERABILITY",
+                      },
+                    }
+                  }
+                >
+                  <Rating
+                    value={5}
+                  />
+                </Link>
+              </Tooltip>
+            </div>
+          </td>
+          <td
+            className="text-right security-column-separator"
+          >
+            <Link
+              onlyActiveOnIndex={false}
+              style={Object {}}
+              to={
+                Object {
+                  "pathname": "/project/issues",
+                  "query": Object {
+                    "id": "foo",
+                    "owaspTop10": "a2",
+                    "resolved": "false",
+                    "statuses": "OPEN,REOPENED",
+                    "types": "SECURITY_HOTSPOT",
+                  },
+                }
+              }
+            >
+              10
+            </Link>
+          </td>
+          <td
+            className="text-right"
+          >
+            <Link
+              onlyActiveOnIndex={false}
+              style={Object {}}
+              to={
+                Object {
+                  "pathname": "/project/issues",
+                  "query": Object {
+                    "id": "foo",
+                    "owaspTop10": "a2",
+                    "resolutions": "FIXED",
+                    "statuses": "RESOLVED",
+                    "types": "SECURITY_HOTSPOT",
+                  },
+                }
+              }
+            >
+              2
+            </Link>
+          </td>
+          <td
+            className="text-right"
+          >
+            <Link
+              onlyActiveOnIndex={false}
+              style={Object {}}
+              to={
+                Object {
+                  "pathname": "/project/issues",
+                  "query": Object {
+                    "id": "foo",
+                    "owaspTop10": "a2",
+                    "resolutions": "WONTFIX",
+                    "statuses": "RESOLVED",
+                    "types": "SECURITY_HOTSPOT",
+                  },
+                }
+              }
+            >
+              0
+            </Link>
+          </td>
+        </tr>
+        <React.Fragment
+          key="42"
+        >
+          <tr>
+            <td
+              className="cwe-title-cell"
+            >
+              <React.Fragment>
+                CWE-42
+              </React.Fragment>
+            </td>
+            <td
+              className="text-right"
+            >
+              <div
+                className="display-inline-flex-center"
+              >
+                <Link
+                  onlyActiveOnIndex={false}
+                  style={Object {}}
+                  to={
+                    Object {
+                      "pathname": "/project/issues",
+                      "query": Object {
+                        "cwe": "42",
+                        "id": "foo",
+                        "owaspTop10": "a2",
+                        "resolved": "false",
+                        "types": "VULNERABILITY",
+                      },
+                    }
+                  }
+                >
+                  1
+                </Link>
+                <Tooltip
+                  overlay="metric.security_rating.tooltip.A"
+                >
+                  <Link
+                    className="link-no-underline spacer-left"
+                    onlyActiveOnIndex={false}
+                    style={Object {}}
+                    to={
+                      Object {
+                        "pathname": "/project/issues",
+                        "query": Object {
+                          "cwe": "42",
+                          "id": "foo",
+                          "owaspTop10": "a2",
+                          "resolved": "false",
+                          "types": "VULNERABILITY",
+                        },
+                      }
+                    }
+                  >
+                    <Rating
+                      value={1}
+                    />
+                  </Link>
+                </Tooltip>
+              </div>
+            </td>
+            <td
+              className="text-right security-column-separator"
+            >
+              <Link
+                onlyActiveOnIndex={false}
+                style={Object {}}
+                to={
+                  Object {
+                    "pathname": "/project/issues",
+                    "query": Object {
+                      "cwe": "42",
+                      "id": "foo",
+                      "owaspTop10": "a2",
+                      "resolved": "false",
+                      "statuses": "OPEN,REOPENED",
+                      "types": "SECURITY_HOTSPOT",
+                    },
+                  }
+                }
+              >
+                10
+              </Link>
+            </td>
+            <td
+              className="text-right"
+            >
+              <Link
+                onlyActiveOnIndex={false}
+                style={Object {}}
+                to={
+                  Object {
+                    "pathname": "/project/issues",
+                    "query": Object {
+                      "cwe": "42",
+                      "id": "foo",
+                      "owaspTop10": "a2",
+                      "resolutions": "FIXED",
+                      "statuses": "RESOLVED",
+                      "types": "SECURITY_HOTSPOT",
+                    },
+                  }
+                }
+              >
+                2
+              </Link>
+            </td>
+            <td
+              className="text-right"
+            >
+              <Link
+                onlyActiveOnIndex={false}
+                style={Object {}}
+                to={
+                  Object {
+                    "pathname": "/project/issues",
+                    "query": Object {
+                      "cwe": "42",
+                      "id": "foo",
+                      "owaspTop10": "a2",
+                      "resolutions": "WONTFIX",
+                      "statuses": "RESOLVED",
+                      "types": "SECURITY_HOTSPOT",
+                    },
+                  }
+                }
+              >
+                0
+              </Link>
+            </td>
+          </tr>
+        </React.Fragment>
+      </React.Fragment>
+      <React.Fragment
+        key="a3"
+      >
+        <tr>
+          <td
+            className=""
+          >
+            <React.Fragment>
+              A3
+            </React.Fragment>
+          </td>
+          <td
+            className="text-right"
+          >
+            -
+          </td>
+          <td
+            className="text-right security-column-separator"
+          >
+            -
+          </td>
+          <td
+            className="text-right"
+          >
+            -
+          </td>
+          <td
+            className="text-right"
+          >
+            -
+          </td>
+        </tr>
+        <React.Fragment
+          key="42"
+        >
+          <tr>
+            <td
+              className="cwe-title-cell"
+            >
+              <React.Fragment>
+                CWE-42
+              </React.Fragment>
+            </td>
+            <td
+              className="text-right"
+            >
+              <div
+                className="display-inline-flex-center"
+              >
+                <Link
+                  onlyActiveOnIndex={false}
+                  style={Object {}}
+                  to={
+                    Object {
+                      "pathname": "/project/issues",
+                      "query": Object {
+                        "cwe": "42",
+                        "id": "foo",
+                        "owaspTop10": "a3",
+                        "resolved": "false",
+                        "types": "VULNERABILITY",
+                      },
+                    }
+                  }
+                >
+                  1
+                </Link>
+                <Tooltip
+                  overlay="metric.security_rating.tooltip.A"
+                >
+                  <Link
+                    className="link-no-underline spacer-left"
+                    onlyActiveOnIndex={false}
+                    style={Object {}}
+                    to={
+                      Object {
+                        "pathname": "/project/issues",
+                        "query": Object {
+                          "cwe": "42",
+                          "id": "foo",
+                          "owaspTop10": "a3",
+                          "resolved": "false",
+                          "types": "VULNERABILITY",
+                        },
+                      }
+                    }
+                  >
+                    <Rating
+                      value={1}
+                    />
+                  </Link>
+                </Tooltip>
+              </div>
+            </td>
+            <td
+              className="text-right security-column-separator"
+            >
+              <Link
+                onlyActiveOnIndex={false}
+                style={Object {}}
+                to={
+                  Object {
+                    "pathname": "/project/issues",
+                    "query": Object {
+                      "cwe": "42",
+                      "id": "foo",
+                      "owaspTop10": "a3",
+                      "resolved": "false",
+                      "statuses": "OPEN,REOPENED",
+                      "types": "SECURITY_HOTSPOT",
+                    },
+                  }
+                }
+              >
+                10
+              </Link>
+            </td>
+            <td
+              className="text-right"
+            >
+              <Link
+                onlyActiveOnIndex={false}
+                style={Object {}}
+                to={
+                  Object {
+                    "pathname": "/project/issues",
+                    "query": Object {
+                      "cwe": "42",
+                      "id": "foo",
+                      "owaspTop10": "a3",
+                      "resolutions": "FIXED",
+                      "statuses": "RESOLVED",
+                      "types": "SECURITY_HOTSPOT",
+                    },
+                  }
+                }
+              >
+                2
+              </Link>
+            </td>
+            <td
+              className="text-right"
+            >
+              <Link
+                onlyActiveOnIndex={false}
+                style={Object {}}
+                to={
+                  Object {
+                    "pathname": "/project/issues",
+                    "query": Object {
+                      "cwe": "42",
+                      "id": "foo",
+                      "owaspTop10": "a3",
+                      "resolutions": "WONTFIX",
+                      "statuses": "RESOLVED",
+                      "types": "SECURITY_HOTSPOT",
+                    },
+                  }
+                }
+              >
+                0
+              </Link>
+            </td>
+          </tr>
+        </React.Fragment>
+      </React.Fragment>
       <React.Fragment
         key="unknown"
       >