DailyView/Carthage/Checkouts/facebook-ios-sdk/FBSDKGamingServicesKit/FBSDKGamingServicesKitTests/GameRequestURLProviderTests.swift
2025-12-30 16:40:31 +08:00

221 lines
6.2 KiB
Swift

/*
* 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 FBSDKGamingServicesKit
import FBSDKCoreKit
import TestTools
import XCTest
final class GameRequestURLProviderTests: XCTestCase {
// swiftlint:disable implicitly_unwrapped_optional
var internalUtility: TestTools.TestInternalUtility!
// swiftlint:enable implicitly_unwrapped_optional
override func setUp() {
super.setUp()
internalUtility = .init()
GameRequestURLProvider.setDependencies(
.init(
accessTokenWallet: TestAccessTokenWallet.self,
authenticationTokenWallet: TestAuthenticationTokenWallet.self,
appAvailabilityChecker: internalUtility
)
)
}
override func tearDown() {
internalUtility = nil
TestAccessTokenWallet.reset()
TestAuthenticationTokenWallet.reset()
GameRequestURLProvider.resetDependencies()
super.tearDown()
}
// MARK: - Dependencies
func testCustomDependencies() throws {
let dependencies = try GameRequestURLProvider.getDependencies()
XCTAssertIdentical(
dependencies.accessTokenWallet,
TestAccessTokenWallet.self,
.Dependencies.customDependency(for: "access token wallet")
)
XCTAssertIdentical(
dependencies.authenticationTokenWallet,
TestAuthenticationTokenWallet.self,
.Dependencies.customDependency(for: "authentication token wallet")
)
XCTAssertIdentical(
dependencies.appAvailabilityChecker,
internalUtility,
.Dependencies.customDependency(for: "app availability checker")
)
}
func testDefaultDependencies() throws {
GameRequestURLProvider.resetDependencies()
let dependencies = try GameRequestURLProvider.getDependencies()
XCTAssertIdentical(
dependencies.accessTokenWallet,
AccessToken.self,
.Dependencies.defaultDependency("AccessToken", for: "access token wallet")
)
XCTAssertIdentical(
dependencies.authenticationTokenWallet,
AuthenticationToken.self,
.Dependencies.defaultDependency("AuthenticationToken", for: "authentication token wallet")
)
XCTAssertIdentical(
dependencies.appAvailabilityChecker,
InternalUtility.shared,
.Dependencies.defaultDependency("InternalUtility", for: "app availability checker")
)
}
// MARK: - Action Type Name
func testActionTypeName() {
[
(GameRequestActionType.askFor, "askfor"),
(.invite, "invite"),
(.send, "send"),
(.turn, "turn"),
]
.forEach { pair in
XCTAssertEqual(
GameRequestURLProvider.actionTypeName(for: pair.0),
pair.1,
"The name of the action type: \(pair.0) should be: \(pair.1)"
)
}
XCTAssertNil(
GameRequestURLProvider.actionTypeName(for: .none),
"The `none` action type should not have a name"
)
}
func testSimpleFilterNames() {
[
(GameRequestFilter.appUsers, "app_users"),
(.appNonUsers, "app_non_users"),
]
.forEach { pair in
XCTAssertEqual(
GameRequestURLProvider.filtersName(for: pair.0),
pair.1,
"The name of the filter: \(pair.0) should be: \(pair.1)"
)
}
}
func testFilterNameForEverybodyWithoutGamingDomain() {
TestAuthenticationTokenWallet.current = SampleAuthenticationToken.validToken(withGraphDomain: "facebook")
XCTAssertNil(
GameRequestURLProvider.filtersName(for: .everybody),
"Should not have a filter name for `everybody` when the graph domain is not gaming"
)
}
func testFilterNameForEverybodyWithGamingDomainWithoutFacebookAppInstalled() {
TestAuthenticationTokenWallet.current = SampleAuthenticationToken.validToken(withGraphDomain: "gaming")
internalUtility.isFacebookAppInstalled = false
XCTAssertNil(
GameRequestURLProvider.filtersName(for: .everybody),
"Should not have a filter name for `everybody` when the facebook app is not installed"
)
}
func testFilterNameForEverybodyWithGamingDomainWithFacebookAppInstalled() {
TestAuthenticationTokenWallet.current = SampleAuthenticationToken.validToken(withGraphDomain: "gaming")
internalUtility.isFacebookAppInstalled = true
XCTAssertEqual(
GameRequestURLProvider.filtersName(for: .everybody),
"everybody",
"Should have a filter name for `everybody` when the graph domain is gaming and the facebook app is installed"
)
}
func testFilterNameForNoneFilter() {
XCTAssertNil(GameRequestURLProvider.filtersName(for: .none), "Should not have a filter name for the `none` filter")
}
func testCreatingDeepLinkURLWithAccessToken() throws {
TestAccessTokenWallet.current = SampleAccessTokens.validToken
let rawQueries: [String: Any] = [
"foo": "bar",
"baz": 1,
]
let url = try XCTUnwrap(
GameRequestURLProvider.createDeepLinkURL(queryDictionary: rawQueries),
"Should create a valid deep link url"
)
XCTAssertEqual(
url.scheme,
"https",
"Should use the expected url scheme"
)
XCTAssertEqual(
url.host,
"fb.gg",
"Should use the expected url host"
)
XCTAssertEqual(
url.path,
"/game_requestui/appID123",
"The path should include the app ID from the access token"
)
XCTAssertEqual(
url.query,
"foo=bar",
"Should omit any query items with non-String values"
)
}
func testCreatingDeepLinkURLWithoutAccessToken() throws {
let url = try XCTUnwrap(
GameRequestURLProvider.createDeepLinkURL(queryDictionary: [:]),
"Should create a valid deep link url"
)
XCTAssertEqual(
url.path,
"/game_requestui",
"Should omit the app ID from the path when it is not available"
)
}
}
// swiftformat:disable extensionaccesscontrol
// MARK: - Assumptions
fileprivate extension String {
enum Dependencies {
static func defaultDependency(_ dependency: String, for type: String) -> String {
"A GameRequestURLProvider type uses \(dependency) as its \(type) dependency by default"
}
static func customDependency(for type: String) -> String {
"A GameRequestURLProvider type uses a custom \(type) dependency when provided"
}
}
}