-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix regressions found in the login with OAuth flow #1976
Changes from 3 commits
ad0b58a
5b81362
5abea9d
cc41eda
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,10 @@ public final class LoginToutViewController: UIViewController, MFMailComposeViewC | |
|> \.translatesAutoresizingMaskIntoConstraints .~ false | ||
}() | ||
|
||
private lazy var signupOrLoginWithOAuthButton = { UIButton(type: .custom) | ||
|> \.translatesAutoresizingMaskIntoConstraints .~ false | ||
}() | ||
|
||
private lazy var loginContextStackView = { UIStackView() }() | ||
private lazy var logoImageView = { UIImageView(frame: .zero) }() | ||
internal var processingView: ProcessingView? = ProcessingView(frame: .zero) | ||
|
@@ -138,15 +142,12 @@ public final class LoginToutViewController: UIViewController, MFMailComposeViewC | |
} | ||
|> UILabel.lens.text %~ { _ in Strings.Get_notified_when_your_friends_back_and_launch_projects() } | ||
|
||
if self.viewModel.outputs.loginWithOAuthEnabled { | ||
// TODO: Add and translate a new version of this string for this page. | ||
_ = self.loginButton |> greenButtonStyle | ||
self.loginButton | ||
.setTitle(Strings.login_tout_generic_intent_traditional_signup_or_login_button(), for: .normal) | ||
} else { | ||
_ = self.loginButton |> greyButtonStyle | ||
self.loginButton.setTitle(Strings.login_tout_back_intent_traditional_login_button(), for: .normal) | ||
} | ||
_ = self.loginButton |> greyButtonStyle | ||
self.loginButton.setTitle(Strings.login_tout_back_intent_traditional_login_button(), for: .normal) | ||
|
||
_ = self.signupOrLoginWithOAuthButton |> greenButtonStyle | ||
self.signupOrLoginWithOAuthButton | ||
.setTitle(Strings.login_tout_generic_intent_traditional_signup_or_login_button(), for: .normal) | ||
|
||
_ = self.loginContextStackView | ||
|> UIStackView.lens.spacing .~ Styles.gridHalf(1) | ||
|
@@ -190,6 +191,12 @@ public final class LoginToutViewController: UIViewController, MFMailComposeViewC | |
self?.pushSignupViewController() | ||
} | ||
|
||
self.viewModel.outputs.startOAuthSignupOrLogin | ||
.observeForControllerAction() | ||
.observeValues { [weak self] _ in | ||
self?.pushOAuthFlow() | ||
} | ||
|
||
self.viewModel.outputs.logIntoEnvironmentWithApple | ||
.observeValues { [weak self] accessTokenEnv in | ||
AppEnvironment.login(accessTokenEnv) | ||
|
@@ -298,6 +305,10 @@ public final class LoginToutViewController: UIViewController, MFMailComposeViewC | |
self.contextLabel.rac.text = self.viewModel.outputs.logInContextText | ||
self.bringCreativeProjectsToLifeLabel.rac.hidden = self.viewModel.outputs.headlineLabelHidden | ||
|
||
self.loginButton.rac.hidden = self.viewModel.outputs.showLoginWithOAuth | ||
self.signupButton.rac.hidden = self.viewModel.outputs.showLoginWithOAuth | ||
self.signupOrLoginWithOAuthButton.rac.hidden = self.viewModel.outputs.showLoginWithOAuth.signal.negate() | ||
|
||
self.viewModel.outputs.headlineLabelHidden | ||
.observeForUI() | ||
.observeValues { [weak self] isHidden in | ||
|
@@ -357,12 +368,9 @@ public final class LoginToutViewController: UIViewController, MFMailComposeViewC | |
_ = ([self.appleLoginButton, self.fbLoginButton, self.getNotifiedLabel], self.fbLoginStackView) | ||
|> ksr_addArrangedSubviewsToStackView() | ||
|
||
if self.viewModel.outputs.loginWithOAuthEnabled { | ||
self.emailLoginStackView.addArrangedSubview(self.loginButton) | ||
} else { | ||
self.emailLoginStackView.addArrangedSubview(self.signupButton) | ||
self.emailLoginStackView.addArrangedSubview(self.loginButton) | ||
} | ||
self.emailLoginStackView.addArrangedSubview(self.signupOrLoginWithOAuthButton) | ||
self.emailLoginStackView.addArrangedSubview(self.signupButton) | ||
self.emailLoginStackView.addArrangedSubview(self.loginButton) | ||
} | ||
|
||
private func setupConstraints() { | ||
|
@@ -391,6 +399,8 @@ public final class LoginToutViewController: UIViewController, MFMailComposeViewC | |
) | ||
self.loginButton.addTarget(self, action: #selector(self.loginButtonPressed(_:)), for: .touchUpInside) | ||
self.signupButton.addTarget(self, action: #selector(self.signupButtonPressed), for: .touchUpInside) | ||
self.signupOrLoginWithOAuthButton | ||
.addTarget(self, action: #selector(self.signupOrLoginWithOAuthButtonPressed), for: .touchUpInside) | ||
} | ||
|
||
private func attemptAppleLogin() { | ||
|
@@ -410,13 +420,17 @@ public final class LoginToutViewController: UIViewController, MFMailComposeViewC | |
} | ||
|
||
fileprivate func pushLoginViewController() { | ||
if self.viewModel.outputs.loginWithOAuthEnabled, let session = createAuthorizationSession() { | ||
session.presentationContextProvider = self | ||
session.start() | ||
} else { | ||
self.navigationController?.pushViewController(LoginViewController.instantiate(), animated: true) | ||
self.navigationItem.backBarButtonItem = UIBarButtonItem.back(nil, selector: nil) | ||
self.navigationController?.pushViewController(LoginViewController.instantiate(), animated: true) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is now only called by the traditional login button. |
||
self.navigationItem.backBarButtonItem = UIBarButtonItem.back(nil, selector: nil) | ||
} | ||
|
||
fileprivate func pushOAuthFlow() { | ||
guard featureLoginWithOAuthEnabled(), let session = createAuthorizationSession() else { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is only called by the new login button. |
||
return | ||
} | ||
|
||
session.presentationContextProvider = self | ||
session.start() | ||
} | ||
|
||
fileprivate func createAuthorizationSession() -> ASWebAuthenticationSession? { | ||
|
@@ -548,6 +562,10 @@ public final class LoginToutViewController: UIViewController, MFMailComposeViewC | |
@objc private func signupButtonPressed() { | ||
self.viewModel.inputs.signupButtonPressed() | ||
} | ||
|
||
@objc private func signupOrLoginWithOAuthButtonPressed() { | ||
self.viewModel.inputs.signupOrLoginWithOAuthButtonPressed() | ||
} | ||
} | ||
|
||
extension LoginToutViewController: TabBarControllerScrollable { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,12 @@ | ||
/// Return remote config values either a value from the cloud, if it found one, or a default value based on the provided key | ||
private func featureEnabled(feature: RemoteConfigFeature, defaultValue: Bool = false) -> Bool { | ||
let valueFromDefaults = AppEnvironment.current.userDefaults | ||
.remoteConfigFeatureFlags[feature.rawValue] | ||
|
||
private func featureEnabled(feature: RemoteConfigFeature) -> Bool { | ||
return AppEnvironment.current.userDefaults | ||
.remoteConfigFeatureFlags[feature.rawValue] ?? | ||
(AppEnvironment.current.remoteConfigClient? | ||
.isFeatureEnabled(featureKey: feature) ?? false) | ||
let valueFromRemoteConfig = AppEnvironment.current.remoteConfigClient? | ||
.isFeatureEnabled(featureKey: feature) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: Unlike before, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, good point - will fix then merge. |
||
|
||
return valueFromDefaults ?? valueFromRemoteConfig ?? defaultValue | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Slight refactoring to support new default values, and to make this easier to read and debug. |
||
} | ||
|
||
public func featureBlockUsersEnabled() -> Bool { | ||
|
@@ -32,7 +34,7 @@ public func featureReportThisProjectEnabled() -> Bool { | |
} | ||
|
||
public func featureLoginWithOAuthEnabled() -> Bool { | ||
featureEnabled(feature: .loginWithOAuthEnabled) | ||
featureEnabled(feature: .loginWithOAuthEnabled, defaultValue: true) | ||
} | ||
|
||
public func featureUseKeychainForOAuthTokenEnabled() -> Bool { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,7 +25,9 @@ final class LoginToutViewModelTests: TestCase { | |
fileprivate let startFacebookConfirmation = TestObserver<String, Never>() | ||
fileprivate let startLogin = TestObserver<(), Never>() | ||
fileprivate let startSignup = TestObserver<(), Never>() | ||
fileprivate let startOAuthSignupOrLogin = TestObserver<(), Never>() | ||
fileprivate let startTwoFactorChallenge = TestObserver<String, Never>() | ||
fileprivate let showLoginWithOAuth = TestObserver<Bool, Never>() | ||
|
||
override func setUp() { | ||
super.setUp() | ||
|
@@ -47,7 +49,9 @@ final class LoginToutViewModelTests: TestCase { | |
.observe(self.startFacebookConfirmation.observer) | ||
self.vm.outputs.startLogin.observe(self.startLogin.observer) | ||
self.vm.outputs.startSignup.observe(self.startSignup.observer) | ||
self.vm.outputs.startOAuthSignupOrLogin.observe(self.startOAuthSignupOrLogin.observer) | ||
self.vm.outputs.startTwoFactorChallenge.observe(self.startTwoFactorChallenge.observer) | ||
self.vm.outputs.showLoginWithOAuth.observe(self.showLoginWithOAuth.observer) | ||
} | ||
|
||
func testLoginIntent_Pledge() { | ||
|
@@ -117,6 +121,43 @@ final class LoginToutViewModelTests: TestCase { | |
) | ||
} | ||
|
||
func testStartSignupOrLoginWithOAuth() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some simple/boilerplate tests, just for sanity. |
||
self.vm.inputs.viewWillAppear() | ||
self.vm.inputs.signupOrLoginWithOAuthButtonPressed() | ||
self.startOAuthSignupOrLogin.assertValueCount(1, "OAuth signup/loginlogin emitted") | ||
} | ||
|
||
func testShowSignupOrLoginWithOAuth_featureFlagOn() { | ||
let mockConfigClient = MockRemoteConfigClient() | ||
mockConfigClient.features = [ | ||
RemoteConfigFeature.loginWithOAuthEnabled.rawValue: true | ||
] | ||
|
||
withEnvironment(remoteConfigClient: mockConfigClient) { | ||
self.vm.inputs.viewWillAppear() | ||
self.showLoginWithOAuth.assertValues([true]) | ||
} | ||
} | ||
|
||
func testShowSignupOrLoginWithOAuth_featureFlagOff() { | ||
let mockConfigClient = MockRemoteConfigClient() | ||
mockConfigClient.features = [ | ||
RemoteConfigFeature.loginWithOAuthEnabled.rawValue: false | ||
] | ||
|
||
withEnvironment(remoteConfigClient: mockConfigClient) { | ||
self.vm.inputs.viewWillAppear() | ||
self.showLoginWithOAuth.assertValues([false]) | ||
} | ||
} | ||
|
||
func testShowSignupOrLoginWithOAuth_featureFlagUnset() { | ||
withEnvironment(remoteConfigClient: nil) { | ||
self.vm.inputs.viewWillAppear() | ||
self.showLoginWithOAuth.assertValues([true]) | ||
} | ||
} | ||
|
||
func testHeadlineLabelHidden() { | ||
self.vm.inputs.configureWith(.starProject, project: nil, reward: nil) | ||
self.vm.inputs.viewWillAppear() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either show the new, combined button, or the two old buttons.