Merge pull request #4200 from SDA-SE/feat/sonarqube-supported-fields
Ask the SonarQube server for all support metrics prior to querying them for a project
This commit is contained in:
@@ -29,7 +29,31 @@ describe('SonarQubeClient', () => {
|
||||
const mockBaseUrl = 'http://backstage:9191/api/proxy';
|
||||
const discoveryApi = UrlPatternDiscovery.compile(mockBaseUrl);
|
||||
|
||||
const setupHandlers = () => {
|
||||
const setupHandlers = (
|
||||
metricKeys = [
|
||||
'alert_status',
|
||||
'bugs',
|
||||
'reliability_rating',
|
||||
'vulnerabilities',
|
||||
'security_rating',
|
||||
'security_hotspots_reviewed',
|
||||
'security_review_rating',
|
||||
'code_smells',
|
||||
'sqale_rating',
|
||||
'coverage',
|
||||
'duplicated_lines_density',
|
||||
],
|
||||
) => {
|
||||
server.use(
|
||||
rest.get(`${mockBaseUrl}/sonarqube/metrics/search`, (_, res, ctx) => {
|
||||
return res(
|
||||
ctx.json({
|
||||
metrics: metricKeys.map(k => ({ key: k })),
|
||||
}),
|
||||
);
|
||||
}),
|
||||
);
|
||||
|
||||
server.use(
|
||||
rest.get(`${mockBaseUrl}/sonarqube/components/show`, (req, res, ctx) => {
|
||||
expect(req.url.searchParams.toString()).toBe('component=our-service');
|
||||
@@ -46,8 +70,9 @@ describe('SonarQubeClient', () => {
|
||||
server.use(
|
||||
rest.get(`${mockBaseUrl}/sonarqube/measures/search`, (req, res, ctx) => {
|
||||
expect(req.url.searchParams.toString()).toBe(
|
||||
'projectKeys=our-service&metricKeys=alert_status%2Cbugs%2Creliability_rating%2Cvulnerabilities%2Csecurity_rating%2Csecurity_hotspots_reviewed%2Csecurity_review_rating%2Ccode_smells%2Csqale_rating%2Ccoverage%2Cduplicated_lines_density',
|
||||
`projectKeys=our-service&metricKeys=${metricKeys.join('%2C')}`,
|
||||
);
|
||||
|
||||
return res(
|
||||
ctx.json({
|
||||
measures: [
|
||||
@@ -111,7 +136,7 @@ describe('SonarQubeClient', () => {
|
||||
value: '1.0',
|
||||
component: 'our-service',
|
||||
},
|
||||
],
|
||||
].filter(m => metricKeys.includes(m.metric)),
|
||||
} as MeasuresWrapper),
|
||||
);
|
||||
}),
|
||||
@@ -187,4 +212,32 @@ describe('SonarQubeClient', () => {
|
||||
'http://a.instance.local/component_measures?id=our-service&metric=coverage&resolved=false&view=list',
|
||||
);
|
||||
});
|
||||
|
||||
it('should only request selected metrics', async () => {
|
||||
setupHandlers(['alert_status', 'bugs']);
|
||||
|
||||
const client = new SonarQubeClient({
|
||||
discoveryApi,
|
||||
baseUrl: 'http://a.instance.local',
|
||||
});
|
||||
|
||||
const summary = await client.getFindingSummary('our-service');
|
||||
|
||||
expect(summary).toEqual(
|
||||
expect.objectContaining({
|
||||
lastAnalysis: '2020-01-01T00:00:00Z',
|
||||
metrics: {
|
||||
alert_status: 'OK',
|
||||
bugs: '2',
|
||||
},
|
||||
projectUrl: 'http://a.instance.local/dashboard?id=our-service',
|
||||
}) as FindingSummary,
|
||||
);
|
||||
expect(summary?.getIssuesUrl('CODE_SMELL')).toEqual(
|
||||
'http://a.instance.local/project/issues?id=our-service&types=CODE_SMELL&resolved=false',
|
||||
);
|
||||
expect(summary?.getComponentMeasuresUrl('COVERAGE')).toEqual(
|
||||
'http://a.instance.local/component_measures?id=our-service&metric=coverage&resolved=false&view=list',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -43,6 +43,13 @@ export class SonarQubeClient implements SonarQubeApi {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private async getSupportedMetrics(): Promise<string[]> {
|
||||
const result = await this.callApi<{ metrics: Array<{ key: string }> }>(
|
||||
'metrics/search',
|
||||
);
|
||||
return result?.metrics?.map(m => m.key) ?? [];
|
||||
}
|
||||
|
||||
async getFindingSummary(
|
||||
componentKey?: string,
|
||||
): Promise<FindingSummary | undefined> {
|
||||
@@ -71,10 +78,16 @@ export class SonarQubeClient implements SonarQubeApi {
|
||||
duplicated_lines_density: undefined,
|
||||
};
|
||||
|
||||
// select the metrics that are supported by the SonarQube instance
|
||||
const supportedMetrics = await this.getSupportedMetrics();
|
||||
const metricKeys = Object.keys(metrics).filter(m =>
|
||||
supportedMetrics.includes(m),
|
||||
);
|
||||
|
||||
const measures = await this.callApi<MeasuresWrapper>(
|
||||
`measures/search?projectKeys=${componentKey}&metricKeys=${Object.keys(
|
||||
metrics,
|
||||
).join(',')}`,
|
||||
`measures/search?projectKeys=${componentKey}&metricKeys=${metricKeys.join(
|
||||
',',
|
||||
)}`,
|
||||
);
|
||||
if (!measures) {
|
||||
return undefined;
|
||||
|
||||
Reference in New Issue
Block a user