@@ -0,0 +1,4 @@ | |||
{ | |||
"printWidth": 100, | |||
"singleQuote": true | |||
} |
@@ -93,7 +93,7 @@ | |||
"path-browserify": "1.0.1", | |||
"postcss-calc": "7.0.2", | |||
"postcss-custom-properties": "9.1.1", | |||
"prettier": "1.19.1", | |||
"prettier": "2.7.1", | |||
"react-select-event": "5.5.1", | |||
"testing-library-selector": "0.2.1", | |||
"typescript": "4.8.4", | |||
@@ -133,10 +133,5 @@ | |||
"last 3 Edge versions", | |||
"IE 11" | |||
], | |||
"prettier": { | |||
"jsxBracketSameLine": true, | |||
"printWidth": 100, | |||
"singleQuote": true | |||
}, | |||
"packageManager": "yarn@3.2.4" | |||
} |
@@ -27,7 +27,7 @@ import { | |||
BitbucketRepository, | |||
GithubOrganization, | |||
GithubRepository, | |||
GitlabProject | |||
GitlabProject, | |||
} from '../types/alm-integration'; | |||
import { Paging } from '../types/types'; | |||
import { ProjectBase } from './components'; | |||
@@ -88,7 +88,7 @@ export function importAzureRepository( | |||
return postJSON('/api/alm_integrations/import_azure_project', { | |||
almSetting, | |||
projectName, | |||
repositoryName | |||
repositoryName, | |||
}).catch(throwGlobalError); | |||
} | |||
@@ -107,7 +107,7 @@ export function getBitbucketServerRepositories( | |||
}> { | |||
return getJSON('/api/alm_integrations/search_bitbucketserver_repos', { | |||
almSetting, | |||
projectName | |||
projectName, | |||
}); | |||
} | |||
@@ -119,7 +119,7 @@ export function importBitbucketServerProject( | |||
return postJSON('/api/alm_integrations/import_bitbucketserver_project', { | |||
almSetting, | |||
projectKey, | |||
repositorySlug | |||
repositorySlug, | |||
}).catch(throwGlobalError); | |||
} | |||
@@ -132,7 +132,7 @@ export function searchForBitbucketServerRepositories( | |||
}> { | |||
return getJSON('/api/alm_integrations/search_bitbucketserver_repos', { | |||
almSetting, | |||
repositoryName | |||
repositoryName, | |||
}); | |||
} | |||
@@ -149,7 +149,7 @@ export function searchForBitbucketCloudRepositories( | |||
almSetting, | |||
repositoryName, | |||
p: page, | |||
ps: pageSize | |||
ps: pageSize, | |||
}); | |||
} | |||
@@ -163,7 +163,7 @@ export function importBitbucketCloudRepository( | |||
): Promise<{ project: ProjectBase }> { | |||
return postJSON('/api/alm_integrations/import_bitbucketcloud_repo', { | |||
almSetting, | |||
repositorySlug | |||
repositorySlug, | |||
}).catch(throwGlobalError); | |||
} | |||
@@ -175,7 +175,7 @@ export function importGithubRepository( | |||
return postJSON('/api/alm_integrations/import_github_project', { | |||
almSetting, | |||
organization, | |||
repositoryKey | |||
repositoryKey, | |||
}).catch(throwGlobalError); | |||
} | |||
@@ -185,7 +185,7 @@ export function getGithubOrganizations( | |||
): Promise<{ organizations: GithubOrganization[] }> { | |||
return getJSON('/api/alm_integrations/list_github_organizations', { | |||
almSetting, | |||
token | |||
token, | |||
}).catch((response?: Response) => { | |||
if (response && response.status !== 400) { | |||
throwGlobalError(response); | |||
@@ -206,7 +206,7 @@ export function getGithubRepositories(data: { | |||
organization, | |||
p: page, | |||
ps: pageSize, | |||
q: query || undefined | |||
q: query || undefined, | |||
}).catch(throwGlobalError); | |||
} | |||
@@ -221,7 +221,7 @@ export function getGitlabProjects(data: { | |||
almSetting, | |||
projectName: query || undefined, | |||
p: page, | |||
ps: pageSize | |||
ps: pageSize, | |||
}) | |||
.then(({ repositories, paging }) => ({ projects: repositories, projectsPaging: paging })) | |||
.catch(throwGlobalError); | |||
@@ -234,6 +234,6 @@ export function importGitlabProject(data: { | |||
const { almSetting, gitlabProjectId } = data; | |||
return postJSON('/api/alm_integrations/import_gitlab_project', { | |||
almSetting, | |||
gitlabProjectId | |||
gitlabProjectId, | |||
}).catch(throwGlobalError); | |||
} |
@@ -33,7 +33,7 @@ import { | |||
GitlabBindingDefinition, | |||
GitlabProjectAlmBindingParams, | |||
ProjectAlmBindingConfigurationErrors, | |||
ProjectAlmBindingResponse | |||
ProjectAlmBindingResponse, | |||
} from '../types/alm-settings'; | |||
export function getAlmDefinitions(): Promise<AlmSettingsBindingDefinitions> { |
@@ -27,14 +27,14 @@ export function getApplicationLeak( | |||
branch?: string | |||
): Promise<ApplicationPeriod[]> { | |||
return getJSON('/api/applications/show_leak', { application, branch }).then( | |||
r => r.leaks, | |||
(r) => r.leaks, | |||
throwGlobalError | |||
); | |||
} | |||
export function getApplicationDetails(application: string, branch?: string): Promise<Application> { | |||
return getJSON('/api/applications/show', { application, branch }).then( | |||
r => r.application, | |||
(r) => r.application, | |||
throwGlobalError | |||
); | |||
} |
@@ -28,10 +28,7 @@ export function logIn(login: string, password: string): Promise<Response> { | |||
} | |||
export function logOut(): Promise<Response> { | |||
return request('/api/authentication/logout') | |||
.setMethod('POST') | |||
.submit() | |||
.then(basicCheckStatus); | |||
return request('/api/authentication/logout').setMethod('POST').submit().then(basicCheckStatus); | |||
} | |||
function basicCheckStatus(response: Response): Promise<Response> { |
@@ -22,12 +22,15 @@ import { getJSON, post } from '../helpers/request'; | |||
import { Branch, PullRequest } from '../types/branch-like'; | |||
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<PullRequest[]> { | |||
return getJSON('/api/project_pull_requests/list', { project }).then( | |||
r => r.pullRequests, | |||
(r) => r.pullRequests, | |||
throwGlobalError | |||
); | |||
} | |||
@@ -48,6 +51,6 @@ export function excludeBranchFromPurge(projectKey: string, branchName: string, e | |||
return post('/api/project_branches/set_automatic_deletion_protection', { | |||
project: projectKey, | |||
branch: branchName, | |||
value: excluded | |||
value: excluded, | |||
}).catch(throwGlobalError); | |||
} |
@@ -52,7 +52,7 @@ export function getStatus( | |||
} | |||
export function getTask(id: string, additionalFields?: string[]): Promise<Task> { | |||
return getJSON('/api/ce/task', { id, additionalFields }).then(r => r.task); | |||
return getJSON('/api/ce/task', { id, additionalFields }).then((r) => r.task); | |||
} | |||
export function cancelTask(id: string): Promise<any> { | |||
@@ -71,7 +71,7 @@ export function getTasksForComponent(component: string): Promise<{ queue: Task[] | |||
} | |||
export function getTypes(): Promise<string[]> { | |||
return getJSON('/api/ce/task_types').then(r => r.taskTypes); | |||
return getJSON('/api/ce/task_types').then((r) => r.taskTypes); | |||
} | |||
export function getWorkers(): Promise<{ canSetWorkerCount: boolean; value: number }> { |
@@ -31,7 +31,7 @@ import { | |||
Paging, | |||
SourceLine, | |||
SourceViewerFile, | |||
Visibility | |||
Visibility, | |||
} from '../types/types'; | |||
export interface BaseSearchProjectsParameters { | |||
@@ -60,9 +60,7 @@ export interface SearchProjectsParameters extends BaseSearchProjectsParameters { | |||
ps?: number; | |||
} | |||
export function getComponents( | |||
parameters: SearchProjectsParameters | |||
): Promise<{ | |||
export function getComponents(parameters: SearchProjectsParameters): Promise<{ | |||
components: Project[]; | |||
paging: Paging; | |||
}> { | |||
@@ -184,11 +182,11 @@ export function getComponentShow(data: { component: string } & BranchParameters) | |||
} | |||
export function getParents(component: string): Promise<any> { | |||
return getComponentShow({ component }).then(r => r.ancestors); | |||
return getComponentShow({ component }).then((r) => r.ancestors); | |||
} | |||
export function getBreadcrumbs(data: { component: string } & BranchParameters): Promise<any> { | |||
return getComponentShow(data).then(r => { | |||
return getComponentShow(data).then((r) => { | |||
const reversedAncestors = [...r.ancestors].reverse(); | |||
return [...reversedAncestors, r.component]; | |||
}); | |||
@@ -219,9 +217,7 @@ export interface Facet { | |||
values: Array<{ val: string; count: number }>; | |||
} | |||
export function searchProjects( | |||
data: RequestData | |||
): Promise<{ | |||
export function searchProjects(data: RequestData): Promise<{ | |||
components: Component[]; | |||
facets: Facet[]; | |||
paging: Paging; | |||
@@ -286,7 +282,7 @@ export function getComponentForSourceViewer( | |||
export function getSources( | |||
data: { key: string; from?: number; to?: number } & BranchParameters | |||
): Promise<SourceLine[]> { | |||
return getJSON('/api/sources/lines', data).then(r => r.sources); | |||
return getJSON('/api/sources/lines', data).then((r) => r.sources); | |||
} | |||
export function getDuplications( | |||
@@ -298,7 +294,7 @@ export function getDuplications( | |||
export function getTests( | |||
data: { sourceFileKey: string; sourceFileLineNumber: number | string } & BranchParameters | |||
): Promise<any> { | |||
return getJSON('/api/tests/list', data).then(r => r.tests); | |||
return getJSON('/api/tests/list', data).then((r) => r.tests); | |||
} | |||
interface ProjectResponse { |
@@ -26,7 +26,7 @@ import { | |||
parseJSON, | |||
post, | |||
postJSON, | |||
RequestData | |||
RequestData, | |||
} from '../helpers/request'; | |||
import { IssueResponse, RawIssuesResponse } from '../types/issues'; | |||
import { Dict, FacetValue, IssueChangelog, SnippetsByComponent, SourceLine } from '../types/types'; | |||
@@ -66,9 +66,9 @@ export function getFacets( | |||
...query, | |||
facets: facets.join(), | |||
ps: 1, | |||
additionalFields: '_all' | |||
additionalFields: '_all', | |||
}; | |||
return searchIssues(data).then(r => { | |||
return searchIssues(data).then((r) => { | |||
return { facets: r.facets, response: r }; | |||
}); | |||
} | |||
@@ -77,7 +77,7 @@ export function getFacet( | |||
query: RequestData, | |||
facet: FacetName | |||
): Promise<{ facet: { count: number; val: string }[]; response: RawIssuesResponse }> { | |||
return getFacets(query, [facet]).then(r => { | |||
return getFacets(query, [facet]).then((r) => { | |||
return { facet: r.facets[0].values, response: r.response }; | |||
}); | |||
} | |||
@@ -90,7 +90,7 @@ export function searchIssueTags(data: { | |||
q?: string; | |||
}): Promise<string[]> { | |||
return getJSON('/api/issues/tags', data) | |||
.then(r => r.tags) | |||
.then((r) => r.tags) | |||
.catch(throwGlobalError); | |||
} | |||
@@ -99,7 +99,7 @@ export function getIssueChangelog(issue: string): Promise<{ changelog: IssueChan | |||
} | |||
export function getIssueFilters() { | |||
return getJSON('/api/issue_filters/search').then(r => r.issueFilters); | |||
return getJSON('/api/issue_filters/search').then((r) => r.issueFilters); | |||
} | |||
export function addIssueComment(data: { issue: string; text: string }): Promise<IssueResponse> { | |||
@@ -149,19 +149,19 @@ export function searchIssueAuthors(data: { | |||
ps?: number; | |||
q?: string; | |||
}): Promise<string[]> { | |||
return getJSON('/api/issues/authors', data).then(r => r.authors, throwGlobalError); | |||
return getJSON('/api/issues/authors', data).then((r) => r.authors, throwGlobalError); | |||
} | |||
export function getIssueFlowSnippets(issueKey: string): Promise<Dict<SnippetsByComponent>> { | |||
return get('/api/sources/issue_snippets', { issueKey }) | |||
.then(r => { | |||
.then((r) => { | |||
if (r.status === HttpStatus.NoContent) { | |||
return {} as any; | |||
} | |||
return parseJSON(r); | |||
}) | |||
.then(result => { | |||
Object.keys(result).forEach(k => { | |||
.then((result) => { | |||
Object.keys(result).forEach((k) => { | |||
if (result[k].sources) { | |||
result[k].sources = result[k].sources.reduce( | |||
(lineMap: Dict<SourceLine>, line: SourceLine) => { |
@@ -22,5 +22,5 @@ import { getJSON } from '../helpers/request'; | |||
import { Language } from '../types/languages'; | |||
export function getLanguages(): Promise<Language[]> { | |||
return getJSON('/api/languages/list').then(r => r.languages, throwGlobalError); | |||
return getJSON('/api/languages/list').then((r) => r.languages, throwGlobalError); | |||
} |
@@ -23,7 +23,7 @@ import { BranchParameters } from '../types/branch-like'; | |||
import { | |||
MeasuresAndMetaWithMetrics, | |||
MeasuresAndMetaWithPeriod, | |||
MeasuresForProjects | |||
MeasuresForProjects, | |||
} from '../types/measures'; | |||
import { Measure } from '../types/types'; | |||
@@ -32,7 +32,7 @@ const COMPONENT_URL = '/api/measures/component'; | |||
export function getMeasures( | |||
data: { component: string; metricKeys: string } & BranchParameters | |||
): Promise<Measure[]> { | |||
return getJSON(COMPONENT_URL, data).then(r => r.component.measures, throwGlobalError); | |||
return getJSON(COMPONENT_URL, data).then((r) => r.component.measures, throwGlobalError); | |||
} | |||
export function getMeasuresWithMetrics( | |||
@@ -44,7 +44,7 @@ export function getMeasuresWithMetrics( | |||
additionalFields: 'metrics', | |||
component, | |||
metricKeys: metrics.join(','), | |||
...branchParameters | |||
...branchParameters, | |||
}).catch(throwGlobalError); | |||
} | |||
@@ -57,7 +57,7 @@ export function getMeasuresWithPeriod( | |||
additionalFields: 'period', | |||
component, | |||
metricKeys: metrics.join(','), | |||
...branchParameters | |||
...branchParameters, | |||
}).catch(throwGlobalError); | |||
} | |||
@@ -70,7 +70,7 @@ export function getMeasuresWithPeriodAndMetrics( | |||
additionalFields: 'period,metrics', | |||
component, | |||
metricKeys: metrics.join(','), | |||
...branchParameters | |||
...branchParameters, | |||
}).catch(throwGlobalError); | |||
} | |||
@@ -80,6 +80,6 @@ export function getMeasuresForProjects( | |||
): Promise<MeasuresForProjects[]> { | |||
return getJSON('/api/measures/search', { | |||
projectKeys: projectKeys.join(), | |||
metricKeys: metricKeys.join() | |||
}).then(r => r.measures); | |||
metricKeys: metricKeys.join(), | |||
}).then((r) => r.measures); | |||
} |
@@ -47,7 +47,7 @@ export function getAllMetrics(data?: { | |||
data: { p?: number; ps?: number } = { ps: 500 }, | |||
prev?: MetricsResponse | |||
): Promise<Metric[]> { | |||
return getMetrics(data).then(r => { | |||
return getMetrics(data).then((r) => { | |||
const result = prev ? prev.metrics.concat(r.metrics) : r.metrics; | |||
if (r.p * r.ps >= r.total) { | |||
return result; |
@@ -29,7 +29,7 @@ export default class AuthenticationServiceMock { | |||
mockSettingValue({ key: 'test1', value: '' }), | |||
mockSettingValue({ key: 'test2', value: 'test2' }), | |||
mockSettingValue({ key: 'sonar.auth.saml.certificate.secured' }), | |||
mockSettingValue({ key: 'sonar.auth.saml.enabled', value: 'false' }) | |||
mockSettingValue({ key: 'sonar.auth.saml.enabled', value: 'false' }), | |||
]; | |||
constructor() { | |||
@@ -41,7 +41,7 @@ export default class AuthenticationServiceMock { | |||
getValuesHandler = (data: { keys: string; component?: string } & BranchParameters) => { | |||
if (data.keys) { | |||
return Promise.resolve(this.settingValues.filter(set => data.keys.includes(set.key))); | |||
return Promise.resolve(this.settingValues.filter((set) => data.keys.includes(set.key))); | |||
} | |||
return Promise.resolve(this.settingValues); | |||
}; | |||
@@ -50,12 +50,12 @@ export default class AuthenticationServiceMock { | |||
if (value === 'error') { | |||
const res = new Response('', { | |||
status: 400, | |||
statusText: 'fail' | |||
statusText: 'fail', | |||
}); | |||
return Promise.reject(res); | |||
} | |||
const updatedSettingValue = this.settingValues.find(set => set.key === definition.key); | |||
const updatedSettingValue = this.settingValues.find((set) => set.key === definition.key); | |||
if (updatedSettingValue) { | |||
updatedSettingValue.value = value; | |||
} | |||
@@ -64,7 +64,7 @@ export default class AuthenticationServiceMock { | |||
resetValueHandler = (data: { keys: string; component?: string } & BranchParameters) => { | |||
if (data.keys) { | |||
this.settingValues.forEach(set => { | |||
this.settingValues.forEach((set) => { | |||
if (data.keys.includes(set.key)) { | |||
set.value = ''; | |||
} |
@@ -27,7 +27,7 @@ export default class BranchesServiceMock { | |||
defaultBranchLikes: BranchLike[] = [ | |||
mockBranch({ isMain: true, name: 'master' }), | |||
mockBranch({ excludedFromPurge: false, name: 'delete-branch' }), | |||
mockBranch({ name: 'normal-branch' }) | |||
mockBranch({ name: 'normal-branch' }), | |||
]; | |||
constructor() { |
@@ -35,7 +35,7 @@ function isLeaf(node: ComponentTree) { | |||
} | |||
function listChildComponent(node: ComponentTree): ComponentMeasure[] { | |||
return map(node.child, n => n.component); | |||
return map(node.child, (n) => n.component); | |||
} | |||
function listAllComponent(node: ComponentTree): ComponentMeasure[] { | |||
@@ -65,28 +65,28 @@ export default class CodeServiceMock { | |||
key: 'foo:folerA', | |||
name: 'folderA', | |||
path: 'folderA', | |||
qualifier: ComponentQualifier.Directory | |||
qualifier: ComponentQualifier.Directory, | |||
}), | |||
child: [ | |||
{ | |||
component: mockComponentMeasure(true, { | |||
key: 'foo:folderA/out.tsx', | |||
name: 'out.tsx', | |||
path: 'folderA/out.tsx' | |||
path: 'folderA/out.tsx', | |||
}), | |||
child: [] | |||
} | |||
] | |||
child: [], | |||
}, | |||
], | |||
}, | |||
{ | |||
component: mockComponentMeasure(true, { | |||
key: 'foo:index.tsx', | |||
name: 'index.tsx', | |||
path: 'index.tsx' | |||
path: 'index.tsx', | |||
}), | |||
child: [] | |||
} | |||
] | |||
child: [], | |||
}, | |||
], | |||
}; | |||
(getComponentTree as jest.Mock).mockImplementation(this.handleGetComponentTree); | |||
(getChildren as jest.Mock).mockImplementation(this.handleGetChildren); | |||
@@ -97,7 +97,7 @@ export default class CodeServiceMock { | |||
if (from.component.key === key) { | |||
return from; | |||
} | |||
return from.child.find(node => this.findBaseComponent(key, node)); | |||
return from.child.find((node) => this.findBaseComponent(key, node)); | |||
} | |||
handleGetChildren = ( | |||
@@ -124,7 +124,7 @@ export default class CodeServiceMock { | |||
let components: ComponentMeasure[] = []; | |||
if (base === undefined) { | |||
return Promise.reject({ | |||
errors: [{ msg: `No component has been found for id ${component}` }] | |||
errors: [{ msg: `No component has been found for id ${component}` }], | |||
}); | |||
} | |||
if (strategy === 'all' || strategy === '') { | |||
@@ -142,8 +142,8 @@ export default class CodeServiceMock { | |||
paging: { | |||
pageIndex: 1, | |||
pageSize: 100, | |||
total: components.length | |||
} | |||
total: components.length, | |||
}, | |||
}); | |||
}; | |||
@@ -154,7 +154,7 @@ export default class CodeServiceMock { | |||
facets: [], | |||
issues: [], | |||
languages: [], | |||
paging: { total: 0, pageIndex: 1, pageSize: 100 } | |||
paging: { total: 0, pageIndex: 1, pageSize: 100 }, | |||
}); | |||
}; | |||
@@ -23,7 +23,7 @@ import { | |||
mockCurrentUser, | |||
mockQualityProfile, | |||
mockRuleDetails, | |||
mockRuleRepository | |||
mockRuleRepository, | |||
} from '../../helpers/testMocks'; | |||
import { RuleRepository } from '../../types/coding-rules'; | |||
import { RawIssuesResponse } from '../../types/issues'; | |||
@@ -37,7 +37,7 @@ import { | |||
Profile, | |||
searchQualityProfiles, | |||
SearchQualityProfilesParameters, | |||
SearchQualityProfilesResponse | |||
SearchQualityProfilesResponse, | |||
} from '../quality-profiles'; | |||
import { getRuleDetails, getRulesApp, searchRules, updateRule } from '../rules'; | |||
import { dismissNotice, getCurrentUser } from '../users'; | |||
@@ -48,7 +48,7 @@ interface FacetFilter { | |||
const FACET_RULE_MAP: { [key: string]: keyof Rule } = { | |||
languages: 'lang', | |||
types: 'type' | |||
types: 'type', | |||
}; | |||
export default class CodingRulesMock { | |||
defaultRules: RuleDetails[] = []; | |||
@@ -62,12 +62,12 @@ export default class CodingRulesMock { | |||
constructor() { | |||
this.repositories = [ | |||
mockRuleRepository({ key: 'repo1' }), | |||
mockRuleRepository({ key: 'repo2' }) | |||
mockRuleRepository({ key: 'repo2' }), | |||
]; | |||
this.qualityProfile = [ | |||
mockQualityProfile({ key: 'p1', name: 'QP Foo', language: 'java', languageName: 'Java' }), | |||
mockQualityProfile({ key: 'p2', name: 'QP Bar', language: 'js' }), | |||
mockQualityProfile({ key: 'p3', name: 'QP FooBar', language: 'java', languageName: 'Java' }) | |||
mockQualityProfile({ key: 'p3', name: 'QP FooBar', language: 'java', languageName: 'Java' }), | |||
]; | |||
const resourceContent = 'Some link <a href="http://example.com">Awsome Reading</a>'; | |||
@@ -80,7 +80,7 @@ export default class CodingRulesMock { | |||
type: 'BUG', | |||
lang: 'java', | |||
langName: 'Java', | |||
name: 'Awsome java rule' | |||
name: 'Awsome java rule', | |||
}), | |||
mockRuleDetails({ | |||
key: 'rule2', | |||
@@ -93,10 +93,10 @@ export default class CodingRulesMock { | |||
{ key: RuleDescriptionSections.ASSESS_THE_PROBLEM, content: 'Assess' }, | |||
{ | |||
key: RuleDescriptionSections.RESOURCES, | |||
content: resourceContent | |||
} | |||
content: resourceContent, | |||
}, | |||
], | |||
langName: 'JavaScript' | |||
langName: 'JavaScript', | |||
}), | |||
mockRuleDetails({ key: 'rule3', name: 'Unknown rule', lang: 'js', langName: 'JavaScript' }), | |||
mockRuleDetails({ | |||
@@ -104,7 +104,7 @@ export default class CodingRulesMock { | |||
type: 'BUG', | |||
lang: 'c', | |||
langName: 'C', | |||
name: 'Awsome C rule' | |||
name: 'Awsome C rule', | |||
}), | |||
mockRuleDetails({ | |||
key: 'rule5', | |||
@@ -117,9 +117,9 @@ export default class CodingRulesMock { | |||
{ key: RuleDescriptionSections.HOW_TO_FIX, content: rootCauseContent }, | |||
{ | |||
key: RuleDescriptionSections.RESOURCES, | |||
content: resourceContent | |||
} | |||
] | |||
content: resourceContent, | |||
}, | |||
], | |||
}), | |||
mockRuleDetails({ | |||
key: 'rule6', | |||
@@ -128,7 +128,7 @@ export default class CodingRulesMock { | |||
langName: 'Python', | |||
name: 'Bad Python rule', | |||
isExternal: true, | |||
descriptionSections: undefined | |||
descriptionSections: undefined, | |||
}), | |||
mockRuleDetails({ | |||
key: 'rule7', | |||
@@ -139,23 +139,23 @@ export default class CodingRulesMock { | |||
descriptionSections: [ | |||
{ | |||
key: RuleDescriptionSections.INTRODUCTION, | |||
content: 'Introduction to this rule with context' | |||
content: 'Introduction to this rule with context', | |||
}, | |||
{ | |||
key: RuleDescriptionSections.HOW_TO_FIX, | |||
content: 'This is how to fix for spring', | |||
context: { key: 'spring', displayName: 'Spring' } | |||
context: { key: 'spring', displayName: 'Spring' }, | |||
}, | |||
{ | |||
key: RuleDescriptionSections.HOW_TO_FIX, | |||
content: 'This is how to fix for spring boot', | |||
context: { key: 'spring_boot', displayName: 'Spring boot' } | |||
context: { key: 'spring_boot', displayName: 'Spring boot' }, | |||
}, | |||
{ | |||
key: RuleDescriptionSections.RESOURCES, | |||
content: resourceContent | |||
} | |||
] | |||
content: resourceContent, | |||
}, | |||
], | |||
}), | |||
mockRuleDetails({ | |||
key: 'rule8', | |||
@@ -168,11 +168,11 @@ export default class CodingRulesMock { | |||
{ key: RuleDescriptionSections.HOW_TO_FIX, content: rootCauseContent }, | |||
{ | |||
key: RuleDescriptionSections.RESOURCES, | |||
content: resourceContent | |||
} | |||
content: resourceContent, | |||
}, | |||
], | |||
educationPrinciples: ['defense_in_depth', 'never_trust_user_input'] | |||
}) | |||
educationPrinciples: ['defense_in_depth', 'never_trust_user_input'], | |||
}), | |||
]; | |||
(updateRule as jest.Mock).mockImplementation(this.handleUpdateRule); | |||
@@ -189,7 +189,7 @@ export default class CodingRulesMock { | |||
} | |||
getRuleWithoutDetails() { | |||
return this.rules.map(r => | |||
return this.rules.map((r) => | |||
pick(r, [ | |||
'isTemplate', | |||
'key', | |||
@@ -201,7 +201,7 @@ export default class CodingRulesMock { | |||
'status', | |||
'sysTags', | |||
'tags', | |||
'type' | |||
'type', | |||
]) | |||
); | |||
} | |||
@@ -209,7 +209,7 @@ export default class CodingRulesMock { | |||
filterFacet({ languages }: FacetFilter) { | |||
let filteredRules = this.getRuleWithoutDetails(); | |||
if (languages) { | |||
filteredRules = filteredRules.filter(r => r.lang && languages.includes(r.lang)); | |||
filteredRules = filteredRules.filter((r) => r.lang && languages.includes(r.lang)); | |||
} | |||
return filteredRules; | |||
} | |||
@@ -234,11 +234,11 @@ export default class CodingRulesMock { | |||
} | |||
allRulesName() { | |||
return this.rules.map(r => r.name); | |||
return this.rules.map((r) => r.name); | |||
} | |||
allQualityProfile(language: string) { | |||
return this.qualityProfile.filter(qp => qp.language === language); | |||
return this.qualityProfile.filter((qp) => qp.language === language); | |||
} | |||
handleGetGacet = (): Promise<{ | |||
@@ -253,8 +253,8 @@ export default class CodingRulesMock { | |||
facets: [], | |||
issues: [], | |||
languages: [], | |||
paging: { total: 0, pageIndex: 1, pageSize: 1 } | |||
} | |||
paging: { total: 0, pageIndex: 1, pageSize: 1 }, | |||
}, | |||
}); | |||
}; | |||
@@ -262,23 +262,23 @@ export default class CodingRulesMock { | |||
actives?: boolean; | |||
key: string; | |||
}): Promise<{ actives?: RuleActivation[]; rule: RuleDetails }> => { | |||
const rule = this.rules.find(r => r.key === parameters.key); | |||
const rule = this.rules.find((r) => r.key === parameters.key); | |||
if (!rule) { | |||
return Promise.reject({ | |||
errors: [{ msg: `No rule has been found for id ${parameters.key}` }] | |||
errors: [{ msg: `No rule has been found for id ${parameters.key}` }], | |||
}); | |||
} | |||
return this.reply({ actives: parameters.actives ? [] : undefined, rule }); | |||
}; | |||
handleUpdateRule = (data: RulesUpdateRequest): Promise<RuleDetails> => { | |||
const rule = this.rules.find(r => r.key === data.key); | |||
const rule = this.rules.find((r) => r.key === data.key); | |||
if (rule === undefined) { | |||
return Promise.reject({ | |||
errors: [{ msg: `No rule has been found for id ${data.key}` }] | |||
errors: [{ msg: `No rule has been found for id ${data.key}` }], | |||
}); | |||
} | |||
const template = this.rules.find(r => r.key === rule.templateKey); | |||
const template = this.rules.find((r) => r.key === rule.templateKey); | |||
// Lets not convert the md to html in test. | |||
rule.mdDesc = data.markdown_description !== undefined ? data.markdown_description : rule.mdDesc; | |||
@@ -289,14 +289,14 @@ export default class CodingRulesMock { | |||
rule.name = data.name !== undefined ? data.name : rule.name; | |||
if (template && data.params) { | |||
rule.params = []; | |||
data.params.split(';').forEach(param => { | |||
data.params.split(';').forEach((param) => { | |||
const parts = param.split('='); | |||
const paramsDef = template.params?.find(p => p.key === parts[0]); | |||
const paramsDef = template.params?.find((p) => p.key === parts[0]); | |||
rule.params?.push({ | |||
key: parts[0], | |||
type: paramsDef?.type || 'STRING', | |||
defaultValue: trim(parts[1], '" '), | |||
htmlDesc: paramsDef?.htmlDesc | |||
htmlDesc: paramsDef?.htmlDesc, | |||
}); | |||
}); | |||
} | |||
@@ -316,17 +316,19 @@ export default class CodingRulesMock { | |||
handleSearchRules = ({ facets, languages, p, ps, rule_key }: SearchRulesQuery) => { | |||
const countFacet = (facets || '').split(',').map((facet: keyof Rule) => { | |||
const facetCount = countBy(this.rules.map(r => r[FACET_RULE_MAP[facet] || facet] as string)); | |||
const facetCount = countBy( | |||
this.rules.map((r) => r[FACET_RULE_MAP[facet] || facet] as string) | |||
); | |||
return { | |||
property: facet, | |||
values: Object.keys(facetCount).map(val => ({ val, count: facetCount[val] })) | |||
values: Object.keys(facetCount).map((val) => ({ val, count: facetCount[val] })), | |||
}; | |||
}); | |||
const currentPs = ps || 10; | |||
const currentP = p || 1; | |||
let filteredRules: Rule[] = []; | |||
if (rule_key) { | |||
filteredRules = this.getRuleWithoutDetails().filter(r => r.key === rule_key); | |||
filteredRules = this.getRuleWithoutDetails().filter((r) => r.key === rule_key); | |||
} else { | |||
filteredRules = this.filterFacet({ languages }); | |||
} | |||
@@ -336,7 +338,7 @@ export default class CodingRulesMock { | |||
p: currentP, | |||
ps: currentPs, | |||
rules: responseRules, | |||
facets: countFacet | |||
facets: countFacet, | |||
}); | |||
}; | |||
@@ -345,31 +347,31 @@ export default class CodingRulesMock { | |||
return this.reply({ | |||
succeeded: this.rules.length - 1, | |||
failed: 1, | |||
errors: [{ msg: 'c rule c:S6069 cannot be activated on cpp profile SonarSource' }] | |||
errors: [{ msg: 'c rule c:S6069 cannot be activated on cpp profile SonarSource' }], | |||
}); | |||
} | |||
return this.reply({ | |||
succeeded: this.rules.length, | |||
failed: 0, | |||
errors: [] | |||
errors: [], | |||
}); | |||
}; | |||
handleBulkDeactivateRules = () => { | |||
return this.reply({ | |||
succeeded: this.rules.length, | |||
failed: 0 | |||
failed: 0, | |||
}); | |||
}; | |||
handleSearchQualityProfiles = ({ language }: SearchQualityProfilesParameters = {}): Promise< | |||
SearchQualityProfilesResponse | |||
> => { | |||
handleSearchQualityProfiles = ({ | |||
language, | |||
}: SearchQualityProfilesParameters = {}): Promise<SearchQualityProfilesResponse> => { | |||
let profiles: Profile[] = this.isAdmin | |||
? this.qualityProfile.map(p => ({ ...p, actions: { edit: true } })) | |||
? this.qualityProfile.map((p) => ({ ...p, actions: { edit: true } })) | |||
: this.qualityProfile; | |||
if (language) { | |||
profiles = profiles.filter(p => p.language === language); | |||
profiles = profiles.filter((p) => p.language === language); | |||
} | |||
return this.reply({ profiles }); | |||
}; | |||
@@ -382,8 +384,8 @@ export default class CodingRulesMock { | |||
return this.reply( | |||
mockCurrentUser({ | |||
dismissedNotices: { | |||
educationPrinciples: this.dismissedNoticesEP | |||
} | |||
educationPrinciples: this.dismissedNoticesEP, | |||
}, | |||
}) | |||
); | |||
}; |
@@ -29,7 +29,7 @@ import { | |||
getStatus, | |||
getTypes, | |||
getWorkers, | |||
setWorkerCount | |||
setWorkerCount, | |||
} from '../ce'; | |||
const RANDOM_RADIX = 36; | |||
@@ -45,13 +45,13 @@ const TASK_TYPES = [ | |||
TaskTypes.AppRefresh, | |||
TaskTypes.ProjectImport, | |||
TaskTypes.ViewRefresh, | |||
TaskTypes.ReportSubmit | |||
TaskTypes.ReportSubmit, | |||
]; | |||
const DEFAULT_TASKS: Task[] = [mockTask()]; | |||
const DEFAULT_WORKERS = { | |||
canSetWorkerCount: true, | |||
value: 2 | |||
value: 2, | |||
}; | |||
const CANCELABLE_TASK_STATUSES = [TaskStatuses.Pending]; | |||
@@ -73,7 +73,7 @@ export default class ComputeEngineServiceMock { | |||
} | |||
handleCancelAllTasks = () => { | |||
this.tasks.forEach(t => { | |||
this.tasks.forEach((t) => { | |||
if (CANCELABLE_TASK_STATUSES.includes(t.status)) { | |||
t.status = TaskStatuses.Canceled; | |||
} | |||
@@ -83,7 +83,7 @@ export default class ComputeEngineServiceMock { | |||
}; | |||
handleCancelTask = (id: string) => { | |||
const task = this.tasks.find(t => t.id === id); | |||
const task = this.tasks.find((t) => t.id === id); | |||
if (task && CANCELABLE_TASK_STATUSES.includes(task.status)) { | |||
task.status = TaskStatuses.Canceled; | |||
@@ -96,7 +96,7 @@ export default class ComputeEngineServiceMock { | |||
handleGetActivity = (data: ActivityRequestParameters) => { | |||
let results = cloneDeep(this.tasks); | |||
results = results.filter(task => { | |||
results = results.filter((task) => { | |||
return !( | |||
(data.component && task.componentKey !== data.component) || | |||
(data.status && !data.status.split(',').includes(task.status)) || | |||
@@ -117,8 +117,8 @@ export default class ComputeEngineServiceMock { | |||
/* | |||
* This is more complex in real life, but it's a good enough approximation to suit tests | |||
*/ | |||
results = Object.values(groupBy(results, t => t.componentKey)).map( | |||
tasks => sortBy(tasks, t => t.executedAt).pop()! | |||
results = Object.values(groupBy(results, (t) => t.componentKey)).map( | |||
(tasks) => sortBy(tasks, (t) => t.executedAt).pop()! | |||
); | |||
} | |||
@@ -130,15 +130,15 @@ export default class ComputeEngineServiceMock { | |||
paging: { | |||
pageIndex: page, | |||
pageSize: PAGE_SIZE, | |||
total: results.length | |||
} | |||
total: results.length, | |||
}, | |||
}); | |||
}; | |||
handleGetStatus = (component?: string) => { | |||
return Promise.resolve( | |||
this.tasks | |||
.filter(task => !component || task.componentKey === component) | |||
.filter((task) => !component || task.componentKey === component) | |||
.reduce( | |||
(stats, task) => { | |||
switch (task.status) { | |||
@@ -187,14 +187,12 @@ export default class ComputeEngineServiceMock { | |||
}; | |||
addTask = (overrides: Partial<Task> = {}) => { | |||
const id = Math.random() | |||
.toString(RANDOM_RADIX) | |||
.slice(RANDOM_PREFIX); | |||
const id = Math.random().toString(RANDOM_RADIX).slice(RANDOM_PREFIX); | |||
this.tasks.push( | |||
mockTask({ | |||
id, | |||
...overrides | |||
...overrides, | |||
}) | |||
); | |||
}; |
@@ -22,7 +22,7 @@ import { RuleDescriptionSections } from '../../apps/coding-rules/rule'; | |||
import { | |||
mockSnippetsByComponent, | |||
mockSourceLine, | |||
mockSourceViewerFile | |||
mockSourceViewerFile, | |||
} from '../../helpers/mocks/sources'; | |||
import { RequestData } from '../../helpers/request'; | |||
import { getStandards } from '../../helpers/security-standard'; | |||
@@ -31,7 +31,7 @@ import { | |||
mockLoggedInUser, | |||
mockPaging, | |||
mockRawIssue, | |||
mockRuleDetails | |||
mockRuleDetails, | |||
} from '../../helpers/testMocks'; | |||
import { BranchParameters } from '../../types/branch-like'; | |||
import { | |||
@@ -39,7 +39,7 @@ import { | |||
RawFacet, | |||
RawIssue, | |||
RawIssuesResponse, | |||
ReferencedComponent | |||
ReferencedComponent, | |||
} from '../../types/issues'; | |||
import { Standards } from '../../types/security'; | |||
import { | |||
@@ -48,7 +48,7 @@ import { | |||
RuleActivation, | |||
RuleDetails, | |||
SnippetsByComponent, | |||
SourceViewerFile | |||
SourceViewerFile, | |||
} from '../../types/types'; | |||
import { NoticeType } from '../../types/users'; | |||
import { getComponentForSourceViewer, getSources } from '../components'; | |||
@@ -64,7 +64,7 @@ import { | |||
setIssueSeverity, | |||
setIssueTags, | |||
setIssueTransition, | |||
setIssueType | |||
setIssueType, | |||
} from '../issues'; | |||
import { getRuleDetails } from '../rules'; | |||
import { dismissNotice, getCurrentUser, searchUsers } from '../users'; | |||
@@ -74,7 +74,7 @@ function mockReferenceComponent(override?: Partial<ReferencedComponent>) { | |||
key: 'component1', | |||
name: 'Component1', | |||
uuid: 'id1', | |||
...override | |||
...override, | |||
}; | |||
} | |||
@@ -93,7 +93,7 @@ export default class IssuesServiceMock { | |||
// Comment should have their own store as we can test better CRUD operation | |||
this.sourceViewerFiles = [ | |||
mockSourceViewerFile('file.foo', 'project'), | |||
mockSourceViewerFile('file.bar', 'project') | |||
mockSourceViewerFile('file.bar', 'project'), | |||
]; | |||
this.list = [ | |||
{ | |||
@@ -106,7 +106,7 @@ export default class IssuesServiceMock { | |||
startLine: 10, | |||
endLine: 10, | |||
startOffset: 0, | |||
endOffset: 2 | |||
endOffset: 2, | |||
}, | |||
flows: [ | |||
{ | |||
@@ -120,8 +120,8 @@ export default class IssuesServiceMock { | |||
startLine: 20, | |||
endLine: 20, | |||
startOffset: 0, | |||
endOffset: 1 | |||
} | |||
endOffset: 1, | |||
}, | |||
}, | |||
{ | |||
component: 'project:file.foo', | |||
@@ -130,10 +130,10 @@ export default class IssuesServiceMock { | |||
startLine: 21, | |||
endLine: 21, | |||
startOffset: 0, | |||
endOffset: 1 | |||
} | |||
} | |||
] | |||
endOffset: 1, | |||
}, | |||
}, | |||
], | |||
}, | |||
{ | |||
type: FlowType.EXECUTION, | |||
@@ -145,8 +145,8 @@ export default class IssuesServiceMock { | |||
startLine: 20, | |||
endLine: 20, | |||
startOffset: 0, | |||
endOffset: 1 | |||
} | |||
endOffset: 1, | |||
}, | |||
}, | |||
{ | |||
component: 'project:file.bar', | |||
@@ -155,8 +155,8 @@ export default class IssuesServiceMock { | |||
startLine: 22, | |||
endLine: 22, | |||
startOffset: 0, | |||
endOffset: 1 | |||
} | |||
endOffset: 1, | |||
}, | |||
}, | |||
{ | |||
component: 'project:file.bar', | |||
@@ -165,28 +165,28 @@ export default class IssuesServiceMock { | |||
startLine: 5, | |||
endLine: 5, | |||
startOffset: 0, | |||
endOffset: 1 | |||
} | |||
} | |||
] | |||
} | |||
] | |||
endOffset: 1, | |||
}, | |||
}, | |||
], | |||
}, | |||
], | |||
}), | |||
snippets: keyBy( | |||
[ | |||
mockSnippetsByComponent( | |||
'file.foo', | |||
'project', | |||
times(40, i => i + 1) | |||
times(40, (i) => i + 1) | |||
), | |||
mockSnippetsByComponent( | |||
'file.bar', | |||
'project', | |||
times(40, i => i + 1) | |||
) | |||
times(40, (i) => i + 1) | |||
), | |||
], | |||
'component.key' | |||
) | |||
), | |||
}, | |||
{ | |||
issue: mockRawIssue(false, { | |||
@@ -195,9 +195,9 @@ export default class IssuesServiceMock { | |||
message: 'Issue on file', | |||
rule: 'simpleRuleId', | |||
textRange: undefined, | |||
line: undefined | |||
line: undefined, | |||
}), | |||
snippets: {} | |||
snippets: {}, | |||
}, | |||
{ | |||
issue: mockRawIssue(false, { | |||
@@ -209,7 +209,7 @@ export default class IssuesServiceMock { | |||
startLine: 10, | |||
endLine: 10, | |||
startOffset: 0, | |||
endOffset: 2 | |||
endOffset: 2, | |||
}, | |||
flows: [ | |||
{ | |||
@@ -221,10 +221,10 @@ export default class IssuesServiceMock { | |||
startLine: 1, | |||
endLine: 1, | |||
startOffset: 0, | |||
endOffset: 1 | |||
} | |||
} | |||
] | |||
endOffset: 1, | |||
}, | |||
}, | |||
], | |||
}, | |||
{ | |||
locations: [ | |||
@@ -235,28 +235,28 @@ export default class IssuesServiceMock { | |||
startLine: 20, | |||
endLine: 20, | |||
startOffset: 0, | |||
endOffset: 1 | |||
} | |||
} | |||
] | |||
} | |||
] | |||
endOffset: 1, | |||
}, | |||
}, | |||
], | |||
}, | |||
], | |||
}), | |||
snippets: keyBy( | |||
[ | |||
mockSnippetsByComponent( | |||
'file.foo', | |||
'project', | |||
times(40, i => i + 1) | |||
times(40, (i) => i + 1) | |||
), | |||
mockSnippetsByComponent( | |||
'file.bar', | |||
'project', | |||
times(40, i => i + 1) | |||
) | |||
times(40, (i) => i + 1) | |||
), | |||
], | |||
'component.key' | |||
) | |||
), | |||
}, | |||
{ | |||
issue: mockRawIssue(false, { | |||
@@ -270,20 +270,20 @@ export default class IssuesServiceMock { | |||
startLine: 25, | |||
endLine: 25, | |||
startOffset: 0, | |||
endOffset: 1 | |||
endOffset: 1, | |||
}, | |||
ruleDescriptionContextKey: 'spring' | |||
ruleDescriptionContextKey: 'spring', | |||
}), | |||
snippets: keyBy( | |||
[ | |||
mockSnippetsByComponent( | |||
'file.bar', | |||
'project', | |||
times(40, i => i + 20) | |||
) | |||
times(40, (i) => i + 20) | |||
), | |||
], | |||
'component.key' | |||
) | |||
), | |||
}, | |||
{ | |||
issue: mockRawIssue(false, { | |||
@@ -295,19 +295,19 @@ export default class IssuesServiceMock { | |||
startLine: 28, | |||
endLine: 28, | |||
startOffset: 0, | |||
endOffset: 1 | |||
} | |||
endOffset: 1, | |||
}, | |||
}), | |||
snippets: keyBy( | |||
[ | |||
mockSnippetsByComponent( | |||
'file.bar', | |||
'project', | |||
times(40, i => i + 20) | |||
) | |||
times(40, (i) => i + 20) | |||
), | |||
], | |||
'component.key' | |||
) | |||
), | |||
}, | |||
{ | |||
issue: mockRawIssue(false, { | |||
@@ -321,23 +321,23 @@ export default class IssuesServiceMock { | |||
startLine: 25, | |||
endLine: 25, | |||
startOffset: 0, | |||
endOffset: 1 | |||
endOffset: 1, | |||
}, | |||
ruleDescriptionContextKey: 'spring', | |||
ruleStatus: 'DEPRECATED', | |||
quickFixAvailable: true | |||
quickFixAvailable: true, | |||
}), | |||
snippets: keyBy( | |||
[ | |||
mockSnippetsByComponent( | |||
'file.bar', | |||
'project', | |||
times(40, i => i + 20) | |||
) | |||
times(40, (i) => i + 20) | |||
), | |||
], | |||
'component.key' | |||
) | |||
} | |||
), | |||
}, | |||
]; | |||
(searchIssues as jest.Mock).mockImplementation(this.handleSearchIssues); | |||
(getRuleDetails as jest.Mock).mockImplementation(this.handleGetRuleDetails); | |||
@@ -372,7 +372,7 @@ export default class IssuesServiceMock { | |||
owasp2021FacetList(): RawFacet { | |||
return { | |||
property: 'owaspTop10-2021', | |||
values: [{ val: 'a1', count: 0 }] | |||
values: [{ val: 'a1', count: 0 }], | |||
}; | |||
} | |||
@@ -383,22 +383,22 @@ export default class IssuesServiceMock { | |||
handleBulkChangeIssues = (issueKeys: string[], query: RequestData) => { | |||
//For now we only check for issue type change. | |||
this.list | |||
.filter(i => issueKeys.includes(i.issue.key)) | |||
.forEach(data => { | |||
.filter((i) => issueKeys.includes(i.issue.key)) | |||
.forEach((data) => { | |||
data.issue.type = query.set_type; | |||
}); | |||
return this.reply({}); | |||
}; | |||
handleGetSources = (data: { key: string; from?: number; to?: number } & BranchParameters) => { | |||
return this.reply(range(data.from || 1, data.to || 10).map(line => mockSourceLine({ line }))); | |||
return this.reply(range(data.from || 1, data.to || 10).map((line) => mockSourceLine({ line }))); | |||
}; | |||
handleGetComponentForSourceViewer = (data: { component: string } & BranchParameters) => { | |||
const file = this.sourceViewerFiles.find(f => f.key === data.component); | |||
const file = this.sourceViewerFiles.find((f) => f.key === data.component); | |||
if (file === undefined) { | |||
return Promise.reject({ | |||
errors: [{ msg: `No source file has been found for id ${data.component}` }] | |||
errors: [{ msg: `No source file has been found for id ${data.component}` }], | |||
}); | |||
} | |||
@@ -406,7 +406,7 @@ export default class IssuesServiceMock { | |||
}; | |||
handleGetIssueFlowSnippets = (issueKey: string): Promise<Dict<SnippetsByComponent>> => { | |||
const issue = this.list.find(i => i.issue.key === issueKey); | |||
const issue = this.list.find((i) => i.issue.key === issueKey); | |||
if (issue === undefined) { | |||
return Promise.reject({ errors: [{ msg: `No issue has been found for id ${issueKey}` }] }); | |||
} | |||
@@ -433,28 +433,28 @@ export default class IssuesServiceMock { | |||
key: RuleDescriptionSections.HOW_TO_FIX, | |||
context: { | |||
key: 'spring', | |||
displayName: 'Spring' | |||
} | |||
displayName: 'Spring', | |||
}, | |||
}, | |||
{ | |||
content: '<p> Context 2 content<p>', | |||
key: RuleDescriptionSections.HOW_TO_FIX, | |||
context: { | |||
key: 'context_2', | |||
displayName: 'Context 2' | |||
} | |||
displayName: 'Context 2', | |||
}, | |||
}, | |||
{ | |||
content: '<p> Context 3 content<p>', | |||
key: RuleDescriptionSections.HOW_TO_FIX, | |||
context: { | |||
key: 'context_3', | |||
displayName: 'Context 3' | |||
} | |||
displayName: 'Context 3', | |||
}, | |||
}, | |||
{ key: RuleDescriptionSections.RESOURCES, content: '<h1>Link</h1>' } | |||
] | |||
}) | |||
{ key: RuleDescriptionSections.RESOURCES, content: '<h1>Link</h1>' }, | |||
], | |||
}), | |||
}); | |||
} | |||
return this.reply({ | |||
@@ -465,10 +465,10 @@ export default class IssuesServiceMock { | |||
descriptionSections: [ | |||
{ | |||
key: RuleDescriptionSections.DEFAULT, | |||
content: '<h1>Default</h1> Default description' | |||
} | |||
] | |||
}) | |||
content: '<h1>Default</h1> Default description', | |||
}, | |||
], | |||
}), | |||
}); | |||
}; | |||
@@ -479,16 +479,16 @@ export default class IssuesServiceMock { | |||
} | |||
return { | |||
property: name, | |||
values: [] | |||
values: [], | |||
}; | |||
}); | |||
return this.reply({ | |||
components: [mockReferenceComponent()], | |||
effortTotal: 199629, | |||
facets, | |||
issues: this.list.map(line => line.issue), | |||
issues: this.list.map((line) => line.issue), | |||
languages: [], | |||
paging: mockPaging() | |||
paging: mockPaging(), | |||
}); | |||
}; | |||
@@ -522,25 +522,25 @@ export default class IssuesServiceMock { | |||
unconfirm: 'REOPENED', | |||
resolve: 'RESOLVED', | |||
wontfix: 'RESOLVED', | |||
falsepositive: 'RESOLVED' | |||
falsepositive: 'RESOLVED', | |||
}; | |||
const transitionMap: Dict<string[]> = { | |||
REOPENED: ['confirm', 'resolve', 'falsepositive', 'wontfix'], | |||
OPEN: ['confirm', 'resolve', 'falsepositive', 'wontfix'], | |||
CONFIRMED: ['resolve', 'unconfirm', 'falsepositive', 'wontfix'], | |||
RESOLVED: ['reopen'] | |||
RESOLVED: ['reopen'], | |||
}; | |||
const resolutionMap: Dict<string> = { | |||
wontfix: 'WONTFIX', | |||
falsepositive: 'FALSE-POSITIVE' | |||
falsepositive: 'FALSE-POSITIVE', | |||
}; | |||
return this.getActionsResponse( | |||
{ | |||
status: statusMap[data.transition], | |||
transitions: transitionMap[statusMap[data.transition]], | |||
resolution: resolutionMap[data.transition] | |||
resolution: resolutionMap[data.transition], | |||
}, | |||
data.issue | |||
); | |||
@@ -562,9 +562,9 @@ export default class IssuesServiceMock { | |||
key: '1234', | |||
login: 'admin', | |||
markdown: data.text, | |||
updatable: true | |||
} | |||
] | |||
updatable: true, | |||
}, | |||
], | |||
}, | |||
data.issue | |||
); | |||
@@ -581,9 +581,9 @@ export default class IssuesServiceMock { | |||
key: '1234', | |||
login: 'admin', | |||
markdown: data.text, | |||
updatable: true | |||
} | |||
] | |||
updatable: true, | |||
}, | |||
], | |||
}, | |||
'issue2' | |||
); | |||
@@ -593,7 +593,7 @@ export default class IssuesServiceMock { | |||
// For comment its little more complex to get comment Id | |||
return this.getActionsResponse( | |||
{ | |||
comments: [] | |||
comments: [], | |||
}, | |||
'issue2' | |||
); | |||
@@ -608,15 +608,15 @@ export default class IssuesServiceMock { | |||
}; | |||
getActionsResponse = (overrides: Partial<RawIssue>, issueKey: string) => { | |||
const issueDataSelected = this.list.find(l => l.issue.key === issueKey)!; | |||
const issueDataSelected = this.list.find((l) => l.issue.key === issueKey)!; | |||
issueDataSelected.issue = { | |||
...issueDataSelected?.issue, | |||
...overrides | |||
...overrides, | |||
}; | |||
return this.reply({ | |||
issue: issueDataSelected.issue | |||
issue: issueDataSelected.issue, | |||
}); | |||
}; | |||
@@ -22,7 +22,7 @@ import { cloneDeep } from 'lodash'; | |||
import { | |||
AddRemoveNotificationParameters, | |||
Notification, | |||
NotificationsResponse | |||
NotificationsResponse, | |||
} from '../../types/notifications'; | |||
import { addNotification, getNotifications, removeNotification } from '../notifications'; | |||
@@ -35,11 +35,11 @@ const perProjectTypes = [ | |||
'NewAlerts', | |||
'NewFalsePositiveIssue', | |||
'NewIssues', | |||
'SQ-MyNewIssues' | |||
'SQ-MyNewIssues', | |||
]; | |||
const defaultNotifications: Notification[] = [ | |||
{ channel: 'EmailNotificationChannel', type: 'ChangesOnMyIssue' } | |||
{ channel: 'EmailNotificationChannel', type: 'ChangesOnMyIssue' }, | |||
]; | |||
export default class NotificationsMock { | |||
@@ -58,7 +58,7 @@ export default class NotificationsMock { | |||
channels: [...channels], | |||
globalTypes: [...globalTypes], | |||
notifications: cloneDeep(this.notifications), | |||
perProjectTypes: [...perProjectTypes] | |||
perProjectTypes: [...perProjectTypes], | |||
}); | |||
}; | |||
@@ -70,7 +70,7 @@ export default class NotificationsMock { | |||
handleRemoveNotification = (params: AddRemoveNotificationParameters) => { | |||
const index = this.notifications.findIndex( | |||
n => n.project === params.project && n.type === params.type && n.channel === params.channel | |||
(n) => n.project === params.project && n.type === params.type && n.channel === params.channel | |||
); | |||
if (index < 0) { |
@@ -30,9 +30,15 @@ const defaultPermissionTemplates: PermissionTemplate[] = [ | |||
name: 'Permission Template 1', | |||
createdAt: '', | |||
defaultFor: [], | |||
permissions: [] | |||
permissions: [], | |||
}, | |||
{ | |||
id: 'template2', | |||
name: 'Permission Template 2', | |||
createdAt: '', | |||
defaultFor: [], | |||
permissions: [], | |||
}, | |||
{ id: 'template2', name: 'Permission Template 2', createdAt: '', defaultFor: [], permissions: [] } | |||
]; | |||
export default class PermissionTemplateServiceMock { |
@@ -40,7 +40,7 @@ import { | |||
searchProjects, | |||
searchUsers, | |||
setQualityGateAsDefault, | |||
updateCondition | |||
updateCondition, | |||
} from '../quality-gates'; | |||
export class QualityGatesServiceMock { | |||
@@ -62,7 +62,7 @@ export class QualityGatesServiceMock { | |||
id: 'AXJMbIUGPAOIsUIE3eNT', | |||
metric: 'new_maintainability_rating', | |||
op: 'GT', | |||
error: '1' | |||
error: '1', | |||
}, | |||
{ id: 'AXJMbIUGPAOIsUIE3eNU', metric: 'new_reliability_rating', op: 'GT', error: '1' }, | |||
{ id: 'AXJMbIUGPAOIsUIE3eNV', metric: 'new_security_rating', op: 'GT', error: '1' }, | |||
@@ -70,17 +70,17 @@ export class QualityGatesServiceMock { | |||
id: 'AXJMbIUHPAOIsUIE3eNc', | |||
metric: 'new_duplicated_lines_density', | |||
op: 'GT', | |||
error: '3' | |||
error: '3', | |||
}, | |||
{ | |||
id: 'AXJMbIUHPAOIsUIE3eOi', | |||
metric: 'new_security_hotspots_reviewed', | |||
op: 'LT', | |||
error: '100' | |||
} | |||
error: '100', | |||
}, | |||
], | |||
isDefault: true, | |||
isBuiltIn: false | |||
isBuiltIn: false, | |||
}), | |||
mockQualityGate({ | |||
id: 'AXGYZrDqC-YjVCvvbRDY', | |||
@@ -88,10 +88,10 @@ export class QualityGatesServiceMock { | |||
conditions: [ | |||
{ id: 'AXJMbIUHPAOIsUIE3eOu', metric: 'new_coverage', op: 'LT', error: '0' }, | |||
{ id: 'AXJMbIUHPAOIsUIE3eOubis', metric: 'new_coverage', op: 'LT', error: '1' }, | |||
{ id: 'deprecated', metric: 'function_complexity', op: 'LT', error: '1' } | |||
{ id: 'deprecated', metric: 'function_complexity', op: 'LT', error: '1' }, | |||
], | |||
isDefault: false, | |||
isBuiltIn: false | |||
isBuiltIn: false, | |||
}), | |||
mockQualityGate({ | |||
id: 'AWBWEMe4qGAMGEYPjJlr', | |||
@@ -103,25 +103,25 @@ export class QualityGatesServiceMock { | |||
id: 'AXJMbIUHPAOIsUIE3eOE', | |||
metric: 'new_maintainability_rating', | |||
op: 'GT', | |||
error: '1' | |||
error: '1', | |||
}, | |||
{ id: 'AXJMbIUHPAOIsUIE3eOF', metric: 'new_coverage', op: 'LT', error: '80' }, | |||
{ | |||
id: 'AXJMbIUHPAOIsUIE3eOG', | |||
metric: 'new_duplicated_lines_density', | |||
op: 'GT', | |||
error: '3' | |||
error: '3', | |||
}, | |||
{ | |||
id: 'AXJMbIUHPAOIsUIE3eOk', | |||
metric: 'new_security_hotspots_reviewed', | |||
op: 'LT', | |||
error: '100' | |||
} | |||
error: '100', | |||
}, | |||
], | |||
isDefault: false, | |||
isBuiltIn: true | |||
}) | |||
isBuiltIn: true, | |||
}), | |||
]; | |||
this.list = cloneDeep(this.readOnlyList); | |||
@@ -130,7 +130,7 @@ export class QualityGatesServiceMock { | |||
{ key: 'test1', name: 'test1', selected: false }, | |||
{ key: 'test2', name: 'test2', selected: false }, | |||
{ key: 'test3', name: 'test3', selected: true }, | |||
{ key: 'test4', name: 'test4', selected: true } | |||
{ key: 'test4', name: 'test4', selected: true }, | |||
]; | |||
(fetchQualityGate as jest.Mock).mockImplementation(this.showHandler); | |||
@@ -164,11 +164,11 @@ export class QualityGatesServiceMock { | |||
} | |||
getDefaultQualityGate() { | |||
return this.list.find(q => q.isDefault) || mockQualityGate({ isDefault: true }); | |||
return this.list.find((q) => q.isDefault) || mockQualityGate({ isDefault: true }); | |||
} | |||
getBuiltInQualityGate() { | |||
return this.list.find(q => q.isBuiltIn) || mockQualityGate({ isBuiltIn: true }); | |||
return this.list.find((q) => q.isBuiltIn) || mockQualityGate({ isBuiltIn: true }); | |||
} | |||
setIsAdmin(isAdmin: boolean) { | |||
@@ -183,26 +183,26 @@ export class QualityGatesServiceMock { | |||
associateProjects: this.isAdmin, | |||
delete: q.isBuiltIn ? false : this.isAdmin, | |||
manageConditions: this.isAdmin, | |||
delegate: this.isAdmin | |||
delegate: this.isAdmin, | |||
}; | |||
} | |||
listHandler = () => { | |||
return this.reply({ | |||
qualitygates: this.list | |||
.map(q => omit(q, 'conditions')) | |||
.map(q => ({ | |||
.map((q) => omit(q, 'conditions')) | |||
.map((q) => ({ | |||
...q, | |||
actions: this.computeActions(q) | |||
actions: this.computeActions(q), | |||
})), | |||
default: this.getDefaultQualityGate().id, | |||
actions: { create: this.isAdmin } | |||
actions: { create: this.isAdmin }, | |||
}); | |||
}; | |||
showHandler = ({ id }: { id: string }) => { | |||
const qualityGate = omit( | |||
this.list.find(q => q.id === id), | |||
this.list.find((q) => q.id === id), | |||
'isDefault' | |||
); | |||
return this.reply({ ...qualityGate, actions: this.computeActions(qualityGate) }); | |||
@@ -216,22 +216,22 @@ export class QualityGatesServiceMock { | |||
name, | |||
conditions: [], | |||
isDefault: false, | |||
isBuiltIn: false | |||
isBuiltIn: false, | |||
}) | |||
); | |||
return this.reply({ | |||
id: newId, | |||
name | |||
name, | |||
}); | |||
}; | |||
destroyHandler = ({ id }: { id: string }) => { | |||
this.list = this.list.filter(q => q.id !== id); | |||
this.list = this.list.filter((q) => q.id !== id); | |||
return Promise.resolve(); | |||
}; | |||
copyHandler = ({ id, name }: { id: string; name: string }) => { | |||
const newQG = cloneDeep(this.list.find(q => q.id === id)); | |||
const newQG = cloneDeep(this.list.find((q) => q.id === id)); | |||
if (newQG === undefined) { | |||
return Promise.reject({ errors: [{ msg: `No quality gate has been found for id ${id}` }] }); | |||
} | |||
@@ -245,27 +245,27 @@ export class QualityGatesServiceMock { | |||
return this.reply({ | |||
id: newQG.id, | |||
name | |||
name, | |||
}); | |||
}; | |||
renameHandler = ({ id, name }: { id: string; name: string }) => { | |||
const renameQG = this.list.find(q => q.id === id); | |||
const renameQG = this.list.find((q) => q.id === id); | |||
if (renameQG === undefined) { | |||
return Promise.reject({ errors: [{ msg: `No quality gate has been found for id ${id}` }] }); | |||
} | |||
renameQG.name = name; | |||
return this.reply({ | |||
id: renameQG.id, | |||
name | |||
name, | |||
}); | |||
}; | |||
setDefaultHandler = ({ id }: { id: string }) => { | |||
this.list.forEach(q => { | |||
this.list.forEach((q) => { | |||
q.isDefault = false; | |||
}); | |||
const selectedQG = this.list.find(q => q.id === id); | |||
const selectedQG = this.list.find((q) => q.id === id); | |||
if (selectedQG === undefined) { | |||
return Promise.reject({ errors: [{ msg: `No quality gate has been found for id ${id}` }] }); | |||
} | |||
@@ -279,10 +279,10 @@ export class QualityGatesServiceMock { | |||
} & Omit<Condition, 'id'> | |||
) => { | |||
const { metric, gateId, op, error } = data; | |||
const qg = this.list.find(q => q.id === gateId); | |||
const qg = this.list.find((q) => q.id === gateId); | |||
if (qg === undefined) { | |||
return Promise.reject({ | |||
errors: [{ msg: `No quality gate has been found for id ${gateId}` }] | |||
errors: [{ msg: `No quality gate has been found for id ${gateId}` }], | |||
}); | |||
} | |||
@@ -295,7 +295,7 @@ export class QualityGatesServiceMock { | |||
}; | |||
updateConditionHandler = ({ id, metric, op, error }: Condition) => { | |||
const condition = flatten(this.list.map(q => q.conditions || [])).find(q => q.id === id); | |||
const condition = flatten(this.list.map((q) => q.conditions || [])).find((q) => q.id === id); | |||
if (condition === undefined) { | |||
return Promise.reject({ errors: [{ msg: `No condition has been found for id ${id}` }] }); | |||
} | |||
@@ -308,33 +308,33 @@ export class QualityGatesServiceMock { | |||
}; | |||
deleteConditionHandler = ({ id }: { id: string }) => { | |||
this.list.forEach(q => { | |||
remove(q.conditions || [], c => c.id === id); | |||
this.list.forEach((q) => { | |||
remove(q.conditions || [], (c) => c.id === id); | |||
}); | |||
return Promise.resolve(); | |||
}; | |||
searchProjectsHandler = ({ | |||
selected, | |||
query | |||
query, | |||
}: { | |||
selected: string; | |||
query: string | undefined; | |||
}) => { | |||
let filteredProjects = this.projects; | |||
if (selected === 'selected') { | |||
filteredProjects = this.projects.filter(p => p.selected); | |||
filteredProjects = this.projects.filter((p) => p.selected); | |||
} else if (selected === 'deselected') { | |||
filteredProjects = this.projects.filter(p => !p.selected); | |||
filteredProjects = this.projects.filter((p) => !p.selected); | |||
} | |||
if (query !== '' && query !== undefined) { | |||
filteredProjects = filteredProjects.filter(p => p.name.includes(query)); | |||
filteredProjects = filteredProjects.filter((p) => p.name.includes(query)); | |||
} | |||
const response = { | |||
paging: { pageIndex: 1, pageSize: 3, total: 55 }, | |||
results: filteredProjects | |||
results: filteredProjects, | |||
}; | |||
return this.reply(response); | |||
}; | |||
@@ -356,7 +356,7 @@ export class QualityGatesServiceMock { | |||
}; | |||
selectHandler = ({ projectKey }: { projectKey: string }) => { | |||
const changedProject = this.projects.find(p => p.key === projectKey); | |||
const changedProject = this.projects.find((p) => p.key === projectKey); | |||
if (changedProject) { | |||
changedProject.selected = true; | |||
} | |||
@@ -364,7 +364,7 @@ export class QualityGatesServiceMock { | |||
}; | |||
deSelectHandler = ({ projectKey }: { projectKey: string }) => { | |||
const changedProject = this.projects.find(p => p.key === projectKey); | |||
const changedProject = this.projects.find((p) => p.key === projectKey); | |||
if (changedProject) { | |||
changedProject.selected = false; | |||
} |
@@ -39,7 +39,7 @@ export default class SecurityHotspotServiceMock { | |||
this.rawHotspotKey = Object.keys(mockRawHotspot()); | |||
this.hotspots = [ | |||
mockHotspot({ key: '1', status: HotspotStatus.TO_REVIEW }), | |||
mockHotspot({ key: '2', status: HotspotStatus.TO_REVIEW }) | |||
mockHotspot({ key: '2', status: HotspotStatus.TO_REVIEW }), | |||
]; | |||
(getMeasures as jest.Mock).mockImplementation(this.handleGetMeasures); | |||
@@ -49,10 +49,10 @@ export default class SecurityHotspotServiceMock { | |||
); | |||
(getRuleDetails as jest.Mock).mockResolvedValue({ rule: mockRuleDetails() }); | |||
(getSources as jest.Mock).mockResolvedValue( | |||
times(NUMBER_OF_LINES, n => | |||
times(NUMBER_OF_LINES, (n) => | |||
mockSourceLine({ | |||
line: n, | |||
code: ' <span class="sym-35 sym">symbole</span>' | |||
code: ' <span class="sym-35 sym">symbole</span>', | |||
}) | |||
) | |||
); | |||
@@ -60,7 +60,7 @@ export default class SecurityHotspotServiceMock { | |||
handleGetSources = (data: { key: string; from?: number; to?: number } & BranchParameters) => { | |||
return this.reply( | |||
range(data.from || 1, data.to || MAX_END_RANGE).map(line => mockSourceLine({ line })) | |||
range(data.from || 1, data.to || MAX_END_RANGE).map((line) => mockSourceLine({ line })) | |||
); | |||
}; | |||
@@ -77,31 +77,31 @@ export default class SecurityHotspotServiceMock { | |||
) => { | |||
return this.reply({ | |||
paging: { pageIndex: 1, pageSize: data.ps, total: this.hotspots.length }, | |||
hotspots: this.hotspots.map(hotspot => pick(hotspot, this.rawHotspotKey)), | |||
hotspots: this.hotspots.map((hotspot) => pick(hotspot, this.rawHotspotKey)), | |||
components: [ | |||
{ | |||
key: 'guillaume-peoch-sonarsource_benflix_AYGpXq2bd8qy4i0eO9ed:index.php', | |||
qualifier: 'FIL', | |||
name: 'index.php', | |||
longName: 'index.php', | |||
path: 'index.php' | |||
path: 'index.php', | |||
}, | |||
{ | |||
key: 'guillaume-peoch-sonarsource_benflix_AYGpXq2bd8qy4i0eO9ed', | |||
qualifier: 'TRK', | |||
name: 'benflix', | |||
longName: 'benflix' | |||
} | |||
] | |||
longName: 'benflix', | |||
}, | |||
], | |||
}); | |||
}; | |||
handleGetSecurityHotspotDetails = (securityHotspotKey: string) => { | |||
const hotspot = this.hotspots.find(h => h.key === securityHotspotKey); | |||
const hotspot = this.hotspots.find((h) => h.key === securityHotspotKey); | |||
if (hotspot === undefined) { | |||
return Promise.reject({ | |||
errors: [{ msg: `No security hotspot for key ${securityHotspotKey}` }] | |||
errors: [{ msg: `No security hotspot for key ${securityHotspotKey}` }], | |||
}); | |||
} | |||
@@ -115,9 +115,9 @@ export default class SecurityHotspotServiceMock { | |||
key: 'guillaume-peoch-sonarsource_benflix_AYGpXq2bd8qy4i0eO9ed', | |||
name: 'benflix', | |||
qualifier: 'TRK', | |||
measures: [{ metric: 'security_hotspots_reviewed', value: '0.0', bestValue: false }] | |||
} | |||
} | |||
measures: [{ metric: 'security_hotspots_reviewed', value: '0.0', bestValue: false }], | |||
}, | |||
}, | |||
]); | |||
}; | |||
@@ -129,7 +129,7 @@ export default class SecurityHotspotServiceMock { | |||
this.rawHotspotKey = Object.keys(mockRawHotspot()); | |||
this.hotspots = [ | |||
mockHotspot({ key: '1', status: HotspotStatus.TO_REVIEW }), | |||
mockHotspot({ key: '2', status: HotspotStatus.TO_REVIEW }) | |||
mockHotspot({ key: '2', status: HotspotStatus.TO_REVIEW }), | |||
]; | |||
}; | |||
} |
@@ -28,8 +28,8 @@ export default class SettingsServiceMock { | |||
defaultValues: SettingValue[] = [ | |||
{ | |||
key: SettingsKey.AuditHouseKeeping, | |||
value: HousekeepingPolicy.Weekly | |||
} | |||
value: HousekeepingPolicy.Weekly, | |||
}, | |||
]; | |||
constructor() { | |||
@@ -40,12 +40,12 @@ export default class SettingsServiceMock { | |||
} | |||
handleGetValue = (data: { key: string; component?: string } & BranchParameters) => { | |||
const setting = this.settingValues.find(s => s.key === data.key); | |||
const setting = this.settingValues.find((s) => s.key === data.key); | |||
return this.reply(setting); | |||
}; | |||
handleGetValues = (data: { keys: string[]; component?: string } & BranchParameters) => { | |||
const settings = this.settingValues.filter(s => data.keys.includes(s.key)); | |||
const settings = this.settingValues.filter((s) => data.keys.includes(s.key)); | |||
return this.reply(settings); | |||
}; | |||
@@ -59,7 +59,7 @@ export default class SettingsServiceMock { | |||
}; | |||
set = (key: SettingsKey, value: string) => { | |||
const setting = this.settingValues.find(s => s.key === key); | |||
const setting = this.settingValues.find((s) => s.key === key); | |||
if (setting) { | |||
setting.value = value; | |||
} else { |
@@ -24,7 +24,7 @@ import { | |||
getComponentData, | |||
getComponentForSourceViewer, | |||
getDuplications, | |||
getSources | |||
getSources, | |||
} from '../../api/components'; | |||
import { mockSourceLine } from '../../helpers/mocks/sources'; | |||
import { HttpStatus } from '../../helpers/request'; | |||
@@ -43,7 +43,7 @@ function mockSourceFileView(name: string, project = 'project') { | |||
analysisDate: '2019-08-08T12:15:12+0200', | |||
leakPeriodDate: '2018-08-07T11:22:22+0200', | |||
version: '1.2-SNAPSHOT', | |||
needIssueSync: false | |||
needIssueSync: false, | |||
}, | |||
sourceFileView: { | |||
key: `${project}:${name}`, | |||
@@ -56,8 +56,8 @@ function mockSourceFileView(name: string, project = 'project') { | |||
projectName: 'Test project', | |||
fav: false, | |||
canMarkAsFavorite: true, | |||
measures: { lines: '0', issues: '0' } | |||
} | |||
measures: { lines: '0', issues: '0' }, | |||
}, | |||
}; | |||
} | |||
@@ -72,44 +72,44 @@ const ANCESTORS = [ | |||
visibility: 'public', | |||
leakPeriodDate: '2018-08-07T11:22:22+0200', | |||
version: '1.2-SNAPSHOT', | |||
needIssueSync: false | |||
} | |||
needIssueSync: false, | |||
}, | |||
]; | |||
const FILES: Dict<any> = { | |||
'project:test3.js': { | |||
...mockSourceFileView('test3.js'), | |||
sources: [], | |||
ancestors: ANCESTORS | |||
ancestors: ANCESTORS, | |||
}, | |||
'project:test2.js': { | |||
...mockSourceFileView('test2.js'), | |||
sources: times(200, n => | |||
sources: times(200, (n) => | |||
mockSourceLine({ | |||
line: n, | |||
code: `\u003cspan class\u003d"cd"\u003eLine ${n}\u003c/span\u003e` | |||
code: `\u003cspan class\u003d"cd"\u003eLine ${n}\u003c/span\u003e`, | |||
}) | |||
), | |||
ancestors: ANCESTORS | |||
ancestors: ANCESTORS, | |||
}, | |||
'foo:index.tsx': { | |||
...mockSourceFileView('index.tsx', 'foo'), | |||
sources: times(200, n => | |||
sources: times(200, (n) => | |||
mockSourceLine({ | |||
line: n, | |||
code: 'function Test() {}' | |||
code: 'function Test() {}', | |||
}) | |||
), | |||
ancestors: ANCESTORS | |||
ancestors: ANCESTORS, | |||
}, | |||
'project:testSymb.tsx': { | |||
...mockSourceFileView('testSymb.tsx'), | |||
sources: times(20, n => | |||
sources: times(20, (n) => | |||
mockSourceLine({ | |||
line: n, | |||
code: ' <span class="sym-35 sym">symbole</span>' | |||
code: ' <span class="sym-35 sym">symbole</span>', | |||
}) | |||
), | |||
ancestors: ANCESTORS | |||
ancestors: ANCESTORS, | |||
}, | |||
'project:test.js': { | |||
...mockSourceFileView('test.js'), | |||
@@ -123,7 +123,7 @@ const FILES: Dict<any> = { | |||
duplicated: false, | |||
isNew: false, | |||
lineHits: 1, | |||
coveredConditions: 1 | |||
coveredConditions: 1, | |||
}, | |||
{ | |||
line: 2, | |||
@@ -134,7 +134,7 @@ const FILES: Dict<any> = { | |||
duplicated: false, | |||
isNew: false, | |||
lineHits: 0, | |||
conditions: 1 | |||
conditions: 1, | |||
}, | |||
{ | |||
line: 3, | |||
@@ -144,19 +144,18 @@ const FILES: Dict<any> = { | |||
scmDate: '2022-01-28T21:03:07+0100', | |||
duplicated: false, | |||
isNew: false, | |||
lineHits: 1 | |||
lineHits: 1, | |||
}, | |||
{ | |||
line: 4, | |||
code: | |||
'\u003cspan class\u003d"cd"\u003e * mailto:info AT sonarsource DOT com\u003c/span\u003e', | |||
code: '\u003cspan class\u003d"cd"\u003e * mailto:info AT sonarsource DOT com\u003c/span\u003e', | |||
scmRevision: 'f09ee6b610528aa37b7b51be395c93524cebae8f', | |||
scmAuthor: 'stas.vilchik@sonarsource.com', | |||
duplicated: false, | |||
isNew: false, | |||
lineHits: 1, | |||
conditions: 1, | |||
coveredConditions: 1 | |||
coveredConditions: 1, | |||
}, | |||
{ | |||
line: 5, | |||
@@ -166,7 +165,7 @@ const FILES: Dict<any> = { | |||
isNew: false, | |||
lineHits: 2, | |||
conditions: 2, | |||
coveredConditions: 1 | |||
coveredConditions: 1, | |||
}, | |||
{ | |||
line: 6, | |||
@@ -174,33 +173,32 @@ const FILES: Dict<any> = { | |||
scmRevision: 'f04ee6b610528aa37b7b51be395c93524cebae8f', | |||
duplicated: false, | |||
isNew: false, | |||
lineHits: 0 | |||
lineHits: 0, | |||
}, | |||
{ | |||
line: 7, | |||
code: '\u003cspan class\u003d"cd"\u003e * 7\u003c/span\u003e', | |||
scmRevision: 'f04ee6b610528aa37b7b51be395c93524cebae8f', | |||
duplicated: true, | |||
isNew: true | |||
isNew: true, | |||
}, | |||
{ | |||
code: | |||
'\u003cspan class\u003d"cd"\u003e * This program is free software; you can redistribute it and/or\u003c/span\u003e', | |||
code: '\u003cspan class\u003d"cd"\u003e * This program is free software; you can redistribute it and/or\u003c/span\u003e', | |||
scmRevision: 'f09ee6b610528aa37b7b51be395c93524cebae8f', | |||
scmAuthor: 'stas.vilchik@sonarsource.com', | |||
scmDate: '2018-07-10T20:21:20+0200', | |||
duplicated: false, | |||
isNew: false | |||
} | |||
isNew: false, | |||
}, | |||
], | |||
ancestors: ANCESTORS, | |||
duplications: [ | |||
{ | |||
blocks: [ | |||
{ from: 7, size: 1, _ref: '1' }, | |||
{ from: 1, size: 1, _ref: '2' } | |||
] | |||
} | |||
{ from: 1, size: 1, _ref: '2' }, | |||
], | |||
}, | |||
], | |||
files: { | |||
'1': { | |||
@@ -209,7 +207,7 @@ const FILES: Dict<any> = { | |||
uuid: 'AX8NSmj8EGYw5-dyy63J', | |||
project: 'project', | |||
projectUuid: 'AX7juKJqVeQLJMPyb_b-', | |||
projectName: 'project' | |||
projectName: 'project', | |||
}, | |||
'2': { | |||
key: 'project:test2.js', | |||
@@ -217,10 +215,10 @@ const FILES: Dict<any> = { | |||
uuid: 'BX8NSmj8EGYw5-dyy63J', | |||
project: 'project', | |||
projectUuid: 'AX7juKJqVeQLJMPyb_b-', | |||
projectName: 'project' | |||
} | |||
} | |||
} | |||
projectName: 'project', | |||
}, | |||
}, | |||
}, | |||
}; | |||
export class SourceViewerServiceMock { |
@@ -30,12 +30,12 @@ const defaultTokens = [ | |||
mockUserToken({ | |||
name: 'local-scanner', | |||
createdAt: '2022-03-07T09:02:59+0000', | |||
lastConnectionDate: '2022-04-07T09:51:48+0000' | |||
lastConnectionDate: '2022-04-07T09:51:48+0000', | |||
}), | |||
mockUserToken({ | |||
name: 'test', | |||
createdAt: '2020-01-23T19:25:19+0000' | |||
}) | |||
createdAt: '2020-01-23T19:25:19+0000', | |||
}), | |||
]; | |||
export default class UserTokensMock { | |||
@@ -59,7 +59,7 @@ export default class UserTokensMock { | |||
login, | |||
type, | |||
projectKey, | |||
expirationDate | |||
expirationDate, | |||
}: { | |||
name: string; | |||
login?: string; | |||
@@ -78,11 +78,9 @@ export default class UserTokensMock { | |||
type, | |||
projectKey, | |||
isExpired: false, | |||
token: Math.random() | |||
.toString(RANDOM_RADIX) | |||
.slice(RANDOM_PREFIX), | |||
token: Math.random().toString(RANDOM_RADIX).slice(RANDOM_PREFIX), | |||
createdAt: '2022-04-04T04:04:04+0000', | |||
expirationDate | |||
expirationDate, | |||
}; | |||
this.tokens.push(token); | |||
@@ -91,7 +89,7 @@ export default class UserTokensMock { | |||
}; | |||
handleRevokeToken = ({ name }: { name: string; login?: string }) => { | |||
const index = this.tokens.findIndex(t => t.name === name); | |||
const index = this.tokens.findIndex((t) => t.name === name); | |||
if (index < 0) { | |||
return Promise.resolve(); |
@@ -24,7 +24,7 @@ import { | |||
PermissionGroup, | |||
PermissionTemplate, | |||
PermissionUser, | |||
Visibility | |||
Visibility, | |||
} from '../types/types'; | |||
import { BaseSearchProjectsParameters } from './components'; | |||
@@ -197,7 +197,7 @@ export function getPermissionTemplateUsers( | |||
if (permission) { | |||
data.permission = permission; | |||
} | |||
return getJSON('/api/permissions/template_users', data).then(r => r.users); | |||
return getJSON('/api/permissions/template_users', data).then((r) => r.users); | |||
} | |||
export function getPermissionTemplateGroups( | |||
@@ -212,7 +212,7 @@ export function getPermissionTemplateGroups( | |||
if (permission) { | |||
data.permission = permission; | |||
} | |||
return getJSON('/api/permissions/template_groups', data).then(r => r.groups); | |||
return getJSON('/api/permissions/template_groups', data).then((r) => r.groups); | |||
} | |||
export function changeProjectVisibility( |
@@ -26,7 +26,7 @@ import { | |||
InstalledPlugin, | |||
PendingPluginResult, | |||
PluginType, | |||
Update | |||
Update, | |||
} from '../types/plugins'; | |||
export function getAvailablePlugins(): Promise<{ | |||
@@ -45,8 +45,8 @@ function getLastUpdates(updates: undefined | Update[]): Update[] { | |||
return []; | |||
} | |||
const lastUpdate = ['COMPATIBLE', 'REQUIRES_SYSTEM_UPGRADE', 'DEPS_REQUIRE_SYSTEM_UPGRADE'].map( | |||
status => { | |||
const index = findLastIndex(updates, update => update.status === status); | |||
(status) => { | |||
const index = findLastIndex(updates, (update) => update.status === status); | |||
return index > -1 ? updates[index] : undefined; | |||
} | |||
); | |||
@@ -87,9 +87,9 @@ export function getInstalledPluginsWithUpdates(): Promise<InstalledPlugin[]> { | |||
return { | |||
...updatePlugin, | |||
...plugin, | |||
updates: getLastUpdates(updatePlugin.updates).map(update => | |||
updates: getLastUpdates(updatePlugin.updates).map((update) => | |||
addChangelog(update, updatePlugin.updates) | |||
) | |||
), | |||
}; | |||
} | |||
return plugin; | |||
@@ -102,7 +102,7 @@ export function getPluginUpdates(): Promise<InstalledPlugin[]> { | |||
return Promise.all([getUpdatesPluginApi(), getInstalledPluginApi()]) | |||
.then(([updates, installed]) => | |||
updates.plugins.map((updatePlugin: InstalledPlugin) => { | |||
const updates = getLastUpdates(updatePlugin.updates).map(update => | |||
const updates = getLastUpdates(updatePlugin.updates).map((update) => | |||
addChangelog(update, updatePlugin.updates) | |||
); | |||
const plugin = installed.plugins.find((p: InstalledPlugin) => p.key === updatePlugin.key); | |||
@@ -110,7 +110,7 @@ export function getPluginUpdates(): Promise<InstalledPlugin[]> { | |||
return { | |||
...plugin, | |||
...updatePlugin, | |||
updates | |||
updates, | |||
}; | |||
} | |||
return { ...updatePlugin, updates }; |
@@ -26,7 +26,7 @@ import { Paging } from '../types/types'; | |||
export enum ProjectActivityStatuses { | |||
STATUS_PROCESSED = 'P', | |||
STATUS_UNPROCESSED = 'U', | |||
STATUS_LIVE_MEASURE_COMPUTE = 'L' | |||
STATUS_LIVE_MEASURE_COMPUTE = 'L', | |||
} | |||
export function getProjectActivity( | |||
@@ -63,7 +63,10 @@ export function createEvent( | |||
if (description) { | |||
data.description = description; | |||
} | |||
return postJSON('/api/project_analyses/create_event', data).then(r => r.event, throwGlobalError); | |||
return postJSON('/api/project_analyses/create_event', data).then( | |||
(r) => r.event, | |||
throwGlobalError | |||
); | |||
} | |||
export function deleteEvent(event: string): Promise<void | Response> { | |||
@@ -82,7 +85,10 @@ export function changeEvent( | |||
if (description) { | |||
data.description = description; | |||
} | |||
return postJSON('/api/project_analyses/update_event', data).then(r => r.event, throwGlobalError); | |||
return postJSON('/api/project_analyses/update_event', data).then( | |||
(r) => r.event, | |||
throwGlobalError | |||
); | |||
} | |||
export function deleteAnalysis(analysis: string): Promise<void | Response> { |
@@ -22,7 +22,10 @@ import { getJSON, post, postJSON } from '../helpers/request'; | |||
import { ProjectLink } from '../types/types'; | |||
export function getProjectLinks(projectKey: string): Promise<ProjectLink[]> { | |||
return getJSON('/api/project_links/search', { projectKey }).then(r => r.links, throwGlobalError); | |||
return getJSON('/api/project_links/search', { projectKey }).then( | |||
(r) => r.links, | |||
throwGlobalError | |||
); | |||
} | |||
export function deleteLink(linkId: string) { | |||
@@ -34,5 +37,5 @@ export function createLink(data: { | |||
projectKey: string; | |||
url: string; | |||
}): Promise<ProjectLink> { | |||
return postJSON('/api/project_links/create', data).then(r => r.link, throwGlobalError); | |||
return postJSON('/api/project_links/create', data).then((r) => r.link, throwGlobalError); | |||
} |
@@ -26,7 +26,7 @@ import { | |||
Group, | |||
QualityGateApplicationStatus, | |||
QualityGateProjectStatus, | |||
SearchPermissionsParameters | |||
SearchPermissionsParameters, | |||
} from '../types/quality-gates'; | |||
import { Condition, Paging, QualityGate } from '../types/types'; | |||
import { UserBase } from '../types/users'; | |||
@@ -83,7 +83,7 @@ export function getGateForProject(data: { project: string }): Promise<QualityGat | |||
({ qualityGate }) => | |||
qualityGate && { | |||
...qualityGate, | |||
isDefault: qualityGate.default | |||
isDefault: qualityGate.default, | |||
}, | |||
throwGlobalError | |||
); | |||
@@ -130,7 +130,7 @@ export function getQualityGateProjectStatus( | |||
} & BranchParameters | |||
): Promise<QualityGateProjectStatus> { | |||
return getJSON('/api/qualitygates/project_status', data) | |||
.then(r => r.projectStatus) | |||
.then((r) => r.projectStatus) | |||
.catch(throwGlobalError); | |||
} | |||
@@ -75,7 +75,7 @@ export function searchQualityProfiles( | |||
export function getQualityProfile({ | |||
compareToSonarWay, | |||
profile: { key } | |||
profile: { key }, | |||
}: { | |||
compareToSonarWay?: boolean; | |||
profile: Profile; | |||
@@ -103,24 +103,21 @@ export function getProfileProjects( | |||
return getJSON('/api/qualityprofiles/projects', data).catch(throwGlobalError); | |||
} | |||
export function getProfileInheritance({ | |||
language, | |||
name: qualityProfile | |||
}: Profile): Promise<{ | |||
export function getProfileInheritance({ language, name: qualityProfile }: Profile): Promise<{ | |||
ancestors: ProfileInheritanceDetails[]; | |||
children: ProfileInheritanceDetails[]; | |||
profile: ProfileInheritanceDetails; | |||
}> { | |||
return getJSON('/api/qualityprofiles/inheritance', { | |||
language, | |||
qualityProfile | |||
qualityProfile, | |||
}).catch(throwGlobalError); | |||
} | |||
export function setDefaultProfile({ language, name: qualityProfile }: Profile) { | |||
return post('/api/qualityprofiles/set_default', { | |||
language, | |||
qualityProfile | |||
qualityProfile, | |||
}); | |||
} | |||
@@ -143,7 +140,7 @@ export function changeProfileParent( | |||
return post('/api/qualityprofiles/change_parent', { | |||
language, | |||
qualityProfile, | |||
parentQualityProfile: parentProfile ? parentProfile.name : undefined | |||
parentQualityProfile: parentProfile ? parentProfile.name : undefined, | |||
}).catch(throwGlobalError); | |||
} | |||
@@ -167,11 +164,11 @@ export function getQualityProfileExporterUrl( | |||
export function getImporters(): Promise< | |||
Array<{ key: string; languages: Array<string>; name: string }> | |||
> { | |||
return getJSON('/api/qualityprofiles/importers').then(r => r.importers, throwGlobalError); | |||
return getJSON('/api/qualityprofiles/importers').then((r) => r.importers, throwGlobalError); | |||
} | |||
export function getExporters(): Promise<any> { | |||
return getJSON('/api/qualityprofiles/exporters').then(r => r.exporters); | |||
return getJSON('/api/qualityprofiles/exporters').then((r) => r.exporters); | |||
} | |||
export function getProfileChangelog( | |||
@@ -190,7 +187,7 @@ export function getProfileChangelog( | |||
to, | |||
language, | |||
qualityProfile, | |||
p: page | |||
p: page, | |||
}); | |||
} | |||
@@ -215,7 +212,7 @@ export function associateProject({ language, name: qualityProfile }: Profile, pr | |||
return post('/api/qualityprofiles/add_project', { | |||
language, | |||
qualityProfile, | |||
project | |||
project, | |||
}).catch(throwGlobalError); | |||
} | |||
@@ -223,7 +220,7 @@ export function dissociateProject({ language, name: qualityProfile }: Profile, p | |||
return post('/api/qualityprofiles/remove_project', { | |||
language, | |||
qualityProfile, | |||
project | |||
project, | |||
}).catch(throwGlobalError); | |||
} | |||
@@ -32,7 +32,7 @@ export function searchRules(data: SearchRulesQuery): Promise<SearchRulesResponse | |||
} | |||
export function takeFacet(response: SearchRulesResponse, property: string) { | |||
const facet = response.facets?.find(f => f.property === property); | |||
const facet = response.facets?.find((f) => f.property === property); | |||
return facet ? facet.values : []; | |||
} | |||
@@ -53,7 +53,7 @@ export function getRuleDetails(parameters: { | |||
} | |||
export function getRuleTags(parameters: { ps?: number; q: string }): Promise<string[]> { | |||
return getJSON('/api/rules/tags', parameters).then(r => r.tags, throwGlobalError); | |||
return getJSON('/api/rules/tags', parameters).then((r) => r.tags, throwGlobalError); | |||
} | |||
export function createRule(data: { | |||
@@ -68,8 +68,8 @@ export function createRule(data: { | |||
type?: string; | |||
}): Promise<RuleDetails> { | |||
return postJSON('/api/rules/create', data).then( | |||
r => r.rule, | |||
response => { | |||
(r) => r.rule, | |||
(response) => { | |||
// do not show global error if the status code is 409 | |||
// this case should be handled inside a component | |||
if (response && response.status === 409) { | |||
@@ -86,5 +86,5 @@ export function deleteRule(parameters: { key: string }) { | |||
} | |||
export function updateRule(data: RulesUpdateRequest): Promise<RuleDetails> { | |||
return postJSON('/api/rules/update', data).then(r => r.rule, throwGlobalError); | |||
return postJSON('/api/rules/update', data).then((r) => r.rule, throwGlobalError); | |||
} |
@@ -27,7 +27,7 @@ import { | |||
HotspotResolution, | |||
HotspotSearchResponse, | |||
HotspotSetStatusRequest, | |||
HotspotStatus | |||
HotspotStatus, | |||
} from '../types/security-hotspots'; | |||
import { UserBase } from '../types/users'; | |||
@@ -100,17 +100,17 @@ export function getSecurityHotspotDetails(securityHotspotKey: string): Promise<H | |||
if (users) { | |||
if (hotspot.assignee) { | |||
hotspot.assigneeUser = users.find(u => u.login === hotspot.assignee) || { | |||
hotspot.assigneeUser = users.find((u) => u.login === hotspot.assignee) || { | |||
active: true, | |||
login: hotspot.assignee | |||
login: hotspot.assignee, | |||
}; | |||
} | |||
hotspot.authorUser = users.find(u => u.login === hotspot.author) || { | |||
hotspot.authorUser = users.find((u) => u.login === hotspot.author) || { | |||
active: true, | |||
login: hotspot.author | |||
login: hotspot.author, | |||
}; | |||
hotspot.comment.forEach(c => { | |||
c.user = users.find(u => u.login === c.login) || { active: true, login: c.login }; | |||
hotspot.comment.forEach((c) => { | |||
c.user = users.find((u) => u.login === c.login) || { active: true, login: c.login }; | |||
}); | |||
} | |||
@@ -26,12 +26,12 @@ import { | |||
ExtendedSettingDefinition, | |||
SettingDefinition, | |||
SettingValue, | |||
SettingValueResponse | |||
SettingValueResponse, | |||
} from '../types/settings'; | |||
export function getDefinitions(component?: string): Promise<ExtendedSettingDefinition[]> { | |||
return getJSON('/api/settings/list_definitions', { component }).then( | |||
r => r.definitions, | |||
(r) => r.definitions, | |||
throwGlobalError | |||
); | |||
} | |||
@@ -47,10 +47,10 @@ export function getValues( | |||
): Promise<SettingValue[]> { | |||
return getJSON('/api/settings/values', { | |||
keys: data.keys.join(','), | |||
component: data.component | |||
component: data.component, | |||
}).then((r: SettingValueResponse) => [ | |||
...r.settings, | |||
...r.setSecuredSettings.map(key => ({ key })) | |||
...r.setSecuredSettings.map((key) => ({ key })), | |||
]); | |||
} | |||
@@ -59,7 +59,7 @@ export function getAllValues( | |||
): Promise<SettingValue[]> { | |||
return getJSON('/api/settings/values', data).then((r: SettingValueResponse) => [ | |||
...r.settings, | |||
...r.setSecuredSettings.map(key => ({ key })) | |||
...r.setSecuredSettings.map((key) => ({ key })), | |||
]); | |||
} | |||
@@ -75,7 +75,7 @@ export function setSettingValue( | |||
data.values = value; | |||
} else if (definition.type === 'PROPERTY_SET') { | |||
data.fieldValues = value | |||
.map((fields: any) => omitBy(fields, value => value == null)) | |||
.map((fields: any) => omitBy(fields, (value) => value == null)) | |||
.map(JSON.stringify); | |||
} else { | |||
data.value = value; |
@@ -23,5 +23,5 @@ export function getPluginStaticFileContent(pluginKey: string, staticFilePath: st | |||
return request(`/static/${pluginKey}/${staticFilePath}`) | |||
.submit() | |||
.then(checkStatus) | |||
.then(response => response.text()); | |||
.then((response) => response.text()); | |||
} |
@@ -53,14 +53,14 @@ export function getAllTimeMachineData( | |||
} & BranchParameters, | |||
prev?: TimeMachineResponse | |||
): Promise<TimeMachineResponse> { | |||
return getTimeMachineData({ ...data, ps: 1000 }).then(r => { | |||
return getTimeMachineData({ ...data, ps: 1000 }).then((r) => { | |||
const result = prev | |||
? { | |||
measures: prev.measures.map((measure, idx) => ({ | |||
...measure, | |||
history: measure.history.concat(r.measures[idx].history) | |||
history: measure.history.concat(r.measures[idx].history), | |||
})), | |||
paging: r.paging | |||
paging: r.paging, | |||
} | |||
: r; | |||
@@ -23,7 +23,7 @@ import { NewUserToken, UserToken } from '../types/token'; | |||
/** List tokens for given user login */ | |||
export function getTokens(login: string): Promise<UserToken[]> { | |||
return getJSON('/api/user_tokens/search', { login }).then(r => r.userTokens, throwGlobalError); | |||
return getJSON('/api/user_tokens/search', { login }).then((r) => r.userTokens, throwGlobalError); | |||
} | |||
export function generateToken(data: { |
@@ -50,7 +50,7 @@ export function removeUserFromGroup(data: { id?: string; name?: string; login?: | |||
} | |||
export function createGroup(data: { description?: string; name: string }): Promise<Group> { | |||
return postJSON('/api/user_groups/create', data).then(r => r.group, throwGlobalError); | |||
return postJSON('/api/user_groups/create', data).then((r) => r.group, throwGlobalError); | |||
} | |||
export function updateGroup(data: { description?: string; id: number; name?: string }) { |
@@ -88,7 +88,7 @@ export function updateUser(data: { | |||
}): Promise<User> { | |||
return postJSON('/api/users/update', { | |||
...data, | |||
scmAccount: data.scmAccount.length > 0 ? data.scmAccount : '' | |||
scmAccount: data.scmAccount.length > 0 ? data.scmAccount : '', | |||
}); | |||
} | |||
@@ -32,7 +32,7 @@ interface RawDomain { | |||
export function fetchWebApi(showInternal = true): Promise<RawDomain[]> { | |||
return getJSON('/api/webservices/list', { include_internals: showInternal }) | |||
.then(r => r.webServices) | |||
.then((r) => r.webServices) | |||
.catch(throwGlobalError); | |||
} | |||
@@ -48,7 +48,7 @@ export class AdminContainer extends React.PureComponent<AdminContainerProps, Sta | |||
state: State = { | |||
pendingPlugins: defaultPendingPlugins, | |||
systemStatus: defaultSystemStatus, | |||
adminPages: [] | |||
adminPages: [], | |||
}; | |||
componentDidMount() { | |||
@@ -68,14 +68,14 @@ export class AdminContainer extends React.PureComponent<AdminContainerProps, Sta | |||
fetchNavigationSettings = () => { | |||
getSettingsNavigation().then( | |||
r => this.setState({ adminPages: r.extensions }), | |||
(r) => this.setState({ adminPages: r.extensions }), | |||
() => {} | |||
); | |||
}; | |||
fetchPendingPlugins = () => { | |||
getPendingPlugins().then( | |||
pendingPlugins => { | |||
(pendingPlugins) => { | |||
if (this.mounted) { | |||
this.setState({ pendingPlugins }); | |||
} | |||
@@ -138,8 +138,9 @@ export class AdminContainer extends React.PureComponent<AdminContainerProps, Sta | |||
fetchSystemStatus: this.fetchSystemStatus, | |||
fetchPendingPlugins: this.fetchPendingPlugins, | |||
pendingPlugins, | |||
systemStatus | |||
}}> | |||
systemStatus, | |||
}} | |||
> | |||
<Outlet context={adminPagesContext} /> | |||
</AdminContext.Provider> | |||
</div> |
@@ -35,6 +35,6 @@ const AdminContext = React.createContext<AdminContextInterface>({ | |||
fetchSystemStatus: () => {}, | |||
fetchPendingPlugins: () => {}, | |||
pendingPlugins: defaultPendingPlugins, | |||
systemStatus: defaultSystemStatus | |||
systemStatus: defaultSystemStatus, | |||
}); | |||
export default AdminContext; |
@@ -68,7 +68,7 @@ export class App extends React.PureComponent<Props> { | |||
renderPreconnectLink = () => { | |||
const { | |||
appState: { settings } | |||
appState: { settings }, | |||
} = this.props; | |||
const enableGravatar = settings[GlobalSettingKeys.EnableGravatar] === 'true'; |
@@ -30,13 +30,13 @@ import { | |||
getBranchLikeQuery, | |||
isBranch, | |||
isMainBranch, | |||
isPullRequest | |||
isPullRequest, | |||
} from '../../helpers/branch-like'; | |||
import { HttpStatus } from '../../helpers/request'; | |||
import { getPortfolioUrl } from '../../helpers/urls'; | |||
import { | |||
ProjectAlmBindingConfigurationErrors, | |||
ProjectAlmBindingResponse | |||
ProjectAlmBindingResponse, | |||
} from '../../types/alm-settings'; | |||
import { BranchLike } from '../../types/branch-like'; | |||
import { ComponentQualifier, isPortfolioLike } from '../../types/component'; | |||
@@ -45,7 +45,7 @@ import { Task, TaskStatuses, TaskTypes, TaskWarning } from '../../types/tasks'; | |||
import { Component, Status } from '../../types/types'; | |||
import handleRequiredAuthorization from '../utils/handleRequiredAuthorization'; | |||
import withAvailableFeatures, { | |||
WithAvailableFeaturesProps | |||
WithAvailableFeaturesProps, | |||
} from './available-features/withAvailableFeatures'; | |||
import withBranchStatusActions from './branch-status/withBranchStatusActions'; | |||
import ComponentContainerNotFound from './ComponentContainerNotFound'; | |||
@@ -107,7 +107,7 @@ export class ComponentContainer extends React.PureComponent<Props, State> { | |||
try { | |||
const [nav, { component }] = await Promise.all([ | |||
getComponentNavigation({ component: key, branch, pullRequest }), | |||
getComponentData({ component: key, branch, pullRequest }) | |||
getComponentData({ component: key, branch, pullRequest }), | |||
]); | |||
componentWithQualifier = this.addQualifier({ ...nav, ...component }); | |||
} catch (e) { | |||
@@ -146,7 +146,7 @@ export class ComponentContainer extends React.PureComponent<Props, State> { | |||
branchLikes, | |||
component: componentWithQualifier, | |||
projectBinding, | |||
loading: false | |||
loading: false, | |||
}); | |||
this.fetchStatus(componentWithQualifier.key); | |||
@@ -174,7 +174,7 @@ export class ComponentContainer extends React.PureComponent<Props, State> { | |||
!hasFeature(Feature.BranchSupport) || | |||
breadcrumb.qualifier === ComponentQualifier.Application | |||
? Promise.resolve([]) | |||
: getPullRequests(key) | |||
: getPullRequests(key), | |||
]); | |||
branchLikes = [...branches, ...pullRequests]; | |||
@@ -214,11 +214,11 @@ export class ComponentContainer extends React.PureComponent<Props, State> { | |||
); | |||
} | |||
const isPending = pendingTasks.some(task => task.status === TaskStatuses.Pending); | |||
const isPending = pendingTasks.some((task) => task.status === TaskStatuses.Pending); | |||
return { | |||
currentTask: newCurrentTask, | |||
isPending, | |||
tasksInProgress: newTasksInProgress | |||
tasksInProgress: newTasksInProgress, | |||
}; | |||
}, | |||
() => { | |||
@@ -237,7 +237,7 @@ export class ComponentContainer extends React.PureComponent<Props, State> { | |||
if (component.qualifier === ComponentQualifier.Project) { | |||
getAnalysisStatus({ | |||
component: component.key, | |||
...getBranchLikeQuery(branchLike) | |||
...getBranchLikeQuery(branchLike), | |||
}).then( | |||
({ component }) => { | |||
this.setState({ warnings: component.warnings }); | |||
@@ -264,14 +264,14 @@ export class ComponentContainer extends React.PureComponent<Props, State> { | |||
addQualifier = (component: Component) => ({ | |||
...component, | |||
qualifier: component.breadcrumbs[component.breadcrumbs.length - 1].qualifier | |||
qualifier: component.breadcrumbs[component.breadcrumbs.length - 1].qualifier, | |||
}); | |||
getCurrentBranchLike = (branchLikes: BranchLike[]) => { | |||
const { query } = this.props.location; | |||
return 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) => isPullRequest(b) && b.key === query.pullRequest) | |||
: branchLikes.find((b) => isBranch(b) && (query.branch ? b.name === query.branch : b.isMain)); | |||
}; | |||
getCurrentTask = (current: Task, branchLike?: BranchLike) => { | |||
@@ -286,12 +286,12 @@ export class ComponentContainer extends React.PureComponent<Props, State> { | |||
getPendingTasksForBranchLike = (pendingTasks: Task[], branchLike?: BranchLike) => { | |||
return pendingTasks.filter( | |||
task => this.isReportRelatedTask(task) && this.isSameBranch(task, branchLike) | |||
(task) => this.isReportRelatedTask(task) && this.isSameBranch(task, branchLike) | |||
); | |||
}; | |||
getInProgressTasks = (pendingTasks: Task[]) => { | |||
return pendingTasks.filter(task => task.status === TaskStatuses.InProgress); | |||
return pendingTasks.filter((task) => task.status === TaskStatuses.InProgress); | |||
}; | |||
isReportRelatedTask = (task: Task) => { | |||
@@ -360,7 +360,7 @@ export class ComponentContainer extends React.PureComponent<Props, State> { | |||
}; | |||
registerBranchStatuses = (branchLikes: BranchLike[], component: Component) => { | |||
branchLikes.forEach(branchLike => { | |||
branchLikes.forEach((branchLike) => { | |||
if (branchLike.status) { | |||
this.props.updateBranchStatus( | |||
branchLike, | |||
@@ -373,7 +373,7 @@ export class ComponentContainer extends React.PureComponent<Props, State> { | |||
handleComponentChange = (changes: Partial<Component>) => { | |||
if (this.mounted) { | |||
this.setState(state => { | |||
this.setState((state) => { | |||
if (state.component) { | |||
const newComponent: Component = { ...state.component, ...changes }; | |||
return { component: newComponent }; | |||
@@ -422,7 +422,7 @@ export class ComponentContainer extends React.PureComponent<Props, State> { | |||
projectBinding, | |||
projectBindingErrors, | |||
tasksInProgress, | |||
warnings | |||
warnings, | |||
} = this.state; | |||
const isInProgress = tasksInProgress && tasksInProgress.length > 0; | |||
@@ -461,8 +461,9 @@ export class ComponentContainer extends React.PureComponent<Props, State> { | |||
isPending, | |||
onBranchesChange: this.handleBranchesChange, | |||
onComponentChange: this.handleComponentChange, | |||
projectBinding | |||
}}> | |||
projectBinding, | |||
}} | |||
> | |||
<Outlet /> | |||
</ComponentContext.Provider> | |||
)} |
@@ -62,7 +62,8 @@ export function GlobalFooter({ hideLoggedInInfo, appState }: GlobalFooterProps) | |||
<a | |||
href="https://www.gnu.org/licenses/lgpl-3.0.txt" | |||
rel="noopener noreferrer" | |||
target="_blank"> | |||
target="_blank" | |||
> | |||
{translate('footer.license')} | |||
</a> | |||
</li> | |||
@@ -70,7 +71,8 @@ export function GlobalFooter({ hideLoggedInInfo, appState }: GlobalFooterProps) | |||
<a | |||
href="https://community.sonarsource.com/c/help/sq" | |||
rel="noopener noreferrer" | |||
target="_blank"> | |||
target="_blank" | |||
> | |||
{translate('footer.community')} | |||
</a> | |||
</li> | |||
@@ -81,7 +83,8 @@ export function GlobalFooter({ hideLoggedInInfo, appState }: GlobalFooterProps) | |||
<a | |||
href="https://redirect.sonarsource.com/doc/plugin-library.html" | |||
rel="noopener noreferrer" | |||
target="_blank"> | |||
target="_blank" | |||
> | |||
{translate('footer.plugins')} | |||
</a> | |||
</li> |
@@ -37,7 +37,8 @@ export default function GlobalFooterBranding() { | |||
href="https://www.sonarqube.org/?referrer=sonarqube" | |||
rel="noopener noreferrer" | |||
target="_blank" | |||
title="SonarQube™"> | |||
title="SonarQube™" | |||
> | |||
SonarQube™ | |||
</a>{' '} | |||
but is <strong>not</strong> an official version provided by{' '} | |||
@@ -45,7 +46,8 @@ export default function GlobalFooterBranding() { | |||
href="https://www.sonarsource.com" | |||
rel="noopener noreferrer" | |||
target="_blank" | |||
title="SonarSource SA"> | |||
title="SonarSource SA" | |||
> | |||
SonarSource SA | |||
</a> | |||
. |
@@ -36,7 +36,8 @@ export default function GlobalMessage(props: GlobalMessageProps) { | |||
<MessageBox | |||
data-test={`global-message__${message.level}`} | |||
level={message.level} | |||
role={message.level === 'SUCCESS' ? 'status' : 'alert'}> | |||
role={message.level === 'SUCCESS' ? 'status' : 'alert'} | |||
> | |||
{cutLongWords(message.text)} | |||
<CloseButton | |||
className="button-small" |
@@ -38,7 +38,7 @@ export default class GlobalMessagesContainer extends React.Component<{}, State> | |||
super(props); | |||
this.state = { | |||
messages: [] | |||
messages: [], | |||
}; | |||
} | |||
@@ -65,7 +65,7 @@ export default class GlobalMessagesContainer extends React.Component<{}, State> | |||
closeMessage = (messageId: string) => { | |||
if (this.mounted) { | |||
this.setState(({ messages }) => { | |||
return { messages: messages.filter(m => m.id !== messageId) }; | |||
return { messages: messages.filter((m) => m.id !== messageId) }; | |||
}); | |||
} | |||
}; | |||
@@ -79,7 +79,7 @@ export default class GlobalMessagesContainer extends React.Component<{}, State> | |||
return ( | |||
<MessagesContainer> | |||
{messages.map(message => ( | |||
{messages.map((message) => ( | |||
<GlobalMessage | |||
closeGlobalMessage={this.closeMessage} | |||
key={message.id} |
@@ -40,8 +40,8 @@ const CATEGORIES: { left: Shortcuts; right: Shortcuts } = { | |||
category: 'global', | |||
shortcuts: [ | |||
{ keys: ['s'], action: 'search' }, | |||
{ keys: ['?'], action: 'open_shortcuts' } | |||
] | |||
{ keys: ['?'], action: 'open_shortcuts' }, | |||
], | |||
}, | |||
{ | |||
category: 'issues_page', | |||
@@ -57,9 +57,9 @@ const CATEGORIES: { left: Shortcuts; right: Shortcuts } = { | |||
{ keys: ['i'], action: 'severity' }, | |||
{ keys: ['c'], action: 'comment' }, | |||
{ keys: ['ctrl', '+', 'enter'], action: 'submit_comment' }, | |||
{ keys: ['t'], action: 'tags' } | |||
] | |||
} | |||
{ keys: ['t'], action: 'tags' }, | |||
], | |||
}, | |||
], | |||
right: [ | |||
{ | |||
@@ -67,26 +67,26 @@ const CATEGORIES: { left: Shortcuts; right: Shortcuts } = { | |||
shortcuts: [ | |||
{ keys: ['↑', '↓'], action: 'select_files' }, | |||
{ keys: ['→'], action: 'open_file' }, | |||
{ keys: ['←'], action: 'back' } | |||
] | |||
{ keys: ['←'], action: 'back' }, | |||
], | |||
}, | |||
{ | |||
category: 'measures_page', | |||
shortcuts: [ | |||
{ keys: ['↑', '↓'], action: 'select_files' }, | |||
{ keys: ['→'], action: 'open_file' }, | |||
{ keys: ['←'], action: 'back' } | |||
] | |||
{ keys: ['←'], action: 'back' }, | |||
], | |||
}, | |||
{ | |||
category: 'rules_page', | |||
shortcuts: [ | |||
{ keys: ['↑', '↓'], action: 'navigate' }, | |||
{ keys: ['→'], action: 'rule_details' }, | |||
{ keys: ['←'], action: 'back' } | |||
] | |||
} | |||
] | |||
{ keys: ['←'], action: 'back' }, | |||
], | |||
}, | |||
], | |||
}; | |||
function renderShortcuts(list: Shortcuts) { | |||
@@ -106,7 +106,7 @@ function renderShortcuts(list: Shortcuts) { | |||
{shortcuts.map(({ action, keys }) => ( | |||
<tr key={action}> | |||
<td> | |||
{keys.map(k => | |||
{keys.map((k) => | |||
k === '+' ? ( | |||
<span key={k} className="little-spacer-right"> | |||
{k} | |||
@@ -143,7 +143,7 @@ export default function KeyboardShortcutsModal() { | |||
} | |||
if (event.key === KeyboardKeys.KeyQuestionMark) { | |||
setDisplay(d => !d); | |||
setDisplay((d) => !d); | |||
} | |||
}; | |||
@@ -169,7 +169,8 @@ export default function KeyboardShortcutsModal() { | |||
onClick={() => { | |||
setDisplay(false); | |||
return true; | |||
}}> | |||
}} | |||
> | |||
{translate('keyboard_shortcuts.disable_link')} | |||
</Link> | |||
</div> |
@@ -27,8 +27,8 @@ export function MigrationContainer() { | |||
const to = { | |||
pathname: '/maintenance', | |||
search: new URLSearchParams({ | |||
return_to: returnTo | |||
}).toString() | |||
return_to: returnTo, | |||
}).toString(), | |||
}; | |||
return <Navigate to={to} />; |
@@ -38,7 +38,8 @@ export default function NonAdminPagesContainer() { | |||
<Alert | |||
className="it__alert-no-access-all-child-project max-width-60 huge-spacer-top" | |||
display="block" | |||
variant="error"> | |||
variant="error" | |||
> | |||
<p>{translate('application.cannot_access_all_child_projects1')}</p> | |||
<br /> | |||
<p>{translate('application.cannot_access_all_child_projects2')}</p> |
@@ -65,7 +65,8 @@ export class PageTracker extends React.Component<Props, State> { | |||
<Helmet | |||
defaultTitle={getInstance()} | |||
defer={false} | |||
onChangeClientState={appState.webAnalyticsJsPath ? this.trackPage : undefined}> | |||
onChangeClientState={appState.webAnalyticsJsPath ? this.trackPage : undefined} | |||
> | |||
{this.props.children} | |||
</Helmet> | |||
); |
@@ -55,7 +55,7 @@ export function PluginRiskConsent(props: PluginRiskConsentProps) { | |||
try { | |||
await setSimpleSettingValue({ | |||
key: SettingsKey.PluginRiskConsent, | |||
value: RiskConsent.Accepted | |||
value: RiskConsent.Accepted, | |||
}); | |||
// force a refresh for the backend |
@@ -54,7 +54,7 @@ export default class RecentHistory { | |||
static add(componentKey: string, componentName: string, icon: string) { | |||
const sonarHistory = RecentHistory.get(); | |||
const newEntry = { key: componentKey, name: componentName, icon }; | |||
let newHistory = sonarHistory.filter(entry => entry.key !== newEntry.key); | |||
let newHistory = sonarHistory.filter((entry) => entry.key !== newEntry.key); | |||
newHistory.unshift(newEntry); | |||
newHistory = newHistory.slice(0, HISTORY_LIMIT); | |||
RecentHistory.set(newHistory); | |||
@@ -62,7 +62,7 @@ export default class RecentHistory { | |||
static remove(componentKey: string) { | |||
const history = RecentHistory.get(); | |||
const newHistory = history.filter(entry => entry.key !== componentKey); | |||
const newHistory = history.filter((entry) => entry.key !== componentKey); | |||
RecentHistory.set(newHistory); | |||
} | |||
} |
@@ -31,7 +31,7 @@ import { portIsValid, sendUserToken } from '../../helpers/sonarlint'; | |||
import { | |||
computeTokenExpirationDate, | |||
getAvailableExpirationOptions, | |||
getNextTokenName | |||
getNextTokenName, | |||
} from '../../helpers/tokens'; | |||
import { NewUserToken, TokenExpiration } from '../../types/token'; | |||
import { LoggedInUser } from '../../types/users'; | |||
@@ -41,7 +41,7 @@ enum Status { | |||
request, | |||
tokenError, | |||
tokenCreated, | |||
tokenSent | |||
tokenSent, | |||
} | |||
interface Props { | |||
@@ -152,7 +152,7 @@ export function SonarLintConnection({ currentUser }: Props) { | |||
<Link to="/account/security"> | |||
{translate('sonarlint-connection.token-error.description2.link')} | |||
</Link> | |||
) | |||
), | |||
}} | |||
/> | |||
</p> |
@@ -69,7 +69,7 @@ export class StartupModal extends React.PureComponent<Props & StateProps, State> | |||
if (!lastPrompt || differenceInDays(new Date(), parseDate(lastPrompt)) >= 1) { | |||
showLicense() | |||
.then(license => { | |||
.then((license) => { | |||
if (!license || !license.isValidEdition) { | |||
save(LICENSE_PROMPT, toShortNotSoISOString(new Date()), currentUser.login); | |||
this.setState({ open: true }); |
@@ -25,7 +25,7 @@ import { Alert } from '../../components/ui/Alert'; | |||
import { Feature } from '../../types/features'; | |||
import { GlobalSettingKeys, SettingValue } from '../../types/settings'; | |||
import withAvailableFeatures, { | |||
WithAvailableFeaturesProps | |||
WithAvailableFeaturesProps, | |||
} from './available-features/withAvailableFeatures'; | |||
import './SystemAnnouncement.css'; | |||
@@ -54,7 +54,7 @@ export class SystemAnnouncement extends React.PureComponent<WithAvailableFeature | |||
getSettings = async () => { | |||
const values: SettingValue[] = await getValues({ | |||
keys: [GlobalSettingKeys.DisplayAnnouncementMessage, GlobalSettingKeys.AnnouncementMessage] | |||
keys: [GlobalSettingKeys.DisplayAnnouncementMessage, GlobalSettingKeys.AnnouncementMessage], | |||
}); | |||
const settings = keyBy(values, 'key'); | |||
@@ -63,7 +63,7 @@ export class SystemAnnouncement extends React.PureComponent<WithAvailableFeature | |||
message: | |||
(settings[GlobalSettingKeys.AnnouncementMessage] && | |||
settings[GlobalSettingKeys.AnnouncementMessage].value) || | |||
'' | |||
'', | |||
}); | |||
}; | |||
@@ -86,7 +86,8 @@ export class SystemAnnouncement extends React.PureComponent<WithAvailableFeature | |||
className="system-announcement-banner" | |||
title={message} | |||
display="banner" | |||
variant="warning"> | |||
variant="warning" | |||
> | |||
{message} | |||
</Alert> | |||
</div> |
@@ -24,11 +24,11 @@ import { AdminContainer, AdminContainerProps } from '../AdminContainer'; | |||
jest.mock('../../../api/plugins', () => ({ | |||
getSettingsNavigation: jest.fn().mockResolvedValue({}), | |||
getPendingPlugins: jest.fn().mockResolvedValue({}) | |||
getPendingPlugins: jest.fn().mockResolvedValue({}), | |||
})); | |||
jest.mock('../../../api/system', () => ({ | |||
getSystemStatus: jest.fn().mockResolvedValue({}) | |||
getSystemStatus: jest.fn().mockResolvedValue({}), | |||
})); | |||
it('should render correctly', () => { | |||
@@ -40,9 +40,10 @@ function shallowRender(props: Partial<AdminContainerProps> = {}) { | |||
return shallow( | |||
<AdminContainer | |||
appState={mockAppState({ | |||
canAdmin: true | |||
canAdmin: true, | |||
})} | |||
{...props}> | |||
{...props} | |||
> | |||
<div /> | |||
</AdminContainer> | |||
); |
@@ -29,9 +29,9 @@ it('should render correctly', () => { | |||
appState: mockAppState({ | |||
settings: { | |||
'sonar.lf.enableGravatar': 'true', | |||
'sonar.lf.gravatarServerUrl': 'http://example.com' | |||
} | |||
}) | |||
'sonar.lf.gravatarServerUrl': 'http://example.com', | |||
}, | |||
}), | |||
}) | |||
).toMatchSnapshot('with gravatar'); | |||
}); | |||
@@ -47,8 +47,8 @@ function shallowRender(props: Partial<App['props']> = {}) { | |||
appState={mockAppState({ | |||
settings: { | |||
'sonar.lf.enableGravatar': 'false', | |||
'sonar.lf.gravatarServerUrl': '' | |||
} | |||
'sonar.lf.gravatarServerUrl': '', | |||
}, | |||
})} | |||
{...props} | |||
/> |
@@ -51,35 +51,35 @@ jest.mock('../../../api/branches', () => { | |||
.fn() | |||
.mockResolvedValue([ | |||
mockPullRequest({ key: 'pr-89', status: { qualityGateStatus: 'ERROR' } }), | |||
mockPullRequest({ key: 'pr-90', title: 'PR Feature 2' }) | |||
]) | |||
mockPullRequest({ key: 'pr-90', title: 'PR Feature 2' }), | |||
]), | |||
}; | |||
}); | |||
jest.mock('../../../api/ce', () => ({ | |||
getAnalysisStatus: jest.fn().mockResolvedValue({ component: { warnings: [] } }), | |||
getTasksForComponent: jest.fn().mockResolvedValue({ queue: [] }) | |||
getTasksForComponent: jest.fn().mockResolvedValue({ queue: [] }), | |||
})); | |||
jest.mock('../../../api/components', () => ({ | |||
getComponentData: jest.fn().mockResolvedValue({ component: { analysisDate: '2018-07-30' } }) | |||
getComponentData: jest.fn().mockResolvedValue({ component: { analysisDate: '2018-07-30' } }), | |||
})); | |||
jest.mock('../../../api/navigation', () => ({ | |||
getComponentNavigation: jest.fn().mockResolvedValue({ | |||
breadcrumbs: [{ key: 'portfolioKey', name: 'portfolio', qualifier: 'VW' }], | |||
key: 'portfolioKey' | |||
}) | |||
key: 'portfolioKey', | |||
}), | |||
})); | |||
jest.mock('../../../api/alm-settings', () => ({ | |||
getProjectAlmBinding: jest.fn().mockResolvedValue(undefined), | |||
validateProjectAlmBinding: jest.fn().mockResolvedValue(undefined) | |||
validateProjectAlmBinding: jest.fn().mockResolvedValue(undefined), | |||
})); | |||
jest.mock('../../utils/handleRequiredAuthorization', () => ({ | |||
__esModule: true, | |||
default: jest.fn() | |||
default: jest.fn(), | |||
})); | |||
const Inner = () => <div />; | |||
@@ -99,7 +99,7 @@ it('changes component', () => { | |||
wrapper.setState({ | |||
branchLikes: [mockMainBranch()], | |||
component: { qualifier: 'TRK', visibility: 'public' } as Component, | |||
loading: false | |||
loading: false, | |||
}); | |||
wrapper.instance().handleComponentChange({ visibility: 'private' }); | |||
@@ -108,7 +108,7 @@ it('changes component', () => { | |||
it('loads the project binding, if any', async () => { | |||
const component = mockComponent({ | |||
breadcrumbs: [{ key: 'foo', name: 'foo', qualifier: ComponentQualifier.Project }] | |||
breadcrumbs: [{ key: 'foo', name: 'foo', qualifier: ComponentQualifier.Project }], | |||
}); | |||
(getComponentNavigation as jest.Mock).mockResolvedValueOnce({}); | |||
(getComponentData as jest.Mock<any>) | |||
@@ -116,7 +116,7 @@ it('loads the project binding, if any', async () => { | |||
.mockResolvedValueOnce({ component }); | |||
(getProjectAlmBinding as jest.Mock).mockResolvedValueOnce(undefined).mockResolvedValueOnce({ | |||
alm: AlmKeys.GitHub, | |||
key: 'foo' | |||
key: 'foo', | |||
}); | |||
const wrapper = shallowRender(); | |||
@@ -137,7 +137,7 @@ it("doesn't load branches portfolio", async () => { | |||
expect(getComponentData).toHaveBeenCalledWith({ component: 'portfolioKey', branch: undefined }); | |||
expect(getComponentNavigation).toHaveBeenCalledWith({ | |||
component: 'portfolioKey', | |||
branch: undefined | |||
branch: undefined, | |||
}); | |||
}); | |||
@@ -146,14 +146,14 @@ it('updates branches on change', async () => { | |||
const wrapper = shallowRender({ | |||
hasFeature: () => true, | |||
location: mockLocation({ query: { id: 'portfolioKey' } }), | |||
updateBranchStatus | |||
updateBranchStatus, | |||
}); | |||
wrapper.setState({ | |||
branchLikes: [mockMainBranch()], | |||
component: mockComponent({ | |||
breadcrumbs: [{ key: 'projectKey', name: 'project', qualifier: 'TRK' }] | |||
breadcrumbs: [{ key: 'projectKey', name: 'project', qualifier: 'TRK' }], | |||
}), | |||
loading: false | |||
loading: false, | |||
}); | |||
wrapper.instance().handleBranchesChange(); | |||
expect(getBranches).toHaveBeenCalledWith('projectKey'); | |||
@@ -164,7 +164,7 @@ it('updates branches on change', async () => { | |||
it('fetches status', async () => { | |||
(getComponentData as jest.Mock<any>).mockResolvedValueOnce({ | |||
component: {} | |||
component: {}, | |||
}); | |||
const wrapper = shallowRender(); | |||
@@ -200,17 +200,17 @@ it('filters correctly the pending tasks for a main branch', () => { | |||
expect(component.getCurrentTask(currentTask, pullRequest)).toMatchObject(currentTask); | |||
expect(component.getPendingTasksForBranchLike(pendingTasks, mainBranch)).toMatchObject([{}]); | |||
expect(component.getPendingTasksForBranchLike(pendingTasks, pullRequest)).toMatchObject([ | |||
currentTask | |||
currentTask, | |||
]); | |||
}); | |||
it('reload component after task progress finished', async () => { | |||
(getTasksForComponent as jest.Mock<any>) | |||
.mockResolvedValueOnce({ | |||
queue: [{ id: 'foo', status: TaskStatuses.InProgress, type: TaskTypes.ViewRefresh }] | |||
queue: [{ id: 'foo', status: TaskStatuses.InProgress, type: TaskTypes.ViewRefresh }], | |||
}) | |||
.mockResolvedValueOnce({ | |||
queue: [] | |||
queue: [], | |||
}); | |||
const wrapper = shallowRender(); | |||
@@ -245,13 +245,13 @@ it('reload component after task progress finished', async () => { | |||
it('reloads component after task progress finished, and moves straight to current', async () => { | |||
(getComponentData as jest.Mock<any>).mockResolvedValueOnce({ | |||
component: { key: 'bar' } | |||
component: { key: 'bar' }, | |||
}); | |||
(getTasksForComponent as jest.Mock<any>) | |||
.mockResolvedValueOnce({ queue: [] }) | |||
.mockResolvedValueOnce({ | |||
queue: [], | |||
current: { id: 'foo', status: TaskStatuses.Success, type: TaskTypes.AppRefresh } | |||
current: { id: 'foo', status: TaskStatuses.Success, type: TaskTypes.AppRefresh }, | |||
}); | |||
const wrapper = shallowRender(); | |||
@@ -279,11 +279,11 @@ it('reloads component after task progress finished, and moves straight to curren | |||
it('only fully loads a non-empty component once', async () => { | |||
(getComponentData as jest.Mock<any>).mockResolvedValueOnce({ | |||
component: { key: 'bar', analysisDate: '2019-01-01' } | |||
component: { key: 'bar', analysisDate: '2019-01-01' }, | |||
}); | |||
(getTasksForComponent as jest.Mock<any>).mockResolvedValueOnce({ | |||
queue: [], | |||
current: { id: 'foo', status: TaskStatuses.Success, type: TaskTypes.Report } | |||
current: { id: 'foo', status: TaskStatuses.Success, type: TaskTypes.Report }, | |||
}); | |||
const wrapper = shallowRender(); | |||
@@ -294,15 +294,15 @@ it('only fully loads a non-empty component once', async () => { | |||
it('only fully reloads a non-empty component if there was previously some task in progress', async () => { | |||
(getComponentData as jest.Mock<any>).mockResolvedValueOnce({ | |||
component: { key: 'bar', analysisDate: '2019-01-01' } | |||
component: { key: 'bar', analysisDate: '2019-01-01' }, | |||
}); | |||
(getTasksForComponent as jest.Mock<any>) | |||
.mockResolvedValueOnce({ | |||
queue: [{ id: 'foo', status: TaskStatuses.InProgress, type: TaskTypes.AppRefresh }] | |||
queue: [{ id: 'foo', status: TaskStatuses.InProgress, type: TaskTypes.AppRefresh }], | |||
}) | |||
.mockResolvedValueOnce({ | |||
queue: [], | |||
current: { id: 'foo', status: TaskStatuses.Success, type: TaskTypes.AppRefresh } | |||
current: { id: 'foo', status: TaskStatuses.Success, type: TaskTypes.AppRefresh }, | |||
}); | |||
const wrapper = shallowRender(); | |||
@@ -347,14 +347,14 @@ it('should redirect if the user has no access', async () => { | |||
it('should redirect if the component is a portfolio', async () => { | |||
const componentKey = 'comp-key'; | |||
(getComponentData as jest.Mock<any>).mockResolvedValueOnce({ | |||
component: { key: componentKey, breadcrumbs: [{ qualifier: ComponentQualifier.Portfolio }] } | |||
component: { key: componentKey, breadcrumbs: [{ qualifier: ComponentQualifier.Portfolio }] }, | |||
}); | |||
const replace = jest.fn(); | |||
const wrapper = shallowRender({ | |||
location: mockLocation({ pathname: '/dashboard' }), | |||
router: mockRouter({ replace }) | |||
router: mockRouter({ replace }), | |||
}); | |||
await waitAndUpdate(wrapper); | |||
expect(replace).toHaveBeenCalledWith({ pathname: '/portfolio', search: `?id=${componentKey}` }); | |||
@@ -362,7 +362,7 @@ it('should redirect if the component is a portfolio', async () => { | |||
it('should display display the unavailable page if the component needs issue sync', async () => { | |||
(getComponentData as jest.Mock).mockResolvedValueOnce({ | |||
component: { key: 'test', qualifier: ComponentQualifier.Project, needIssueSync: true } | |||
component: { key: 'test', qualifier: ComponentQualifier.Project, needIssueSync: true }, | |||
}); | |||
const wrapper = shallowRender(); | |||
@@ -375,8 +375,8 @@ it('should display display the unavailable page if the component needs issue syn | |||
it('should correctly reload last task warnings if anything got dismissed', async () => { | |||
(getComponentData as jest.Mock<any>).mockResolvedValueOnce({ | |||
component: mockComponent({ | |||
breadcrumbs: [{ key: 'foo', name: 'Foo', qualifier: ComponentQualifier.Project }] | |||
}) | |||
breadcrumbs: [{ key: 'foo', name: 'Foo', qualifier: ComponentQualifier.Project }], | |||
}), | |||
}); | |||
(getComponentNavigation as jest.Mock).mockResolvedValueOnce({}); | |||
@@ -390,14 +390,14 @@ it('should correctly reload last task warnings if anything got dismissed', async | |||
describe('should correctly validate the project binding depending on the context', () => { | |||
const COMPONENT = mockComponent({ | |||
breadcrumbs: [{ key: 'foo', name: 'Foo', qualifier: ComponentQualifier.Project }] | |||
breadcrumbs: [{ key: 'foo', name: 'Foo', qualifier: ComponentQualifier.Project }], | |||
}); | |||
const PROJECT_BINDING_ERRORS = mockProjectAlmBindingConfigurationErrors(); | |||
it.each([ | |||
["has an analysis; won't perform any check", { ...COMPONENT, analysisDate: '2020-01' }], | |||
['has a project binding; check is OK', COMPONENT, undefined, 1], | |||
['has a project binding; check is not OK', COMPONENT, PROJECT_BINDING_ERRORS, 1] | |||
['has a project binding; check is not OK', COMPONENT, PROJECT_BINDING_ERRORS, 1], | |||
])('%s', async (_, component, projectBindingErrors = undefined, n = 0) => { | |||
(getComponentNavigation as jest.Mock).mockResolvedValueOnce({}); | |||
(getComponentData as jest.Mock<any>).mockResolvedValueOnce({ component }); | |||
@@ -417,12 +417,12 @@ describe('should correctly validate the project binding depending on the context | |||
it.each([ | |||
[ComponentQualifier.Application], | |||
[ComponentQualifier.Portfolio], | |||
[ComponentQualifier.SubPortfolio] | |||
[ComponentQualifier.SubPortfolio], | |||
])( | |||
'should not care about PR decoration settings for %s', | |||
async (componentQualifier: ComponentQualifier) => { | |||
const component = mockComponent({ | |||
breadcrumbs: [{ key: 'foo', name: 'Foo', qualifier: componentQualifier }] | |||
breadcrumbs: [{ key: 'foo', name: 'Foo', qualifier: componentQualifier }], | |||
}); | |||
(getComponentNavigation as jest.Mock).mockResolvedValueOnce({}); | |||
(getComponentData as jest.Mock<any>).mockResolvedValueOnce({ component }); | |||
@@ -442,7 +442,8 @@ function shallowRender(props: Partial<ComponentContainer['props']> = {}) { | |||
location={mockLocation({ query: { id: 'foo' } })} | |||
updateBranchStatus={jest.fn()} | |||
router={mockRouter()} | |||
{...props}> | |||
{...props} | |||
> | |||
<Inner /> | |||
</ComponentContainer> | |||
); |
@@ -31,7 +31,7 @@ it('should not render the only logged in information', () => { | |||
expect( | |||
getWrapper({ | |||
hideLoggedInInfo: true, | |||
appState: mockAppState({ version: '6.4-SNAPSHOT' }) | |||
appState: mockAppState({ version: '6.4-SNAPSHOT' }), | |||
}) | |||
).toMatchSnapshot(); | |||
}); | |||
@@ -39,7 +39,7 @@ it('should not render the only logged in information', () => { | |||
it('should show the db warning message', () => { | |||
expect( | |||
getWrapper({ | |||
appState: mockAppState({ productionDatabase: false, edition: EditionKey.community }) | |||
appState: mockAppState({ productionDatabase: false, edition: EditionKey.community }), | |||
}).find('Alert') | |||
).toMatchSnapshot(); | |||
}); | |||
@@ -47,7 +47,7 @@ it('should show the db warning message', () => { | |||
it('should display the sq version', () => { | |||
expect( | |||
getWrapper({ | |||
appState: mockAppState({ edition: EditionKey.enterprise, version: '6.4-SNAPSHOT' }) | |||
appState: mockAppState({ edition: EditionKey.enterprise, version: '6.4-SNAPSHOT' }), | |||
}) | |||
).toMatchSnapshot(); | |||
}); |
@@ -27,12 +27,12 @@ jest.mock('react', () => { | |||
let close: () => void; | |||
return { | |||
...jest.requireActual('react'), | |||
useEffect: jest.fn().mockImplementation(f => { | |||
useEffect: jest.fn().mockImplementation((f) => { | |||
close = f(); | |||
}), | |||
clean: () => { | |||
close(); | |||
} | |||
}, | |||
}; | |||
}); | |||
@@ -66,13 +66,13 @@ it('should ignore other keydownes', () => { | |||
expect(wrapper.type()).toBeNull(); | |||
}); | |||
it.each([['input'], ['select'], ['textarea']])('should ignore events on a %s', type => { | |||
it.each([['input'], ['select'], ['textarea']])('should ignore events on a %s', (type) => { | |||
const wrapper = shallowRender(); | |||
const fakeEvent = new KeyboardEvent('keydown', { key: '!' }); | |||
Object.defineProperty(fakeEvent, 'target', { | |||
value: document.createElement(type) | |||
value: document.createElement(type), | |||
}); | |||
document.dispatchEvent(fakeEvent); |
@@ -29,8 +29,8 @@ it.each([ | |||
[mockLoggedInUser(), '/projects'], | |||
[ | |||
mockLoggedInUser({ homepage: { type: 'ISSUES' } }), | |||
expect.objectContaining({ pathname: '/issues' }) | |||
] | |||
expect.objectContaining({ pathname: '/issues' }), | |||
], | |||
])('should render correctly', (currentUser: CurrentUser, expected: string) => { | |||
const wrapper = shallowRender({ currentUser }); | |||
@@ -24,7 +24,7 @@ import { getSystemStatus } from '../../../helpers/system'; | |||
import MigrationContainer from '../MigrationContainer'; | |||
jest.mock('../../../helpers/system', () => ({ | |||
getSystemStatus: jest.fn() | |||
getSystemStatus: jest.fn(), | |||
})); | |||
const originalLocation = window.location; | |||
@@ -33,18 +33,18 @@ beforeAll(() => { | |||
const location = { | |||
pathname: '/projects', | |||
search: '?query=toto', | |||
hash: '#hash' | |||
hash: '#hash', | |||
}; | |||
Object.defineProperty(window, 'location', { | |||
writable: true, | |||
value: location | |||
value: location, | |||
}); | |||
}); | |||
afterAll(() => { | |||
Object.defineProperty(window, 'location', { | |||
writable: true, | |||
value: originalLocation | |||
value: originalLocation, | |||
}); | |||
}); | |||
@@ -25,11 +25,11 @@ import { mockAppState, mockLocation } from '../../../helpers/testMocks'; | |||
import { PageTracker } from '../PageTracker'; | |||
jest.mock('../../../helpers/extensions', () => ({ | |||
installScript: jest.fn().mockResolvedValue({}) | |||
installScript: jest.fn().mockResolvedValue({}), | |||
})); | |||
jest.mock('../../../helpers/extensionsHandler', () => ({ | |||
getWebAnalyticsPageHandlerFromCache: jest.fn().mockReturnValue(undefined) | |||
getWebAnalyticsPageHandlerFromCache: jest.fn().mockReturnValue(undefined), | |||
})); | |||
beforeAll(() => { |
@@ -25,13 +25,13 @@ import { mockLoggedInUser, mockRouter } from '../../../helpers/testMocks'; | |||
import { PluginRiskConsent, PluginRiskConsentProps } from '../PluginRiskConsent'; | |||
jest.mock('../../../api/settings', () => ({ | |||
setSimpleSettingValue: jest.fn().mockResolvedValue({}) | |||
setSimpleSettingValue: jest.fn().mockResolvedValue({}), | |||
})); | |||
jest.mock('react', () => { | |||
return { | |||
...jest.requireActual('react'), | |||
useEffect: jest.fn().mockImplementation(f => f()) | |||
useEffect: jest.fn().mockImplementation((f) => f()), | |||
}; | |||
}); | |||
@@ -47,7 +47,7 @@ it('should redirect non-admin users', () => { | |||
const replace = jest.fn(); | |||
const wrapper = shallowRender({ | |||
currentUser: mockLoggedInUser(), | |||
router: mockRouter({ replace }) | |||
router: mockRouter({ replace }), | |||
}); | |||
expect(wrapper.type()).toBeNull(); | |||
expect(replace).toHaveBeenCalled(); | |||
@@ -56,10 +56,7 @@ it('should redirect non-admin users', () => { | |||
it('should handle acknowledgement and redirect', async () => { | |||
const wrapper = shallowRender(); | |||
wrapper | |||
.find(Button) | |||
.first() | |||
.simulate('click'); | |||
wrapper.find(Button).first().simulate('click'); | |||
await new Promise(setImmediate); | |||
@@ -23,7 +23,7 @@ import RecentHistory, { History } from '../RecentHistory'; | |||
jest.mock('../../../helpers/storage', () => ({ | |||
get: jest.fn(), | |||
remove: jest.fn(), | |||
save: jest.fn() | |||
save: jest.fn(), | |||
})); | |||
beforeEach(() => { |
@@ -24,7 +24,7 @@ import { mockLoggedInUser } from '../../../helpers/testMocks'; | |||
import { ResetPassword, ResetPasswordProps } from '../ResetPassword'; | |||
jest.mock('../../../helpers/system', () => ({ | |||
getBaseUrl: jest.fn().mockReturnValue('/context') | |||
getBaseUrl: jest.fn().mockReturnValue('/context'), | |||
})); | |||
const originalLocation = window.location; | |||
@@ -32,18 +32,18 @@ const originalLocation = window.location; | |||
beforeAll(() => { | |||
const location = { | |||
...window.location, | |||
href: null | |||
href: null, | |||
}; | |||
Object.defineProperty(window, 'location', { | |||
writable: true, | |||
value: location | |||
value: location, | |||
}); | |||
}); | |||
afterAll(() => { | |||
Object.defineProperty(window, 'location', { | |||
writable: true, | |||
value: originalLocation | |||
value: originalLocation, | |||
}); | |||
}); | |||
@@ -32,7 +32,7 @@ jest.mock('../../../api/user-tokens'); | |||
jest.mock('../../../helpers/handleRequiredAuthentication', () => ({ | |||
__esModule: true, | |||
default: jest.fn() | |||
default: jest.fn(), | |||
})); | |||
jest.mock('../../../helpers/sonarlint', () => { | |||
@@ -61,9 +61,9 @@ jest.mock('../../../api/settings', () => { | |||
getAllValues: jest.fn().mockResolvedValue([ | |||
{ | |||
key: SettingsKey.TokenMaxAllowedLifetime, | |||
value: 'No expiration' | |||
} | |||
]) | |||
value: 'No expiration', | |||
}, | |||
]), | |||
}; | |||
}); | |||
@@ -141,7 +141,7 @@ function renderSonarLintConnection(overrides: { currentUser?: CurrentUser; port? | |||
const { currentUser, port } = { | |||
currentUser: mockLoggedInUser(), | |||
port: '64120', | |||
...overrides | |||
...overrides, | |||
}; | |||
const searchParams = new URLSearchParams(); | |||
@@ -152,6 +152,6 @@ function renderSonarLintConnection(overrides: { currentUser?: CurrentUser; port? | |||
renderApp('sonarlint/auth', <SonarLintConnection />, { | |||
currentUser, | |||
navigateTo: `sonarlint/auth?${searchParams.toString()}` | |||
navigateTo: `sonarlint/auth?${searchParams.toString()}`, | |||
}); | |||
} |
@@ -31,21 +31,21 @@ import { LoggedInUser } from '../../../types/users'; | |||
import { StartupModal } from '../StartupModal'; | |||
jest.mock('../../../api/editions', () => ({ | |||
showLicense: jest.fn().mockResolvedValue(undefined) | |||
showLicense: jest.fn().mockResolvedValue(undefined), | |||
})); | |||
jest.mock('../../../helpers/storage', () => ({ | |||
get: jest.fn(), | |||
save: jest.fn() | |||
save: jest.fn(), | |||
})); | |||
jest.mock('../../../helpers/l10n', () => ({ | |||
hasMessage: jest.fn().mockReturnValue(true) | |||
hasMessage: jest.fn().mockReturnValue(true), | |||
})); | |||
jest.mock('../../../helpers/dates', () => ({ | |||
parseDate: jest.fn().mockReturnValue('parsed-date'), | |||
toShortNotSoISOString: jest.fn().mockReturnValue('short-not-iso-date') | |||
toShortNotSoISOString: jest.fn().mockReturnValue('short-not-iso-date'), | |||
})); | |||
jest.mock('date-fns', () => ({ differenceInDays: jest.fn().mockReturnValue(1) })); | |||
@@ -56,7 +56,7 @@ const LOGGED_IN_USER: LoggedInUser = { | |||
login: 'luke', | |||
name: 'Skywalker', | |||
scmAccounts: [], | |||
dismissedNotices: {} | |||
dismissedNotices: {}, | |||
}; | |||
beforeEach(() => { | |||
@@ -90,7 +90,7 @@ it('should render only the children', async () => { | |||
getWrapper({ | |||
appState: mockAppState({ canAdmin: false }), | |||
currentUser: { ...LOGGED_IN_USER }, | |||
location: mockLocation({ pathname: '/create-organization' }) | |||
location: mockLocation({ pathname: '/create-organization' }), | |||
}) | |||
); | |||
}); | |||
@@ -124,7 +124,8 @@ function getWrapper(props: Partial<StartupModal['props']> = {}) { | |||
currentUser={LOGGED_IN_USER} | |||
location={mockLocation({ pathname: 'foo/bar' })} | |||
router={mockRouter()} | |||
{...props}> | |||
{...props} | |||
> | |||
<div /> | |||
</StartupModal> | |||
); |
@@ -26,7 +26,7 @@ import { AvailableFeaturesContext } from '../available-features/AvailableFeature | |||
import SystemAnnouncement from '../SystemAnnouncement'; | |||
jest.mock('../../../api/settings', () => ({ | |||
getValues: jest.fn() | |||
getValues: jest.fn(), | |||
})); | |||
jest.mock('lodash', () => { | |||
@@ -41,41 +41,41 @@ it('should display system announcement', async () => { | |||
{ | |||
key: 'sonar.announcement.displayMessage', | |||
value: 'false', | |||
inherited: true | |||
} | |||
inherited: true, | |||
}, | |||
]) | |||
.mockResolvedValueOnce([ | |||
{ | |||
key: 'sonar.announcement.displayMessage', | |||
value: 'false', | |||
inherited: true | |||
} | |||
inherited: true, | |||
}, | |||
]) | |||
.mockResolvedValueOnce([ | |||
{ | |||
key: 'sonar.announcement.displayMessage', | |||
value: 'true' | |||
} | |||
value: 'true', | |||
}, | |||
]) | |||
.mockResolvedValueOnce([ | |||
{ | |||
key: 'sonar.announcement.displayMessage', | |||
value: 'true' | |||
value: 'true', | |||
}, | |||
{ | |||
key: 'sonar.announcement.message', | |||
value: '' | |||
} | |||
value: '', | |||
}, | |||
]) | |||
.mockResolvedValueOnce([ | |||
{ | |||
key: 'sonar.announcement.displayMessage', | |||
value: 'true' | |||
value: 'true', | |||
}, | |||
{ | |||
key: 'sonar.announcement.message', | |||
value: 'Foo' | |||
} | |||
value: 'Foo', | |||
}, | |||
]); | |||
renderSystemAnnouncement(); |
@@ -28,6 +28,6 @@ export const DEFAULT_APP_STATE = { | |||
productionDatabase: true, | |||
qualifiers: [], | |||
settings: {}, | |||
version: '' | |||
version: '', | |||
}; | |||
export const AppStateContext = React.createContext<AppState>(DEFAULT_APP_STATE); |
@@ -29,7 +29,7 @@ export interface AppStateContextProviderProps { | |||
export default function AppStateContextProvider({ | |||
appState, | |||
children | |||
children, | |||
}: React.PropsWithChildren<AppStateContextProviderProps>) { | |||
return <AppStateContext.Provider value={appState}>{children}</AppStateContext.Provider>; | |||
} |
@@ -26,7 +26,7 @@ import AppStateContextProvider, { AppStateContextProviderProps } from '../AppSta | |||
it('should set value correctly', async () => { | |||
const appState = mockAppState({ settings: { 'sonar.lf.logoUrl': 'whatevs/' } }); | |||
const wrapper = render({ | |||
appState | |||
appState, | |||
}); | |||
await waitAndUpdate(wrapper); | |||
@@ -30,8 +30,8 @@ jest.mock('../AppStateContext', () => { | |||
AppStateContext: { | |||
Consumer: ({ children }: { children: (props: {}) => React.ReactNode }) => { | |||
return children(appState); | |||
} | |||
} | |||
}, | |||
}, | |||
}; | |||
}); | |||
@@ -38,7 +38,7 @@ export default function withAppStateContext<P>( | |||
render() { | |||
return ( | |||
<AppStateContext.Consumer> | |||
{appState => <WrappedComponent appState={appState} {...(this.props as P)} />} | |||
{(appState) => <WrappedComponent appState={appState} {...(this.props as P)} />} | |||
</AppStateContext.Consumer> | |||
); | |||
} |
@@ -27,8 +27,8 @@ jest.mock('../AvailableFeaturesContext', () => { | |||
AvailableFeaturesContext: { | |||
Consumer: ({ children }: { children: (props: {}) => React.ReactNode }) => { | |||
return children([Feature.MonoRepositoryPullRequestDecoration]); | |||
} | |||
} | |||
}, | |||
}, | |||
}; | |||
}); | |||
@@ -44,9 +44,6 @@ it('should provide a way to check if a feature is available', () => { | |||
const wrapper = shallow(<UnderTest />); | |||
expect(wrapper.dive().type()).toBe(Wrapped); | |||
expect( | |||
wrapper | |||
.dive<Wrapped>() | |||
.props() | |||
.hasFeature(Feature.MonoRepositoryPullRequestDecoration) | |||
wrapper.dive<Wrapped>().props().hasFeature(Feature.MonoRepositoryPullRequestDecoration) | |||
).toBe(true); | |||
}); |
@@ -38,9 +38,9 @@ export default function withAvailableFeatures<P>( | |||
render() { | |||
return ( | |||
<AvailableFeaturesContext.Consumer> | |||
{availableFeatures => ( | |||
{(availableFeatures) => ( | |||
<WrappedComponent | |||
hasFeature={feature => availableFeatures.includes(feature)} | |||
hasFeature={(feature) => availableFeatures.includes(feature)} | |||
{...(this.props as P)} | |||
/> | |||
)} |
@@ -42,5 +42,5 @@ export const BranchStatusContext = React.createContext<BranchStatusContextInterf | |||
}, | |||
updateBranchStatus: () => { | |||
throw Error('BranchStatusContext is not provided'); | |||
} | |||
}, | |||
}); |
@@ -34,7 +34,7 @@ interface State { | |||
export default class BranchStatusContextProvider extends React.PureComponent<{}, State> { | |||
mounted = false; | |||
state: State = { | |||
branchStatusByComponent: {} | |||
branchStatusByComponent: {}, | |||
}; | |||
componentDidMount() { | |||
@@ -48,7 +48,7 @@ export default class BranchStatusContextProvider extends React.PureComponent<{}, | |||
fetchBranchStatus = async (branchLike: BranchLike, projectKey: string) => { | |||
const projectStatus = await getQualityGateProjectStatus({ | |||
projectKey, | |||
...getBranchLikeQuery(branchLike) | |||
...getBranchLikeQuery(branchLike), | |||
}).catch(() => undefined); | |||
if (!this.mounted || projectStatus === undefined) { | |||
@@ -78,10 +78,10 @@ export default class BranchStatusContextProvider extends React.PureComponent<{}, | |||
[branchLikeKey]: { | |||
conditions, | |||
ignoredConditions, | |||
status | |||
} | |||
} | |||
} | |||
status, | |||
}, | |||
}, | |||
}, | |||
})); | |||
}; | |||
@@ -91,8 +91,9 @@ export default class BranchStatusContextProvider extends React.PureComponent<{}, | |||
value={{ | |||
branchStatusByComponent: this.state.branchStatusByComponent, | |||
fetchBranchStatus: this.fetchBranchStatus, | |||
updateBranchStatus: this.updateBranchStatus | |||
}}> | |||
updateBranchStatus: this.updateBranchStatus, | |||
}} | |||
> | |||
{this.props.children} | |||
</BranchStatusContext.Provider> | |||
); |
@@ -26,7 +26,7 @@ import { QualityGateProjectStatus } from '../../../../types/quality-gates'; | |||
import BranchStatusContextProvider from '../BranchStatusContextProvider'; | |||
jest.mock('../../../../api/quality-gates', () => ({ | |||
getQualityGateProjectStatus: jest.fn().mockResolvedValue({}) | |||
getQualityGateProjectStatus: jest.fn().mockResolvedValue({}), | |||
})); | |||
describe('fetchBranchStatus', () => { | |||
@@ -36,7 +36,7 @@ describe('fetchBranchStatus', () => { | |||
const status: QualityGateProjectStatus = { | |||
status: 'OK', | |||
conditions: [], | |||
ignoredConditions: false | |||
ignoredConditions: false, | |||
}; | |||
(getQualityGateProjectStatus as jest.Mock).mockResolvedValueOnce(status); | |||
const wrapper = shallowRender(); | |||
@@ -48,7 +48,7 @@ describe('fetchBranchStatus', () => { | |||
await waitAndUpdate(wrapper); | |||
expect(wrapper.state().branchStatusByComponent).toEqual({ | |||
[projectKey]: { [`branch-${branchName}`]: status } | |||
[projectKey]: { [`branch-${branchName}`]: status }, | |||
}); | |||
}); | |||
@@ -24,5 +24,5 @@ import { ComponentContextShape } from '../../../types/component'; | |||
export const ComponentContext = React.createContext<ComponentContextShape>({ | |||
branchLikes: [], | |||
onBranchesChange: noop, | |||
onComponentChange: noop | |||
onComponentChange: noop, | |||
}); |
@@ -33,7 +33,7 @@ export default function withComponentContext<P extends Partial<ComponentContextS | |||
render() { | |||
return ( | |||
<ComponentContext.Consumer> | |||
{componentContext => <WrappedComponent {...componentContext} {...(this.props as P)} />} | |||
{(componentContext) => <WrappedComponent {...componentContext} {...(this.props as P)} />} | |||
</ComponentContext.Consumer> | |||
); | |||
} |
@@ -36,17 +36,17 @@ export default class CurrentUserContextProvider extends React.PureComponent<Prop | |||
} | |||
updateCurrentUserHomepage = (homepage: HomePage) => { | |||
this.setState(prevState => ({ | |||
currentUser: { ...prevState.currentUser, homepage } | |||
this.setState((prevState) => ({ | |||
currentUser: { ...prevState.currentUser, homepage }, | |||
})); | |||
}; | |||
updateDismissedNotices = (key: NoticeType, value: boolean) => { | |||
this.setState(prevState => ({ | |||
this.setState((prevState) => ({ | |||
currentUser: { | |||
...prevState.currentUser, | |||
dismissedNotices: { ...prevState.currentUser.dismissedNotices, [key]: value } | |||
} | |||
dismissedNotices: { ...prevState.currentUser.dismissedNotices, [key]: value }, | |||
}, | |||
})); | |||
}; | |||
@@ -56,8 +56,9 @@ export default class CurrentUserContextProvider extends React.PureComponent<Prop | |||
value={{ | |||
currentUser: this.state.currentUser, | |||
updateCurrentUserHomepage: this.updateCurrentUserHomepage, | |||
updateDismissedNotices: this.updateDismissedNotices | |||
}}> | |||
updateDismissedNotices: this.updateDismissedNotices, | |||
}} | |||
> | |||
{this.props.children} | |||
</CurrentUserContext.Provider> | |||
); |
@@ -49,7 +49,7 @@ export default class CreateApplicationForm extends React.PureComponent<Props, St | |||
description: '', | |||
key: '', | |||
name: '', | |||
visibility: Visibility.Public | |||
visibility: Visibility.Public, | |||
}; | |||
} | |||
@@ -84,7 +84,7 @@ export default class CreateApplicationForm extends React.PureComponent<Props, St | |||
if (this.mounted) { | |||
this.props.onCreate({ | |||
key: application.key, | |||
qualifier: ComponentQualifier.Application | |||
qualifier: ComponentQualifier.Application, | |||
}); | |||
} | |||
} | |||
@@ -101,7 +101,8 @@ export default class CreateApplicationForm extends React.PureComponent<Props, St | |||
header={header} | |||
onClose={this.props.onClose} | |||
onSubmit={this.handleFormSubmit} | |||
size="small"> | |||
size="small" | |||
> | |||
{({ onCloseClick, onFormSubmit, submitting }) => ( | |||
<form className="views-form" onSubmit={onFormSubmit}> | |||
<div className="modal-head"> | |||
@@ -156,13 +157,14 @@ export default class CreateApplicationForm extends React.PureComponent<Props, St | |||
<div className="modal-field"> | |||
<label>{translate('visibility')}</label> | |||
<div className="little-spacer-top"> | |||
{[Visibility.Public, Visibility.Private].map(v => ( | |||
{[Visibility.Public, Visibility.Private].map((v) => ( | |||
<Radio | |||
className={`big-spacer-right visibility-${v}`} | |||
key={v} | |||
checked={visibility === v} | |||
value={v} | |||
onCheck={this.handleVisibilityChange}> | |||
onCheck={this.handleVisibilityChange} | |||
> | |||
{translate('visibility', v)} | |||
</Radio> | |||
))} | |||
@@ -178,7 +180,8 @@ export default class CreateApplicationForm extends React.PureComponent<Props, St | |||
<ResetButtonLink | |||
className="js-modal-close" | |||
id="view-edit-cancel" | |||
onClick={onCloseClick}> | |||
onClick={onCloseClick} | |||
> | |||
{translate('cancel')} | |||
</ResetButtonLink> | |||
</div> |
@@ -84,7 +84,7 @@ export class Extension extends React.PureComponent<Props, State> { | |||
// See SONAR-16207 and core-extension-enterprise-server/src/main/js/portfolios/components/Header.tsx | |||
// for more information on why we're passing this as a prop to an extension. | |||
updateCurrentUserHomepage: this.props.updateCurrentUserHomepage, | |||
...this.props.options | |||
...this.props.options, | |||
}); | |||
if (result) { | |||
@@ -120,7 +120,7 @@ export class Extension extends React.PureComponent<Props, State> { | |||
{this.state.extensionElement ? ( | |||
this.state.extensionElement | |||
) : ( | |||
<div ref={container => (this.container = container)} /> | |||
<div ref={(container) => (this.container = container)} /> | |||
)} | |||
</div> | |||
); |
@@ -27,6 +27,6 @@ export default function GlobalAdminPageExtension() { | |||
const { pluginKey, extensionKey } = useParams(); | |||
const { adminPages } = useOutletContext<AdminPagesContext>(); | |||
const extension = (adminPages || []).find(p => p.key === `${pluginKey}/${extensionKey}`); | |||
const extension = (adminPages || []).find((p) => p.key === `${pluginKey}/${extensionKey}`); | |||
return extension ? <Extension extension={extension} /> : <NotFound withContainer={false} />; | |||
} |
@@ -35,7 +35,7 @@ export interface GlobalPageExtensionProps { | |||
function GlobalPageExtension(props: GlobalPageExtensionProps) { | |||
const { | |||
appState: { globalPages }, | |||
params | |||
params, | |||
} = props; | |||
const { extensionKey, pluginKey } = useParams(); | |||
@@ -44,7 +44,7 @@ function GlobalPageExtension(props: GlobalPageExtensionProps) { | |||
? `${params.pluginKey}/${params.extensionKey}` | |||
: `${pluginKey}/${extensionKey}`; | |||
const extension = (globalPages || []).find(p => p.key === fullKey); | |||
const extension = (globalPages || []).find((p) => p.key === fullKey); | |||
return extension ? <Extension extension={extension} /> : <NotFound withContainer={false} />; | |||
} | |||
@@ -30,7 +30,9 @@ export default function ProjectAdminPageExtension() { | |||
const extension = | |||
component && | |||
component.configuration && | |||
(component.configuration.extensions || []).find(p => p.key === `${pluginKey}/${extensionKey}`); | |||
(component.configuration.extensions || []).find( | |||
(p) => p.key === `${pluginKey}/${extensionKey}` | |||
); | |||
return extension ? ( | |||
<Extension extension={extension} options={{ component }} /> |
@@ -43,7 +43,7 @@ export default function ProjectPageExtension({ params }: ProjectPageExtensionPro | |||
? `${params.pluginKey}/${params.extensionKey}` | |||
: `${pluginKey}/${extensionKey}`; | |||
const extension = component.extensions && component.extensions.find(p => p.key === fullKey); | |||
const extension = component.extensions && component.extensions.find((p) => p.key === fullKey); | |||
return extension ? ( | |||
<Extension extension={extension} options={{ branchLike, component }} /> | |||
) : ( |
@@ -26,7 +26,7 @@ import { ComponentQualifier, Visibility } from '../../../../types/component'; | |||
import CreateApplicationForm from '../CreateApplicationForm'; | |||
jest.mock('../../../../api/application', () => ({ | |||
createApplication: jest.fn().mockResolvedValue({ application: { key: 'foo' } }) | |||
createApplication: jest.fn().mockResolvedValue({ application: { key: 'foo' } }), | |||
})); | |||
beforeEach(jest.clearAllMocks); | |||
@@ -47,17 +47,14 @@ it('should correctly create application on form submit', async () => { | |||
instance.handleNameChange(mockEvent({ currentTarget: { value: 'name' } })); | |||
instance.handleVisibilityChange(Visibility.Private); | |||
wrapper | |||
.find(SimpleModal) | |||
.props() | |||
.onSubmit(); | |||
wrapper.find(SimpleModal).props().onSubmit(); | |||
expect(createApplication).toHaveBeenCalledWith('name', 'description', 'key', Visibility.Private); | |||
await waitAndUpdate(wrapper); | |||
expect(onCreate).toHaveBeenCalledWith( | |||
expect.objectContaining({ | |||
key: 'foo', | |||
qualifier: ComponentQualifier.Application | |||
qualifier: ComponentQualifier.Application, | |||
}) | |||
); | |||
@@ -25,17 +25,17 @@ import { | |||
mockAppState, | |||
mockCurrentUser, | |||
mockLocation, | |||
mockRouter | |||
mockRouter, | |||
} from '../../../../helpers/testMocks'; | |||
import { waitAndUpdate } from '../../../../helpers/testUtils'; | |||
import { Extension } from '../Extension'; | |||
jest.mock('../../../../helpers/extensions', () => ({ | |||
getExtensionStart: jest.fn().mockResolvedValue({}) | |||
getExtensionStart: jest.fn().mockResolvedValue({}), | |||
})); | |||
jest.mock('react-helmet-async', () => ({ | |||
Helmet: () => null | |||
Helmet: () => null, | |||
})); | |||
beforeEach(() => { |
@@ -28,7 +28,7 @@ jest.mock('../Extension', () => ({ | |||
__esModule: true, | |||
default(props: { extension: { key: string; name: string } }) { | |||
return <h1>{props.extension.name}</h1>; | |||
} | |||
}, | |||
})); | |||
const extensions = [{ key: 'plugin123/ext42', name: 'extension 42' }]; | |||
@@ -60,6 +60,6 @@ function renderGlobalPageExtension( | |||
) { | |||
renderApp(`extension/:pluginKey/:extensionKey`, <GlobalPageExtension params={params} />, { | |||
appState: mockAppState({ globalPages }), | |||
navigateTo | |||
navigateTo, | |||
}); | |||
} |
@@ -30,13 +30,13 @@ import { ComponentContext } from '../../componentContext/ComponentContext'; | |||
import ProjectAdminPageExtension from '../ProjectAdminPageExtension'; | |||
jest.mock('../../../../helpers/extensions', () => ({ | |||
getExtensionStart: jest.fn().mockResolvedValue(jest.fn()) | |||
getExtensionStart: jest.fn().mockResolvedValue(jest.fn()), | |||
})); | |||
it('should render correctly when the extension is found', () => { | |||
renderProjectAdminPageExtension( | |||
mockComponent({ | |||
configuration: { extensions: [{ key: 'pluginId/extensionId', name: 'name' }] } | |||
configuration: { extensions: [{ key: 'pluginId/extensionId', name: 'name' }] }, | |||
}), | |||
{ pluginKey: 'pluginId', extensionKey: 'extensionId' } | |||
); |
@@ -30,7 +30,7 @@ import { ComponentContext } from '../../componentContext/ComponentContext'; | |||
import ProjectPageExtension, { ProjectPageExtensionProps } from '../ProjectPageExtension'; | |||
jest.mock('../../../../helpers/extensions', () => ({ | |||
getExtensionStart: jest.fn().mockResolvedValue(jest.fn()) | |||
getExtensionStart: jest.fn().mockResolvedValue(jest.fn()), | |||
})); | |||
it('should not render when no component is passed', () => { |
@@ -27,7 +27,7 @@ import { | |||
Button, | |||
EditButton, | |||
ResetButtonLink, | |||
SubmitButton | |||
SubmitButton, | |||
} from '../../../components/controls/buttons'; | |||
import ButtonToggle from '../../../components/controls/ButtonToggle'; | |||
import Checkbox from '../../../components/controls/Checkbox'; | |||
@@ -85,7 +85,7 @@ import { | |||
isBranch, | |||
isMainBranch, | |||
isPullRequest, | |||
sortBranches | |||
sortBranches, | |||
} from '../../../helpers/branch-like'; | |||
import { throwGlobalError } from '../../../helpers/error'; | |||
import { addGlobalSuccessMessage } from '../../../helpers/globalMessages'; | |||
@@ -101,7 +101,7 @@ import { | |||
post, | |||
postJSON, | |||
postJSONBody, | |||
request | |||
request, | |||
} from '../../../helpers/request'; | |||
import { sanitizeStringRestricted } from '../../../helpers/sanitize'; | |||
import { | |||
@@ -110,7 +110,7 @@ import { | |||
renderOwaspTop102021Category, | |||
renderOwaspTop10Category, | |||
renderSansTop25Category, | |||
renderSonarSourceSecurityCategory | |||
renderSonarSourceSecurityCategory, | |||
} from '../../../helpers/security-standard'; | |||
import { | |||
getCodeUrl, | |||
@@ -118,7 +118,7 @@ import { | |||
getComponentIssuesUrl, | |||
getComponentSecurityHotspotsUrl, | |||
getMeasureHistoryUrl, | |||
getRulesUrl | |||
getRulesUrl, | |||
} from '../../../helpers/urls'; | |||
const exposeLibraries = () => { | |||
@@ -135,7 +135,7 @@ const exposeLibraries = () => { | |||
postJSON, | |||
postJSONBody, | |||
throwGlobalError, | |||
addGlobalSuccessMessage | |||
addGlobalSuccessMessage, | |||
}; | |||
global.t = translate; | |||
global.tp = translateWithParameters; | |||
@@ -166,9 +166,9 @@ const exposeLibraries = () => { | |||
getComponentSecurityHotspotsUrl, | |||
getMeasureHistoryUrl, | |||
getRulesUrl, | |||
sanitizeStringRestricted | |||
sanitizeStringRestricted, | |||
}; | |||
} | |||
}, | |||
}); | |||
/** | |||
@@ -179,7 +179,7 @@ const exposeLibraries = () => { | |||
// eslint-disable-next-line no-console | |||
console.warn('SonarMeasures usages are deprecated since SonarQube 8.7'); | |||
return { ...measures }; | |||
} | |||
}, | |||
}); | |||
/** | |||
@@ -253,9 +253,9 @@ const exposeLibraries = () => { | |||
Suggestions, | |||
Tooltip, | |||
VulnerabilityIcon, | |||
WarningIcon | |||
WarningIcon, | |||
}; | |||
} | |||
}, | |||
}); | |||
}; | |||
@@ -19,7 +19,7 @@ | |||
*/ | |||
import * as React from 'react'; | |||
import withIndexationContext, { | |||
WithIndexationContextProps | |||
WithIndexationContextProps, | |||
} from '../../../components/hoc/withIndexationContext'; | |||
import { hasGlobalPermission } from '../../../helpers/users'; | |||
import { IndexationNotificationType } from '../../../types/indexation'; | |||
@@ -70,13 +70,13 @@ export class IndexationNotification extends React.PureComponent<Props, State> { | |||
this.setState({ | |||
notificationType: hasFailures | |||
? IndexationNotificationType.InProgressWithFailure | |||
: IndexationNotificationType.InProgress | |||
: IndexationNotificationType.InProgress, | |||
}); | |||
} else if (hasFailures) { | |||
this.setState({ notificationType: IndexationNotificationType.CompletedWithFailure }); | |||
} else if (IndexationNotificationHelper.shouldDisplayCompletedNotification()) { | |||
this.setState({ | |||
notificationType: IndexationNotificationType.Completed | |||
notificationType: IndexationNotificationType.Completed, | |||
}); | |||
IndexationNotificationHelper.markCompletedNotificationAsDisplayed(); | |||
@@ -93,8 +93,8 @@ export class IndexationNotification extends React.PureComponent<Props, State> { | |||
const { notificationType } = this.state; | |||
const { | |||
indexationContext: { | |||
status: { percentCompleted } | |||
} | |||
status: { percentCompleted }, | |||
}, | |||
} = this.props; | |||
if (notificationType === undefined) { |
@@ -32,7 +32,7 @@ export default class IndexationNotificationHelper { | |||
this.stopPolling(); | |||
// eslint-disable-next-line promise/catch-or-return | |||
this.poll(onNewStatus).then(status => { | |||
this.poll(onNewStatus).then((status) => { | |||
if (!status.isCompleted) { | |||
this.interval = setInterval(() => this.poll(onNewStatus), POLLING_INTERVAL_MS); | |||
} |