Skip to content

Commit

Permalink
Adding GraphQLResult conversion extension (apollographql#139)
Browse files Browse the repository at this point in the history
  • Loading branch information
BobaFetters authored and gh-action-runner committed Nov 21, 2023
1 parent 360f068 commit 1a508b1
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 0 deletions.
115 changes: 115 additions & 0 deletions Tests/ApolloTests/GraphQLResultTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import XCTest
import Apollo
import ApolloAPI
import ApolloInternalTestHelpers
import StarWarsAPI

final class GraphQLResultTests: XCTestCase {

override func setUpWithError() throws {
try super.setUpWithError()
}

override func tearDownWithError() throws {
try super.tearDownWithError()
}

func test__result__givenResponseWithData_convertsToJSON() throws {
let jsonObj: [String: AnyHashable] = [
"hero": [
"name": "Luke Skywalker",
"__typename": "Human"
]
]
let heroData = try StarWarsAPI.HeroNameQuery.Data(data: jsonObj)
let result = GraphQLResult(
data: heroData,
extensions: nil,
errors: nil,
source: .server,
dependentKeys: nil
)

let expectedJSON: [String: Any] = [
"data": [
"hero": [
"name": "Luke Skywalker",
"__typename": "Human"
]
]
]

let convertedJSON = result.asJSONDictionary()
XCTAssertEqual(convertedJSON, expectedJSON)
}

func test__result__givenResponseWithNullData_convertsToJSON() throws {
let jsonObj: [String: AnyHashable] = [
"hero": NSNull()
]
let heroData = try StarWarsAPI.HeroNameQuery.Data(data: jsonObj)
let result = GraphQLResult(
data: heroData,
extensions: nil,
errors: nil,
source: .server,
dependentKeys: nil
)

let expectedJSON: [String: Any] = [
"data": [
"hero": NSNull()
]
]

let convertedJSON = result.asJSONDictionary()
XCTAssertEqual(convertedJSON, expectedJSON)
}

func test__result__givenResponseWithErrors_convertsToJSON() throws {
let jsonObj: [String: AnyHashable] = [
"message": "Sample error message",
"locations": [
"line": 1,
"column": 1
],
"path": [
"TestPath"
],
"extensions": [
"test": "extension"
]
]

let error = GraphQLError(jsonObj)
let result = GraphQLResult<HeroNameQuery.Data>(
data: nil,
extensions: nil,
errors: [error],
source: .server,
dependentKeys: nil
)

let expectedJSON: [String: Any] = [
"errors": [
[
"message": "Sample error message",
"locations": [
"line": 1,
"column": 1
],
"path": [
"TestPath"
],
"extensions": [
"test": "extension"
]
]
]
]

let convertedJSON = result.asJSONDictionary()
XCTAssertEqual(convertedJSON, expectedJSON)
}

}
11 changes: 11 additions & 0 deletions apollo-ios/Sources/Apollo/GraphQLError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,14 @@ extension GraphQLError: LocalizedError {
return self.description
}
}

extension GraphQLError {
func asJSONDictionary() -> [String: Any] {
var dict: [String: Any] = [:]
if let message = self["message"] { dict["message"] = message }
if let locations = self["locations"] { dict["locations"] = locations }
if let path = self["path"] { dict["path"] = path }
if let extensions = self["extensions"] { dict["extensions"] = extensions }
return dict
}
}
29 changes: 29 additions & 0 deletions apollo-ios/Sources/Apollo/GraphQLResult.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,32 @@ extension GraphQLResult: Equatable where Data: Equatable {
}

extension GraphQLResult: Hashable where Data: Hashable {}

extension GraphQLResult {

/// Converts a ``GraphQLResult`` into a basic JSON dictionary for use.
///
/// - Returns: A `[String: Any]` JSON dictionary representing the ``GraphQLResult``.
public func asJSONDictionary() -> [String: Any] {
var dict: [String: Any] = [:]
if let data { dict["data"] = convert(value: data.__data) }
if let errors { dict["errors"] = errors.map { $0.asJSONDictionary() } }
if let extensions { dict["extensions"] = extensions }
return dict
}

private func convert(value: Any) -> Any {
var val: Any = value
if let value = value as? ApolloAPI.DataDict {
val = value._data
} else if let value = value as? CustomScalarType {
val = value._jsonValue
}
if let dict = val as? [String: Any] {
return dict.mapValues(convert)
} else if let arr = val as? [Any] {
return arr.map(convert)
}
return val
}
}

0 comments on commit 1a508b1

Please sign in to comment.