Skip to content

Commit

Permalink
add test to make sure updating cache policy in error interceptor work…
Browse files Browse the repository at this point in the history
…s as advertised
  • Loading branch information
designatednerd committed Dec 10, 2020
1 parent 66e24ea commit a48bfcf
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 1 deletion.
6 changes: 5 additions & 1 deletion Apollo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@
9BAEEC15234C132600808306 /* CLIExtractorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BAEEC14234C132600808306 /* CLIExtractorTests.swift */; };
9BAEEC17234C275600808306 /* ApolloSchemaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BAEEC16234C275600808306 /* ApolloSchemaTests.swift */; };
9BAEEC19234C297800808306 /* ApolloCodegenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BAEEC18234C297800808306 /* ApolloCodegenTests.swift */; };
9BB4F5B22581AA50004F0BD6 /* CacheDependentInterceptorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BB4F5B12581AA50004F0BD6 /* CacheDependentInterceptorTests.swift */; };
9BC139A424EDCA6C00876D29 /* InterceptorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BC139A224EDCA4400876D29 /* InterceptorTests.swift */; };
9BC139A624EDCAD900876D29 /* BlindRetryingTestInterceptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BC139A524EDCAD900876D29 /* BlindRetryingTestInterceptor.swift */; };
9BC139A824EDCE4F00876D29 /* RetryToCountThenSucceedInterceptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BC139A724EDCE4F00876D29 /* RetryToCountThenSucceedInterceptor.swift */; };
Expand Down Expand Up @@ -665,6 +666,7 @@
9BAEEC16234C275600808306 /* ApolloSchemaTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApolloSchemaTests.swift; sourceTree = "<group>"; };
9BAEEC18234C297800808306 /* ApolloCodegenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApolloCodegenTests.swift; sourceTree = "<group>"; };
9BB1DAC624A66B2500396235 /* ApolloMacPlayground.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; name = ApolloMacPlayground.playground; path = Playgrounds/ApolloMacPlayground.playground; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
9BB4F5B12581AA50004F0BD6 /* CacheDependentInterceptorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CacheDependentInterceptorTests.swift; sourceTree = "<group>"; };
9BC139A224EDCA4400876D29 /* InterceptorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InterceptorTests.swift; sourceTree = "<group>"; };
9BC139A524EDCAD900876D29 /* BlindRetryingTestInterceptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlindRetryingTestInterceptor.swift; sourceTree = "<group>"; };
9BC139A724EDCE4F00876D29 /* RetryToCountThenSucceedInterceptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RetryToCountThenSucceedInterceptor.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1498,15 +1500,16 @@
9FA6ABBD1EC0A988000017BE /* ApolloCacheDependentTests */ = {
isa = PBXGroup;
children = (
9BB4F5B12581AA50004F0BD6 /* CacheDependentInterceptorTests.swift */,
9FA6ABC51EC0A9F7000017BE /* FetchQueryTests.swift */,
9FA6ABC81EC0A9F7000017BE /* StarWarsServerCachingRoundtripTests.swift */,
9FA6ABC91EC0A9F7000017BE /* StarWarsServerTests.swift */,
9FA6ABC61EC0A9F7000017BE /* LoadQueryFromStoreTests.swift */,
9F8622F71EC2004200C38162 /* ReadWriteFromStoreTests.swift */,
9B60204E23FDFA9F00D0C8E0 /* SQLiteCacheTests.swift */,
9FD03C2D25527CE6002227DC /* StoreConcurrencyTests.swift */,
9FA6ABCB1EC0A9F7000017BE /* WatchQueryTests.swift */,
9FA6ABC01EC0A988000017BE /* Info.plist */,
9B60204E23FDFA9F00D0C8E0 /* SQLiteCacheTests.swift */,
);
path = ApolloCacheDependentTests;
sourceTree = "<group>";
Expand Down Expand Up @@ -2555,6 +2558,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9BB4F5B22581AA50004F0BD6 /* CacheDependentInterceptorTests.swift in Sources */,
9FD03C2E25527CE7002227DC /* StoreConcurrencyTests.swift in Sources */,
9F39101725493DDC00AF54A6 /* FetchQueryTests.swift in Sources */,
9FA6ABCD1EC0A9F7000017BE /* LoadQueryFromStoreTests.swift in Sources */,
Expand Down
127 changes: 127 additions & 0 deletions Tests/ApolloCacheDependentTests/CacheDependentInterceptorTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
//
// CacheDependentInterceptorTests.swift
// ApolloCacheDependentTests
//
// Created by Ellen Shapiro on 12/9/20.
// Copyright © 2020 Apollo GraphQL. All rights reserved.
//

import XCTest
import Apollo
import ApolloTestSupport
import StarWarsAPI

class CacheDependentInterceptorTests: XCTestCase, CacheDependentTesting {
var cacheType: TestCacheProvider.Type {
InMemoryTestCacheProvider.self
}
var defaultWaitTimeout: TimeInterval = 5


var cache: NormalizedCache!
var store: ApolloStore!
var client: ApolloClient!

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

cache = try makeNormalizedCache()
store = ApolloStore(cache: cache)
}

func testChangingCachePolicyInErrorInterceptorWorks() {
// Set up initial cache state
mergeRecordsIntoCache([
"QUERY_ROOT": ["hero": Reference(key: "hero")],
"hero": ["__typename": "Droid", "name": "R2-D2"]
])

/// This interceptor will reroute anything that fails with a response code error to retry hitting only the cache
class RerouteToCacheErrorInterceptor: ApolloErrorInterceptor {
var handledError: Error?

func handleErrorAsync<Operation: GraphQLOperation>(
error: Error,
chain: RequestChain,
request: HTTPRequest<Operation>,
response: HTTPResponse<Operation>?,
completion: @escaping (Result<GraphQLResult<Operation.Data>, Error>) -> Void) {

self.handledError = error

switch error {
case ResponseCodeInterceptor.ResponseCodeError.invalidResponseCode:
request.cachePolicy = .returnCacheDataDontFetch
chain.retry(request: request, completion: completion)
default:
completion(.failure(error))
}
}
}


class TestProvider: LegacyInterceptorProvider {
init(store: ApolloStore) {
super.init(client: self.mockClient,
store: store)
}

let mockClient: MockURLSessionClient = {
let client = MockURLSessionClient()
client.response = HTTPURLResponse(url: TestURL.mockServer.url,
statusCode: 401,
httpVersion: nil,
headerFields: nil)
client.data = Data()
return client
}()

let additionalInterceptor = RerouteToCacheErrorInterceptor()

override func additionalErrorInterceptor<Operation: GraphQLOperation>(for operation: Operation) -> ApolloErrorInterceptor? {
self.additionalInterceptor
}
}

let testProvider = TestProvider(store: self.store)
let network = RequestChainNetworkTransport(interceptorProvider: testProvider,
endpointURL: TestURL.mockServer.url)

let expectation = self.expectation(description: "Request sent")

// Send the initial request ignoring cache data so it doesn't initially get the data from the cache,
_ = network.send(operation: HeroNameQuery(), cachePolicy: .fetchIgnoringCacheData) { result in
defer {
expectation.fulfill()
}

// Check that the final result is what we expected
switch result {
case .failure(let error):
XCTFail("Unexpected error: \(error)")
case .success(let graphQLResult):
guard let heroName = graphQLResult.data?.hero?.name else {
XCTFail("Could not access hero name from returned result")
return
}

XCTAssertEqual(heroName, "R2-D2")
}

// Validate that there was a handled error before we went to the cache and we didn't just go straight to the cache
guard let handledError = testProvider.additionalInterceptor.handledError else {
XCTFail("No error was handled!")
return
}
switch handledError {
case ResponseCodeInterceptor.ResponseCodeError.invalidResponseCode(let response, _):
XCTAssertEqual(response?.statusCode, 401)
default:
XCTFail("Unexpected error on the additional error handler: \(handledError)")
}
}

self.wait(for: [expectation], timeout: self.defaultWaitTimeout)
}
}

0 comments on commit a48bfcf

Please sign in to comment.