Commit 7ba56ef2 authored by Mikołaj Wawrzyniak's avatar Mikołaj Wawrzyniak

Merge branch 'pl-json-schema-matcher' into 'master'

Improve schema matcher to display errors

See merge request gitlab-org/gitlab!79839
parents c1b01902 c55a8a53
{ {
"type": "object", "type": "object",
"properties" : { "properties" : {
"properties" : { "id": { "type": "integer" },
"id": { "type": "integer" }, "iid": { "type": "integer" },
"iid": { "type": "integer" }, "project_id": { "type": "integer" },
"project_id": { "type": "integer" }, "title": { "type": "string" },
"title": { "type": "string" }, "description": { "type": ["string", "null"] },
"description": { "type": ["string", "null"] }, "state": { "type": "string" },
"state": { "type": "string" }, "merged_by": {
"merged_by": { "type": ["object", "null"],
"type": ["object", "null"], "properties": {
"properties": { "name": { "type": "string" },
"name": { "type": "string" }, "username": { "type": "string" },
"username": { "type": "string" }, "id": { "type": "integer" },
"id": { "type": "integer" }, "state": { "type": "string" },
"state": { "type": "string" }, "avatar_url": { "type": "uri" },
"avatar_url": { "type": "uri" }, "web_url": { "type": "uri" }
"web_url": { "type": "uri" }
},
"additionalProperties": false
}, },
"merge_user": { "additionalProperties": false
"type": ["object", "null"], },
"properties": { "merge_user": {
"name": { "type": "string" }, "type": ["object", "null"],
"username": { "type": "string" }, "properties": {
"id": { "type": "integer" }, "name": { "type": "string" },
"state": { "type": "string" }, "username": { "type": "string" },
"avatar_url": { "type": "uri" }, "id": { "type": "integer" },
"web_url": { "type": "uri" } "state": { "type": "string" },
}, "avatar_url": { "type": "uri" },
"additionalProperties": false "web_url": { "type": "uri" }
},
"merged_at": { "type": ["string", "null"] },
"closed_by": {
"type": ["object", "null"],
"properties": {
"name": { "type": "string" },
"username": { "type": "string" },
"id": { "type": "integer" },
"state": { "type": "string" },
"avatar_url": { "type": "uri" },
"web_url": { "type": "uri" }
},
"additionalProperties": false
},
"closed_at": { "type": ["string", "null"], "format": "date-time" },
"created_at": { "type": "string", "format": "date-time" },
"updated_at": { "type": "string", "format": "date-time" },
"target_branch": { "type": "string" },
"source_branch": { "type": "string" },
"upvotes": { "type": "integer" },
"downvotes": { "type": "integer" },
"author": {
"type": "object",
"properties": {
"name": { "type": "string" },
"username": { "type": "string" },
"id": { "type": "integer" },
"state": { "type": "string" },
"avatar_url": { "type": "uri" },
"web_url": { "type": "uri" }
},
"additionalProperties": false
},
"assignee": {
"type": ["object", "null"],
"properties": {
"name": { "type": "string" },
"username": { "type": "string" },
"id": { "type": "integer" },
"state": { "type": "string" },
"avatar_url": { "type": "uri" },
"web_url": { "type": "uri" }
},
"additionalProperties": false
},
"assignees": {
"items": {
"$ref": "./merge_request.json"
}
}, },
"source_project_id": { "type": "integer" }, "additionalProperties": false
"target_project_id": { "type": "integer" }, },
"labels": { "merged_at": { "type": ["string", "null"] },
"type": "array", "closed_by": {
"items": { "type": ["object", "null"],
"type": "string" "properties": {
} "name": { "type": "string" },
"username": { "type": "string" },
"id": { "type": "integer" },
"state": { "type": "string" },
"avatar_url": { "type": "uri" },
"web_url": { "type": "uri" }
}, },
"work_in_progress": { "type": "boolean" }, "additionalProperties": false
"milestone": { },
"type": ["object", "null"], "closed_at": { "type": ["string", "null"], "format": "date-time" },
"properties": { "created_at": { "type": "string", "format": "date-time" },
"id": { "type": "integer" }, "updated_at": { "type": "string", "format": "date-time" },
"iid": { "type": "integer" }, "target_branch": { "type": "string" },
"project_id": { "type": ["integer", "null"] }, "source_branch": { "type": "string" },
"group_id": { "type": ["integer", "null"] }, "upvotes": { "type": "integer" },
"title": { "type": "string" }, "downvotes": { "type": "integer" },
"description": { "type": ["string", "null"] }, "author": {
"state": { "type": "string" }, "type": "object",
"created_at": { "type": "string", "format": "date-time" }, "properties": {
"updated_at": { "type": "string", "format": "date-time" }, "name": { "type": "string" },
"due_date": { "type": "string", "format": "date-time" }, "username": { "type": "string" },
"start_date": { "type": "string", "format": "date-time" } "id": { "type": "integer" },
}, "state": { "type": "string" },
"additionalProperties": false "avatar_url": { "type": "uri" },
"web_url": { "type": "uri" }
}, },
"merge_when_pipeline_succeeds": { "type": "boolean" }, "additionalProperties": false
"merge_status": { "type": "string" }, },
"sha": { "type": "string" }, "assignee": {
"merge_commit_sha": { "type": ["string", "null"] }, "type": ["object", "null"],
"user_notes_count": { "type": "integer" }, "properties": {
"changes_count": { "type": "string" }, "name": { "type": "string" },
"should_remove_source_branch": { "type": ["boolean", "null"] }, "username": { "type": "string" },
"force_remove_source_branch": { "type": ["boolean", "null"] }, "id": { "type": "integer" },
"discussion_locked": { "type": ["boolean", "null"] }, "state": { "type": "string" },
"web_url": { "type": "uri" }, "avatar_url": { "type": "uri" },
"squash": { "type": "boolean" }, "web_url": { "type": "uri" }
"time_stats": {
"time_estimate": { "type": "integer" },
"total_time_spent": { "type": "integer" },
"human_time_estimate": { "type": ["string", "null"] },
"human_total_time_spent": { "type": ["string", "null"] }
}, },
"allow_collaboration": { "type": ["boolean", "null"] }, "additionalProperties": false
"allow_maintainer_to_push": { "type": ["boolean", "null"] }, },
"references": { "assignees": {
"short": {"type": "string"}, "type": "array",
"relative": {"type": "string"}, "items": {
"full": {"type": "string"} "$ref": "user/basic.json"
}
},
"source_project_id": { "type": "integer" },
"target_project_id": { "type": "integer" },
"labels": {
"type": "array",
"items": {
"type": "string"
} }
}, },
"required": [ "work_in_progress": { "type": "boolean" },
"id", "iid", "project_id", "title", "description", "milestone": {
"state", "created_at", "updated_at", "target_branch",
"source_branch", "upvotes", "downvotes", "author",
"assignee", "source_project_id", "target_project_id",
"labels", "work_in_progress", "milestone", "merge_when_pipeline_succeeds",
"merge_status", "sha", "merge_commit_sha", "user_notes_count",
"should_remove_source_branch", "force_remove_source_branch",
"web_url", "squash"
],
"head_pipeline": {
"oneOf": [ "oneOf": [
{ "type": "null" }, { "type": "null" },
{ "$ref": "pipeline/detail.json" } { "$ref": "milestone.json" }
] ]
},
"merge_when_pipeline_succeeds": { "type": "boolean" },
"merge_status": { "type": "string" },
"sha": { "type": "string" },
"merge_commit_sha": { "type": ["string", "null"] },
"user_notes_count": { "type": "integer" },
"changes_count": { "type": "string" },
"should_remove_source_branch": { "type": ["boolean", "null"] },
"force_remove_source_branch": { "type": ["boolean", "null"] },
"discussion_locked": { "type": ["boolean", "null"] },
"web_url": { "type": "uri" },
"squash": { "type": "boolean" },
"time_stats": {
"time_estimate": { "type": "integer" },
"total_time_spent": { "type": "integer" },
"human_time_estimate": { "type": ["string", "null"] },
"human_total_time_spent": { "type": ["string", "null"] }
},
"allow_collaboration": { "type": ["boolean", "null"] },
"allow_maintainer_to_push": { "type": ["boolean", "null"] },
"references": {
"short": {"type": "string"},
"relative": {"type": "string"},
"full": {"type": "string"}
} }
},
"required": [
"id", "iid", "project_id", "title", "description",
"state", "created_at", "updated_at", "target_branch",
"source_branch", "upvotes", "downvotes", "author",
"assignee", "source_project_id", "target_project_id",
"labels", "work_in_progress", "milestone", "merge_when_pipeline_succeeds",
"merge_status", "sha", "merge_commit_sha", "user_notes_count",
"should_remove_source_branch", "force_remove_source_branch",
"web_url", "squash"
],
"head_pipeline": {
"oneOf": [
{ "type": "null" },
{ "$ref": "pipeline/detail.json" }
]
} }
} }
...@@ -36,12 +36,38 @@ end ...@@ -36,12 +36,38 @@ end
RSpec::Matchers.define :match_response_schema do |schema, dir: nil, **options| RSpec::Matchers.define :match_response_schema do |schema, dir: nil, **options|
match do |response| match do |response|
schema_path = Pathname.new(SchemaPath.expand(schema, dir)) @schema_path = Pathname.new(SchemaPath.expand(schema, dir))
validator = SchemaPath.validator(schema_path) validator = SchemaPath.validator(@schema_path)
data = Gitlab::Json.parse(response.body) @data = Gitlab::Json.parse(response.body)
validator.valid?(data) @schema_errors = validator.validate(@data)
@schema_errors.none?
end
failure_message do |actual|
message = []
message << <<~MESSAGE
expected JSON response to match schema #{@schema_path.inspect}.
JSON input: #{Gitlab::Json.pretty_generate(@data).indent(2)}
Schema errors:
MESSAGE
@schema_errors.each do |error|
property_name, actual_value = error.values_at('data_pointer', 'data')
property_name = 'root' if property_name.empty?
message << <<~MESSAGE
Property: #{property_name}
Actual value: #{Gitlab::Json.pretty_generate(actual_value).indent(2)}
Error: #{JSONSchemer::Errors.pretty(error)}
MESSAGE
end
message.join("\n")
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment