]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-12333 Cleanup profile inheritance typings, improve coverage
authorWouter Admiraal <wouter.admiraal@sonarsource.com>
Thu, 22 Aug 2019 13:15:54 +0000 (15:15 +0200)
committerSonarTech <sonartech@sonarsource.com>
Tue, 27 Aug 2019 18:21:04 +0000 (20:21 +0200)
server/sonar-web/src/main/js/api/quality-profiles.ts
server/sonar-web/src/main/js/app/types.d.ts
server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritance.tsx
server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritanceBox.tsx
server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileInheritanceBox-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileInheritanceBox-test.tsx.snap [new file with mode: 0644]
server/sonar-web/src/main/js/helpers/testMocks.ts

index b1a5459d4fce699b29848833c947092918c91fc4..e9f79660f51374f722d861d1e06a937f50179546 100644 (file)
@@ -101,7 +101,13 @@ export function getProfileProjects(
   return getJSON('/api/qualityprofiles/projects', data).catch(throwGlobalError);
 }
 
-export function getProfileInheritance(profileKey: string): Promise<any> {
+export function getProfileInheritance(
+  profileKey: string
+): Promise<{
+  ancestors: T.ProfileInheritanceDetails[];
+  children: T.ProfileInheritanceDetails[];
+  profile: T.ProfileInheritanceDetails;
+}> {
   return getJSON('/api/qualityprofiles/inheritance', { profileKey }).catch(throwGlobalError);
 }
 
index 09accb78d73b079d77cd9563924d67b5652f40a0..8bfd5c55adcf08bd5b9e6945fdec6f631b5ca4ac 100644 (file)
@@ -614,6 +614,14 @@ declare namespace T {
     }>;
   }
 
+  export interface ProfileInheritanceDetails {
+    activeRuleCount: number;
+    isBuiltIn: boolean;
+    key: string;
+    name: string;
+    overridingRuleCount?: number;
+  }
+
   export interface ProjectLink {
     id: string;
     name?: string;
index 745583c979bb300b2b222c6adb5dc5d8ad461c90..98c4879c0125b102ed7e07cce898dd127be9decf 100644 (file)
@@ -33,21 +33,12 @@ interface Props {
   updateProfiles: () => Promise<void>;
 }
 
-interface ProfileInheritanceDetails {
-  activeRuleCount: number;
-  isBuiltIn: boolean;
-  key: string;
-  language: string;
-  name: string;
-  overridingRuleCount?: number;
-}
-
 interface State {
-  ancestors?: Array<ProfileInheritanceDetails>;
-  children?: Array<ProfileInheritanceDetails>;
+  ancestors?: T.ProfileInheritanceDetails[];
+  children?: T.ProfileInheritanceDetails[];
   formOpen: boolean;
   loading: boolean;
-  profile?: ProfileInheritanceDetails;
+  profile?: T.ProfileInheritanceDetails;
 }
 
 export default class ProfileInheritance extends React.PureComponent<Props, State> {
@@ -78,9 +69,11 @@ export default class ProfileInheritance extends React.PureComponent<Props, State
       r => {
         if (this.mounted) {
           const { ancestors, children } = r;
+          ancestors.reverse();
+
           this.setState({
             children,
-            ancestors: ancestors.reverse(),
+            ancestors,
             profile: r.profile,
             loading: false
           });
@@ -167,7 +160,6 @@ export default class ProfileInheritance extends React.PureComponent<Props, State
                     language={profile.language}
                     organization={this.props.organization}
                     profile={this.state.profile}
-                    type="current"
                   />
                 )}
 
index 29c8e6ccc3e5faf5ed25b1262875f31b2774dcfe..59e2428633a2fd6c64a842e4e50784284a8170ca 100644 (file)
@@ -30,20 +30,22 @@ interface Props {
   extendsBuiltIn?: boolean;
   language: string;
   organization: string | null;
-  profile: {
-    activeRuleCount: number;
-    isBuiltIn: boolean;
-    key: string;
-    language: string;
-    name: string;
-    overridingRuleCount?: number;
-  };
-  type: string;
+  profile: T.ProfileInheritanceDetails;
+  type?: string;
 }
 
-export default function ProfileInheritanceBox({ type, displayLink = true, ...props }: Props) {
-  const { profile, className, extendsBuiltIn } = props;
-  const offset = 25 * props.depth;
+export default function ProfileInheritanceBox(props: Props) {
+  const {
+    className,
+    depth,
+    extendsBuiltIn,
+    language,
+    organization,
+    profile,
+    displayLink = true,
+    type = 'current'
+  } = props;
+  const offset = 25 * depth;
 
   return (
     <tr className={className} data-test={`quality-profiles__inheritance-${type}`}>
@@ -52,9 +54,9 @@ export default function ProfileInheritanceBox({ type, displayLink = true, ...pro
           {displayLink ? (
             <ProfileLink
               className="text-middle"
-              language={props.language}
+              language={language}
               name={profile.name}
-              organization={props.organization}>
+              organization={organization}>
               {profile.name}
             </ProfileLink>
           ) : (
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileInheritanceBox-test.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileInheritanceBox-test.tsx
new file mode 100644 (file)
index 0000000..fc03dde
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import { shallow } from 'enzyme';
+import * as React from 'react';
+import { mockQualityProfileInheritance } from '../../../../helpers/testMocks';
+import ProfileInheritanceBox from '../ProfileInheritanceBox';
+
+it('should render correctly', () => {
+  expect(shallowRender()).toMatchSnapshot();
+  expect(
+    shallowRender({
+      depth: 3,
+      displayLink: true,
+      profile: mockQualityProfileInheritance({ isBuiltIn: true })
+    })
+  ).toMatchSnapshot();
+  expect(shallowRender({ extendsBuiltIn: true })).toMatchSnapshot();
+  expect(
+    shallowRender({ profile: mockQualityProfileInheritance({ overridingRuleCount: 10 }) })
+  ).toMatchSnapshot();
+});
+
+function shallowRender(props = {}) {
+  return shallow(
+    <ProfileInheritanceBox
+      depth={1}
+      language="foo"
+      organization={null}
+      profile={mockQualityProfileInheritance()}
+      {...props}
+    />
+  );
+}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileInheritanceBox-test.tsx.snap b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileInheritanceBox-test.tsx.snap
new file mode 100644 (file)
index 0000000..934da5e
--- /dev/null
@@ -0,0 +1,140 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<tr
+  data-test="quality-profiles__inheritance-current"
+>
+  <td>
+    <div
+      style={
+        Object {
+          "paddingLeft": 25,
+        }
+      }
+    >
+      <ProfileLink
+        className="text-middle"
+        language="foo"
+        name="Foo"
+        organization={null}
+      >
+        Foo
+      </ProfileLink>
+    </div>
+  </td>
+  <td>
+    quality_profile.x_active_rules.4
+  </td>
+  <td>
+    <p>
+      quality_profiles.x_overridden_rules.0
+    </p>
+  </td>
+</tr>
+`;
+
+exports[`should render correctly 2`] = `
+<tr
+  data-test="quality-profiles__inheritance-current"
+>
+  <td>
+    <div
+      style={
+        Object {
+          "paddingLeft": 75,
+        }
+      }
+    >
+      <ProfileLink
+        className="text-middle"
+        language="foo"
+        name="Foo"
+        organization={null}
+      >
+        Foo
+      </ProfileLink>
+      <BuiltInQualityProfileBadge
+        className="spacer-left"
+      />
+    </div>
+  </td>
+  <td>
+    quality_profile.x_active_rules.4
+  </td>
+  <td>
+    <p>
+      quality_profiles.x_overridden_rules.0
+    </p>
+  </td>
+</tr>
+`;
+
+exports[`should render correctly 3`] = `
+<tr
+  data-test="quality-profiles__inheritance-current"
+>
+  <td>
+    <div
+      style={
+        Object {
+          "paddingLeft": 25,
+        }
+      }
+    >
+      <ProfileLink
+        className="text-middle"
+        language="foo"
+        name="Foo"
+        organization={null}
+      >
+        Foo
+      </ProfileLink>
+      <HelpTooltip
+        className="spacer-left"
+        overlay="quality_profiles.extends_built_in"
+      />
+    </div>
+  </td>
+  <td>
+    quality_profile.x_active_rules.4
+  </td>
+  <td>
+    <p>
+      quality_profiles.x_overridden_rules.0
+    </p>
+  </td>
+</tr>
+`;
+
+exports[`should render correctly 4`] = `
+<tr
+  data-test="quality-profiles__inheritance-current"
+>
+  <td>
+    <div
+      style={
+        Object {
+          "paddingLeft": 25,
+        }
+      }
+    >
+      <ProfileLink
+        className="text-middle"
+        language="foo"
+        name="Foo"
+        organization={null}
+      >
+        Foo
+      </ProfileLink>
+    </div>
+  </td>
+  <td>
+    quality_profile.x_active_rules.4
+  </td>
+  <td>
+    <p>
+      quality_profiles.x_overridden_rules.10
+    </p>
+  </td>
+</tr>
+`;
index 03b6da9b100cbb81ac8b651e4ad95cbc86276339..9554291413497bc47d8f530c3ccb4df54ea83c5d 100644 (file)
@@ -552,6 +552,19 @@ export function mockQualityProfile(overrides: Partial<Profile> = {}): Profile {
   };
 }
 
+export function mockQualityProfileInheritance(
+  overrides: Partial<T.ProfileInheritanceDetails> = {}
+): T.ProfileInheritanceDetails {
+  return {
+    activeRuleCount: 4,
+    isBuiltIn: false,
+    key: 'foo',
+    name: 'Foo',
+    overridingRuleCount: 0,
+    ...overrides
+  };
+}
+
 export function mockQualityGateProjectStatus(
   overrides: Partial<T.QualityGateProjectStatus> = {}
 ): T.QualityGateProjectStatus {