diff --git a/Tests/ApolloTests/RequestChainTests.swift b/Tests/ApolloTests/RequestChainTests.swift index 197827e92..fbce37249 100644 --- a/Tests/ApolloTests/RequestChainTests.swift +++ b/Tests/ApolloTests/RequestChainTests.swift @@ -1215,4 +1215,193 @@ class RequestChainTests: XCTestCase { // then wait(for: expectations, timeout: 1, enforceOrder: true) } + + // MARK: Response Tests + + func test__response__givenUnsuccessfulStatusCode_shouldFail() throws { + // given + let client = MockURLSessionClient( + response: .mock( + url: TestURL.mockServer.url, + statusCode: 500, + httpVersion: nil, + headerFields: nil + ), + data: """ + { + "data": { + "__typename": "Hero", + "name": "R2-D2" + } + } + """.data(using: .utf8) + ) + + let provider = DefaultInterceptorProvider( + client: client, + store: ApolloStore() + ) + + let transport = RequestChainNetworkTransport( + interceptorProvider: provider, + endpointURL: TestURL.mockServer.url + ) + + let expectation = expectation(description: "Response received") + + _ = transport.send(operation: MockQuery()) { result in + switch result { + case .success: + XCTFail("Unexpected response: \(result)") + + case .failure: + expectation.fulfill() + } + } + + wait(for: [expectation], timeout: 1) + } + + // This test is odd because you might assume it would fail but there is no content-type checking on standard + // GraphQL response parsing. So this test is here to ensure that existing behaviour does not change. + func test__response__givenUnknownContentType_shouldNotFail() throws { + // given + let client = MockURLSessionClient( + response: .mock( + url: TestURL.mockServer.url, + statusCode: 200, + httpVersion: nil, + headerFields: ["content-type": "unknown/type"] + ), + data: """ + { + "data": { + "__typename": "Hero", + "name": "R2-D2" + } + } + """.data(using: .utf8) + ) + + let provider = DefaultInterceptorProvider( + client: client, + store: ApolloStore() + ) + + let transport = RequestChainNetworkTransport( + interceptorProvider: provider, + endpointURL: TestURL.mockServer.url + ) + + let expectation = expectation(description: "Response received") + + _ = transport.send(operation: MockQuery()) { result in + switch result { + case let .success(responseData): + XCTAssertEqual(responseData.data?.__typename, "Hero") + XCTAssertEqual(responseData.data?.name, "R2-D2") + + expectation.fulfill() + + case .failure: + XCTFail("Unexpected response: \(result)") + } + } + + wait(for: [expectation], timeout: 1) + } + + func test__response__givenJSONContentType_shouldSucceed() throws { + // given + let client = MockURLSessionClient( + response: .mock( + url: TestURL.mockServer.url, + statusCode: 200, + httpVersion: nil, + headerFields: ["content-type": "application/json"] + ), + data: """ + { + "data": { + "__typename": "Hero", + "name": "R2-D2" + } + } + """.data(using: .utf8) + ) + + let provider = DefaultInterceptorProvider( + client: client, + store: ApolloStore() + ) + + let transport = RequestChainNetworkTransport( + interceptorProvider: provider, + endpointURL: TestURL.mockServer.url + ) + + let expectation = expectation(description: "Response received") + + _ = transport.send(operation: MockQuery()) { result in + switch result { + case let .success(responseData): + XCTAssertEqual(responseData.data?.__typename, "Hero") + XCTAssertEqual(responseData.data?.name, "R2-D2") + + expectation.fulfill() + + case .failure: + XCTFail("Unexpected response: \(result)") + } + } + + wait(for: [expectation], timeout: 1) + } + + func test__response__givenGraphQLOverHTTPContentType_shouldSucceed() throws { + // given + let client = MockURLSessionClient( + response: .mock( + url: TestURL.mockServer.url, + statusCode: 200, + httpVersion: nil, + headerFields: ["content-type": "application/graphql-response+json"] + ), + data: """ + { + "data": { + "__typename": "Hero", + "name": "R2-D2" + } + } + """.data(using: .utf8) + ) + + let provider = DefaultInterceptorProvider( + client: client, + store: ApolloStore() + ) + + let transport = RequestChainNetworkTransport( + interceptorProvider: provider, + endpointURL: TestURL.mockServer.url + ) + + let expectation = expectation(description: "Response received") + + _ = transport.send(operation: MockQuery()) { result in + switch result { + case let .success(responseData): + XCTAssertEqual(responseData.data?.__typename, "Hero") + XCTAssertEqual(responseData.data?.name, "R2-D2") + + expectation.fulfill() + + case .failure: + XCTFail("Unexpected response: \(result)") + } + } + + wait(for: [expectation], timeout: 1) + } }