*/ | */ | ||||
import { getJSON, post } from 'sonar-ui-common/helpers/request'; | import { getJSON, post } from 'sonar-ui-common/helpers/request'; | ||||
import throwGlobalError from '../app/utils/throwGlobalError'; | import throwGlobalError from '../app/utils/throwGlobalError'; | ||||
import { Branch, PullRequest } from '../types/branch-like'; | |||||
export function getBranches(project: string): Promise<T.Branch[]> { | |||||
export function getBranches(project: string): Promise<Branch[]> { | |||||
return getJSON('/api/project_branches/list', { project }).then(r => r.branches, throwGlobalError); | return getJSON('/api/project_branches/list', { project }).then(r => r.branches, throwGlobalError); | ||||
} | } | ||||
export function getPullRequests(project: string): Promise<T.PullRequest[]> { | |||||
export function getPullRequests(project: string): Promise<PullRequest[]> { | |||||
return getJSON('/api/project_pull_requests/list', { project }).then( | return getJSON('/api/project_pull_requests/list', { project }).then( | ||||
r => r.pullRequests, | r => r.pullRequests, | ||||
throwGlobalError | throwGlobalError |
*/ | */ | ||||
import { getJSON, post, postJSON, RequestData } from 'sonar-ui-common/helpers/request'; | import { getJSON, post, postJSON, RequestData } from 'sonar-ui-common/helpers/request'; | ||||
import throwGlobalError from '../app/utils/throwGlobalError'; | import throwGlobalError from '../app/utils/throwGlobalError'; | ||||
import { BranchParameters } from '../types/branch-like'; | |||||
export interface BaseSearchProjectsParameters { | export interface BaseSearchProjectsParameters { | ||||
analyzedBefore?: string; | analyzedBefore?: string; | ||||
} | } | ||||
export function getComponent( | export function getComponent( | ||||
data: { component: string; metricKeys: string } & T.BranchParameters | |||||
data: { component: string; metricKeys: string } & BranchParameters | |||||
): Promise<{ component: T.ComponentMeasure }> { | ): Promise<{ component: T.ComponentMeasure }> { | ||||
return getJSON('/api/measures/component', data); | return getJSON('/api/measures/component', data); | ||||
} | } | ||||
q?: string; | q?: string; | ||||
s?: string; | s?: string; | ||||
strategy?: 'all' | 'leaves' | 'children'; | strategy?: 'all' | 'leaves' | 'children'; | ||||
} & T.BranchParameters; | |||||
} & BranchParameters; | |||||
export function getTree<T = TreeComponent>( | export function getTree<T = TreeComponent>( | ||||
data: GetTreeParams & { qualifiers?: string } | data: GetTreeParams & { qualifiers?: string } | ||||
return getTree<TreeComponentWithPath>({ ...data, qualifiers: 'DIR' }); | return getTree<TreeComponentWithPath>({ ...data, qualifiers: 'DIR' }); | ||||
} | } | ||||
export function getComponentData(data: { component: string } & T.BranchParameters): Promise<any> { | |||||
export function getComponentData(data: { component: string } & BranchParameters): Promise<any> { | |||||
return getJSON('/api/components/show', data); | return getJSON('/api/components/show', data); | ||||
} | } | ||||
export function doesComponentExists( | export function doesComponentExists( | ||||
data: { component: string } & T.BranchParameters | |||||
data: { component: string } & BranchParameters | |||||
): Promise<boolean> { | ): Promise<boolean> { | ||||
return getComponentData(data).then(({ component }) => component !== undefined, () => false); | return getComponentData(data).then(({ component }) => component !== undefined, () => false); | ||||
} | } | ||||
export function getComponentShow(data: { component: string } & T.BranchParameters): Promise<any> { | |||||
export function getComponentShow(data: { component: string } & BranchParameters): Promise<any> { | |||||
return getComponentData(data).catch(throwGlobalError); | return getComponentData(data).catch(throwGlobalError); | ||||
} | } | ||||
return getComponentShow({ component }).then(r => r.ancestors); | return getComponentShow({ component }).then(r => r.ancestors); | ||||
} | } | ||||
export function getBreadcrumbs(data: { component: string } & T.BranchParameters): Promise<any> { | |||||
export function getBreadcrumbs(data: { component: string } & BranchParameters): Promise<any> { | |||||
return getComponentShow(data).then(r => { | return getComponentShow(data).then(r => { | ||||
const reversedAncestors = [...r.ancestors].reverse(); | const reversedAncestors = [...r.ancestors].reverse(); | ||||
return [...reversedAncestors, r.component]; | return [...reversedAncestors, r.component]; | ||||
} | } | ||||
export function getComponentForSourceViewer( | export function getComponentForSourceViewer( | ||||
data: { component: string } & T.BranchParameters | |||||
data: { component: string } & BranchParameters | |||||
): Promise<T.SourceViewerFile> { | ): Promise<T.SourceViewerFile> { | ||||
return getJSON('/api/components/app', data); | return getJSON('/api/components/app', data); | ||||
} | } | ||||
export function getSources( | export function getSources( | ||||
data: { key: string; from?: number; to?: number } & T.BranchParameters | |||||
data: { key: string; from?: number; to?: number } & BranchParameters | |||||
): Promise<T.SourceLine[]> { | ): Promise<T.SourceLine[]> { | ||||
return getJSON('/api/sources/lines', data).then(r => r.sources); | return getJSON('/api/sources/lines', data).then(r => r.sources); | ||||
} | } | ||||
export function getDuplications( | export function getDuplications( | ||||
data: { key: string } & T.BranchParameters | |||||
data: { key: string } & BranchParameters | |||||
): Promise<{ duplications: T.Duplication[]; files: T.Dict<T.DuplicatedFile> }> { | ): Promise<{ duplications: T.Duplication[]; files: T.Dict<T.DuplicatedFile> }> { | ||||
return getJSON('/api/duplications/show', data).catch(throwGlobalError); | return getJSON('/api/duplications/show', data).catch(throwGlobalError); | ||||
} | } | ||||
export function getTests( | export function getTests( | ||||
data: { sourceFileKey: string; sourceFileLineNumber: number | string } & T.BranchParameters | |||||
data: { sourceFileKey: string; sourceFileLineNumber: number | string } & BranchParameters | |||||
): Promise<any> { | ): Promise<any> { | ||||
return getJSON('/api/tests/list', data).then(r => r.tests); | return getJSON('/api/tests/list', data).then(r => r.tests); | ||||
} | } |
*/ | */ | ||||
import { getJSON, post, postJSON, RequestData } from 'sonar-ui-common/helpers/request'; | import { getJSON, post, postJSON, RequestData } from 'sonar-ui-common/helpers/request'; | ||||
import throwGlobalError from '../app/utils/throwGlobalError'; | import throwGlobalError from '../app/utils/throwGlobalError'; | ||||
import { BranchParameters } from '../types/branch-like'; | |||||
export function getMeasures( | export function getMeasures( | ||||
data: { component: string; metricKeys: string } & T.BranchParameters | |||||
data: { component: string; metricKeys: string } & BranchParameters | |||||
): Promise<T.Measure[]> { | ): Promise<T.Measure[]> { | ||||
return getJSON('/api/measures/component', data).then(r => r.component.measures, throwGlobalError); | return getJSON('/api/measures/component', data).then(r => r.component.measures, throwGlobalError); | ||||
} | } |
*/ | */ | ||||
import { getJSON } from 'sonar-ui-common/helpers/request'; | import { getJSON } from 'sonar-ui-common/helpers/request'; | ||||
import throwGlobalError from '../app/utils/throwGlobalError'; | import throwGlobalError from '../app/utils/throwGlobalError'; | ||||
import { BranchParameters } from '../types/branch-like'; | |||||
export function getGlobalNavigation(): Promise<T.AppState> { | export function getGlobalNavigation(): Promise<T.AppState> { | ||||
return getJSON('/api/navigation/global'); | return getJSON('/api/navigation/global'); | ||||
type NavComponent = T.Omit<T.Component, 'alm' | 'qualifier' | 'leakPeriodDate' | 'path' | 'tags'>; | type NavComponent = T.Omit<T.Component, 'alm' | 'qualifier' | 'leakPeriodDate' | 'path' | 'tags'>; | ||||
export function getComponentNavigation( | export function getComponentNavigation( | ||||
data: { component: string } & T.BranchParameters | |||||
data: { component: string } & BranchParameters | |||||
): Promise<NavComponent> { | ): Promise<NavComponent> { | ||||
return getJSON('/api/navigation/component', data).catch(throwGlobalError); | return getJSON('/api/navigation/component', data).catch(throwGlobalError); | ||||
} | } |
*/ | */ | ||||
import { getJSON, post, postJSON, RequestData } from 'sonar-ui-common/helpers/request'; | import { getJSON, post, postJSON, RequestData } from 'sonar-ui-common/helpers/request'; | ||||
import throwGlobalError from '../app/utils/throwGlobalError'; | import throwGlobalError from '../app/utils/throwGlobalError'; | ||||
import { BranchParameters } from '../types/branch-like'; | |||||
export function getProjectActivity( | export function getProjectActivity( | ||||
data: { | data: { | ||||
from?: string; | from?: string; | ||||
p?: number; | p?: number; | ||||
ps?: number; | ps?: number; | ||||
} & T.BranchParameters | |||||
} & BranchParameters | |||||
): Promise<{ analyses: T.Analysis[]; paging: T.Paging }> { | ): Promise<{ analyses: T.Analysis[]; paging: T.Paging }> { | ||||
return getJSON('/api/project_analyses/search', data).catch(throwGlobalError); | return getJSON('/api/project_analyses/search', data).catch(throwGlobalError); | ||||
} | } |
*/ | */ | ||||
import { getJSON, post, postJSON } from 'sonar-ui-common/helpers/request'; | import { getJSON, post, postJSON } from 'sonar-ui-common/helpers/request'; | ||||
import throwGlobalError from '../app/utils/throwGlobalError'; | import throwGlobalError from '../app/utils/throwGlobalError'; | ||||
import { BranchParameters } from '../types/branch-like'; | |||||
export function fetchQualityGates(data: { | export function fetchQualityGates(data: { | ||||
organization?: string; | organization?: string; | ||||
data: { | data: { | ||||
projectKey?: string; | projectKey?: string; | ||||
projectId?: string; | projectId?: string; | ||||
} & T.BranchParameters | |||||
} & BranchParameters | |||||
): Promise<T.QualityGateProjectStatus> { | ): Promise<T.QualityGateProjectStatus> { | ||||
return getJSON('/api/qualitygates/project_status', data) | return getJSON('/api/qualitygates/project_status', data) | ||||
.then(r => r.projectStatus) | .then(r => r.projectStatus) |
import { getJSON, post, postJSON, RequestData } from 'sonar-ui-common/helpers/request'; | import { getJSON, post, postJSON, RequestData } from 'sonar-ui-common/helpers/request'; | ||||
import throwGlobalError from '../app/utils/throwGlobalError'; | import throwGlobalError from '../app/utils/throwGlobalError'; | ||||
import { isCategoryDefinition } from '../apps/settings/utils'; | import { isCategoryDefinition } from '../apps/settings/utils'; | ||||
import { BranchParameters } from '../types/branch-like'; | |||||
export function getDefinitions(component?: string): Promise<T.SettingCategoryDefinition[]> { | export function getDefinitions(component?: string): Promise<T.SettingCategoryDefinition[]> { | ||||
return getJSON('/api/settings/list_definitions', { component }).then( | return getJSON('/api/settings/list_definitions', { component }).then( | ||||
} | } | ||||
export function getValues( | export function getValues( | ||||
data: { keys: string; component?: string } & T.BranchParameters | |||||
data: { keys: string; component?: string } & BranchParameters | |||||
): Promise<T.SettingValue[]> { | ): Promise<T.SettingValue[]> { | ||||
return getJSON('/api/settings/values', data).then(r => r.settings); | return getJSON('/api/settings/values', data).then(r => r.settings); | ||||
} | } | ||||
} | } | ||||
export function setSimpleSettingValue( | export function setSimpleSettingValue( | ||||
data: { component?: string; value: string; key: string } & T.BranchParameters | |||||
data: { component?: string; value: string; key: string } & BranchParameters | |||||
): Promise<void | Response> { | ): Promise<void | Response> { | ||||
return post('/api/settings/set', data).catch(throwGlobalError); | return post('/api/settings/set', data).catch(throwGlobalError); | ||||
} | } | ||||
export function resetSettingValue( | export function resetSettingValue( | ||||
data: { keys: string; component?: string } & T.BranchParameters | |||||
data: { keys: string; component?: string } & BranchParameters | |||||
): Promise<void> { | ): Promise<void> { | ||||
return post('/api/settings/reset', data); | return post('/api/settings/reset', data); | ||||
} | } |
*/ | */ | ||||
import { getJSON } from 'sonar-ui-common/helpers/request'; | import { getJSON } from 'sonar-ui-common/helpers/request'; | ||||
import throwGlobalError from '../app/utils/throwGlobalError'; | import throwGlobalError from '../app/utils/throwGlobalError'; | ||||
import { BranchParameters } from '../types/branch-like'; | |||||
interface TimeMachineResponse { | interface TimeMachineResponse { | ||||
measures: { | measures: { | ||||
p?: number; | p?: number; | ||||
ps?: number; | ps?: number; | ||||
to?: string; | to?: string; | ||||
} & T.BranchParameters | |||||
} & BranchParameters | |||||
): Promise<TimeMachineResponse> { | ): Promise<TimeMachineResponse> { | ||||
return getJSON('/api/measures/search_history', data).catch(throwGlobalError); | return getJSON('/api/measures/search_history', data).catch(throwGlobalError); | ||||
} | } | ||||
from?: string; | from?: string; | ||||
p?: number; | p?: number; | ||||
to?: string; | to?: string; | ||||
} & T.BranchParameters, | |||||
} & BranchParameters, | |||||
prev?: TimeMachineResponse | prev?: TimeMachineResponse | ||||
): Promise<TimeMachineResponse> { | ): Promise<TimeMachineResponse> { | ||||
return getTimeMachineData({ ...data, ps: 1000 }).then(r => { | return getTimeMachineData({ ...data, ps: 1000 }).then(r => { |
import { | import { | ||||
getBranchLikeQuery, | getBranchLikeQuery, | ||||
isBranch, | isBranch, | ||||
isLongLivingBranch, | |||||
isMainBranch, | isMainBranch, | ||||
isPullRequest, | |||||
isShortLivingBranch | |||||
} from '../../helpers/branches'; | |||||
isPullRequest | |||||
} from '../../helpers/branch-like'; | |||||
import { isSonarCloud } from '../../helpers/system'; | import { isSonarCloud } from '../../helpers/system'; | ||||
import { | import { | ||||
fetchOrganization, | fetchOrganization, | ||||
registerBranchStatus, | registerBranchStatus, | ||||
requireAuthorization | requireAuthorization | ||||
} from '../../store/rootActions'; | } from '../../store/rootActions'; | ||||
import { BranchLike } from '../../types/branch-like'; | |||||
import ComponentContainerNotFound from './ComponentContainerNotFound'; | import ComponentContainerNotFound from './ComponentContainerNotFound'; | ||||
import { ComponentContext } from './ComponentContext'; | import { ComponentContext } from './ComponentContext'; | ||||
import ComponentNav from './nav/component/ComponentNav'; | import ComponentNav from './nav/component/ComponentNav'; | ||||
children: React.ReactElement; | children: React.ReactElement; | ||||
fetchOrganization: (organization: string) => void; | fetchOrganization: (organization: string) => void; | ||||
location: Pick<Location, 'query'>; | location: Pick<Location, 'query'>; | ||||
registerBranchStatus: (branchLike: T.BranchLike, component: string, status: T.Status) => void; | |||||
registerBranchStatus: (branchLike: BranchLike, component: string, status: T.Status) => void; | |||||
requireAuthorization: (router: Pick<Router, 'replace'>) => void; | requireAuthorization: (router: Pick<Router, 'replace'>) => void; | ||||
router: Pick<Router, 'replace'>; | router: Pick<Router, 'replace'>; | ||||
} | } | ||||
interface State { | interface State { | ||||
branchLike?: T.BranchLike; | |||||
branchLikes: T.BranchLike[]; | |||||
branchLike?: BranchLike; | |||||
branchLikes: BranchLike[]; | |||||
component?: T.Component; | component?: T.Component; | ||||
currentTask?: T.Task; | currentTask?: T.Task; | ||||
isPending: boolean; | isPending: boolean; | ||||
fetchBranches = ( | fetchBranches = ( | ||||
component: T.Component | component: T.Component | ||||
): Promise<{ | ): Promise<{ | ||||
branchLike?: T.BranchLike; | |||||
branchLikes: T.BranchLike[]; | |||||
branchLike?: BranchLike; | |||||
branchLikes: BranchLike[]; | |||||
component: T.Component; | component: T.Component; | ||||
}> => { | }> => { | ||||
const breadcrumb = component.breadcrumbs.find(({ qualifier }) => { | const breadcrumb = component.breadcrumbs.find(({ qualifier }) => { | ||||
); | ); | ||||
}; | }; | ||||
fetchWarnings = (component: T.Component, branchLike?: T.BranchLike) => { | |||||
fetchWarnings = (component: T.Component, branchLike?: BranchLike) => { | |||||
if (component.qualifier === 'TRK') { | if (component.qualifier === 'TRK') { | ||||
getAnalysisStatus({ | getAnalysisStatus({ | ||||
component: component.key, | component: component.key, | ||||
} | } | ||||
}; | }; | ||||
getCurrentBranchLike = (branchLikes: T.BranchLike[]) => { | |||||
getCurrentBranchLike = (branchLikes: BranchLike[]) => { | |||||
const { query } = this.props.location; | const { query } = this.props.location; | ||||
return query.pullRequest | return query.pullRequest | ||||
? branchLikes.find(b => isPullRequest(b) && b.key === query.pullRequest) | ? branchLikes.find(b => isPullRequest(b) && b.key === query.pullRequest) | ||||
: branchLikes.find(b => isBranch(b) && (query.branch ? b.name === query.branch : b.isMain)); | : branchLikes.find(b => isBranch(b) && (query.branch ? b.name === query.branch : b.isMain)); | ||||
}; | }; | ||||
getCurrentTask = (current: T.Task, branchLike?: T.BranchLike) => { | |||||
getCurrentTask = (current: T.Task, branchLike?: BranchLike) => { | |||||
if (!current) { | if (!current) { | ||||
return undefined; | return undefined; | ||||
} | } | ||||
: undefined; | : undefined; | ||||
}; | }; | ||||
getPendingTasks = (pendingTasks: T.Task[], branchLike?: T.BranchLike) => { | |||||
getPendingTasks = (pendingTasks: T.Task[], branchLike?: BranchLike) => { | |||||
return pendingTasks.filter(task => this.isSameBranch(task, branchLike)); | return pendingTasks.filter(task => this.isSameBranch(task, branchLike)); | ||||
}; | }; | ||||
isSameBranch = ( | |||||
task: Pick<T.Task, 'branch' | 'branchType' | 'pullRequest'>, | |||||
branchLike?: T.BranchLike | |||||
) => { | |||||
isSameBranch = (task: Pick<T.Task, 'branch' | 'pullRequest'>, branchLike?: BranchLike) => { | |||||
if (branchLike && !isMainBranch(branchLike)) { | if (branchLike && !isMainBranch(branchLike)) { | ||||
if (isPullRequest(branchLike)) { | if (isPullRequest(branchLike)) { | ||||
return branchLike.key === task.pullRequest; | return branchLike.key === task.pullRequest; | ||||
} | } | ||||
if (isShortLivingBranch(branchLike) || isLongLivingBranch(branchLike)) { | |||||
return branchLike.type === task.branchType && branchLike.name === task.branch; | |||||
if (isBranch(branchLike)) { | |||||
return branchLike.name === task.branch; | |||||
} | } | ||||
} | } | ||||
return !task.branch && !task.pullRequest; | return !task.branch && !task.pullRequest; | ||||
}; | }; | ||||
registerBranchStatuses = (branchLikes: T.BranchLike[], component: T.Component) => { | |||||
registerBranchStatuses = (branchLikes: BranchLike[], component: T.Component) => { | |||||
branchLikes.forEach(branchLike => { | branchLikes.forEach(branchLike => { | ||||
if (branchLike.status) { | if (branchLike.status) { | ||||
this.props.registerBranchStatus( | this.props.registerBranchStatus( |
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { BranchLike } from '../../types/branch-like'; | |||||
interface ComponentContextType { | interface ComponentContextType { | ||||
branchLike: T.BranchLike | undefined; | |||||
branchLike: BranchLike | undefined; | |||||
component: T.Component | undefined; | component: T.Component | undefined; | ||||
} | } | ||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { BranchLike } from '../../types/branch-like'; | |||||
import handleRequiredAuthorization from '../utils/handleRequiredAuthorization'; | import handleRequiredAuthorization from '../utils/handleRequiredAuthorization'; | ||||
import A11ySkipTarget from './a11y/A11ySkipTarget'; | import A11ySkipTarget from './a11y/A11ySkipTarget'; | ||||
interface Props { | interface Props { | ||||
children: JSX.Element; | children: JSX.Element; | ||||
branchLike?: T.BranchLike; | |||||
branchLikes: T.BranchLike[]; | |||||
branchLike?: BranchLike; | |||||
branchLikes: BranchLike[]; | |||||
component: T.Component; | component: T.Component; | ||||
isInProgress?: boolean; | isInProgress?: boolean; | ||||
isPending?: boolean; | isPending?: boolean; |
import { getComponentData } from '../../../api/components'; | import { getComponentData } from '../../../api/components'; | ||||
import { getComponentNavigation } from '../../../api/nav'; | import { getComponentNavigation } from '../../../api/nav'; | ||||
import { STATUSES } from '../../../apps/background-tasks/constants'; | import { STATUSES } from '../../../apps/background-tasks/constants'; | ||||
import { mockBranch, mockMainBranch, mockPullRequest } from '../../../helpers/mocks/branch-like'; | |||||
import { isSonarCloud } from '../../../helpers/system'; | import { isSonarCloud } from '../../../helpers/system'; | ||||
import { | |||||
mockComponent, | |||||
mockLocation, | |||||
mockLongLivingBranch, | |||||
mockMainBranch, | |||||
mockPullRequest, | |||||
mockRouter, | |||||
mockShortLivingBranch | |||||
} from '../../../helpers/testMocks'; | |||||
import { mockComponent, mockLocation, mockRouter } from '../../../helpers/testMocks'; | |||||
import { ComponentContainer } from '../ComponentContainer'; | import { ComponentContainer } from '../ComponentContainer'; | ||||
jest.mock('../../../api/branches', () => { | jest.mock('../../../api/branches', () => { | ||||
const { mockMainBranch, mockPullRequest } = require.requireActual('../../../helpers/testMocks'); | |||||
const { mockMainBranch, mockPullRequest } = require.requireActual( | |||||
'../../../helpers/mocks/branch-like' | |||||
); | |||||
return { | return { | ||||
getBranches: jest | getBranches: jest | ||||
.fn() | .fn() | ||||
const Inner = () => <div />; | const Inner = () => <div />; | ||||
const mainBranch: T.MainBranch = mockMainBranch(); | |||||
const mainBranch = mockMainBranch(); | |||||
beforeEach(() => { | beforeEach(() => { | ||||
jest.clearAllMocks(); | jest.clearAllMocks(); | ||||
const wrapper = shallowRender(); | const wrapper = shallowRender(); | ||||
const component = wrapper.instance(); | const component = wrapper.instance(); | ||||
const mainBranch = mockMainBranch(); | const mainBranch = mockMainBranch(); | ||||
const shortBranch = mockShortLivingBranch(); | |||||
const longBranch = mockLongLivingBranch(); | |||||
const branch3 = mockBranch({ name: 'branch-3' }); | |||||
const branch2 = mockBranch({ name: 'branch-2' }); | |||||
const pullRequest = mockPullRequest(); | const pullRequest = mockPullRequest(); | ||||
expect(component.isSameBranch({}, undefined)).toBeTruthy(); | expect(component.isSameBranch({}, undefined)).toBeTruthy(); | ||||
expect(component.isSameBranch({}, mainBranch)).toBeTruthy(); | expect(component.isSameBranch({}, mainBranch)).toBeTruthy(); | ||||
expect(component.isSameBranch({}, shortBranch)).toBeFalsy(); | |||||
expect( | |||||
component.isSameBranch({ branch: shortBranch.name, branchType: 'SHORT' }, shortBranch) | |||||
).toBeTruthy(); | |||||
expect( | |||||
component.isSameBranch({ branch: 'feature', branchType: 'SHORT' }, longBranch) | |||||
).toBeFalsy(); | |||||
expect( | |||||
component.isSameBranch({ branch: 'feature', branchType: 'SHORT' }, longBranch) | |||||
).toBeFalsy(); | |||||
expect( | |||||
component.isSameBranch({ branch: 'branch-6.6', branchType: 'LONG' }, longBranch) | |||||
).toBeFalsy(); | |||||
expect( | |||||
component.isSameBranch({ branch: longBranch.name, branchType: 'LONG' }, longBranch) | |||||
).toBeTruthy(); | |||||
expect( | |||||
component.isSameBranch({ branch: 'branch-6.7', branchType: 'LONG' }, pullRequest) | |||||
).toBeFalsy(); | |||||
expect(component.isSameBranch({}, branch3)).toBeFalsy(); | |||||
expect(component.isSameBranch({ branch: branch3.name }, branch3)).toBeTruthy(); | |||||
expect(component.isSameBranch({ branch: 'feature' }, branch2)).toBeFalsy(); | |||||
expect(component.isSameBranch({ branch: 'branch-6.6' }, branch2)).toBeFalsy(); | |||||
expect(component.isSameBranch({ branch: branch2.name }, branch2)).toBeTruthy(); | |||||
expect(component.isSameBranch({ branch: 'branch-6.7' }, pullRequest)).toBeFalsy(); | |||||
expect(component.isSameBranch({ pullRequest: pullRequest.key }, pullRequest)).toBeTruthy(); | expect(component.isSameBranch({ pullRequest: pullRequest.key }, pullRequest)).toBeTruthy(); | ||||
const currentTask = { pullRequest: pullRequest.key, status: STATUSES.IN_PROGRESS } as T.Task; | const currentTask = { pullRequest: pullRequest.key, status: STATUSES.IN_PROGRESS } as T.Task; | ||||
const failedTask = { ...currentTask, status: STATUSES.FAILED }; | const failedTask = { ...currentTask, status: STATUSES.FAILED }; | ||||
const pendingTasks = [ | |||||
currentTask, | |||||
{ branch: shortBranch.name, branchType: 'SHORT' } as T.Task, | |||||
{} as T.Task | |||||
]; | |||||
const pendingTasks = [currentTask, { branch: branch3.name } as T.Task, {} as T.Task]; | |||||
expect(component.getCurrentTask(currentTask, undefined)).toBe(undefined); | expect(component.getCurrentTask(currentTask, undefined)).toBe(undefined); | ||||
expect(component.getCurrentTask(failedTask, mainBranch)).toBe(failedTask); | expect(component.getCurrentTask(failedTask, mainBranch)).toBe(failedTask); | ||||
expect(component.getCurrentTask(currentTask, mainBranch)).toBe(undefined); | expect(component.getCurrentTask(currentTask, mainBranch)).toBe(undefined); |
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import NotFound from '../NotFound'; | import NotFound from '../NotFound'; | ||||
import Extension from './Extension'; | import Extension from './Extension'; | ||||
export interface ProjectPageExtensionProps { | export interface ProjectPageExtensionProps { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
component: T.Component; | component: T.Component; | ||||
location: { query: { id: string } }; | location: { query: { id: string } }; | ||||
params: { | params: { |
import { shallow } from 'enzyme'; | import { shallow } from 'enzyme'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { mockComponent, mockLocation, mockMainBranch } from '../../../../helpers/testMocks'; | |||||
import { mockMainBranch } from '../../../../helpers/mocks/branch-like'; | |||||
import { mockComponent, mockLocation } from '../../../../helpers/testMocks'; | |||||
import ProjectPageExtension, { ProjectPageExtensionProps } from '../ProjectPageExtension'; | import ProjectPageExtension, { ProjectPageExtensionProps } from '../ProjectPageExtension'; | ||||
it('should render correctly', () => { | it('should render correctly', () => { |
Object { | Object { | ||||
"branchLike": Object { | "branchLike": Object { | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | |||||
"isMain": true, | "isMain": true, | ||||
"name": "master", | "name": "master", | ||||
}, | }, |
import AlertErrorIcon from 'sonar-ui-common/components/icons/AlertErrorIcon'; | import AlertErrorIcon from 'sonar-ui-common/components/icons/AlertErrorIcon'; | ||||
import AlertSuccessIcon from 'sonar-ui-common/components/icons/AlertSuccessIcon'; | import AlertSuccessIcon from 'sonar-ui-common/components/icons/AlertSuccessIcon'; | ||||
import AlertWarnIcon from 'sonar-ui-common/components/icons/AlertWarnIcon'; | import AlertWarnIcon from 'sonar-ui-common/components/icons/AlertWarnIcon'; | ||||
import BranchIcon from 'sonar-ui-common/components/icons/BranchIcon'; | |||||
import CheckIcon from 'sonar-ui-common/components/icons/CheckIcon'; | import CheckIcon from 'sonar-ui-common/components/icons/CheckIcon'; | ||||
import ClearIcon from 'sonar-ui-common/components/icons/ClearIcon'; | import ClearIcon from 'sonar-ui-common/components/icons/ClearIcon'; | ||||
import DetachIcon from 'sonar-ui-common/components/icons/DetachIcon'; | import DetachIcon from 'sonar-ui-common/components/icons/DetachIcon'; | ||||
import DropdownIcon from 'sonar-ui-common/components/icons/DropdownIcon'; | import DropdownIcon from 'sonar-ui-common/components/icons/DropdownIcon'; | ||||
import HelpIcon from 'sonar-ui-common/components/icons/HelpIcon'; | import HelpIcon from 'sonar-ui-common/components/icons/HelpIcon'; | ||||
import LockIcon from 'sonar-ui-common/components/icons/LockIcon'; | import LockIcon from 'sonar-ui-common/components/icons/LockIcon'; | ||||
import LongLivingBranchIcon from 'sonar-ui-common/components/icons/LongLivingBranchIcon'; | |||||
import PlusCircleIcon from 'sonar-ui-common/components/icons/PlusCircleIcon'; | import PlusCircleIcon from 'sonar-ui-common/components/icons/PlusCircleIcon'; | ||||
import PullRequestIcon from 'sonar-ui-common/components/icons/PullRequestIcon'; | import PullRequestIcon from 'sonar-ui-common/components/icons/PullRequestIcon'; | ||||
import QualifierIcon from 'sonar-ui-common/components/icons/QualifierIcon'; | import QualifierIcon from 'sonar-ui-common/components/icons/QualifierIcon'; | ||||
import { | import { | ||||
getBranchLikeQuery, | getBranchLikeQuery, | ||||
isBranch, | isBranch, | ||||
isLongLivingBranch, | |||||
isMainBranch, | |||||
isPullRequest | isPullRequest | ||||
} from '../../../helpers/branches'; | |||||
} from '../../../helpers/branch-like'; | |||||
import * as measures from '../../../helpers/measures'; | import * as measures from '../../../helpers/measures'; | ||||
import { | import { | ||||
getStandards, | getStandards, | ||||
global.SonarHelpers = { | global.SonarHelpers = { | ||||
getBranchLikeQuery, | getBranchLikeQuery, | ||||
isBranch, | isBranch, | ||||
isLongLivingBranch, | |||||
isMainBranch, | |||||
isPullRequest, | isPullRequest, | ||||
getStandards, | getStandards, | ||||
renderCWECategory, | renderCWECategory, | ||||
Level, | Level, | ||||
ListFooter, | ListFooter, | ||||
LockIcon, | LockIcon, | ||||
LongLivingBranchIcon, | |||||
LongLivingBranchIcon: BranchIcon, | |||||
Modal, | Modal, | ||||
NotFound, | NotFound, | ||||
PlusCircleIcon, | PlusCircleIcon, |
import * as React from 'react'; | import * as React from 'react'; | ||||
import { Link } from 'react-router'; | import { Link } from 'react-router'; | ||||
import QualifierIcon from 'sonar-ui-common/components/icons/QualifierIcon'; | import QualifierIcon from 'sonar-ui-common/components/icons/QualifierIcon'; | ||||
import { isMainBranch } from '../../../../helpers/branches'; | |||||
import { isMainBranch } from '../../../../helpers/branch-like'; | |||||
import { getProjectUrl } from '../../../../helpers/urls'; | import { getProjectUrl } from '../../../../helpers/urls'; | ||||
import { BranchLike } from '../../../../types/branch-like'; | |||||
interface Props { | interface Props { | ||||
component: T.Component; | component: T.Component; | ||||
currentBranchLike: T.BranchLike | undefined; | |||||
currentBranchLike: BranchLike | undefined; | |||||
} | } | ||||
export function ComponentBreadcrumb(props: Props) { | export function ComponentBreadcrumb(props: Props) { |
import * as React from 'react'; | import * as React from 'react'; | ||||
import ContextNavBar from 'sonar-ui-common/components/ui/ContextNavBar'; | import ContextNavBar from 'sonar-ui-common/components/ui/ContextNavBar'; | ||||
import { STATUSES } from '../../../../apps/background-tasks/constants'; | import { STATUSES } from '../../../../apps/background-tasks/constants'; | ||||
import { BranchLike } from '../../../../types/branch-like'; | |||||
import { rawSizes } from '../../../theme'; | import { rawSizes } from '../../../theme'; | ||||
import RecentHistory from '../../RecentHistory'; | import RecentHistory from '../../RecentHistory'; | ||||
import './ComponentNav.css'; | import './ComponentNav.css'; | ||||
import ComponentNavMeta from './ComponentNavMeta'; | import ComponentNavMeta from './ComponentNavMeta'; | ||||
interface Props { | interface Props { | ||||
branchLikes: T.BranchLike[]; | |||||
currentBranchLike: T.BranchLike | undefined; | |||||
branchLikes: BranchLike[]; | |||||
currentBranchLike: BranchLike | undefined; | |||||
component: T.Component; | component: T.Component; | ||||
currentTask?: T.Task; | currentTask?: T.Task; | ||||
currentTaskOnSameBranch?: boolean; | currentTaskOnSameBranch?: boolean; |
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import Helmet from 'react-helmet'; | import Helmet from 'react-helmet'; | ||||
import { BranchLike } from '../../../../types/branch-like'; | |||||
import BranchLikeNavigation from './branch-like/BranchLikeNavigation'; | import BranchLikeNavigation from './branch-like/BranchLikeNavigation'; | ||||
import CurrentBranchLikeMergeInformation from './branch-like/CurrentBranchLikeMergeInformation'; | import CurrentBranchLikeMergeInformation from './branch-like/CurrentBranchLikeMergeInformation'; | ||||
import { ComponentBreadcrumb } from './ComponentBreadcrumb'; | import { ComponentBreadcrumb } from './ComponentBreadcrumb'; | ||||
export interface ComponentNavHeaderProps { | export interface ComponentNavHeaderProps { | ||||
branchLikes: T.BranchLike[]; | |||||
branchLikes: BranchLike[]; | |||||
component: T.Component; | component: T.Component; | ||||
currentBranchLike: T.BranchLike | undefined; | |||||
currentBranchLike: BranchLike | undefined; | |||||
} | } | ||||
export function ComponentNavHeader(props: ComponentNavHeaderProps) { | export function ComponentNavHeader(props: ComponentNavHeaderProps) { |
import NavBarTabs from 'sonar-ui-common/components/ui/NavBarTabs'; | import NavBarTabs from 'sonar-ui-common/components/ui/NavBarTabs'; | ||||
import { translate } from 'sonar-ui-common/helpers/l10n'; | import { translate } from 'sonar-ui-common/helpers/l10n'; | ||||
import { withAppState } from '../../../../components/hoc/withAppState'; | import { withAppState } from '../../../../components/hoc/withAppState'; | ||||
import { | |||||
getBranchLikeQuery, | |||||
isMainBranch, | |||||
isPullRequest, | |||||
isShortLivingBranch | |||||
} from '../../../../helpers/branches'; | |||||
import { getBranchLikeQuery, isMainBranch, isPullRequest } from '../../../../helpers/branch-like'; | |||||
import { isSonarCloud } from '../../../../helpers/system'; | import { isSonarCloud } from '../../../../helpers/system'; | ||||
import { BranchLike } from '../../../../types/branch-like'; | |||||
const SETTINGS_URLS = [ | const SETTINGS_URLS = [ | ||||
'/project/admin', | '/project/admin', | ||||
interface Props { | interface Props { | ||||
appState: Pick<T.AppState, 'branchesEnabled'>; | appState: Pick<T.AppState, 'branchesEnabled'>; | ||||
branchLike: T.BranchLike | undefined; | |||||
branchLike: BranchLike | undefined; | |||||
component: T.Component; | component: T.Component; | ||||
location?: any; | location?: any; | ||||
} | } | ||||
renderActivityLink() { | renderActivityLink() { | ||||
const { branchLike } = this.props; | const { branchLike } = this.props; | ||||
if (isShortLivingBranch(branchLike) || isPullRequest(branchLike)) { | |||||
if (isPullRequest(branchLike)) { | |||||
return null; | return null; | ||||
} | } | ||||
const { branchLike, component } = this.props; | const { branchLike, component } = this.props; | ||||
const { extensions = [] } = component; | const { extensions = [] } = component; | ||||
if (isShortLivingBranch(branchLike) || isPullRequest(branchLike)) { | |||||
if (isPullRequest(branchLike)) { | |||||
return null; | return null; | ||||
} | } | ||||
import Favorite from '../../../../components/controls/Favorite'; | import Favorite from '../../../../components/controls/Favorite'; | ||||
import HomePageSelect from '../../../../components/controls/HomePageSelect'; | import HomePageSelect from '../../../../components/controls/HomePageSelect'; | ||||
import DateTimeFormatter from '../../../../components/intl/DateTimeFormatter'; | import DateTimeFormatter from '../../../../components/intl/DateTimeFormatter'; | ||||
import { | |||||
isLongLivingBranch, | |||||
isMainBranch, | |||||
isPullRequest, | |||||
isShortLivingBranch | |||||
} from '../../../../helpers/branches'; | |||||
import { isBranch, isMainBranch, isPullRequest } from '../../../../helpers/branch-like'; | |||||
import { isLoggedIn } from '../../../../helpers/users'; | import { isLoggedIn } from '../../../../helpers/users'; | ||||
import { getCurrentUser, Store } from '../../../../store/rootReducer'; | import { getCurrentUser, Store } from '../../../../store/rootReducer'; | ||||
import { BranchLike } from '../../../../types/branch-like'; | |||||
import ComponentNavWarnings from './ComponentNavWarnings'; | import ComponentNavWarnings from './ComponentNavWarnings'; | ||||
export interface Props { | export interface Props { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
currentUser: T.CurrentUser; | currentUser: T.CurrentUser; | ||||
component: T.Component; | component: T.Component; | ||||
warnings: string[]; | warnings: string[]; | ||||
export function ComponentNavMeta({ branchLike, component, currentUser, warnings }: Props) { | export function ComponentNavMeta({ branchLike, component, currentUser, warnings }: Props) { | ||||
const mainBranch = !branchLike || isMainBranch(branchLike); | const mainBranch = !branchLike || isMainBranch(branchLike); | ||||
const longBranch = isLongLivingBranch(branchLike); | |||||
const isABranch = isBranch(branchLike); | |||||
const currentPage = getCurrentPage(component, branchLike); | const currentPage = getCurrentPage(component, branchLike); | ||||
const displayVersion = component.version !== undefined && (mainBranch || longBranch); | |||||
const displayVersion = component.version !== undefined && isABranch; | |||||
return ( | return ( | ||||
<div className="navbar-context-meta flex-0"> | <div className="navbar-context-meta flex-0"> | ||||
qualifier={component.qualifier} | qualifier={component.qualifier} | ||||
/> | /> | ||||
)} | )} | ||||
{(mainBranch || longBranch) && currentPage !== undefined && ( | |||||
{isABranch && currentPage !== undefined && ( | |||||
<HomePageSelect className="spacer-left" currentPage={currentPage} /> | <HomePageSelect className="spacer-left" currentPage={currentPage} /> | ||||
)} | )} | ||||
</div> | </div> | ||||
)} | )} | ||||
{(isShortLivingBranch(branchLike) || isPullRequest(branchLike)) && ( | |||||
{isPullRequest(branchLike) && ( | |||||
<div className="navbar-context-meta-secondary display-inline-flex-center"> | <div className="navbar-context-meta-secondary display-inline-flex-center"> | ||||
{isPullRequest(branchLike) && branchLike.url !== undefined && ( | {isPullRequest(branchLike) && branchLike.url !== undefined && ( | ||||
<a | <a | ||||
); | ); | ||||
} | } | ||||
export function getCurrentPage(component: T.Component, branchLike: T.BranchLike | undefined) { | |||||
export function getCurrentPage(component: T.Component, branchLike: BranchLike | undefined) { | |||||
let currentPage: T.HomePage | undefined; | let currentPage: T.HomePage | undefined; | ||||
if (component.qualifier === 'VW' || component.qualifier === 'SVW') { | if (component.qualifier === 'VW' || component.qualifier === 'SVW') { | ||||
currentPage = { type: 'PORTFOLIO', component: component.key }; | currentPage = { type: 'PORTFOLIO', component: component.key }; | ||||
} else if (component.qualifier === 'APP') { | } else if (component.qualifier === 'APP') { | ||||
const branch = isLongLivingBranch(branchLike) ? branchLike.name : undefined; | |||||
const branch = isBranch(branchLike) ? branchLike.name : undefined; | |||||
currentPage = { type: 'APPLICATION', component: component.key, branch }; | currentPage = { type: 'APPLICATION', component: component.key, branch }; | ||||
} else if (component.qualifier === 'TRK') { | } else if (component.qualifier === 'TRK') { | ||||
// when home page is set to the default branch of a project, its name is returned as `undefined` | // when home page is set to the default branch of a project, its name is returned as `undefined` | ||||
const branch = isLongLivingBranch(branchLike) ? branchLike.name : undefined; | |||||
const branch = isBranch(branchLike) ? branchLike.name : undefined; | |||||
currentPage = { type: 'PROJECT', component: component.key, branch }; | currentPage = { type: 'PROJECT', component: component.key, branch }; | ||||
} | } | ||||
return currentPage; | return currentPage; |
import { shallow } from 'enzyme'; | import { shallow } from 'enzyme'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { mockComponent, mockMainBranch } from '../../../../../helpers/testMocks'; | |||||
import { mockMainBranch } from '../../../../../helpers/mocks/branch-like'; | |||||
import { mockComponent } from '../../../../../helpers/testMocks'; | |||||
import { ComponentQualifier } from '../../../../../types/component'; | import { ComponentQualifier } from '../../../../../types/component'; | ||||
import { ComponentBreadcrumb } from '../ComponentBreadcrumb'; | import { ComponentBreadcrumb } from '../ComponentBreadcrumb'; | ||||
import { shallow } from 'enzyme'; | import { shallow } from 'enzyme'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { mockSetOfBranchAndPullRequest } from '../../../../../helpers/mocks/branch-pull-request'; | |||||
import { mockSetOfBranchAndPullRequest } from '../../../../../helpers/mocks/branch-like'; | |||||
import { mockComponent } from '../../../../../helpers/testMocks'; | import { mockComponent } from '../../../../../helpers/testMocks'; | ||||
import { ComponentNavHeader, ComponentNavHeaderProps } from '../ComponentNavHeader'; | import { ComponentNavHeader, ComponentNavHeaderProps } from '../ComponentNavHeader'; | ||||
*/ | */ | ||||
import { shallow } from 'enzyme'; | import { shallow } from 'enzyme'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { mockMainBranch } from '../../../../../helpers/testMocks'; | |||||
import { mockBranch, mockMainBranch } from '../../../../../helpers/mocks/branch-like'; | |||||
import { ComponentNavMenu } from '../ComponentNavMenu'; | import { ComponentNavMenu } from '../ComponentNavMenu'; | ||||
const mainBranch: T.MainBranch = mockMainBranch(); | |||||
const mainBranch = mockMainBranch(); | |||||
const baseComponent = { | const baseComponent = { | ||||
breadcrumbs: [], | breadcrumbs: [], | ||||
expect(wrapper.find('Dropdown[data-test="security"]')).toMatchSnapshot(); | expect(wrapper.find('Dropdown[data-test="security"]')).toMatchSnapshot(); | ||||
}); | }); | ||||
it('should work for short-living branches', () => { | |||||
const branch: T.ShortLivingBranch = { | |||||
isMain: false, | |||||
excludedFromPurge: true, | |||||
mergeBranch: 'master', | |||||
name: 'feature', | |||||
type: 'SHORT' | |||||
}; | |||||
const component = { | |||||
...baseComponent, | |||||
configuration: { showSettings: true }, | |||||
extensions: [{ key: 'component-foo', name: 'ComponentFoo' }] | |||||
}; | |||||
expect( | |||||
shallow( | |||||
<ComponentNavMenu | |||||
appState={{ branchesEnabled: true }} | |||||
branchLike={branch} | |||||
component={component} | |||||
/> | |||||
) | |||||
).toMatchSnapshot(); | |||||
}); | |||||
it('should work for long-living branches', () => { | |||||
const branch: T.LongLivingBranch = { | |||||
excludedFromPurge: true, | |||||
isMain: false, | |||||
name: 'release', | |||||
type: 'LONG' | |||||
}; | |||||
it('should work for a branch', () => { | |||||
const branch = mockBranch({ | |||||
name: 'release' | |||||
}); | |||||
[true, false].forEach(showSettings => | [true, false].forEach(showSettings => | ||||
expect( | expect( | ||||
shallow( | shallow( |
*/ | */ | ||||
import { shallow } from 'enzyme'; | import { shallow } from 'enzyme'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { | |||||
mockComponent, | |||||
mockCurrentUser, | |||||
mockLoggedInUser, | |||||
mockLongLivingBranch, | |||||
mockPullRequest, | |||||
mockShortLivingBranch | |||||
} from '../../../../../helpers/testMocks'; | |||||
import { mockBranch, mockPullRequest } from '../../../../../helpers/mocks/branch-like'; | |||||
import { mockComponent, mockCurrentUser, mockLoggedInUser } from '../../../../../helpers/testMocks'; | |||||
import { ComponentNavMeta, getCurrentPage, Props } from '../ComponentNavMeta'; | import { ComponentNavMeta, getCurrentPage, Props } from '../ComponentNavMeta'; | ||||
describe('#ComponentNavMeta', () => { | describe('#ComponentNavMeta', () => { | ||||
it('renders status of short-living branch', () => { | |||||
expect(shallowRender()).toMatchSnapshot(); | |||||
}); | |||||
it('renders meta for long-living branch', () => { | |||||
it('renders meta for a branch', () => { | |||||
expect( | expect( | ||||
shallowRender({ branchLike: mockLongLivingBranch(), currentUser: mockLoggedInUser() }) | |||||
shallowRender({ branchLike: mockBranch(), currentUser: mockLoggedInUser() }) | |||||
).toMatchSnapshot(); | ).toMatchSnapshot(); | ||||
}); | }); | ||||
expect( | expect( | ||||
getCurrentPage( | getCurrentPage( | ||||
mockComponent({ key: 'foo', qualifier: 'APP' }), | mockComponent({ key: 'foo', qualifier: 'APP' }), | ||||
mockLongLivingBranch({ name: 'develop' }) | |||||
mockBranch({ name: 'develop' }) | |||||
) | ) | ||||
).toEqual({ type: 'APPLICATION', component: 'foo', branch: 'develop' }); | ).toEqual({ type: 'APPLICATION', component: 'foo', branch: 'develop' }); | ||||
}); | }); | ||||
it('should return a portfolio page', () => { | |||||
expect(getCurrentPage(mockComponent(), mockShortLivingBranch())).toEqual({ | |||||
it('should return a project page', () => { | |||||
expect(getCurrentPage(mockComponent(), mockBranch({ name: 'feature/foo' }))).toEqual({ | |||||
type: 'PROJECT', | type: 'PROJECT', | ||||
component: 'my-project', | component: 'my-project', | ||||
branch: undefined | |||||
branch: 'feature/foo' | |||||
}); | }); | ||||
}); | }); | ||||
}); | }); | ||||
function shallowRender(props: Partial<Props> = {}) { | function shallowRender(props: Partial<Props> = {}) { | ||||
return shallow( | return shallow( | ||||
<ComponentNavMeta | <ComponentNavMeta | ||||
branchLike={mockShortLivingBranch()} | |||||
branchLike={mockBranch()} | |||||
component={mockComponent({ analysisDate: '2017-01-02T00:00:00.000Z', version: '0.0.1' })} | component={mockComponent({ analysisDate: '2017-01-02T00:00:00.000Z', version: '0.0.1' })} | ||||
currentUser={mockCurrentUser()} | currentUser={mockCurrentUser()} | ||||
warnings={[]} | warnings={[]} |
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"mergeBranch": "master", | |||||
"name": "slb-1", | |||||
"type": "SHORT", | |||||
"name": "branch-11", | |||||
} | } | ||||
} | } | ||||
/> | /> | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"mergeBranch": "master", | |||||
"name": "slb-1", | |||||
"type": "SHORT", | |||||
"name": "branch-11", | |||||
}, | }, | ||||
Object { | Object { | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"name": "llb-1", | |||||
"type": "LONG", | |||||
"name": "branch-1", | |||||
}, | }, | ||||
Object { | Object { | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"mergeBranch": "llb-1", | |||||
"name": "slb-2", | |||||
"type": "SHORT", | |||||
"name": "branch-12", | |||||
}, | }, | ||||
Object { | Object { | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"name": "llb-3", | |||||
"type": "LONG", | |||||
"name": "branch-3", | |||||
}, | }, | ||||
Object { | Object { | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"name": "llb-2", | |||||
"type": "LONG", | |||||
"name": "branch-2", | |||||
}, | }, | ||||
Object { | Object { | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"mergeBranch": "master", | |||||
"name": "slb-1", | |||||
"type": "SHORT", | |||||
"name": "branch-11", | |||||
} | } | ||||
} | } | ||||
/> | /> | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"mergeBranch": "master", | |||||
"name": "slb-1", | |||||
"type": "SHORT", | |||||
"name": "branch-11", | |||||
} | } | ||||
} | } | ||||
/> | /> |
exports[`should render correctly for security extensions 2`] = `null`; | exports[`should render correctly for security extensions 2`] = `null`; | ||||
exports[`should work for all qualifiers 1`] = ` | |||||
exports[`should work for a branch 1`] = ` | |||||
<NavBarTabs> | <NavBarTabs> | ||||
<li> | <li> | ||||
<Link | <Link | ||||
Object { | Object { | ||||
"pathname": "/dashboard", | "pathname": "/dashboard", | ||||
"query": Object { | "query": Object { | ||||
"branch": "release", | |||||
"id": "foo", | "id": "foo", | ||||
}, | }, | ||||
} | } | ||||
Object { | Object { | ||||
"pathname": "/project/issues", | "pathname": "/project/issues", | ||||
"query": Object { | "query": Object { | ||||
"branch": "release", | |||||
"id": "foo", | "id": "foo", | ||||
"resolved": "false", | "resolved": "false", | ||||
}, | }, | ||||
Object { | Object { | ||||
"pathname": "/component_measures", | "pathname": "/component_measures", | ||||
"query": Object { | "query": Object { | ||||
"branch": "release", | |||||
"id": "foo", | "id": "foo", | ||||
}, | }, | ||||
} | } | ||||
Object { | Object { | ||||
"pathname": "/code", | "pathname": "/code", | ||||
"query": Object { | "query": Object { | ||||
"branch": "release", | |||||
"id": "foo", | "id": "foo", | ||||
}, | }, | ||||
} | } | ||||
Object { | Object { | ||||
"pathname": "/project/activity", | "pathname": "/project/activity", | ||||
"query": Object { | "query": Object { | ||||
"branch": "release", | |||||
"id": "foo", | "id": "foo", | ||||
}, | }, | ||||
} | } | ||||
project_activity.page | project_activity.page | ||||
</Link> | </Link> | ||||
</li> | </li> | ||||
<Dropdown | |||||
data-test="administration" | |||||
overlay={ | |||||
<ul | |||||
className="menu" | |||||
> | |||||
<li> | |||||
<Link | |||||
activeClassName="active" | |||||
onlyActiveOnIndex={false} | |||||
style={Object {}} | |||||
to={ | |||||
Object { | |||||
"pathname": "/project/settings", | |||||
"query": Object { | |||||
"id": "foo", | |||||
}, | |||||
} | |||||
} | |||||
> | |||||
project_settings.page | |||||
</Link> | |||||
</li> | |||||
<li> | |||||
<Link | |||||
activeClassName="active" | |||||
onlyActiveOnIndex={false} | |||||
style={Object {}} | |||||
to={ | |||||
Object { | |||||
"pathname": "/project/branches", | |||||
"query": Object { | |||||
"id": "foo", | |||||
}, | |||||
} | |||||
} | |||||
> | |||||
project_branch_pull_request.page | |||||
</Link> | |||||
</li> | |||||
<li> | |||||
<Link | |||||
activeClassName="active" | |||||
onlyActiveOnIndex={false} | |||||
style={Object {}} | |||||
to={ | |||||
Object { | |||||
"pathname": "/project/baseline", | |||||
"query": Object { | |||||
"id": "foo", | |||||
}, | |||||
} | |||||
} | |||||
> | |||||
project_baseline.page | |||||
</Link> | |||||
</li> | |||||
<li> | |||||
<Link | |||||
activeClassName="active" | |||||
onlyActiveOnIndex={false} | |||||
style={Object {}} | |||||
to={ | |||||
Object { | |||||
"pathname": "/project/webhooks", | |||||
"query": Object { | |||||
"id": "foo", | |||||
}, | |||||
} | |||||
} | |||||
> | |||||
webhooks.page | |||||
</Link> | |||||
</li> | |||||
<li> | |||||
<Link | |||||
activeClassName="active" | |||||
onlyActiveOnIndex={false} | |||||
style={Object {}} | |||||
to={ | |||||
Object { | |||||
"pathname": "/project/deletion", | |||||
"query": Object { | |||||
"id": "foo", | |||||
}, | |||||
} | |||||
} | |||||
> | |||||
deletion.page | |||||
</Link> | |||||
</li> | |||||
</ul> | |||||
} | |||||
tagName="li" | |||||
> | |||||
<Component /> | |||||
</Dropdown> | |||||
</NavBarTabs> | </NavBarTabs> | ||||
`; | `; | ||||
exports[`should work for all qualifiers 2`] = ` | |||||
exports[`should work for a branch 2`] = ` | |||||
<NavBarTabs> | <NavBarTabs> | ||||
<li> | <li> | ||||
<Link | <Link | ||||
style={Object {}} | style={Object {}} | ||||
to={ | to={ | ||||
Object { | Object { | ||||
"pathname": "/portfolio", | |||||
"pathname": "/dashboard", | |||||
"query": Object { | "query": Object { | ||||
"branch": "release", | |||||
"id": "foo", | "id": "foo", | ||||
}, | }, | ||||
} | } | ||||
Object { | Object { | ||||
"pathname": "/project/issues", | "pathname": "/project/issues", | ||||
"query": Object { | "query": Object { | ||||
"branch": "release", | |||||
"id": "foo", | "id": "foo", | ||||
"resolved": "false", | "resolved": "false", | ||||
}, | }, | ||||
Object { | Object { | ||||
"pathname": "/component_measures", | "pathname": "/component_measures", | ||||
"query": Object { | "query": Object { | ||||
"branch": "release", | |||||
"id": "foo", | "id": "foo", | ||||
}, | }, | ||||
} | } | ||||
Object { | Object { | ||||
"pathname": "/code", | "pathname": "/code", | ||||
"query": Object { | "query": Object { | ||||
"branch": "release", | |||||
"id": "foo", | "id": "foo", | ||||
}, | }, | ||||
} | } | ||||
} | } | ||||
> | > | ||||
view_projects.page | |||||
code.page | |||||
</Link> | </Link> | ||||
</li> | </li> | ||||
<li> | <li> | ||||
Object { | Object { | ||||
"pathname": "/project/activity", | "pathname": "/project/activity", | ||||
"query": Object { | "query": Object { | ||||
"branch": "release", | |||||
"id": "foo", | "id": "foo", | ||||
}, | }, | ||||
} | } | ||||
project_activity.page | project_activity.page | ||||
</Link> | </Link> | ||||
</li> | </li> | ||||
<Dropdown | |||||
data-test="administration" | |||||
overlay={ | |||||
<ul | |||||
className="menu" | |||||
> | |||||
<li> | |||||
<Link | |||||
activeClassName="active" | |||||
onlyActiveOnIndex={false} | |||||
style={Object {}} | |||||
to={ | |||||
Object { | |||||
"pathname": "/project/deletion", | |||||
"query": Object { | |||||
"id": "foo", | |||||
}, | |||||
} | |||||
} | |||||
> | |||||
deletion.page | |||||
</Link> | |||||
</li> | |||||
</ul> | |||||
} | |||||
tagName="li" | |||||
> | |||||
<Component /> | |||||
</Dropdown> | |||||
</NavBarTabs> | </NavBarTabs> | ||||
`; | `; | ||||
exports[`should work for all qualifiers 3`] = ` | |||||
exports[`should work for all qualifiers 1`] = ` | |||||
<NavBarTabs> | <NavBarTabs> | ||||
<li> | <li> | ||||
<Link | <Link | ||||
style={Object {}} | style={Object {}} | ||||
to={ | to={ | ||||
Object { | Object { | ||||
"pathname": "/portfolio", | |||||
"pathname": "/dashboard", | |||||
"query": Object { | "query": Object { | ||||
"id": "foo", | "id": "foo", | ||||
}, | }, | ||||
} | } | ||||
} | } | ||||
> | > | ||||
view_projects.page | |||||
code.page | |||||
</Link> | </Link> | ||||
</li> | </li> | ||||
<li> | <li> | ||||
project_activity.page | project_activity.page | ||||
</Link> | </Link> | ||||
</li> | </li> | ||||
<Dropdown | |||||
data-test="administration" | |||||
overlay={ | |||||
<ul | |||||
className="menu" | |||||
> | |||||
<li> | |||||
<Link | |||||
activeClassName="active" | |||||
onlyActiveOnIndex={false} | |||||
style={Object {}} | |||||
to={ | |||||
Object { | |||||
"pathname": "/project/settings", | |||||
"query": Object { | |||||
"id": "foo", | |||||
}, | |||||
} | |||||
} | |||||
> | |||||
project_settings.page | |||||
</Link> | |||||
</li> | |||||
<li> | |||||
<Link | |||||
activeClassName="active" | |||||
onlyActiveOnIndex={false} | |||||
style={Object {}} | |||||
to={ | |||||
Object { | |||||
"pathname": "/project/branches", | |||||
"query": Object { | |||||
"id": "foo", | |||||
}, | |||||
} | |||||
} | |||||
> | |||||
project_branch_pull_request.page | |||||
</Link> | |||||
</li> | |||||
<li> | |||||
<Link | |||||
activeClassName="active" | |||||
onlyActiveOnIndex={false} | |||||
style={Object {}} | |||||
to={ | |||||
Object { | |||||
"pathname": "/project/baseline", | |||||
"query": Object { | |||||
"id": "foo", | |||||
}, | |||||
} | |||||
} | |||||
> | |||||
project_baseline.page | |||||
</Link> | |||||
</li> | |||||
<li> | |||||
<Link | |||||
activeClassName="active" | |||||
onlyActiveOnIndex={false} | |||||
style={Object {}} | |||||
to={ | |||||
Object { | |||||
"pathname": "/project/webhooks", | |||||
"query": Object { | |||||
"id": "foo", | |||||
}, | |||||
} | |||||
} | |||||
> | |||||
webhooks.page | |||||
</Link> | |||||
</li> | |||||
<li> | |||||
<Link | |||||
activeClassName="active" | |||||
onlyActiveOnIndex={false} | |||||
style={Object {}} | |||||
to={ | |||||
Object { | |||||
"pathname": "/project/deletion", | |||||
"query": Object { | |||||
"id": "foo", | |||||
}, | |||||
} | |||||
} | |||||
> | |||||
deletion.page | |||||
</Link> | |||||
</li> | |||||
</ul> | |||||
} | |||||
tagName="li" | |||||
> | |||||
<Component /> | |||||
</Dropdown> | |||||
</NavBarTabs> | </NavBarTabs> | ||||
`; | `; | ||||
exports[`should work for all qualifiers 4`] = ` | |||||
exports[`should work for all qualifiers 2`] = ` | |||||
<NavBarTabs> | <NavBarTabs> | ||||
<li> | <li> | ||||
<Link | <Link | ||||
style={Object {}} | style={Object {}} | ||||
to={ | to={ | ||||
Object { | Object { | ||||
"pathname": "/dashboard", | |||||
"pathname": "/portfolio", | |||||
"query": Object { | "query": Object { | ||||
"id": "foo", | "id": "foo", | ||||
}, | }, | ||||
</NavBarTabs> | </NavBarTabs> | ||||
`; | `; | ||||
exports[`should work for long-living branches 1`] = ` | |||||
exports[`should work for all qualifiers 3`] = ` | |||||
<NavBarTabs> | <NavBarTabs> | ||||
<li> | <li> | ||||
<Link | <Link | ||||
style={Object {}} | style={Object {}} | ||||
to={ | to={ | ||||
Object { | Object { | ||||
"pathname": "/dashboard", | |||||
"pathname": "/portfolio", | |||||
"query": Object { | "query": Object { | ||||
"branch": "release", | |||||
"id": "foo", | "id": "foo", | ||||
}, | }, | ||||
} | } | ||||
Object { | Object { | ||||
"pathname": "/project/issues", | "pathname": "/project/issues", | ||||
"query": Object { | "query": Object { | ||||
"branch": "release", | |||||
"id": "foo", | "id": "foo", | ||||
"resolved": "false", | "resolved": "false", | ||||
}, | }, | ||||
Object { | Object { | ||||
"pathname": "/component_measures", | "pathname": "/component_measures", | ||||
"query": Object { | "query": Object { | ||||
"branch": "release", | |||||
"id": "foo", | "id": "foo", | ||||
}, | }, | ||||
} | } | ||||
Object { | Object { | ||||
"pathname": "/code", | "pathname": "/code", | ||||
"query": Object { | "query": Object { | ||||
"branch": "release", | |||||
"id": "foo", | "id": "foo", | ||||
}, | }, | ||||
} | } | ||||
} | } | ||||
> | > | ||||
code.page | |||||
view_projects.page | |||||
</Link> | </Link> | ||||
</li> | </li> | ||||
<li> | <li> | ||||
Object { | Object { | ||||
"pathname": "/project/activity", | "pathname": "/project/activity", | ||||
"query": Object { | "query": Object { | ||||
"branch": "release", | |||||
"id": "foo", | "id": "foo", | ||||
}, | }, | ||||
} | } | ||||
</NavBarTabs> | </NavBarTabs> | ||||
`; | `; | ||||
exports[`should work for long-living branches 2`] = ` | |||||
exports[`should work for all qualifiers 4`] = ` | |||||
<NavBarTabs> | <NavBarTabs> | ||||
<li> | <li> | ||||
<Link | <Link | ||||
Object { | Object { | ||||
"pathname": "/dashboard", | "pathname": "/dashboard", | ||||
"query": Object { | "query": Object { | ||||
"branch": "release", | |||||
"id": "foo", | "id": "foo", | ||||
}, | }, | ||||
} | } | ||||
Object { | Object { | ||||
"pathname": "/project/issues", | "pathname": "/project/issues", | ||||
"query": Object { | "query": Object { | ||||
"branch": "release", | |||||
"id": "foo", | "id": "foo", | ||||
"resolved": "false", | "resolved": "false", | ||||
}, | }, | ||||
Object { | Object { | ||||
"pathname": "/component_measures", | "pathname": "/component_measures", | ||||
"query": Object { | "query": Object { | ||||
"branch": "release", | |||||
"id": "foo", | "id": "foo", | ||||
}, | }, | ||||
} | } | ||||
Object { | Object { | ||||
"pathname": "/code", | "pathname": "/code", | ||||
"query": Object { | "query": Object { | ||||
"branch": "release", | |||||
"id": "foo", | "id": "foo", | ||||
}, | }, | ||||
} | } | ||||
} | } | ||||
> | > | ||||
code.page | |||||
view_projects.page | |||||
</Link> | </Link> | ||||
</li> | </li> | ||||
<li> | <li> | ||||
Object { | Object { | ||||
"pathname": "/project/activity", | "pathname": "/project/activity", | ||||
"query": Object { | "query": Object { | ||||
"branch": "release", | |||||
"id": "foo", | "id": "foo", | ||||
}, | }, | ||||
} | } | ||||
project_activity.page | project_activity.page | ||||
</Link> | </Link> | ||||
</li> | </li> | ||||
</NavBarTabs> | |||||
`; | |||||
exports[`should work for short-living branches 1`] = ` | |||||
<NavBarTabs> | |||||
<li> | |||||
<Link | |||||
activeClassName="active" | |||||
onlyActiveOnIndex={false} | |||||
style={Object {}} | |||||
to={ | |||||
Object { | |||||
"pathname": "/dashboard", | |||||
"query": Object { | |||||
"branch": "feature", | |||||
"id": "foo", | |||||
}, | |||||
} | |||||
} | |||||
> | |||||
overview.page | |||||
</Link> | |||||
</li> | |||||
<li> | |||||
<Link | |||||
activeClassName="active" | |||||
className="" | |||||
onlyActiveOnIndex={false} | |||||
style={Object {}} | |||||
to={ | |||||
Object { | |||||
"pathname": "/project/issues", | |||||
"query": Object { | |||||
"branch": "feature", | |||||
"id": "foo", | |||||
"resolved": "false", | |||||
}, | |||||
} | |||||
} | |||||
> | |||||
issues.page | |||||
</Link> | |||||
</li> | |||||
<li> | |||||
<Link | |||||
activeClassName="active" | |||||
onlyActiveOnIndex={false} | |||||
style={Object {}} | |||||
to={ | |||||
Object { | |||||
"pathname": "/component_measures", | |||||
"query": Object { | |||||
"branch": "feature", | |||||
"id": "foo", | |||||
}, | |||||
} | |||||
} | |||||
> | |||||
layout.measures | |||||
</Link> | |||||
</li> | |||||
<li> | |||||
<Link | |||||
activeClassName="active" | |||||
onlyActiveOnIndex={false} | |||||
style={Object {}} | |||||
to={ | |||||
Object { | |||||
"pathname": "/code", | |||||
"query": Object { | |||||
"branch": "feature", | |||||
"id": "foo", | |||||
}, | |||||
} | |||||
} | |||||
> | |||||
code.page | |||||
</Link> | |||||
</li> | |||||
<Dropdown | |||||
data-test="administration" | |||||
overlay={ | |||||
<ul | |||||
className="menu" | |||||
> | |||||
<li> | |||||
<Link | |||||
activeClassName="active" | |||||
onlyActiveOnIndex={false} | |||||
style={Object {}} | |||||
to={ | |||||
Object { | |||||
"pathname": "/project/deletion", | |||||
"query": Object { | |||||
"id": "foo", | |||||
}, | |||||
} | |||||
} | |||||
> | |||||
deletion.page | |||||
</Link> | |||||
</li> | |||||
</ul> | |||||
} | |||||
tagName="li" | |||||
> | |||||
<Component /> | |||||
</Dropdown> | |||||
</NavBarTabs> | </NavBarTabs> | ||||
`; | `; | ||||
// Jest Snapshot v1, https://goo.gl/fbAQLP | // Jest Snapshot v1, https://goo.gl/fbAQLP | ||||
exports[`#ComponentNavMeta renders meta for long-living branch 1`] = ` | |||||
exports[`#ComponentNavMeta renders meta for a branch 1`] = ` | |||||
<div | <div | ||||
className="navbar-context-meta flex-0" | className="navbar-context-meta flex-0" | ||||
> | > | ||||
</div> | </div> | ||||
</div> | </div> | ||||
`; | `; | ||||
exports[`#ComponentNavMeta renders status of short-living branch 1`] = ` | |||||
<div | |||||
className="navbar-context-meta flex-0" | |||||
> | |||||
<div | |||||
className="spacer-left text-ellipsis" | |||||
> | |||||
<DateTimeFormatter | |||||
date="2017-01-02T00:00:00.000Z" | |||||
/> | |||||
</div> | |||||
<div | |||||
className="navbar-context-meta-secondary display-inline-flex-center" | |||||
> | |||||
<Connect(BranchStatus) | |||||
branchLike={ | |||||
Object { | |||||
"analysisDate": "2018-01-01", | |||||
"excludedFromPurge": true, | |||||
"isMain": false, | |||||
"mergeBranch": "master", | |||||
"name": "feature/foo", | |||||
"type": "SHORT", | |||||
} | |||||
} | |||||
component="my-project" | |||||
/> | |||||
</div> | |||||
</div> | |||||
`; |
import * as React from 'react'; | import * as React from 'react'; | ||||
import Toggler from 'sonar-ui-common/components/controls/Toggler'; | import Toggler from 'sonar-ui-common/components/controls/Toggler'; | ||||
import { withAppState } from '../../../../../components/hoc/withAppState'; | import { withAppState } from '../../../../../components/hoc/withAppState'; | ||||
import { BranchLike } from '../../../../../types/branch-like'; | |||||
import './BranchLikeNavigation.css'; | import './BranchLikeNavigation.css'; | ||||
import CurrentBranchLike from './CurrentBranchLike'; | import CurrentBranchLike from './CurrentBranchLike'; | ||||
import Menu from './Menu'; | import Menu from './Menu'; | ||||
export interface BranchLikeNavigationProps { | export interface BranchLikeNavigationProps { | ||||
appState: Pick<T.AppState, 'branchesEnabled'>; | appState: Pick<T.AppState, 'branchesEnabled'>; | ||||
branchLikes: T.BranchLike[]; | |||||
branchLikes: BranchLike[]; | |||||
component: T.Component; | component: T.Component; | ||||
currentBranchLike: T.BranchLike; | |||||
currentBranchLike: BranchLike; | |||||
} | } | ||||
export function BranchLikeNavigation(props: BranchLikeNavigationProps) { | export function BranchLikeNavigation(props: BranchLikeNavigationProps) { |
import { translate } from 'sonar-ui-common/helpers/l10n'; | import { translate } from 'sonar-ui-common/helpers/l10n'; | ||||
import DocTooltip from '../../../../../components/docs/DocTooltip'; | import DocTooltip from '../../../../../components/docs/DocTooltip'; | ||||
import BranchLikeIcon from '../../../../../components/icons/BranchLikeIcon'; | import BranchLikeIcon from '../../../../../components/icons/BranchLikeIcon'; | ||||
import { getBranchLikeDisplayName } from '../../../../../helpers/branches'; | |||||
import { getBranchLikeDisplayName } from '../../../../../helpers/branch-like'; | |||||
import { getPortfolioAdminUrl } from '../../../../../helpers/urls'; | import { getPortfolioAdminUrl } from '../../../../../helpers/urls'; | ||||
import { BranchLike } from '../../../../../types/branch-like'; | |||||
import { ComponentQualifier } from '../../../../../types/component'; | import { ComponentQualifier } from '../../../../../types/component'; | ||||
import { colors } from '../../../../theme'; | import { colors } from '../../../../theme'; | ||||
export interface CurrentBranchLikeProps { | export interface CurrentBranchLikeProps { | ||||
branchesEnabled: boolean; | branchesEnabled: boolean; | ||||
component: T.Component; | component: T.Component; | ||||
currentBranchLike: T.BranchLike; | |||||
currentBranchLike: BranchLike; | |||||
hasManyBranches: boolean; | hasManyBranches: boolean; | ||||
} | } | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { FormattedMessage } from 'react-intl'; | import { FormattedMessage } from 'react-intl'; | ||||
import { translate } from 'sonar-ui-common/helpers/l10n'; | import { translate } from 'sonar-ui-common/helpers/l10n'; | ||||
import { isPullRequest } from '../../../../../helpers/branches'; | |||||
import { isPullRequest } from '../../../../../helpers/branch-like'; | |||||
import { BranchLike } from '../../../../../types/branch-like'; | |||||
export interface CurrentBranchLikeMergeInformationProps { | export interface CurrentBranchLikeMergeInformationProps { | ||||
currentBranchLike: T.BranchLike; | |||||
currentBranchLike: BranchLike; | |||||
} | } | ||||
export function CurrentBranchLikeMergeInformation(props: CurrentBranchLikeMergeInformationProps) { | export function CurrentBranchLikeMergeInformation(props: CurrentBranchLikeMergeInformationProps) { |
isBranch, | isBranch, | ||||
isPullRequest, | isPullRequest, | ||||
isSameBranchLike | isSameBranchLike | ||||
} from '../../../../../helpers/branches'; | |||||
} from '../../../../../helpers/branch-like'; | |||||
import { getBranchLikeUrl } from '../../../../../helpers/urls'; | import { getBranchLikeUrl } from '../../../../../helpers/urls'; | ||||
import { BranchLike, BranchLikeTree } from '../../../../../types/branch-like'; | |||||
import { ComponentQualifier } from '../../../../../types/component'; | import { ComponentQualifier } from '../../../../../types/component'; | ||||
import MenuItemList from './MenuItemList'; | import MenuItemList from './MenuItemList'; | ||||
interface Props { | interface Props { | ||||
branchLikes: T.BranchLike[]; | |||||
branchLikes: BranchLike[]; | |||||
canAdminComponent?: boolean; | canAdminComponent?: boolean; | ||||
component: T.Component; | component: T.Component; | ||||
currentBranchLike: T.BranchLike; | |||||
currentBranchLike: BranchLike; | |||||
onClose: () => void; | onClose: () => void; | ||||
router: Pick<Router, 'push'>; | router: Pick<Router, 'push'>; | ||||
} | } | ||||
interface State { | interface State { | ||||
branchLikesToDisplay: T.BranchLike[]; | |||||
branchLikesToDisplayTree: T.BranchLikeTree; | |||||
branchLikesToDisplay: BranchLike[]; | |||||
branchLikesToDisplayTree: BranchLikeTree; | |||||
query: string; | query: string; | ||||
selectedBranchLike: T.BranchLike | undefined; | |||||
selectedBranchLike: BranchLike | undefined; | |||||
} | } | ||||
export class Menu extends React.PureComponent<Props, State> { | export class Menu extends React.PureComponent<Props, State> { | ||||
}; | }; | ||||
} | } | ||||
processBranchLikes = (branchLikes: T.BranchLike[]) => { | |||||
processBranchLikes = (branchLikes: BranchLike[]) => { | |||||
const tree = getBrancheLikesAsTree(branchLikes); | const tree = getBrancheLikesAsTree(branchLikes); | ||||
return { | return { | ||||
branchLikesToDisplay: [ | branchLikesToDisplay: [ | ||||
handleSearchChange = (query: string) => { | handleSearchChange = (query: string) => { | ||||
const q = query.toLowerCase(); | const q = query.toLowerCase(); | ||||
const filterBranch = (branch: T.BranchLike) => | |||||
const filterBranch = (branch: BranchLike) => | |||||
isBranch(branch) && branch.name.toLowerCase().includes(q); | isBranch(branch) && branch.name.toLowerCase().includes(q); | ||||
const filterPullRequest = (pr: T.BranchLike) => | |||||
const filterPullRequest = (pr: BranchLike) => | |||||
isPullRequest(pr) && (pr.title.toLowerCase().includes(q) || pr.key.toLowerCase().includes(q)); | isPullRequest(pr) && (pr.title.toLowerCase().includes(q) || pr.key.toLowerCase().includes(q)); | ||||
const filteredBranchLikes = this.props.branchLikes.filter( | const filteredBranchLikes = this.props.branchLikes.filter( | ||||
}); | }); | ||||
}; | }; | ||||
handleOnSelect = (branchLike: T.BranchLike) => { | |||||
handleOnSelect = (branchLike: BranchLike) => { | |||||
this.setState({ selectedBranchLike: branchLike }, () => { | this.setState({ selectedBranchLike: branchLike }, () => { | ||||
this.props.onClose(); | this.props.onClose(); | ||||
this.props.router.push(getBranchLikeUrl(this.props.component.key, branchLike)); | this.props.router.push(getBranchLikeUrl(this.props.component.key, branchLike)); |
import { translate } from 'sonar-ui-common/helpers/l10n'; | import { translate } from 'sonar-ui-common/helpers/l10n'; | ||||
import BranchStatus from '../../../../../components/common/BranchStatus'; | import BranchStatus from '../../../../../components/common/BranchStatus'; | ||||
import BranchLikeIcon from '../../../../../components/icons/BranchLikeIcon'; | import BranchLikeIcon from '../../../../../components/icons/BranchLikeIcon'; | ||||
import { getBranchLikeDisplayName, isMainBranch } from '../../../../../helpers/branches'; | |||||
import { getBranchLikeDisplayName, isMainBranch } from '../../../../../helpers/branch-like'; | |||||
import { BranchLike } from '../../../../../types/branch-like'; | |||||
export interface MenuItemProps { | export interface MenuItemProps { | ||||
branchLike: T.BranchLike; | |||||
branchLike: BranchLike; | |||||
component: T.Component; | component: T.Component; | ||||
indent?: boolean; | indent?: boolean; | ||||
onSelect: (branchLike: T.BranchLike) => void; | |||||
onSelect: (branchLike: BranchLike) => void; | |||||
selected: boolean; | selected: boolean; | ||||
setSelectedNode?: (node: HTMLLIElement) => void; | setSelectedNode?: (node: HTMLLIElement) => void; | ||||
} | } |
import { translate } from 'sonar-ui-common/helpers/l10n'; | import { translate } from 'sonar-ui-common/helpers/l10n'; | ||||
import { scrollToElement } from 'sonar-ui-common/helpers/scrolling'; | import { scrollToElement } from 'sonar-ui-common/helpers/scrolling'; | ||||
import { isDefined } from 'sonar-ui-common/helpers/types'; | import { isDefined } from 'sonar-ui-common/helpers/types'; | ||||
import { getBranchLikeKey, isSameBranchLike } from '../../../../../helpers/branches'; | |||||
import { getBranchLikeKey, isSameBranchLike } from '../../../../../helpers/branch-like'; | |||||
import { BranchLike, BranchLikeTree } from '../../../../../types/branch-like'; | |||||
import MenuItem from './MenuItem'; | import MenuItem from './MenuItem'; | ||||
export interface MenuItemListProps { | export interface MenuItemListProps { | ||||
branchLikeTree: T.BranchLikeTree; | |||||
branchLikeTree: BranchLikeTree; | |||||
component: T.Component; | component: T.Component; | ||||
hasResults: boolean; | hasResults: boolean; | ||||
onSelect: (branchLike: T.BranchLike) => void; | |||||
selectedBranchLike: T.BranchLike | undefined; | |||||
onSelect: (branchLike: BranchLike) => void; | |||||
selectedBranchLike: BranchLike | undefined; | |||||
} | } | ||||
export function MenuItemList(props: MenuItemListProps) { | export function MenuItemList(props: MenuItemListProps) { | ||||
const { branchLikeTree, component, hasResults, onSelect, selectedBranchLike } = props; | const { branchLikeTree, component, hasResults, onSelect, selectedBranchLike } = props; | ||||
const renderItem = (branchLike: T.BranchLike, indent?: boolean) => ( | |||||
const renderItem = (branchLike: BranchLike, indent?: boolean) => ( | |||||
<MenuItem | <MenuItem | ||||
branchLike={branchLike} | branchLike={branchLike} | ||||
component={component} | component={component} |
import * as React from 'react'; | import * as React from 'react'; | ||||
import Toggler from 'sonar-ui-common/components/controls/Toggler'; | import Toggler from 'sonar-ui-common/components/controls/Toggler'; | ||||
import { click } from 'sonar-ui-common/helpers/testUtils'; | import { click } from 'sonar-ui-common/helpers/testUtils'; | ||||
import { mockSetOfBranchAndPullRequest } from '../../../../../../helpers/mocks/branch-pull-request'; | |||||
import { mockSetOfBranchAndPullRequest } from '../../../../../../helpers/mocks/branch-like'; | |||||
import { mockAppState, mockComponent } from '../../../../../../helpers/testMocks'; | import { mockAppState, mockComponent } from '../../../../../../helpers/testMocks'; | ||||
import { BranchLikeNavigation, BranchLikeNavigationProps } from '../BranchLikeNavigation'; | import { BranchLikeNavigation, BranchLikeNavigationProps } from '../BranchLikeNavigation'; | ||||
import { shallow } from 'enzyme'; | import { shallow } from 'enzyme'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { mockComponent, mockMainBranch } from '../../../../../../helpers/testMocks'; | |||||
import { mockMainBranch } from '../../../../../../helpers/mocks/branch-like'; | |||||
import { mockComponent } from '../../../../../../helpers/testMocks'; | |||||
import { ComponentQualifier } from '../../../../../../types/component'; | import { ComponentQualifier } from '../../../../../../types/component'; | ||||
import { CurrentBranchLike, CurrentBranchLikeProps } from '../CurrentBranchLike'; | import { CurrentBranchLike, CurrentBranchLikeProps } from '../CurrentBranchLike'; | ||||
import { shallow } from 'enzyme'; | import { shallow } from 'enzyme'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { mockMainBranch, mockPullRequest } from '../../../../../../helpers/testMocks'; | |||||
import { mockMainBranch, mockPullRequest } from '../../../../../../helpers/mocks/branch-like'; | |||||
import { | import { | ||||
CurrentBranchLikeMergeInformation, | CurrentBranchLikeMergeInformation, | ||||
CurrentBranchLikeMergeInformationProps | CurrentBranchLikeMergeInformationProps |
import SearchBox from 'sonar-ui-common/components/controls/SearchBox'; | import SearchBox from 'sonar-ui-common/components/controls/SearchBox'; | ||||
import { KeyCodes } from 'sonar-ui-common/helpers/keycodes'; | import { KeyCodes } from 'sonar-ui-common/helpers/keycodes'; | ||||
import { click, mockEvent } from 'sonar-ui-common/helpers/testUtils'; | import { click, mockEvent } from 'sonar-ui-common/helpers/testUtils'; | ||||
import { mockSetOfBranchAndPullRequest } from '../../../../../../helpers/mocks/branch-pull-request'; | |||||
import { mockComponent, mockPullRequest, mockRouter } from '../../../../../../helpers/testMocks'; | |||||
import { | |||||
mockPullRequest, | |||||
mockSetOfBranchAndPullRequest | |||||
} from '../../../../../../helpers/mocks/branch-like'; | |||||
import { mockComponent, mockRouter } from '../../../../../../helpers/testMocks'; | |||||
import { Menu } from '../Menu'; | import { Menu } from '../Menu'; | ||||
import { MenuItemList } from '../MenuItemList'; | import { MenuItemList } from '../MenuItemList'; | ||||
onKeyDown(mockEvent({ keyCode: KeyCodes.DownArrow })); | onKeyDown(mockEvent({ keyCode: KeyCodes.DownArrow })); | ||||
onKeyDown(mockEvent({ keyCode: KeyCodes.DownArrow })); | onKeyDown(mockEvent({ keyCode: KeyCodes.DownArrow })); | ||||
expect(wrapper.state().selectedBranchLike).toBe(branchLikes[7]); | |||||
expect(wrapper.state().selectedBranchLike).toBe(branchLikes[0]); | |||||
onKeyDown(mockEvent({ keyCode: KeyCodes.Enter })); | onKeyDown(mockEvent({ keyCode: KeyCodes.Enter })); | ||||
expect(push).toHaveBeenCalled(); | expect(push).toHaveBeenCalled(); |
import { shallow } from 'enzyme'; | import { shallow } from 'enzyme'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { click } from 'sonar-ui-common/helpers/testUtils'; | import { click } from 'sonar-ui-common/helpers/testUtils'; | ||||
import { | |||||
mockComponent, | |||||
mockMainBranch, | |||||
mockPullRequest | |||||
} from '../../../../../../helpers/testMocks'; | |||||
import { mockMainBranch, mockPullRequest } from '../../../../../../helpers/mocks/branch-like'; | |||||
import { mockComponent } from '../../../../../../helpers/testMocks'; | |||||
import { MenuItem, MenuItemProps } from '../MenuItem'; | import { MenuItem, MenuItemProps } from '../MenuItem'; | ||||
it('should render a main branch correctly', () => { | it('should render a main branch correctly', () => { |
import { shallow } from 'enzyme'; | import { shallow } from 'enzyme'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { getBrancheLikesAsTree } from '../../../../../../helpers/branches'; | |||||
import { mockSetOfBranchAndPullRequest } from '../../../../../../helpers/mocks/branch-pull-request'; | |||||
import { mockComponent, mockPullRequest } from '../../../../../../helpers/testMocks'; | |||||
import { getBrancheLikesAsTree } from '../../../../../../helpers/branch-like'; | |||||
import { | |||||
mockPullRequest, | |||||
mockSetOfBranchAndPullRequest | |||||
} from '../../../../../../helpers/mocks/branch-like'; | |||||
import { mockComponent } from '../../../../../../helpers/testMocks'; | |||||
import { MenuItemList, MenuItemListProps } from '../MenuItemList'; | import { MenuItemList, MenuItemListProps } from '../MenuItemList'; | ||||
it('should render correctly', () => { | it('should render correctly', () => { |
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"mergeBranch": "master", | |||||
"name": "slb-1", | |||||
"type": "SHORT", | |||||
"name": "branch-11", | |||||
} | } | ||||
} | } | ||||
hasManyBranches={true} | hasManyBranches={true} | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"mergeBranch": "master", | |||||
"name": "slb-1", | |||||
"type": "SHORT", | |||||
"name": "branch-11", | |||||
}, | }, | ||||
Object { | Object { | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"name": "llb-1", | |||||
"type": "LONG", | |||||
"name": "branch-1", | |||||
}, | }, | ||||
Object { | Object { | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"mergeBranch": "llb-1", | |||||
"name": "slb-2", | |||||
"type": "SHORT", | |||||
"name": "branch-12", | |||||
}, | }, | ||||
Object { | Object { | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"name": "llb-3", | |||||
"type": "LONG", | |||||
"name": "branch-3", | |||||
}, | }, | ||||
Object { | Object { | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"name": "llb-2", | |||||
"type": "LONG", | |||||
"name": "branch-2", | |||||
}, | }, | ||||
Object { | Object { | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"mergeBranch": "master", | |||||
"name": "slb-1", | |||||
"type": "SHORT", | |||||
"name": "branch-11", | |||||
} | } | ||||
} | } | ||||
onClose={[Function]} | onClose={[Function]} | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"mergeBranch": "master", | |||||
"name": "slb-1", | |||||
"type": "SHORT", | |||||
"name": "branch-11", | |||||
} | } | ||||
} | } | ||||
hasManyBranches={true} | hasManyBranches={true} |
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"name": "llb-1", | |||||
"type": "LONG", | |||||
"name": "branch-1", | |||||
}, | }, | ||||
"pullRequests": Array [], | "pullRequests": Array [], | ||||
}, | }, | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"name": "llb-2", | |||||
"type": "LONG", | |||||
"name": "branch-11", | |||||
}, | }, | ||||
"pullRequests": Array [], | "pullRequests": Array [], | ||||
}, | }, | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"name": "llb-3", | |||||
"type": "LONG", | |||||
"name": "branch-12", | |||||
}, | }, | ||||
"pullRequests": Array [], | "pullRequests": Array [], | ||||
}, | }, | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"mergeBranch": "master", | |||||
"name": "slb-1", | |||||
"type": "SHORT", | |||||
"name": "branch-2", | |||||
}, | }, | ||||
"pullRequests": Array [], | "pullRequests": Array [], | ||||
}, | }, | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"mergeBranch": "llb-1", | |||||
"name": "slb-2", | |||||
"type": "SHORT", | |||||
"name": "branch-3", | |||||
}, | }, | ||||
"pullRequests": Array [], | "pullRequests": Array [], | ||||
}, | }, | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"name": "llb-1", | |||||
"type": "LONG", | |||||
"name": "branch-1", | |||||
}, | }, | ||||
"pullRequests": Array [], | "pullRequests": Array [], | ||||
}, | }, | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"name": "llb-2", | |||||
"type": "LONG", | |||||
"name": "branch-11", | |||||
}, | }, | ||||
"pullRequests": Array [], | "pullRequests": Array [], | ||||
}, | }, | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"name": "llb-3", | |||||
"type": "LONG", | |||||
"name": "branch-12", | |||||
}, | }, | ||||
"pullRequests": Array [], | "pullRequests": Array [], | ||||
}, | }, | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"mergeBranch": "master", | |||||
"name": "slb-1", | |||||
"type": "SHORT", | |||||
"name": "branch-2", | |||||
}, | }, | ||||
"pullRequests": Array [], | "pullRequests": Array [], | ||||
}, | }, | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"mergeBranch": "llb-1", | |||||
"name": "slb-2", | |||||
"type": "SHORT", | |||||
"name": "branch-3", | |||||
}, | }, | ||||
"pullRequests": Array [], | "pullRequests": Array [], | ||||
}, | }, | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"mergeBranch": "master", | |||||
"name": "slb-1", | |||||
"type": "SHORT", | |||||
"name": "branch-11", | |||||
} | } | ||||
} | } | ||||
/> | /> |
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"name": "llb-1", | |||||
"type": "LONG", | |||||
"name": "branch-1", | |||||
} | } | ||||
} | } | ||||
component={ | component={ | ||||
"tags": Array [], | "tags": Array [], | ||||
} | } | ||||
} | } | ||||
key="branch-llb-1" | |||||
key="branch-branch-1" | |||||
onSelect={[MockFunction]} | onSelect={[MockFunction]} | ||||
selected={false} | selected={false} | ||||
setSelectedNode={[Function]} | setSelectedNode={[Function]} | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"name": "llb-2", | |||||
"type": "LONG", | |||||
"name": "branch-11", | |||||
} | } | ||||
} | } | ||||
component={ | component={ | ||||
"tags": Array [], | "tags": Array [], | ||||
} | } | ||||
} | } | ||||
key="branch-llb-2" | |||||
key="branch-branch-11" | |||||
onSelect={[MockFunction]} | onSelect={[MockFunction]} | ||||
selected={false} | |||||
selected={true} | |||||
setSelectedNode={[Function]} | setSelectedNode={[Function]} | ||||
/> | /> | ||||
<hr /> | <hr /> | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"name": "llb-3", | |||||
"type": "LONG", | |||||
"name": "branch-12", | |||||
} | } | ||||
} | } | ||||
component={ | component={ | ||||
"tags": Array [], | "tags": Array [], | ||||
} | } | ||||
} | } | ||||
key="branch-llb-3" | |||||
key="branch-branch-12" | |||||
onSelect={[MockFunction]} | onSelect={[MockFunction]} | ||||
selected={false} | selected={false} | ||||
setSelectedNode={[Function]} | setSelectedNode={[Function]} | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"mergeBranch": "master", | |||||
"name": "slb-1", | |||||
"type": "SHORT", | |||||
"name": "branch-2", | |||||
} | } | ||||
} | } | ||||
component={ | component={ | ||||
"tags": Array [], | "tags": Array [], | ||||
} | } | ||||
} | } | ||||
key="branch-slb-1" | |||||
key="branch-branch-2" | |||||
onSelect={[MockFunction]} | onSelect={[MockFunction]} | ||||
selected={true} | |||||
selected={false} | |||||
setSelectedNode={[Function]} | setSelectedNode={[Function]} | ||||
/> | /> | ||||
<hr /> | <hr /> | ||||
"analysisDate": "2018-01-01", | "analysisDate": "2018-01-01", | ||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"mergeBranch": "llb-1", | |||||
"name": "slb-2", | |||||
"type": "SHORT", | |||||
"name": "branch-3", | |||||
} | } | ||||
} | } | ||||
component={ | component={ | ||||
"tags": Array [], | "tags": Array [], | ||||
} | } | ||||
} | } | ||||
key="branch-slb-2" | |||||
key="branch-branch-3" | |||||
onSelect={[MockFunction]} | onSelect={[MockFunction]} | ||||
selected={false} | selected={false} | ||||
setSelectedNode={[Function]} | setSelectedNode={[Function]} |
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { Link } from 'react-router'; | import { Link } from 'react-router'; | ||||
import LongLivingBranchIcon from 'sonar-ui-common/components/icons/LongLivingBranchIcon'; | |||||
import BranchIcon from 'sonar-ui-common/components/icons/BranchIcon'; | |||||
import PullRequestIcon from 'sonar-ui-common/components/icons/PullRequestIcon'; | import PullRequestIcon from 'sonar-ui-common/components/icons/PullRequestIcon'; | ||||
import QualifierIcon from 'sonar-ui-common/components/icons/QualifierIcon'; | import QualifierIcon from 'sonar-ui-common/components/icons/QualifierIcon'; | ||||
import ShortLivingBranchIcon from 'sonar-ui-common/components/icons/ShortLivingBranchIcon'; | |||||
import Organization from '../../../components/shared/Organization'; | import Organization from '../../../components/shared/Organization'; | ||||
import { | |||||
getLongLivingBranchUrl, | |||||
getProjectUrl, | |||||
getPullRequestUrl, | |||||
getShortLivingBranchUrl | |||||
} from '../../../helpers/urls'; | |||||
import { getBranchUrl, getProjectUrl, getPullRequestUrl } from '../../../helpers/urls'; | |||||
import TaskType from './TaskType'; | import TaskType from './TaskType'; | ||||
interface Props { | interface Props { | ||||
return ( | return ( | ||||
<td> | <td> | ||||
{task.branchType === 'SHORT' && <ShortLivingBranchIcon className="little-spacer-right" />} | |||||
{task.branchType === 'LONG' && <LongLivingBranchIcon className="little-spacer-right" />} | |||||
{task.branch !== undefined && <BranchIcon className="little-spacer-right" />} | |||||
{task.pullRequest !== undefined && <PullRequestIcon className="little-spacer-right" />} | {task.pullRequest !== undefined && <PullRequestIcon className="little-spacer-right" />} | ||||
{!task.branchType && !task.pullRequest && task.componentQualifier && ( | |||||
{!task.branch && !task.pullRequest && task.componentQualifier && ( | |||||
<span className="little-spacer-right"> | <span className="little-spacer-right"> | ||||
<QualifierIcon qualifier={task.componentQualifier} /> | <QualifierIcon qualifier={task.componentQualifier} /> | ||||
</span> | </span> | ||||
function getTaskComponentUrl(componentKey: string, task: T.Task) { | function getTaskComponentUrl(componentKey: string, task: T.Task) { | ||||
if (task.branch) { | if (task.branch) { | ||||
if (task.branchType === 'SHORT') { | |||||
return getShortLivingBranchUrl(componentKey, task.branch); | |||||
} else if (task.branchType === 'LONG') { | |||||
return getLongLivingBranchUrl(componentKey, task.branch); | |||||
} | |||||
return getBranchUrl(componentKey, task.branch); | |||||
} else if (task.pullRequest) { | } else if (task.pullRequest) { | ||||
return getPullRequestUrl(componentKey, task.pullRequest); | return getPullRequestUrl(componentKey, task.pullRequest); | ||||
} | } |
}); | }); | ||||
it('renders correctly for branches and pullrequest', () => { | it('renders correctly for branches and pullrequest', () => { | ||||
expect( | |||||
shallow(<TaskComponent task={{ ...TASK, branch: 'feature', branchType: 'SHORT' }} />) | |||||
).toMatchSnapshot(); | |||||
expect( | |||||
shallow(<TaskComponent task={{ ...TASK, branch: 'branch-6.7', branchType: 'LONG' }} />) | |||||
).toMatchSnapshot(); | |||||
expect(shallow(<TaskComponent task={{ ...TASK, branch: 'feature' }} />)).toMatchSnapshot(); | |||||
expect(shallow(<TaskComponent task={{ ...TASK, branch: 'branch-6.7' }} />)).toMatchSnapshot(); | |||||
expect(shallow(<TaskComponent task={{ ...TASK, pullRequest: 'pr-89' }} />)).toMatchSnapshot(); | expect(shallow(<TaskComponent task={{ ...TASK, pullRequest: 'pr-89' }} />)).toMatchSnapshot(); | ||||
}); | }); |
exports[`renders correctly for branches and pullrequest 1`] = ` | exports[`renders correctly for branches and pullrequest 1`] = ` | ||||
<td> | <td> | ||||
<ShortLivingBranchIcon | |||||
<BranchIcon | |||||
className="little-spacer-right" | className="little-spacer-right" | ||||
/> | /> | ||||
<Connect(Organization) | <Connect(Organization) | ||||
exports[`renders correctly for branches and pullrequest 2`] = ` | exports[`renders correctly for branches and pullrequest 2`] = ` | ||||
<td> | <td> | ||||
<LongLivingBranchIcon | |||||
<BranchIcon | |||||
className="little-spacer-right" | className="little-spacer-right" | ||||
/> | /> | ||||
<Connect(Organization) | <Connect(Organization) |
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
*/ | */ | ||||
import { getChildren } from '../../../api/components'; | import { getChildren } from '../../../api/components'; | ||||
import { mockMainBranch, mockPullRequest } from '../../../helpers/testMocks'; | |||||
import { mockMainBranch, mockPullRequest } from '../../../helpers/mocks/branch-like'; | |||||
import { addComponent, addComponentChildren, getComponentBreadcrumbs } from '../bucket'; | import { addComponent, addComponentChildren, getComponentBreadcrumbs } from '../bucket'; | ||||
import { getCodeMetrics, loadMoreChildren, retrieveComponentChildren } from '../utils'; | import { getCodeMetrics, loadMoreChildren, retrieveComponentChildren } from '../utils'; | ||||
import { translate } from 'sonar-ui-common/helpers/l10n'; | import { translate } from 'sonar-ui-common/helpers/l10n'; | ||||
import A11ySkipTarget from '../../../app/components/a11y/A11ySkipTarget'; | import A11ySkipTarget from '../../../app/components/a11y/A11ySkipTarget'; | ||||
import Suggestions from '../../../app/components/embed-docs-modal/Suggestions'; | import Suggestions from '../../../app/components/embed-docs-modal/Suggestions'; | ||||
import { isPullRequest, isSameBranchLike, isShortLivingBranch } from '../../../helpers/branches'; | |||||
import { isPullRequest, isSameBranchLike } from '../../../helpers/branch-like'; | |||||
import { getCodeUrl, getProjectUrl } from '../../../helpers/urls'; | import { getCodeUrl, getProjectUrl } from '../../../helpers/urls'; | ||||
import { fetchBranchStatus, fetchMetrics } from '../../../store/rootActions'; | import { fetchBranchStatus, fetchMetrics } from '../../../store/rootActions'; | ||||
import { getMetrics } from '../../../store/rootReducer'; | import { getMetrics } from '../../../store/rootReducer'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import { addComponent, addComponentBreadcrumbs, clearBucket } from '../bucket'; | import { addComponent, addComponentBreadcrumbs, clearBucket } from '../bucket'; | ||||
import '../code.css'; | import '../code.css'; | ||||
import { loadMoreChildren, retrieveComponent, retrieveComponentChildren } from '../utils'; | import { loadMoreChildren, retrieveComponent, retrieveComponentChildren } from '../utils'; | ||||
} | } | ||||
interface DispatchToProps { | interface DispatchToProps { | ||||
fetchBranchStatus: (branchLike: T.BranchLike, projectKey: string) => Promise<void>; | |||||
fetchBranchStatus: (branchLike: BranchLike, projectKey: string) => Promise<void>; | |||||
fetchMetrics: () => void; | fetchMetrics: () => void; | ||||
} | } | ||||
interface OwnProps { | interface OwnProps { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
component: T.Component; | component: T.Component; | ||||
location: Pick<Location, 'query'>; | location: Pick<Location, 'query'>; | ||||
router: Pick<InjectedRouter, 'push'>; | router: Pick<InjectedRouter, 'push'>; | ||||
refreshBranchStatus = () => { | refreshBranchStatus = () => { | ||||
const { branchLike, component } = this.props; | const { branchLike, component } = this.props; | ||||
if (branchLike && component && (isPullRequest(branchLike) || isShortLivingBranch(branchLike))) { | |||||
if (branchLike && component && isPullRequest(branchLike)) { | |||||
this.props.fetchBranchStatus(branchLike, component.key); | this.props.fetchBranchStatus(branchLike, component.key); | ||||
} | } | ||||
}; | }; |
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import ComponentName from './ComponentName'; | import ComponentName from './ComponentName'; | ||||
interface Props { | interface Props { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
breadcrumbs: T.Breadcrumb[]; | breadcrumbs: T.Breadcrumb[]; | ||||
rootComponent: T.ComponentMeasure; | rootComponent: T.ComponentMeasure; | ||||
} | } |
import * as React from 'react'; | import * as React from 'react'; | ||||
import { withScrollTo } from '../../../components/hoc/withScrollTo'; | import { withScrollTo } from '../../../components/hoc/withScrollTo'; | ||||
import { WorkspaceContext } from '../../../components/workspace/context'; | import { WorkspaceContext } from '../../../components/workspace/context'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import ComponentMeasure from './ComponentMeasure'; | import ComponentMeasure from './ComponentMeasure'; | ||||
import ComponentName from './ComponentName'; | import ComponentName from './ComponentName'; | ||||
import ComponentPin from './ComponentPin'; | import ComponentPin from './ComponentPin'; | ||||
interface Props { | interface Props { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
canBePinned?: boolean; | canBePinned?: boolean; | ||||
canBrowse?: boolean; | canBrowse?: boolean; | ||||
component: T.ComponentMeasure; | component: T.ComponentMeasure; |
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { Link } from 'react-router'; | import { Link } from 'react-router'; | ||||
import LongLivingBranchIcon from 'sonar-ui-common/components/icons/LongLivingBranchIcon'; | |||||
import BranchIcon from 'sonar-ui-common/components/icons/BranchIcon'; | |||||
import QualifierIcon from 'sonar-ui-common/components/icons/QualifierIcon'; | import QualifierIcon from 'sonar-ui-common/components/icons/QualifierIcon'; | ||||
import { translate } from 'sonar-ui-common/helpers/l10n'; | import { translate } from 'sonar-ui-common/helpers/l10n'; | ||||
import { colors } from '../../../app/theme'; | import { colors } from '../../../app/theme'; | ||||
import { getBranchLikeQuery } from '../../../helpers/branches'; | |||||
import { getBranchLikeQuery } from '../../../helpers/branch-like'; | |||||
import { BranchLike } from '../../../types/branch-like'; | |||||
export function getTooltip(component: T.ComponentMeasure) { | export function getTooltip(component: T.ComponentMeasure) { | ||||
const isFile = component.qualifier === 'FIL' || component.qualifier === 'UTS'; | const isFile = component.qualifier === 'FIL' || component.qualifier === 'UTS'; | ||||
} | } | ||||
export interface Props { | export interface Props { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
canBrowse?: boolean; | canBrowse?: boolean; | ||||
component: T.ComponentMeasure; | component: T.ComponentMeasure; | ||||
previous?: T.ComponentMeasure; | previous?: T.ComponentMeasure; | ||||
</span> | </span> | ||||
{component.branch ? ( | {component.branch ? ( | ||||
<span className="text-ellipsis spacer-left"> | <span className="text-ellipsis spacer-left"> | ||||
<LongLivingBranchIcon className="little-spacer-right" /> | |||||
<BranchIcon className="little-spacer-right" /> | |||||
<span className="note">{component.branch}</span> | <span className="note">{component.branch}</span> | ||||
</span> | </span> | ||||
) : ( | ) : ( |
import PinIcon from 'sonar-ui-common/components/icons/PinIcon'; | import PinIcon from 'sonar-ui-common/components/icons/PinIcon'; | ||||
import { translate } from 'sonar-ui-common/helpers/l10n'; | import { translate } from 'sonar-ui-common/helpers/l10n'; | ||||
import { WorkspaceContextShape } from '../../../components/workspace/context'; | import { WorkspaceContextShape } from '../../../components/workspace/context'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
interface Props { | interface Props { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
component: T.ComponentMeasure; | component: T.ComponentMeasure; | ||||
openComponent: WorkspaceContextShape['openComponent']; | openComponent: WorkspaceContextShape['openComponent']; | ||||
} | } |
import { intersection } from 'lodash'; | import { intersection } from 'lodash'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import withKeyboardNavigation from '../../../components/hoc/withKeyboardNavigation'; | import withKeyboardNavigation from '../../../components/hoc/withKeyboardNavigation'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import { getCodeMetrics } from '../utils'; | import { getCodeMetrics } from '../utils'; | ||||
import Component from './Component'; | import Component from './Component'; | ||||
import ComponentsEmpty from './ComponentsEmpty'; | import ComponentsEmpty from './ComponentsEmpty'; | ||||
interface Props { | interface Props { | ||||
baseComponent?: T.ComponentMeasure; | baseComponent?: T.ComponentMeasure; | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
components: T.ComponentMeasure[]; | components: T.ComponentMeasure[]; | ||||
metrics: T.Dict<T.Metric>; | metrics: T.Dict<T.Metric>; | ||||
rootComponent: T.ComponentMeasure; | rootComponent: T.ComponentMeasure; |
import { translate } from 'sonar-ui-common/helpers/l10n'; | import { translate } from 'sonar-ui-common/helpers/l10n'; | ||||
import { getTree } from '../../../api/components'; | import { getTree } from '../../../api/components'; | ||||
import { Location, Router, withRouter } from '../../../components/hoc/withRouter'; | import { Location, Router, withRouter } from '../../../components/hoc/withRouter'; | ||||
import { getBranchLikeQuery } from '../../../helpers/branches'; | |||||
import { getBranchLikeQuery } from '../../../helpers/branch-like'; | |||||
import { BranchLike } from '../../../types/branch-like'; | |||||
interface Props { | interface Props { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
component: T.ComponentMeasure; | component: T.ComponentMeasure; | ||||
location: Location; | location: Location; | ||||
onSearchClear: () => void; | onSearchClear: () => void; |
import { scrollToElement } from 'sonar-ui-common/helpers/scrolling'; | import { scrollToElement } from 'sonar-ui-common/helpers/scrolling'; | ||||
import withKeyboardNavigation from '../../../components/hoc/withKeyboardNavigation'; | import withKeyboardNavigation from '../../../components/hoc/withKeyboardNavigation'; | ||||
import SourceViewer from '../../../components/SourceViewer/SourceViewer'; | import SourceViewer from '../../../components/SourceViewer/SourceViewer'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
interface Props { | interface Props { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
component: string; | component: string; | ||||
componentMeasures: T.Measure[] | undefined; | componentMeasures: T.Measure[] | undefined; | ||||
location: Pick<Location, 'query'>; | location: Pick<Location, 'query'>; |
import { shallow } from 'enzyme'; | import { shallow } from 'enzyme'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; | import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; | ||||
import { mockIssue, mockPullRequest, mockRouter } from '../../../../helpers/testMocks'; | |||||
import { mockPullRequest } from '../../../../helpers/mocks/branch-like'; | |||||
import { mockIssue, mockRouter } from '../../../../helpers/testMocks'; | |||||
import { retrieveComponent } from '../../utils'; | import { retrieveComponent } from '../../utils'; | ||||
import { App } from '../App'; | import { App } from '../App'; | ||||
*/ | */ | ||||
import { shallow } from 'enzyme'; | import { shallow } from 'enzyme'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { mockComponentMeasure, mockMainBranch } from '../../../../helpers/testMocks'; | |||||
import { mockMainBranch } from '../../../../helpers/mocks/branch-like'; | |||||
import { mockComponentMeasure } from '../../../../helpers/testMocks'; | |||||
import ComponentName, { getTooltip, mostCommonPrefix, Props } from '../ComponentName'; | import ComponentName, { getTooltip, mostCommonPrefix, Props } from '../ComponentName'; | ||||
describe('#getTooltip', () => { | describe('#getTooltip', () => { |
*/ | */ | ||||
import { shallow } from 'enzyme'; | import { shallow } from 'enzyme'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { mockBranch } from '../../../../helpers/mocks/branch-like'; | |||||
import { Components } from '../Components'; | import { Components } from '../Components'; | ||||
const COMPONENT = { key: 'foo', name: 'Foo', qualifier: 'TRK' }; | const COMPONENT = { key: 'foo', name: 'Foo', qualifier: 'TRK' }; | ||||
const PORTFOLIO = { key: 'bar', name: 'Bar', qualifier: 'VW' }; | const PORTFOLIO = { key: 'bar', name: 'Bar', qualifier: 'VW' }; | ||||
const METRICS = { coverage: { id: '1', key: 'coverage', type: 'PERCENT', name: 'Coverage' } }; | const METRICS = { coverage: { id: '1', key: 'coverage', type: 'PERCENT', name: 'Coverage' } }; | ||||
const BRANCH: T.ShortLivingBranch = { | |||||
isMain: false, | |||||
excludedFromPurge: true, | |||||
name: 'feature', | |||||
mergeBranch: 'master', | |||||
type: 'SHORT' | |||||
}; | |||||
const BRANCH = mockBranch({ name: 'feature' }); | |||||
it('renders correctly', () => { | it('renders correctly', () => { | ||||
expect( | expect( |
<span | <span | ||||
className="text-ellipsis spacer-left" | className="text-ellipsis spacer-left" | ||||
> | > | ||||
<LongLivingBranchIcon | |||||
<BranchIcon | |||||
className="little-spacer-right" | className="little-spacer-right" | ||||
/> | /> | ||||
<span | <span | ||||
<span | <span | ||||
className="text-ellipsis spacer-left" | className="text-ellipsis spacer-left" | ||||
> | > | ||||
<LongLivingBranchIcon | |||||
<BranchIcon | |||||
className="little-spacer-right" | className="little-spacer-right" | ||||
/> | /> | ||||
<span | <span |
} | } | ||||
} | } | ||||
canBePinned={true} | canBePinned={true} | ||||
metrics={Array []} | |||||
metrics={ | |||||
Array [ | |||||
"coverage", | |||||
] | |||||
} | |||||
rootComponent={ | rootComponent={ | ||||
Object { | Object { | ||||
"key": "foo", | "key": "foo", | ||||
<withScrollTo(Component) | <withScrollTo(Component) | ||||
branchLike={ | branchLike={ | ||||
Object { | Object { | ||||
"analysisDate": "2018-01-01", | |||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"mergeBranch": "master", | |||||
"name": "feature", | "name": "feature", | ||||
"type": "SHORT", | |||||
} | } | ||||
} | } | ||||
canBePinned={true} | canBePinned={true} | ||||
} | } | ||||
} | } | ||||
key="foo" | key="foo" | ||||
metrics={Array []} | |||||
metrics={ | |||||
Array [ | |||||
Object { | |||||
"id": "1", | |||||
"key": "coverage", | |||||
"name": "Coverage", | |||||
"type": "PERCENT", | |||||
}, | |||||
] | |||||
} | |||||
rootComponent={ | rootComponent={ | ||||
Object { | Object { | ||||
"key": "foo", | "key": "foo", | ||||
</td> | </td> | ||||
<td | <td | ||||
colSpan={4} | |||||
colSpan={5} | |||||
> | > | ||||
</td> | </td> | ||||
<withScrollTo(Component) | <withScrollTo(Component) | ||||
branchLike={ | branchLike={ | ||||
Object { | Object { | ||||
"analysisDate": "2018-01-01", | |||||
"excludedFromPurge": true, | "excludedFromPurge": true, | ||||
"isMain": false, | "isMain": false, | ||||
"mergeBranch": "master", | |||||
"name": "feature", | "name": "feature", | ||||
"type": "SHORT", | |||||
} | } | ||||
} | } | ||||
canBePinned={true} | canBePinned={true} | ||||
} | } | ||||
} | } | ||||
key="foo" | key="foo" | ||||
metrics={Array []} | |||||
metrics={ | |||||
Array [ | |||||
Object { | |||||
"id": "1", | |||||
"key": "coverage", | |||||
"name": "Coverage", | |||||
"type": "PERCENT", | |||||
}, | |||||
] | |||||
} | |||||
rootComponent={ | rootComponent={ | ||||
Object { | Object { | ||||
"key": "foo", | "key": "foo", | ||||
colSpan={3} | colSpan={3} | ||||
/> | /> | ||||
<td | <td | ||||
colSpan={4} | |||||
colSpan={5} | |||||
/> | /> | ||||
</tr> | </tr> | ||||
</tbody> | </tbody> |
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
*/ | */ | ||||
import { getBreadcrumbs, getChildren, getComponent } from '../../api/components'; | import { getBreadcrumbs, getChildren, getComponent } from '../../api/components'; | ||||
import { getBranchLikeQuery, isPullRequest, isShortLivingBranch } from '../../helpers/branches'; | |||||
import { getBranchLikeQuery, isPullRequest } from '../../helpers/branch-like'; | |||||
import { BranchLike } from '../../types/branch-like'; | |||||
import { | import { | ||||
addComponent, | addComponent, | ||||
addComponentBreadcrumbs, | addComponentBreadcrumbs, | ||||
}; | }; | ||||
} | } | ||||
export function showLeakMeasure(branchLike?: T.BranchLike) { | |||||
return isShortLivingBranch(branchLike) || isPullRequest(branchLike); | |||||
export function showLeakMeasure(branchLike?: BranchLike) { | |||||
return isPullRequest(branchLike); | |||||
} | } | ||||
function skipRootDir(breadcrumbs: T.ComponentMeasure[]) { | function skipRootDir(breadcrumbs: T.ComponentMeasure[]) { | ||||
export function getCodeMetrics( | export function getCodeMetrics( | ||||
qualifier: string, | qualifier: string, | ||||
branchLike?: T.BranchLike, | |||||
branchLike?: BranchLike, | |||||
options: { includeQGStatus?: boolean } = {} | options: { includeQGStatus?: boolean } = {} | ||||
) { | ) { | ||||
if (['VW', 'SVW'].includes(qualifier)) { | if (['VW', 'SVW'].includes(qualifier)) { | ||||
return [...METRICS]; | return [...METRICS]; | ||||
} | } | ||||
function retrieveComponentBase(componentKey: string, qualifier: string, branchLike?: T.BranchLike) { | |||||
function retrieveComponentBase(componentKey: string, qualifier: string, branchLike?: BranchLike) { | |||||
const existing = getComponentFromBucket(componentKey); | const existing = getComponentFromBucket(componentKey); | ||||
if (existing) { | if (existing) { | ||||
return Promise.resolve(existing); | return Promise.resolve(existing); | ||||
export function retrieveComponentChildren( | export function retrieveComponentChildren( | ||||
componentKey: string, | componentKey: string, | ||||
qualifier: string, | qualifier: string, | ||||
branchLike?: T.BranchLike | |||||
branchLike?: BranchLike | |||||
): Promise<{ components: T.ComponentMeasure[]; page: number; total: number }> { | ): Promise<{ components: T.ComponentMeasure[]; page: number; total: number }> { | ||||
const existing = getComponentChildren(componentKey); | const existing = getComponentChildren(componentKey); | ||||
if (existing) { | if (existing) { | ||||
function retrieveComponentBreadcrumbs( | function retrieveComponentBreadcrumbs( | ||||
component: string, | component: string, | ||||
branchLike?: T.BranchLike | |||||
branchLike?: BranchLike | |||||
): Promise<T.Breadcrumb[]> { | ): Promise<T.Breadcrumb[]> { | ||||
const existing = getComponentBreadcrumbs(component); | const existing = getComponentBreadcrumbs(component); | ||||
if (existing) { | if (existing) { | ||||
export function retrieveComponent( | export function retrieveComponent( | ||||
componentKey: string, | componentKey: string, | ||||
qualifier: string, | qualifier: string, | ||||
branchLike?: T.BranchLike | |||||
branchLike?: BranchLike | |||||
): Promise<{ | ): Promise<{ | ||||
breadcrumbs: T.Breadcrumb[]; | breadcrumbs: T.Breadcrumb[]; | ||||
component: T.ComponentMeasure; | component: T.ComponentMeasure; | ||||
componentKey: string, | componentKey: string, | ||||
page: number, | page: number, | ||||
qualifier: string, | qualifier: string, | ||||
branchLike?: T.BranchLike | |||||
branchLike?: BranchLike | |||||
): Promise<Children> { | ): Promise<Children> { | ||||
const metrics = getCodeMetrics(qualifier, branchLike, { includeQGStatus: true }); | const metrics = getCodeMetrics(qualifier, branchLike, { includeQGStatus: true }); | ||||
import ScreenPositionHelper from '../../../components/common/ScreenPositionHelper'; | import ScreenPositionHelper from '../../../components/common/ScreenPositionHelper'; | ||||
import { enhanceMeasure } from '../../../components/measure/utils'; | import { enhanceMeasure } from '../../../components/measure/utils'; | ||||
import '../../../components/search-navigator.css'; | import '../../../components/search-navigator.css'; | ||||
import { | |||||
getBranchLikeQuery, | |||||
isPullRequest, | |||||
isSameBranchLike, | |||||
isShortLivingBranch | |||||
} from '../../../helpers/branches'; | |||||
import { getBranchLikeQuery, isPullRequest, isSameBranchLike } from '../../../helpers/branch-like'; | |||||
import { getLeakPeriod } from '../../../helpers/periods'; | import { getLeakPeriod } from '../../../helpers/periods'; | ||||
import { fetchBranchStatus } from '../../../store/rootActions'; | import { fetchBranchStatus } from '../../../store/rootActions'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import Sidebar from '../sidebar/Sidebar'; | import Sidebar from '../sidebar/Sidebar'; | ||||
import '../style.css'; | import '../style.css'; | ||||
import { | import { | ||||
import MeasuresEmpty from './MeasuresEmpty'; | import MeasuresEmpty from './MeasuresEmpty'; | ||||
interface Props extends WithRouterProps { | interface Props extends WithRouterProps { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
component: T.ComponentMeasure; | component: T.ComponentMeasure; | ||||
fetchBranchStatus: (branchLike: T.BranchLike, projectKey: string) => Promise<void>; | |||||
fetchBranchStatus: (branchLike: BranchLike, projectKey: string) => Promise<void>; | |||||
} | } | ||||
interface State { | interface State { | ||||
refreshBranchStatus = () => { | refreshBranchStatus = () => { | ||||
const { branchLike, component } = this.props; | const { branchLike, component } = this.props; | ||||
if (branchLike && component && (isPullRequest(branchLike) || isShortLivingBranch(branchLike))) { | |||||
if (branchLike && component && isPullRequest(branchLike)) { | |||||
this.props.fetchBranchStatus(branchLike, component.key); | this.props.fetchBranchStatus(branchLike, component.key); | ||||
} | } | ||||
}; | }; | ||||
} | } | ||||
const hideDrilldown = | const hideDrilldown = | ||||
(isShortLivingBranch(branchLike) || isPullRequest(branchLike)) && | |||||
isPullRequest(branchLike) && | |||||
(metric.key === 'coverage' || metric.key === 'duplicated_lines_density'); | (metric.key === 'coverage' || metric.key === 'duplicated_lines_density'); | ||||
if (hideDrilldown) { | if (hideDrilldown) { |
import * as key from 'keymaster'; | import * as key from 'keymaster'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { getBreadcrumbs } from '../../../api/components'; | import { getBreadcrumbs } from '../../../api/components'; | ||||
import { getBranchLikeQuery, isSameBranchLike } from '../../../helpers/branches'; | |||||
import { getBranchLikeQuery, isSameBranchLike } from '../../../helpers/branch-like'; | |||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import Breadcrumb from './Breadcrumb'; | import Breadcrumb from './Breadcrumb'; | ||||
interface Props { | interface Props { | ||||
backToFirst: boolean; | backToFirst: boolean; | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
className?: string; | className?: string; | ||||
component: T.ComponentMeasure; | component: T.ComponentMeasure; | ||||
handleSelect: (component: string) => void; | handleSelect: (component: string) => void; |
import { getMeasures } from '../../../api/measures'; | import { getMeasures } from '../../../api/measures'; | ||||
import A11ySkipTarget from '../../../app/components/a11y/A11ySkipTarget'; | import A11ySkipTarget from '../../../app/components/a11y/A11ySkipTarget'; | ||||
import SourceViewer from '../../../components/SourceViewer/SourceViewer'; | import SourceViewer from '../../../components/SourceViewer/SourceViewer'; | ||||
import { getBranchLikeQuery, isSameBranchLike } from '../../../helpers/branches'; | |||||
import { getBranchLikeQuery, isSameBranchLike } from '../../../helpers/branch-like'; | |||||
import { getPeriodValue, isDiffMetric } from '../../../helpers/measures'; | import { getPeriodValue, isDiffMetric } from '../../../helpers/measures'; | ||||
import { getProjectUrl } from '../../../helpers/urls'; | import { getProjectUrl } from '../../../helpers/urls'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import { complementary } from '../config/complementary'; | import { complementary } from '../config/complementary'; | ||||
import FilesView from '../drilldown/FilesView'; | import FilesView from '../drilldown/FilesView'; | ||||
import TreeMapView from '../drilldown/TreeMapView'; | import TreeMapView from '../drilldown/TreeMapView'; | ||||
import MeasureViewSelect from './MeasureViewSelect'; | import MeasureViewSelect from './MeasureViewSelect'; | ||||
interface Props { | interface Props { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
leakPeriod?: T.Period; | leakPeriod?: T.Period; | ||||
requestedMetric: Pick<T.Metric, 'key' | 'direction'>; | requestedMetric: Pick<T.Metric, 'key' | 'direction'>; | ||||
metrics: T.Dict<T.Metric>; | metrics: T.Dict<T.Metric>; |
import Measure from '../../../components/measure/Measure'; | import Measure from '../../../components/measure/Measure'; | ||||
import { isDiffMetric } from '../../../helpers/measures'; | import { isDiffMetric } from '../../../helpers/measures'; | ||||
import { getMeasureHistoryUrl } from '../../../helpers/urls'; | import { getMeasureHistoryUrl } from '../../../helpers/urls'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import { hasFullMeasures } from '../utils'; | import { hasFullMeasures } from '../utils'; | ||||
import LeakPeriodLegend from './LeakPeriodLegend'; | import LeakPeriodLegend from './LeakPeriodLegend'; | ||||
interface Props { | interface Props { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
component: T.ComponentMeasure; | component: T.ComponentMeasure; | ||||
leakPeriod?: T.Period; | leakPeriod?: T.Period; | ||||
measureValue?: string; | measureValue?: string; |
import { getComponentLeaves } from '../../../api/components'; | import { getComponentLeaves } from '../../../api/components'; | ||||
import A11ySkipTarget from '../../../app/components/a11y/A11ySkipTarget'; | import A11ySkipTarget from '../../../app/components/a11y/A11ySkipTarget'; | ||||
import SourceViewer from '../../../components/SourceViewer/SourceViewer'; | import SourceViewer from '../../../components/SourceViewer/SourceViewer'; | ||||
import { getBranchLikeQuery, isSameBranchLike } from '../../../helpers/branches'; | |||||
import { getBranchLikeQuery, isSameBranchLike } from '../../../helpers/branch-like'; | |||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import BubbleChart from '../drilldown/BubbleChart'; | import BubbleChart from '../drilldown/BubbleChart'; | ||||
import { enhanceComponent, getBubbleMetrics, hasFullMeasures, isFileType } from '../utils'; | import { enhanceComponent, getBubbleMetrics, hasFullMeasures, isFileType } from '../utils'; | ||||
import Breadcrumbs from './Breadcrumbs'; | import Breadcrumbs from './Breadcrumbs'; | ||||
import MeasureContentHeader from './MeasureContentHeader'; | import MeasureContentHeader from './MeasureContentHeader'; | ||||
interface Props { | interface Props { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
className?: string; | className?: string; | ||||
component: T.ComponentMeasure; | component: T.ComponentMeasure; | ||||
domain: string; | domain: string; |
import * as React from 'react'; | import * as React from 'react'; | ||||
import { InjectedRouter } from 'react-router'; | import { InjectedRouter } from 'react-router'; | ||||
import { getComponentShow } from '../../../api/components'; | import { getComponentShow } from '../../../api/components'; | ||||
import { getBranchLikeQuery, isSameBranchLike } from '../../../helpers/branches'; | |||||
import { getBranchLikeQuery, isSameBranchLike } from '../../../helpers/branch-like'; | |||||
import { getProjectUrl } from '../../../helpers/urls'; | import { getProjectUrl } from '../../../helpers/urls'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import { isViewType, Query } from '../utils'; | import { isViewType, Query } from '../utils'; | ||||
import MeasureOverview from './MeasureOverview'; | import MeasureOverview from './MeasureOverview'; | ||||
interface Props { | interface Props { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
className?: string; | className?: string; | ||||
domain: string; | domain: string; | ||||
leakPeriod?: T.Period; | leakPeriod?: T.Period; |
import * as React from 'react'; | import * as React from 'react'; | ||||
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; | import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; | ||||
import { getMeasuresAndMeta } from '../../../../api/measures'; | import { getMeasuresAndMeta } from '../../../../api/measures'; | ||||
import { | |||||
mockComponent, | |||||
mockIssue, | |||||
mockLocation, | |||||
mockMainBranch, | |||||
mockPullRequest, | |||||
mockRouter | |||||
} from '../../../../helpers/testMocks'; | |||||
import { mockMainBranch, mockPullRequest } from '../../../../helpers/mocks/branch-like'; | |||||
import { mockComponent, mockIssue, mockLocation, mockRouter } from '../../../../helpers/testMocks'; | |||||
import { App } from '../App'; | import { App } from '../App'; | ||||
jest.mock('../../../../api/metrics', () => ({ | jest.mock('../../../../api/metrics', () => ({ |
*/ | */ | ||||
import { shallow } from 'enzyme'; | import { shallow } from 'enzyme'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { mockBranch } from '../../../../helpers/mocks/branch-like'; | |||||
import MeasureHeader from '../MeasureHeader'; | import MeasureHeader from '../MeasureHeader'; | ||||
const METRIC = { | const METRIC = { | ||||
).toMatchSnapshot(); | ).toMatchSnapshot(); | ||||
}); | }); | ||||
it('should render with long living branch', () => { | |||||
const longBranch: T.LongLivingBranch = { | |||||
isMain: false, | |||||
excludedFromPurge: true, | |||||
name: 'branch-6.7', | |||||
type: 'LONG' | |||||
}; | |||||
expect( | |||||
shallow(<MeasureHeader branchLike={longBranch} {...PROPS} />).find('Link') | |||||
).toMatchSnapshot(); | |||||
}); | |||||
it('should render with short living branch', () => { | |||||
const shortBranch: T.ShortLivingBranch = { | |||||
isMain: false, | |||||
excludedFromPurge: true, | |||||
name: 'feature', | |||||
mergeBranch: 'master', | |||||
type: 'SHORT' | |||||
}; | |||||
it('should render with a branch', () => { | |||||
const branch = mockBranch({ name: 'feature' }); | |||||
expect( | expect( | ||||
shallow( | shallow( | ||||
<MeasureHeader | <MeasureHeader | ||||
{...PROPS} | {...PROPS} | ||||
branchLike={shortBranch} | |||||
branchLike={branch} | |||||
measureValue={LEAK_MEASURE} | measureValue={LEAK_MEASURE} | ||||
metric={LEAK_METRIC} | metric={LEAK_METRIC} | ||||
/> | /> |
</div> | </div> | ||||
`; | `; | ||||
exports[`should render with long living branch 1`] = ` | |||||
<Link | |||||
className="js-show-history spacer-left button button-small" | |||||
onlyActiveOnIndex={false} | |||||
style={Object {}} | |||||
to={ | |||||
Object { | |||||
"pathname": "/project/activity", | |||||
"query": Object { | |||||
"branch": "branch-6.7", | |||||
"custom_metrics": "reliability_rating", | |||||
"graph": "custom", | |||||
"id": "foo", | |||||
}, | |||||
} | |||||
} | |||||
> | |||||
<HistoryIcon /> | |||||
</Link> | |||||
`; | |||||
exports[`should render with short living branch 1`] = ` | |||||
exports[`should render with a branch 1`] = ` | |||||
<div | <div | ||||
className="measure-details-header big-spacer-bottom" | className="measure-details-header big-spacer-bottom" | ||||
> | > | ||||
> | > | ||||
<strong> | <strong> | ||||
<Measure | <Measure | ||||
className="leak-box" | |||||
metricKey="new_reliability_rating" | metricKey="new_reliability_rating" | ||||
metricType="RATING" | metricType="RATING" | ||||
value="3.0" | value="3.0" | ||||
</div> | </div> | ||||
<div | <div | ||||
className="measure-details-primary-actions" | className="measure-details-primary-actions" | ||||
/> | |||||
> | |||||
<InjectIntl(LeakPeriodLegend) | |||||
className="spacer-left" | |||||
component={ | |||||
Object { | |||||
"key": "foo", | |||||
"name": "Foo", | |||||
"qualifier": "TRK", | |||||
} | |||||
} | |||||
period={ | |||||
Object { | |||||
"date": "2017-05-16T13:50:02+0200", | |||||
"index": 1, | |||||
"mode": "previous_version", | |||||
"parameter": "6,4", | |||||
} | |||||
} | |||||
/> | |||||
</div> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
`; | `; |
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { Link } from 'react-router'; | import { Link } from 'react-router'; | ||||
import BranchIcon from 'sonar-ui-common/components/icons/BranchIcon'; | |||||
import LinkIcon from 'sonar-ui-common/components/icons/LinkIcon'; | import LinkIcon from 'sonar-ui-common/components/icons/LinkIcon'; | ||||
import LongLivingBranchIcon from 'sonar-ui-common/components/icons/LongLivingBranchIcon'; | |||||
import QualifierIcon from 'sonar-ui-common/components/icons/QualifierIcon'; | import QualifierIcon from 'sonar-ui-common/components/icons/QualifierIcon'; | ||||
import { translate } from 'sonar-ui-common/helpers/l10n'; | import { translate } from 'sonar-ui-common/helpers/l10n'; | ||||
import { splitPath } from 'sonar-ui-common/helpers/path'; | import { splitPath } from 'sonar-ui-common/helpers/path'; | ||||
getComponentDrilldownUrlWithSelection, | getComponentDrilldownUrlWithSelection, | ||||
getProjectUrl | getProjectUrl | ||||
} from '../../../helpers/urls'; | } from '../../../helpers/urls'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import { View } from '../utils'; | import { View } from '../utils'; | ||||
interface Props { | interface Props { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
component: T.ComponentMeasureEnhanced; | component: T.ComponentMeasureEnhanced; | ||||
onClick: (component: string) => void; | onClick: (component: string) => void; | ||||
metric: T.Metric; | metric: T.Metric; | ||||
<> | <> | ||||
{component.branch ? ( | {component.branch ? ( | ||||
<> | <> | ||||
<LongLivingBranchIcon className="spacer-left little-spacer-right" /> | |||||
<BranchIcon className="spacer-left little-spacer-right" /> | |||||
<span className="note">{component.branch}</span> | <span className="note">{component.branch}</span> | ||||
</> | </> | ||||
) : ( | ) : ( |
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { getLocalizedMetricName } from 'sonar-ui-common/helpers/l10n'; | import { getLocalizedMetricName } from 'sonar-ui-common/helpers/l10n'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import { complementary } from '../config/complementary'; | import { complementary } from '../config/complementary'; | ||||
import { View } from '../utils'; | import { View } from '../utils'; | ||||
import ComponentsListRow from './ComponentsListRow'; | import ComponentsListRow from './ComponentsListRow'; | ||||
import EmptyResult from './EmptyResult'; | import EmptyResult from './EmptyResult'; | ||||
interface Props { | interface Props { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
components: T.ComponentMeasureEnhanced[]; | components: T.ComponentMeasureEnhanced[]; | ||||
onClick: (component: string) => void; | onClick: (component: string) => void; | ||||
metric: T.Metric; | metric: T.Metric; |
*/ | */ | ||||
import * as classNames from 'classnames'; | import * as classNames from 'classnames'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import { View } from '../utils'; | import { View } from '../utils'; | ||||
import ComponentCell from './ComponentCell'; | import ComponentCell from './ComponentCell'; | ||||
import MeasureCell from './MeasureCell'; | import MeasureCell from './MeasureCell'; | ||||
interface Props { | interface Props { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
component: T.ComponentMeasureEnhanced; | component: T.ComponentMeasureEnhanced; | ||||
isSelected: boolean; | isSelected: boolean; | ||||
onClick: (component: string) => void; | onClick: (component: string) => void; |
import { formatMeasure } from 'sonar-ui-common/helpers/measures'; | import { formatMeasure } from 'sonar-ui-common/helpers/measures'; | ||||
import { scrollToElement } from 'sonar-ui-common/helpers/scrolling'; | import { scrollToElement } from 'sonar-ui-common/helpers/scrolling'; | ||||
import { isDiffMetric, isPeriodBestValue } from '../../../helpers/measures'; | import { isDiffMetric, isPeriodBestValue } from '../../../helpers/measures'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import { View } from '../utils'; | import { View } from '../utils'; | ||||
import ComponentsList from './ComponentsList'; | import ComponentsList from './ComponentsList'; | ||||
interface Props { | interface Props { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
components: T.ComponentMeasureEnhanced[]; | components: T.ComponentMeasureEnhanced[]; | ||||
defaultShowBestMeasures: boolean; | defaultShowBestMeasures: boolean; | ||||
fetchMore: () => void; | fetchMore: () => void; |
import { colors } from '../../../app/theme'; | import { colors } from '../../../app/theme'; | ||||
import ColorBoxLegend from '../../../components/charts/ColorBoxLegend'; | import ColorBoxLegend from '../../../components/charts/ColorBoxLegend'; | ||||
import { isDiffMetric } from '../../../helpers/measures'; | import { isDiffMetric } from '../../../helpers/measures'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import EmptyResult from './EmptyResult'; | import EmptyResult from './EmptyResult'; | ||||
interface Props { | interface Props { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
components: T.ComponentMeasureEnhanced[]; | components: T.ComponentMeasureEnhanced[]; | ||||
handleSelect: (component: string) => void; | handleSelect: (component: string) => void; | ||||
metric: T.Metric; | metric: T.Metric; |
import { getLocalizedMetricName } from 'sonar-ui-common/helpers/l10n'; | import { getLocalizedMetricName } from 'sonar-ui-common/helpers/l10n'; | ||||
import { cleanQuery, parseAsString, serializeString } from 'sonar-ui-common/helpers/query'; | import { cleanQuery, parseAsString, serializeString } from 'sonar-ui-common/helpers/query'; | ||||
import { enhanceMeasure } from '../../components/measure/utils'; | import { enhanceMeasure } from '../../components/measure/utils'; | ||||
import { | |||||
isLongLivingBranch, | |||||
isMainBranch, | |||||
isPullRequest, | |||||
isShortLivingBranch | |||||
} from '../../helpers/branches'; | |||||
import { isBranch, isPullRequest } from '../../helpers/branch-like'; | |||||
import { getDisplayMetrics, isDiffMetric } from '../../helpers/measures'; | import { getDisplayMetrics, isDiffMetric } from '../../helpers/measures'; | ||||
import { BranchLike } from '../../types/branch-like'; | |||||
import { bubbles } from './config/bubbles'; | import { bubbles } from './config/bubbles'; | ||||
import { domains } from './config/domains'; | import { domains } from './config/domains'; | ||||
return metric !== 'alert_status'; | return metric !== 'alert_status'; | ||||
} | } | ||||
export function hasFullMeasures(branch?: T.BranchLike) { | |||||
return !branch || isLongLivingBranch(branch) || isMainBranch(branch); | |||||
export function hasFullMeasures(branch?: BranchLike) { | |||||
return !branch || isBranch(branch); | |||||
} | } | ||||
export function getMeasuresPageMetricKeys(metrics: T.Dict<T.Metric>, branch?: T.BranchLike) { | |||||
export function getMeasuresPageMetricKeys(metrics: T.Dict<T.Metric>, branch?: BranchLike) { | |||||
const metricKeys = getDisplayMetrics(Object.values(metrics)).map(metric => metric.key); | const metricKeys = getDisplayMetrics(Object.values(metrics)).map(metric => metric.key); | ||||
if (isPullRequest(branch) || isShortLivingBranch(branch)) { | |||||
if (isPullRequest(branch)) { | |||||
return metricKeys.filter(key => isDiffMetric(key)); | return metricKeys.filter(key => isDiffMetric(key)); | ||||
} else { | } else { | ||||
return metricKeys; | return metricKeys; |
fillBranchLike, | fillBranchLike, | ||||
getBranchLikeQuery, | getBranchLikeQuery, | ||||
isPullRequest, | isPullRequest, | ||||
isSameBranchLike, | |||||
isShortLivingBranch | |||||
} from '../../../helpers/branches'; | |||||
isSameBranchLike | |||||
} from '../../../helpers/branch-like'; | |||||
import { isSonarCloud } from '../../../helpers/system'; | import { isSonarCloud } from '../../../helpers/system'; | ||||
import { fetchBranchStatus } from '../../../store/rootActions'; | import { fetchBranchStatus } from '../../../store/rootActions'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import * as actions from '../actions'; | import * as actions from '../actions'; | ||||
import ConciseIssuesList from '../conciseIssuesList/ConciseIssuesList'; | import ConciseIssuesList from '../conciseIssuesList/ConciseIssuesList'; | ||||
import ConciseIssuesListHeader from '../conciseIssuesList/ConciseIssuesListHeader'; | import ConciseIssuesListHeader from '../conciseIssuesList/ConciseIssuesListHeader'; | ||||
} | } | ||||
interface Props { | interface Props { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
component?: T.Component; | component?: T.Component; | ||||
currentUser: T.CurrentUser; | currentUser: T.CurrentUser; | ||||
fetchBranchStatus: (branchLike: T.BranchLike, projectKey: string) => Promise<void>; | |||||
fetchBranchStatus: (branchLike: BranchLike, projectKey: string) => Promise<void>; | |||||
fetchIssues: (query: T.RawQuery, requestOrganizations?: boolean) => Promise<FetchIssuesPromise>; | fetchIssues: (query: T.RawQuery, requestOrganizations?: boolean) => Promise<FetchIssuesPromise>; | ||||
hideAuthorFacet?: boolean; | hideAuthorFacet?: boolean; | ||||
location: Pick<Location, 'pathname' | 'query'>; | location: Pick<Location, 'pathname' | 'query'>; | ||||
handleReload = () => { | handleReload = () => { | ||||
this.fetchFirstIssues(); | this.fetchFirstIssues(); | ||||
this.refreshBranchStatus(); | this.refreshBranchStatus(); | ||||
if (isShortLivingBranch(this.props.branchLike) || isPullRequest(this.props.branchLike)) { | |||||
if (isPullRequest(this.props.branchLike)) { | |||||
this.props.onBranchesChange(); | this.props.onBranchesChange(); | ||||
} | } | ||||
}; | }; | ||||
refreshBranchStatus = () => { | refreshBranchStatus = () => { | ||||
const { branchLike, component } = this.props; | const { branchLike, component } = this.props; | ||||
if (branchLike && component && (isPullRequest(branchLike) || isShortLivingBranch(branchLike))) { | |||||
if (branchLike && component && isPullRequest(branchLike)) { | |||||
this.props.fetchBranchStatus(branchLike, component.key); | this.props.fetchBranchStatus(branchLike, component.key); | ||||
} | } | ||||
}; | }; |
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import { Query, scrollToIssue } from '../utils'; | import { Query, scrollToIssue } from '../utils'; | ||||
import ListItem from './ListItem'; | import ListItem from './ListItem'; | ||||
interface Props { | interface Props { | ||||
branchLike: T.BranchLike | undefined; | |||||
branchLike: BranchLike | undefined; | |||||
checked: string[]; | checked: string[]; | ||||
component: T.Component | undefined; | component: T.Component | undefined; | ||||
issues: T.Issue[]; | issues: T.Issue[]; |
import * as React from 'react'; | import * as React from 'react'; | ||||
import { scrollToElement } from 'sonar-ui-common/helpers/scrolling'; | import { scrollToElement } from 'sonar-ui-common/helpers/scrolling'; | ||||
import SourceViewer from '../../../components/SourceViewer/SourceViewer'; | import SourceViewer from '../../../components/SourceViewer/SourceViewer'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import CrossComponentSourceViewer from '../crossComponentSourceViewer/CrossComponentSourceViewer'; | import CrossComponentSourceViewer from '../crossComponentSourceViewer/CrossComponentSourceViewer'; | ||||
import { getLocations, getSelectedLocation } from '../utils'; | import { getLocations, getSelectedLocation } from '../utils'; | ||||
interface Props { | interface Props { | ||||
branchLike: T.BranchLike | undefined; | |||||
branchLike: BranchLike | undefined; | |||||
issues: T.Issue[]; | issues: T.Issue[]; | ||||
loadIssues: (component: string, from: number, to: number) => Promise<T.Issue[]>; | loadIssues: (component: string, from: number, to: number) => Promise<T.Issue[]>; | ||||
locationsNavigator: boolean; | locationsNavigator: boolean; |
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import Issue from '../../../components/issue/Issue'; | import Issue from '../../../components/issue/Issue'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import { Query } from '../utils'; | import { Query } from '../utils'; | ||||
import ComponentBreadcrumbs from './ComponentBreadcrumbs'; | import ComponentBreadcrumbs from './ComponentBreadcrumbs'; | ||||
interface Props { | interface Props { | ||||
branchLike: T.BranchLike | undefined; | |||||
branchLike: BranchLike | undefined; | |||||
checked: boolean; | checked: boolean; | ||||
component: T.Component | undefined; | component: T.Component | undefined; | ||||
issue: T.Issue; | issue: T.Issue; |
import * as React from 'react'; | import * as React from 'react'; | ||||
import handleRequiredAuthentication from 'sonar-ui-common/helpers/handleRequiredAuthentication'; | import handleRequiredAuthentication from 'sonar-ui-common/helpers/handleRequiredAuthentication'; | ||||
import { KEYCODE_MAP, keydown, waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; | import { KEYCODE_MAP, keydown, waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; | ||||
import { mockPullRequest } from '../../../../helpers/mocks/branch-like'; | |||||
import { | import { | ||||
mockComponent, | mockComponent, | ||||
mockCurrentUser, | mockCurrentUser, | ||||
mockIssue, | mockIssue, | ||||
mockLocation, | mockLocation, | ||||
mockLoggedInUser, | mockLoggedInUser, | ||||
mockPullRequest, | |||||
mockRouter | mockRouter | ||||
} from '../../../../helpers/testMocks'; | } from '../../../../helpers/testMocks'; | ||||
import { | import { |
*/ | */ | ||||
import { shallow } from 'enzyme'; | import { shallow } from 'enzyme'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { mockIssue, mockMainBranch } from '../../../../helpers/testMocks'; | |||||
import { mockMainBranch } from '../../../../helpers/mocks/branch-like'; | |||||
import { mockIssue } from '../../../../helpers/testMocks'; | |||||
import IssuesSourceViewer from '../IssuesSourceViewer'; | import IssuesSourceViewer from '../IssuesSourceViewer'; | ||||
it('should render SourceViewer correctly', () => { | it('should render SourceViewer correctly', () => { |
import getCoverageStatus from '../../../components/SourceViewer/helpers/getCoverageStatus'; | import getCoverageStatus from '../../../components/SourceViewer/helpers/getCoverageStatus'; | ||||
import { locationsByLine } from '../../../components/SourceViewer/helpers/indexing'; | import { locationsByLine } from '../../../components/SourceViewer/helpers/indexing'; | ||||
import SourceViewerHeaderSlim from '../../../components/SourceViewer/SourceViewerHeaderSlim'; | import SourceViewerHeaderSlim from '../../../components/SourceViewer/SourceViewerHeaderSlim'; | ||||
import { getBranchLikeQuery } from '../../../helpers/branches'; | |||||
import { getBranchLikeQuery } from '../../../helpers/branch-like'; | |||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import SnippetViewer from './SnippetViewer'; | import SnippetViewer from './SnippetViewer'; | ||||
import { | import { | ||||
createSnippets, | createSnippets, | ||||
} from './utils'; | } from './utils'; | ||||
interface Props { | interface Props { | ||||
branchLike: T.BranchLike | undefined; | |||||
branchLike: BranchLike | undefined; | |||||
duplications?: T.Duplication[]; | duplications?: T.Duplication[]; | ||||
duplicationsByLine?: { [line: number]: number[] }; | duplicationsByLine?: { [line: number]: number[] }; | ||||
highlightedLocationMessage: { index: number; text: string | undefined } | undefined; | highlightedLocationMessage: { index: number; text: string | undefined } | undefined; |
} from '../../../components/SourceViewer/helpers/indexing'; | } from '../../../components/SourceViewer/helpers/indexing'; | ||||
import { SourceViewerContext } from '../../../components/SourceViewer/SourceViewerContext'; | import { SourceViewerContext } from '../../../components/SourceViewer/SourceViewerContext'; | ||||
import { WorkspaceContext } from '../../../components/workspace/context'; | import { WorkspaceContext } from '../../../components/workspace/context'; | ||||
import { getBranchLikeQuery } from '../../../helpers/branches'; | |||||
import { getBranchLikeQuery } from '../../../helpers/branch-like'; | |||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import ComponentSourceSnippetViewer from './ComponentSourceSnippetViewer'; | import ComponentSourceSnippetViewer from './ComponentSourceSnippetViewer'; | ||||
import { groupLocationsByComponent } from './utils'; | import { groupLocationsByComponent } from './utils'; | ||||
interface Props { | interface Props { | ||||
branchLike: T.Branch | T.PullRequest | undefined; | |||||
branchLike: BranchLike | undefined; | |||||
highlightedLocationMessage?: { index: number; text: string | undefined }; | highlightedLocationMessage?: { index: number; text: string | undefined }; | ||||
issue: T.Issue; | issue: T.Issue; | ||||
issues: T.Issue[]; | issues: T.Issue[]; |
optimizeLocationMessage, | optimizeLocationMessage, | ||||
optimizeSelectedIssue | optimizeSelectedIssue | ||||
} from '../../../components/SourceViewer/helpers/lines'; | } from '../../../components/SourceViewer/helpers/lines'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import { inSnippet, LINES_BELOW_ISSUE } from './utils'; | import { inSnippet, LINES_BELOW_ISSUE } from './utils'; | ||||
interface Props { | interface Props { | ||||
branchLike: T.BranchLike | undefined; | |||||
branchLike: BranchLike | undefined; | |||||
component: T.SourceViewerFile; | component: T.SourceViewerFile; | ||||
duplications?: T.Duplication[]; | duplications?: T.Duplication[]; | ||||
duplicationsByLine?: { [line: number]: number[] }; | duplicationsByLine?: { [line: number]: number[] }; |
import * as React from 'react'; | import * as React from 'react'; | ||||
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; | import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; | ||||
import { getSources } from '../../../../api/components'; | import { getSources } from '../../../../api/components'; | ||||
import { mockBranch, mockMainBranch } from '../../../../helpers/mocks/branch-like'; | |||||
import { | import { | ||||
mockFlowLocation, | mockFlowLocation, | ||||
mockIssue, | mockIssue, | ||||
mockMainBranch, | |||||
mockShortLivingBranch, | |||||
mockSnippetsByComponent, | mockSnippetsByComponent, | ||||
mockSourceLine, | mockSourceLine, | ||||
mockSourceViewerFile | mockSourceViewerFile | ||||
}; | }; | ||||
const wrapper = shallowRender({ | const wrapper = shallowRender({ | ||||
branchLike: mockShortLivingBranch({ name: 'asdf' }), | |||||
branchLike: mockBranch({ name: 'asdf' }), | |||||
snippetGroup | snippetGroup | ||||
}); | }); | ||||
import { range } from 'lodash'; | import { range } from 'lodash'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { scrollHorizontally } from 'sonar-ui-common/helpers/scrolling'; | import { scrollHorizontally } from 'sonar-ui-common/helpers/scrolling'; | ||||
import { | |||||
mockIssue, | |||||
mockMainBranch, | |||||
mockSourceLine, | |||||
mockSourceViewerFile | |||||
} from '../../../../helpers/testMocks'; | |||||
import { mockMainBranch } from '../../../../helpers/mocks/branch-like'; | |||||
import { mockIssue, mockSourceLine, mockSourceViewerFile } from '../../../../helpers/testMocks'; | |||||
import SnippetViewer from '../SnippetViewer'; | import SnippetViewer from '../SnippetViewer'; | ||||
jest.mock('sonar-ui-common/helpers/scrolling', () => ({ | jest.mock('sonar-ui-common/helpers/scrolling', () => ({ |
import Modal from 'sonar-ui-common/components/controls/Modal'; | import Modal from 'sonar-ui-common/components/controls/Modal'; | ||||
import { translate } from 'sonar-ui-common/helpers/l10n'; | import { translate } from 'sonar-ui-common/helpers/l10n'; | ||||
import CodeSnippet from '../../../components/common/CodeSnippet'; | import CodeSnippet from '../../../components/common/CodeSnippet'; | ||||
import { getBranchLikeQuery } from '../../../helpers/branches'; | |||||
import { getBranchLikeQuery } from '../../../helpers/branch-like'; | |||||
import { isSonarCloud } from '../../../helpers/system'; | import { isSonarCloud } from '../../../helpers/system'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import BadgeButton from './BadgeButton'; | import BadgeButton from './BadgeButton'; | ||||
import BadgeParams from './BadgeParams'; | import BadgeParams from './BadgeParams'; | ||||
import './styles.css'; | import './styles.css'; | ||||
import { BadgeOptions, BadgeType, getBadgeSnippet, getBadgeUrl } from './utils'; | import { BadgeOptions, BadgeType, getBadgeSnippet, getBadgeUrl } from './utils'; | ||||
interface Props { | interface Props { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
metrics: T.Dict<T.Metric>; | metrics: T.Dict<T.Metric>; | ||||
project: string; | project: string; | ||||
qualifier: string; | qualifier: string; |
import * as React from 'react'; | import * as React from 'react'; | ||||
import { click } from 'sonar-ui-common/helpers/testUtils'; | import { click } from 'sonar-ui-common/helpers/testUtils'; | ||||
import { Location } from 'sonar-ui-common/helpers/urls'; | import { Location } from 'sonar-ui-common/helpers/urls'; | ||||
import { mockBranch } from '../../../../helpers/mocks/branch-like'; | |||||
import { isSonarCloud } from '../../../../helpers/system'; | import { isSonarCloud } from '../../../../helpers/system'; | ||||
import ProjectBadges from '../ProjectBadges'; | import ProjectBadges from '../ProjectBadges'; | ||||
jest.mock('../../../../helpers/system', () => ({ isSonarCloud: jest.fn() })); | jest.mock('../../../../helpers/system', () => ({ isSonarCloud: jest.fn() })); | ||||
const shortBranch: T.ShortLivingBranch = { | |||||
excludedFromPurge: true, | |||||
isMain: false, | |||||
mergeBranch: '', | |||||
name: 'branch-6.6', | |||||
type: 'SHORT' | |||||
}; | |||||
const shortBranch = mockBranch({ name: 'branch-6.6' }); | |||||
it('should display the modal after click on sonarcloud', () => { | it('should display the modal after click on sonarcloud', () => { | ||||
(isSonarCloud as jest.Mock).mockImplementation(() => true); | (isSonarCloud as jest.Mock).mockImplementation(() => true); |
import { getBaseUrl, getPathUrlAsString } from 'sonar-ui-common/helpers/urls'; | import { getBaseUrl, getPathUrlAsString } from 'sonar-ui-common/helpers/urls'; | ||||
import Suggestions from '../../../app/components/embed-docs-modal/Suggestions'; | import Suggestions from '../../../app/components/embed-docs-modal/Suggestions'; | ||||
import { Router, withRouter } from '../../../components/hoc/withRouter'; | import { Router, withRouter } from '../../../components/hoc/withRouter'; | ||||
import { isPullRequest, isShortLivingBranch } from '../../../helpers/branches'; | |||||
import { isPullRequest } from '../../../helpers/branch-like'; | |||||
import { isSonarCloud } from '../../../helpers/system'; | import { isSonarCloud } from '../../../helpers/system'; | ||||
import { getProjectUrl } from '../../../helpers/urls'; | import { getProjectUrl } from '../../../helpers/urls'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import OverviewApp from './OverviewApp'; | import OverviewApp from './OverviewApp'; | ||||
const EmptyOverview = lazyLoad(() => import('./EmptyOverview')); | const EmptyOverview = lazyLoad(() => import('./EmptyOverview')); | ||||
const ReviewApp = lazyLoad(() => import('../pullRequests/ReviewApp')); | const ReviewApp = lazyLoad(() => import('../pullRequests/ReviewApp')); | ||||
interface Props { | interface Props { | ||||
branchLike?: T.BranchLike; | |||||
branchLikes: T.BranchLike[]; | |||||
branchLike?: BranchLike; | |||||
branchLikes: BranchLike[]; | |||||
component: T.Component; | component: T.Component; | ||||
isInProgress?: boolean; | isInProgress?: boolean; | ||||
isPending?: boolean; | isPending?: boolean; | ||||
</Helmet> | </Helmet> | ||||
)} | )} | ||||
{isShortLivingBranch(branchLike) || isPullRequest(branchLike) ? ( | |||||
{isPullRequest(branchLike) ? ( | |||||
<> | <> | ||||
<Suggestions suggestions="pull_requests" /> | <Suggestions suggestions="pull_requests" /> | ||||
<ReviewApp branchLike={branchLike} component={component} /> | <ReviewApp branchLike={branchLike} component={component} /> |
import { getApplicationLeak } from '../../../api/application'; | import { getApplicationLeak } from '../../../api/application'; | ||||
import DateFromNow from '../../../components/intl/DateFromNow'; | import DateFromNow from '../../../components/intl/DateFromNow'; | ||||
import DateTooltipFormatter from '../../../components/intl/DateTooltipFormatter'; | import DateTooltipFormatter from '../../../components/intl/DateTooltipFormatter'; | ||||
import { Branch } from '../../../types/branch-like'; | |||||
interface Props { | interface Props { | ||||
branch?: T.LongLivingBranch; | |||||
branch?: Branch; | |||||
component: T.LightComponent; | component: T.LightComponent; | ||||
} | } | ||||
import { connect } from 'react-redux'; | import { connect } from 'react-redux'; | ||||
import { Alert } from 'sonar-ui-common/components/ui/Alert'; | import { Alert } from 'sonar-ui-common/components/ui/Alert'; | ||||
import { translate } from 'sonar-ui-common/helpers/l10n'; | import { translate } from 'sonar-ui-common/helpers/l10n'; | ||||
import { isBranch, isLongLivingBranch, isMainBranch } from '../../../helpers/branches'; | |||||
import { isBranch, isMainBranch } from '../../../helpers/branch-like'; | |||||
import { isSonarCloud } from '../../../helpers/system'; | import { isSonarCloud } from '../../../helpers/system'; | ||||
import { isLoggedIn } from '../../../helpers/users'; | import { isLoggedIn } from '../../../helpers/users'; | ||||
import { getCurrentUser, Store } from '../../../store/rootReducer'; | import { getCurrentUser, Store } from '../../../store/rootReducer'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import AnalyzeTutorial from '../../tutorials/analyzeProject/AnalyzeTutorial'; | import AnalyzeTutorial from '../../tutorials/analyzeProject/AnalyzeTutorial'; | ||||
import AnalyzeTutorialSonarCloud from '../../tutorials/analyzeProject/AnalyzeTutorialSonarCloud'; | import AnalyzeTutorialSonarCloud from '../../tutorials/analyzeProject/AnalyzeTutorialSonarCloud'; | ||||
import MetaContainer from '../meta/MetaContainer'; | import MetaContainer from '../meta/MetaContainer'; | ||||
interface OwnProps { | interface OwnProps { | ||||
branchLike?: T.BranchLike; | |||||
branchLikes: T.BranchLike[]; | |||||
branchLike?: BranchLike; | |||||
branchLikes: BranchLike[]; | |||||
component: T.Component; | component: T.Component; | ||||
hasAnalyses?: boolean; | hasAnalyses?: boolean; | ||||
onComponentChange: (changes: {}) => void; | onComponentChange: (changes: {}) => void; | ||||
const hasBranches = branchLikes.length > 1; | const hasBranches = branchLikes.length > 1; | ||||
const hasBadBranchConfig = | const hasBadBranchConfig = | ||||
branchLikes.length > 2 || | branchLikes.length > 2 || | ||||
(branchLikes.length === 2 && branchLikes.some(branch => isLongLivingBranch(branch))); | |||||
(branchLikes.length === 2 && | |||||
branchLikes.some(branch => isBranch(branch) && !isMainBranch(branchLike))); | |||||
return ( | return ( | ||||
<div className="page page-limited"> | <div className="page page-limited"> | ||||
<div className="overview page-with-sidebar"> | <div className="overview page-with-sidebar"> | ||||
branchLike, | branchLike, | ||||
message | message | ||||
}: { | }: { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
message: string; | message: string; | ||||
}) { | }) { | ||||
if (!isBranch(branchLike)) { | if (!isBranch(branchLike)) { |
import { | import { | ||||
getBranchLikeDisplayName, | getBranchLikeDisplayName, | ||||
getBranchLikeQuery, | getBranchLikeQuery, | ||||
isLongLivingBranch, | |||||
isBranch, | |||||
isMainBranch, | isMainBranch, | ||||
isSameBranchLike | isSameBranchLike | ||||
} from '../../../helpers/branches'; | |||||
} from '../../../helpers/branch-like'; | |||||
import { enhanceMeasuresWithMetrics } from '../../../helpers/measures'; | import { enhanceMeasuresWithMetrics } from '../../../helpers/measures'; | ||||
import { getLeakPeriod } from '../../../helpers/periods'; | import { getLeakPeriod } from '../../../helpers/periods'; | ||||
import { fetchMetrics } from '../../../store/rootActions'; | import { fetchMetrics } from '../../../store/rootActions'; | ||||
import { getMetrics, Store } from '../../../store/rootReducer'; | import { getMetrics, Store } from '../../../store/rootReducer'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import { | import { | ||||
DEFAULT_GRAPH, | DEFAULT_GRAPH, | ||||
getDisplayedHistoryMetrics, | getDisplayedHistoryMetrics, | ||||
import { HISTORY_METRICS_LIST, METRICS } from '../utils'; | import { HISTORY_METRICS_LIST, METRICS } from '../utils'; | ||||
interface Props { | interface Props { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
component: T.Component; | component: T.Component; | ||||
fetchMetrics: () => void; | fetchMetrics: () => void; | ||||
onComponentChange: (changes: {}) => void; | onComponentChange: (changes: {}) => void; | ||||
<div className="overview-main page-main"> | <div className="overview-main page-main"> | ||||
{component.qualifier === 'APP' ? ( | {component.qualifier === 'APP' ? ( | ||||
<ApplicationQualityGate | <ApplicationQualityGate | ||||
branch={isLongLivingBranch(branchLike) ? branchLike : undefined} | |||||
branch={isBranch(branchLike) && !isMainBranch(branchLike) ? branchLike : undefined} | |||||
component={component} | component={component} | ||||
/> | /> | ||||
) : ( | ) : ( |
*/ | */ | ||||
import { shallow } from 'enzyme'; | import { shallow } from 'enzyme'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { | |||||
mockComponent, | |||||
mockLoggedInUser, | |||||
mockMainBranch, | |||||
mockPullRequest | |||||
} from '../../../../helpers/testMocks'; | |||||
import { mockMainBranch, mockPullRequest } from '../../../../helpers/mocks/branch-like'; | |||||
import { mockComponent, mockLoggedInUser } from '../../../../helpers/testMocks'; | |||||
import { EmptyOverview, WarningMessage } from '../EmptyOverview'; | import { EmptyOverview, WarningMessage } from '../EmptyOverview'; | ||||
const branch = mockMainBranch(); | const branch = mockMainBranch(); |
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; | import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; | ||||
import { getMeasuresAndMeta } from '../../../../api/measures'; | import { getMeasuresAndMeta } from '../../../../api/measures'; | ||||
import { getAllTimeMachineData } from '../../../../api/time-machine'; | import { getAllTimeMachineData } from '../../../../api/time-machine'; | ||||
import { | |||||
mockComponent, | |||||
mockLongLivingBranch, | |||||
mockMainBranch, | |||||
mockMeasure, | |||||
mockMetric | |||||
} from '../../../../helpers/testMocks'; | |||||
import { mockBranch, mockMainBranch } from '../../../../helpers/mocks/branch-like'; | |||||
import { mockComponent, mockMeasure, mockMetric } from '../../../../helpers/testMocks'; | |||||
import { OverviewApp } from '../OverviewApp'; | import { OverviewApp } from '../OverviewApp'; | ||||
jest.mock('../../../../api/measures', () => { | jest.mock('../../../../api/measures', () => { | ||||
await waitAndUpdate(wrapper); | await waitAndUpdate(wrapper); | ||||
expect(wrapper.find('h3').text()).toBe('overview.project.main_branch_empty'); | expect(wrapper.find('h3').text()).toBe('overview.project.main_branch_empty'); | ||||
wrapper.setProps({ branchLike: mockLongLivingBranch({ name: 'branch-foo' }) }); | |||||
wrapper.setProps({ branchLike: mockBranch({ name: 'branch-foo' }) }); | |||||
await waitAndUpdate(wrapper); | await waitAndUpdate(wrapper); | ||||
expect(wrapper.find('h3').text()).toBe('overview.project.branch_X_empty.branch-foo'); | expect(wrapper.find('h3').text()).toBe('overview.project.branch_X_empty.branch-foo'); | ||||
await waitAndUpdate(wrapper); | await waitAndUpdate(wrapper); | ||||
expect(wrapper.find('h3').text()).toBe('overview.project.main_branch_no_lines_of_code'); | expect(wrapper.find('h3').text()).toBe('overview.project.main_branch_no_lines_of_code'); | ||||
wrapper.setProps({ branchLike: mockLongLivingBranch({ name: 'branch-foo' }) }); | |||||
wrapper.setProps({ branchLike: mockBranch({ name: 'branch-foo' }) }); | |||||
await waitAndUpdate(wrapper); | await waitAndUpdate(wrapper); | ||||
expect(wrapper.find('h3').text()).toBe('overview.project.branch_X_no_lines_of_code.branch-foo'); | expect(wrapper.find('h3').text()).toBe('overview.project.branch_X_no_lines_of_code.branch-foo'); | ||||
import { translate } from 'sonar-ui-common/helpers/l10n'; | import { translate } from 'sonar-ui-common/helpers/l10n'; | ||||
import { getProjectActivity } from '../../../api/projectActivity'; | import { getProjectActivity } from '../../../api/projectActivity'; | ||||
import PreviewGraph from '../../../components/preview-graph/PreviewGraph'; | import PreviewGraph from '../../../components/preview-graph/PreviewGraph'; | ||||
import { getBranchLikeQuery, isSameBranchLike } from '../../../helpers/branches'; | |||||
import { getBranchLikeQuery, isSameBranchLike } from '../../../helpers/branch-like'; | |||||
import { getActivityUrl } from '../../../helpers/urls'; | import { getActivityUrl } from '../../../helpers/urls'; | ||||
import { BranchLike } from '../../../types/branch-like'; | |||||
import Analysis from './Analysis'; | import Analysis from './Analysis'; | ||||
interface Props { | interface Props { | ||||
branchLike?: T.BranchLike; | |||||
branchLike?: BranchLike; | |||||
component: T.Component; | component: T.Component; | ||||
history?: { | history?: { | ||||
[metric: string]: Array<{ date: Date; value?: string }>; | [metric: string]: Array<{ date: Date; value?: string }>; |
*/ | */ | ||||
import { shallow } from 'enzyme'; | import { shallow } from 'enzyme'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { mockMainBranch } from '../../../../helpers/testMocks'; | |||||
import { mockMainBranch } from '../../../../helpers/mocks/branch-like'; | |||||
import AnalysesList from '../AnalysesList'; | import AnalysesList from '../AnalysesList'; | ||||
it('should render show more link', () => { | it('should render show more link', () => { | ||||
const branchLike: T.MainBranch = mockMainBranch(); | |||||
const branchLike = mockMainBranch(); | |||||
const component = { | const component = { | ||||
breadcrumbs: [{ key: 'foo', name: 'foo', qualifier: 'TRK' }], | breadcrumbs: [{ key: 'foo', name: 'foo', qualifier: 'TRK' }], | ||||
key: 'foo', | key: 'foo', |
import { translateWithParameters } from 'sonar-ui-common/helpers/l10n'; | import { translateWithParameters } from 'sonar-ui-common/helpers/l10n'; | ||||
import DocTooltip from '../../../components/docs/DocTooltip'; | import DocTooltip from '../../../components/docs/DocTooltip'; | ||||
import DateFromNow from '../../../components/intl/DateFromNow'; | import DateFromNow from '../../../components/intl/DateFromNow'; | ||||
import { isLongLivingBranch } from '../../../helpers/branches'; | |||||
import { isBranch, isMainBranch } from '../../../helpers/branch-like'; | |||||
import ApplicationLeakPeriodLegend from '../components/ApplicationLeakPeriodLegend'; | import ApplicationLeakPeriodLegend from '../components/ApplicationLeakPeriodLegend'; | ||||
import LeakPeriodLegend from '../components/LeakPeriodLegend'; | import LeakPeriodLegend from '../components/LeakPeriodLegend'; | ||||
import { getMetricName } from '../utils'; | import { getMetricName } from '../utils'; | ||||
<div className="overview-domain-leak"> | <div className="overview-domain-leak"> | ||||
{component.qualifier === 'APP' ? ( | {component.qualifier === 'APP' ? ( | ||||
<ApplicationLeakPeriodLegend | <ApplicationLeakPeriodLegend | ||||
branch={isLongLivingBranch(branchLike) ? branchLike : undefined} | |||||
branch={isBranch(branchLike) && !isMainBranch(branchLike) ? branchLike : undefined} | |||||
component={component} | component={component} | ||||
/> | /> | ||||
) : ( | ) : ( |
*/ | */ | ||||
import { shallow } from 'enzyme'; | import { shallow } from 'enzyme'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { | |||||
mockComponent, | |||||
mockMainBranch, | |||||
mockMeasureEnhanced, | |||||
mockMetric | |||||
} from '../../../../helpers/testMocks'; | |||||
import { mockMainBranch } from '../../../../helpers/mocks/branch-like'; | |||||
import { mockComponent, mockMeasureEnhanced, mockMetric } from '../../../../helpers/testMocks'; | |||||
import Bugs from '../Bugs'; | import Bugs from '../Bugs'; | ||||
import { ComposedProps } from '../enhance'; | import { ComposedProps } from '../enhance'; | ||||