]> source.dussan.org Git - sonarqube.git/commitdiff
Move tests of projectBaseline
authorWouter Admiraal <wouter.admiraal@sonarsource.com>
Mon, 30 Dec 2019 09:16:58 +0000 (10:16 +0100)
committerSonarTech <sonartech@sonarsource.com>
Thu, 2 Jan 2020 19:46:12 +0000 (20:46 +0100)
34 files changed:
server/sonar-web/src/main/js/apps/projectBaseline/__tests__/App-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/projectBaseline/__tests__/BaselineSettingAnalysis-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/projectBaseline/__tests__/BaselineSettingDays-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/projectBaseline/__tests__/BaselineSettingPreviousVersion-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/projectBaseline/__tests__/BranchAnalysisList-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/projectBaseline/__tests__/BranchBaselineSettingModal-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/projectBaseline/__tests__/BranchList-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/projectBaseline/__tests__/ProjectBaselineSelector-test.tsx [deleted file]
server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/App-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/BaselineSettingAnalysis-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/BaselineSettingDays-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/BaselineSettingPreviousVersion-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/BranchAnalysisList-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/BranchBaselineSettingModal-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/BranchList-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/ProjectBaselineSelector-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/apps/projectBaseline/__tests__/utils-test.ts [deleted file]
server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/App-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/BaselineSettingAnalysis-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/BaselineSettingDays-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/BaselineSettingPreviousVersion-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/BranchAnalysisList-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/BranchBaselineSettingModal-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/BranchList-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/ProjectBaselineSelector-test.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/App-test.tsx.snap [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BaselineSettingAnalysis-test.tsx.snap [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BaselineSettingDays-test.tsx.snap [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BaselineSettingPreviousVersion-test.tsx.snap [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BranchAnalysisList-test.tsx.snap [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BranchBaselineSettingModal-test.tsx.snap [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BranchList-test.tsx.snap [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/ProjectBaselineSelector-test.tsx.snap [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/utils-test.ts [new file with mode: 0644]

diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/App-test.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/App-test.tsx
deleted file mode 100644 (file)
index 1e1b5fa..0000000
+++ /dev/null
@@ -1,95 +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 { shallow } from 'enzyme';
-import * as React from 'react';
-import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
-import { getNewCodePeriod, resetNewCodePeriod, setNewCodePeriod } from '../../../api/newCodePeriod';
-import { mockComponent, mockEvent } from '../../../helpers/testMocks';
-import App from '../components/App';
-
-jest.mock('../../../api/newCodePeriod', () => ({
-  getNewCodePeriod: jest.fn().mockResolvedValue({}),
-  resetNewCodePeriod: jest.fn().mockResolvedValue({}),
-  setNewCodePeriod: jest.fn().mockResolvedValue({})
-}));
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-});
-
-it('should not display reset button if project setting is not set', () => {
-  const wrapper = shallowRender();
-
-  expect(wrapper.find('Button')).toHaveLength(0);
-});
-
-it('should reset the setting correctly', async () => {
-  const wrapper = shallowRender();
-  await waitAndUpdate(wrapper);
-  wrapper.instance().resetSetting();
-  await waitAndUpdate(wrapper);
-  expect(wrapper.state('currentSetting')).toBeUndefined();
-  expect(wrapper.state('selected')).toBeUndefined();
-});
-
-it('should save correctly', async () => {
-  const component = mockComponent();
-  const wrapper = shallowRender({ component });
-  await waitAndUpdate(wrapper);
-  wrapper.setState({ selected: 'NUMBER_OF_DAYS', days: '23' });
-  wrapper.instance().handleSubmit(mockEvent());
-  await waitAndUpdate(wrapper);
-  expect(setNewCodePeriod).toHaveBeenCalledWith({
-    project: component.key,
-    type: 'NUMBER_OF_DAYS',
-    value: '23'
-  });
-  expect(wrapper.state('currentSetting')).toEqual(wrapper.state('selected'));
-});
-
-it('should handle errors gracefully', async () => {
-  (getNewCodePeriod as jest.Mock).mockRejectedValue('error');
-  (setNewCodePeriod as jest.Mock).mockRejectedValue('error');
-  (resetNewCodePeriod as jest.Mock).mockRejectedValue('error');
-
-  const wrapper = shallowRender();
-  wrapper.setState({ selected: 'PREVIOUS_VERSION' });
-  await waitAndUpdate(wrapper);
-
-  expect(wrapper.state('loading')).toBe(false);
-  wrapper.instance().resetSetting();
-  await waitAndUpdate(wrapper);
-  expect(wrapper.state('saving')).toBe(false);
-  wrapper.instance().handleSubmit(mockEvent());
-  await waitAndUpdate(wrapper);
-  expect(wrapper.state('saving')).toBe(false);
-});
-
-function shallowRender(props: Partial<App['props']> = {}) {
-  return shallow<App>(
-    <App
-      branchLikes={[]}
-      branchesEnabled={true}
-      canAdmin={true}
-      component={mockComponent()}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/BaselineSettingAnalysis-test.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/BaselineSettingAnalysis-test.tsx
deleted file mode 100644 (file)
index 384ba11..0000000
+++ /dev/null
@@ -1,41 +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 { shallow } from 'enzyme';
-import * as React from 'react';
-import BaselineSettingAnalysis, { Props } from '../components/BaselineSettingAnalysis';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-});
-
-it('should callback when clicked', () => {
-  const onSelect = jest.fn();
-  const wrapper = shallowRender({ onSelect, selected: false });
-
-  wrapper
-    .find('RadioCard')
-    .first()
-    .simulate('click');
-  expect(onSelect).toHaveBeenCalledWith('SPECIFIC_ANALYSIS');
-});
-
-function shallowRender(props: Partial<Props> = {}) {
-  return shallow(<BaselineSettingAnalysis onSelect={jest.fn()} selected={true} {...props} />);
-}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/BaselineSettingDays-test.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/BaselineSettingDays-test.tsx
deleted file mode 100644 (file)
index f8cd5d9..0000000
+++ /dev/null
@@ -1,69 +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 { shallow } from 'enzyme';
-import * as React from 'react';
-import BaselineSettingDays, { Props } from '../components/BaselineSettingDays';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-  expect(shallowRender({ isChanged: true })).toMatchSnapshot();
-  expect(shallowRender({ isChanged: true, isValid: false })).toMatchSnapshot();
-});
-
-it('should not display input when not selected', () => {
-  const wrapper = shallowRender({ selected: false });
-  expect(wrapper.find('ValidationInput')).toHaveLength(0);
-});
-
-it('should callback when clicked', () => {
-  const onSelect = jest.fn();
-  const wrapper = shallowRender({ onSelect, selected: false });
-
-  wrapper
-    .find('RadioCard')
-    .first()
-    .simulate('click');
-  expect(onSelect).toHaveBeenCalledWith('NUMBER_OF_DAYS');
-});
-
-it('should callback when changing days', () => {
-  const onChangeDays = jest.fn();
-  const wrapper = shallowRender({ onChangeDays });
-
-  wrapper
-    .find('input')
-    .first()
-    .simulate('change', { currentTarget: { value: '23' } });
-  expect(onChangeDays).toHaveBeenCalledWith('23');
-});
-
-function shallowRender(props: Partial<Props> = {}) {
-  return shallow(
-    <BaselineSettingDays
-      days="28"
-      isChanged={false}
-      isValid={true}
-      onChangeDays={jest.fn()}
-      onSelect={jest.fn()}
-      selected={true}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/BaselineSettingPreviousVersion-test.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/BaselineSettingPreviousVersion-test.tsx
deleted file mode 100644 (file)
index e38e179..0000000
+++ /dev/null
@@ -1,46 +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 { shallow } from 'enzyme';
-import * as React from 'react';
-import BaselineSettingPreviousVersion, {
-  Props
-} from '../components/BaselineSettingPreviousVersion';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-  expect(shallowRender({ isDefault: true })).toMatchSnapshot();
-});
-
-it('should callback when clicked', () => {
-  const onSelect = jest.fn();
-  const wrapper = shallowRender({ onSelect, selected: false });
-
-  wrapper
-    .find('RadioCard')
-    .first()
-    .simulate('click');
-  expect(onSelect).toHaveBeenCalledWith('PREVIOUS_VERSION');
-});
-
-function shallowRender(props: Partial<Props> = {}) {
-  return shallow(
-    <BaselineSettingPreviousVersion onSelect={jest.fn()} selected={true} {...props} />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/BranchAnalysisList-test.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/BranchAnalysisList-test.tsx
deleted file mode 100644 (file)
index 992853b..0000000
+++ /dev/null
@@ -1,110 +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 { subDays } from 'date-fns';
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import { toShortNotSoISOString } from 'sonar-ui-common/helpers/dates';
-import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
-import { getProjectActivity } from '../../../api/projectActivity';
-import { mockAnalysis, mockAnalysisEvent } from '../../../helpers/testMocks';
-import BranchAnalysisList from '../components/BranchAnalysisList';
-
-jest.mock('../../../api/projectActivity', () => ({
-  getProjectActivity: jest.fn().mockResolvedValue({
-    analyses: []
-  })
-}));
-
-beforeEach(() => {
-  jest.clearAllMocks();
-});
-
-it('should render correctly', async () => {
-  (getProjectActivity as jest.Mock).mockResolvedValueOnce({
-    analyses: [
-      mockAnalysis({
-        key: '4',
-        date: '2017-03-02T10:36:01+0100',
-        projectVersion: '4.2'
-      }),
-      mockAnalysis({
-        key: '3',
-        date: '2017-03-02T09:36:01+0100',
-        events: [mockAnalysisEvent()],
-        projectVersion: '4.2'
-      }),
-      mockAnalysis({
-        key: '2',
-        events: [
-          mockAnalysisEvent(),
-          mockAnalysisEvent({ category: 'VERSION', qualityGate: undefined })
-        ],
-        projectVersion: '4.1'
-      }),
-      mockAnalysis({ key: '1', projectVersion: '4.1' })
-    ]
-  });
-
-  const wrapper = shallowRender();
-  await waitAndUpdate(wrapper);
-  expect(wrapper).toMatchSnapshot();
-});
-
-it('should reload analyses after range change', () => {
-  const wrapper = shallowRender();
-
-  wrapper.instance().handleRangeChange({ value: 20 });
-
-  expect(getProjectActivity).toBeCalledWith({
-    branch: 'master',
-    project: 'project1',
-    from: toShortNotSoISOString(subDays(new Date(), 20))
-  });
-});
-
-it('should register the badge nodes', () => {
-  const wrapper = shallowRender();
-
-  const element = document.createElement('div');
-
-  wrapper.instance().registerBadgeNode('4.3')(element);
-
-  expect(element.getAttribute('originOffsetTop')).not.toBeNull();
-});
-
-it('should handle scroll', () => {
-  const wrapper = shallowRender();
-
-  wrapper.instance().handleScroll({ currentTarget: { scrollTop: 12 } } as any);
-
-  expect(wrapper.state('scroll')).toBe(12);
-});
-
-function shallowRender(props: Partial<BranchAnalysisList['props']> = {}) {
-  return shallow<BranchAnalysisList>(
-    <BranchAnalysisList
-      analysis="analysis1"
-      branch="master"
-      component="project1"
-      onSelectAnalysis={jest.fn()}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/BranchBaselineSettingModal-test.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/BranchBaselineSettingModal-test.tsx
deleted file mode 100644 (file)
index cbae7bc..0000000
+++ /dev/null
@@ -1,100 +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 { shallow } from 'enzyme';
-import * as React from 'react';
-import { mockEvent, waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
-import { setNewCodePeriod } from '../../../api/newCodePeriod';
-import { mockMainBranch } from '../../../helpers/mocks/branch-like';
-import BranchBaselineSettingModal from '../components/BranchBaselineSettingModal';
-
-jest.mock('../../../api/newCodePeriod', () => ({
-  setNewCodePeriod: jest.fn().mockResolvedValue({})
-}));
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-});
-
-it('should display the branch analysis list when necessary', () => {
-  const wrapper = shallowRender();
-
-  wrapper.setState({ selected: 'SPECIFIC_ANALYSIS' });
-
-  expect(wrapper.find('BranchAnalysisList')).toHaveLength(1);
-});
-
-it('should save correctly', async () => {
-  const branch = mockMainBranch({ name: 'branchname' });
-  const component = 'compKey';
-  const wrapper = shallowRender({
-    branch,
-    component
-  });
-
-  wrapper.setState({ analysis: 'analysis572893', selected: 'SPECIFIC_ANALYSIS' });
-  await waitAndUpdate(wrapper);
-
-  wrapper.instance().handleSubmit(mockEvent());
-  await new Promise(setImmediate);
-
-  expect(setNewCodePeriod).toHaveBeenCalledWith({
-    project: component,
-    type: 'SPECIFIC_ANALYSIS',
-    value: 'analysis572893',
-    branch: 'branchname'
-  });
-});
-
-it('should disable the save button when saving', () => {
-  const wrapper = shallowRender();
-
-  wrapper.setState({ saving: true });
-
-  expect(
-    wrapper
-      .find('SubmitButton')
-      .first()
-      .prop('disabled')
-  ).toBe(true);
-});
-
-it('should disable the save button when date is invalid', () => {
-  const wrapper = shallowRender();
-
-  wrapper.setState({ days: 'asdf' });
-
-  expect(
-    wrapper
-      .find('SubmitButton')
-      .first()
-      .prop('disabled')
-  ).toBe(true);
-});
-
-function shallowRender(props: Partial<BranchBaselineSettingModal['props']> = {}) {
-  return shallow<BranchBaselineSettingModal>(
-    <BranchBaselineSettingModal
-      branch={mockMainBranch()}
-      component="compKey"
-      onClose={jest.fn()}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/BranchList-test.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/BranchList-test.tsx
deleted file mode 100644 (file)
index 9bf67e0..0000000
+++ /dev/null
@@ -1,130 +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 { shallow } from 'enzyme';
-import * as React from 'react';
-import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
-import { listBranchesNewCodePeriod, resetNewCodePeriod } from '../../../api/newCodePeriod';
-import { mockBranch, mockMainBranch, mockPullRequest } from '../../../helpers/mocks/branch-like';
-import { mockComponent } from '../../../helpers/testMocks';
-import BranchBaselineSettingModal from '../components/BranchBaselineSettingModal';
-import BranchList from '../components/BranchList';
-
-jest.mock('../../../api/newCodePeriod', () => ({
-  listBranchesNewCodePeriod: jest.fn().mockResolvedValue({ newCodePeriods: [] }),
-  resetNewCodePeriod: jest.fn().mockResolvedValue(null)
-}));
-
-it('should render correctly', async () => {
-  (listBranchesNewCodePeriod as jest.Mock).mockResolvedValueOnce({
-    newCodePeriods: [
-      {
-        projectKey: '',
-        branchKey: 'master',
-        type: 'NUMBER_OF_DAYS',
-        value: '27'
-      }
-    ]
-  });
-  const wrapper = shallowRender({
-    branchLikes: [
-      mockMainBranch(),
-      mockBranch(),
-      mockBranch({ name: 'branch-7.0' }),
-      mockPullRequest()
-    ]
-  });
-  await waitAndUpdate(wrapper);
-  expect(wrapper.state().branches).toHaveLength(3);
-  expect(wrapper).toMatchSnapshot();
-});
-
-it('should handle reset', () => {
-  const component = mockComponent();
-  const wrapper = shallowRender({ component });
-
-  wrapper.instance().resetToDefault('master');
-
-  expect(resetNewCodePeriod).toBeCalledWith({
-    project: component.key,
-    branch: 'master'
-  });
-});
-
-it('should toggle popup', async () => {
-  const wrapper = shallowRender({ branchLikes: [mockMainBranch(), mockBranch()] });
-
-  wrapper.setState({ editedBranch: mockMainBranch() });
-
-  await waitAndUpdate(wrapper);
-
-  const nodes = wrapper.find(BranchBaselineSettingModal);
-  expect(nodes).toHaveLength(1);
-  expect(nodes.first().props().branch).toEqual(mockMainBranch());
-
-  wrapper.instance().closeEditModal('master', { type: 'NUMBER_OF_DAYS', value: '23' });
-
-  expect(wrapper.find('BranchBaselineSettingModal')).toHaveLength(0);
-  expect(wrapper.state().branches.find(b => b.name === 'master')).toEqual({
-    analysisDate: '2018-01-01',
-    excludedFromPurge: true,
-    isMain: true,
-    name: 'master',
-    newCodePeriod: {
-      type: 'NUMBER_OF_DAYS',
-      value: '23'
-    }
-  });
-});
-
-it('should render the right setting label', () => {
-  const wrapper = shallowRender();
-
-  expect(
-    wrapper.instance().renderNewCodePeriodSetting({ type: 'NUMBER_OF_DAYS', value: '21' })
-  ).toBe('baseline.number_days: 21');
-  expect(wrapper.instance().renderNewCodePeriodSetting({ type: 'PREVIOUS_VERSION' })).toBe(
-    'baseline.previous_version'
-  );
-  expect(
-    wrapper.instance().renderNewCodePeriodSetting({
-      type: 'SPECIFIC_ANALYSIS',
-      value: 'A85835',
-      effectiveValue: '2018-12-02T13:01:12'
-    })
-  ).toMatchInlineSnapshot(`
-    <React.Fragment>
-      baseline.specific_analysis: 
-      <DateTimeFormatter
-        date="2018-12-02T13:01:12"
-      />
-    </React.Fragment>
-  `);
-});
-
-function shallowRender(props: Partial<BranchList['props']> = {}) {
-  return shallow<BranchList>(
-    <BranchList
-      branchLikes={[]}
-      component={mockComponent()}
-      inheritedSetting={{ type: 'PREVIOUS_VERSION' }}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/ProjectBaselineSelector-test.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/ProjectBaselineSelector-test.tsx
deleted file mode 100644 (file)
index ddaf452..0000000
+++ /dev/null
@@ -1,124 +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 { shallow } from 'enzyme';
-import * as React from 'react';
-import ProjectBaselineSelector, {
-  ProjectBaselineSelectorProps
-} from '../components/ProjectBaselineSelector';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-  expect(
-    shallowRender({
-      branchesEnabled: false,
-      generalSetting: { type: 'NUMBER_OF_DAYS', value: '23' }
-    })
-  ).toMatchSnapshot();
-  expect(
-    shallowRender({ branchesEnabled: false, generalSetting: { type: 'NUMBER_OF_DAYS', value: '' } })
-  ).toMatchSnapshot();
-});
-
-it('should not show save button when unchanged', () => {
-  const wrapper = shallowRender({
-    currentSetting: 'PREVIOUS_VERSION',
-    selected: 'PREVIOUS_VERSION',
-    overrideGeneralSetting: true
-  });
-  expect(
-    wrapper
-      .find('SubmitButton')
-      .parent()
-      .hasClass('invisible')
-  ).toBe(true);
-});
-
-it('should show save button when changed', () => {
-  const wrapper = shallowRender({
-    currentSetting: 'PREVIOUS_VERSION',
-    selected: 'NUMBER_OF_DAYS',
-    overrideGeneralSetting: true
-  });
-  expect(wrapper.find('SubmitButton')).toHaveLength(1);
-});
-
-it('should show save button when value changed', () => {
-  const wrapper = shallowRender({
-    currentSetting: 'NUMBER_OF_DAYS',
-    currentSettingValue: '23',
-    days: '25',
-    selected: 'NUMBER_OF_DAYS',
-    overrideGeneralSetting: true
-  });
-  expect(wrapper.find('SubmitButton')).toHaveLength(1);
-});
-
-it('should disable the save button when saving', () => {
-  const wrapper = shallowRender({
-    currentSetting: 'NUMBER_OF_DAYS',
-    currentSettingValue: '25',
-    saving: true,
-    selected: 'PREVIOUS_VERSION',
-    overrideGeneralSetting: true
-  });
-
-  expect(
-    wrapper
-      .find('SubmitButton')
-      .first()
-      .prop('disabled')
-  ).toBe(true);
-});
-
-it('should disable the save button when date is invalid', () => {
-  const wrapper = shallowRender({
-    currentSetting: 'PREVIOUS_VERSION',
-    days: 'hello',
-    selected: 'NUMBER_OF_DAYS',
-    overrideGeneralSetting: true
-  });
-
-  expect(
-    wrapper
-      .find('SubmitButton')
-      .first()
-      .prop('disabled')
-  ).toBe(true);
-});
-
-function shallowRender(props: Partial<ProjectBaselineSelectorProps> = {}) {
-  return shallow(
-    <ProjectBaselineSelector
-      branchesEnabled={true}
-      component=""
-      days="12"
-      generalSetting={{}}
-      onCancel={jest.fn()}
-      onSelectAnalysis={jest.fn()}
-      onSelectDays={jest.fn()}
-      onSelectSetting={jest.fn()}
-      onSubmit={jest.fn()}
-      onToggleSpecificSetting={jest.fn()}
-      overrideGeneralSetting={false}
-      saving={false}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/App-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/App-test.tsx.snap
deleted file mode 100644 (file)
index d23ae12..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<Fragment>
-  <Suggestions
-    suggestions="project_baseline"
-  />
-  <div
-    className="page page-limited"
-  >
-    <header
-      className="page-header"
-    >
-      <h1
-        className="page-title"
-      >
-        project_baseline.page
-      </h1>
-      <p
-        className="page-description"
-      >
-        <FormattedMessage
-          defaultMessage="project_baseline.page.description"
-          id="project_baseline.page.description"
-          values={
-            Object {
-              "link": <Link
-                onlyActiveOnIndex={false}
-                style={Object {}}
-                to="/documentation/project-administration/new-code-period/"
-              >
-                project_baseline.page.description.link
-              </Link>,
-            }
-          }
-        />
-        <br />
-        <FormattedMessage
-          defaultMessage="project_baseline.page.description2"
-          id="project_baseline.page.description2"
-          values={
-            Object {
-              "link": <Link
-                onlyActiveOnIndex={false}
-                style={Object {}}
-                to="/admin/settings?category=new_code_period"
-              >
-                project_baseline.page.description2.link
-              </Link>,
-            }
-          }
-        />
-      </p>
-    </header>
-    <DeferredSpinner
-      timeout={100}
-    />
-  </div>
-</Fragment>
-`;
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/BaselineSettingAnalysis-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/BaselineSettingAnalysis-test.tsx.snap
deleted file mode 100644 (file)
index a5dc612..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<RadioCard
-  onClick={[Function]}
-  selected={true}
-  title="baseline.specific_analysis"
->
-  <p
-    className="big-spacer-bottom"
-  >
-    baseline.specific_analysis.description
-  </p>
-</RadioCard>
-`;
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/BaselineSettingDays-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/BaselineSettingDays-test.tsx.snap
deleted file mode 100644 (file)
index aabe88a..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<RadioCard
-  onClick={[Function]}
-  selected={true}
-  title="baseline.number_days"
->
-  <p
-    className="big-spacer-bottom"
-  >
-    baseline.number_days.description
-  </p>
-  <ValidationInput
-    id="baseline_number_of_days"
-    isInvalid={false}
-    isValid={false}
-    label="baseline.specify_days"
-    required={true}
-  >
-    <input
-      onChange={[Function]}
-      type="text"
-      value="28"
-    />
-  </ValidationInput>
-</RadioCard>
-`;
-
-exports[`should render correctly 2`] = `
-<RadioCard
-  onClick={[Function]}
-  selected={true}
-  title="baseline.number_days"
->
-  <p
-    className="big-spacer-bottom"
-  >
-    baseline.number_days.description
-  </p>
-  <ValidationInput
-    id="baseline_number_of_days"
-    isInvalid={false}
-    isValid={true}
-    label="baseline.specify_days"
-    required={true}
-  >
-    <input
-      onChange={[Function]}
-      type="text"
-      value="28"
-    />
-  </ValidationInput>
-</RadioCard>
-`;
-
-exports[`should render correctly 3`] = `
-<RadioCard
-  onClick={[Function]}
-  selected={true}
-  title="baseline.number_days"
->
-  <p
-    className="big-spacer-bottom"
-  >
-    baseline.number_days.description
-  </p>
-  <ValidationInput
-    id="baseline_number_of_days"
-    isInvalid={true}
-    isValid={false}
-    label="baseline.specify_days"
-    required={true}
-  >
-    <input
-      onChange={[Function]}
-      type="text"
-      value="28"
-    />
-  </ValidationInput>
-</RadioCard>
-`;
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/BaselineSettingPreviousVersion-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/BaselineSettingPreviousVersion-test.tsx.snap
deleted file mode 100644 (file)
index cb4acd7..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<RadioCard
-  onClick={[Function]}
-  selected={true}
-  title="baseline.previous_version"
->
-  <p>
-    baseline.previous_version.description
-  </p>
-</RadioCard>
-`;
-
-exports[`should render correctly 2`] = `
-<RadioCard
-  onClick={[Function]}
-  selected={true}
-  title="baseline.previous_version (default)"
->
-  <p>
-    baseline.previous_version.description
-  </p>
-</RadioCard>
-`;
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/BranchAnalysisList-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/BranchAnalysisList-test.tsx.snap
deleted file mode 100644 (file)
index e215412..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<Fragment>
-  <div
-    className="spacer-bottom"
-  >
-    baseline.analysis_from
-    <Select
-      autoBlur={true}
-      className="input-medium spacer-left"
-      clearable={false}
-      onChange={[Function]}
-      options={
-        Array [
-          Object {
-            "label": "baseline.branch_analyses.ranges.30days",
-            "value": 30,
-          },
-          Object {
-            "label": "baseline.branch_analyses.ranges.allTime",
-            "value": 0,
-          },
-        ]
-      }
-      searchable={false}
-      value={0}
-    />
-  </div>
-  <div
-    className="branch-analysis-list-wrapper"
-  >
-    <div
-      className="bordered branch-analysis-list"
-      onScroll={[Function]}
-    >
-      <div
-        className="big-spacer-top big-spacer-bottom strong"
-      >
-        baseline.no_analyses
-      </div>
-    </div>
-  </div>
-</Fragment>
-`;
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/BranchBaselineSettingModal-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/BranchBaselineSettingModal-test.tsx.snap
deleted file mode 100644 (file)
index e9ffc30..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<Modal
-  contentLabel="baseline.new_code_period_for_branch_x.master"
-  onRequestClose={[Function]}
-  size="large"
->
-  <header
-    className="modal-head"
-  >
-    <h2>
-      baseline.new_code_period_for_branch_x.master
-    </h2>
-  </header>
-  <form
-    onSubmit={[Function]}
-  >
-    <div
-      className="modal-body modal-container branch-baseline-setting-modal"
-    >
-      <div
-        className="display-flex-row huge-spacer-bottom"
-        role="radiogroup"
-      >
-        <BaselineSettingPreviousVersion
-          isDefault={false}
-          onSelect={[Function]}
-          selected={false}
-        />
-        <BaselineSettingDays
-          days="30"
-          isChanged={false}
-          isValid={false}
-          onChangeDays={[Function]}
-          onSelect={[Function]}
-          selected={false}
-        />
-        <BaselineSettingAnalysis
-          onSelect={[Function]}
-          selected={false}
-        />
-      </div>
-    </div>
-    <footer
-      className="modal-foot"
-    >
-      <DeferredSpinner
-        className="spacer-right"
-        loading={false}
-        timeout={100}
-      />
-      <SubmitButton
-        disabled={true}
-      >
-        save
-      </SubmitButton>
-      <ResetButtonLink
-        onClick={[MockFunction]}
-      >
-        cancel
-      </ResetButtonLink>
-    </footer>
-  </form>
-</Modal>
-`;
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/BranchList-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/BranchList-test.tsx.snap
deleted file mode 100644 (file)
index 5c2965d..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<Fragment>
-  <table
-    className="data zebra"
-  >
-    <thead>
-      <tr>
-        <th>
-          branch_list.branch
-        </th>
-        <th
-          className="nowrap huge-spacer-right"
-        >
-          branch_list.current_setting
-        </th>
-        <th
-          className="thin nowrap"
-        >
-          branch_list.actions
-        </th>
-      </tr>
-    </thead>
-    <tbody>
-      <tr
-        key="master"
-      >
-        <td
-          className="nowrap"
-        >
-          <BranchLikeIcon
-            branchLike={
-              Object {
-                "analysisDate": "2018-01-01",
-                "excludedFromPurge": true,
-                "isMain": true,
-                "name": "master",
-                "newCodePeriod": Object {
-                  "effectiveValue": undefined,
-                  "type": "NUMBER_OF_DAYS",
-                  "value": "27",
-                },
-              }
-            }
-            className="little-spacer-right"
-          />
-          master
-          <div
-            className="badge spacer-left"
-          >
-            branches.main_branch
-          </div>
-        </td>
-        <td
-          className="huge-spacer-right nowrap"
-        >
-          baseline.number_days: 27
-        </td>
-        <td
-          className="text-right"
-        >
-          <ActionsDropdown>
-            <ActionsDropdownItem
-              onClick={[Function]}
-            >
-              edit
-            </ActionsDropdownItem>
-            <ActionsDropdownItem
-              onClick={[Function]}
-            >
-              reset_to_default
-            </ActionsDropdownItem>
-          </ActionsDropdown>
-        </td>
-      </tr>
-      <tr
-        key="branch-6.7"
-      >
-        <td
-          className="nowrap"
-        >
-          <BranchLikeIcon
-            branchLike={
-              Object {
-                "analysisDate": "2018-01-01",
-                "excludedFromPurge": true,
-                "isMain": false,
-                "name": "branch-6.7",
-              }
-            }
-            className="little-spacer-right"
-          />
-          branch-6.7
-        </td>
-        <td
-          className="huge-spacer-right nowrap"
-        >
-          branch_list.default_setting
-        </td>
-        <td
-          className="text-right"
-        >
-          <ActionsDropdown>
-            <ActionsDropdownItem
-              onClick={[Function]}
-            >
-              edit
-            </ActionsDropdownItem>
-          </ActionsDropdown>
-        </td>
-      </tr>
-      <tr
-        key="branch-7.0"
-      >
-        <td
-          className="nowrap"
-        >
-          <BranchLikeIcon
-            branchLike={
-              Object {
-                "analysisDate": "2018-01-01",
-                "excludedFromPurge": true,
-                "isMain": false,
-                "name": "branch-7.0",
-              }
-            }
-            className="little-spacer-right"
-          />
-          branch-7.0
-        </td>
-        <td
-          className="huge-spacer-right nowrap"
-        >
-          branch_list.default_setting
-        </td>
-        <td
-          className="text-right"
-        >
-          <ActionsDropdown>
-            <ActionsDropdownItem
-              onClick={[Function]}
-            >
-              edit
-            </ActionsDropdownItem>
-          </ActionsDropdown>
-        </td>
-      </tr>
-    </tbody>
-  </table>
-</Fragment>
-`;
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/ProjectBaselineSelector-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/__snapshots__/ProjectBaselineSelector-test.tsx.snap
deleted file mode 100644 (file)
index 67c95df..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<form
-  className="project-baseline-selector"
-  onSubmit={[MockFunction]}
->
-  <div
-    className="big-spacer-top spacer-bottom"
-    role="radiogroup"
-  >
-    <Radio
-      checked={true}
-      className="big-spacer-bottom"
-      onCheck={[Function]}
-      value="general"
-    >
-      project_baseline.general_setting
-    </Radio>
-    <div
-      className="big-spacer-left"
-    >
-      <div
-        className="general-setting"
-      >
-        <strong>
-          baseline.previous_version
-        </strong>
-        : 
-        baseline.previous_version.description
-      </div>
-    </div>
-    <Radio
-      checked={false}
-      className="huge-spacer-top"
-      onCheck={[Function]}
-      value="specific"
-    >
-      project_baseline.specific_setting
-    </Radio>
-  </div>
-  <div
-    className="big-spacer-left big-spacer-right branch-baseline-setting-modal"
-  >
-    <div
-      className="display-flex-row big-spacer-bottom"
-      role="radiogroup"
-    >
-      <BaselineSettingPreviousVersion
-        disabled={true}
-        onSelect={[MockFunction]}
-        selected={false}
-      />
-      <BaselineSettingDays
-        days="12"
-        disabled={true}
-        isChanged={false}
-        isValid={true}
-        onChangeDays={[MockFunction]}
-        onSelect={[MockFunction]}
-        selected={false}
-      />
-    </div>
-  </div>
-  <div
-    className="big-spacer-top invisible"
-  >
-    <p
-      className="spacer-bottom"
-    >
-      baseline.next_analysis_notice
-    </p>
-    <DeferredSpinner
-      className="spacer-right"
-      loading={false}
-      timeout={100}
-    />
-    <SubmitButton
-      disabled={true}
-    >
-      save
-    </SubmitButton>
-    <ResetButtonLink
-      className="spacer-left"
-      onClick={[MockFunction]}
-    >
-      cancel
-    </ResetButtonLink>
-  </div>
-</form>
-`;
-
-exports[`should render correctly 2`] = `
-<form
-  className="project-baseline-selector"
-  onSubmit={[MockFunction]}
->
-  <div
-    className="big-spacer-top spacer-bottom"
-    role="radiogroup"
-  >
-    <Radio
-      checked={true}
-      className="big-spacer-bottom"
-      onCheck={[Function]}
-      value="general"
-    >
-      project_baseline.general_setting
-    </Radio>
-    <div
-      className="big-spacer-left"
-    >
-      <div
-        className="general-setting"
-      >
-        <strong>
-          baseline.number_days (duration.days.23)
-        </strong>
-        : 
-        baseline.number_days.description
-      </div>
-    </div>
-    <Radio
-      checked={false}
-      className="huge-spacer-top"
-      onCheck={[Function]}
-      value="specific"
-    >
-      project_baseline.specific_setting
-    </Radio>
-  </div>
-  <div
-    className="big-spacer-left big-spacer-right branch-baseline-setting-modal"
-  >
-    <div
-      className="display-flex-row big-spacer-bottom"
-      role="radiogroup"
-    >
-      <BaselineSettingPreviousVersion
-        disabled={true}
-        onSelect={[MockFunction]}
-        selected={false}
-      />
-      <BaselineSettingDays
-        days="12"
-        disabled={true}
-        isChanged={false}
-        isValid={true}
-        onChangeDays={[MockFunction]}
-        onSelect={[MockFunction]}
-        selected={false}
-      />
-      <BaselineSettingAnalysis
-        disabled={true}
-        onSelect={[MockFunction]}
-        selected={false}
-      />
-    </div>
-  </div>
-  <div
-    className="big-spacer-top invisible"
-  >
-    <p
-      className="spacer-bottom"
-    >
-      baseline.next_analysis_notice
-    </p>
-    <DeferredSpinner
-      className="spacer-right"
-      loading={false}
-      timeout={100}
-    />
-    <SubmitButton
-      disabled={true}
-    >
-      save
-    </SubmitButton>
-    <ResetButtonLink
-      className="spacer-left"
-      onClick={[MockFunction]}
-    >
-      cancel
-    </ResetButtonLink>
-  </div>
-</form>
-`;
-
-exports[`should render correctly 3`] = `
-<form
-  className="project-baseline-selector"
-  onSubmit={[MockFunction]}
->
-  <div
-    className="big-spacer-top spacer-bottom"
-    role="radiogroup"
-  >
-    <Radio
-      checked={true}
-      className="big-spacer-bottom"
-      onCheck={[Function]}
-      value="general"
-    >
-      project_baseline.general_setting
-    </Radio>
-    <div
-      className="big-spacer-left"
-    >
-      <div
-        className="general-setting"
-      >
-        <strong>
-          baseline.number_days (duration.days.?)
-        </strong>
-        : 
-        baseline.number_days.description
-      </div>
-    </div>
-    <Radio
-      checked={false}
-      className="huge-spacer-top"
-      onCheck={[Function]}
-      value="specific"
-    >
-      project_baseline.specific_setting
-    </Radio>
-  </div>
-  <div
-    className="big-spacer-left big-spacer-right branch-baseline-setting-modal"
-  >
-    <div
-      className="display-flex-row big-spacer-bottom"
-      role="radiogroup"
-    >
-      <BaselineSettingPreviousVersion
-        disabled={true}
-        onSelect={[MockFunction]}
-        selected={false}
-      />
-      <BaselineSettingDays
-        days="12"
-        disabled={true}
-        isChanged={false}
-        isValid={true}
-        onChangeDays={[MockFunction]}
-        onSelect={[MockFunction]}
-        selected={false}
-      />
-      <BaselineSettingAnalysis
-        disabled={true}
-        onSelect={[MockFunction]}
-        selected={false}
-      />
-    </div>
-  </div>
-  <div
-    className="big-spacer-top invisible"
-  >
-    <p
-      className="spacer-bottom"
-    >
-      baseline.next_analysis_notice
-    </p>
-    <DeferredSpinner
-      className="spacer-right"
-      loading={false}
-      timeout={100}
-    />
-    <SubmitButton
-      disabled={true}
-    >
-      save
-    </SubmitButton>
-    <ResetButtonLink
-      className="spacer-left"
-      onClick={[MockFunction]}
-    >
-      cancel
-    </ResetButtonLink>
-  </div>
-</form>
-`;
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/utils-test.ts b/server/sonar-web/src/main/js/apps/projectBaseline/__tests__/utils-test.ts
deleted file mode 100644 (file)
index a06699d..0000000
+++ /dev/null
@@ -1,115 +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 { getSettingValue, validateSetting } from '../utils';
-
-describe('getSettingValue', () => {
-  it('should work for Days', () => {
-    expect(getSettingValue({ analysis: 'analysis', days: '35', type: 'NUMBER_OF_DAYS' })).toBe(
-      '35'
-    );
-  });
-
-  it('should work for Analysis', () => {
-    expect(getSettingValue({ analysis: 'analysis1', days: '35', type: 'SPECIFIC_ANALYSIS' })).toBe(
-      'analysis1'
-    );
-  });
-
-  it('should work for Previous version', () => {
-    expect(
-      getSettingValue({ analysis: 'analysis1', days: '35', type: 'PREVIOUS_VERSION' })
-    ).toBeUndefined();
-  });
-});
-
-describe('validateSettings', () => {
-  it('should validate at branch level', () => {
-    expect(validateSetting({ days: '' })).toEqual({ isChanged: false, isValid: false });
-    expect(
-      validateSetting({
-        currentSetting: 'PREVIOUS_VERSION',
-        days: '12',
-        selected: 'NUMBER_OF_DAYS'
-      })
-    ).toEqual({ isChanged: true, isValid: true });
-    expect(
-      validateSetting({
-        currentSetting: 'PREVIOUS_VERSION',
-        days: 'nope',
-        selected: 'NUMBER_OF_DAYS'
-      })
-    ).toEqual({ isChanged: true, isValid: false });
-    expect(
-      validateSetting({
-        currentSetting: 'NUMBER_OF_DAYS',
-        currentSettingValue: '15',
-        days: '15',
-        selected: 'NUMBER_OF_DAYS'
-      })
-    ).toEqual({ isChanged: false, isValid: true });
-    expect(
-      validateSetting({
-        currentSetting: 'NUMBER_OF_DAYS',
-        currentSettingValue: '15',
-        days: '13',
-        selected: 'NUMBER_OF_DAYS'
-      })
-    ).toEqual({ isChanged: true, isValid: true });
-    expect(
-      validateSetting({
-        analysis: 'analysis1',
-        currentSetting: 'SPECIFIC_ANALYSIS',
-        currentSettingValue: 'analysis1',
-        days: '',
-        selected: 'SPECIFIC_ANALYSIS'
-      })
-    ).toEqual({ isChanged: false, isValid: true });
-    expect(
-      validateSetting({
-        analysis: 'analysis2',
-        currentSetting: 'SPECIFIC_ANALYSIS',
-        currentSettingValue: 'analysis1',
-        days: '',
-        selected: 'SPECIFIC_ANALYSIS'
-      })
-    ).toEqual({ isChanged: true, isValid: true });
-  });
-
-  it('should validate at project level', () => {
-    expect(validateSetting({ days: '', overrideGeneralSetting: false })).toEqual({
-      isChanged: false,
-      isValid: true
-    });
-    expect(validateSetting({ days: '', overrideGeneralSetting: true })).toEqual({
-      isChanged: true,
-      isValid: false
-    });
-    expect(
-      validateSetting({
-        currentSetting: 'PREVIOUS_VERSION',
-        days: '',
-        overrideGeneralSetting: false
-      })
-    ).toEqual({
-      isChanged: true,
-      isValid: true
-    });
-  });
-});
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/App-test.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/App-test.tsx
new file mode 100644 (file)
index 0000000..d19e6f4
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * 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 { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
+import {
+  getNewCodePeriod,
+  resetNewCodePeriod,
+  setNewCodePeriod
+} from '../../../../api/newCodePeriod';
+import { mockComponent, mockEvent } from '../../../../helpers/testMocks';
+import App from '../App';
+
+jest.mock('../../../../api/newCodePeriod', () => ({
+  getNewCodePeriod: jest.fn().mockResolvedValue({}),
+  resetNewCodePeriod: jest.fn().mockResolvedValue({}),
+  setNewCodePeriod: jest.fn().mockResolvedValue({})
+}));
+
+it('should render correctly', () => {
+  expect(shallowRender()).toMatchSnapshot();
+});
+
+it('should not display reset button if project setting is not set', () => {
+  const wrapper = shallowRender();
+
+  expect(wrapper.find('Button')).toHaveLength(0);
+});
+
+it('should reset the setting correctly', async () => {
+  const wrapper = shallowRender();
+  await waitAndUpdate(wrapper);
+  wrapper.instance().resetSetting();
+  await waitAndUpdate(wrapper);
+  expect(wrapper.state('currentSetting')).toBeUndefined();
+  expect(wrapper.state('selected')).toBeUndefined();
+});
+
+it('should save correctly', async () => {
+  const component = mockComponent();
+  const wrapper = shallowRender({ component });
+  await waitAndUpdate(wrapper);
+  wrapper.setState({ selected: 'NUMBER_OF_DAYS', days: '23' });
+  wrapper.instance().handleSubmit(mockEvent());
+  await waitAndUpdate(wrapper);
+  expect(setNewCodePeriod).toHaveBeenCalledWith({
+    project: component.key,
+    type: 'NUMBER_OF_DAYS',
+    value: '23'
+  });
+  expect(wrapper.state('currentSetting')).toEqual(wrapper.state('selected'));
+});
+
+it('should handle errors gracefully', async () => {
+  (getNewCodePeriod as jest.Mock).mockRejectedValue('error');
+  (setNewCodePeriod as jest.Mock).mockRejectedValue('error');
+  (resetNewCodePeriod as jest.Mock).mockRejectedValue('error');
+
+  const wrapper = shallowRender();
+  wrapper.setState({ selected: 'PREVIOUS_VERSION' });
+  await waitAndUpdate(wrapper);
+
+  expect(wrapper.state('loading')).toBe(false);
+  wrapper.instance().resetSetting();
+  await waitAndUpdate(wrapper);
+  expect(wrapper.state('saving')).toBe(false);
+  wrapper.instance().handleSubmit(mockEvent());
+  await waitAndUpdate(wrapper);
+  expect(wrapper.state('saving')).toBe(false);
+});
+
+function shallowRender(props: Partial<App['props']> = {}) {
+  return shallow<App>(
+    <App
+      branchLikes={[]}
+      branchesEnabled={true}
+      canAdmin={true}
+      component={mockComponent()}
+      {...props}
+    />
+  );
+}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/BaselineSettingAnalysis-test.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/BaselineSettingAnalysis-test.tsx
new file mode 100644 (file)
index 0000000..38ad100
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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 BaselineSettingAnalysis, { Props } from '../BaselineSettingAnalysis';
+
+it('should render correctly', () => {
+  expect(shallowRender()).toMatchSnapshot();
+});
+
+it('should callback when clicked', () => {
+  const onSelect = jest.fn();
+  const wrapper = shallowRender({ onSelect, selected: false });
+
+  wrapper
+    .find('RadioCard')
+    .first()
+    .simulate('click');
+  expect(onSelect).toHaveBeenCalledWith('SPECIFIC_ANALYSIS');
+});
+
+function shallowRender(props: Partial<Props> = {}) {
+  return shallow(<BaselineSettingAnalysis onSelect={jest.fn()} selected={true} {...props} />);
+}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/BaselineSettingDays-test.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/BaselineSettingDays-test.tsx
new file mode 100644 (file)
index 0000000..600401f
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * 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 BaselineSettingDays, { Props } from '../BaselineSettingDays';
+
+it('should render correctly', () => {
+  expect(shallowRender()).toMatchSnapshot();
+  expect(shallowRender({ isChanged: true })).toMatchSnapshot();
+  expect(shallowRender({ isChanged: true, isValid: false })).toMatchSnapshot();
+});
+
+it('should not display input when not selected', () => {
+  const wrapper = shallowRender({ selected: false });
+  expect(wrapper.find('ValidationInput')).toHaveLength(0);
+});
+
+it('should callback when clicked', () => {
+  const onSelect = jest.fn();
+  const wrapper = shallowRender({ onSelect, selected: false });
+
+  wrapper
+    .find('RadioCard')
+    .first()
+    .simulate('click');
+  expect(onSelect).toHaveBeenCalledWith('NUMBER_OF_DAYS');
+});
+
+it('should callback when changing days', () => {
+  const onChangeDays = jest.fn();
+  const wrapper = shallowRender({ onChangeDays });
+
+  wrapper
+    .find('input')
+    .first()
+    .simulate('change', { currentTarget: { value: '23' } });
+  expect(onChangeDays).toHaveBeenCalledWith('23');
+});
+
+function shallowRender(props: Partial<Props> = {}) {
+  return shallow(
+    <BaselineSettingDays
+      days="28"
+      isChanged={false}
+      isValid={true}
+      onChangeDays={jest.fn()}
+      onSelect={jest.fn()}
+      selected={true}
+      {...props}
+    />
+  );
+}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/BaselineSettingPreviousVersion-test.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/BaselineSettingPreviousVersion-test.tsx
new file mode 100644 (file)
index 0000000..73b22d2
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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 BaselineSettingPreviousVersion, { Props } from '../BaselineSettingPreviousVersion';
+
+it('should render correctly', () => {
+  expect(shallowRender()).toMatchSnapshot();
+  expect(shallowRender({ isDefault: true })).toMatchSnapshot();
+});
+
+it('should callback when clicked', () => {
+  const onSelect = jest.fn();
+  const wrapper = shallowRender({ onSelect, selected: false });
+
+  wrapper
+    .find('RadioCard')
+    .first()
+    .simulate('click');
+  expect(onSelect).toHaveBeenCalledWith('PREVIOUS_VERSION');
+});
+
+function shallowRender(props: Partial<Props> = {}) {
+  return shallow(
+    <BaselineSettingPreviousVersion onSelect={jest.fn()} selected={true} {...props} />
+  );
+}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/BranchAnalysisList-test.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/BranchAnalysisList-test.tsx
new file mode 100644 (file)
index 0000000..bb2f914
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * 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 { subDays } from 'date-fns';
+import { shallow } from 'enzyme';
+import * as React from 'react';
+import { toShortNotSoISOString } from 'sonar-ui-common/helpers/dates';
+import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
+import { getProjectActivity } from '../../../../api/projectActivity';
+import { mockAnalysis, mockAnalysisEvent } from '../../../../helpers/testMocks';
+import BranchAnalysisList from '../BranchAnalysisList';
+
+jest.mock('date-fns/start_of_day', () =>
+  jest.fn(() => ({
+    getTime: () => '1488322800000' // 2017-03-02
+  }))
+);
+
+jest.mock('sonar-ui-common/helpers/dates', () => ({
+  parseDate: jest.fn().mockReturnValue('2017-03-02'),
+  toShortNotSoISOString: jest.fn().mockReturnValue('2017-03-02')
+}));
+
+jest.mock('../../../../api/projectActivity', () => ({
+  getProjectActivity: jest.fn().mockResolvedValue({
+    analyses: []
+  })
+}));
+
+beforeEach(() => {
+  jest.clearAllMocks();
+});
+
+it('should render correctly', async () => {
+  (getProjectActivity as jest.Mock).mockResolvedValue({
+    analyses: [
+      mockAnalysis({
+        key: '4',
+        date: '2017-03-02T10:36:01',
+        projectVersion: '4.2'
+      }),
+      mockAnalysis({
+        key: '3',
+        date: '2017-03-02T09:36:01',
+        events: [mockAnalysisEvent()],
+        projectVersion: '4.2'
+      }),
+      mockAnalysis({
+        key: '2',
+        date: '2017-03-02T08:36:01',
+        events: [
+          mockAnalysisEvent(),
+          mockAnalysisEvent({ category: 'VERSION', qualityGate: undefined })
+        ],
+        projectVersion: '4.1'
+      }),
+      mockAnalysis({ key: '1', projectVersion: '4.1' })
+    ]
+  });
+
+  const wrapper = shallowRender();
+  await waitAndUpdate(wrapper);
+  expect(wrapper).toMatchSnapshot();
+});
+
+it('should reload analyses after range change', () => {
+  const wrapper = shallowRender();
+
+  wrapper.instance().handleRangeChange({ value: 30 });
+
+  expect(getProjectActivity).toBeCalledWith({
+    branch: 'master',
+    project: 'project1',
+    from: toShortNotSoISOString(subDays(new Date(), 30))
+  });
+});
+
+it('should register the badge nodes', () => {
+  const wrapper = shallowRender();
+
+  const element = document.createElement('div');
+
+  wrapper.instance().registerBadgeNode('4.3')(element);
+
+  expect(element.getAttribute('originOffsetTop')).not.toBeNull();
+});
+
+it('should handle scroll', () => {
+  const wrapper = shallowRender();
+
+  wrapper.instance().handleScroll({ currentTarget: { scrollTop: 12 } } as any);
+
+  expect(wrapper.state('scroll')).toBe(12);
+});
+
+function shallowRender(props: Partial<BranchAnalysisList['props']> = {}) {
+  return shallow<BranchAnalysisList>(
+    <BranchAnalysisList
+      analysis="analysis1"
+      branch="master"
+      component="project1"
+      onSelectAnalysis={jest.fn()}
+      {...props}
+    />
+  );
+}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/BranchBaselineSettingModal-test.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/BranchBaselineSettingModal-test.tsx
new file mode 100644 (file)
index 0000000..f1fee0e
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * 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 { mockEvent, waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
+import { setNewCodePeriod } from '../../../../api/newCodePeriod';
+import { mockMainBranch } from '../../../../helpers/mocks/branch-like';
+import BranchBaselineSettingModal from '../BranchBaselineSettingModal';
+
+jest.mock('../../../../api/newCodePeriod', () => ({
+  setNewCodePeriod: jest.fn().mockResolvedValue({})
+}));
+
+it('should render correctly', () => {
+  expect(shallowRender()).toMatchSnapshot();
+});
+
+it('should display the branch analysis list when necessary', () => {
+  const wrapper = shallowRender();
+
+  wrapper.setState({ selected: 'SPECIFIC_ANALYSIS' });
+
+  expect(wrapper.find('BranchAnalysisList')).toHaveLength(1);
+});
+
+it('should save correctly', async () => {
+  const branch = mockMainBranch({ name: 'branchname' });
+  const component = 'compKey';
+  const wrapper = shallowRender({
+    branch,
+    component
+  });
+
+  wrapper.setState({ analysis: 'analysis572893', selected: 'SPECIFIC_ANALYSIS' });
+  await waitAndUpdate(wrapper);
+
+  wrapper.instance().handleSubmit(mockEvent());
+  await new Promise(setImmediate);
+
+  expect(setNewCodePeriod).toHaveBeenCalledWith({
+    project: component,
+    type: 'SPECIFIC_ANALYSIS',
+    value: 'analysis572893',
+    branch: 'branchname'
+  });
+});
+
+it('should disable the save button when saving', () => {
+  const wrapper = shallowRender();
+
+  wrapper.setState({ saving: true });
+
+  expect(
+    wrapper
+      .find('SubmitButton')
+      .first()
+      .prop('disabled')
+  ).toBe(true);
+});
+
+it('should disable the save button when date is invalid', () => {
+  const wrapper = shallowRender();
+
+  wrapper.setState({ days: 'asdf' });
+
+  expect(
+    wrapper
+      .find('SubmitButton')
+      .first()
+      .prop('disabled')
+  ).toBe(true);
+});
+
+function shallowRender(props: Partial<BranchBaselineSettingModal['props']> = {}) {
+  return shallow<BranchBaselineSettingModal>(
+    <BranchBaselineSettingModal
+      branch={mockMainBranch()}
+      component="compKey"
+      onClose={jest.fn()}
+      {...props}
+    />
+  );
+}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/BranchList-test.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/BranchList-test.tsx
new file mode 100644 (file)
index 0000000..f46e49b
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * 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 { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
+import { listBranchesNewCodePeriod, resetNewCodePeriod } from '../../../../api/newCodePeriod';
+import { mockBranch, mockMainBranch, mockPullRequest } from '../../../../helpers/mocks/branch-like';
+import { mockComponent } from '../../../../helpers/testMocks';
+import BranchBaselineSettingModal from '../BranchBaselineSettingModal';
+import BranchList from '../BranchList';
+
+jest.mock('../../../../api/newCodePeriod', () => ({
+  listBranchesNewCodePeriod: jest.fn().mockResolvedValue({ newCodePeriods: [] }),
+  resetNewCodePeriod: jest.fn().mockResolvedValue(null)
+}));
+
+it('should render correctly', async () => {
+  (listBranchesNewCodePeriod as jest.Mock).mockResolvedValueOnce({
+    newCodePeriods: [
+      {
+        projectKey: '',
+        branchKey: 'master',
+        type: 'NUMBER_OF_DAYS',
+        value: '27'
+      }
+    ]
+  });
+  const wrapper = shallowRender({
+    branchLikes: [
+      mockMainBranch(),
+      mockBranch(),
+      mockBranch({ name: 'branch-7.0' }),
+      mockPullRequest()
+    ]
+  });
+  await waitAndUpdate(wrapper);
+  expect(wrapper.state().branches).toHaveLength(3);
+  expect(wrapper).toMatchSnapshot();
+});
+
+it('should handle reset', () => {
+  const component = mockComponent();
+  const wrapper = shallowRender({ component });
+
+  wrapper.instance().resetToDefault('master');
+
+  expect(resetNewCodePeriod).toBeCalledWith({
+    project: component.key,
+    branch: 'master'
+  });
+});
+
+it('should toggle popup', async () => {
+  const wrapper = shallowRender({ branchLikes: [mockMainBranch(), mockBranch()] });
+
+  wrapper.setState({ editedBranch: mockMainBranch() });
+
+  await waitAndUpdate(wrapper);
+
+  const nodes = wrapper.find(BranchBaselineSettingModal);
+  expect(nodes).toHaveLength(1);
+  expect(nodes.first().props().branch).toEqual(mockMainBranch());
+
+  wrapper.instance().closeEditModal('master', { type: 'NUMBER_OF_DAYS', value: '23' });
+
+  expect(wrapper.find('BranchBaselineSettingModal')).toHaveLength(0);
+  expect(wrapper.state().branches.find(b => b.name === 'master')).toEqual({
+    analysisDate: '2018-01-01',
+    excludedFromPurge: true,
+    isMain: true,
+    name: 'master',
+    newCodePeriod: {
+      type: 'NUMBER_OF_DAYS',
+      value: '23'
+    }
+  });
+});
+
+it('should render the right setting label', () => {
+  const wrapper = shallowRender();
+
+  expect(
+    wrapper.instance().renderNewCodePeriodSetting({ type: 'NUMBER_OF_DAYS', value: '21' })
+  ).toBe('baseline.number_days: 21');
+  expect(wrapper.instance().renderNewCodePeriodSetting({ type: 'PREVIOUS_VERSION' })).toBe(
+    'baseline.previous_version'
+  );
+  expect(
+    wrapper.instance().renderNewCodePeriodSetting({
+      type: 'SPECIFIC_ANALYSIS',
+      value: 'A85835',
+      effectiveValue: '2018-12-02T13:01:12'
+    })
+  ).toMatchInlineSnapshot(`
+    <React.Fragment>
+      baseline.specific_analysis: 
+      <DateTimeFormatter
+        date="2018-12-02T13:01:12"
+      />
+    </React.Fragment>
+  `);
+});
+
+function shallowRender(props: Partial<BranchList['props']> = {}) {
+  return shallow<BranchList>(
+    <BranchList
+      branchLikes={[]}
+      component={mockComponent()}
+      inheritedSetting={{ type: 'PREVIOUS_VERSION' }}
+      {...props}
+    />
+  );
+}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/ProjectBaselineSelector-test.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/ProjectBaselineSelector-test.tsx
new file mode 100644 (file)
index 0000000..aacc683
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * 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 ProjectBaselineSelector, { ProjectBaselineSelectorProps } from '../ProjectBaselineSelector';
+
+it('should render correctly', () => {
+  expect(shallowRender()).toMatchSnapshot();
+  expect(
+    shallowRender({
+      branchesEnabled: false,
+      generalSetting: { type: 'NUMBER_OF_DAYS', value: '23' }
+    })
+  ).toMatchSnapshot();
+  expect(
+    shallowRender({ branchesEnabled: false, generalSetting: { type: 'NUMBER_OF_DAYS', value: '' } })
+  ).toMatchSnapshot();
+});
+
+it('should not show save button when unchanged', () => {
+  const wrapper = shallowRender({
+    currentSetting: 'PREVIOUS_VERSION',
+    selected: 'PREVIOUS_VERSION',
+    overrideGeneralSetting: true
+  });
+  expect(
+    wrapper
+      .find('SubmitButton')
+      .parent()
+      .hasClass('invisible')
+  ).toBe(true);
+});
+
+it('should show save button when changed', () => {
+  const wrapper = shallowRender({
+    currentSetting: 'PREVIOUS_VERSION',
+    selected: 'NUMBER_OF_DAYS',
+    overrideGeneralSetting: true
+  });
+  expect(wrapper.find('SubmitButton')).toHaveLength(1);
+});
+
+it('should show save button when value changed', () => {
+  const wrapper = shallowRender({
+    currentSetting: 'NUMBER_OF_DAYS',
+    currentSettingValue: '23',
+    days: '25',
+    selected: 'NUMBER_OF_DAYS',
+    overrideGeneralSetting: true
+  });
+  expect(wrapper.find('SubmitButton')).toHaveLength(1);
+});
+
+it('should disable the save button when saving', () => {
+  const wrapper = shallowRender({
+    currentSetting: 'NUMBER_OF_DAYS',
+    currentSettingValue: '25',
+    saving: true,
+    selected: 'PREVIOUS_VERSION',
+    overrideGeneralSetting: true
+  });
+
+  expect(
+    wrapper
+      .find('SubmitButton')
+      .first()
+      .prop('disabled')
+  ).toBe(true);
+});
+
+it('should disable the save button when date is invalid', () => {
+  const wrapper = shallowRender({
+    currentSetting: 'PREVIOUS_VERSION',
+    days: 'hello',
+    selected: 'NUMBER_OF_DAYS',
+    overrideGeneralSetting: true
+  });
+
+  expect(
+    wrapper
+      .find('SubmitButton')
+      .first()
+      .prop('disabled')
+  ).toBe(true);
+});
+
+function shallowRender(props: Partial<ProjectBaselineSelectorProps> = {}) {
+  return shallow(
+    <ProjectBaselineSelector
+      branchesEnabled={true}
+      component=""
+      days="12"
+      generalSetting={{}}
+      onCancel={jest.fn()}
+      onSelectAnalysis={jest.fn()}
+      onSelectDays={jest.fn()}
+      onSelectSetting={jest.fn()}
+      onSubmit={jest.fn()}
+      onToggleSpecificSetting={jest.fn()}
+      overrideGeneralSetting={false}
+      saving={false}
+      {...props}
+    />
+  );
+}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/App-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/App-test.tsx.snap
new file mode 100644 (file)
index 0000000..d23ae12
--- /dev/null
@@ -0,0 +1,60 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<Fragment>
+  <Suggestions
+    suggestions="project_baseline"
+  />
+  <div
+    className="page page-limited"
+  >
+    <header
+      className="page-header"
+    >
+      <h1
+        className="page-title"
+      >
+        project_baseline.page
+      </h1>
+      <p
+        className="page-description"
+      >
+        <FormattedMessage
+          defaultMessage="project_baseline.page.description"
+          id="project_baseline.page.description"
+          values={
+            Object {
+              "link": <Link
+                onlyActiveOnIndex={false}
+                style={Object {}}
+                to="/documentation/project-administration/new-code-period/"
+              >
+                project_baseline.page.description.link
+              </Link>,
+            }
+          }
+        />
+        <br />
+        <FormattedMessage
+          defaultMessage="project_baseline.page.description2"
+          id="project_baseline.page.description2"
+          values={
+            Object {
+              "link": <Link
+                onlyActiveOnIndex={false}
+                style={Object {}}
+                to="/admin/settings?category=new_code_period"
+              >
+                project_baseline.page.description2.link
+              </Link>,
+            }
+          }
+        />
+      </p>
+    </header>
+    <DeferredSpinner
+      timeout={100}
+    />
+  </div>
+</Fragment>
+`;
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BaselineSettingAnalysis-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BaselineSettingAnalysis-test.tsx.snap
new file mode 100644 (file)
index 0000000..a5dc612
--- /dev/null
@@ -0,0 +1,15 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<RadioCard
+  onClick={[Function]}
+  selected={true}
+  title="baseline.specific_analysis"
+>
+  <p
+    className="big-spacer-bottom"
+  >
+    baseline.specific_analysis.description
+  </p>
+</RadioCard>
+`;
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BaselineSettingDays-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BaselineSettingDays-test.tsx.snap
new file mode 100644 (file)
index 0000000..aabe88a
--- /dev/null
@@ -0,0 +1,82 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<RadioCard
+  onClick={[Function]}
+  selected={true}
+  title="baseline.number_days"
+>
+  <p
+    className="big-spacer-bottom"
+  >
+    baseline.number_days.description
+  </p>
+  <ValidationInput
+    id="baseline_number_of_days"
+    isInvalid={false}
+    isValid={false}
+    label="baseline.specify_days"
+    required={true}
+  >
+    <input
+      onChange={[Function]}
+      type="text"
+      value="28"
+    />
+  </ValidationInput>
+</RadioCard>
+`;
+
+exports[`should render correctly 2`] = `
+<RadioCard
+  onClick={[Function]}
+  selected={true}
+  title="baseline.number_days"
+>
+  <p
+    className="big-spacer-bottom"
+  >
+    baseline.number_days.description
+  </p>
+  <ValidationInput
+    id="baseline_number_of_days"
+    isInvalid={false}
+    isValid={true}
+    label="baseline.specify_days"
+    required={true}
+  >
+    <input
+      onChange={[Function]}
+      type="text"
+      value="28"
+    />
+  </ValidationInput>
+</RadioCard>
+`;
+
+exports[`should render correctly 3`] = `
+<RadioCard
+  onClick={[Function]}
+  selected={true}
+  title="baseline.number_days"
+>
+  <p
+    className="big-spacer-bottom"
+  >
+    baseline.number_days.description
+  </p>
+  <ValidationInput
+    id="baseline_number_of_days"
+    isInvalid={true}
+    isValid={false}
+    label="baseline.specify_days"
+    required={true}
+  >
+    <input
+      onChange={[Function]}
+      type="text"
+      value="28"
+    />
+  </ValidationInput>
+</RadioCard>
+`;
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BaselineSettingPreviousVersion-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BaselineSettingPreviousVersion-test.tsx.snap
new file mode 100644 (file)
index 0000000..cb4acd7
--- /dev/null
@@ -0,0 +1,25 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<RadioCard
+  onClick={[Function]}
+  selected={true}
+  title="baseline.previous_version"
+>
+  <p>
+    baseline.previous_version.description
+  </p>
+</RadioCard>
+`;
+
+exports[`should render correctly 2`] = `
+<RadioCard
+  onClick={[Function]}
+  selected={true}
+  title="baseline.previous_version (default)"
+>
+  <p>
+    baseline.previous_version.description
+  </p>
+</RadioCard>
+`;
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BranchAnalysisList-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BranchAnalysisList-test.tsx.snap
new file mode 100644 (file)
index 0000000..46a6219
--- /dev/null
@@ -0,0 +1,271 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<Fragment>
+  <div
+    className="spacer-bottom"
+  >
+    baseline.analysis_from
+    <Select
+      autoBlur={true}
+      className="input-medium spacer-left"
+      clearable={false}
+      onChange={[Function]}
+      options={
+        Array [
+          Object {
+            "label": "baseline.branch_analyses.ranges.30days",
+            "value": 30,
+          },
+          Object {
+            "label": "baseline.branch_analyses.ranges.allTime",
+            "value": 0,
+          },
+        ]
+      }
+      searchable={false}
+      value={0}
+    />
+  </div>
+  <div
+    className="branch-analysis-list-wrapper"
+  >
+    <div
+      className="bordered branch-analysis-list"
+      onScroll={[Function]}
+    >
+      <ul>
+        <li
+          key="noversion"
+        >
+          <ul
+            className="branch-analysis-days-list"
+          >
+            <li
+              className="branch-analysis-day"
+              data-day="2017-03-02"
+              key="1488322800000"
+            >
+              <div
+                className="branch-analysis-date"
+              >
+                <DateFormatter
+                  date={1488322800000}
+                  long={true}
+                />
+              </div>
+              <ul
+                className="branch-analysis-analyses-list"
+              >
+                <li
+                  className="branch-analysis"
+                  data-date="2017-03-02"
+                  key="4"
+                  onClick={[Function]}
+                >
+                  <div
+                    className="branch-analysis-time spacer-right"
+                  >
+                    <TimeFormatter
+                      date="2017-03-02"
+                      long={false}
+                    >
+                      <Component />
+                    </TimeFormatter>
+                  </div>
+                  <div
+                    className="analysis-selection-button"
+                  >
+                    <i
+                      className="icon-radio"
+                    />
+                  </div>
+                </li>
+                <li
+                  className="branch-analysis"
+                  data-date="2017-03-02"
+                  key="3"
+                  onClick={[Function]}
+                >
+                  <div
+                    className="branch-analysis-time spacer-right"
+                  >
+                    <TimeFormatter
+                      date="2017-03-02"
+                      long={false}
+                    >
+                      <Component />
+                    </TimeFormatter>
+                  </div>
+                  <Memo(Events)
+                    analysisKey="3"
+                    events={
+                      Array [
+                        Object {
+                          "category": "QUALITY_GATE",
+                          "description": "Lorem ipsum dolor sit amet",
+                          "key": "E11",
+                          "name": "Lorem ipsum",
+                          "qualityGate": Object {
+                            "failing": Array [
+                              Object {
+                                "branch": "master",
+                                "key": "foo",
+                                "name": "Foo",
+                              },
+                              Object {
+                                "branch": "feature/bar",
+                                "key": "bar",
+                                "name": "Bar",
+                              },
+                            ],
+                            "status": "ERROR",
+                            "stillFailing": true,
+                          },
+                        },
+                      ]
+                    }
+                    isFirst={false}
+                  />
+                  <div
+                    className="analysis-selection-button"
+                  >
+                    <i
+                      className="icon-radio"
+                    />
+                  </div>
+                </li>
+              </ul>
+            </li>
+          </ul>
+        </li>
+        <li
+          key="E11"
+        >
+          <div
+            className="branch-analysis-version-badge"
+          >
+            <Tooltip
+              mouseEnterDelay={0.5}
+              overlay="version Lorem ipsum"
+            >
+              <span
+                className="badge"
+              >
+                Lorem ipsum
+              </span>
+            </Tooltip>
+          </div>
+          <ul
+            className="branch-analysis-days-list"
+          >
+            <li
+              className="branch-analysis-day"
+              data-day="2017-03-02"
+              key="1488322800000"
+            >
+              <div
+                className="branch-analysis-date"
+              >
+                <DateFormatter
+                  date={1488322800000}
+                  long={true}
+                />
+              </div>
+              <ul
+                className="branch-analysis-analyses-list"
+              >
+                <li
+                  className="branch-analysis"
+                  data-date="2017-03-02"
+                  key="2"
+                  onClick={[Function]}
+                >
+                  <div
+                    className="branch-analysis-time spacer-right"
+                  >
+                    <TimeFormatter
+                      date="2017-03-02"
+                      long={false}
+                    >
+                      <Component />
+                    </TimeFormatter>
+                  </div>
+                  <Memo(Events)
+                    analysisKey="2"
+                    events={
+                      Array [
+                        Object {
+                          "category": "QUALITY_GATE",
+                          "description": "Lorem ipsum dolor sit amet",
+                          "key": "E11",
+                          "name": "Lorem ipsum",
+                          "qualityGate": Object {
+                            "failing": Array [
+                              Object {
+                                "branch": "master",
+                                "key": "foo",
+                                "name": "Foo",
+                              },
+                              Object {
+                                "branch": "feature/bar",
+                                "key": "bar",
+                                "name": "Bar",
+                              },
+                            ],
+                            "status": "ERROR",
+                            "stillFailing": true,
+                          },
+                        },
+                        Object {
+                          "category": "VERSION",
+                          "description": "Lorem ipsum dolor sit amet",
+                          "key": "E11",
+                          "name": "Lorem ipsum",
+                          "qualityGate": undefined,
+                        },
+                      ]
+                    }
+                    isFirst={false}
+                  />
+                  <div
+                    className="analysis-selection-button"
+                  >
+                    <i
+                      className="icon-radio"
+                    />
+                  </div>
+                </li>
+                <li
+                  className="branch-analysis"
+                  data-date="2017-03-02"
+                  key="1"
+                  onClick={[Function]}
+                >
+                  <div
+                    className="branch-analysis-time spacer-right"
+                  >
+                    <TimeFormatter
+                      date="2017-03-02"
+                      long={false}
+                    >
+                      <Component />
+                    </TimeFormatter>
+                  </div>
+                  <div
+                    className="analysis-selection-button"
+                  >
+                    <i
+                      className="icon-radio"
+                    />
+                  </div>
+                </li>
+              </ul>
+            </li>
+          </ul>
+        </li>
+      </ul>
+    </div>
+  </div>
+</Fragment>
+`;
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BranchBaselineSettingModal-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BranchBaselineSettingModal-test.tsx.snap
new file mode 100644 (file)
index 0000000..e9ffc30
--- /dev/null
@@ -0,0 +1,66 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<Modal
+  contentLabel="baseline.new_code_period_for_branch_x.master"
+  onRequestClose={[Function]}
+  size="large"
+>
+  <header
+    className="modal-head"
+  >
+    <h2>
+      baseline.new_code_period_for_branch_x.master
+    </h2>
+  </header>
+  <form
+    onSubmit={[Function]}
+  >
+    <div
+      className="modal-body modal-container branch-baseline-setting-modal"
+    >
+      <div
+        className="display-flex-row huge-spacer-bottom"
+        role="radiogroup"
+      >
+        <BaselineSettingPreviousVersion
+          isDefault={false}
+          onSelect={[Function]}
+          selected={false}
+        />
+        <BaselineSettingDays
+          days="30"
+          isChanged={false}
+          isValid={false}
+          onChangeDays={[Function]}
+          onSelect={[Function]}
+          selected={false}
+        />
+        <BaselineSettingAnalysis
+          onSelect={[Function]}
+          selected={false}
+        />
+      </div>
+    </div>
+    <footer
+      className="modal-foot"
+    >
+      <DeferredSpinner
+        className="spacer-right"
+        loading={false}
+        timeout={100}
+      />
+      <SubmitButton
+        disabled={true}
+      >
+        save
+      </SubmitButton>
+      <ResetButtonLink
+        onClick={[MockFunction]}
+      >
+        cancel
+      </ResetButtonLink>
+    </footer>
+  </form>
+</Modal>
+`;
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BranchList-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/BranchList-test.tsx.snap
new file mode 100644 (file)
index 0000000..5c2965d
--- /dev/null
@@ -0,0 +1,152 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<Fragment>
+  <table
+    className="data zebra"
+  >
+    <thead>
+      <tr>
+        <th>
+          branch_list.branch
+        </th>
+        <th
+          className="nowrap huge-spacer-right"
+        >
+          branch_list.current_setting
+        </th>
+        <th
+          className="thin nowrap"
+        >
+          branch_list.actions
+        </th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr
+        key="master"
+      >
+        <td
+          className="nowrap"
+        >
+          <BranchLikeIcon
+            branchLike={
+              Object {
+                "analysisDate": "2018-01-01",
+                "excludedFromPurge": true,
+                "isMain": true,
+                "name": "master",
+                "newCodePeriod": Object {
+                  "effectiveValue": undefined,
+                  "type": "NUMBER_OF_DAYS",
+                  "value": "27",
+                },
+              }
+            }
+            className="little-spacer-right"
+          />
+          master
+          <div
+            className="badge spacer-left"
+          >
+            branches.main_branch
+          </div>
+        </td>
+        <td
+          className="huge-spacer-right nowrap"
+        >
+          baseline.number_days: 27
+        </td>
+        <td
+          className="text-right"
+        >
+          <ActionsDropdown>
+            <ActionsDropdownItem
+              onClick={[Function]}
+            >
+              edit
+            </ActionsDropdownItem>
+            <ActionsDropdownItem
+              onClick={[Function]}
+            >
+              reset_to_default
+            </ActionsDropdownItem>
+          </ActionsDropdown>
+        </td>
+      </tr>
+      <tr
+        key="branch-6.7"
+      >
+        <td
+          className="nowrap"
+        >
+          <BranchLikeIcon
+            branchLike={
+              Object {
+                "analysisDate": "2018-01-01",
+                "excludedFromPurge": true,
+                "isMain": false,
+                "name": "branch-6.7",
+              }
+            }
+            className="little-spacer-right"
+          />
+          branch-6.7
+        </td>
+        <td
+          className="huge-spacer-right nowrap"
+        >
+          branch_list.default_setting
+        </td>
+        <td
+          className="text-right"
+        >
+          <ActionsDropdown>
+            <ActionsDropdownItem
+              onClick={[Function]}
+            >
+              edit
+            </ActionsDropdownItem>
+          </ActionsDropdown>
+        </td>
+      </tr>
+      <tr
+        key="branch-7.0"
+      >
+        <td
+          className="nowrap"
+        >
+          <BranchLikeIcon
+            branchLike={
+              Object {
+                "analysisDate": "2018-01-01",
+                "excludedFromPurge": true,
+                "isMain": false,
+                "name": "branch-7.0",
+              }
+            }
+            className="little-spacer-right"
+          />
+          branch-7.0
+        </td>
+        <td
+          className="huge-spacer-right nowrap"
+        >
+          branch_list.default_setting
+        </td>
+        <td
+          className="text-right"
+        >
+          <ActionsDropdown>
+            <ActionsDropdownItem
+              onClick={[Function]}
+            >
+              edit
+            </ActionsDropdownItem>
+          </ActionsDropdown>
+        </td>
+      </tr>
+    </tbody>
+  </table>
+</Fragment>
+`;
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/ProjectBaselineSelector-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/__snapshots__/ProjectBaselineSelector-test.tsx.snap
new file mode 100644 (file)
index 0000000..67c95df
--- /dev/null
@@ -0,0 +1,281 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<form
+  className="project-baseline-selector"
+  onSubmit={[MockFunction]}
+>
+  <div
+    className="big-spacer-top spacer-bottom"
+    role="radiogroup"
+  >
+    <Radio
+      checked={true}
+      className="big-spacer-bottom"
+      onCheck={[Function]}
+      value="general"
+    >
+      project_baseline.general_setting
+    </Radio>
+    <div
+      className="big-spacer-left"
+    >
+      <div
+        className="general-setting"
+      >
+        <strong>
+          baseline.previous_version
+        </strong>
+        : 
+        baseline.previous_version.description
+      </div>
+    </div>
+    <Radio
+      checked={false}
+      className="huge-spacer-top"
+      onCheck={[Function]}
+      value="specific"
+    >
+      project_baseline.specific_setting
+    </Radio>
+  </div>
+  <div
+    className="big-spacer-left big-spacer-right branch-baseline-setting-modal"
+  >
+    <div
+      className="display-flex-row big-spacer-bottom"
+      role="radiogroup"
+    >
+      <BaselineSettingPreviousVersion
+        disabled={true}
+        onSelect={[MockFunction]}
+        selected={false}
+      />
+      <BaselineSettingDays
+        days="12"
+        disabled={true}
+        isChanged={false}
+        isValid={true}
+        onChangeDays={[MockFunction]}
+        onSelect={[MockFunction]}
+        selected={false}
+      />
+    </div>
+  </div>
+  <div
+    className="big-spacer-top invisible"
+  >
+    <p
+      className="spacer-bottom"
+    >
+      baseline.next_analysis_notice
+    </p>
+    <DeferredSpinner
+      className="spacer-right"
+      loading={false}
+      timeout={100}
+    />
+    <SubmitButton
+      disabled={true}
+    >
+      save
+    </SubmitButton>
+    <ResetButtonLink
+      className="spacer-left"
+      onClick={[MockFunction]}
+    >
+      cancel
+    </ResetButtonLink>
+  </div>
+</form>
+`;
+
+exports[`should render correctly 2`] = `
+<form
+  className="project-baseline-selector"
+  onSubmit={[MockFunction]}
+>
+  <div
+    className="big-spacer-top spacer-bottom"
+    role="radiogroup"
+  >
+    <Radio
+      checked={true}
+      className="big-spacer-bottom"
+      onCheck={[Function]}
+      value="general"
+    >
+      project_baseline.general_setting
+    </Radio>
+    <div
+      className="big-spacer-left"
+    >
+      <div
+        className="general-setting"
+      >
+        <strong>
+          baseline.number_days (duration.days.23)
+        </strong>
+        : 
+        baseline.number_days.description
+      </div>
+    </div>
+    <Radio
+      checked={false}
+      className="huge-spacer-top"
+      onCheck={[Function]}
+      value="specific"
+    >
+      project_baseline.specific_setting
+    </Radio>
+  </div>
+  <div
+    className="big-spacer-left big-spacer-right branch-baseline-setting-modal"
+  >
+    <div
+      className="display-flex-row big-spacer-bottom"
+      role="radiogroup"
+    >
+      <BaselineSettingPreviousVersion
+        disabled={true}
+        onSelect={[MockFunction]}
+        selected={false}
+      />
+      <BaselineSettingDays
+        days="12"
+        disabled={true}
+        isChanged={false}
+        isValid={true}
+        onChangeDays={[MockFunction]}
+        onSelect={[MockFunction]}
+        selected={false}
+      />
+      <BaselineSettingAnalysis
+        disabled={true}
+        onSelect={[MockFunction]}
+        selected={false}
+      />
+    </div>
+  </div>
+  <div
+    className="big-spacer-top invisible"
+  >
+    <p
+      className="spacer-bottom"
+    >
+      baseline.next_analysis_notice
+    </p>
+    <DeferredSpinner
+      className="spacer-right"
+      loading={false}
+      timeout={100}
+    />
+    <SubmitButton
+      disabled={true}
+    >
+      save
+    </SubmitButton>
+    <ResetButtonLink
+      className="spacer-left"
+      onClick={[MockFunction]}
+    >
+      cancel
+    </ResetButtonLink>
+  </div>
+</form>
+`;
+
+exports[`should render correctly 3`] = `
+<form
+  className="project-baseline-selector"
+  onSubmit={[MockFunction]}
+>
+  <div
+    className="big-spacer-top spacer-bottom"
+    role="radiogroup"
+  >
+    <Radio
+      checked={true}
+      className="big-spacer-bottom"
+      onCheck={[Function]}
+      value="general"
+    >
+      project_baseline.general_setting
+    </Radio>
+    <div
+      className="big-spacer-left"
+    >
+      <div
+        className="general-setting"
+      >
+        <strong>
+          baseline.number_days (duration.days.?)
+        </strong>
+        : 
+        baseline.number_days.description
+      </div>
+    </div>
+    <Radio
+      checked={false}
+      className="huge-spacer-top"
+      onCheck={[Function]}
+      value="specific"
+    >
+      project_baseline.specific_setting
+    </Radio>
+  </div>
+  <div
+    className="big-spacer-left big-spacer-right branch-baseline-setting-modal"
+  >
+    <div
+      className="display-flex-row big-spacer-bottom"
+      role="radiogroup"
+    >
+      <BaselineSettingPreviousVersion
+        disabled={true}
+        onSelect={[MockFunction]}
+        selected={false}
+      />
+      <BaselineSettingDays
+        days="12"
+        disabled={true}
+        isChanged={false}
+        isValid={true}
+        onChangeDays={[MockFunction]}
+        onSelect={[MockFunction]}
+        selected={false}
+      />
+      <BaselineSettingAnalysis
+        disabled={true}
+        onSelect={[MockFunction]}
+        selected={false}
+      />
+    </div>
+  </div>
+  <div
+    className="big-spacer-top invisible"
+  >
+    <p
+      className="spacer-bottom"
+    >
+      baseline.next_analysis_notice
+    </p>
+    <DeferredSpinner
+      className="spacer-right"
+      loading={false}
+      timeout={100}
+    />
+    <SubmitButton
+      disabled={true}
+    >
+      save
+    </SubmitButton>
+    <ResetButtonLink
+      className="spacer-left"
+      onClick={[MockFunction]}
+    >
+      cancel
+    </ResetButtonLink>
+  </div>
+</form>
+`;
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/utils-test.ts b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/utils-test.ts
new file mode 100644 (file)
index 0000000..5f78465
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * 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 { getSettingValue, validateSetting } from '../../utils';
+
+describe('getSettingValue', () => {
+  it('should work for Days', () => {
+    expect(getSettingValue({ analysis: 'analysis', days: '35', type: 'NUMBER_OF_DAYS' })).toBe(
+      '35'
+    );
+  });
+
+  it('should work for Analysis', () => {
+    expect(getSettingValue({ analysis: 'analysis1', days: '35', type: 'SPECIFIC_ANALYSIS' })).toBe(
+      'analysis1'
+    );
+  });
+
+  it('should work for Previous version', () => {
+    expect(
+      getSettingValue({ analysis: 'analysis1', days: '35', type: 'PREVIOUS_VERSION' })
+    ).toBeUndefined();
+  });
+});
+
+describe('validateSettings', () => {
+  it('should validate at branch level', () => {
+    expect(validateSetting({ days: '' })).toEqual({ isChanged: false, isValid: false });
+    expect(
+      validateSetting({
+        currentSetting: 'PREVIOUS_VERSION',
+        days: '12',
+        selected: 'NUMBER_OF_DAYS'
+      })
+    ).toEqual({ isChanged: true, isValid: true });
+    expect(
+      validateSetting({
+        currentSetting: 'PREVIOUS_VERSION',
+        days: 'nope',
+        selected: 'NUMBER_OF_DAYS'
+      })
+    ).toEqual({ isChanged: true, isValid: false });
+    expect(
+      validateSetting({
+        currentSetting: 'NUMBER_OF_DAYS',
+        currentSettingValue: '15',
+        days: '15',
+        selected: 'NUMBER_OF_DAYS'
+      })
+    ).toEqual({ isChanged: false, isValid: true });
+    expect(
+      validateSetting({
+        currentSetting: 'NUMBER_OF_DAYS',
+        currentSettingValue: '15',
+        days: '13',
+        selected: 'NUMBER_OF_DAYS'
+      })
+    ).toEqual({ isChanged: true, isValid: true });
+    expect(
+      validateSetting({
+        analysis: 'analysis1',
+        currentSetting: 'SPECIFIC_ANALYSIS',
+        currentSettingValue: 'analysis1',
+        days: '',
+        selected: 'SPECIFIC_ANALYSIS'
+      })
+    ).toEqual({ isChanged: false, isValid: true });
+    expect(
+      validateSetting({
+        analysis: 'analysis2',
+        currentSetting: 'SPECIFIC_ANALYSIS',
+        currentSettingValue: 'analysis1',
+        days: '',
+        selected: 'SPECIFIC_ANALYSIS'
+      })
+    ).toEqual({ isChanged: true, isValid: true });
+  });
+
+  it('should validate at project level', () => {
+    expect(validateSetting({ days: '', overrideGeneralSetting: false })).toEqual({
+      isChanged: false,
+      isValid: true
+    });
+    expect(validateSetting({ days: '', overrideGeneralSetting: true })).toEqual({
+      isChanged: true,
+      isValid: false
+    });
+    expect(
+      validateSetting({
+        currentSetting: 'PREVIOUS_VERSION',
+        days: '',
+        overrideGeneralSetting: false
+      })
+    ).toEqual({
+      isChanged: true,
+      isValid: true
+    });
+  });
+});