Skip to content

Commit

Permalink
Abstracting dependencies for FBSDKLoginButton
Browse files Browse the repository at this point in the history
Summary:
In order to further increase some test coverage, some dependencies needed to be abstracted as we need to pass different underlying types when testing.

Increased test coverage for login button and login kit.

Before:

{F710854289}

{F710854034}

After:

{F710854337}

{F710854079}

Reviewed By: samodom

Differential Revision: D34774326

fbshipit-source-id: e8d5197af05b53fd3346f5180869e0ee713dbf72
  • Loading branch information
Pablo Brizuela Guardado authored and facebook-github-bot committed Mar 15, 2022
1 parent 0d2160b commit 76fbbbd
Show file tree
Hide file tree
Showing 9 changed files with 344 additions and 114 deletions.
1 change: 1 addition & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ file_name:
ShareAppEventNames.swift,
ShareAppEventParameters.swift,
ShareDialogMode.swift,
InternalUtilityExtensions.swift
]
trailing_comma:
mandatory_comma: true
Expand Down
67 changes: 41 additions & 26 deletions FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,48 @@
static const CGFloat kPaddingBetweenLogoTitle = 8.0;

@interface FBSDKLoginButton ()

@property (nonatomic) BOOL hasShownTooltipBubble;
@property (nonatomic) id<FBSDKLoginProviding> loginProvider;
@property (nonatomic) NSString *userID;
@property (nonatomic) NSString *userName;
@property (nonatomic) id<FBSDKUserInterfaceElementProviding> elementProvider;
@property (nonatomic) id<FBSDKUserInterfaceStringProviding> stringProvider;
@property (nonatomic) id<FBSDKLoginProviding> loginProvider;
@property (nonatomic) id<FBSDKGraphRequestFactory> graphRequestFactory;

@end

@implementation FBSDKLoginButton

// MARK: - Type Dependencies

- (void)configureWithElementProvider:(nonnull id<FBSDKUserInterfaceElementProviding>)elementProvider
stringProvider:(nonnull id<FBSDKUserInterfaceStringProviding>)stringProvider
loginProvider:(nonnull id<FBSDKLoginProviding>)loginProvider
graphRequestFactory:(nonnull id<FBSDKGraphRequestFactory>)graphRequestFactory
{
self.elementProvider = elementProvider;
self.stringProvider = stringProvider;
self.loginProvider = loginProvider;
self.graphRequestFactory = graphRequestFactory;
}

- (void)configureDefaultTypeDependencies
{
[self configureWithElementProvider:FBSDKInternalUtility.sharedUtility
stringProvider:FBSDKInternalUtility.sharedUtility
loginProvider:[FBSDKLoginManager new]
graphRequestFactory:[FBSDKGraphRequestFactory new]];
}

#pragma mark - Properties

- (FBSDKDefaultAudience)defaultAudience
{
return _loginProvider.defaultAudience;
return self.loginProvider.defaultAudience;
}

- (void)setDefaultAudience:(FBSDKDefaultAudience)defaultAudience
{
_loginProvider.defaultAudience = defaultAudience;
self.loginProvider.defaultAudience = defaultAudience;
}

- (void)setLoginTracking:(FBSDKLoginTracking)loginTracking
Expand Down Expand Up @@ -139,7 +160,7 @@ - (CGSize)sizeThatFits:(CGSize)size

- (void)configureButton
{
_loginProvider = [FBSDKLoginManager new];
[self configureDefaultTypeDependencies];

NSString *logInTitle = [self _shortLogInTitle];
NSString *logOutTitle = [self _logOutTitle];
Expand Down Expand Up @@ -208,7 +229,7 @@ - (void)_buttonPressed:(id)sender
NSLocalizedStringWithDefaultValue(
@"LoginButton.LoggedInAs",
@"FacebookSDK",
[FBSDKInternalUtility.sharedUtility bundleForStrings],
[self.stringProvider bundleForStrings],
@"Logged in as %@",
@"The format string for the FBSDKLoginButton label when the user is logged in"
);
Expand All @@ -218,7 +239,7 @@ - (void)_buttonPressed:(id)sender
NSLocalizedStringWithDefaultValue(
@"LoginButton.LoggedIn",
@"FacebookSDK",
[FBSDKInternalUtility.sharedUtility bundleForStrings],
[self.stringProvider bundleForStrings],
@"Logged in using Facebook",
@"The fallback string for the FBSDKLoginButton label when the user name is not available yet"
);
Expand All @@ -228,15 +249,15 @@ - (void)_buttonPressed:(id)sender
NSLocalizedStringWithDefaultValue(
@"LoginButton.CancelLogout",
@"FacebookSDK",
[FBSDKInternalUtility.sharedUtility bundleForStrings],
[self.stringProvider bundleForStrings],
@"Cancel",
@"The label for the FBSDKLoginButton action sheet to cancel logging out"
);
NSString *logOutTitle =
NSLocalizedStringWithDefaultValue(
@"LoginButton.ConfirmLogOut",
@"FacebookSDK",
[FBSDKInternalUtility.sharedUtility bundleForStrings],
[self.stringProvider bundleForStrings],
@"Log Out",
@"The label for the FBSDKLoginButton action sheet to confirm logging out"
);
Expand All @@ -255,7 +276,7 @@ - (void)_buttonPressed:(id)sender
}];
[alertController addAction:cancel];
[alertController addAction:logout];
UIViewController *topMostViewController = [FBSDKInternalUtility.sharedUtility topMostViewController];
UIViewController *topMostViewController = [self.elementProvider topMostViewController];
[topMostViewController presentViewController:alertController
animated:YES
completion:nil];
Expand All @@ -278,9 +299,11 @@ - (void)_buttonPressed:(id)sender
[self logTapEventWithEventName:FBSDKAppEventNameFBSDKLoginButtonDidTap parameters:nil];
}

[_loginProvider logInFromViewController:[FBSDKInternalUtility.sharedUtility viewControllerForView:self]
configuration:loginConfig
completion:handler];
if (loginConfig != nil) {
[self.loginProvider logInFromViewController:[self.elementProvider viewControllerForView:self]
configuration:loginConfig
completion:handler];
}
}
}

Expand All @@ -300,7 +323,7 @@ - (NSString *)_logOutTitle
return NSLocalizedStringWithDefaultValue(
@"LoginButton.LogOut",
@"FacebookSDK",
[FBSDKInternalUtility.sharedUtility bundleForStrings],
[self.stringProvider bundleForStrings],
@"Log out",
@"The label for the FBSDKLoginButton when the user is currently logged in"
);
Expand All @@ -311,7 +334,7 @@ - (NSString *)_longLogInTitle
return NSLocalizedStringWithDefaultValue(
@"LoginButton.LogInContinue",
@"FacebookSDK",
[FBSDKInternalUtility.sharedUtility bundleForStrings],
[self.stringProvider bundleForStrings],
@"Continue with Facebook",
@"The long label for the FBSDKLoginButton when the user is currently logged out"
);
Expand All @@ -322,7 +345,7 @@ - (NSString *)_shortLogInTitle
return NSLocalizedStringWithDefaultValue(
@"LoginButton.LogIn",
@"FacebookSDK",
[FBSDKInternalUtility.sharedUtility bundleForStrings],
[self.stringProvider bundleForStrings],
@"Log in",
@"The short label for the FBSDKLoginButton when the user is currently logged out"
);
Expand Down Expand Up @@ -407,18 +430,10 @@ - (BOOL)_isAuthenticated

- (void)_logout
{
[self->_loginProvider logOut];
[self.loginProvider logOut];
[self.delegate loginButtonDidLogOut:self];
}

- (id<FBSDKGraphRequestFactory>)graphRequestFactory
{
if (!_graphRequestFactory) {
_graphRequestFactory = [FBSDKGraphRequestFactory new];
}
return _graphRequestFactory;
}

@end

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* 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

extension InternalUtility: UserInterfaceElementProviding {}

extension InternalUtility: UserInterfaceStringProviding {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* 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 UIKit

@objc(FBSDKUserInterfaceElementProviding)
public protocol UserInterfaceElementProviding {
func topMostViewController() -> UIViewController?
@objc(viewControllerForView:)
func viewController(for view: UIView) -> UIViewController?
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* 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

@objc(FBSDKUserInterfaceStringProviding)
public protocol UserInterfaceStringProviding {
var bundleForStrings: Bundle { get }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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 TestUserInterfaceElementProvider: UserInterfaceElementProviding {
var stubbedTopMostViewController: UIViewController?
var capturedView: UIView?

func topMostViewController() -> UIViewController? {
stubbedTopMostViewController
}

func viewController(for view: UIView) -> UIViewController? {
capturedView = view
return stubbedTopMostViewController
}
}
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 FBSDKCoreKit

final class TestUserInterfaceStringProvider: UserInterfaceStringProviding {
var stubbedBundleForStrings: Bundle?

var bundleForStrings: Bundle {
stubbedBundleForStrings ?? .main
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,18 @@
* LICENSE file in the root directory of this source tree.
*/

#import <FBSDKLoginKit/FBSDKLoginKit-Swift.h>

#import "FBSDKLoginButton.h"

NS_ASSUME_NONNULL_BEGIN

@interface FBSDKLoginButton (Testing)

@property (nonatomic) id<FBSDKGraphRequestFactory> graphRequestFactory;

@property (nonatomic) id<FBSDKUserInterfaceElementProviding> elementProvider;
@property (nonatomic) id<FBSDKUserInterfaceStringProviding> stringProvider;
@property (nonatomic) id<FBSDKLoginProviding> loginProvider;
- (FBSDKLoginConfiguration *)loginConfiguration;
- (BOOL)_isAuthenticated;
- (void)_fetchAndSetContent;
Expand All @@ -24,10 +28,15 @@ NS_ASSUME_NONNULL_BEGIN
- (void)_profileDidChangeNotification:(NSNotification *)notification;
- (nullable NSString *)userName;
- (nullable NSString *)userID;
- (void)setLoginProvider:(id<FBSDKLoginProviding>)loginProvider;
- (void)_buttonPressed:(id)sender;
- (void)_logout;
- (void)setGraphRequestFactory:(nonnull id<FBSDKGraphRequestFactory>)graphRequestFactory;
// UNCRUSTIFY_FORMAT_OFF
- (void)configureWithElementProvider:(nonnull id<FBSDKUserInterfaceElementProviding>)elementProvider
stringProvider:(nonnull id<FBSDKUserInterfaceStringProviding>)stringProvider
loginProvider:(nonnull id<FBSDKLoginProviding>)loginProvider
graphRequestFactory:(nonnull id<FBSDKGraphRequestFactory>)graphRequestFactory
NS_SWIFT_NAME(configure(elementProvider:stringProvider:loginProvider:graphRequestFactory:));
// UNCRUSTIFY_FORMAT_ON
@end

NS_ASSUME_NONNULL_END
Loading

0 comments on commit 76fbbbd

Please sign in to comment.