FBSDKCoreKit/FBSDKCoreKitTests/GraphRequestTests.swift (281 lines of code) (raw):

/* * Copyright (c) Meta Platforms, Inc. and affiliates. * All rights reserved. * * This source code is licensed under the license found in the * LICENSE file in the root directory of this source tree. */ @testable import FBSDKCoreKit import TestTools import XCTest final class GraphRequestTests: XCTestCase { let path = "me" let parameters = ["fields": ""] let version = "v13.0" let prefix = "graph." let settings = TestSettings() var factory = TestGraphRequestConnectionFactory() override func setUp() { super.setUp() AuthenticationToken.current = nil GraphRequest.resetClassDependencies() AccessToken.resetCurrentAccessTokenCache() TestAccessTokenWallet.reset() GraphRequest.configure( settings: settings, currentAccessTokenStringProvider: TestAccessTokenWallet.self, graphRequestConnectionFactory: factory ) } override func tearDown() { GraphRequest.resetClassDependencies() TestAccessTokenWallet.reset() super.tearDown() } // MARK: - Tests func testDefaultDependencies() { GraphRequest.resetClassDependencies() let request = GraphRequest(graphPath: path) XCTAssertNil( GraphRequest.settings, "Should not have default settings" ) XCTAssertNil( request.tokenString, "Should not have a token string when no token string provider has been provided" ) XCTAssertNil( request.graphRequestConnectionFactory, "Should not have a default connection factory" ) } func testConfiguringWithDependencies() { TestAccessTokenWallet.currentAccessToken = SampleAccessTokens.validToken let request = GraphRequest(graphPath: path) XCTAssertTrue( GraphRequest.settings === settings, "GraphRequest should store the settings dependency it was configured with" ) XCTAssertEqual( request.tokenString, TestAccessTokenWallet.tokenString, "Should use the token string provider for the token string" ) XCTAssertTrue( request.graphRequestConnectionFactory === factory, "New instances should use the factory provider configured on the type" ) } func testCreatingWithCustomURLSessionProxyFactory() { factory = TestGraphRequestConnectionFactory(stubbedConnection: GraphRequestConnection()) let request = GraphRequest( graphPath: path, parameters: nil, tokenString: nil, httpMethod: nil, flags: [], graphRequestConnectionFactory: factory ) XCTAssertTrue( request.graphRequestConnectionFactory === factory, "A graph request should persist the session factory it was created with" ) } func testDefaultGETParameters() { verifyRequest( GraphRequest(graphPath: path), expectedGraphPath: path, expectedParameters: parameters, expectedTokenString: nil, expectedVersion: version, expectedMethod: .get ) } func testStartRequestUsesRequestProvidedByFactory() { let connection = TestGraphRequestConnection() factory = TestGraphRequestConnectionFactory(stubbedConnection: connection) let request = GraphRequest( graphPath: path, parameters: nil, tokenString: nil, httpMethod: nil, flags: [], graphRequestConnectionFactory: factory ) request.start { _, _, _ in } connection.capturedCompletion?(nil, nil, nil) XCTAssertEqual( connection.startCallCount, 1, "The graph request should use the provided connection" ) } func testGraphRequestGETWithEmptyParameters() { [ GraphRequest(graphPath: path, parameters: [:]), GraphRequest(graphPath: path, parameters: [:], flags: []), GraphRequest(graphPath: path, parameters: [:], tokenString: nil, version: version, httpMethod: .get), ] .forEach { verifyRequest( $0, expectedGraphPath: path, expectedParameters: [:], expectedTokenString: nil, expectedVersion: version, expectedMethod: .get ) } } func testGraphRequestGETWithNonEmptyParameters() { [ GraphRequest(graphPath: path, parameters: parameters), GraphRequest(graphPath: path, parameters: parameters, flags: []), GraphRequest(graphPath: path, parameters: parameters, tokenString: nil, version: version, httpMethod: .get), ] .forEach { verifyRequest( $0, expectedGraphPath: path, expectedParameters: parameters, expectedTokenString: nil, expectedVersion: version, expectedMethod: .get ) } } func testDefaultPOSTParameters() { let request = GraphRequest(graphPath: path, httpMethod: .post) verifyRequest( request, expectedGraphPath: path, expectedParameters: [:], expectedTokenString: nil, expectedVersion: version, expectedMethod: .post ) } func testGraphRequestPOSTWithEmptyParameters() { [ GraphRequest(graphPath: path, parameters: [:], httpMethod: .post), GraphRequest(graphPath: path, parameters: [:], tokenString: nil, version: version, httpMethod: .post), ] .forEach { verifyRequest( $0, expectedGraphPath: path, expectedParameters: [:], expectedTokenString: nil, expectedVersion: version, expectedMethod: .post ) } } func testGraphRequestPOSTWithNonEmptyParameters() { [ GraphRequest(graphPath: path, parameters: parameters, httpMethod: .post), GraphRequest(graphPath: path, parameters: parameters, tokenString: nil, version: version, httpMethod: .post), ] .forEach { verifyRequest( $0, expectedGraphPath: path, expectedParameters: parameters, expectedTokenString: nil, expectedVersion: version, expectedMethod: .post ) } } func testSerializeURL() throws { let baseURL = try InternalUtility.shared.facebookURL( withHostPrefix: prefix, path: path, queryParameters: [:], defaultVersion: version ) let url = GraphRequest.serializeURL( baseURL.absoluteString, params: parameters, httpMethod: HTTPMethod.post.rawValue, forBatch: true ) let expectedURL = "https://graph.facebook.com/\(version)/me?fields=" XCTAssertEqual(url, expectedURL) let encodedURL = Utility.encode(urlString: expectedURL) XCTAssertEqual(encodedURL, "https%3A%2F%2Fgraph.facebook.com%2F\(version)%2Fme%3Ffields%3D") XCTAssertEqual(Utility.decode(urlString: encodedURL), expectedURL) } func testAttachments() { XCTAssertTrue(GraphRequest.isAttachment(UIImage())) XCTAssertTrue(GraphRequest.isAttachment(Data())) XCTAssertTrue( GraphRequest.isAttachment( GraphRequestDataAttachment( data: Data(), filename: "fakefile", contentType: "foo" ) ) ) XCTAssertFalse(GraphRequest.isAttachment("string")) XCTAssertFalse(GraphRequest.isAttachment(Date())) } func testDebuggingHelpers() { let request = GraphRequest(graphPath: path, parameters: parameters, httpMethod: .post) let descriptionPart = "graphPath: me, HTTPMethod: POST, parameters: {\n fields = \"\"" XCTAssertTrue( request.description.contains(descriptionPart), "Requests should have useful information in their description" ) } func testDebuggingMetadata() { let request = GraphRequest(graphPath: path) let metadata = GraphRequestMetadata(request: request, completionHandler: nil, batchParameters: [:]) XCTAssertTrue( metadata.description.contains("request: "), "Request metadata should include information about the request" ) } func testSetSettingsWithCertainVersion() { let testVersion = "v123" settings.graphAPIVersion = testVersion let request = GraphRequest(graphPath: path) XCTAssertEqual(request.version, testVersion) } func testSetSettingsWithGraphErrorRecoveryEnabled() { settings.isGraphErrorRecoveryEnabled = true let request = GraphRequest(graphPath: path) XCTAssertFalse(request.isGraphErrorRecoveryDisabled) } func testSetSettingsWithDebugParamValue() throws { let debugParameter = "TestValue" settings.graphAPIDebugParamValue = debugParameter let baseURL = try InternalUtility.shared.facebookURL( withHostPrefix: prefix, path: path, queryParameters: [:], defaultVersion: version ) let url = GraphRequest.serializeURL( baseURL.absoluteString, params: [:], httpMethod: HTTPMethod.post.rawValue, forBatch: true ) let expectedURL = String( format: "https://graph.facebook.com/%@/me?debug=%@", version, debugParameter ) XCTAssertEqual(url, expectedURL) } // MARK: - Custom test assertions // swiftlint:disable:next function_parameter_count func verifyRequest( _ request: GraphRequest, expectedGraphPath: String, expectedParameters: [String: String], expectedTokenString: String?, expectedVersion: String, expectedMethod: HTTPMethod, file: StaticString = #filePath, line: UInt = #line ) { XCTAssertEqual(request.graphPath, expectedGraphPath, file: file, line: line) XCTAssertEqual(request.parameters as? [String: String], expectedParameters, file: file, line: line) XCTAssertEqual(request.tokenString, expectedTokenString, file: file, line: line) XCTAssertEqual(request.version, expectedVersion, file: file, line: line) XCTAssertEqual(request.httpMethod, expectedMethod, file: file, line: line) } }