Skip to content

Commit a1966bb

Browse files
authored
Add test for verify iOS client (#2096)
1 parent 46cb564 commit a1966bb

File tree

6 files changed

+187
-25
lines changed

6 files changed

+187
-25
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Copyright 2018 Google
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#import <XCTest/XCTest.h>
18+
#import <EarlGrey/EarlGrey.h>
19+
#import <FirebaseCore/FIRApp.h>
20+
#import "FirebaseAuth.h"
21+
22+
static CGFloat const kShortScrollDistance = 100;
23+
24+
static NSTimeInterval const kWaitForElementTimeOut = 15;
25+
26+
@interface FIRVerifyIOSClientTests : XCTestCase
27+
@end
28+
29+
/** Convenience function for EarlGrey tests. */
30+
static id<GREYMatcher> grey_scrollView(void) {
31+
return [GREYMatchers matcherForKindOfClass:[UIScrollView class]];
32+
}
33+
34+
@implementation FIRVerifyIOSClientTests
35+
36+
/** To reset the app so that each test sees the app in a clean state. */
37+
- (void)setUp {
38+
[super setUp];
39+
40+
[self signOut];
41+
42+
[[EarlGrey selectElementWithMatcher:grey_allOf(grey_scrollView(),
43+
grey_kindOfClass([UITableView class]), nil)]
44+
performAction:grey_scrollToContentEdge(kGREYContentEdgeTop)];
45+
}
46+
47+
#pragma mark - Tests
48+
49+
/** Test verify ios client*/
50+
- (void)testVerifyIOSClient {
51+
[[[EarlGrey selectElementWithMatcher:grey_allOf(grey_text(@"Verify iOS client"),
52+
grey_sufficientlyVisible(), nil)]
53+
usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, kShortScrollDistance)
54+
onElementWithMatcher:grey_allOf(grey_scrollView(), grey_kindOfClass([UITableView class]),
55+
nil)] performAction:grey_tap()];
56+
57+
[self waitForElementWithText:@"OK" withDelay:kWaitForElementTimeOut];
58+
59+
[[EarlGrey selectElementWithMatcher:grey_text(@"OK")] performAction:grey_tap()];
60+
}
61+
62+
#pragma mark - Helpers
63+
64+
/** Sign out current account. */
65+
- (void)signOut {
66+
NSError *signOutError;
67+
BOOL status = [[FIRAuth auth] signOut:&signOutError];
68+
69+
// Just log the error because we don't want to fail the test if signing out fails.
70+
if (!status) {
71+
NSLog(@"Error signing out: %@", signOutError);
72+
}
73+
}
74+
75+
/** Wait for an element with text to appear. */
76+
- (void)waitForElementWithText:(NSString *)text withDelay:(NSTimeInterval)maxDelay {
77+
GREYCondition *displayed =
78+
[GREYCondition conditionWithName:@"Wait for element"
79+
block:^BOOL {
80+
NSError *error = nil;
81+
[[EarlGrey selectElementWithMatcher:grey_text(text)]
82+
assertWithMatcher:grey_sufficientlyVisible()
83+
error:&error];
84+
return !error;
85+
}];
86+
GREYAssertTrue([displayed waitWithTimeout:maxDelay], @"Failed to wait for element '%@'.", text);
87+
}
88+
89+
@end

Example/Auth/EarlGreyTests/FirebaseAuthEarlGreyTests.m

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ @interface BasicUITest :XCTestCase
3838
@end
3939

4040
/** Convenience function for EarlGrey tests. */
41-
id<GREYMatcher> grey_scrollView(void) {
41+
static id<GREYMatcher> grey_scrollView(void) {
4242
return [GREYMatchers matcherForKindOfClass:[UIScrollView class]];
4343
}
4444

@@ -52,7 +52,7 @@ - (void)setUp {
5252

5353
[[EarlGrey selectElementWithMatcher:grey_allOf(grey_scrollView(),
5454
grey_kindOfClass([UITableView class]), nil)]
55-
performAction:grey_scrollToContentEdge(kGREYContentEdgeTop)];
55+
performAction:grey_scrollToContentEdge(kGREYContentEdgeTop)];
5656
}
5757

5858
#pragma mark - Tests
@@ -148,8 +148,7 @@ - (void)testSignInWithInvalidBYOAuthToken {
148148

149149
[[EarlGrey selectElementWithMatcher:grey_text(@"Done")] performAction:grey_tap()];
150150

151-
NSString *invalidTokenErrorMessage =
152-
@"The custom token format is incorrect. Please check the documentation.";
151+
NSString *invalidTokenErrorMessage = @"Sign-In Error";
153152

154153
[self waitForElementWithText:invalidTokenErrorMessage withDelay:kWaitForElementTimeOut];
155154

@@ -182,4 +181,5 @@ - (void)waitForElementWithText:(NSString *)text withDelay:(NSTimeInterval)maxDel
182181
}];
183182
GREYAssertTrue([displayed waitWithTimeout:maxDelay], @"Failed to wait for element '%@'.", text);
184183
}
184+
185185
@end

Example/Auth/Sample/MainViewController.m

Lines changed: 82 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@
3939
#import "UserInfoViewController.h"
4040
#import "UserTableViewCell.h"
4141

42+
#import "FIRAuth_Internal.h"
43+
#import "FIRAuthAPNSToken.h"
44+
#import "FIRAuthAPNSTokenManager.h"
45+
#import "FIRAuthAppCredential.h"
46+
#import "FIRAuthAppCredentialManager.h"
47+
#import "FIRAuthBackend.h"
48+
#import "FIRVerifyClientRequest.h"
49+
#import "FIRVerifyClientResponse.h"
50+
#import "FIRSendVerificationCodeRequest.h"
51+
4252
NS_ASSUME_NONNULL_BEGIN
4353

4454
/** @typedef textInputCompletionBlock
@@ -578,6 +588,11 @@
578588
*/
579589
static NSString *const kPhoneNumberSignInReCaptchaTitle = @"Sign in With Phone Number";
580590

591+
/** @var kVerifyIOSClientTitle
592+
@brief The title for button to verify iOS client.
593+
*/
594+
static NSString *const kVerifyIOSClientTitle = @"Verify iOS client";
595+
581596
/** @var kIsNewUserToggleTitle
582597
@brief The title for button to enable new or existing user toggle.
583598
*/
@@ -741,6 +756,8 @@ - (void)updateTable {
741756
action:^{
742757
[weakSelf unlinkFromProvider:FIRPhoneAuthProviderID completion:nil];
743758
}],
759+
[StaticContentTableViewCell cellWithTitle:kVerifyIOSClientTitle
760+
action:^{ [weakSelf verifyIOSClient]; }],
744761
]],
745762
[StaticContentTableViewSection sectionWithTitle:kSectionTitleSignIn cells:@[
746763
[StaticContentTableViewCell cellWithTitle:kSwitchToInMemoryUserTitle
@@ -1605,17 +1622,19 @@ - (void)removeIDTokenListener {
16051622
@param string The string to add to the console.
16061623
*/
16071624
- (void)log:(NSString *)string {
1608-
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
1609-
dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
1610-
NSString *date = [dateFormatter stringFromDate:[NSDate date]];
1611-
if (!_consoleString) {
1612-
_consoleString = [NSMutableString string];
1613-
}
1614-
[_consoleString appendString:[NSString stringWithFormat:@"%@ %@\n", date, string]];
1615-
_consoleTextView.text = _consoleString;
1625+
dispatch_async(dispatch_get_main_queue(), ^{
1626+
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
1627+
dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
1628+
NSString *date = [dateFormatter stringFromDate:[NSDate date]];
1629+
if (!_consoleString) {
1630+
_consoleString = [NSMutableString string];
1631+
}
1632+
[_consoleString appendString:[NSString stringWithFormat:@"%@ %@\n", date, string]];
1633+
_consoleTextView.text = _consoleString;
16161634

1617-
CGRect targetRect = CGRectMake(0, _consoleTextView.contentSize.height - 1, 1, 1);
1618-
[_consoleTextView scrollRectToVisible:targetRect animated:YES];
1635+
CGRect targetRect = CGRectMake(0, _consoleTextView.contentSize.height - 1, 1, 1);
1636+
[_consoleTextView scrollRectToVisible:targetRect animated:YES];
1637+
});
16191638
}
16201639

16211640
/** @fn logSuccess:
@@ -2885,6 +2904,59 @@ - (void)signInWithPhoneNumber:(NSString *_Nullable)phoneNumber
28852904
}];
28862905
}
28872906

2907+
/** @fn verifyIOSClient
2908+
@brief Trigger verify iOS client by sending a verification code to the test number.
2909+
*/
2910+
- (void)verifyIOSClient {
2911+
[[AppManager auth].tokenManager getTokenWithCallback:^(FIRAuthAPNSToken *_Nullable token,
2912+
NSError *_Nullable error) {
2913+
if (!token) {
2914+
[self logFailure:@"Verify iOS client failed." error:error];
2915+
return;
2916+
}
2917+
FIRVerifyClientRequest *request =
2918+
[[FIRVerifyClientRequest alloc] initWithAppToken:token.string
2919+
isSandbox:token.type == FIRAuthAPNSTokenTypeSandbox
2920+
requestConfiguration:[AppManager auth].requestConfiguration];
2921+
[FIRAuthBackend verifyClient:request callback:^(FIRVerifyClientResponse *_Nullable response,
2922+
NSError *_Nullable error) {
2923+
if (error) {
2924+
[self logFailure:@"Verify iOS client failed." error:error];
2925+
return;
2926+
}
2927+
NSTimeInterval timeout = [response.suggestedTimeOutDate timeIntervalSinceNow];
2928+
[[AppManager auth].appCredentialManager
2929+
didStartVerificationWithReceipt:response.receipt
2930+
timeout:timeout
2931+
callback:^(FIRAuthAppCredential *credential) {
2932+
if (!credential.secret) {
2933+
[self logFailure:@"Failed to receive remote notification to verify app identity."
2934+
error:error];
2935+
return;
2936+
}
2937+
NSString *testPhoneNumber = @"+16509964692";
2938+
FIRSendVerificationCodeRequest *request =
2939+
[[FIRSendVerificationCodeRequest alloc] initWithPhoneNumber:testPhoneNumber
2940+
appCredential:credential
2941+
reCAPTCHAToken:nil
2942+
requestConfiguration:
2943+
[AppManager auth].requestConfiguration];
2944+
[FIRAuthBackend sendVerificationCode:request
2945+
callback:^(FIRSendVerificationCodeResponse *_Nullable response,
2946+
NSError *_Nullable error) {
2947+
if (error) {
2948+
[self logFailure:@"Verify iOS client failed." error:error];
2949+
return;
2950+
} else {
2951+
[self logSuccess:@"Verify iOS client succeeded."];
2952+
[self showMessagePrompt:@"Verify iOS client succeed."];
2953+
}
2954+
}];
2955+
}];
2956+
}];
2957+
}];
2958+
}
2959+
28882960
/** @fn signInWithPhoneNumberWithPrompt
28892961
@brief Allows sign in with phone number via popup prompt.
28902962
*/

Example/Firebase.xcodeproj/project.pbxproj

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@
116116
0672F2F31EBBA7D900818E87 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 0672F2F11EBBA7D900818E87 /* GoogleService-Info.plist */; };
117117
069428831EC3B38C00F7BC69 /* 1mb.dat in Resources */ = {isa = PBXBuildFile; fileRef = 069428801EC3B35A00F7BC69 /* 1mb.dat */; };
118118
06C24A061EC39BCB005208CA /* FIRStorageIntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 06121ECA1EC39A0B0008D70E /* FIRStorageIntegrationTests.m */; };
119+
409E1130219FA260000E6CFC /* FIRVerifyIOSClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 409E112F219FA260000E6CFC /* FIRVerifyIOSClientTests.m */; };
119120
7E9485421F578AC4005A3939 /* FIRAuthURLPresenterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E94853F1F578A9D005A3939 /* FIRAuthURLPresenterTests.m */; };
120121
7EE21F7A1FE89193009B1370 /* FIREmailLinkRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EE21F791FE89193009B1370 /* FIREmailLinkRequestTests.m */; };
121122
7EE21F7C1FE8919E009B1370 /* FIREmailLinkSignInResponseTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EE21F7B1FE8919D009B1370 /* FIREmailLinkSignInResponseTests.m */; };
@@ -947,6 +948,7 @@
947948
069428801EC3B35A00F7BC69 /* 1mb.dat */ = {isa = PBXFileReference; lastKnownFileType = file; path = 1mb.dat; sourceTree = "<group>"; };
948949
0697B1201EC13D8A00542174 /* Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Base64.h; sourceTree = "<group>"; };
949950
0697B1211EC13D8A00542174 /* Base64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Base64.m; sourceTree = "<group>"; };
951+
409E112F219FA260000E6CFC /* FIRVerifyIOSClientTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FIRVerifyIOSClientTests.m; sourceTree = "<group>"; };
950952
6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
951953
6003F58F195388D20070C39A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
952954
6003F591195388D20070C39A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
@@ -2017,6 +2019,7 @@
20172019
isa = PBXGroup;
20182020
children = (
20192021
DE26D1FA1F70333E004AE1D3 /* FirebaseAuthEarlGreyTests.m */,
2022+
409E112F219FA260000E6CFC /* FIRVerifyIOSClientTests.m */,
20202023
DE26D1FB1F70333E004AE1D3 /* Info.plist */,
20212024
);
20222025
path = EarlGreyTests;
@@ -4181,6 +4184,7 @@
41814184
buildActionMask = 2147483647;
41824185
files = (
41834186
DE26D2771F705CB5004AE1D3 /* FirebaseAuthEarlGreyTests.m in Sources */,
4187+
409E1130219FA260000E6CFC /* FIRVerifyIOSClientTests.m in Sources */,
41844188
);
41854189
runOnlyForDeploymentPostprocessing = 0;
41864190
};
@@ -6033,7 +6037,7 @@
60336037
"\"${PODS_ROOT}/Headers/Public\"",
60346038
"\"${PODS_ROOT}/Headers/Public/FirebaseInstanceID\"",
60356039
"\"${PODS_ROOT}/Headers/Public/GoogleSignIn\"",
6036-
"\"${PODS_ROOT}/../../Firebase/Auth/Source\"",
6040+
"\"${PODS_ROOT}/../../Firebase/Auth/Source\"/**",
60376041
);
60386042
INFOPLIST_FILE = Auth/Sample/Application.plist;
60396043
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
@@ -6072,7 +6076,7 @@
60726076
"\"${PODS_ROOT}/Headers/Public\"",
60736077
"\"${PODS_ROOT}/Headers/Public/FirebaseInstanceID\"",
60746078
"\"${PODS_ROOT}/Headers/Public/GoogleSignIn\"",
6075-
"\"${PODS_ROOT}/../../Firebase/Auth/Source\"",
6079+
"\"${PODS_ROOT}/../../Firebase/Auth/Source\"/**",
60766080
);
60776081
INFOPLIST_FILE = Auth/Sample/Application.plist;
60786082
IPHONEOS_DEPLOYMENT_TARGET = 8.0;

Example/Firebase.xcodeproj/xcshareddata/xcschemes/Auth_Sample.xcscheme

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,26 +26,25 @@
2626
buildConfiguration = "Debug"
2727
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
2828
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29-
language = ""
3029
shouldUseLaunchSchemeArgsEnv = "YES">
3130
<Testables>
3231
<TestableReference
3332
skipped = "NO">
3433
<BuildableReference
3534
BuildableIdentifier = "primary"
36-
BlueprintIdentifier = "DE26D25C1F7049F1004AE1D3"
37-
BuildableName = "Auth_ApiTests.xctest"
38-
BlueprintName = "Auth_ApiTests"
35+
BlueprintIdentifier = "DE26D26C1F705C35004AE1D3"
36+
BuildableName = "Auth_EarlGreyTests.xctest"
37+
BlueprintName = "Auth_EarlGreyTests"
3938
ReferencedContainer = "container:Firebase.xcodeproj">
4039
</BuildableReference>
4140
</TestableReference>
4241
<TestableReference
4342
skipped = "NO">
4443
<BuildableReference
4544
BuildableIdentifier = "primary"
46-
BlueprintIdentifier = "DE26D26C1F705C35004AE1D3"
47-
BuildableName = "Auth_EarlGreyTests.xctest"
48-
BlueprintName = "Auth_EarlGreyTests"
45+
BlueprintIdentifier = "DE26D25C1F7049F1004AE1D3"
46+
BuildableName = "Auth_ApiTests.xctest"
47+
BlueprintName = "Auth_ApiTests"
4948
ReferencedContainer = "container:Firebase.xcodeproj">
5049
</BuildableReference>
5150
</TestableReference>
@@ -66,7 +65,6 @@
6665
buildConfiguration = "Debug"
6766
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
6867
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
69-
language = ""
7068
launchStyle = "0"
7169
useCustomWorkingDirectory = "NO"
7270
ignoresPersistentStateOnLaunch = "NO"

Firebase/Auth/Source/Public/FIRPhoneAuthProvider.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ extern NSString *const FIRPhoneAuthProviderID NS_SWIFT_NAME(PhoneAuthProviderID)
3232
*/
3333
extern NSString *const _Nonnull FIRPhoneAuthSignInMethod NS_SWIFT_NAME(PhoneAuthSignInMethod);
3434

35-
3635
/** @typedef FIRVerificationResultCallback
3736
@brief The type of block invoked when a request to send a verification code has finished.
3837

0 commit comments

Comments
 (0)