FacebookAuthTests.m 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. * Copyright 2019 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. #import <XCTest/XCTest.h>
  17. #import "FIRAuthApiTestsBase.h"
  18. /** Facebook app access token that will be used for Facebook Graph API, which is different from
  19. * account access token.
  20. */
  21. static NSString *const kFacebookAppAccessToken = KFACEBOOK_APP_ACCESS_TOKEN;
  22. /** Facebook app ID that will be used for Facebook Graph API. */
  23. static NSString *const kFacebookAppID = KFACEBOOK_APP_ID;
  24. static NSString *const kFacebookGraphApiAuthority = @"graph.facebook.com";
  25. static NSString *const kFacebookTestAccountName = KFACEBOOK_USER_NAME;
  26. @interface FacebookAuthTests : FIRAuthApiTestsBase
  27. @end
  28. @implementation FacebookAuthTests
  29. - (void)testSignInWithFaceboook {
  30. FIRAuth *auth = [FIRAuth auth];
  31. if (!auth) {
  32. XCTFail(@"Could not obtain auth object.");
  33. }
  34. NSDictionary *userInfoDict = [self createFacebookTestingAccount];
  35. NSString *facebookAccessToken = userInfoDict[@"access_token"];
  36. NSLog(@"Facebook testing account access token is: %@", facebookAccessToken);
  37. NSString *facebookAccountId = userInfoDict[@"id"];
  38. NSLog(@"Facebook testing account id is: %@", facebookAccountId);
  39. FIRAuthCredential *credential =
  40. [FIRFacebookAuthProvider credentialWithAccessToken:facebookAccessToken];
  41. XCTestExpectation *expectation = [self expectationWithDescription:@"Facebook sign-in finished."];
  42. [auth signInWithCredential:credential
  43. completion:^(FIRAuthDataResult *result, NSError *error) {
  44. if (error) {
  45. NSLog(@"Facebook sign in error: %@", error);
  46. }
  47. [expectation fulfill];
  48. }];
  49. [self waitForExpectationsWithTimeout:kExpectationsTimeout
  50. handler:^(NSError *error) {
  51. if (error != nil) {
  52. XCTFail(@"Failed to wait for expectations "
  53. @"in Facebook sign in. Error: %@",
  54. error.localizedDescription);
  55. }
  56. }];
  57. XCTAssertEqualObjects(auth.currentUser.displayName, kFacebookTestAccountName);
  58. // Clean up the created Firebase/Facebook user for future runs.
  59. [self deleteCurrentUser];
  60. [self deleteFacebookTestingAccountbyId:facebookAccountId];
  61. }
  62. - (void)testLinkAnonymousAccountToFacebookAccount {
  63. FIRAuth *auth = [FIRAuth auth];
  64. if (!auth) {
  65. XCTFail(@"Could not obtain auth object.");
  66. }
  67. [self signInAnonymously];
  68. NSDictionary *userInfoDict = [self createFacebookTestingAccount];
  69. NSString *facebookAccessToken = userInfoDict[@"access_token"];
  70. NSLog(@"Facebook testing account access token is: %@", facebookAccessToken);
  71. NSString *facebookAccountId = userInfoDict[@"id"];
  72. NSLog(@"Facebook testing account id is: %@", facebookAccountId);
  73. FIRAuthCredential *credential =
  74. [FIRFacebookAuthProvider credentialWithAccessToken:facebookAccessToken];
  75. XCTestExpectation *expectation = [self expectationWithDescription:@"Facebook linking finished."];
  76. [auth.currentUser linkWithCredential:credential
  77. completion:^(FIRAuthDataResult *result, NSError *error) {
  78. if (error) {
  79. NSLog(@"Link to Facebook error: %@", error);
  80. }
  81. [expectation fulfill];
  82. }];
  83. [self waitForExpectationsWithTimeout:kExpectationsTimeout
  84. handler:^(NSError *error) {
  85. if (error != nil) {
  86. XCTFail(@"Failed to wait for expectations "
  87. @"in linking to Facebook. Error: %@",
  88. error.localizedDescription);
  89. }
  90. }];
  91. NSArray<id<FIRUserInfo>> *providerData = auth.currentUser.providerData;
  92. XCTAssertEqual([providerData count], 1);
  93. XCTAssertEqualObjects([providerData[0] providerID], @"facebook.com");
  94. // Clean up the created Firebase/Facebook user for future runs.
  95. [self deleteCurrentUser];
  96. [self deleteFacebookTestingAccountbyId:facebookAccountId];
  97. }
  98. /** Creates a Facebook testing account using Facebook Graph API and return a dictionary that
  99. * constains "id", "access_token", "login_url", "email" and "password" of the created account.
  100. */
  101. - (NSDictionary *)createFacebookTestingAccount {
  102. // Build the URL.
  103. NSString *urltoCreateTestUser =
  104. [NSString stringWithFormat:@"https://%@/%@/accounts/test-users", kFacebookGraphApiAuthority,
  105. kFacebookAppID];
  106. // Build the POST request.
  107. NSString *bodyString =
  108. [NSString stringWithFormat:@"installed=true&name=%@&permissions=read_stream&access_token=%@",
  109. kFacebookTestAccountName, kFacebookAppAccessToken];
  110. NSData *postData = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
  111. GTMSessionFetcherService *service = [[GTMSessionFetcherService alloc] init];
  112. GTMSessionFetcher *fetcher = [service fetcherWithURLString:urltoCreateTestUser];
  113. fetcher.bodyData = postData;
  114. [fetcher setRequestValue:@"text/plain" forHTTPHeaderField:@"Content-Type"];
  115. XCTestExpectation *expectation =
  116. [self expectationWithDescription:@"Creating Facebook account finished."];
  117. __block NSData *data = nil;
  118. [fetcher beginFetchWithCompletionHandler:^(NSData *receivedData, NSError *error) {
  119. if (error) {
  120. NSLog(@"Creating Facebook account finished with error: %@", error);
  121. return;
  122. }
  123. data = receivedData;
  124. [expectation fulfill];
  125. }];
  126. [self waitForExpectationsWithTimeout:kExpectationsTimeout
  127. handler:^(NSError *error) {
  128. if (error != nil) {
  129. XCTFail(@"Failed to wait for expectations "
  130. @"in creating Facebook account. Error: %@",
  131. error.localizedDescription);
  132. }
  133. }];
  134. // Parses the access token from the JSON data.
  135. NSDictionary *userInfoDict = [NSJSONSerialization JSONObjectWithData:data
  136. options:kNilOptions
  137. error:nil];
  138. return userInfoDict;
  139. }
  140. /** Delete a Facebook testing account by account Id using Facebook Graph API. */
  141. - (void)deleteFacebookTestingAccountbyId:(NSString *)accountId {
  142. // Build the URL.
  143. NSString *urltoDeleteTestUser =
  144. [NSString stringWithFormat:@"https://%@/%@", kFacebookGraphApiAuthority, accountId];
  145. // Build the POST request.
  146. NSString *bodyString =
  147. [NSString stringWithFormat:@"method=delete&access_token=%@", kFacebookAppAccessToken];
  148. NSData *postData = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
  149. GTMSessionFetcherService *service = [[GTMSessionFetcherService alloc] init];
  150. GTMSessionFetcher *fetcher = [service fetcherWithURLString:urltoDeleteTestUser];
  151. fetcher.bodyData = postData;
  152. [fetcher setRequestValue:@"text/plain" forHTTPHeaderField:@"Content-Type"];
  153. XCTestExpectation *expectation =
  154. [self expectationWithDescription:@"Deleting Facebook account finished."];
  155. [fetcher beginFetchWithCompletionHandler:^(NSData *receivedData, NSError *error) {
  156. NSString *deleteResult = [[NSString alloc] initWithData:receivedData
  157. encoding:NSUTF8StringEncoding];
  158. NSLog(@"The result of deleting Facebook account is: %@", deleteResult);
  159. if (error) {
  160. NSLog(@"Deleting Facebook account finished with error: %@", error);
  161. }
  162. [expectation fulfill];
  163. }];
  164. [self waitForExpectationsWithTimeout:kExpectationsTimeout
  165. handler:^(NSError *error) {
  166. if (error != nil) {
  167. XCTFail(@"Failed to wait for expectations "
  168. @"in deleting Facebook account. Error: %@",
  169. error.localizedDescription);
  170. }
  171. }];
  172. }
  173. @end