From d5a34561b9fc6aededfaa234d8f0db208884a853 Mon Sep 17 00:00:00 2001 From: Mathew Polzin Date: Fri, 31 Jul 2020 17:50:30 -0700 Subject: [PATCH] instead of failing to parse when an operation callback is found, ignore it gracefully (until it is supported by OpenAPIKit in the future) --- Sources/OpenAPIKit/Operation/Operation.swift | 8 +- .../SwaggerDocSamplesTests.swift | 76 +++++++++++++++++++ .../Operation/OperationTests.swift | 24 ++++++ 3 files changed, 106 insertions(+), 2 deletions(-) diff --git a/Sources/OpenAPIKit/Operation/Operation.swift b/Sources/OpenAPIKit/Operation/Operation.swift index 18844ae54..0688d453b 100644 --- a/Sources/OpenAPIKit/Operation/Operation.swift +++ b/Sources/OpenAPIKit/Operation/Operation.swift @@ -259,7 +259,7 @@ extension OpenAPI.Operation { case parameters case requestBody case responses -// case callbacks + case callbacks case deprecated case security case servers @@ -276,7 +276,7 @@ extension OpenAPI.Operation { .parameters, .requestBody, .responses, -// .callbacks, + .callbacks, .deprecated, .security, .servers @@ -305,6 +305,8 @@ extension OpenAPI.Operation { self = .requestBody case "responses": self = .responses + case "callbacks": + self = .callbacks case "deprecated": self = .deprecated case "security": @@ -334,6 +336,8 @@ extension OpenAPI.Operation { return "requestBody" case .responses: return "responses" + case .callbacks: + return "callbacks" case .deprecated: return "deprecated" case .security: diff --git a/Tests/OpenAPIKitCompatibilitySuite/SwaggerDocSamplesTests.swift b/Tests/OpenAPIKitCompatibilitySuite/SwaggerDocSamplesTests.swift index e7a7e2a69..bbaca1a5a 100644 --- a/Tests/OpenAPIKitCompatibilitySuite/SwaggerDocSamplesTests.swift +++ b/Tests/OpenAPIKitCompatibilitySuite/SwaggerDocSamplesTests.swift @@ -318,6 +318,82 @@ components: throw friendlyError } } + + func test_callbackExample() throws { + let docString = commonBaseDocument + """ +paths: + /streams: + post: + description: subscribes a client to receive out-of-band data + parameters: + - name: callbackUrl + in: query + required: true + description: | + the location where data will be sent. Must be network accessible + by the source server + schema: + type: string + format: uri + example: https://tonys-server.com + responses: + '201': + description: subscription successfully created + content: + application/json: + schema: + description: subscription information + required: + - subscriptionId + properties: + subscriptionId: + description: this unique identifier allows management of the subscription + type: string + example: 2531329f-fb09-4ef7-887e-84e648214436 + callbacks: + # the name `onData` is a convenience locator + onData: + # when data is sent, it will be sent to the `callbackUrl` provided + # when making the subscription PLUS the suffix `/data` + '{$request.query.callbackUrl}/data': + post: + requestBody: + description: subscription payload + content: + application/json: + schema: + type: object + properties: + timestamp: + type: string + format: date-time + userData: + type: string + responses: + '202': + description: | + Your server implementation should return this HTTP status code + if the data was received successfully + '204': + description: | + Your server should return this HTTP status code if no longer interested + in further updates +""" + + // test decoding + do { + let doc = try YAMLDecoder().decode(OpenAPI.Document.self, from: docString) + + // test validating + try doc.validate() + + // test dereferencing and resolving + _ = try doc.locallyDereferenced().resolved() + } catch let error { + let friendlyError = OpenAPI.Error(from: error) + throw friendlyError + } + } } fileprivate let commonBaseDocument = """ diff --git a/Tests/OpenAPIKitTests/Operation/OperationTests.swift b/Tests/OpenAPIKitTests/Operation/OperationTests.swift index ef4967eb4..d33d8d006 100644 --- a/Tests/OpenAPIKitTests/Operation/OperationTests.swift +++ b/Tests/OpenAPIKitTests/Operation/OperationTests.swift @@ -250,6 +250,30 @@ extension OperationTests { XCTAssertEqual(operation.responses[200]?.reference, .component(named: "test")) } + func test_doesNotFailDecodingCallbacks() { + let operationData = +""" +{ + "responses" : {}, + "callbacks" : { + "callback" : { + "{$request.query.queryUrl}" : { + "post" : { + "responses" : { + "200" : { + "description" : "callback successfully processed" + } + } + } + } + } + } +} +""".data(using: .utf8)! + + XCTAssertNoThrow(try orderUnstableDecode(OpenAPI.Operation.self, from: operationData)) + } + // Note that JSONEncoder for Linux Foundation does not respect order func test_responseOrder_encode() throws { let operation = OpenAPI.Operation(