Skip to content

Commit

Permalink
Merge pull request #314 from nexon/bugfix/294-dereferencing-callbacks
Browse files Browse the repository at this point in the history
Bugfix/294 dereferencing callbacks
  • Loading branch information
mattpolzin authored Sep 12, 2023
2 parents 96eee1d + f9a8e8d commit beca680
Show file tree
Hide file tree
Showing 8 changed files with 193 additions and 0 deletions.
17 changes: 17 additions & 0 deletions Sources/OpenAPIKit/Callbacks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,21 @@ extension OpenAPI {

/// A map of named collections of Callback Objects (`OpenAPI.Callbacks`).
public typealias CallbacksMap = OrderedDictionary<String, Either<OpenAPI.Reference<Callbacks>, Callbacks>>

/// A dictionary of Dereferenced of callbacks.
public typealias DereferencedCallbacks = OrderedDictionary<CallbackURL, DereferencedPathItem>

/// A dictionary of Dereferenced map of callbacks.
public typealias DereferencedCallbacksMap = OrderedDictionary<String, DereferencedCallbacks>
}

extension OpenAPI.CallbackURL: LocallyDereferenceable {
public func _dereferenced(
in components: OpenAPI.Components,
following references: Set<AnyHashable>,
dereferencedFromComponentNamed name: String?
) throws -> OpenAPI.CallbackURL {
self
}
}

9 changes: 9 additions & 0 deletions Sources/OpenAPIKit/Operation/DereferencedOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ public struct DereferencedOperation: Equatable {
public let requestBody: DereferencedRequest?
/// A dereferenced map of responses.
public let responses: DereferencedResponse.Map
/// A dereferenced map of callbacks.
public let callbacks: OpenAPI.DereferencedCallbacksMap

/// An array of dereferenced security requirements.
///
/// If defined, overrides the security requirements in the
Expand Down Expand Up @@ -71,6 +74,12 @@ public struct DereferencedOperation: Equatable {
)
}

self.callbacks = try operation.callbacks.mapValues { callback in
try callback._dereferenced(in: components,
following: references,
dereferencedFromComponentNamed: nil)
}

self.underlyingOperation = operation
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// OrderedDictionry+LocallyDereferenceable.swift
//
//
// Created by Alberto Lagos on 11-09-23.
//

import OpenAPIKitCore
import Foundation

/// A Swift extension for dereferencing an `OrderedDictionary` conforming to the `LocallyDereferenceable` protocol.
///
/// - Parameters:
/// - components: The OpenAPI components containing definitions.
/// - references: A set of references to track dereferenced items.
/// - name: The name of the component from which the dereferencing is initiated.
///
/// - Returns: A dereferenced `OrderedDictionary` containing keys and values of dereferenced types.
///
/// - Throws: An error if dereferencing fails for any element.
extension OrderedDictionary: LocallyDereferenceable where Key: LocallyDereferenceable, Key.DereferencedSelf: Hashable, Value: LocallyDereferenceable {

public func _dereferenced(in components: OpenAPI.Components,
following references: Set<AnyHashable>,
dereferencedFromComponentNamed name: String?) throws -> OpenAPIKitCore.OrderedDictionary<Key.DereferencedSelf, Value.DereferencedSelf> {

try reduce(into: OrderedDictionary<Key.DereferencedSelf, Value.DereferencedSelf>()) { result, element in
let key = try element.key._dereferenced(in: components, following: references, dereferencedFromComponentNamed: nil)

let value = try element.value._dereferenced(in: components, following: references, dereferencedFromComponentNamed: nil)
result[key] = value
}

}
}
16 changes: 16 additions & 0 deletions Sources/OpenAPIKit30/Callbacks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,20 @@ extension OpenAPI {

/// A map of named collections of Callback Objects (`OpenAPI.Callbacks`).
public typealias CallbacksMap = OrderedDictionary<String, Either<JSONReference<Callbacks>, Callbacks>>

/// A dictionary of Dereferenced of callbacks.
public typealias DereferencedCallbacks = OrderedDictionary<CallbackURL, DereferencedPathItem>

/// A dictionary of Dereferenced map of callbacks.
public typealias DereferencedCallbacksMap = OrderedDictionary<String, DereferencedCallbacks>
}

extension OpenAPI.CallbackURL: LocallyDereferenceable {
public func _dereferenced(
in components: OpenAPI.Components,
following references: Set<AnyHashable>,
dereferencedFromComponentNamed name: String?
) throws -> OpenAPI.CallbackURL {
self
}
}
9 changes: 9 additions & 0 deletions Sources/OpenAPIKit30/Operation/DereferencedOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ public struct DereferencedOperation: Equatable {
public let requestBody: DereferencedRequest?
/// A dereferenced map of responses.
public let responses: DereferencedResponse.Map
/// A dereferenced map of callbacks.
public let callbacks: OpenAPI.DereferencedCallbacksMap

/// An array of dereferenced security requirements.
///
/// If defined, overrides the security requirements in the
Expand Down Expand Up @@ -71,6 +74,12 @@ public struct DereferencedOperation: Equatable {
)
}

self.callbacks = try operation.callbacks.mapValues { callback in
try callback._dereferenced(in: components,
following: references,
dereferencedFromComponentNamed: nil)
}

self.underlyingOperation = operation
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// OrderedDictionry+LocallyDereferenceable.swift
//
//
// Created by Alberto Lagos on 11-09-23.
//

import OpenAPIKitCore
import Foundation

/// A Swift extension for dereferencing an `OrderedDictionary` conforming to the `LocallyDereferenceable` protocol.
///
/// - Parameters:
/// - components: The OpenAPI components containing definitions.
/// - references: A set of references to track dereferenced items.
/// - name: The name of the component from which the dereferencing is initiated.
///
/// - Returns: A dereferenced `OrderedDictionary` containing keys and values of dereferenced types.
///
/// - Throws: An error if dereferencing fails for any element.
extension OrderedDictionary: LocallyDereferenceable where Key: LocallyDereferenceable, Key.DereferencedSelf: Hashable, Value: LocallyDereferenceable {

public func _dereferenced(in components: OpenAPI.Components,
following references: Set<AnyHashable>,
dereferencedFromComponentNamed name: String?) throws -> OpenAPIKitCore.OrderedDictionary<Key.DereferencedSelf, Value.DereferencedSelf> {

try reduce(into: OrderedDictionary<Key.DereferencedSelf, Value.DereferencedSelf>()) { result, element in
let key = try element.key._dereferenced(in: components, following: references, dereferencedFromComponentNamed: nil)

let value = try element.value._dereferenced(in: components, following: references, dereferencedFromComponentNamed: nil)
result[key] = value
}

}
}
35 changes: 35 additions & 0 deletions Tests/OpenAPIKit30Tests/Operation/DereferencedOperationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,39 @@ final class DereferencedOperationTests: XCTestCase {
).dereferenced(in: .noComponents)
)
}

func test_dereferencedCallback() throws {
let components = OpenAPI.Components(
callbacks: [
"callback": [
OpenAPI.CallbackURL(rawValue: "{$url}")!: .init(
description: "Example of pathItem",
post: .init(tags: "op callback", responses: [:])
)
]
]
)

let t1 = try OpenAPI.Operation(
responses: [:],
callbacks: [
"callback": .reference(.component(named: "callback"))
]
).dereferenced(in: components)
XCTAssertEqual(t1.callbacks.count, 1)
XCTAssertEqual(t1.callbacks["callback"]?.keys[0], OpenAPI.CallbackURL(rawValue: "{$url}"))
XCTAssertEqual(t1.callbacks["callback"]?.values[0].description, "Example of pathItem")
XCTAssertEqual(t1.callbacks["callback"]?.values[0][.post]?.tags, ["op callback"])
}

func test_callbackReferenceMissing() throws {
XCTAssertThrowsError(
try OpenAPI.Operation(
responses: [:],
callbacks: [
"callback": .reference(.component(named: "callback"))
]
).dereferenced(in: .noComponents)
)
}
}
37 changes: 37 additions & 0 deletions Tests/OpenAPIKitTests/Operation/DereferencedOperationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,41 @@ final class DereferencedOperationTests: XCTestCase {
).dereferenced(in: .noComponents)
)
}

func test_dereferencedCallback() throws {
let components = OpenAPI.Components(
callbacks: [
"callback": [
OpenAPI.CallbackURL(rawValue: "{$url}")!: .pathItem(
.init(
description: "Example of pathItem",
post: .init(tags: "op callback", responses: [:])
)
)
]
]
)

let t1 = try OpenAPI.Operation(
responses: [:],
callbacks: [
"callback": .reference(.component(named: "callback"))
]
).dereferenced(in: components)
XCTAssertEqual(t1.callbacks.count, 1)
XCTAssertEqual(t1.callbacks["callback"]?.keys[0], OpenAPI.CallbackURL(rawValue: "{$url}"))
XCTAssertEqual(t1.callbacks["callback"]?.values[0].description, "Example of pathItem")
XCTAssertEqual(t1.callbacks["callback"]?.values[0][.post]?.tags, ["op callback"])
}

func test_callbackReferenceMissing() throws {
XCTAssertThrowsError(
try OpenAPI.Operation(
responses: [:],
callbacks: [
"callback": .reference(.component(named: "callback"))
]
).dereferenced(in: .noComponents)
)
}
}

0 comments on commit beca680

Please sign in to comment.