-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SWG-9025 Fetch organization standardization configuration command (#410)
* SWG-9025 Fetch organization standardization configuration command * SWG-9025 small tweaks around functionality and naming * SWG-9025 first batch of tests * SWG-9025 tests + docs * SWG-9025 improving my english * SWG-9025 removing spaces
- Loading branch information
1 parent
2494aa1
commit c31e8d6
Showing
5 changed files
with
259 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
const { Flags, Args } = require('@oclif/core') | ||
const BaseCommand = require('../../../support/command/base-command') | ||
const { pipeAsync } = require('../../../utils/general') | ||
const { getResponseContent } = require('../../../support/command/handle-response') | ||
const { getStandardization } = require('../../../requests/standardization') | ||
|
||
class ValidateDownloadRulesCommand extends BaseCommand { | ||
async run() { | ||
const { args, flags } = await this.parse(ValidateDownloadRulesCommand) | ||
|
||
const includeSystemRules = flags['include-system-rules'] ?? false | ||
const includeDisabledRules = flags['include-disabled-rules'] ?? false | ||
const organization = args['OWNER'] | ||
|
||
const organizationRuleset = await this.getExportedOrganizationRuleset(organization, {includeSystemRules, includeDisabledRules}) | ||
this.log(JSON.stringify(organizationRuleset, null, 2)) | ||
} | ||
|
||
getExportedOrganizationRuleset(orgName, queryParams) { | ||
return this.executeHttp({ | ||
execute: () => getStandardization([orgName, 'spectral'], queryParams), | ||
onResolve: pipeAsync(getResponseContent, JSON.parse), | ||
options: {} | ||
}) | ||
} | ||
} | ||
|
||
ValidateDownloadRulesCommand.description = `Get existing SwaggerHub's organization standardization ruleset. | ||
Requires organization name argument. An error will occur if provided organization doesn't exist | ||
or your account is not permitted to access that organization's settings. | ||
If the flag \`-s\` or \`--include-system-rules\` is used, the returned ruleset will also include SwaggerHub system rules. | ||
If the flag \`-d\` or \`--include-disabled-rules\` is used, the returned ruleset will also include disabled custom rules` | ||
|
||
ValidateDownloadRulesCommand.examples = [ | ||
'swaggerhub api:validate:download-rules myOrg -s', | ||
'swaggerhub api:validate:download-rules myOrg --include-disabled-rules -s', | ||
] | ||
|
||
ValidateDownloadRulesCommand.args = { | ||
'OWNER': Args.string({ | ||
required: true, | ||
description: 'Which organization standardization rules to fetch from SwaggerHub' | ||
}) | ||
} | ||
ValidateDownloadRulesCommand.flags = { | ||
'include-system-rules': Flags.boolean({ | ||
char: 's', | ||
description: 'Includes system rules in fetched organization\'s ruleset', | ||
required: false | ||
}), | ||
'include-disabled-rules': Flags.boolean({ | ||
char: 'd', | ||
description: 'Includes disabled rules in fetched organization\'s ruleset', | ||
required: false | ||
}), | ||
...BaseCommand.flags | ||
} | ||
module.exports = ValidateDownloadRulesCommand |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
const { expect, test } = require('@oclif/test') | ||
const config = require('../../../../src/config') | ||
const { | ||
ruleset, | ||
rulesetWithDisabledRule, | ||
rulesetWithSystemRule, | ||
rulesetWithDisabledAndSystemRule | ||
} = require('../../../resources/rulesets') | ||
|
||
const orgName = 'org1' | ||
describe('invalid api:validate:download-rules', () => { | ||
test | ||
.stdout() | ||
.command(['api:validate:download-rules']) | ||
.exit(2) | ||
.it('runs api:validate:download-rules with no organization name provided') | ||
|
||
test | ||
.stub(config, 'getConfig', () => ({ SWAGGERHUB_URL: 'https://api.swaggerhub.com' })) | ||
.nock('https://api.swaggerhub.com/standardization',{ reqheaders: { Accept: 'application/json' }}, api => api | ||
.get(`/org2/spectral`) | ||
.query({ includeSystemRules : false, includeDisabledRules : false}) | ||
.reply(404, 'Access Denied') | ||
) | ||
.command(['api:validate:download-rules', 'org2']) | ||
.exit(2) | ||
.it('Access Denied returned when trying to fetch ruleset of not existing or not available organization') | ||
|
||
test | ||
.stub(config, 'isURLValid', () => false) | ||
.command(['api:validate:download-rules', 'org1']) | ||
.catch(ctx => | ||
expect(ctx.message).to.equal('Please verify that the configured SwaggerHub URL is correct.') | ||
) | ||
.it('invalid SwaggerHub URL provided in the config') | ||
}) | ||
|
||
describe('valid api:validate:download-rules', () => { | ||
test | ||
.stub(config, 'getConfig', () => ({ SWAGGERHUB_URL: 'https://api.swaggerhub.com' })) | ||
.nock('https://api.swaggerhub.com/standardization',{ reqheaders: { Accept: 'application/json' }}, api => api | ||
.get(`/${orgName}/spectral`) | ||
.query({ includeSystemRules : false, includeDisabledRules : false}) | ||
.reply(200, ruleset) | ||
) | ||
.stdout() | ||
.command(['api:validate:download-rules', 'org1']) | ||
.it('runs api:validate:download-rules and returns organization rules without system rules nor disabled rules', ctx => { | ||
expect(ctx.stdout).to.contains(JSON.stringify(ruleset, null, 2)) | ||
}) | ||
|
||
test | ||
.stub(config, 'getConfig', () => ({ SWAGGERHUB_URL: 'https://api.swaggerhub.com' })) | ||
.nock('https://api.swaggerhub.com/standardization',{ reqheaders: { Accept: 'application/json' }}, api => api | ||
.get(`/${orgName}/spectral`) | ||
.query({ includeSystemRules : true, includeDisabledRules : false}) | ||
.reply(200, rulesetWithSystemRule) | ||
) | ||
.stdout() | ||
.command(['api:validate:download-rules', 'org1', '-s']) | ||
.it('runs api:validate:download-rules and returns organization rules with system rules, but without disabled rules', ctx => { | ||
expect(ctx.stdout).to.contains(JSON.stringify(rulesetWithSystemRule, null, 2)) | ||
}) | ||
|
||
test | ||
.stub(config, 'getConfig', () => ({ SWAGGERHUB_URL: 'https://api.swaggerhub.com' })) | ||
.nock('https://api.swaggerhub.com/standardization',{ reqheaders: { Accept: 'application/json' }}, api => api | ||
.get(`/${orgName}/spectral`) | ||
.query({ includeSystemRules : false, includeDisabledRules : true}) | ||
.reply(200, rulesetWithDisabledRule) | ||
) | ||
.stdout() | ||
.command(['api:validate:download-rules', 'org1', '-d']) | ||
.it('runs api:validate:download-rules and returns organization rules without system rules, but with disabled rules', ctx => { | ||
expect(ctx.stdout).to.contains(JSON.stringify(rulesetWithDisabledRule, null, 2)) | ||
}) | ||
|
||
|
||
test | ||
.stub(config, 'getConfig', () => ({ SWAGGERHUB_URL: 'https://api.swaggerhub.com' })) | ||
.nock('https://api.swaggerhub.com/standardization',{ reqheaders: { Accept: 'application/json' }}, api => api | ||
.get(`/${orgName}/spectral`) | ||
.query({ includeSystemRules : true, includeDisabledRules : true}) | ||
.reply(200, rulesetWithDisabledAndSystemRule) | ||
) | ||
.stdout() | ||
.command(['api:validate:download-rules', 'org1', '-s', '-d']) | ||
.it('runs api:validate:download-rules and returns organization rules with system rules and disabled rules', ctx => { | ||
expect(ctx.stdout).to.contains(JSON.stringify(rulesetWithDisabledAndSystemRule, null, 2)) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
const baseRulesetConfiguration = { | ||
"extends": [ | ||
"https://api.dev.swaggerhub.com/standardization/spectral/system-rules", | ||
"https://api.dev.swaggerhub.com/standardization/spectral/styleguide/owasp-top-10.js" | ||
], | ||
"documentationUrl": "https://support.smartbear.com/swaggerhub/docs/en/manage-resource-access/api-standardization.html#UUID-5425b1a0-27d3-677c-54f2-f2acab09a7a6_section-idm4667026578035233960922912739", | ||
} | ||
|
||
const basicRules = { | ||
"owasp:api1:2019-no-numeric-ids": "error", | ||
"custom-rule": { | ||
"description": "description", | ||
"message": "message", | ||
"formats": [ | ||
"oas2", | ||
"oas3_0", | ||
"oas3_1" | ||
], | ||
"severity": "off", | ||
"given": "$.info.title", | ||
"then": { | ||
"function": "pattern", | ||
"functionOptions": { | ||
"match": "some-title" | ||
} | ||
} | ||
} | ||
} | ||
|
||
const disabledRule ={ | ||
"disabled-custom-rule": { | ||
"description": "description", | ||
"message": "message", | ||
"formats": [ | ||
"oas2", | ||
"oas3_0", | ||
"oas3_1" | ||
], | ||
"severity": "off", | ||
"given": "$.info.title", | ||
"then": { | ||
"function": "pattern", | ||
"functionOptions": { | ||
"match": "some-title" | ||
} | ||
} | ||
} | ||
} | ||
|
||
const systemRule ={ | ||
"swaggerhub-asyncapi-tags-at-least-one": "error" | ||
} | ||
|
||
const ruleset = {...baseRulesetConfiguration, rules: basicRules} | ||
const rulesetWithSystemRule = {...baseRulesetConfiguration, rules: {...basicRules, ...systemRule}} | ||
const rulesetWithDisabledRule = {...baseRulesetConfiguration, rules: {...basicRules, ...disabledRule}} | ||
const rulesetWithDisabledAndSystemRule = {...baseRulesetConfiguration, rules: {...basicRules, ...disabledRule, ...systemRule}} | ||
|
||
module.exports = { | ||
ruleset, | ||
rulesetWithSystemRule, | ||
rulesetWithDisabledRule, | ||
rulesetWithDisabledAndSystemRule | ||
} |