]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-12632 Rework leak period components
authorWouter Admiraal <wouter.admiraal@sonarsource.com>
Thu, 19 Dec 2019 09:52:10 +0000 (10:52 +0100)
committerSonarTech <sonartech@sonarsource.com>
Mon, 10 Feb 2020 19:46:15 +0000 (20:46 +0100)
server/sonar-web/src/main/js/apps/overview/branches/ApplicationLeakPeriodInfo.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/overview/branches/LeakPeriodInfo.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/overview/branches/ProjectLeakPeriodInfo.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/overview/branches/__tests__/ApplicationLeakPeriodInfo-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/overview/branches/__tests__/LeakPeriodInfo-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/overview/branches/__tests__/ProjectLeakPeriodInfo-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/overview/components/__tests__/ApplicationLeakPeriodLegend-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/ApplicationLeakPeriodLegend-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/helpers/periods.ts

diff --git a/server/sonar-web/src/main/js/apps/overview/branches/ApplicationLeakPeriodInfo.tsx b/server/sonar-web/src/main/js/apps/overview/branches/ApplicationLeakPeriodInfo.tsx
new file mode 100644 (file)
index 0000000..1d27c58
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 * as React from 'react';
+import { translateWithParameters } from 'sonar-ui-common/helpers/l10n';
+import DateFromNow from '../../../components/intl/DateFromNow';
+import { ApplicationPeriod } from '../../../types/application';
+
+export interface ApplicationLeakPeriodInfoProps {
+  leakPeriod: ApplicationPeriod;
+}
+
+export function ApplicationLeakPeriodInfo({ leakPeriod }: ApplicationLeakPeriodInfoProps) {
+  return (
+    <>
+      <div className="note spacer-top">
+        {translateWithParameters('overview.max_new_code_period_from_x', leakPeriod.projectName)}
+      </div>
+      <DateFromNow date={leakPeriod.date}>
+        {fromNow => (
+          <div className="note little-spacer-top">
+            {translateWithParameters('overview.started_x', fromNow)}
+          </div>
+        )}
+      </DateFromNow>
+    </>
+  );
+}
+
+export default React.memo(ApplicationLeakPeriodInfo);
diff --git a/server/sonar-web/src/main/js/apps/overview/branches/LeakPeriodInfo.tsx b/server/sonar-web/src/main/js/apps/overview/branches/LeakPeriodInfo.tsx
new file mode 100644 (file)
index 0000000..46dc08d
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 * as React from 'react';
+import { isApplicationPeriod } from '../../../helpers/periods';
+import { ApplicationPeriod } from '../../../types/application';
+import ApplicationLeakPeriodInfo from './ApplicationLeakPeriodInfo';
+import ProjectLeakPeriodInfo from './ProjectLeakPeriodInfo';
+
+export interface LeakPeriodInfoProps {
+  leakPeriod: T.Period | ApplicationPeriod;
+}
+
+export function LeakPeriodInfo({ leakPeriod }: LeakPeriodInfoProps) {
+  if (isApplicationPeriod(leakPeriod)) {
+    return <ApplicationLeakPeriodInfo leakPeriod={leakPeriod} />;
+  } else {
+    return <ProjectLeakPeriodInfo leakPeriod={leakPeriod} />;
+  }
+}
+
+export default React.memo(LeakPeriodInfo);
diff --git a/server/sonar-web/src/main/js/apps/overview/branches/ProjectLeakPeriodInfo.tsx b/server/sonar-web/src/main/js/apps/overview/branches/ProjectLeakPeriodInfo.tsx
new file mode 100644 (file)
index 0000000..60728b5
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 * as React from 'react';
+import { InjectedIntl, injectIntl } from 'react-intl';
+import { translateWithParameters } from 'sonar-ui-common/helpers/l10n';
+import { longFormatterOption } from '../../../components/intl/DateFormatter';
+import DateFromNow from '../../../components/intl/DateFromNow';
+import { formatterOption } from '../../../components/intl/DateTimeFormatter';
+import { getPeriodDate, getPeriodLabel } from '../../../helpers/periods';
+
+export interface ProjectLeakPeriodInfoProps {
+  intl: Pick<InjectedIntl, 'formatDate' | 'formatTime'>;
+  leakPeriod: T.Period;
+}
+
+export function ProjectLeakPeriodInfo(props: ProjectLeakPeriodInfoProps) {
+  const {
+    intl: { formatDate, formatTime },
+    leakPeriod
+  } = props;
+
+  const leakPeriodLabel = getPeriodLabel(
+    leakPeriod,
+    ['manual_baseline', 'SPECIFIC_ANALYSIS'].includes(leakPeriod.mode)
+      ? (date: string) => formatTime(date, formatterOption)
+      : (date: string) => formatDate(date, longFormatterOption)
+  );
+
+  if (!leakPeriodLabel) {
+    return null;
+  }
+
+  if (leakPeriod.mode === 'days' || leakPeriod.mode === 'NUMBER_OF_DAYS') {
+    return <div className="note spacer-top">{leakPeriodLabel} </div>;
+  }
+
+  const leakPeriodDate = getPeriodDate(leakPeriod);
+
+  if (!leakPeriodDate) {
+    return null;
+  }
+
+  return (
+    <>
+      <div className="note spacer-top">{leakPeriodLabel}</div>
+      <DateFromNow date={leakPeriodDate}>
+        {fromNow => (
+          <div className="note little-spacer-top">
+            {translateWithParameters(
+              leakPeriod.mode === 'previous_analysis'
+                ? 'overview.previous_analysis_x'
+                : 'overview.started_x',
+              fromNow
+            )}
+          </div>
+        )}
+      </DateFromNow>
+    </>
+  );
+}
+
+export default React.memo(injectIntl(ProjectLeakPeriodInfo));
diff --git a/server/sonar-web/src/main/js/apps/overview/branches/__tests__/ApplicationLeakPeriodInfo-test.tsx b/server/sonar-web/src/main/js/apps/overview/branches/__tests__/ApplicationLeakPeriodInfo-test.tsx
new file mode 100644 (file)
index 0000000..49a5368
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 { mockApplicationPeriod } from '../../../../helpers/mocks/application';
+import {
+  ApplicationLeakPeriodInfo,
+  ApplicationLeakPeriodInfoProps
+} from '../ApplicationLeakPeriodInfo';
+
+jest.mock('../../../../components/intl/DateFromNow');
+
+it('renders correctly', () => {
+  const wrapper = shallowRender();
+  expect(wrapper).toMatchSnapshot();
+  expect(wrapper.find('DateFromNow').dive()).toMatchSnapshot();
+});
+
+function shallowRender(props: Partial<ApplicationLeakPeriodInfoProps> = {}) {
+  return shallow(<ApplicationLeakPeriodInfo leakPeriod={mockApplicationPeriod()} {...props} />);
+}
diff --git a/server/sonar-web/src/main/js/apps/overview/branches/__tests__/LeakPeriodInfo-test.tsx b/server/sonar-web/src/main/js/apps/overview/branches/__tests__/LeakPeriodInfo-test.tsx
new file mode 100644 (file)
index 0000000..a6a8860
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 { mockApplicationPeriod } from '../../../../helpers/mocks/application';
+import { mockPeriod } from '../../../../helpers/testMocks';
+import { LeakPeriodInfo, LeakPeriodInfoProps } from '../LeakPeriodInfo';
+
+it('renders correctly for projects', () => {
+  expect(shallowRender()).toMatchSnapshot();
+});
+
+it('renders correctly for applications', () => {
+  expect(shallowRender({ leakPeriod: mockApplicationPeriod() })).toMatchSnapshot();
+});
+
+function shallowRender(props: Partial<LeakPeriodInfoProps> = {}) {
+  return shallow(<LeakPeriodInfo leakPeriod={mockPeriod()} {...props} />);
+}
diff --git a/server/sonar-web/src/main/js/apps/overview/branches/__tests__/ProjectLeakPeriodInfo-test.tsx b/server/sonar-web/src/main/js/apps/overview/branches/__tests__/ProjectLeakPeriodInfo-test.tsx
new file mode 100644 (file)
index 0000000..862b9a9
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 { differenceInDays } from 'date-fns';
+import { shallow } from 'enzyme';
+import * as React from 'react';
+import { mockPeriod } from '../../../../helpers/testMocks';
+import { ProjectLeakPeriodInfo } from '../ProjectLeakPeriodInfo';
+
+jest.mock('date-fns/difference_in_days', () => jest.fn().mockReturnValue(10));
+
+it('should render correctly for 10 days', () => {
+  expect(shallowRender({ mode: 'days', parameter: '10' })).toMatchSnapshot();
+});
+
+it('should render correctly for a specific date', () => {
+  expect(shallowRender({ mode: 'date', parameter: '2013-01-01' })).toMatchSnapshot();
+});
+
+it('should render correctly for a specific version', () => {
+  expect(shallowRender({ mode: 'version', parameter: '0.1' })).toMatchSnapshot();
+});
+
+it('should render correctly for "previous_version"', () => {
+  expect(shallowRender({ mode: 'previous_version' })).toMatchSnapshot();
+});
+
+it('should render correctly for "previous_analysis"', () => {
+  expect(shallowRender({ mode: 'previous_analysis' })).toMatchSnapshot();
+});
+
+it('should render correctly for "manual_baseline"', () => {
+  expect(shallowRender({ mode: 'manual_baseline' })).toMatchSnapshot();
+  expect(shallowRender({ mode: 'manual_baseline', parameter: '1.1.2' })).toMatchSnapshot();
+});
+
+it('should render a more precise date', () => {
+  (differenceInDays as jest.Mock<any>).mockReturnValueOnce(0);
+  expect(
+    shallowRender({ date: '2018-08-17T00:00:00+0200', mode: 'previous_version' })
+  ).toMatchSnapshot();
+});
+
+function shallowRender(period: Partial<T.Period> = {}) {
+  return shallow(
+    <ProjectLeakPeriodInfo
+      intl={{
+        formatDate: (date: string) => 'formatted.' + date,
+        formatTime: (date: string) => 'formattedTime.' + date
+      }}
+      leakPeriod={mockPeriod({ ...period })}
+    />
+  );
+}
diff --git a/server/sonar-web/src/main/js/apps/overview/components/__tests__/ApplicationLeakPeriodLegend-test.tsx b/server/sonar-web/src/main/js/apps/overview/components/__tests__/ApplicationLeakPeriodLegend-test.tsx
deleted file mode 100644 (file)
index 5ffe655..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
-import ApplicationLeakPeriodLegend from '../ApplicationLeakPeriodLegend';
-
-jest.mock('../../../../api/application', () => ({
-  getApplicationLeak: jest.fn(() =>
-    Promise.resolve([
-      { date: '2017-01-01T11:39:03+0100', project: 'foo', projectName: 'Foo' },
-      { date: '2017-02-01T11:39:03+0100', project: 'bar', projectName: 'Bar' }
-    ])
-  )
-}));
-
-it('renders', async () => {
-  const wrapper = shallow(
-    <ApplicationLeakPeriodLegend
-      component={{ key: 'foo', organization: 'bar', qualifier: 'APP' }}
-    />
-  );
-  expect(wrapper).toMatchSnapshot();
-
-  await waitAndUpdate(wrapper);
-  expect(wrapper).toMatchSnapshot();
-});
diff --git a/server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/ApplicationLeakPeriodLegend-test.tsx.snap b/server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/ApplicationLeakPeriodLegend-test.tsx.snap
deleted file mode 100644 (file)
index c01087c..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders 1`] = `
-<Tooltip
-  overlay={
-    <i
-      className="spinner spacer"
-    />
-  }
->
-  <div
-    className="overview-legend overview-legend-spaced-line"
-  >
-    issues.max_new_code_period
-    :
-     
-  </div>
-</Tooltip>
-`;
-
-exports[`renders 2`] = `
-<Tooltip
-  overlay={
-    <ul
-      className="text-left"
-    >
-      <li>
-        Foo
-        : 
-        <DateTooltipFormatter
-          date="2017-01-01T11:39:03+0100"
-        />
-      </li>
-      <li>
-        Bar
-        : 
-        <DateTooltipFormatter
-          date="2017-02-01T11:39:03+0100"
-        />
-      </li>
-    </ul>
-  }
->
-  <div
-    className="overview-legend"
-  >
-    issues.max_new_code_period
-    :
-     
-    <DateFromNow
-      date="2017-01-01T11:39:03+0100"
-    >
-      <Component />
-    </DateFromNow>
-    <br />
-    <span
-      className="note"
-    >
-      from
-      :
-      Foo
-    </span>
-  </div>
-</Tooltip>
-`;
index 70dda7212ba12540b733b3dd3ada4ab5f723d395..8d714909592a8afea18d05a86f74e0cde0fee585 100644 (file)
@@ -19,6 +19,7 @@
  */
 import { parseDate } from 'sonar-ui-common/helpers/dates';
 import { translate, translateWithParameters } from 'sonar-ui-common/helpers/l10n';
+import { ApplicationPeriod } from '../types/application';
 
 function getPeriod<T extends T.Period | T.PeriodMeasure>(periods: T[] | undefined, index: number) {
   if (!Array.isArray(periods)) {
@@ -71,3 +72,9 @@ export function getPeriodLabel(
 export function getPeriodDate(period?: { date?: string }): Date | undefined {
   return period && period.date ? parseDate(period.date) : undefined;
 }
+
+export function isApplicationPeriod(
+  period: T.Period | ApplicationPeriod
+): period is ApplicationPeriod {
+  return (period as ApplicationPeriod).project !== undefined;
+}