Skip to content

Commit 4dc63f8

Browse files
authored
Fix Firestore tests for M22 (firebase#834)
* Add FIRFirestoreTests to the Firestore Xcode project * Avoid waitForExpectations:timeout: This API was added in Xcode 8.3, but we still build production releases with Xcode 8.2. waitForExpectationsWithTimeout:handler: is available from Xcode 7.2. * Add AppForUnitTesting Add a utility for constructing a Firebase App for testing. * Handle the nil UID from FIRAuth * Avoid running CMake tests twice * Only build app_testing on Apple platforms * Revise test.sh messages
1 parent 935f3ca commit 4dc63f8

File tree

15 files changed

+227
-79
lines changed

15 files changed

+227
-79
lines changed

Firestore/Example/Firestore.xcodeproj/project.pbxproj

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
/* Begin PBXBuildFile section */
2626
3B843E4C1F3A182900548890 /* remote_store_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 3B843E4A1F3930A400548890 /* remote_store_spec_test.json */; };
2727
5436F32420008FAD006E51E3 /* string_printf_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5436F32320008FAD006E51E3 /* string_printf_test.cc */; };
28+
5467FB01203E5717009C9584 /* FIRFirestoreTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5467FAFF203E56F8009C9584 /* FIRFirestoreTests.mm */; };
29+
5467FB08203E6A44009C9584 /* app_testing.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5467FB07203E6A44009C9584 /* app_testing.mm */; };
2830
54740A571FC914BA00713A1A /* secure_random_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54740A531FC913E500713A1A /* secure_random_test.cc */; };
2931
54740A581FC914F000713A1A /* autoid_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54740A521FC913E500713A1A /* autoid_test.cc */; };
3032
54764FAF1FAA21B90085E60A /* FSTGoogleTestTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 54764FAE1FAA21B90085E60A /* FSTGoogleTestTests.mm */; };
@@ -216,6 +218,9 @@
216218
42491D7DC8C8CD245CC22B93 /* Pods-SwiftBuildTest.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftBuildTest.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SwiftBuildTest/Pods-SwiftBuildTest.debug.xcconfig"; sourceTree = "<group>"; };
217219
4EBC5F5ABE1FD097EFE5E224 /* Pods-Firestore_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-Firestore_Example/Pods-Firestore_Example.release.xcconfig"; sourceTree = "<group>"; };
218220
5436F32320008FAD006E51E3 /* string_printf_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = string_printf_test.cc; path = ../../core/test/firebase/firestore/util/string_printf_test.cc; sourceTree = "<group>"; };
221+
5467FAFF203E56F8009C9584 /* FIRFirestoreTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FIRFirestoreTests.mm; sourceTree = "<group>"; };
222+
5467FB06203E6A44009C9584 /* app_testing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = app_testing.h; path = ../../core/test/firebase/firestore/testutil/app_testing.h; sourceTree = "<group>"; };
223+
5467FB07203E6A44009C9584 /* app_testing.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = app_testing.mm; path = ../../core/test/firebase/firestore/testutil/app_testing.mm; sourceTree = "<group>"; };
219224
54740A521FC913E500713A1A /* autoid_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = autoid_test.cc; path = ../../core/test/firebase/firestore/util/autoid_test.cc; sourceTree = "<group>"; };
220225
54740A531FC913E500713A1A /* secure_random_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = secure_random_test.cc; path = ../../core/test/firebase/firestore/util/secure_random_test.cc; sourceTree = "<group>"; };
221226
54764FAE1FAA21B90085E60A /* FSTGoogleTestTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = FSTGoogleTestTests.mm; path = GoogleTest/FSTGoogleTestTests.mm; sourceTree = "<group>"; };
@@ -429,6 +434,15 @@
429434
/* End PBXFrameworksBuildPhase section */
430435

431436
/* Begin PBXGroup section */
437+
5467FB05203E652F009C9584 /* testutil */ = {
438+
isa = PBXGroup;
439+
children = (
440+
5467FB06203E6A44009C9584 /* app_testing.h */,
441+
5467FB07203E6A44009C9584 /* app_testing.mm */,
442+
);
443+
name = testutil;
444+
sourceTree = "<group>";
445+
};
432446
54740A561FC913EB00713A1A /* util */ = {
433447
isa = PBXGroup;
434448
children = (
@@ -452,6 +466,7 @@
452466
AB380CF7201937B800D97691 /* core */,
453467
54EB764B202277970088B8F3 /* immutable */,
454468
AB356EF5200E9D1A0089B766 /* model */,
469+
5467FB05203E652F009C9584 /* testutil */,
455470
54740A561FC913EB00713A1A /* util */,
456471
54764FAE1FAA21B90085E60A /* FSTGoogleTestTests.mm */,
457472
AB7BAB332012B519001E0872 /* geo_point_test.cc */,
@@ -697,16 +712,17 @@
697712
DE51B1831F0D48AC0013853F /* API */ = {
698713
isa = PBXGroup;
699714
children = (
700-
B65D34A7203C99090076A5E1 /* FIRTimestampTest.m */,
701715
5492E045202154AA00B64F25 /* FIRCollectionReferenceTests.mm */,
702716
5492E049202154AA00B64F25 /* FIRDocumentReferenceTests.mm */,
703717
5492E04B202154AA00B64F25 /* FIRDocumentSnapshotTests.mm */,
704718
5492E04C202154AA00B64F25 /* FIRFieldPathTests.mm */,
705719
5492E04A202154AA00B64F25 /* FIRFieldValueTests.mm */,
720+
5467FAFF203E56F8009C9584 /* FIRFirestoreTests.mm */,
706721
5492E048202154AA00B64F25 /* FIRGeoPointTests.mm */,
707722
5492E04F202154AA00B64F25 /* FIRQuerySnapshotTests.mm */,
708723
5492E046202154AA00B64F25 /* FIRQueryTests.mm */,
709724
5492E04D202154AA00B64F25 /* FIRSnapshotMetadataTests.mm */,
725+
B65D34A7203C99090076A5E1 /* FIRTimestampTest.m */,
710726
5492E047202154AA00B64F25 /* FSTAPIHelpers.h */,
711727
5492E04E202154AA00B64F25 /* FSTAPIHelpers.mm */,
712728
);
@@ -1301,6 +1317,7 @@
13011317
54740A581FC914F000713A1A /* autoid_test.cc in Sources */,
13021318
548DB927200D590300E00ABC /* assert_test.cc in Sources */,
13031319
5492E0A62021552D00B64F25 /* FSTPersistenceTestHelpers.mm in Sources */,
1320+
5467FB01203E5717009C9584 /* FIRFirestoreTests.mm in Sources */,
13041321
5492E0A12021552D00B64F25 /* FSTMemoryLocalStoreTests.mm in Sources */,
13051322
5436F32420008FAD006E51E3 /* string_printf_test.cc in Sources */,
13061323
5492E067202154B900B64F25 /* FSTEventManagerTests.mm in Sources */,
@@ -1334,6 +1351,7 @@
13341351
5492E065202154B900B64F25 /* FSTViewTests.mm in Sources */,
13351352
5492E03C2021401F00B64F25 /* XCTestCase+Await.mm in Sources */,
13361353
B6152AD7202A53CB000E5744 /* document_key_test.cc in Sources */,
1354+
5467FB08203E6A44009C9584 /* app_testing.mm in Sources */,
13371355
54764FAF1FAA21B90085E60A /* FSTGoogleTestTests.mm in Sources */,
13381356
AB380D04201BC6E400D97691 /* ordered_code_test.cc in Sources */,
13391357
5492E03F2021401F00B64F25 /* FSTHelpers.mm in Sources */,

Firestore/Example/Firestore.xcodeproj/xcshareddata/xcschemes/Firestore_Tests.xcscheme

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@
77
buildImplicitDependencies = "YES">
88
<BuildActionEntries>
99
<BuildActionEntry
10+
buildForTesting = "YES"
1011
buildForRunning = "YES"
11-
buildForTesting = "YES">
12+
buildForProfiling = "YES"
13+
buildForArchiving = "YES"
14+
buildForAnalyzing = "YES">
1215
<BuildableReference
1316
BuildableIdentifier = "primary"
1417
BlueprintIdentifier = "6003F5AD195388D20070C39A"
@@ -51,6 +54,15 @@
5154
debugDocumentVersioning = "YES"
5255
debugServiceExtension = "internal"
5356
allowLocationSimulation = "YES">
57+
<MacroExpansion>
58+
<BuildableReference
59+
BuildableIdentifier = "primary"
60+
BlueprintIdentifier = "6003F5AD195388D20070C39A"
61+
BuildableName = "Firestore_Tests.xctest"
62+
BlueprintName = "Firestore_Tests"
63+
ReferencedContainer = "container:Firestore.xcodeproj">
64+
</BuildableReference>
65+
</MacroExpansion>
5466
<AdditionalOptions>
5567
</AdditionalOptions>
5668
</LaunchAction>

Firestore/Example/Tests/API/FIRFirestoreTests.mm

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,21 @@
2020

2121
#import <XCTest/XCTest.h>
2222

23+
#include "Firestore/core/test/firebase/firestore/testutil/app_testing.h"
24+
25+
namespace testutil = firebase::firestore::testutil;
26+
2327
@interface FIRFirestoreTests : XCTestCase
2428
@end
2529

2630
@implementation FIRFirestoreTests
2731

2832
- (void)testDeleteApp {
29-
// Create a FIRApp for testing.
30-
NSString *appName = @"custom_app_name";
31-
FIROptions *options =
32-
[[FIROptions alloc] initWithGoogleAppID:@"1:123:ios:123ab" GCMSenderID:@"gcm_sender_id"];
33-
options.projectID = @"project_id";
34-
[FIRApp configureWithName:appName options:options];
35-
3633
// Ensure the app is set appropriately.
37-
FIRApp *app = [FIRApp appNamed:appName];
34+
FIRApp *app = testutil::AppForUnitTesting();
35+
NSString *appName = app.name;
36+
FIROptions *options = app.options;
37+
3838
FIRFirestore *firestore = [FIRFirestore firestoreForApp:app];
3939
XCTAssertEqualObjects(firestore.app, app);
4040

@@ -56,7 +56,10 @@ - (void)testDeleteApp {
5656
[defaultAppDeletedExpectation fulfill];
5757
}];
5858

59-
[self waitForExpectations:@[ defaultAppDeletedExpectation ] timeout:2];
59+
[self waitForExpectationsWithTimeout:2
60+
handler:^(NSError *_Nullable error) {
61+
XCTAssertNil(error);
62+
}];
6063
}
6164

6265
@end

Firestore/Example/Tests/SpecTests/FSTSpecTests.mm

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -332,12 +332,10 @@ - (void)doEnableNetwork {
332332
}
333333

334334
- (void)doChangeUser:(id)UID {
335-
if (UID == nil || [UID isEqual:[NSNull null]]) {
336-
[self.driver changeUser:User::Unauthenticated()];
337-
} else {
338-
XCTAssert([UID isKindOfClass:[NSString class]]);
339-
[self.driver changeUser:User(UID)];
335+
if ([UID isEqual:[NSNull null]]) {
336+
UID = nil;
340337
}
338+
[self.driver changeUser:User::FromUid(UID)];
341339
}
342340

343341
- (void)doRestart {

Firestore/Source/Auth/FSTCredentialsProvider.mm

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ - (instancetype)initWithApp:(FIRApp *)app {
6262
self = [super init];
6363
if (self) {
6464
_app = app;
65-
_currentUser = User([self.app getUID]);
65+
_currentUser = User::FromUid([self.app getUID]);
6666
_userCounter = 0;
6767

6868
// Register for user changes so that we can internally track the current user.
@@ -84,8 +84,8 @@ - (instancetype)initWithApp:(FIRApp *)app {
8484
return;
8585
}
8686

87-
NSString *userID = userInfo[FIRAuthStateDidChangeInternalNotificationUIDKey];
88-
User newUser = User(userID);
87+
NSString *uid = userInfo[FIRAuthStateDidChangeInternalNotificationUIDKey];
88+
User newUser = User::FromUid(uid);
8989
if (newUser != self->_currentUser) {
9090
self->_currentUser = newUser;
9191
self.userCounter++;

Firestore/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ add_subdirectory(src/firebase/firestore/model)
2020
add_subdirectory(src/firebase/firestore/remote)
2121
add_subdirectory(src/firebase/firestore/util)
2222

23+
add_subdirectory(test/firebase/firestore/testutil)
2324
add_subdirectory(test/firebase/firestore)
2425
add_subdirectory(test/firebase/firestore/auth)
2526
add_subdirectory(test/firebase/firestore/core)

Firestore/core/src/firebase/firestore/auth/firebase_credentials_provider_apple.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include <memory>
2828
#include <mutex> // NOLINT(build/c++11)
29+
#include <utility>
2930

3031
#include "Firestore/core/src/firebase/firestore/auth/credentials_provider.h"
3132
#include "Firestore/core/src/firebase/firestore/auth/user.h"
@@ -76,8 +77,8 @@ class FirebaseCredentialsProvider : public CredentialsProvider {
7677
* avoid races between notifications arriving and C++ object destruction.
7778
*/
7879
struct Contents {
79-
Contents(FIRApp* app, const absl::string_view uid)
80-
: app(app), current_user(uid), mutex() {
80+
Contents(FIRApp* app, User&& user)
81+
: app(app), current_user(std::move(user)), mutex() {
8182
}
8283

8384
const FIRApp* app;

Firestore/core/src/firebase/firestore/auth/firebase_credentials_provider_apple.mm

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@
2828
namespace auth {
2929

3030
FirebaseCredentialsProvider::FirebaseCredentialsProvider(FIRApp* app)
31-
: contents_(
32-
std::make_shared<Contents>(app, util::MakeStringView([app getUID]))) {
31+
: contents_(std::make_shared<Contents>(app, User::FromUid([app getUID]))) {
3332
std::weak_ptr<Contents> weak_contents = contents_;
3433

3534
auth_listener_handle_ = [[NSNotificationCenter defaultCenter]

Firestore/core/src/firebase/firestore/auth/user.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,6 @@ class User {
4343
/** Construct an authenticated user with the given UID. */
4444
explicit User(const absl::string_view uid);
4545

46-
#if defined(__OBJC__)
47-
explicit User(NSString* uid)
48-
: User(firebase::firestore::util::MakeStringView(uid)) {
49-
}
50-
#endif // defined(__OBJC__)
51-
5246
const std::string& uid() const {
5347
return uid_;
5448
}
@@ -62,6 +56,20 @@ class User {
6256
/** Returns an unauthenticated instance. */
6357
static const User& Unauthenticated();
6458

59+
#if defined(__OBJC__)
60+
/**
61+
* Returns an authenticated user if uid is non-nil, otherwise an
62+
* unauthenticated user.
63+
*/
64+
static User FromUid(NSString* _Nullable uid) {
65+
if (uid == nil) {
66+
return Unauthenticated();
67+
} else {
68+
return User(util::MakeStringView(uid));
69+
}
70+
}
71+
#endif // defined(__OBJC__)
72+
6573
User& operator=(const User& other) = default;
6674

6775
friend bool operator==(const User& lhs, const User& rhs);

Firestore/core/test/firebase/firestore/auth/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,6 @@ if(APPLE)
3030
firebase_credentials_provider_test.mm
3131
DEPENDS
3232
firebase_firestore_auth_apple
33+
firebase_firestore_testutil
3334
)
3435
endif(APPLE)

Firestore/core/test/firebase/firestore/auth/firebase_credentials_provider_test.mm

Lines changed: 28 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -21,74 +21,59 @@
2121
#import <FirebaseCore/FIROptionsInternal.h>
2222

2323
#include "Firestore/core/src/firebase/firestore/util/string_apple.h"
24+
#include "Firestore/core/test/firebase/firestore/testutil/app_testing.h"
2425

2526
#include "gtest/gtest.h"
2627

2728
namespace firebase {
2829
namespace firestore {
2930
namespace auth {
3031

31-
// TODO(zxu123): Make this an integration test and get infos from environment.
32-
// Set a .plist file here to enable the test-case.
33-
static NSString* const kPlist = @"";
34-
35-
class FirebaseCredentialsProviderTest : public ::testing::Test {
36-
protected:
37-
void SetUp() override {
38-
app_ready_ = false;
39-
if (![kPlist hasSuffix:@".plist"]) {
40-
return;
41-
}
42-
43-
static dispatch_once_t once_token;
44-
dispatch_once(&once_token, ^{
45-
FIROptions* options = [[FIROptions alloc] initWithContentsOfFile:kPlist];
46-
[FIRApp configureWithOptions:options];
47-
});
32+
FIRApp* AppWithFakeUid(NSString* _Nullable uid) {
33+
FIRApp* app = testutil::AppForUnitTesting();
34+
app.getUIDImplementation = ^NSString* {
35+
return uid;
36+
};
37+
return app;
38+
}
4839

49-
// Set getUID implementation.
50-
FIRApp* default_app = [FIRApp defaultApp];
51-
default_app.getUIDImplementation = ^NSString* {
52-
return @"I'm a fake uid.";
53-
};
54-
app_ready_ = true;
55-
}
40+
TEST(FirebaseCredentialsProviderTest, GetTokenUnauthenticated) {
41+
FIRApp* app = AppWithFakeUid(nil);
5642

57-
bool app_ready_;
58-
};
43+
FirebaseCredentialsProvider credentials_provider(app);
44+
credentials_provider.GetToken(
45+
/*force_refresh=*/true, [](Token token, const absl::string_view error) {
46+
EXPECT_EQ("", token.token());
47+
const User& user = token.user();
48+
EXPECT_EQ("", user.uid());
49+
EXPECT_FALSE(user.is_authenticated());
50+
EXPECT_EQ("", error) << error;
51+
});
52+
}
5953

60-
// Set kPlist above before enable.
61-
TEST_F(FirebaseCredentialsProviderTest, GetToken) {
62-
if (!app_ready_) {
63-
return;
64-
}
54+
TEST(FirebaseCredentialsProviderTest, GetToken) {
55+
FIRApp* app = AppWithFakeUid(@"fake uid");
6556

66-
FirebaseCredentialsProvider credentials_provider([FIRApp defaultApp]);
57+
FirebaseCredentialsProvider credentials_provider(app);
6758
credentials_provider.GetToken(
6859
/*force_refresh=*/true, [](Token token, const absl::string_view error) {
6960
EXPECT_EQ("", token.token());
7061
const User& user = token.user();
71-
EXPECT_EQ("I'm a fake uid.", user.uid());
62+
EXPECT_EQ("fake uid", user.uid());
7263
EXPECT_TRUE(user.is_authenticated());
7364
EXPECT_EQ("", error) << error;
7465
});
7566
}
7667

77-
// Set kPlist above before enable.
78-
TEST_F(FirebaseCredentialsProviderTest, SetListener) {
79-
if (!app_ready_) {
80-
return;
81-
}
68+
TEST(FirebaseCredentialsProviderTest, SetListener) {
69+
FIRApp* app = AppWithFakeUid(@"fake uid");
8270

83-
FirebaseCredentialsProvider credentials_provider([FIRApp defaultApp]);
71+
FirebaseCredentialsProvider credentials_provider(app);
8472
credentials_provider.SetUserChangeListener([](User user) {
85-
EXPECT_EQ("I'm a fake uid.", user.uid());
73+
EXPECT_EQ("fake uid", user.uid());
8674
EXPECT_TRUE(user.is_authenticated());
8775
});
8876

89-
// TODO(wilhuff): We should wait for the above expectations to actually happen
90-
// before continuing.
91-
9277
credentials_provider.SetUserChangeListener(nullptr);
9378
}
9479

0 commit comments

Comments
 (0)