migrate some services from examples to openApi part 46; affects [codeclimate librariesio nexus] and securityheaders (#9933)

* fix codeclimate tests

* migrate some services from examples to openApi

* fix nexus service tests

* update codeclimate tests again
This commit is contained in:
chris48s
2024-02-13 19:33:28 +00:00
committed by GitHub
parent e01272d7e2
commit c121889bdd
9 changed files with 170 additions and 219 deletions

View File

@@ -1,8 +1,8 @@
import Joi from 'joi' import Joi from 'joi'
import { colorScale, letterScore } from '../color-formatters.js' import { colorScale, letterScore } from '../color-formatters.js'
import { nonNegativeInteger } from '../validators.js' import { nonNegativeInteger } from '../validators.js'
import { BaseJsonService, NotFound } from '../index.js' import { BaseJsonService, NotFound, pathParams } from '../index.js'
import { keywords, isLetterGrade, fetchRepo } from './codeclimate-common.js' import { isLetterGrade, fetchRepo } from './codeclimate-common.js'
const schema = Joi.object({ const schema = Joi.object({
data: Joi.object({ data: Joi.object({
@@ -93,43 +93,43 @@ export default class CodeclimateAnalysis extends BaseJsonService {
':variant(maintainability|maintainability-percentage|tech-debt|issues)/:user/:repo', ':variant(maintainability|maintainability-percentage|tech-debt|issues)/:user/:repo',
} }
static examples = [ static openApi = {
{ '/codeclimate/{variant}/{user}/{repo}': {
title: 'Code Climate maintainability', get: {
pattern: summary: 'Code Climate maintainability',
':format(maintainability|maintainability-percentage)/:user/:repo', parameters: pathParams(
namedParams: { {
format: 'maintainability', name: 'variant',
user: 'tensorflow', example: 'maintainability',
repo: 'models', schema: {
type: 'string',
enum: ['maintainability', 'maintainability-percentage'],
},
},
{ name: 'user', example: 'tensorflow' },
{ name: 'repo', example: 'models' },
),
}, },
staticPreview: this.render({
variant: 'maintainability',
maintainabilityLetter: 'F',
}),
keywords,
}, },
{ '/codeclimate/tech-debt/{user}/{repo}': {
title: 'Code Climate issues', get: {
pattern: 'issues/:user/:repo', summary: 'Code Climate issues',
namedParams: { user: 'twbs', repo: 'bootstrap' }, parameters: pathParams(
staticPreview: this.render({ { name: 'user', example: 'tensorflow' },
variant: 'issues', { name: 'repo', example: 'models' },
issueCount: '89', ),
}), },
keywords,
}, },
{ '/codeclimate/issues/{user}/{repo}': {
title: 'Code Climate technical debt', get: {
pattern: 'tech-debt/:user/:repo', summary: 'Code Climate technical debt',
namedParams: { user: 'tensorflow', repo: 'models' }, parameters: pathParams(
staticPreview: this.render({ { name: 'user', example: 'tensorflow' },
variant: 'tech-debt', { name: 'repo', example: 'models' },
techDebtPercentage: 3.0, ),
}), },
keywords,
}, },
] }
static render({ variant, ...props }) { static render({ variant, ...props }) {
const { render } = variantMap[variant] const { render } = variantMap[variant]

View File

@@ -55,7 +55,7 @@ t.create('issues when outer user repos query returns multiple items')
relationships: { relationships: {
latest_default_branch_snapshot: { latest_default_branch_snapshot: {
data: { data: {
id: '64786eee4fedea000101580d', id: '65ae115f34117d0001055101',
type: 'snapshots', type: 'snapshots',
}, },
}, },

View File

@@ -1,8 +1,6 @@
import Joi from 'joi' import Joi from 'joi'
import { NotFound } from '../index.js' import { NotFound } from '../index.js'
const keywords = ['codeclimate']
const isLetterGrade = Joi.equal('A', 'B', 'C', 'D', 'E', 'F').required() const isLetterGrade = Joi.equal('A', 'B', 'C', 'D', 'E', 'F').required()
const repoSchema = Joi.object({ const repoSchema = Joi.object({
@@ -39,4 +37,4 @@ async function fetchRepo(serviceInstance, { user, repo }) {
return repoInfos return repoInfos
} }
export { keywords, isLetterGrade, fetchRepo } export { isLetterGrade, fetchRepo }

View File

@@ -1,7 +1,7 @@
import Joi from 'joi' import Joi from 'joi'
import { coveragePercentage, letterScore } from '../color-formatters.js' import { coveragePercentage, letterScore } from '../color-formatters.js'
import { BaseJsonService, NotFound } from '../index.js' import { BaseJsonService, NotFound, pathParams } from '../index.js'
import { keywords, isLetterGrade, fetchRepo } from './codeclimate-common.js' import { isLetterGrade, fetchRepo } from './codeclimate-common.js'
const schema = Joi.object({ const schema = Joi.object({
data: Joi.object({ data: Joi.object({
@@ -21,22 +21,22 @@ export default class CodeclimateCoverage extends BaseJsonService {
pattern: ':format(coverage|coverage-letter)/:user/:repo', pattern: ':format(coverage|coverage-letter)/:user/:repo',
} }
static examples = [ static openApi = {
{ '/codeclimate/{format}/{user}/{repo}': {
title: 'Code Climate coverage', get: {
namedParams: { summary: 'Code Climate coverage',
format: 'coverage', parameters: pathParams(
user: 'codeclimate', {
repo: 'codeclimate', name: 'format',
example: 'coverage',
schema: { type: 'string', enum: this.getEnum('format') },
},
{ name: 'user', example: 'codeclimate' },
{ name: 'repo', example: 'codeclimate' },
),
}, },
staticPreview: this.render({
format: 'coverage',
percentage: 95.123,
letter: 'A',
}),
keywords,
}, },
] }
static render({ wantLetter, percentage, letter }) { static render({ wantLetter, percentage, letter }) {
if (wantLetter) { if (wantLetter) {

View File

@@ -46,7 +46,7 @@ t.create('test coverage when outer user repos query returns multiple items')
}, },
latest_default_branch_test_report: { latest_default_branch_test_report: {
data: { data: {
id: '6463c8a3e3bc340001004bce', id: '65a1662cb0077b00013cb4de',
type: 'test_reports', type: 'test_reports',
}, },
}, },

View File

@@ -1,4 +1,5 @@
import Joi from 'joi' import Joi from 'joi'
import { pathParams } from '../index.js'
import LibrariesIoBase from './librariesio-base.js' import LibrariesIoBase from './librariesio-base.js'
import { import {
transform, transform,
@@ -24,62 +25,27 @@ class LibrariesIoProjectDependencies extends LibrariesIoBase {
pattern: ':platform/:scope(@[^/]+)?/:packageName/:version?', pattern: ':platform/:scope(@[^/]+)?/:packageName/:version?',
} }
static examples = [ static openApi = {
{ '/librariesio/release/{platform}/{packageName}': {
title: 'Libraries.io dependency status for latest release', get: {
pattern: ':platform/:packageName', summary: 'Libraries.io dependency status for latest release',
namedParams: { parameters: pathParams(
platform: 'hex', { name: 'platform', example: 'npm' },
packageName: 'phoenix', { name: 'packageName', example: '@babel/core' },
),
}, },
staticPreview: renderDependenciesBadge({
deprecatedCount: 0,
outdatedCount: 1,
}),
}, },
{ '/librariesio/release/{platform}/{packageName}/{version}': {
title: 'Libraries.io dependency status for specific release', get: {
pattern: ':platform/:packageName/:version', summary: 'Libraries.io dependency status for specific release',
namedParams: { parameters: pathParams(
platform: 'hex', { name: 'platform', example: 'npm' },
packageName: 'phoenix', { name: 'packageName', example: '@babel/core' },
version: '1.0.3', { name: 'version', example: '7.0.0' },
),
}, },
staticPreview: renderDependenciesBadge({
deprecatedCount: 0,
outdatedCount: 3,
}),
}, },
{ }
title:
'Libraries.io dependency status for latest release, scoped npm package',
pattern: ':platform/:scope/:packageName',
namedParams: {
platform: 'npm',
scope: '@babel',
packageName: 'core',
},
staticPreview: renderDependenciesBadge({
deprecatedCount: 8,
outdatedCount: 0,
}),
},
{
title:
'Libraries.io dependency status for specific release, scoped npm package',
pattern: ':platform/:scope/:packageName/:version',
namedParams: {
platform: 'npm',
scope: '@babel',
packageName: 'core',
version: '7.0.0',
},
staticPreview: renderDependenciesBadge({
deprecatedCount: 12,
outdatedCount: 0,
}),
},
]
static _cacheLength = 900 static _cacheLength = 900

View File

@@ -5,7 +5,13 @@ import {
optionalUrl, optionalUrl,
optionalDottedVersionNClausesWithOptionalSuffix, optionalDottedVersionNClausesWithOptionalSuffix,
} from '../validators.js' } from '../validators.js'
import { BaseJsonService, InvalidResponse, NotFound } from '../index.js' import {
BaseJsonService,
InvalidResponse,
NotFound,
pathParams,
queryParams,
} from '../index.js'
import { isSnapshotVersion } from './nexus-version.js' import { isSnapshotVersion } from './nexus-version.js'
const nexus2SearchApiSchema = Joi.object({ const nexus2SearchApiSchema = Joi.object({
@@ -51,6 +57,36 @@ const queryParamSchema = Joi.object({
nexusVersion: Joi.equal('2', '3'), nexusVersion: Joi.equal('2', '3'),
}).required() }).required()
const openApiQueryParams = queryParams(
{ name: 'server', example: 'https://oss.sonatype.org', required: true },
{
name: 'nexusVersion',
example: '2',
schema: { type: 'string', enum: ['2', '3'] },
description:
'Specifying `nexusVersion=3` when targeting Nexus 3 servers will speed up the badge rendering.',
},
{
name: 'queryOpt',
example: ':c=agent-apple-osx:p=tar.gz',
description: `<p>
Note that you can use query options with any Nexus badge type (Releases, Snapshots, or Repository).
</p>
<p>
Query options should be provided as key=value pairs separated by a colon.
</p>
<p>
Possible values:
<ul>
<li><a href="https://nexus.pentaho.org/swagger-ui/#/search/search">All Nexus 3 badges</a></li>
<li><a href="https://repository.sonatype.org/nexus-restlet1x-plugin/default/docs/path__artifact_maven_resolve.html">Nexus 2 Releases and Snapshots badges</a></li>
<li><a href="https://repository.sonatype.org/nexus-indexer-lucene-plugin/default/docs/path__lucene_search.html">Nexus 2 Repository badges</a></li>
</ul>
</p>
`,
},
)
export default class Nexus extends BaseJsonService { export default class Nexus extends BaseJsonService {
static category = 'version' static category = 'version'
@@ -66,88 +102,45 @@ export default class Nexus extends BaseJsonService {
serviceKey: 'nexus', serviceKey: 'nexus',
} }
static examples = [ static openApi = {
{ '/nexus/r/{groupId}/{artifactId}': {
title: 'Sonatype Nexus (Releases)', get: {
pattern: 'r/:groupId/:artifactId', summary: 'Sonatype Nexus (Releases)',
namedParams: { parameters: [
groupId: 'org.apache.commons', ...pathParams(
artifactId: 'commons-lang3', { name: 'groupId', example: 'com.google.guava' },
{ name: 'artifactId', example: 'guava' },
),
...openApiQueryParams,
],
}, },
queryParams: {
server: 'https://nexus.pentaho.org',
nexusVersion: '3',
},
staticPreview: this.render({
version: '3.9',
}),
documentation: `<p>
Specifying 'nexusVersion=3' when targeting Nexus 3 servers will speed up the badge rendering.
Note that you can use this query parameter with any Nexus badge type (Releases, Snapshots, or Repository).
</p>
`,
}, },
{ '/nexus/s/{groupId}/{artifactId}': {
title: 'Sonatype Nexus (Snapshots)', get: {
pattern: 's/:groupId/:artifactId', summary: 'Sonatype Nexus (Snapshots)',
namedParams: { parameters: [
groupId: 'com.google.guava', ...pathParams(
artifactId: 'guava', { name: 'groupId', example: 'com.google.guava' },
{ name: 'artifactId', example: 'guava' },
),
...openApiQueryParams,
],
}, },
queryParams: {
server: 'https://oss.sonatype.org',
},
staticPreview: this.render({
version: 'v24.0-SNAPSHOT',
}),
}, },
{ '/nexus/{repo}/{groupId}/{artifactId}': {
title: 'Sonatype Nexus (Repository)', get: {
pattern: ':repo/:groupId/:artifactId', summary: 'Sonatype Nexus (Repository)',
namedParams: { parameters: [
repo: 'developer', ...pathParams(
groupId: 'ai.h2o', { name: 'repo', example: 'snapshots' },
artifactId: 'h2o-automl', { name: 'groupId', example: 'com.google.guava' },
{ name: 'artifactId', example: 'guava' },
),
...openApiQueryParams,
],
}, },
queryParams: {
server: 'https://repository.jboss.org/nexus',
},
staticPreview: this.render({
version: '3.22.0.2',
}),
}, },
{ }
title: 'Sonatype Nexus (Query Options)',
pattern: ':repo/:groupId/:artifactId',
namedParams: {
repo: 'fs-public-snapshots',
groupId: 'com.progress.fuse',
artifactId: 'fusehq',
},
queryParams: {
server: 'https://repository.jboss.org/nexus',
queryOpt: ':c=agent-apple-osx:p=tar.gz',
},
staticPreview: this.render({
version: '7.0.1-SNAPSHOT',
}),
documentation: `<p>
Note that you can use query options with any Nexus badge type (Releases, Snapshots, or Repository).
</p>
<p>
Query options should be provided as key=value pairs separated by a colon.
</p>
<p>
Possible values:
<ul>
<li><a href="https://nexus.pentaho.org/swagger-ui/#/search/search">All Nexus 3 badges</a></li>
<li><a href="https://repository.sonatype.org/nexus-restlet1x-plugin/default/docs/path__artifact_maven_resolve.html">Nexus 2 Releases and Snapshots badges</a></li>
<li><a href="https://repository.sonatype.org/nexus-indexer-lucene-plugin/default/docs/path__lucene_search.html">Nexus 2 Repository badges</a></li>
</ul>
</p>
`,
},
]
static defaultBadgeData = { static defaultBadgeData = {
label: 'nexus', label: 'nexus',

View File

@@ -230,7 +230,7 @@ t.create('Nexus 2 - user query params')
t.create('Nexus 3 - search release version valid artifact') t.create('Nexus 3 - search release version valid artifact')
.get( .get(
'/r/org.apache.commons/commons-lang3.json?server=https://nexus.pentaho.org&nexusVersion=3', '/r/me.neznamy/tab-api.json?server=https://repo.tomkeuper.com&nexusVersion=3',
) )
.expectBadge({ .expectBadge({
label: 'nexus', label: 'nexus',
@@ -241,9 +241,7 @@ t.create(
'Nexus 3 - search release version valid artifact without explicit nexusVersion parameter', 'Nexus 3 - search release version valid artifact without explicit nexusVersion parameter',
) )
.timeout(15000) .timeout(15000)
.get( .get('/r/me.neznamy/tab-api.json?server=https://repo.tomkeuper.com')
'/r/org.apache.commons/commons-lang3.json?server=https://nexus.pentaho.org',
)
.expectBadge({ .expectBadge({
label: 'nexus', label: 'nexus',
message: isVersion, message: isVersion,
@@ -251,7 +249,7 @@ t.create(
t.create('Nexus 3 - search release version of an nonexistent artifact') t.create('Nexus 3 - search release version of an nonexistent artifact')
.get( .get(
'/r/org.apache.commons/nonexistent-artifact-id.json?server=https://nexus.pentaho.org&nexusVersion=3', '/r/me.neznamy/nonexistent-artifact-id.json?server=https://repo.tomkeuper.com&nexusVersion=3',
) )
.expectBadge({ .expectBadge({
label: 'nexus', label: 'nexus',
@@ -260,7 +258,7 @@ t.create('Nexus 3 - search release version of an nonexistent artifact')
t.create('Nexus 3 - search snapshot version valid snapshot artifact') t.create('Nexus 3 - search snapshot version valid snapshot artifact')
.get( .get(
'/s/org.pentaho/pentaho-registry.json?server=https://nexus.pentaho.org&nexusVersion=3', '/s/com.tomkeuper.bedwars/bedwars-api.json?server=https://repo.tomkeuper.com&nexusVersion=3',
) )
.expectBadge({ .expectBadge({
label: 'nexus', label: 'nexus',
@@ -269,7 +267,7 @@ t.create('Nexus 3 - search snapshot version valid snapshot artifact')
t.create('Nexus 3 - search snapshot version for artifact without snapshots') t.create('Nexus 3 - search snapshot version for artifact without snapshots')
.get( .get(
'/s/javax.inject/javax.inject.json?server=https://nexus.pentaho.org&nexusVersion=3', '/s/com.tomkeuper/spigot.json?server=https://repo.tomkeuper.com&nexusVersion=3',
) )
.expectBadge({ .expectBadge({
label: 'nexus', label: 'nexus',
@@ -279,7 +277,7 @@ t.create('Nexus 3 - search snapshot version for artifact without snapshots')
t.create('Nexus 3 - repository version') t.create('Nexus 3 - repository version')
.get( .get(
'/proxy-public-3rd-party-release/com.h2database/h2.json?server=https://nexus.pentaho.org&nexusVersion=3', '/bedwars-releases/me.neznamy/tab-api.json?server=https://repo.tomkeuper.com&nexusVersion=3',
) )
.expectBadge({ .expectBadge({
label: 'nexus', label: 'nexus',
@@ -291,7 +289,7 @@ t.create(
) )
.timeout(15000) .timeout(15000)
.get( .get(
'/proxy-public-3rd-party-release/com.h2database/h2.json?server=https://nexus.pentaho.org', '/bedwars-releases/me.neznamy/tab-api.json?server=https://repo.tomkeuper.com&nexusVersion=3',
) )
.expectBadge({ .expectBadge({
label: 'nexus', label: 'nexus',
@@ -300,7 +298,7 @@ t.create(
t.create('Nexus 3 - repository version with query') t.create('Nexus 3 - repository version with query')
.get( .get(
`/proxy-public-3rd-party-release/org.junit.jupiter/junit-jupiter.json?server=https://nexus.pentaho.org&nexusVersion=3&queryOpt=${encodeURIComponent( `/bedwars-releases/me.neznamy/tab-api.json?server=https://repo.tomkeuper.com&nexusVersion=3&queryOpt=${encodeURIComponent(
':maven.extension=jar:direction=asc', ':maven.extension=jar:direction=asc',
)}`, )}`,
) )
@@ -312,11 +310,11 @@ t.create('Nexus 3 - repository version with query')
t.create('Nexus 3 - search release version without snapshots') t.create('Nexus 3 - search release version without snapshots')
.get( .get(
// Limit the version from above, so that any later artifacts don't break this test. // Limit the version from above, so that any later artifacts don't break this test.
`/r/org.pentaho.adaptive/pdi-engines.json?server=https://nexus.pentaho.org&nexusVersion=3&queryOpt=${encodeURIComponent( `/r/me.neznamy/tab-api.json?server=https://repo.tomkeuper.com&nexusVersion=3&queryOpt=${encodeURIComponent(
':maven.baseVersion=<8.0.0.1', ':maven.baseVersion=<4.0.0.0',
)}`, )}`,
) )
.expectBadge({ .expectBadge({
label: 'nexus', label: 'nexus',
message: 'v8.0.0.0-28', message: 'v4.0.0',
}) })

View File

@@ -1,13 +1,13 @@
import Joi from 'joi' import Joi from 'joi'
import { optionalUrl } from '../validators.js' import { optionalUrl } from '../validators.js'
import { BaseService, NotFound } from '../index.js' import { BaseService, NotFound, queryParams } from '../index.js'
const queryParamSchema = Joi.object({ const queryParamSchema = Joi.object({
url: optionalUrl.required(), url: optionalUrl.required(),
ignoreRedirects: Joi.equal(''), ignoreRedirects: Joi.equal(''),
}).required() }).required()
const documentation = ` const description = `
The [Security Headers](https://securityheaders.com/) The [Security Headers](https://securityheaders.com/)
provide an easy mechanism to analyze HTTP response headers and provide an easy mechanism to analyze HTTP response headers and
give information on how to deploy missing headers. give information on how to deploy missing headers.
@@ -24,26 +24,22 @@ export default class SecurityHeaders extends BaseService {
queryParamSchema, queryParamSchema,
} }
static examples = [ static openApi = {
{ '/security-headers': {
title: 'Security Headers', get: {
namedParams: {}, summary: 'Security Headers',
queryParams: { url: 'https://shields.io' }, description,
staticPreview: this.render({ parameters: queryParams(
grade: 'A+', { name: 'url', example: 'https://shields.io', required: true },
}), {
documentation, name: 'ignoreRedirects',
schema: { type: 'boolean' },
example: null,
},
),
},
}, },
{ }
title: "Security Headers (Don't follow redirects)",
namedParams: {},
queryParams: { url: 'https://www.shields.io', ignoreRedirects: null },
staticPreview: this.render({
grade: 'R',
}),
documentation,
},
]
static defaultBadgeData = { static defaultBadgeData = {
label: 'security headers', label: 'security headers',