Skip to content

Commit 7ee8be7

Browse files
committed
feat(sonar-services): add rule list and detail
1 parent 73e5b41 commit 7ee8be7

File tree

10 files changed

+554
-7
lines changed

10 files changed

+554
-7
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* Sustainability tags used to filter issues or rules
3+
*
4+
* - `sustainability`: generic tag used on some sonar rules
5+
* - `greensight`: tag used by the Capgemini Greensight plugin
6+
* - `ecocode`: tag occasionaly used when creedengo was called ecocode
7+
* - `creedengo`: tag identifying rules provided by Creedengo plugins
8+
*
9+
* @type {string}
10+
*/
11+
export const SUSTAINABILITY_TAGS = 'sustainability,greensight,ecocode,creedengo'

shared/sonar-services/src/api/issues/sonar.issues.search.api.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
//import sonarRequestAPI from '@sonar/sonar-request'
22
import sonarRequestAPI from '../polyfills/sonar-request.js'
3+
import { SUSTAINABILITY_TAGS } from '../constants.js'
34

45
const API = 'api/issues'
56
const routeUrl = `${API}/search`
67
const sustainabilitySearchParams = {
78
issueStatuses: 'OPEN,CONFIRMED',
89
statuses: 'OPEN,CONFIRMED,REOPENED', // legacy support
9-
tags: 'sustainability,greensight,ecocode,creedengo',
10+
tags: SUSTAINABILITY_TAGS,
1011
}
1112

1213
/**
@@ -39,18 +40,19 @@ function facetFormater(result, severity) {
3940
* Get an issues facet for a given project, branch, and facet name.
4041
*
4142
* @param {string} facetName
42-
* @param {Object} options
43-
* @param {string} options.project key of the project
44-
* @param {string} options.branch
43+
* @param {Object} config
44+
* @param {string} config.project key of the project
45+
* @param {string} config.branch
4546
* @returns Promise<{[key: string]: number}>
4647
*/
47-
export async function getIssuesFacet(facetName, { project, branch}) {
48+
export async function getIssuesFacet(facetName, { project, branch, severity }) {
4849
const searchParams = {
4950
...sustainabilitySearchParams,
5051
componentKeys: project,
5152
branch,
53+
severity,
5254
facets: facetName,
53-
ps: 1, // no issues parsing, we only want the facets
55+
ps: 0, // no issues parsing, we only want the facets
5456
}
5557
const { facets } = await sonarRequestAPI.getJSON(routeUrl, searchParams);
5658

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import * as search from './sonar.rules.search.api.js'
2+
import * as show from './sonar.rules.show.api.js'
3+
4+
export default {
5+
...search,
6+
...show
7+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//import sonarRequestAPI from '@sonar/sonar-request'
2+
import sonarRequestAPI from '../polyfills/sonar-request.js'
3+
import { SUSTAINABILITY_TAGS } from '../constants.js'
4+
5+
const API = 'api/rules'
6+
const routeUrl = `${API}/search`
7+
const sustainabilitySearchParams = { tags: SUSTAINABILITY_TAGS }
8+
9+
/**
10+
* Return Sonarqube rules
11+
* !! only gather sustainability rules !!
12+
*
13+
* @param {Object} params
14+
* @param {string} params.rule_key
15+
* @param {string} params.languages
16+
* @param {string} params.qprofile
17+
* @param {'true'|'false'|'yes'|'no'} params.prioritizedRule
18+
* @param {'INFO'|'MINOR'|'MAJOR'|'CRITICAL'|'BLOCKER'} params.severities
19+
* @param {'INFO'|'LOW'|'MEDIUM'|'HIGH'|'BLOCKER'} params.impactSeverities
20+
* @param {'MAINTAINABILITY'|'RELIABILITY'|'SECURITY'} params.impactSoftwareQualities
21+
* @returns Promise<Array<{[key: string]: any}>>
22+
*/
23+
export async function findRules({ project, branch }) {
24+
const searchParams = {
25+
...sustainabilitySearchParams,
26+
componentKeys: project,
27+
branch,
28+
}
29+
const page = await sonarRequestAPI.getJSON(routeUrl, searchParams)
30+
const { rules = [] } = page
31+
return rules
32+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { setupServer } from 'msw/node'
2+
import { HttpResponse, http } from 'msw'
3+
import { afterAll, afterEach, beforeAll, describe, expect, test } from 'vitest'
4+
5+
import mockRuleList from './sonar.rules.search.mock'
6+
import { findRules } from './sonar.rules.search.api'
7+
8+
export const restHandlers = [
9+
http.get('/api/rules/search', () => HttpResponse.json(mockRuleList))
10+
]
11+
12+
const server = setupServer(...restHandlers)
13+
// Start server before all tests
14+
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))
15+
// Close server after all tests
16+
afterAll(() => server.close())
17+
// Reset handlers after each test `important for test isolation`
18+
afterEach(() => server.resetHandlers())
19+
20+
describe('findRules', () => {
21+
test('findRules retrieve 1 rule', async () => {
22+
const issues = await findRules({ project: 'foo', branch: 'master' })
23+
expect(issues).toStrictEqual(mockRuleList.rules)
24+
})
25+
})

0 commit comments

Comments
 (0)