From a21e5da264c70b8ab86c50c67e0bbf626598e246 Mon Sep 17 00:00:00 2001 From: Mathieu Suen Date: Mon, 21 Feb 2022 14:29:11 +0100 Subject: [NO JIRA] Migrate part of quality gates app to RTL --- .../main/js/api/mocks/QualityGatesServiceMock.ts | 294 +++++++++ server/sonar-web/src/main/js/api/quality-gates.ts | 2 +- .../ProjectQualityGateApp-test.tsx.snap | 12 +- .../js/apps/quality-gates/components/Condition.tsx | 2 + .../quality-gates/components/ConditionModal.tsx | 27 +- .../quality-gates/components/ConditionOperator.tsx | 11 +- .../apps/quality-gates/components/Conditions.tsx | 35 +- .../components/CopyQualityGateForm.tsx | 4 - .../js/apps/quality-gates/components/Details.tsx | 2 +- .../quality-gates/components/DetailsContent.tsx | 2 +- .../main/js/apps/quality-gates/components/List.tsx | 3 +- .../components/RenameQualityGateForm.tsx | 4 - .../quality-gates/components/ThresholdInput.tsx | 20 +- .../quality-gates/components/__tests__/App-it.tsx | 274 +++++++++ .../__tests__/BuiltInQualityGateBadge-test.tsx | 30 - .../components/__tests__/Condition-test.tsx | 57 -- .../components/__tests__/ConditionModal-test.tsx | 102 ---- .../__tests__/ConditionOperator-test.tsx | 37 -- .../components/__tests__/Conditions-test.tsx | 80 --- .../__tests__/CopyQualityGateForm-test.tsx | 68 --- .../__tests__/CreateQualityGateForm-test.tsx | 71 --- .../__tests__/DeleteQualityGateForm-test.tsx | 57 -- .../components/__tests__/Details-test.tsx | 2 +- .../components/__tests__/List-test.tsx | 39 -- .../components/__tests__/ListHeader-test.tsx | 33 -- .../components/__tests__/MetricSelect-test.tsx | 47 -- .../__tests__/RenameQualityGateForm-test.tsx | 64 -- .../components/__tests__/ThresholdInput-test.tsx | 74 --- .../BuiltInQualityGateBadge-test.tsx.snap | 13 - .../__snapshots__/Condition-test.tsx.snap | 203 ------- .../__snapshots__/ConditionModal-test.tsx.snap | 364 ------------ .../__snapshots__/ConditionOperator-test.tsx.snap | 26 - .../__snapshots__/Conditions-test.tsx.snap | 660 --------------------- .../CopyQualityGateForm-test.tsx.snap | 36 -- .../CreateQualityGateForm-test.tsx.snap | 36 -- .../DeleteQualityGateForm-test.tsx.snap | 13 - .../__snapshots__/DetailsContent-test.tsx.snap | 10 +- .../__snapshots__/DetailsHeader-test.tsx.snap | 2 +- .../__tests__/__snapshots__/List-test.tsx.snap | 73 --- .../__snapshots__/ListHeader-test.tsx.snap | 40 -- .../__snapshots__/MetricSelect-test.tsx.snap | 19 - .../RenameQualityGateForm-test.tsx.snap | 36 -- .../src/main/js/components/controls/Tooltip.tsx | 8 +- .../components/controls/__tests__/Tooltip-test.tsx | 10 +- .../__snapshots__/ActionsDropdown-test.tsx.snap | 4 +- .../__tests__/__snapshots__/Tooltip-test.tsx.snap | 8 +- .../components/controls/__tests__/buttons-test.tsx | 2 +- .../src/main/js/components/controls/buttons.tsx | 1 + server/sonar-web/src/main/js/helpers/testMocks.ts | 2 +- server/sonar-web/src/main/js/types/types.ts | 2 +- .../main/resources/org/sonar/l10n/core.properties | 2 + 51 files changed, 653 insertions(+), 2370 deletions(-) create mode 100644 server/sonar-web/src/main/js/api/mocks/QualityGatesServiceMock.ts create mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/App-it.tsx delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/BuiltInQualityGateBadge-test.tsx delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/Condition-test.tsx delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/ConditionModal-test.tsx delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/ConditionOperator-test.tsx delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/Conditions-test.tsx delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/CopyQualityGateForm-test.tsx delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/CreateQualityGateForm-test.tsx delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/DeleteQualityGateForm-test.tsx delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/List-test.tsx delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/ListHeader-test.tsx delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/MetricSelect-test.tsx delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/RenameQualityGateForm-test.tsx delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/ThresholdInput-test.tsx delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/BuiltInQualityGateBadge-test.tsx.snap delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/Condition-test.tsx.snap delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/ConditionModal-test.tsx.snap delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/ConditionOperator-test.tsx.snap delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/Conditions-test.tsx.snap delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/CopyQualityGateForm-test.tsx.snap delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/CreateQualityGateForm-test.tsx.snap delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/DeleteQualityGateForm-test.tsx.snap delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/List-test.tsx.snap delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/ListHeader-test.tsx.snap delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/MetricSelect-test.tsx.snap delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/RenameQualityGateForm-test.tsx.snap diff --git a/server/sonar-web/src/main/js/api/mocks/QualityGatesServiceMock.ts b/server/sonar-web/src/main/js/api/mocks/QualityGatesServiceMock.ts new file mode 100644 index 00000000000..0ca29ed0d63 --- /dev/null +++ b/server/sonar-web/src/main/js/api/mocks/QualityGatesServiceMock.ts @@ -0,0 +1,294 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 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 { cloneDeep, flatten, omit, remove } from 'lodash'; +import { mockQualityGate } from '../../helpers/mocks/quality-gates'; +import { Condition, QualityGate } from '../../types/types'; +import { + copyQualityGate, + createCondition, + createQualityGate, + deleteCondition, + deleteQualityGate, + fetchQualityGate, + fetchQualityGates, + renameQualityGate, + searchGroups, + searchProjects, + searchUsers, + updateCondition +} from '../quality-gates'; + +export class QualityGatesServiceMock { + isAdmin = false; + readOnlyList: QualityGate[]; + list: QualityGate[]; + + constructor(list?: QualityGate[], defaultId = 'AWBWEMe2qGAMGEYPjJlm') { + this.readOnlyList = list || [ + mockQualityGate({ + id: defaultId, + name: 'SonarSource way', + conditions: [ + { id: 'AXJMbIUGPAOIsUIE3eNC', metric: 'new_coverage', op: 'LT', error: '85' }, + { id: 'AXJMbIUGPAOIsUIE3eNE', metric: 'reliability_rating', op: 'GT', error: '4' }, + { id: 'AXJMbIUGPAOIsUIE3eND', metric: 'security_rating', op: 'GT', error: '4' }, + { + id: 'AXJMbIUGPAOIsUIE3eNT', + metric: 'new_maintainability_rating', + op: 'GT', + error: '1' + }, + { id: 'AXJMbIUGPAOIsUIE3eNU', metric: 'new_reliability_rating', op: 'GT', error: '1' }, + { id: 'AXJMbIUGPAOIsUIE3eNV', metric: 'new_security_rating', op: 'GT', error: '1' }, + { + id: 'AXJMbIUHPAOIsUIE3eNc', + metric: 'new_duplicated_lines_density', + op: 'GT', + error: '3' + }, + { + id: 'AXJMbIUHPAOIsUIE3eOi', + metric: 'new_security_hotspots_reviewed', + op: 'LT', + error: '100' + } + ], + isDefault: true, + isBuiltIn: false + }), + mockQualityGate({ + id: 'AXGYZrDqC-YjVCvvbRDY', + name: 'SonarSource way - CFamily', + conditions: [ + { id: 'AXJMbIUHPAOIsUIE3eOu', metric: 'new_coverage', op: 'LT', error: '0' }, + { id: 'AXJMbIUHPAOIsUIE3eOubis', metric: 'new_coverage', op: 'LT', error: '1' }, + { id: 'deprecated', metric: 'function_complexity', op: 'LT', error: '1' } + ], + isDefault: false, + isBuiltIn: false + }), + mockQualityGate({ + id: 'AWBWEMe4qGAMGEYPjJlr', + name: 'Sonar way', + conditions: [ + { id: 'AXJMbIUHPAOIsUIE3eNs', metric: 'new_security_rating', op: 'GT', error: '1' }, + { id: 'AXJMbIUHPAOIsUIE3eOD', metric: 'new_reliability_rating', op: 'GT', error: '1' }, + { + id: 'AXJMbIUHPAOIsUIE3eOE', + metric: 'new_maintainability_rating', + op: 'GT', + error: '1' + }, + { id: 'AXJMbIUHPAOIsUIE3eOF', metric: 'new_coverage', op: 'LT', error: '80' }, + { + id: 'AXJMbIUHPAOIsUIE3eOG', + metric: 'new_duplicated_lines_density', + op: 'GT', + error: '3' + }, + { + id: 'AXJMbIUHPAOIsUIE3eOk', + metric: 'new_security_hotspots_reviewed', + op: 'LT', + error: '100' + } + ], + isDefault: false, + isBuiltIn: true + }) + ]; + + this.list = cloneDeep(this.readOnlyList); + + (fetchQualityGate as jest.Mock).mockImplementation(this.showHandler); + (fetchQualityGates as jest.Mock).mockImplementation(this.listHandler); + (createQualityGate as jest.Mock).mockImplementation(this.createHandler); + (deleteQualityGate as jest.Mock).mockImplementation(this.destroyHandler); + (copyQualityGate as jest.Mock).mockImplementation(this.copyHandler); + (renameQualityGate as jest.Mock).mockImplementation(this.renameHandler); + (createCondition as jest.Mock).mockImplementation(this.createConditionHandler); + (updateCondition as jest.Mock).mockImplementation(this.updateConditionHandler); + (deleteCondition as jest.Mock).mockImplementation(this.deleteConditionHandler); + + // To be implemented. + (searchUsers as jest.Mock).mockResolvedValue({ users: [] }); + (searchGroups as jest.Mock).mockResolvedValue({ groups: [] }); + (searchProjects as jest.Mock).mockResolvedValue({ + paging: { + pageIndex: 1, + pageSize: 100, + total: 0 + }, + results: [] + }); + } + + getCorruptedQualityGateName() { + return 'SonarSource way - CFamily'; + } + + reset() { + this.setIsAdmin(false); + this.list = cloneDeep(this.readOnlyList); + } + + getDefaultQualityGate() { + return this.list.find(q => q.isDefault) || mockQualityGate({ isDefault: true }); + } + + getBuiltInQualityGate() { + return this.list.find(q => q.isBuiltIn) || mockQualityGate({ isBuiltIn: true }); + } + + setIsAdmin(isAdmin: boolean) { + this.isAdmin = isAdmin; + } + + computeActions(q: QualityGate) { + return { + rename: q.isBuiltIn ? false : this.isAdmin, + setAsDefault: q.isDefault ? false : this.isAdmin, + copy: this.isAdmin, + associateProjects: this.isAdmin, + delete: q.isBuiltIn ? false : this.isAdmin, + manageConditions: this.isAdmin, + delegate: this.isAdmin + }; + } + + listHandler = () => { + return this.reply({ + qualitygates: this.list + .map(q => omit(q, 'conditions')) + .map(q => ({ + ...q, + actions: this.computeActions(q) + })), + default: this.getDefaultQualityGate().id, + actions: { create: this.isAdmin } + }); + }; + + showHandler = ({ id }: { id: string }) => { + const qualityGate = omit( + this.list.find(q => q.id === id), + 'isDefault' + ); + return this.reply({ ...qualityGate, actions: this.computeActions(qualityGate) }); + }; + + createHandler = ({ name }: { name: string }) => { + const newId = `newId${this.list.length}`; + this.list.push( + mockQualityGate({ + id: newId, + name, + conditions: [], + isDefault: false, + isBuiltIn: false + }) + ); + return this.reply({ + id: newId, + name + }); + }; + + destroyHandler = ({ id }: { id: string }) => { + this.list = this.list.filter(q => q.id !== id); + return Promise.resolve(); + }; + + copyHandler = ({ id, name }: { id: string; name: string }) => { + const newQG = cloneDeep(this.list.find(q => q.id === id)); + if (newQG === undefined) { + return Promise.reject({ errors: [{ msg: `No quality gate has been found for id ${id}` }] }); + } + newQG.name = name; + newQG.id = `newId${this.list.length}`; + + newQG.isDefault = false; + newQG.isBuiltIn = false; + + this.list.push(newQG); + + return this.reply({ + id: newQG.id, + name + }); + }; + + renameHandler = ({ id, name }: { id: string; name: string }) => { + const renameQG = this.list.find(q => q.id === id); + if (renameQG === undefined) { + return Promise.reject({ errors: [{ msg: `No quality gate has been found for id ${id}` }] }); + } + renameQG.name = name; + return this.reply({ + id: renameQG.id, + name + }); + }; + + createConditionHandler = ( + data: { + gateId: string; + } & Omit + ) => { + const { metric, gateId, op, error } = data; + const qg = this.list.find(q => q.id === gateId); + if (qg === undefined) { + return Promise.reject({ + errors: [{ msg: `No quality gate has been found for id ${gateId}` }] + }); + } + + const conditions = qg.conditions || []; + const id = `condId${qg.id}${conditions.length}`; + const newCondition = { id, metric, op, error }; + conditions.push(newCondition); + qg.conditions = conditions; + return this.reply(newCondition); + }; + + updateConditionHandler = ({ id, metric, op, error }: Condition) => { + const condition = flatten(this.list.map(q => q.conditions || [])).find(q => q.id === id); + if (condition === undefined) { + return Promise.reject({ errors: [{ msg: `No condition has been found for id ${id}` }] }); + } + + condition.metric = metric; + condition.op = op; + condition.error = error; + + return this.reply(condition); + }; + + deleteConditionHandler = ({ id }: { id: string }) => { + this.list.forEach(q => { + remove(q.conditions || [], c => c.id === id); + }); + return Promise.resolve(); + }; + + reply(response: T): Promise { + return Promise.resolve(cloneDeep(response)); + } +} diff --git a/server/sonar-web/src/main/js/api/quality-gates.ts b/server/sonar-web/src/main/js/api/quality-gates.ts index af4bad890cb..cc3d83be8e0 100644 --- a/server/sonar-web/src/main/js/api/quality-gates.ts +++ b/server/sonar-web/src/main/js/api/quality-gates.ts @@ -73,7 +73,7 @@ export function updateCondition(data: Condition): Promise { return postJSON('/api/qualitygates/update_condition', data).catch(throwGlobalError); } -export function deleteCondition(data: { id: number }): Promise { +export function deleteCondition(data: { id: string }): Promise { return post('/api/qualitygates/delete_condition', data); } diff --git a/server/sonar-web/src/main/js/apps/projectQualityGate/__tests__/__snapshots__/ProjectQualityGateApp-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectQualityGate/__tests__/__snapshots__/ProjectQualityGateApp-test.tsx.snap index 03331f67dba..13d8d45338b 100644 --- a/server/sonar-web/src/main/js/apps/projectQualityGate/__tests__/__snapshots__/ProjectQualityGateApp-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/projectQualityGate/__tests__/__snapshots__/ProjectQualityGateApp-test.tsx.snap @@ -8,13 +8,13 @@ exports[`renders correctly 1`] = ` "conditions": Array [ Object { "error": "10", - "id": 1, + "id": "1", "metric": "coverage", "op": "LT", }, Object { "error": "10", - "id": 1, + "id": "1", "metric": "new_bugs", "op": "LT", }, @@ -26,13 +26,13 @@ exports[`renders correctly 1`] = ` "conditions": Array [ Object { "error": "10", - "id": 1, + "id": "1", "metric": "coverage", "op": "LT", }, Object { "error": "10", - "id": 1, + "id": "1", "metric": "new_bugs", "op": "LT", }, @@ -45,13 +45,13 @@ exports[`renders correctly 1`] = ` "conditions": Array [ Object { "error": "10", - "id": 1, + "id": "1", "metric": "coverage", "op": "LT", }, Object { "error": "10", - "id": 1, + "id": "1", "metric": "new_bugs", "op": "LT", }, diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/Condition.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/Condition.tsx index 4f1b4203e15..97d3834a76b 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/Condition.tsx +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/Condition.tsx @@ -108,12 +108,14 @@ export class ConditionComponent extends React.PureComponent { <> diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionModal.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionModal.tsx index 03e45767dec..be2a2129959 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionModal.tsx +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionModal.tsx @@ -65,19 +65,16 @@ export default class ConditionModal extends React.PureComponent { } handleFormSubmit = () => { - if (this.state.metric) { - const { condition, qualityGate } = this.props; - const newCondition: Omit = { - metric: this.state.metric.key, - op: this.getSinglePossibleOperator(this.state.metric) || this.state.op, - error: this.state.error - }; - const submitPromise = condition - ? updateCondition({ id: condition.id, ...newCondition }) - : createCondition({ gateId: qualityGate.id, ...newCondition }); - return submitPromise.then(this.props.onAddCondition); - } - return Promise.reject(); + const { condition, qualityGate } = this.props; + const newCondition: Omit = { + metric: this.state.metric!.key, + op: this.getSinglePossibleOperator(this.state.metric!) || this.state.op, + error: this.state.error + }; + const submitPromise = condition + ? updateCondition({ id: condition.id, ...newCondition }) + : createCondition({ gateId: qualityGate.id, ...newCondition }); + return submitPromise.then(this.props.onAddCondition); }; handleScopeChange = (scope: 'new' | 'overall') => { @@ -160,7 +157,7 @@ export default class ConditionModal extends React.PureComponent { {metric && ( <>
-
-
- -`; - -exports[`should render correctly for no conditions 1`] = ` -
-
-

- quality_gates.conditions -

- -
-
- quality_gates.no_conditions -
-
-`; - -exports[`should render correctly with an updated condition 1`] = ` -
-
-

- quality_gates.conditions -

- -
-
-

- quality_gates.conditions.overall_code.long -

-

- quality_gates.conditions.overall_code.description -

- - - - - - - - - - - - -
- quality_gates.conditions.metric - - quality_gates.conditions.operator - - quality_gates.conditions.value -
-
-
-`; - -exports[`should render correctly with new code conditions 1`] = ` -
-
-

- quality_gates.conditions -

- -
-
-

- quality_gates.conditions.new_code.long -

-

- quality_gates.conditions.new_code.description -

- - - - - - - - - - - - -
- quality_gates.conditions.metric - - quality_gates.conditions.operator - - quality_gates.conditions.value -
-
-
-

- quality_gates.conditions.overall_code.long -

-

- quality_gates.conditions.overall_code.description -

- - - - - - - - - - - - -
- quality_gates.conditions.metric - - quality_gates.conditions.operator - - quality_gates.conditions.value -
-
-
-`; - -exports[`should render the add conditions button and modal 1`] = ` -
-
- - - -
-
-

- quality_gates.conditions -

- -
-
-

- quality_gates.conditions.overall_code.long -

-

- quality_gates.conditions.overall_code.description -

- - - - - - - - - - - - - - -
- quality_gates.conditions.metric - - quality_gates.conditions.operator - - quality_gates.conditions.value - - edit - - delete -
-
-
-`; diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/CopyQualityGateForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/CopyQualityGateForm-test.tsx.snap deleted file mode 100644 index f3607739dd5..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/CopyQualityGateForm-test.tsx.snap +++ /dev/null @@ -1,36 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly 1`] = ` - - -
- - -
-
-`; diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/CreateQualityGateForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/CreateQualityGateForm-test.tsx.snap deleted file mode 100644 index f81416622fd..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/CreateQualityGateForm-test.tsx.snap +++ /dev/null @@ -1,36 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly 1`] = ` - - -
- - -
-
-`; diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/DeleteQualityGateForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/DeleteQualityGateForm-test.tsx.snap deleted file mode 100644 index d99d75037ab..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/DeleteQualityGateForm-test.tsx.snap +++ /dev/null @@ -1,13 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly 1`] = ` - - - -`; diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/DetailsContent-test.tsx.snap b/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/DetailsContent-test.tsx.snap index 7354a115ce8..74843ff5fe9 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/DetailsContent-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/DetailsContent-test.tsx.snap @@ -86,7 +86,7 @@ exports[`should render correctly: is default 1`] = ` Array [ Object { "error": "10", - "id": 1, + "id": "1", "metric": "coverage", "op": "LT", }, @@ -100,7 +100,7 @@ exports[`should render correctly: is default 1`] = ` "conditions": Array [ Object { "error": "10", - "id": 1, + "id": "1", "metric": "coverage", "op": "LT", }, @@ -204,7 +204,7 @@ exports[`should render correctly: is not default 1`] = ` Array [ Object { "error": "10", - "id": 1, + "id": "1", "metric": "coverage", "op": "LT", }, @@ -218,7 +218,7 @@ exports[`should render correctly: is not default 1`] = ` "conditions": Array [ Object { "error": "10", - "id": 1, + "id": "1", "metric": "coverage", "op": "LT", }, @@ -259,7 +259,7 @@ exports[`should render correctly: is not default 1`] = ` "conditions": Array [ Object { "error": "10", - "id": 1, + "id": "1", "metric": "coverage", "op": "LT", }, diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/DetailsHeader-test.tsx.snap b/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/DetailsHeader-test.tsx.snap index 614efb96ed8..a1106a333c9 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/DetailsHeader-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/DetailsHeader-test.tsx.snap @@ -55,7 +55,7 @@ exports[`should render correctly: admin actions 1`] = ` "conditions": Array [ Object { "error": "10", - "id": 1, + "id": "1", "metric": "coverage", "op": "LT", }, diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/List-test.tsx.snap b/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/List-test.tsx.snap deleted file mode 100644 index 9fad96d9809..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/List-test.tsx.snap +++ /dev/null @@ -1,73 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly 1`] = ` -
- - - qualitygate - - - - - qualitygate - - - - - - qualitygate - - - default - - -
-`; diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/ListHeader-test.tsx.snap b/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/ListHeader-test.tsx.snap deleted file mode 100644 index 0913eca851b..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/ListHeader-test.tsx.snap +++ /dev/null @@ -1,40 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly 1`] = ` -
-
-

- quality_gates.page -

- -
-
-`; - -exports[`should render correctly 2`] = ` - - - -`; diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/MetricSelect-test.tsx.snap b/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/MetricSelect-test.tsx.snap deleted file mode 100644 index 1d2d3106f23..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/MetricSelect-test.tsx.snap +++ /dev/null @@ -1,19 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly 1`] = ` - -`; diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/RenameQualityGateForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/RenameQualityGateForm-test.tsx.snap deleted file mode 100644 index b0220d9f9ed..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/__snapshots__/RenameQualityGateForm-test.tsx.snap +++ /dev/null @@ -1,36 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly 1`] = ` - - -
- - -
-
-`; diff --git a/server/sonar-web/src/main/js/components/controls/Tooltip.tsx b/server/sonar-web/src/main/js/components/controls/Tooltip.tsx index 80cb8cd2292..e52cd274a8d 100644 --- a/server/sonar-web/src/main/js/components/controls/Tooltip.tsx +++ b/server/sonar-web/src/main/js/components/controls/Tooltip.tsx @@ -346,8 +346,8 @@ export class TooltipInner extends React.Component { return (
{this.props.overlay}
@@ -367,8 +367,8 @@ export class TooltipInner extends React.Component { return ( <> {React.cloneElement(this.props.children, { - onMouseEnter: this.handleMouseEnter, - onMouseLeave: this.handleMouseLeave + onPointerEnter: this.handleMouseEnter, + onPointerLeave: this.handleMouseLeave })} {this.isVisible() && ( diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/Tooltip-test.tsx b/server/sonar-web/src/main/js/components/controls/__tests__/Tooltip-test.tsx index aa0450f088d..bd79b3c3ca8 100644 --- a/server/sonar-web/src/main/js/components/controls/__tests__/Tooltip-test.tsx +++ b/server/sonar-web/src/main/js/components/controls/__tests__/Tooltip-test.tsx @@ -56,26 +56,26 @@ it('should open & close', () => { const onHide = jest.fn(); const wrapper = shallowRenderTooltipInner({ onHide, onShow }); - wrapper.find('#tooltip').simulate('mouseenter'); + wrapper.find('#tooltip').simulate('pointerenter'); jest.runOnlyPendingTimers(); wrapper.update(); expect(wrapper.find('TooltipPortal').exists()).toBe(true); expect(onShow).toBeCalled(); - wrapper.find('#tooltip').simulate('mouseleave'); + wrapper.find('#tooltip').simulate('pointerleave'); jest.runOnlyPendingTimers(); wrapper.update(); expect(wrapper.find('TooltipPortal').exists()).toBe(false); expect(onHide).toBeCalled(); }); -it('should not open when mouse goes away quickly', () => { +it('should not open when pointer goes away quickly', () => { const onShow = jest.fn(); const onHide = jest.fn(); const wrapper = shallowRenderTooltipInner({ onHide, onShow }); - wrapper.find('#tooltip').simulate('mouseenter'); - wrapper.find('#tooltip').simulate('mouseleave'); + wrapper.find('#tooltip').simulate('pointerenter'); + wrapper.find('#tooltip').simulate('pointerleave'); jest.runOnlyPendingTimers(); wrapper.update(); diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ActionsDropdown-test.tsx.snap b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ActionsDropdown-test.tsx.snap index 4bd6a2ea46d..42636f02080 100644 --- a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ActionsDropdown-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/ActionsDropdown-test.tsx.snap @@ -123,8 +123,8 @@ exports[`ActionsDropdownItem should render correctly copy item 1`] = ` >
  • `; @@ -26,8 +26,8 @@ exports[`should render 2`] = `
    { const preventDefault = jest.fn(); const onClick = jest.fn(); const button = shallowRender({ disabled: true, onClick, preventDefault: false }).find('button'); - expect(button.props().disabled).toBeUndefined(); + expect(button.props().disabled).toBe(true); expect(button.props().className).toContain('disabled'); expect(button.props()['aria-disabled']).toBe(true); click(button, mockEvent({ preventDefault })); diff --git a/server/sonar-web/src/main/js/components/controls/buttons.tsx b/server/sonar-web/src/main/js/components/controls/buttons.tsx index a1acfe858f0..8c0aa493d2a 100644 --- a/server/sonar-web/src/main/js/components/controls/buttons.tsx +++ b/server/sonar-web/src/main/js/components/controls/buttons.tsx @@ -76,6 +76,7 @@ export class Button extends React.PureComponent {