mirror of
https://github.com/zhigang1992/facebook-ios-sdk.git
synced 2026-01-12 22:47:16 +08:00
Improve test coverage of MessageDialog in ShareKit
Reviewed By: shuxinzhang Differential Revision: D35806609 fbshipit-source-id: d205dba25e18b47bca22ea4f5d142f64f018a170
This commit is contained in:
committed by
Facebook GitHub Bot
parent
677ba3ff30
commit
0ab188aafe
@@ -241,7 +241,7 @@ public class MessageDialog: NSObject, SharingDialog { // swiftlint:disable:this
|
||||
return shouldUseNativeDialog && internalUtility.isMessengerAppInstalled
|
||||
}
|
||||
|
||||
private func handleCompletion(dialogResults: [String: Any], response: BridgeAPIResponse) {
|
||||
func handleCompletion(dialogResults: [String: Any], response: BridgeAPIResponse) {
|
||||
let completionGesture = dialogResults[ShareBridgeAPI.CompletionGesture.key] as? String
|
||||
let isCancelGesture = (completionGesture == ShareBridgeAPI.CompletionGesture.cancelValue)
|
||||
if isCancelGesture || response.isCancelled {
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* 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 FBSDKCoreKit
|
||||
|
||||
final class TestBridgeAPIResponse: BridgeAPIResponse {
|
||||
|
||||
var stubbedResponseParameters: [String: Any]?
|
||||
|
||||
override var responseParameters: [String: Any]? {
|
||||
stubbedResponseParameters ?? super.responseParameters
|
||||
}
|
||||
}
|
||||
@@ -12,13 +12,6 @@ import XCTest
|
||||
|
||||
final class MessageDialogTests: XCTestCase {
|
||||
|
||||
enum Assumptions {
|
||||
static let contentValidation = """
|
||||
Known valid content should pass validation without issue. \
|
||||
If this test fails then the criteria for the fixture may no longer be valid
|
||||
"""
|
||||
}
|
||||
|
||||
// swiftlint:disable implicitly_unwrapped_optional
|
||||
var dialog: MessageDialog!
|
||||
var shareDialogConfiguration: TestShareDialogConfiguration!
|
||||
@@ -161,6 +154,22 @@ final class MessageDialogTests: XCTestCase {
|
||||
)
|
||||
}
|
||||
|
||||
func testCreatingWithFactoryMethod() {
|
||||
let content = ShareModelTestUtility.linkContent
|
||||
dialog = MessageDialog.dialog(content: content, delegate: delegate)
|
||||
|
||||
XCTAssertIdentical(dialog.shareContent, content, .factoryCreation)
|
||||
XCTAssertIdentical(dialog.delegate, delegate, .factoryCreation)
|
||||
}
|
||||
|
||||
func testCreatingAndShowingWithFactoryMethod() {
|
||||
let content = ShareModelTestUtility.linkContent
|
||||
dialog = MessageDialog.show(content: content, delegate: delegate)
|
||||
|
||||
XCTAssertIdentical(dialog.shareContent, content, .factoryCreation)
|
||||
XCTAssertIdentical(dialog.delegate, delegate, .factoryCreation)
|
||||
}
|
||||
|
||||
func testCanShow() {
|
||||
shareDialogConfiguration.stubbedShouldUseNativeDialog = true
|
||||
internalUtility.isMessengerAppInstalled = true
|
||||
@@ -192,13 +201,13 @@ final class MessageDialogTests: XCTestCase {
|
||||
dialog = MessageDialog()
|
||||
|
||||
dialog.shareContent = ShareModelTestUtility.linkContent
|
||||
XCTAssertNoThrow(try dialog.validate(), Assumptions.contentValidation)
|
||||
XCTAssertNoThrow(try dialog.validate(), .contentValidation)
|
||||
|
||||
dialog.shareContent = ShareModelTestUtility.photoContentWithImages
|
||||
XCTAssertNoThrow(try dialog.validate(), Assumptions.contentValidation)
|
||||
XCTAssertNoThrow(try dialog.validate(), .contentValidation)
|
||||
|
||||
dialog.shareContent = ShareModelTestUtility.videoContentWithoutPreviewPhoto
|
||||
XCTAssertNoThrow(try dialog.validate(), Assumptions.contentValidation)
|
||||
XCTAssertNoThrow(try dialog.validate(), .contentValidation)
|
||||
|
||||
dialog.shareContent = ShareModelTestUtility.cameraEffectContent
|
||||
XCTAssertNil(
|
||||
@@ -256,6 +265,142 @@ final class MessageDialogTests: XCTestCase {
|
||||
XCTAssertEqual(error.message, "Message dialog does not support ShareCameraEffectContent.", .failureIsHandled)
|
||||
XCTAssertNil(error.underlyingError, .failureIsHandled)
|
||||
}
|
||||
|
||||
func testShowingDialog() throws {
|
||||
shareDialogConfiguration.stubbedShouldUseNativeDialog = true
|
||||
shareDialogConfiguration.stubbedShouldUseSafariViewController = true
|
||||
internalUtility.isMessengerAppInstalled = true
|
||||
let parameters = ["key": "value"]
|
||||
TestShareUtility.stubbedBridgeParameters = parameters
|
||||
let request = TestBridgeAPIRequest()
|
||||
bridgeAPIRequestFactory.stubbedBridgeAPIRequest = request
|
||||
let content = ShareModelTestUtility.linkContent
|
||||
content.pageID = "foo"
|
||||
dialog.shareContent = content
|
||||
|
||||
XCTAssertTrue(dialog.show(), .showingValidDialog)
|
||||
|
||||
// Getting bridge parameters
|
||||
XCTAssertIdentical(shareUtility.capturedBridgeParametersShareContent, content, .showingValidDialog)
|
||||
let options = try XCTUnwrap(shareUtility.capturedBridgeParametersBridgeOptions, .showingValidDialog)
|
||||
XCTAssertTrue(options.isEmpty, .showingValidDialog)
|
||||
XCTAssertEqual(
|
||||
shareUtility.capturedBridgeParametersShouldFailOnDataError,
|
||||
dialog.shouldFailOnDataError,
|
||||
.showingValidDialog
|
||||
)
|
||||
|
||||
// Creating bridge API request
|
||||
XCTAssertEqual(bridgeAPIRequestFactory.capturedProtocolType, .native, .showingValidDialog)
|
||||
XCTAssertEqual(bridgeAPIRequestFactory.capturedScheme, URLScheme.messengerApp.rawValue, .showingValidDialog)
|
||||
XCTAssertEqual(bridgeAPIRequestFactory.capturedMethodName, ShareBridgeAPI.MethodName.share, .showingValidDialog)
|
||||
XCTAssertEqual(bridgeAPIRequestFactory.capturedParameters as? [String: String], parameters, .showingValidDialog)
|
||||
XCTAssertNil(bridgeAPIRequestFactory.capturedUserInfo, .showingValidDialog)
|
||||
|
||||
// Opening bridge API request
|
||||
XCTAssertIdentical(bridgeAPIRequestOpener.capturedRequest, request, .showingValidDialog)
|
||||
XCTAssertEqual(
|
||||
bridgeAPIRequestOpener.capturedUseSafariViewController,
|
||||
shareDialogConfiguration.stubbedShouldUseSafariViewController,
|
||||
.showingValidDialog
|
||||
)
|
||||
XCTAssertNil(bridgeAPIRequestOpener.capturedFromViewController, .showingValidDialog)
|
||||
|
||||
// Logging
|
||||
XCTAssertEqual(eventLogger.logInternalEventName, .shareDialogShow, .showingValidDialog)
|
||||
let expectedParameters: [AppEvents.ParameterName: String] = [
|
||||
.shareContentType: ShareAppEventsParameters.ContentTypeValue.status,
|
||||
.shareContentUUID: content.shareUUID!, // swiftlint:disable:this force_unwrapping
|
||||
.shareContentPageID: content.pageID!, // swiftlint:disable:this force_unwrapping
|
||||
]
|
||||
XCTAssertEqual(
|
||||
eventLogger.logInternalEventParameters as? [AppEvents.ParameterName: String],
|
||||
expectedParameters,
|
||||
.showingValidDialog
|
||||
)
|
||||
XCTAssertTrue(eventLogger.logInternalEventIsImplicitlyLogged ?? false, .showingValidDialog)
|
||||
XCTAssertEqual(eventLogger.logInternalEventAccessToken, TestAccessTokenWallet.current, .showingValidDialog)
|
||||
|
||||
// Completion
|
||||
let response = TestBridgeAPIResponse(request: request, error: nil)
|
||||
response.stubbedResponseParameters = parameters
|
||||
bridgeAPIRequestOpener.capturedCompletionBlock?(response)
|
||||
XCTAssertEqual(delegate?.sharerDidCompleteResults as? [String: String], parameters, .showingValidDialog)
|
||||
XCTAssertIdentical(internalUtility.unregisterTransientObjectObject as AnyObject, dialog, .showingValidDialog)
|
||||
}
|
||||
|
||||
func testHandlingNormalCancellation() {
|
||||
let request = TestBridgeAPIRequest()
|
||||
let response = TestBridgeAPIResponse(cancelledWith: request)
|
||||
|
||||
dialog.handleCompletion(dialogResults: [:], response: response)
|
||||
|
||||
XCTAssertEqual(eventLogger.logInternalEventName, .messengerShareDialogResult, .cancellationIsHandled)
|
||||
XCTAssertEqual(
|
||||
eventLogger.logInternalEventParameters as? [AppEvents.ParameterName: String],
|
||||
[.outcome: ShareAppEventsParameters.DialogOutcomeValue.cancelled],
|
||||
.cancellationIsHandled
|
||||
)
|
||||
XCTAssertTrue(eventLogger.logInternalEventIsImplicitlyLogged ?? false, .cancellationIsHandled)
|
||||
XCTAssertIdentical(eventLogger.logInternalEventAccessToken, accessTokenWallet.current, .cancellationIsHandled)
|
||||
XCTAssertIdentical(delegate.sharerDidCancelSharer as AnyObject, dialog, .cancellationIsHandled)
|
||||
}
|
||||
|
||||
func testHandlingCancellationViaGesture() {
|
||||
let request = TestBridgeAPIRequest()
|
||||
let response = TestBridgeAPIResponse(request: request, error: nil)
|
||||
let results = [ShareBridgeAPI.CompletionGesture.key: ShareBridgeAPI.CompletionGesture.cancelValue]
|
||||
dialog.handleCompletion(dialogResults: results, response: response)
|
||||
|
||||
XCTAssertEqual(eventLogger.logInternalEventName, .messengerShareDialogResult, .cancellationIsHandled)
|
||||
XCTAssertEqual(
|
||||
eventLogger.logInternalEventParameters as? [AppEvents.ParameterName: String],
|
||||
[.outcome: ShareAppEventsParameters.DialogOutcomeValue.cancelled],
|
||||
.cancellationIsHandled
|
||||
)
|
||||
XCTAssertTrue(eventLogger.logInternalEventIsImplicitlyLogged ?? false, .cancellationIsHandled)
|
||||
XCTAssertIdentical(eventLogger.logInternalEventAccessToken, accessTokenWallet.current, .cancellationIsHandled)
|
||||
XCTAssertIdentical(delegate.sharerDidCancelSharer as AnyObject, dialog, .cancellationIsHandled)
|
||||
}
|
||||
|
||||
func testHandlingFailure() {
|
||||
let request = TestBridgeAPIRequest()
|
||||
let error = SampleError()
|
||||
let response = TestBridgeAPIResponse(request: request, error: error)
|
||||
dialog.handleCompletion(dialogResults: [:], response: response)
|
||||
|
||||
XCTAssertEqual(eventLogger.logInternalEventName, .shareDialogResult, .failureIsHandled)
|
||||
XCTAssertEqual(
|
||||
eventLogger.logInternalEventParameters as? [AppEvents.ParameterName: String],
|
||||
[
|
||||
.outcome: ShareAppEventsParameters.DialogOutcomeValue.failed,
|
||||
.errorMessage: String(describing: error),
|
||||
],
|
||||
.failureIsHandled
|
||||
)
|
||||
XCTAssertTrue(eventLogger.logInternalEventIsImplicitlyLogged ?? false, .failureIsHandled)
|
||||
XCTAssertIdentical(eventLogger.logInternalEventAccessToken, accessTokenWallet.current, .failureIsHandled)
|
||||
XCTAssertIdentical(delegate.sharerDidFailSharer as AnyObject, dialog, .failureIsHandled)
|
||||
XCTAssertEqual(delegate.sharerDidFailError as? SampleError, error, .failureIsHandled)
|
||||
}
|
||||
|
||||
func testHandlingSuccess() {
|
||||
let request = TestBridgeAPIRequest()
|
||||
let response = TestBridgeAPIResponse(request: request, error: nil)
|
||||
let results = ["key": "value"]
|
||||
dialog.handleCompletion(dialogResults: results, response: response)
|
||||
|
||||
XCTAssertEqual(eventLogger.logInternalEventName, .messengerShareDialogResult, .successIsHandled)
|
||||
XCTAssertEqual(
|
||||
eventLogger.logInternalEventParameters as? [AppEvents.ParameterName: String],
|
||||
[.outcome: ShareAppEventsParameters.DialogOutcomeValue.completed],
|
||||
.successIsHandled
|
||||
)
|
||||
XCTAssertTrue(eventLogger.logInternalEventIsImplicitlyLogged ?? false, .successIsHandled)
|
||||
XCTAssertIdentical(eventLogger.logInternalEventAccessToken, accessTokenWallet.current, .successIsHandled)
|
||||
XCTAssertIdentical(delegate.sharerDidCompleteSharer as AnyObject, dialog, .successIsHandled)
|
||||
XCTAssertEqual(delegate.sharerDidCompleteResults as? [String: String], results, .successIsHandled)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Assumptions
|
||||
@@ -269,5 +414,15 @@ fileprivate extension String {
|
||||
"The MessageDialog type uses a custom \(type) dependency when provided"
|
||||
}
|
||||
|
||||
static let factoryCreation = "A dialog can be created using a factory method"
|
||||
|
||||
static let contentValidation = """
|
||||
Known valid content passes validation without issue. \
|
||||
When this test fails then the criteria for the fixture may no longer be valid.
|
||||
"""
|
||||
|
||||
static let cancellationIsHandled = "Cancellation is sent to a dialog's delegate and logged"
|
||||
static let failureIsHandled = "Failure is sent to a dialog's delegate and logged"
|
||||
static let successIsHandled = "Success is sent to a dialog's delegate and logged"
|
||||
static let showingValidDialog = "A dialog shows valid content by creating a bridge API request an opening it"
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
public struct SampleError: Error {
|
||||
public struct SampleError: Error, Equatable {
|
||||
private let uuid = UUID()
|
||||
|
||||
public init() {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user