@redocly/openapi-core 1.23.1 → 1.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/lib/config/all.js +3 -0
  3. package/lib/config/config.js +4 -1
  4. package/lib/config/minimal.js +3 -0
  5. package/lib/config/recommended-strict.js +3 -0
  6. package/lib/config/recommended.js +3 -0
  7. package/lib/rules/arazzo/criteria-unique.d.ts +2 -0
  8. package/lib/rules/arazzo/criteria-unique.js +65 -0
  9. package/lib/rules/arazzo/index.js +6 -0
  10. package/lib/rules/spot/no-actions-type-end.d.ts +2 -0
  11. package/lib/rules/spot/no-actions-type-end.js +28 -0
  12. package/lib/rules/spot/no-criteria-xpath.d.ts +2 -0
  13. package/lib/rules/spot/no-criteria-xpath.js +21 -0
  14. package/lib/types/arazzo.js +1 -1
  15. package/lib/types/redocly-yaml.d.ts +1 -1
  16. package/lib/types/redocly-yaml.js +3 -0
  17. package/package.json +2 -2
  18. package/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +6 -0
  19. package/src/config/all.ts +3 -0
  20. package/src/config/config.ts +4 -1
  21. package/src/config/minimal.ts +3 -0
  22. package/src/config/recommended-strict.ts +3 -0
  23. package/src/config/recommended.ts +3 -0
  24. package/src/rules/arazzo/__tests__/criteria-unique.test.ts +161 -0
  25. package/src/rules/arazzo/__tests__/no-actions-type-end.test.ts +122 -0
  26. package/src/rules/arazzo/__tests__/no-criteria-xpath.test.ts +127 -0
  27. package/src/rules/arazzo/criteria-unique.ts +63 -0
  28. package/src/rules/arazzo/index.ts +6 -0
  29. package/src/rules/spot/no-actions-type-end.ts +27 -0
  30. package/src/rules/spot/no-criteria-xpath.ts +20 -0
  31. package/src/types/arazzo.ts +1 -1
  32. package/src/types/redocly-yaml.ts +3 -0
  33. package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @redocly/openapi-core
2
2
 
3
+ ## 1.24.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Added Spot and Arazzo rules: `no-criteria-xpath`, `no-actions-type-end`, `criteria-unique`.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated @redocly/ajv to v8.11.2.
12
+ - Fixed an issue where custom rules were not applied to Arazzo descriptions.
13
+
3
14
  ## 1.23.1
4
15
 
5
16
  ## 1.23.0
package/lib/config/all.js CHANGED
@@ -139,6 +139,9 @@ const all = {
139
139
  'step-onSuccess-unique': 'error',
140
140
  'step-onFailure-unique': 'error',
141
141
  'requestBody-replacements-unique': 'error',
142
+ 'no-criteria-xpath': 'error',
143
+ 'no-actions-type-end': 'error',
144
+ 'criteria-unique': 'error',
142
145
  },
143
146
  };
144
147
  exports.default = all;
@@ -38,7 +38,10 @@ class StyleguideConfig {
38
38
  [oas_types_1.SpecVersion.OAS3_1]: { ...rawConfig.rules, ...rawConfig.oas3_1Rules },
39
39
  [oas_types_1.SpecVersion.Async2]: { ...rawConfig.rules, ...rawConfig.async2Rules },
40
40
  [oas_types_1.SpecVersion.Async3]: { ...rawConfig.rules, ...rawConfig.async3Rules },
41
- [oas_types_1.SpecVersion.Arazzo]: { ...rawConfig.arazzoRules },
41
+ [oas_types_1.SpecVersion.Arazzo]: {
42
+ ...rawConfig.arazzoRules,
43
+ ...(rawConfig.rules?.assertions ? { assertions: rawConfig.rules.assertions } : {}),
44
+ },
42
45
  };
43
46
  this.preprocessors = {
44
47
  [oas_types_1.SpecVersion.OAS2]: { ...rawConfig.preprocessors, ...rawConfig.oas2Preprocessors },
@@ -121,6 +121,9 @@ const minimal = {
121
121
  'step-onSuccess-unique': 'off',
122
122
  'step-onFailure-unique': 'off',
123
123
  'requestBody-replacements-unique': 'off',
124
+ 'no-criteria-xpath': 'off',
125
+ 'no-actions-type-end': 'off',
126
+ 'criteria-unique': 'off',
124
127
  },
125
128
  };
126
129
  exports.default = minimal;
@@ -121,6 +121,9 @@ const recommendedStrict = {
121
121
  'step-onSuccess-unique': 'error',
122
122
  'step-onFailure-unique': 'error',
123
123
  'requestBody-replacements-unique': 'error',
124
+ 'no-criteria-xpath': 'error',
125
+ 'no-actions-type-end': 'error',
126
+ 'criteria-unique': 'error',
124
127
  },
125
128
  };
126
129
  exports.default = recommendedStrict;
@@ -121,6 +121,9 @@ const recommended = {
121
121
  'step-onSuccess-unique': 'warn',
122
122
  'step-onFailure-unique': 'warn',
123
123
  'requestBody-replacements-unique': 'warn',
124
+ 'no-criteria-xpath': 'warn',
125
+ 'no-actions-type-end': 'warn',
126
+ 'criteria-unique': 'warn',
124
127
  },
125
128
  };
126
129
  exports.default = recommended;
@@ -0,0 +1,2 @@
1
+ import type { ArazzoRule } from '../../visitors';
2
+ export declare const CriteriaUnique: ArazzoRule;
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CriteriaUnique = void 0;
4
+ const CriteriaUnique = () => {
5
+ return {
6
+ FailureActionObject: {
7
+ enter(action, { report, location }) {
8
+ const criterias = action.criteria;
9
+ const seen = new Set();
10
+ for (const criteria of criterias) {
11
+ const key = JSON.stringify(criteria);
12
+ if (seen.has(key)) {
13
+ report({
14
+ message: 'The FailureAction criteria items must be unique.',
15
+ location: location.child(['criteria', criterias.indexOf(criteria)]),
16
+ });
17
+ }
18
+ else {
19
+ seen.add(key);
20
+ }
21
+ }
22
+ },
23
+ },
24
+ SuccessActionObject: {
25
+ enter(action, { report, location }) {
26
+ const criterias = action.criteria;
27
+ const seen = new Set();
28
+ for (const criteria of criterias) {
29
+ const key = JSON.stringify(criteria);
30
+ if (seen.has(key)) {
31
+ report({
32
+ message: 'The SuccessAction criteria items must be unique.',
33
+ location: location.child(['criteria', criterias.indexOf(criteria)]),
34
+ });
35
+ }
36
+ else {
37
+ seen.add(key);
38
+ }
39
+ }
40
+ },
41
+ },
42
+ Step: {
43
+ enter(step, { report, location }) {
44
+ if (!step.successCriteria) {
45
+ return;
46
+ }
47
+ const successCriterias = step.successCriteria;
48
+ const seen = new Set();
49
+ for (const criteria of successCriterias) {
50
+ const key = JSON.stringify(criteria);
51
+ if (seen.has(key)) {
52
+ report({
53
+ message: 'The Step SuccessCriteria items must be unique.',
54
+ location: location.child(['successCriteria', successCriterias.indexOf(criteria)]),
55
+ });
56
+ }
57
+ else {
58
+ seen.add(key);
59
+ }
60
+ }
61
+ },
62
+ },
63
+ };
64
+ };
65
+ exports.CriteriaUnique = CriteriaUnique;
@@ -14,6 +14,9 @@ const parameters_unique_1 = require("./parameters-unique");
14
14
  const step_onSuccess_unique_1 = require("./step-onSuccess-unique");
15
15
  const step_onFailure_unique_1 = require("./step-onFailure-unique");
16
16
  const requestBody_replacements_unique_1 = require("./requestBody-replacements-unique");
17
+ const no_criteria_xpath_1 = require("../spot/no-criteria-xpath");
18
+ const no_actions_type_end_1 = require("../spot/no-actions-type-end");
19
+ const criteria_unique_1 = require("./criteria-unique");
17
20
  exports.rules = {
18
21
  spec: spec_1.Spec,
19
22
  assertions: assertions_1.Assertions,
@@ -28,5 +31,8 @@ exports.rules = {
28
31
  'step-onSuccess-unique': step_onSuccess_unique_1.StepOnSuccessUnique,
29
32
  'step-onFailure-unique': step_onFailure_unique_1.StepOnFailureUnique,
30
33
  'requestBody-replacements-unique': requestBody_replacements_unique_1.RequestBodyReplacementsUnique,
34
+ 'no-criteria-xpath': no_criteria_xpath_1.NoCriteriaXpath,
35
+ 'no-actions-type-end': no_actions_type_end_1.NoActionsTypeEnd,
36
+ 'criteria-unique': criteria_unique_1.CriteriaUnique,
31
37
  };
32
38
  exports.preprocessors = {};
@@ -0,0 +1,2 @@
1
+ import type { ArazzoRule } from '../../visitors';
2
+ export declare const NoActionsTypeEnd: ArazzoRule;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NoActionsTypeEnd = void 0;
4
+ const NoActionsTypeEnd = () => {
5
+ return {
6
+ FailureActionObject: {
7
+ enter(action, { report, location }) {
8
+ if (action.type === 'end') {
9
+ report({
10
+ message: 'The `end` type action is not supported by Spot.',
11
+ location: location.child(['type']),
12
+ });
13
+ }
14
+ },
15
+ },
16
+ SuccessActionObject: {
17
+ enter(action, { report, location }) {
18
+ if (action.type === 'end') {
19
+ report({
20
+ message: 'The `end` type action is not supported by Spot.',
21
+ location: location.child(['type']),
22
+ });
23
+ }
24
+ },
25
+ },
26
+ };
27
+ };
28
+ exports.NoActionsTypeEnd = NoActionsTypeEnd;
@@ -0,0 +1,2 @@
1
+ import type { ArazzoRule } from '../../visitors';
2
+ export declare const NoCriteriaXpath: ArazzoRule;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NoCriteriaXpath = void 0;
4
+ const NoCriteriaXpath = () => {
5
+ return {
6
+ CriterionObject: {
7
+ enter(criteria, { report, location }) {
8
+ if (!criteria.type) {
9
+ return;
10
+ }
11
+ if (criteria?.type?.type === 'xpath' || criteria?.type === 'xpath') {
12
+ report({
13
+ message: 'The `xpath` type criteria is not supported by Spot.',
14
+ location: location.child(['type']),
15
+ });
16
+ }
17
+ },
18
+ },
19
+ };
20
+ };
21
+ exports.NoCriteriaXpath = NoCriteriaXpath;
@@ -212,7 +212,7 @@ const CriterionObject = {
212
212
  else if (typeof value === 'string') {
213
213
  return { enum: ['regex', 'jsonpath', 'simple', 'xpath'] };
214
214
  }
215
- else if (value.type === 'jsonpath') {
215
+ else if (value?.type === 'jsonpath') {
216
216
  return 'JSONPathCriterion';
217
217
  }
218
218
  else {
@@ -11,7 +11,7 @@ declare const builtInAsync2Rules: readonly ["spec", "info-contact", "info-licens
11
11
  declare const builtInAsync3Rules: readonly ["spec", "info-contact", "info-license-strict", "operation-operationId", "tag-description", "tags-alphabetical", "channels-kebab-case", "no-channel-trailing-slash"];
12
12
  export type BuiltInAsync2RuleId = typeof builtInAsync2Rules[number];
13
13
  export type BuiltInAsync3RuleId = typeof builtInAsync3Rules[number];
14
- declare const builtInArazzoRules: readonly ["spec", "parameters-not-in-body", "sourceDescription-type", "version-enum", "workflowId-unique", "stepId-unique", "sourceDescription-name-unique", "workflow-dependsOn", "parameters-unique", "step-onSuccess-unique", "step-onFailure-unique", "requestBody-replacements-unique"];
14
+ declare const builtInArazzoRules: readonly ["spec", "parameters-not-in-body", "sourceDescription-type", "version-enum", "workflowId-unique", "stepId-unique", "sourceDescription-name-unique", "workflow-dependsOn", "parameters-unique", "step-onSuccess-unique", "step-onFailure-unique", "requestBody-replacements-unique", "no-criteria-xpath", "no-actions-type-end", "criteria-unique"];
15
15
  export type BuiltInArazzoRuleId = typeof builtInArazzoRules[number];
16
16
  declare const oas2NodeTypesList: readonly ["Root", "Tag", "TagList", "ExternalDocs", "SecurityRequirement", "SecurityRequirementList", "Info", "Contact", "License", "Paths", "PathItem", "Parameter", "ParameterList", "ParameterItems", "Operation", "Example", "ExamplesMap", "Examples", "Header", "Responses", "Response", "Schema", "Xml", "SchemaProperties", "NamedSchemas", "NamedResponses", "NamedParameters", "NamedSecuritySchemes", "SecurityScheme", "TagGroup", "TagGroups", "EnumDescriptions", "Logo", "XCodeSample", "XCodeSampleList", "XServer", "XServerList"];
17
17
  export type Oas2NodeType = typeof oas2NodeTypesList[number];
@@ -106,6 +106,9 @@ const builtInArazzoRules = [
106
106
  'step-onSuccess-unique',
107
107
  'step-onFailure-unique',
108
108
  'requestBody-replacements-unique',
109
+ 'no-criteria-xpath',
110
+ 'no-actions-type-end',
111
+ 'criteria-unique',
109
112
  ];
110
113
  const builtInRules = [
111
114
  ...builtInCommonOASRules,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/openapi-core",
3
- "version": "1.23.1",
3
+ "version": "1.24.0",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "engines": {
@@ -35,7 +35,7 @@
35
35
  "Roman Hotsiy <roman@redoc.ly> (https://redoc.ly/)"
36
36
  ],
37
37
  "dependencies": {
38
- "@redocly/ajv": "^8.11.0",
38
+ "@redocly/ajv": "^8.11.2",
39
39
  "@redocly/config": "^0.10.1",
40
40
  "colorette": "^1.2.0",
41
41
  "https-proxy-agent": "^7.0.4",
@@ -5,6 +5,9 @@ exports[`resolveConfig should ignore minimal from the root and read local file 1
5
5
  "arazzoDecorators": {},
6
6
  "arazzoPreprocessors": {},
7
7
  "arazzoRules": {
8
+ "criteria-unique": "warn",
9
+ "no-actions-type-end": "warn",
10
+ "no-criteria-xpath": "warn",
8
11
  "parameters-not-in-body": "warn",
9
12
  "parameters-unique": "error",
10
13
  "requestBody-replacements-unique": "warn",
@@ -147,6 +150,9 @@ exports[`resolveStyleguideConfig should resolve extends with local file config w
147
150
  "arazzoDecorators": {},
148
151
  "arazzoPreprocessors": {},
149
152
  "arazzoRules": {
153
+ "criteria-unique": "warn",
154
+ "no-actions-type-end": "warn",
155
+ "no-criteria-xpath": "warn",
150
156
  "parameters-not-in-body": "warn",
151
157
  "parameters-unique": "error",
152
158
  "requestBody-replacements-unique": "warn",
package/src/config/all.ts CHANGED
@@ -139,6 +139,9 @@ const all: PluginStyleguideConfig<'built-in'> = {
139
139
  'step-onSuccess-unique': 'error',
140
140
  'step-onFailure-unique': 'error',
141
141
  'requestBody-replacements-unique': 'error',
142
+ 'no-criteria-xpath': 'error',
143
+ 'no-actions-type-end': 'error',
144
+ 'criteria-unique': 'error',
142
145
  },
143
146
  };
144
147
 
@@ -73,7 +73,10 @@ export class StyleguideConfig {
73
73
  [SpecVersion.OAS3_1]: { ...rawConfig.rules, ...rawConfig.oas3_1Rules },
74
74
  [SpecVersion.Async2]: { ...rawConfig.rules, ...rawConfig.async2Rules },
75
75
  [SpecVersion.Async3]: { ...rawConfig.rules, ...rawConfig.async3Rules },
76
- [SpecVersion.Arazzo]: { ...rawConfig.arazzoRules },
76
+ [SpecVersion.Arazzo]: {
77
+ ...rawConfig.arazzoRules,
78
+ ...(rawConfig.rules?.assertions ? { assertions: rawConfig.rules.assertions } : {}),
79
+ },
77
80
  };
78
81
 
79
82
  this.preprocessors = {
@@ -121,6 +121,9 @@ const minimal: PluginStyleguideConfig<'built-in'> = {
121
121
  'step-onSuccess-unique': 'off',
122
122
  'step-onFailure-unique': 'off',
123
123
  'requestBody-replacements-unique': 'off',
124
+ 'no-criteria-xpath': 'off',
125
+ 'no-actions-type-end': 'off',
126
+ 'criteria-unique': 'off',
124
127
  },
125
128
  };
126
129
 
@@ -121,6 +121,9 @@ const recommendedStrict: PluginStyleguideConfig<'built-in'> = {
121
121
  'step-onSuccess-unique': 'error',
122
122
  'step-onFailure-unique': 'error',
123
123
  'requestBody-replacements-unique': 'error',
124
+ 'no-criteria-xpath': 'error',
125
+ 'no-actions-type-end': 'error',
126
+ 'criteria-unique': 'error',
124
127
  },
125
128
  };
126
129
 
@@ -121,6 +121,9 @@ const recommended: PluginStyleguideConfig<'built-in'> = {
121
121
  'step-onSuccess-unique': 'warn',
122
122
  'step-onFailure-unique': 'warn',
123
123
  'requestBody-replacements-unique': 'warn',
124
+ 'no-criteria-xpath': 'warn',
125
+ 'no-actions-type-end': 'warn',
126
+ 'criteria-unique': 'warn',
124
127
  },
125
128
  };
126
129
 
@@ -0,0 +1,161 @@
1
+ import { outdent } from 'outdent';
2
+ import { lintDocument } from '../../../lint';
3
+ import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../../__tests__/utils';
4
+ import { BaseResolver } from '../../../resolve';
5
+
6
+ describe('Arazzo criteria-unique', () => {
7
+ const document = parseYamlToDocument(
8
+ outdent`
9
+ arazzo: '1.0.0'
10
+ info:
11
+ title: Cool API
12
+ version: 1.0.0
13
+ description: A cool API
14
+ sourceDescriptions:
15
+ - name: museum-api
16
+ type: openapi
17
+ url: openapi.yaml
18
+ workflows:
19
+ - workflowId: get-museum-hours
20
+ description: This workflow demonstrates how to get the museum opening hours and buy tickets.
21
+ parameters:
22
+ - in: header
23
+ name: Authorization
24
+ value: Basic Og==
25
+ steps:
26
+ - stepId: create-event
27
+ description: >-
28
+ Create a new special event.
29
+ operationPath: $sourceDescriptions.museum-api#/paths/~1special-events/post
30
+ requestBody:
31
+ payload:
32
+ name: 'Mermaid Treasure Identification and Analysis'
33
+ location: 'Under the seaaa 🦀 🎶 🌊.'
34
+ eventDescription: 'Join us as we review and classify a rare collection of 20 thingamabobs, gadgets, gizmos, whoosits, and whatsits, kindly donated by Ariel.'
35
+ dates:
36
+ - '2023-09-05'
37
+ - '2023-09-08'
38
+ price: 0
39
+ successCriteria:
40
+ - condition: $statusCode == 200
41
+ - condition: $statusCode == 200
42
+ - context: $response.body
43
+ condition: $.name == 'Mermaid Treasure Identification and Analysis'
44
+ type: jsonpath
45
+ - context: $response.body
46
+ condition: $.name == 'Mermaid Treasure Identification and Analysis'
47
+ type: jsonpath
48
+ onSuccess:
49
+ - name: 'onSuccessActionName'
50
+ type: 'goto'
51
+ stepId: 'buy-ticket'
52
+ criteria:
53
+ - condition: $response.body.open == true
54
+ - condition: $response.body.open == true
55
+ onFailure:
56
+ - name: 'onFailureActionName'
57
+ type: 'goto'
58
+ stepId: 'buy-ticket'
59
+ criteria:
60
+ - condition: $response.body.open == true
61
+ - condition: $response.body.open == true
62
+ outputs:
63
+ createdEventId: $response.body.eventId
64
+ name: $response.body.name
65
+ - workflowId: get-museum-hours-2
66
+ description: This workflow demonstrates how to get the museum opening hours and buy tickets.
67
+ parameters:
68
+ - in: header
69
+ name: Authorization
70
+ value: Basic Og==
71
+ steps:
72
+ - stepId: get-museum-hours
73
+ description: >-
74
+ Get museum hours by resolving request details with getMuseumHours operationId from openapi.yaml description.
75
+ operationId: museum-api.getMuseumHours
76
+ successCriteria:
77
+ - condition: $statusCode == 200
78
+ `,
79
+ 'arazzo.yaml'
80
+ );
81
+
82
+ it('should report when the duplicated criteria exists', async () => {
83
+ const results = await lintDocument({
84
+ externalRefResolver: new BaseResolver(),
85
+ document,
86
+ config: await makeConfig({
87
+ rules: {},
88
+ arazzoRules: { 'criteria-unique': 'error' },
89
+ }),
90
+ });
91
+
92
+ expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
93
+ [
94
+ {
95
+ "location": [
96
+ {
97
+ "pointer": "#/workflows/0/steps/0/successCriteria/1",
98
+ "reportOnKey": false,
99
+ "source": "arazzo.yaml",
100
+ },
101
+ ],
102
+ "message": "The Step SuccessCriteria items must be unique.",
103
+ "ruleId": "criteria-unique",
104
+ "severity": "error",
105
+ "suggest": [],
106
+ },
107
+ {
108
+ "location": [
109
+ {
110
+ "pointer": "#/workflows/0/steps/0/successCriteria/3",
111
+ "reportOnKey": false,
112
+ "source": "arazzo.yaml",
113
+ },
114
+ ],
115
+ "message": "The Step SuccessCriteria items must be unique.",
116
+ "ruleId": "criteria-unique",
117
+ "severity": "error",
118
+ "suggest": [],
119
+ },
120
+ {
121
+ "location": [
122
+ {
123
+ "pointer": "#/workflows/0/steps/0/onSuccess/0/criteria/1",
124
+ "reportOnKey": false,
125
+ "source": "arazzo.yaml",
126
+ },
127
+ ],
128
+ "message": "The SuccessAction criteria items must be unique.",
129
+ "ruleId": "criteria-unique",
130
+ "severity": "error",
131
+ "suggest": [],
132
+ },
133
+ {
134
+ "location": [
135
+ {
136
+ "pointer": "#/workflows/0/steps/0/onFailure/0/criteria/1",
137
+ "reportOnKey": false,
138
+ "source": "arazzo.yaml",
139
+ },
140
+ ],
141
+ "message": "The FailureAction criteria items must be unique.",
142
+ "ruleId": "criteria-unique",
143
+ "severity": "error",
144
+ "suggest": [],
145
+ },
146
+ ]
147
+ `);
148
+ });
149
+
150
+ it('should not report when the duplicated criteria exists', async () => {
151
+ const results = await lintDocument({
152
+ externalRefResolver: new BaseResolver(),
153
+ document,
154
+ config: await makeConfig({
155
+ rules: {},
156
+ }),
157
+ });
158
+
159
+ expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`);
160
+ });
161
+ });
@@ -0,0 +1,122 @@
1
+ import { outdent } from 'outdent';
2
+ import { lintDocument } from '../../../lint';
3
+ import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../../__tests__/utils';
4
+ import { BaseResolver } from '../../../resolve';
5
+
6
+ describe('Arazzo no-actions-type-end', () => {
7
+ const document = parseYamlToDocument(
8
+ outdent`
9
+ arazzo: '1.0.0'
10
+ info:
11
+ title: Cool API
12
+ version: 1.0.0
13
+ description: A cool API
14
+ sourceDescriptions:
15
+ - name: museum-api
16
+ type: openapi
17
+ url: openapi.yaml
18
+ workflows:
19
+ - workflowId: get-museum-hours
20
+ description: This workflow demonstrates how to get the museum opening hours and buy tickets.
21
+ parameters:
22
+ - in: header
23
+ name: Authorization
24
+ value: Basic Og==
25
+ steps:
26
+ - stepId: create-event
27
+ description: >-
28
+ Create a new special event.
29
+ operationPath: $sourceDescriptions.museum-api#/paths/~1special-events/post
30
+ requestBody:
31
+ payload:
32
+ name: 'Mermaid Treasure Identification and Analysis'
33
+ location: 'Under the seaaa 🦀 🎶 🌊.'
34
+ eventDescription: 'Join us as we review and classify a rare collection of 20 thingamabobs, gadgets, gizmos, whoosits, and whatsits, kindly donated by Ariel.'
35
+ dates:
36
+ - '2023-09-05'
37
+ - '2023-09-08'
38
+ price: 0
39
+ successCriteria:
40
+ - condition: $statusCode == 201
41
+ onSuccess:
42
+ - name: 'onSuccessActionName'
43
+ type: 'end'
44
+ stepId: 'buy-ticket'
45
+ onFailure:
46
+ - name: 'onFailureActionName'
47
+ type: 'end'
48
+ stepId: 'buy-ticket'
49
+ outputs:
50
+ createdEventId: $response.body.eventId
51
+ name: $response.body.name
52
+ - workflowId: get-museum-hours-2
53
+ description: This workflow demonstrates how to get the museum opening hours and buy tickets.
54
+ parameters:
55
+ - in: header
56
+ name: Authorization
57
+ value: Basic Og==
58
+ steps:
59
+ - stepId: get-museum-hours
60
+ description: >-
61
+ Get museum hours by resolving request details with getMuseumHours operationId from openapi.yaml description.
62
+ operationId: museum-api.getMuseumHours
63
+ successCriteria:
64
+ - condition: $statusCode == 200
65
+ `,
66
+ 'arazzo.yaml'
67
+ );
68
+
69
+ it('should report when the type `end` action exists', async () => {
70
+ const results = await lintDocument({
71
+ externalRefResolver: new BaseResolver(),
72
+ document,
73
+ config: await makeConfig({
74
+ rules: {},
75
+ arazzoRules: { 'no-actions-type-end': 'error' },
76
+ }),
77
+ });
78
+
79
+ expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
80
+ [
81
+ {
82
+ "location": [
83
+ {
84
+ "pointer": "#/workflows/0/steps/0/onSuccess/0/type",
85
+ "reportOnKey": false,
86
+ "source": "arazzo.yaml",
87
+ },
88
+ ],
89
+ "message": "The \`end\` type action is not supported by Spot.",
90
+ "ruleId": "no-actions-type-end",
91
+ "severity": "error",
92
+ "suggest": [],
93
+ },
94
+ {
95
+ "location": [
96
+ {
97
+ "pointer": "#/workflows/0/steps/0/onFailure/0/type",
98
+ "reportOnKey": false,
99
+ "source": "arazzo.yaml",
100
+ },
101
+ ],
102
+ "message": "The \`end\` type action is not supported by Spot.",
103
+ "ruleId": "no-actions-type-end",
104
+ "severity": "error",
105
+ "suggest": [],
106
+ },
107
+ ]
108
+ `);
109
+ });
110
+
111
+ it('should not report when the type `end` action exists', async () => {
112
+ const results = await lintDocument({
113
+ externalRefResolver: new BaseResolver(),
114
+ document,
115
+ config: await makeConfig({
116
+ rules: {},
117
+ }),
118
+ });
119
+
120
+ expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`);
121
+ });
122
+ });