Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions arazzo/arazzo.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,11 @@ func (a *Arazzo) Validate(ctx context.Context, opts ...validation.Option) []erro

arazzoVersion, err := version.Parse(a.Arazzo)
if err != nil {
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("arazzo.version is invalid %s: %s", a.Arazzo, err.Error()), core, core.Arazzo))
errs = append(errs, validation.NewValueError(validation.SeverityError, validation.RuleValidationInvalidFormat, fmt.Errorf("arazzo.version is invalid %s: %w", a.Arazzo, err), core, core.Arazzo))
}
if arazzoVersion != nil {
if arazzoVersion.GreaterThan(*MaximumSupportedVersion) {
errs = append(errs, validation.NewValueError(validation.NewValueValidationError("arazzo.version only Arazzo versions between %s and %s are supported", MinimumSupportedVersion, MaximumSupportedVersion), core, core.Arazzo))
errs = append(errs, validation.NewValueError(validation.SeverityError, validation.RuleValidationSupportedVersion, fmt.Errorf("arazzo.version only Arazzo versions between %s and %s are supported", MinimumSupportedVersion, MaximumSupportedVersion), core, core.Arazzo))
}
}

Expand All @@ -125,7 +125,7 @@ func (a *Arazzo) Validate(ctx context.Context, opts ...validation.Option) []erro
errs = append(errs, sourceDescription.Validate(ctx, opts...)...)

if _, ok := sourceDescriptionNames[sourceDescription.Name]; ok {
errs = append(errs, validation.NewSliceError(validation.NewValueValidationError("sourceDescription.name %s is not unique", sourceDescription.Name), core, core.SourceDescriptions, i))
errs = append(errs, validation.NewSliceError(validation.SeverityError, validation.RuleValidationDuplicateKey, fmt.Errorf("sourceDescription.name %s is not unique", sourceDescription.Name), core, core.SourceDescriptions, i))
}

sourceDescriptionNames[sourceDescription.Name] = true
Expand All @@ -137,7 +137,7 @@ func (a *Arazzo) Validate(ctx context.Context, opts ...validation.Option) []erro
errs = append(errs, workflow.Validate(ctx, opts...)...)

if _, ok := workflowIds[workflow.WorkflowID]; ok {
errs = append(errs, validation.NewSliceError(validation.NewValueValidationError("workflow.workflowId %s is not unique", workflow.WorkflowID), core, core.Workflows, i))
errs = append(errs, validation.NewSliceError(validation.SeverityError, validation.RuleValidationDuplicateKey, fmt.Errorf("workflow.workflowId %s is not unique", workflow.WorkflowID), core, core.Workflows, i))
}

workflowIds[workflow.WorkflowID] = true
Expand Down
4 changes: 2 additions & 2 deletions arazzo/arazzo_examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,6 @@ func Example_validating() {
fmt.Printf("%s\n", err.Error())
}
// Output:
// [3:3] info.version is missing
// [13:9] step at least one of operationId, operationPath or workflowId fields must be set
// [3:3] error validation-required-field info.version is required
// [13:9] error validation-required-field step at least one of operationId, operationPath or workflowId fields must be set
}
40 changes: 20 additions & 20 deletions arazzo/arazzo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,11 +300,11 @@ sourceDescriptions:
column int
underlyingError error
}{
{line: 1, column: 1, underlyingError: validation.NewMissingFieldError("arazzo.workflows is missing")},
{line: 1, column: 9, underlyingError: validation.NewValueValidationError("arazzo.version only Arazzo versions between 1.0.0 and 1.0.1 are supported")},
{line: 4, column: 3, underlyingError: validation.NewMissingFieldError("info.version is missing")},
{line: 6, column: 5, underlyingError: validation.NewMissingFieldError("sourceDescription.url is missing")},
{line: 7, column: 11, underlyingError: validation.NewValueValidationError("sourceDescription.type must be one of [openapi, arazzo]")},
{line: 1, column: 1, underlyingError: errors.New("arazzo.workflows is required")},
{line: 1, column: 9, underlyingError: errors.New("arazzo.version only Arazzo versions between 1.0.0 and 1.0.1 are supported")},
{line: 4, column: 3, underlyingError: errors.New("info.version is required")},
{line: 6, column: 5, underlyingError: errors.New("sourceDescription.url is required")},
{line: 7, column: 11, underlyingError: errors.New("sourceDescription.type must be one of [openapi, arazzo]")},
}

require.Len(t, validationErrs, len(expectedErrors), "number of validation errors should match")
Expand Down Expand Up @@ -546,8 +546,8 @@ var stressTests = []struct {
args: args{
location: "https://raw.githubusercontent.com/Redocly/museum-openapi-example/2770b2b2e59832d245c7b0eb0badf6568d7efb53/arazzo/museum-api.arazzo.yaml",
validationIgnores: []string{
"[71:24] invalid jsonpath expression: Error at line 1, column 7: unexpected token when parsing segment", // legit invalid RFC 9535 syntax
"[107:24] invalid jsonpath expression: Error at line 1, column 7: unexpected token when parsing segment", // legit invalid RFC 9535 syntax
"[71:24] error validation-invalid-syntax invalid jsonpath expression: Error at line 1, column 7: unexpected token when parsing segment", // legit invalid RFC 9535 syntax
"[107:24] error validation-invalid-syntax invalid jsonpath expression: Error at line 1, column 7: unexpected token when parsing segment", // legit invalid RFC 9535 syntax
},
},
wantTitle: "Redocly Museum API Test Workflow",
Expand All @@ -564,7 +564,7 @@ var stressTests = []struct {
args: args{
location: "https://raw.githubusercontent.com/Redocly/warp-single-sidebar/b78fc09da52d7755e92e1bc8f990edd37421cbde/apis/arazzo.yaml",
validationIgnores: []string{
"[63:24] invalid jsonpath expression: Error at line 1, column 12: unexpected token when parsing segment", // legit invalid RFC 9535 syntax
"[63:24] error validation-invalid-syntax invalid jsonpath expression: Error at line 1, column 12: unexpected token when parsing segment", // legit invalid RFC 9535 syntax
},
},
wantTitle: "Warp API",
Expand Down Expand Up @@ -605,10 +605,10 @@ var stressTests = []struct {
args: args{
location: "https://raw.githubusercontent.com/OAI/Arazzo-Specification/23852b8b0d13ab1e3288a57a990611ffed45ab5d/examples/1.0.0/oauth.arazzo.yaml",
validationIgnores: []string{
"[65:24] invalid jsonpath expression: Error at line 1, column 15: unexpected token when parsing segment", // legit invalid RFC 9535 syntax
"[105:24] invalid jsonpath expression: Error at line 1, column 15: unexpected token when parsing segment", // legit invalid RFC 9535 syntax
"[155:24] invalid jsonpath expression: Error at line 1, column 15: unexpected token when parsing segment", // legit invalid RFC 9535 syntax
"[175:24] invalid jsonpath expression: Error at line 1, column 15: unexpected token when parsing segment", // legit invalid RFC 9535 syntax
"[65:24] error validation-invalid-syntax invalid jsonpath expression: Error at line 1, column 15: unexpected token when parsing segment", // legit invalid RFC 9535 syntax
"[105:24] error validation-invalid-syntax invalid jsonpath expression: Error at line 1, column 15: unexpected token when parsing segment", // legit invalid RFC 9535 syntax
"[155:24] error validation-invalid-syntax invalid jsonpath expression: Error at line 1, column 15: unexpected token when parsing segment", // legit invalid RFC 9535 syntax
"[175:24] error validation-invalid-syntax invalid jsonpath expression: Error at line 1, column 15: unexpected token when parsing segment", // legit invalid RFC 9535 syntax
},
},
wantTitle: "Example OAuth service",
Expand All @@ -632,7 +632,7 @@ var stressTests = []struct {
args: args{
location: "https://raw.githubusercontent.com/frankkilcommins/simple-spectral-arazzo-GA/4ec8856f1cf21c0f77597c715c150ef3e2772a89/apis/OnlineStore.arazzo.yaml",
validationIgnores: []string{
"info.title is missing", // legit issue
"info.title is required", // legit issue
"operationId must be a valid expression if there are multiple OpenAPI source descriptions", // legit issue
"$responses.body.menuItems[0].subcategories[0].id", // legit issue
},
Expand All @@ -645,9 +645,9 @@ var stressTests = []struct {
args: args{
location: "https://raw.githubusercontent.com/leidenheit/itarazzo-library/3b335e1c4293444add52b5f2476420e2d871b1a5/src/test/resources/test.arazzo.yaml",
validationIgnores: []string{
"expression is not valid, must begin with $: <root><id>4711</id><name>Chocolate</name></root>", // legit issue
"[32:24] invalid jsonpath expression: Error at line 1, column 0: unexpected token", // unsupported version: draft-goessner-dispatch-jsonpath-00
"[36:24] invalid jsonpath expression: Error at line 1, column 5: unexpected token when parsing segment", // unsupported version: draft-goessner-dispatch-jsonpath-00
"expression is not valid, must begin with $: <root><id>4711</id><name>Chocolate</name></root>", // legit issue
"[32:24] error validation-invalid-syntax invalid jsonpath expression: Error at line 1, column 0: unexpected token", // unsupported version: draft-goessner-dispatch-jsonpath-00
"[36:24] error validation-invalid-syntax invalid jsonpath expression: Error at line 1, column 5: unexpected token when parsing segment", // unsupported version: draft-goessner-dispatch-jsonpath-00
},
},
wantTitle: "A cookie eating workflow",
Expand All @@ -659,9 +659,9 @@ var stressTests = []struct {
validationIgnores: []string{
"jsonpointer must start with /: $.status", // legit issues TODO: improve the error returned as it is wrong
"jsonpointer must start with /: $.id", // legit issues TODO: improve the error returned as it is wrong
"[81:24] invalid jsonpath expression: Error at line 1, column 7: unexpected token when parsing segment", // unsupported version: draft-goessner-dispatch-jsonpath-00
"[110:24] invalid jsonpath expression: Error at line 1, column 5: unexpected token when parsing segment", // unsupported version: draft-goessner-dispatch-jsonpath-00
"[114:24] invalid jsonpath expression: Error at line 1, column 9: unexpected token when parsing segment", // unsupported version: draft-goessner-dispatch-jsonpath-00
"[81:24] error validation-invalid-syntax invalid jsonpath expression: Error at line 1, column 7: unexpected token when parsing segment", // unsupported version: draft-goessner-dispatch-jsonpath-00
"[110:24] error validation-invalid-syntax invalid jsonpath expression: Error at line 1, column 5: unexpected token when parsing segment", // unsupported version: draft-goessner-dispatch-jsonpath-00
"[114:24] error validation-invalid-syntax invalid jsonpath expression: Error at line 1, column 9: unexpected token when parsing segment", // unsupported version: draft-goessner-dispatch-jsonpath-00
},
},
wantTitle: "PetStore - Example of Workflows",
Expand All @@ -671,7 +671,7 @@ var stressTests = []struct {
args: args{
location: "https://raw.githubusercontent.com/ritza-co/e2e-testing-arazzo/c0615c3708a1e4c0fcaeb79edae78ddc4eb5ba82/arazzo.yaml",
validationIgnores: []string{
"[42:24] invalid jsonpath expression: Error at line 1, column 8: unexpected token", // legit invalid RFC 9535 syntax
"[42:24] error validation-invalid-syntax invalid jsonpath expression: Error at line 1, column 8: unexpected token", // legit invalid RFC 9535 syntax
},
},
wantTitle: "Build-a-Bot Workflow",
Expand Down
9 changes: 5 additions & 4 deletions arazzo/components.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package arazzo

import (
"context"
"fmt"
"regexp"

"github.com/speakeasy-api/openapi/arazzo/core"
Expand Down Expand Up @@ -44,15 +45,15 @@ func (c *Components) Validate(ctx context.Context, opts ...validation.Option) []

for key, input := range c.Inputs.All() {
if !componentNameRegex.MatchString(key) {
errs = append(errs, validation.NewMapKeyError(validation.NewValueValidationError("components.inputs key must be a valid key [%s]: %s", componentNameRegex.String(), key), core, core.Inputs, key))
errs = append(errs, validation.NewMapKeyError(validation.SeverityError, validation.RuleValidationInvalidFormat, fmt.Errorf("components.inputs key must be a valid key [%s]: %s", componentNameRegex.String(), key), core, core.Inputs, key))
}

errs = append(errs, input.Validate(ctx, opts...)...)
}

for key, parameter := range c.Parameters.All() {
if !componentNameRegex.MatchString(key) {
errs = append(errs, validation.NewMapKeyError(validation.NewValueValidationError("components.parameters key must be a valid key [%s]: %s", componentNameRegex.String(), key), core, core.Parameters, key))
errs = append(errs, validation.NewMapKeyError(validation.SeverityError, validation.RuleValidationInvalidFormat, fmt.Errorf("components.parameters key must be a valid key [%s]: %s", componentNameRegex.String(), key), core, core.Parameters, key))
}

paramOps := opts
Expand All @@ -63,7 +64,7 @@ func (c *Components) Validate(ctx context.Context, opts ...validation.Option) []

for key, successAction := range c.SuccessActions.All() {
if !componentNameRegex.MatchString(key) {
errs = append(errs, validation.NewMapKeyError(validation.NewValueValidationError("components.successActions key must be a valid key [%s]: %s", componentNameRegex.String(), key), core, core.SuccessActions, key))
errs = append(errs, validation.NewMapKeyError(validation.SeverityError, validation.RuleValidationInvalidFormat, fmt.Errorf("components.successActions key must be a valid key [%s]: %s", componentNameRegex.String(), key), core, core.SuccessActions, key))
}

successActionOps := opts
Expand All @@ -74,7 +75,7 @@ func (c *Components) Validate(ctx context.Context, opts ...validation.Option) []

for key, failureAction := range c.FailureActions.All() {
if !componentNameRegex.MatchString(key) {
errs = append(errs, validation.NewMapKeyError(validation.NewValueValidationError("components.failureActions key must be a valid key [%s]: %s", componentNameRegex.String(), key), core, core.FailureActions, key))
errs = append(errs, validation.NewMapKeyError(validation.SeverityError, validation.RuleValidationInvalidFormat, fmt.Errorf("components.failureActions key must be a valid key [%s]: %s", componentNameRegex.String(), key), core, core.FailureActions, key))
}

failureActionOps := opts
Expand Down
2 changes: 1 addition & 1 deletion arazzo/core/criterion.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func (c *CriterionTypeUnion) Unmarshal(ctx context.Context, parentName string, n
c.DetermineValidity(validationErrs)
default:
return []error{
validation.NewValidationError(validation.NewTypeMismatchError(parentName, "criterionTypeUnion expected string or object, got %s", yml.NodeKindToString(resolvedNode.Kind)), resolvedNode),
validation.NewValidationError(validation.SeverityError, validation.RuleValidationTypeMismatch, validation.NewTypeMismatchError(parentName, "criterionTypeUnion expected string or object, got %s", yml.NodeKindToString(resolvedNode.Kind)), resolvedNode),
}, nil
}

Expand Down
4 changes: 1 addition & 3 deletions arazzo/core/reusable.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,8 @@ func (r *Reusable[T]) Unmarshal(ctx context.Context, parentName string, node *ya
if resolvedNode.Kind != yaml.MappingNode {
r.SetValid(false, false)

r.SetValid(false, false)

return []error{
validation.NewValidationError(validation.NewTypeMismatchError(parentName, "reusable expected object, got %s", yml.NodeKindToString(resolvedNode.Kind)), resolvedNode),
validation.NewValidationError(validation.SeverityError, validation.RuleValidationTypeMismatch, validation.NewTypeMismatchError(parentName, "reusable expected object, got %s", yml.NodeKindToString(resolvedNode.Kind)), resolvedNode),
}, nil
}

Expand Down
9 changes: 5 additions & 4 deletions arazzo/criterion/condition.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package criterion

import (
"errors"
"fmt"
"strings"

"github.com/speakeasy-api/openapi/expression"
Expand Down Expand Up @@ -81,21 +82,21 @@ func (s *Condition) Validate(valueNode *yaml.Node, opts ...validation.Option) []
errs := []error{}

if s.Expression == "" {
errs = append(errs, validation.NewValidationError(validation.NewMissingValueError("expression is required"), valueNode))
errs = append(errs, validation.NewValidationError(validation.SeverityError, validation.RuleValidationRequiredField, errors.New("expression is required"), valueNode))
}

if err := s.Expression.Validate(); err != nil {
errs = append(errs, validation.NewValidationError(validation.NewValueValidationError(err.Error()), valueNode))
errs = append(errs, validation.NewValidationError(validation.SeverityError, validation.RuleValidationInvalidSyntax, fmt.Errorf("%s", err.Error()), valueNode))
}

switch s.Operator {
case OperatorLT, OperatorLTE, OperatorGT, OperatorGTE, OperatorEQ, OperatorNE, OperatorNot, OperatorAnd, OperatorOr:
default:
errs = append(errs, validation.NewValidationError(validation.NewValueValidationError("operator must be one of [%s]", strings.Join([]string{string(OperatorLT), string(OperatorLTE), string(OperatorGT), string(OperatorGTE), string(OperatorEQ), string(OperatorNE), string(OperatorNot), string(OperatorAnd), string(OperatorOr)}, ", ")), valueNode))
errs = append(errs, validation.NewValidationError(validation.SeverityError, validation.RuleValidationAllowedValues, fmt.Errorf("operator must be one of [%s]", strings.Join([]string{string(OperatorLT), string(OperatorLTE), string(OperatorGT), string(OperatorGTE), string(OperatorEQ), string(OperatorNE), string(OperatorNot), string(OperatorAnd), string(OperatorOr)}, ", ")), valueNode))
}

if s.Value == "" {
errs = append(errs, validation.NewValidationError(validation.NewMissingValueError("value is required"), valueNode))
errs = append(errs, validation.NewValidationError(validation.SeverityError, validation.RuleValidationRequiredField, errors.New("value is required"), valueNode))
}

return errs
Expand Down
Loading
Loading