]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-11935 No WS error message when display issues in removed file
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>
Thu, 25 Apr 2019 12:59:31 +0000 (14:59 +0200)
committerSonarTech <sonartech@sonarsource.com>
Tue, 7 May 2019 18:21:27 +0000 (20:21 +0200)
server/sonar-web/src/main/js/api/components.ts
server/sonar-web/src/main/js/app/components/ComponentContainer.tsx
server/sonar-web/src/main/js/app/components/__tests__/ComponentContainer-test.tsx
server/sonar-web/src/main/js/app/utils/__test__/handleRequiredAuthentication-test.ts [deleted file]
server/sonar-web/src/main/js/app/utils/__tests__/handleRequiredAuthentication-test.ts [new file with mode: 0644]
server/sonar-web/src/main/js/app/utils/__tests__/throwGlobalError-test.ts [new file with mode: 0644]
server/sonar-web/src/main/js/app/utils/throwGlobalError.ts
server/sonar-web/src/main/js/apps/code/utils.ts
server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.tsx

index 6141c5d879bc5ef0646f0157d980d57ecadd1a85..2b98f70503fd967295967de16021d08c379ef74f 100644 (file)
@@ -122,8 +122,8 @@ export function getComponentLeaves(
 
 export function getComponent(
   data: { component: string; metricKeys: string } & T.BranchParameters
-): Promise<any> {
-  return getJSON('/api/measures/component', data).then(r => r.component, throwGlobalError);
+): Promise<{ component: T.ComponentMeasure }> {
+  return getJSON('/api/measures/component', data);
 }
 
 export interface TreeComponent extends T.LightComponent {
@@ -151,17 +151,18 @@ export function getTree(data: {
   return getJSON('/api/components/tree', data).catch(throwGlobalError);
 }
 
+export function getComponentData(data: { component: string } & T.BranchParameters): Promise<any> {
+  return getJSON('/api/components/show', data);
+}
+
 export function doesComponentExists(
   data: { component: string } & T.BranchParameters
 ): Promise<boolean> {
-  return getJSON('/api/components/show', data).then(
-    ({ component }) => component !== undefined,
-    () => false
-  );
+  return getComponentData(data).then(({ component }) => component !== undefined, () => false);
 }
 
 export function getComponentShow(data: { component: string } & T.BranchParameters): Promise<any> {
-  return getJSON('/api/components/show', data).catch(throwGlobalError);
+  return getComponentData(data).catch(throwGlobalError);
 }
 
 export function getParents(component: string): Promise<any> {
@@ -175,10 +176,6 @@ export function getBreadcrumbs(data: { component: string } & T.BranchParameters)
   });
 }
 
-export function getComponentData(data: { component: string } & T.BranchParameters): Promise<any> {
-  return getComponentShow(data).then(r => r.component);
-}
-
 export function getMyProjects(data: {
   p?: number;
   ps?: number;
index b5294b5941491560a8c9559e90bfa908de23fbf6..9ef3f832d684f894a93ebc13dcdd1dd435c08c74 100644 (file)
@@ -114,28 +114,30 @@ export class ComponentContainer extends React.PureComponent<Props, State> {
       getComponentNavigation({ component: key, branch, pullRequest }),
       getComponentData({ component: key, branch, pullRequest })
     ])
-      .then(([nav, data]) => {
-        const component = this.addQualifier({ ...nav, ...data });
+      .then(([nav, { component }]) => {
+        const componentWithQualifier = this.addQualifier({ ...nav, ...component });
 
         if (isSonarCloud()) {
-          this.props.fetchOrganization(component.organization);
+          this.props.fetchOrganization(componentWithQualifier.organization);
         }
-        return component;
-      })
+        return componentWithQualifier;
+      }, onError)
       .then(this.fetchBranches)
-      .then(({ branchLike, branchLikes, component }) => {
-        if (this.mounted) {
-          this.setState({
-            branchLike,
-            branchLikes,
-            component,
-            loading: false
-          });
-          this.fetchStatus(component);
-          this.fetchWarnings(component, branchLike);
-        }
-      })
-      .catch(onError);
+      .then(
+        ({ branchLike, branchLikes, component }) => {
+          if (this.mounted) {
+            this.setState({
+              branchLike,
+              branchLikes,
+              component,
+              loading: false
+            });
+            this.fetchStatus(component);
+            this.fetchWarnings(component, branchLike);
+          }
+        },
+        () => {}
+      );
   }
 
   fetchBranches = (
index f534409f7cf719ba562cbe8f6c8ba1ac382d5bc6..905e3bfe37147c68cffbcbfded8b50d69805c3df 100644 (file)
@@ -58,7 +58,7 @@ jest.mock('../../../api/ce', () => ({
 }));
 
 jest.mock('../../../api/components', () => ({
-  getComponentData: jest.fn().mockResolvedValue({ analysisDate: '2018-07-30' })
+  getComponentData: jest.fn().mockResolvedValue({ component: { analysisDate: '2018-07-30' } })
 }));
 
 jest.mock('../../../api/nav', () => ({
@@ -130,7 +130,9 @@ it('updates branches on change', async () => {
 
 it('loads organization', async () => {
   (isSonarCloud as jest.Mock).mockReturnValue(true);
-  (getComponentData as jest.Mock<any>).mockResolvedValueOnce({ organization: 'org' });
+  (getComponentData as jest.Mock<any>).mockResolvedValueOnce({
+    component: { organization: 'org' }
+  });
 
   const fetchOrganization = jest.fn();
   shallowRender({ fetchOrganization });
@@ -139,7 +141,9 @@ it('loads organization', async () => {
 });
 
 it('fetches status', async () => {
-  (getComponentData as jest.Mock<any>).mockResolvedValueOnce({ organization: 'org' });
+  (getComponentData as jest.Mock<any>).mockResolvedValueOnce({
+    component: { organization: 'org' }
+  });
 
   shallowRender();
   await new Promise(setImmediate);
diff --git a/server/sonar-web/src/main/js/app/utils/__test__/handleRequiredAuthentication-test.ts b/server/sonar-web/src/main/js/app/utils/__test__/handleRequiredAuthentication-test.ts
deleted file mode 100644 (file)
index 2d1b7ff..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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 handleRequiredAuthentication from '../handleRequiredAuthentication';
-import getHistory from '../getHistory';
-
-jest.mock('../getHistory', () => ({
-  default: jest.fn()
-}));
-
-it('should not render for anonymous user', () => {
-  const replace = jest.fn();
-  (getHistory as jest.Mock<any>).mockReturnValue({ replace });
-  handleRequiredAuthentication();
-  expect(replace).toBeCalledWith(expect.objectContaining({ pathname: '/sessions/new' }));
-});
diff --git a/server/sonar-web/src/main/js/app/utils/__tests__/handleRequiredAuthentication-test.ts b/server/sonar-web/src/main/js/app/utils/__tests__/handleRequiredAuthentication-test.ts
new file mode 100644 (file)
index 0000000..2d1b7ff
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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 handleRequiredAuthentication from '../handleRequiredAuthentication';
+import getHistory from '../getHistory';
+
+jest.mock('../getHistory', () => ({
+  default: jest.fn()
+}));
+
+it('should not render for anonymous user', () => {
+  const replace = jest.fn();
+  (getHistory as jest.Mock<any>).mockReturnValue({ replace });
+  handleRequiredAuthentication();
+  expect(replace).toBeCalledWith(expect.objectContaining({ pathname: '/sessions/new' }));
+});
diff --git a/server/sonar-web/src/main/js/app/utils/__tests__/throwGlobalError-test.ts b/server/sonar-web/src/main/js/app/utils/__tests__/throwGlobalError-test.ts
new file mode 100644 (file)
index 0000000..5f00a89
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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 throwGlobalError from '../throwGlobalError';
+import getStore from '../getStore';
+
+it('should put the error message in the store', async () => {
+  const response: any = { json: jest.fn().mockResolvedValue({ errors: [{ msg: 'error 1' }] }) };
+  await throwGlobalError({ response }).catch(() => {});
+  expect(getStore().getState().globalMessages[0]).toMatchObject({
+    level: 'ERROR',
+    message: 'error 1'
+  });
+});
+
+it('should put a default error messsage in the store', async () => {
+  const response: any = { json: jest.fn().mockResolvedValue({}) };
+  await throwGlobalError({ response }).catch(() => {});
+  expect(getStore().getState().globalMessages[0]).toMatchObject({
+    level: 'ERROR',
+    message: 'default_error_message'
+  });
+});
index fa582130c2deaf8aa76089cc8e753c55ff35956c..fcd2506af13107c3f22aed3f9372a161b819e1e7 100644 (file)
@@ -25,11 +25,11 @@ export default function throwGlobalError(error: { response: Response }): Promise
   const store = getStore();
 
   // eslint-disable-next-line promise/no-promise-in-callback
-  parseError(error)
-    .then(message => {
+  parseError(error).then(
+    message => {
       store.dispatch(addGlobalErrorMessage(message));
-    })
-    .catch(() => {});
-
+    },
+    () => {}
+  );
   return Promise.reject(error.response);
 }
index ceae7a7f157daac6952a1838b584b85d57caab1f..863bb094892f74b9418bc78aedbb227a55e1d55b 100644 (file)
@@ -123,7 +123,7 @@ function retrieveComponentBase(componentKey: string, qualifier: string, branchLi
     component: componentKey,
     metricKeys: metrics.join(),
     ...getBranchLikeQuery(branchLike)
-  }).then(component => {
+  }).then(({ component }) => {
     addComponent(component);
     return component;
   });
index 3abf5f6e0d690edd595bace17a2782ef4092e46d..f1d3e4521840dbce9c15880577ca346c7a38370a 100644 (file)
@@ -719,9 +719,9 @@ function defaultLoadComponent(component: string, branchLike: T.BranchLike | unde
   return Promise.all([
     getComponentForSourceViewer({ component, ...getBranchLikeQuery(branchLike) }),
     getComponentData({ component, ...getBranchLikeQuery(branchLike) })
-  ]).then(([component, data]) => ({
-    ...component,
-    leakPeriodDate: data.leakPeriodDate
+  ]).then(([sourceViewerComponent, { component }]) => ({
+    ...sourceViewerComponent,
+    leakPeriodDate: component.leakPeriodDate
   }));
 }