From: Stas Vilchik Date: Mon, 2 Nov 2015 15:00:33 +0000 (+0100) Subject: refactor urls helper X-Git-Tag: 5.3-RC1~412 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=251f55f9e4a80ffbb3c68a0407baf7c211250083;p=sonarqube.git refactor urls helper --- diff --git a/server/sonar-web/src/main/js/apps/background-tasks/tasks.js b/server/sonar-web/src/main/js/apps/background-tasks/tasks.js index c469637204d..2d1b6352768 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/tasks.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/tasks.js @@ -1,6 +1,6 @@ import moment from 'moment'; import React from 'react'; -import {getProjectUrl} from '../../helpers/Url'; +import { getComponentUrl } from '../../helpers/urls'; import QualifierIcon from '../../components/shared/qualifier-icon'; import PendingIcon from '../../components/shared/pending-icon'; import {STATUSES} from './constants'; @@ -51,7 +51,7 @@ export default React.createClass({ - {task.componentName} + {task.componentName} ); }, diff --git a/server/sonar-web/src/main/js/apps/overview/domain/bubble-chart.js b/server/sonar-web/src/main/js/apps/overview/domain/bubble-chart.js index 4a72a92dffc..58c65c45ad1 100644 --- a/server/sonar-web/src/main/js/apps/overview/domain/bubble-chart.js +++ b/server/sonar-web/src/main/js/apps/overview/domain/bubble-chart.js @@ -1,7 +1,7 @@ import _ from 'underscore'; import React from 'react'; import { BubbleChart } from '../../../components/charts/bubble-chart'; -import { getProjectUrl } from '../../../helpers/Url'; +import { getComponentUrl } from '../../../helpers/urls'; import { getFiles } from '../../../api/components'; import { formatMeasure } from '../../../helpers/measures'; @@ -87,7 +87,7 @@ export class DomainBubbleChart extends React.Component { x: getMeasure(component, this.props.xMetric), y: getMeasure(component, this.props.yMetric), size: this.getSizeMetricsValue(component), - link: getProjectUrl(component.key), + link: getComponentUrl(component.key), tooltip: this.getTooltip(component) }; }); diff --git a/server/sonar-web/src/main/js/apps/overview/helpers/drilldown-link.js b/server/sonar-web/src/main/js/apps/overview/helpers/drilldown-link.js index 338a34bc016..51f18ea39f5 100644 --- a/server/sonar-web/src/main/js/apps/overview/helpers/drilldown-link.js +++ b/server/sonar-web/src/main/js/apps/overview/helpers/drilldown-link.js @@ -2,6 +2,8 @@ import _ from 'underscore'; import moment from 'moment'; import React from 'react'; import IssuesLink from './issues-link'; +import { getComponentDrilldownUrl } from '../../../helpers/urls'; + export default React.createClass({ isIssueMeasure() { @@ -80,16 +82,7 @@ export default React.createClass({ return this.renderIssuesLink(); } - let params = { id: this.props.component, metric: this.props.metric }; - if (this.props.period) { - params.period = this.props.period; - } - - let query = Object.keys(params).map(key => { - return `${key}=${encodeURIComponent(params[key])}`; - }).join('&'), - url = `${baseUrl}/drilldown/measures?${query}`; - + let url = getComponentDrilldownUrl(this.props.component, this.props.metric, this.props.period); return {this.props.children}; } }); diff --git a/server/sonar-web/src/main/js/apps/overview/helpers/issues-link.js b/server/sonar-web/src/main/js/apps/overview/helpers/issues-link.js index f1331395671..065961496b4 100644 --- a/server/sonar-web/src/main/js/apps/overview/helpers/issues-link.js +++ b/server/sonar-web/src/main/js/apps/overview/helpers/issues-link.js @@ -1,11 +1,10 @@ import React from 'react'; +import { getComponentIssuesUrl } from '../../../helpers/urls'; + export default React.createClass({ render() { - let params = Object.keys(this.props.params).map((key) => { - return `${key}=${encodeURIComponent(this.props.params[key])}`; - }).join('|'), - url = `${window.baseUrl}/component_issues/index?id=${encodeURIComponent(this.props.component)}#${params}`; + let url = getComponentIssuesUrl(this.props.component, this.props.params); return {this.props.children}; } }); diff --git a/server/sonar-web/src/main/js/apps/overview/issues/assignees.js b/server/sonar-web/src/main/js/apps/overview/issues/assignees.js index 87c55e1de69..b13bc21fd0c 100644 --- a/server/sonar-web/src/main/js/apps/overview/issues/assignees.js +++ b/server/sonar-web/src/main/js/apps/overview/issues/assignees.js @@ -1,14 +1,14 @@ import React from 'react'; import Assignee from '../../../components/shared/assignee-helper'; import { DomainHeader } from '../domain/header'; -import { componentIssuesUrl } from '../../../helpers/Url'; +import { getComponentIssuesUrl } from '../../../helpers/urls'; import { formatMeasure } from '../../../helpers/measures'; export default class extends React.Component { render () { let rows = this.props.assignees.map(s => { - let href = componentIssuesUrl(this.props.component.key, { statuses: 'OPEN,REOPENED', assignees: s.val }); + let href = getComponentIssuesUrl(this.props.component.key, { statuses: 'OPEN,REOPENED', assignees: s.val }); return diff --git a/server/sonar-web/src/main/js/apps/overview/issues/severities.js b/server/sonar-web/src/main/js/apps/overview/issues/severities.js index efd0e8e3184..26008e4648f 100644 --- a/server/sonar-web/src/main/js/apps/overview/issues/severities.js +++ b/server/sonar-web/src/main/js/apps/overview/issues/severities.js @@ -2,7 +2,7 @@ import _ from 'underscore'; import React from 'react'; import SeverityHelper from '../../../components/shared/severity-helper'; import { DomainHeader } from '../domain/header'; -import { componentIssuesUrl } from '../../../helpers/Url'; +import { getComponentIssuesUrl } from '../../../helpers/urls'; import { formatMeasure } from '../../../helpers/measures'; @@ -13,7 +13,7 @@ export default class extends React.Component { render () { let rows = this.sortedSeverities().map(s => { - let href = componentIssuesUrl(this.props.component.key, { resolved: 'false', severities: s.val }); + let href = getComponentIssuesUrl(this.props.component.key, { resolved: 'false', severities: s.val }); return diff --git a/server/sonar-web/src/main/js/apps/overview/issues/tags.js b/server/sonar-web/src/main/js/apps/overview/issues/tags.js index 4d86824d25f..6c91a4539b1 100644 --- a/server/sonar-web/src/main/js/apps/overview/issues/tags.js +++ b/server/sonar-web/src/main/js/apps/overview/issues/tags.js @@ -1,14 +1,14 @@ import React from 'react'; import { DomainHeader } from '../domain/header'; import { WordCloud } from '../../../components/charts/word-cloud'; -import { componentIssuesUrl } from '../../../helpers/Url'; +import { getComponentIssuesUrl } from '../../../helpers/urls'; import { formatMeasure } from '../../../helpers/measures'; export default class extends React.Component { renderWordCloud () { let tags = this.props.tags.map(tag => { - let link = componentIssuesUrl(this.props.component.key, { resolved: 'false', tags: tag.val }); + let link = getComponentIssuesUrl(this.props.component.key, { resolved: 'false', tags: tag.val }); let tooltip = `Issues: ${formatMeasure(tag.count, 'SHORT_INT')}`; return { text: tag.val, size: tag.count, link, tooltip }; }); diff --git a/server/sonar-web/src/main/js/apps/project-permissions/project.js b/server/sonar-web/src/main/js/apps/project-permissions/project.js index ce1b9dae58c..f7de774d897 100644 --- a/server/sonar-web/src/main/js/apps/project-permissions/project.js +++ b/server/sonar-web/src/main/js/apps/project-permissions/project.js @@ -2,7 +2,7 @@ import React from 'react'; import UsersView from './users-view'; import GroupsView from './groups-view'; import ApplyTemplateView from './apply-template-view'; -import {getProjectUrl} from '../../helpers/Url'; +import { getComponentUrl } from '../../helpers/urls'; import QualifierIcon from '../../components/shared/qualifier-icon'; export default React.createClass({ @@ -74,7 +74,7 @@ export default React.createClass({ - {this.props.project.name} + {this.props.project.name} {permissions} diff --git a/server/sonar-web/src/main/js/apps/projects/projects.js b/server/sonar-web/src/main/js/apps/projects/projects.js index 6aa42f53c0b..1f3babcd067 100644 --- a/server/sonar-web/src/main/js/apps/projects/projects.js +++ b/server/sonar-web/src/main/js/apps/projects/projects.js @@ -1,5 +1,5 @@ import React from 'react'; -import {getProjectUrl} from '../../helpers/Url'; +import { getComponentUrl } from '../../helpers/urls'; import Checkbox from '../../components/shared/checkbox'; import QualifierIcon from '../../components/shared/qualifier-icon'; @@ -33,7 +33,7 @@ export default React.createClass({ - {project.name} + {project.name} {project.key} diff --git a/server/sonar-web/src/main/js/helpers/Url.js b/server/sonar-web/src/main/js/helpers/Url.js deleted file mode 100644 index f369bb79b67..00000000000 --- a/server/sonar-web/src/main/js/helpers/Url.js +++ /dev/null @@ -1,13 +0,0 @@ -export function getProjectUrl (project) { - if (typeof project !== 'string') { - throw new TypeError('Project ID or KEY should be passed'); - } - return `${window.baseUrl}/dashboard?id=${encodeURIComponent(project)}`; -} - -export function componentIssuesUrl (componentKey, query) { - let serializedQuery = Object.keys(query).map(criterion => { - return `${encodeURIComponent(criterion)}=${encodeURIComponent(query[criterion])}`; - }).join('|'); - return window.baseUrl + '/component_issues?id=' + encodeURIComponent(componentKey) + '#' + serializedQuery; -} diff --git a/server/sonar-web/src/main/js/helpers/urls.js b/server/sonar-web/src/main/js/helpers/urls.js new file mode 100644 index 00000000000..4af420e6a2b --- /dev/null +++ b/server/sonar-web/src/main/js/helpers/urls.js @@ -0,0 +1,39 @@ +/** + * Generate URL for a component's home page + * @param {string} componentKey + * @returns {string} + */ +export function getComponentUrl (componentKey) { + return window.baseUrl + '/dashboard?id=' + encodeURIComponent(componentKey); +} + + +/** + * Generate URL for a component's issues page + * @param {string} componentKey + * @param {object} query + * @returns {string} + */ +export function getComponentIssuesUrl (componentKey, query) { + let serializedQuery = Object.keys(query).map(criterion => { + return `${encodeURIComponent(criterion)}=${encodeURIComponent(query[criterion])}`; + }).join('|'); + return window.baseUrl + '/component_issues?id=' + encodeURIComponent(componentKey) + '#' + serializedQuery; +} + + +/** + * Generate URL for a component's drilldown page + * @param {string} componentKey + * @param {string} metric + * @param {string|number} [period] + * @returns {string} + */ +export function getComponentDrilldownUrl (componentKey, metric, period) { + let url = window.baseUrl + '/drilldown/measures?id=' + encodeURIComponent(componentKey) + + '&metric=' + encodeURIComponent(metric); + if (period) { + url += '&period=' + period; + } + return url; +} diff --git a/server/sonar-web/tests/helpers/urls-test.js b/server/sonar-web/tests/helpers/urls-test.js new file mode 100644 index 00000000000..da02b326155 --- /dev/null +++ b/server/sonar-web/tests/helpers/urls-test.js @@ -0,0 +1,89 @@ +import { expect } from 'chai'; + +import { getComponentUrl, getComponentIssuesUrl, getComponentDrilldownUrl } from '../../src/main/js/helpers/urls'; + + +const SIMPLE_COMPONENT_KEY = 'sonarqube'; +const COMPLEX_COMPONENT_KEY = 'org.sonarsource.sonarqube:sonarqube'; +const COMPLEX_COMPONENT_KEY_ENCODED = encodeURIComponent(COMPLEX_COMPONENT_KEY); +const METRIC = 'coverage'; +const PERIOD = '3'; + + +describe('URLs', function () { + var oldBaseUrl; + + beforeEach(function () { + oldBaseUrl = window.baseUrl; + }); + + afterEach(function () { + window.baseUrl = oldBaseUrl; + }); + + describe('#getComponentUrl', function () { + it('should return component url', function () { + expect(getComponentUrl(SIMPLE_COMPONENT_KEY)).to.equal('/dashboard?id=' + SIMPLE_COMPONENT_KEY); + }); + + it('should encode component key', function () { + expect(getComponentUrl(COMPLEX_COMPONENT_KEY)).to.equal('/dashboard?id=' + COMPLEX_COMPONENT_KEY_ENCODED); + }); + + it('should take baseUrl into account', function () { + window.baseUrl = '/context'; + expect(getComponentUrl(COMPLEX_COMPONENT_KEY)).to.equal('/context/dashboard?id=' + COMPLEX_COMPONENT_KEY_ENCODED); + }); + }); + + describe('#getComponentIssuesUrl', function () { + it('should work without parameters', function () { + expect(getComponentIssuesUrl(SIMPLE_COMPONENT_KEY, {})).to.equal( + '/component_issues?id=' + SIMPLE_COMPONENT_KEY + '#'); + }); + + it('should encode component key', function () { + expect(getComponentIssuesUrl(COMPLEX_COMPONENT_KEY, {})).to.equal( + '/component_issues?id=' + COMPLEX_COMPONENT_KEY_ENCODED + '#'); + }); + + it('should work with parameters', function () { + expect(getComponentIssuesUrl(SIMPLE_COMPONENT_KEY, { resolved: 'false' })).to.equal( + '/component_issues?id=' + SIMPLE_COMPONENT_KEY + '#resolved=false'); + }); + + it('should encode parameters', function () { + expect(getComponentIssuesUrl(SIMPLE_COMPONENT_KEY, { componentUuids: COMPLEX_COMPONENT_KEY })).to.equal( + '/component_issues?id=' + SIMPLE_COMPONENT_KEY + '#componentUuids=' + COMPLEX_COMPONENT_KEY_ENCODED); + }); + + it('should take baseUrl into account', function () { + window.baseUrl = '/context'; + expect(getComponentIssuesUrl(SIMPLE_COMPONENT_KEY, {})).to.equal( + '/context/component_issues?id=' + SIMPLE_COMPONENT_KEY + '#'); + }); + }); + + describe('#getComponentDrilldownUrl', function () { + it('should return component drilldown url', function () { + expect(getComponentDrilldownUrl(SIMPLE_COMPONENT_KEY, METRIC)).to.equal( + '/drilldown/measures?id=' + SIMPLE_COMPONENT_KEY + '&metric=' + METRIC); + }); + + it('should encode component key', function () { + expect(getComponentDrilldownUrl(COMPLEX_COMPONENT_KEY, METRIC)).to.equal( + '/drilldown/measures?id=' + COMPLEX_COMPONENT_KEY_ENCODED + '&metric=' + METRIC); + }); + + it('should work with period', function () { + expect(getComponentDrilldownUrl(SIMPLE_COMPONENT_KEY, METRIC, PERIOD)).to.equal( + '/drilldown/measures?id=' + SIMPLE_COMPONENT_KEY + '&metric=' + METRIC + '&period=' + PERIOD); + }); + + it('should take baseUrl into account', function () { + window.baseUrl = '/context'; + expect(getComponentDrilldownUrl(SIMPLE_COMPONENT_KEY, METRIC)).to.equal( + '/context/drilldown/measures?id=' + SIMPLE_COMPONENT_KEY + '&metric=' + METRIC); + }); + }); +});