forked from facebook/facebook-ios-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Summary: Creates a general-purpose `_WebDialog` wrapper for `fb.gg`. Reviewed By: joesus Differential Revision: D39452083 fbshipit-source-id: 48f0e76c6e02739c219633c40bf24af7c983e154
- Loading branch information
1 parent
43cfd8b
commit 4c890ed
Showing
4 changed files
with
229 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
95 changes: 95 additions & 0 deletions
95
FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/GamingWebDialog.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
/* | ||
* 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. | ||
*/ | ||
|
||
// swiftlint:disable:all prefer_final_classes | ||
|
||
#if !os(tvOS) | ||
|
||
import FBSDKCoreKit | ||
import Foundation | ||
|
||
/** | ||
General-purpose web dialog for presenting `fb.gg/dialog/{view}` | ||
- warning: INTERNAL - DO NOT USE. This class is public so that other public types may extend it. | ||
*/ | ||
public class GamingWebDialog<Success: GamingWebDialogSuccess>: WebDialogDelegate { | ||
private enum Keys { | ||
static var path: String { "/gaming/dialog/" } | ||
static var errorCode: String { "error_code" } | ||
static var errorMessage: String { "error_message" } | ||
} | ||
|
||
public var completion: ((Result<Success, Error>) -> Void)? | ||
var dialog: _WebDialog? | ||
var parameters = [String: String]() | ||
var frame = CGRect.zero | ||
let name: String | ||
|
||
init(name: String) { | ||
self.name = name | ||
} | ||
|
||
func show(completion: @escaping (Result<Success, Error>) -> Void) { | ||
self.completion = completion | ||
dialog = _WebDialog( | ||
name: name, | ||
parameters: parameters, | ||
webViewFrame: frame, | ||
path: Keys.path + name | ||
) | ||
dialog?.delegate = self | ||
InternalUtility.shared.registerTransientObject(self) | ||
dialog?.show() | ||
} | ||
|
||
public func webDialog(_ webDialog: _WebDialog, didCompleteWithResults results: [String: Any]) { | ||
guard webDialog == dialog else { | ||
if let dialog = dialog { | ||
let error = _ErrorFactory().unknownError(message: "The dialog failed to retrieve results.") | ||
self.webDialog(dialog, didFailWithError: error) | ||
} | ||
return | ||
} | ||
|
||
if | ||
let errorCode = results[Keys.errorCode] as? Int, | ||
let errorMessage = results[Keys.errorMessage] as? String { | ||
let errorFactory = _ErrorFactory() | ||
let error = errorFactory.error( | ||
code: errorCode, | ||
userInfo: nil, | ||
message: errorMessage, | ||
underlyingError: nil | ||
) | ||
completion?(.failure(error)) | ||
completion = nil | ||
return | ||
} | ||
|
||
completion?(.success(Success(results))) | ||
completion = nil | ||
} | ||
|
||
public func webDialog(_ webDialog: _WebDialog, didFailWithError error: Error) { | ||
guard webDialog == dialog else { | ||
return | ||
} | ||
completion?(.failure(error)) | ||
InternalUtility.shared.unregisterTransientObject(self) | ||
} | ||
|
||
public func webDialogDidCancel(_ webDialog: _WebDialog) { | ||
guard webDialog == dialog else { | ||
return | ||
} | ||
completion?(.success(Success([:]))) | ||
InternalUtility.shared.unregisterTransientObject(self) | ||
} | ||
} | ||
|
||
#endif |
17 changes: 17 additions & 0 deletions
17
FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/GamingWebDialogSuccess.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/* | ||
* 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. | ||
*/ | ||
|
||
import Foundation | ||
|
||
/** | ||
The result of a completed `GamingWebDialog` | ||
- warning: INTERNAL - DO NOT USE | ||
*/ | ||
public protocol GamingWebDialogSuccess { | ||
init(_ dict: [String: Any]) | ||
} |
112 changes: 112 additions & 0 deletions
112
FBSDKGamingServicesKit/FBSDKGamingServicesKitTests/GamingWebDialogTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
/* | ||
* 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 | ||
@testable import FBSDKGamingServicesKit | ||
import TestTools | ||
import XCTest | ||
|
||
final class GamingWebDialogTests: XCTestCase { | ||
|
||
struct Success: GamingWebDialogSuccess { | ||
let payload: String? | ||
|
||
init(_ dict: [String: Any]) { | ||
payload = dict["payload"] as? String | ||
} | ||
} | ||
|
||
let payloadKey = "payload" | ||
let errorCodeKey = "error_code" | ||
let errorMessageKey = "error_message" | ||
|
||
// swiftlint:disable:next implicitly_unwrapped_optional | ||
var gamingWebDialog: GamingWebDialog<Success>! | ||
// swiftlint:disable:next implicitly_unwrapped_optional | ||
var webDialog: _WebDialog! | ||
|
||
var webDelegate: WebDialogDelegate { gamingWebDialog as WebDialogDelegate } | ||
var dialogCompleted = false | ||
var dialogFailed = false | ||
var error: Error? | ||
var payload: String? | ||
|
||
override func setUp() { | ||
super.setUp() | ||
error = nil | ||
payload = nil | ||
dialogCompleted = false | ||
dialogFailed = false | ||
|
||
gamingWebDialog = GamingWebDialog(name: "test") | ||
|
||
webDialog = _WebDialog(name: "Test") | ||
webDialog.delegate = webDelegate | ||
gamingWebDialog.dialog = webDialog | ||
gamingWebDialog.completion = { result in | ||
switch result { | ||
case let .success(success): | ||
self.dialogCompleted = true | ||
self.payload = success.payload | ||
case let .failure(error): | ||
self.dialogFailed = true | ||
self.error = error | ||
} | ||
} | ||
} | ||
|
||
func testDialogSucceedsWithPayload() throws { | ||
let testPayload = "test payload" | ||
|
||
gamingWebDialog.webDialog(webDialog, didCompleteWithResults: [payloadKey: testPayload]) | ||
|
||
XCTAssertTrue(dialogCompleted) | ||
XCTAssertFalse(dialogFailed) | ||
XCTAssertNil(error) | ||
XCTAssertEqual(payload, testPayload) | ||
} | ||
|
||
func testDialogFailsWithError() throws { | ||
let testErrorCode = 418 | ||
let testErrorMessage = "I'm a teapot" | ||
|
||
gamingWebDialog.webDialog( | ||
webDialog, | ||
didCompleteWithResults: [errorCodeKey: testErrorCode, errorMessageKey: testErrorMessage] | ||
) | ||
let error = try XCTUnwrap(error) as NSError | ||
|
||
XCTAssertFalse(dialogCompleted) | ||
XCTAssertTrue(dialogFailed) | ||
XCTAssertNotNil(error) | ||
XCTAssertEqual(error.code, testErrorCode) | ||
XCTAssertEqual(error.userInfo.values.first as? String, testErrorMessage) | ||
} | ||
|
||
func testDialogFailsWithUnknownError() throws { | ||
gamingWebDialog.webDialog( | ||
_WebDialog(name: "wrong dialog"), | ||
didCompleteWithResults: [:] | ||
) | ||
gamingWebDialog.show { _ in } | ||
let error = try XCTUnwrap(error) as NSError | ||
|
||
XCTAssertFalse(dialogCompleted) | ||
XCTAssertTrue(dialogFailed) | ||
XCTAssertNotNil(error) | ||
} | ||
|
||
func testDialogSucceedsEmptyWhenCanceled() throws { | ||
gamingWebDialog.webDialogDidCancel(webDialog) | ||
|
||
XCTAssertTrue(dialogCompleted) | ||
XCTAssertFalse(dialogFailed) | ||
XCTAssertNil(payload) | ||
XCTAssertNil(error) | ||
} | ||
} |