@@ -112,59 +112,149 @@ TEST(TimestampIsNear, Matcher) {
112
112
EXPECT_THAT (firebase::Variant::EmptyString (), Not (TimestampIsNear (0 )));
113
113
}
114
114
115
+
115
116
class FirebaseDatabaseTest : public FirebaseTest {
116
117
public:
117
118
FirebaseDatabaseTest ();
118
119
~FirebaseDatabaseTest () override ;
119
120
121
+ // Called once before all tests.
122
+ static void SetUpTestSuite ();
123
+ // Called once after all tests.
124
+ static void TearDownTestSuite ();
125
+
126
+ // Called at the start of each test.
120
127
void SetUp () override ;
128
+ // Called after each test.
121
129
void TearDown () override ;
122
130
123
131
protected:
124
- // Initialize Firebase App, Firebase Auth, and Firebase Database.
125
- void Initialize ();
126
- // Shut down Firebase Database, Firebase Auth, and Firebase App.
127
- void Terminate ();
132
+ // Initialize Firebase App and Firebase Auth.
133
+ static void InitializeAppAndAuth ();
134
+ // Shut down Firebase App and Firebase Auth.
135
+ static void TerminateAppAndAuth ();
136
+
128
137
// Sign in an anonymous user.
129
- void SignIn ();
138
+ static void SignIn ();
130
139
// Sign out the current user, if applicable.
131
- void SignOut ();
140
+ static void SignOut ();
141
+
142
+ // Initialize Firebase Database.
143
+ void InitializeDatabase ();
144
+ // Shut down Firebase Database.
145
+ void TerminateDatabase ();
132
146
133
147
firebase::database::DatabaseReference CreateWorkingPath (
134
148
bool suppress_cleanup = false );
135
149
150
+ static firebase::App* shared_app_;
151
+ static firebase::auth::Auth* shared_auth_;
152
+
136
153
static bool first_time_;
137
154
138
155
bool initialized_;
139
- firebase::auth::Auth* auth_;
140
156
firebase::database::Database* database_;
141
157
142
158
std::vector<firebase::database::DatabaseReference> cleanup_paths_;
143
159
};
144
160
161
+ // Initialization flow looks like this:
162
+ // - Once, before any tests run:
163
+ // - SetUpTestSuite: Initialize App and Auth. Sign in.
164
+ // - For each test:
165
+ // - SetUp: Initialize Database.
166
+ // - Run the test.
167
+ // - TearDown: Shut down Database.
168
+ // - Once, after all tests are finished:
169
+ // - TearDownTestSuite: Sign out. Shut down Auth and App.
170
+
171
+ firebase::App* FirebaseDatabaseTest::shared_app_;
172
+ firebase::auth::Auth* FirebaseDatabaseTest::shared_auth_;
173
+
145
174
bool FirebaseDatabaseTest::first_time_ = true ;
146
175
176
+ void FirebaseDatabaseTest::SetUpTestSuite () {
177
+ InitializeAppAndAuth ();
178
+ }
179
+
180
+ void FirebaseDatabaseTest::InitializeAppAndAuth () {
181
+ LogDebug (" Initialize Firebase App." );
182
+
183
+ FindFirebaseConfig (FIREBASE_CONFIG_STRING);
184
+
185
+ #if defined(__ANDROID__)
186
+ shared_app_ = ::firebase::App::Create (app_framework::GetJniEnv (),
187
+ app_framework::GetActivity ());
188
+ #else
189
+ shared_app_ = ::firebase::App::Create ();
190
+ #endif // defined(__ANDROID__)
191
+
192
+ ASSERT_NE (shared_app_, nullptr );
193
+
194
+ LogDebug (" Initializing Auth." );
195
+
196
+ // Initialize Firebase Auth.
197
+ ::firebase::ModuleInitializer initializer;
198
+ initializer.Initialize (
199
+ shared_app_, &shared_auth_, [](::firebase::App* app, void * target) {
200
+ LogDebug (" Attempting to initialize Firebase Auth." );
201
+ ::firebase::InitResult result;
202
+ *reinterpret_cast <firebase::auth::Auth**>(target) =
203
+ ::firebase::auth::Auth::GetAuth (app, &result);
204
+ return result;
205
+ });
206
+
207
+ WaitForCompletion (initializer.InitializeLastResult (), " InitializeAuth" );
208
+
209
+ ASSERT_EQ (initializer.InitializeLastResult ().error (), 0 )
210
+ << initializer.InitializeLastResult ().error_message ();
211
+
212
+ LogDebug (" Successfully initialized Auth." );
213
+
214
+ ASSERT_NE (shared_auth_, nullptr );
215
+
216
+ // Sign in anonymously.
217
+ SignIn ();
218
+ }
219
+
220
+ void FirebaseDatabaseTest::TearDownTestSuite () {
221
+ TerminateAppAndAuth ();
222
+ }
223
+
224
+ void FirebaseDatabaseTest::TerminateAppAndAuth () {
225
+ if (shared_auth_) {
226
+ LogDebug (" Signing out." );
227
+ SignOut ();
228
+ LogDebug (" Shutdown Auth." );
229
+ delete shared_auth_;
230
+ shared_auth_ = nullptr ;
231
+ }
232
+ if (shared_app_) {
233
+ LogDebug (" Shutdown App." );
234
+ delete shared_app_;
235
+ shared_app_ = nullptr ;
236
+ }
237
+ }
238
+
147
239
FirebaseDatabaseTest::FirebaseDatabaseTest ()
148
- : initialized_(false ), auth_( nullptr ), database_(nullptr ) {
240
+ : initialized_(false ), database_(nullptr ) {
149
241
FindFirebaseConfig (FIREBASE_CONFIG_STRING);
150
242
}
151
243
152
244
FirebaseDatabaseTest::~FirebaseDatabaseTest () {
153
245
// Must be cleaned up on exit.
154
- assert (app_ == nullptr );
155
- assert (auth_ == nullptr );
156
246
assert (database_ == nullptr );
157
247
}
158
248
159
249
void FirebaseDatabaseTest::SetUp () {
160
250
FirebaseTest::SetUp ();
161
- Initialize ();
251
+ InitializeDatabase ();
162
252
}
163
253
164
254
void FirebaseDatabaseTest::TearDown () {
165
255
// Delete the shared path, if there is one.
166
256
if (initialized_) {
167
- if (!cleanup_paths_.empty () && database_ && app_ ) {
257
+ if (!cleanup_paths_.empty () && database_ && shared_app_ ) {
168
258
LogDebug (" Cleaning up..." );
169
259
std::vector<firebase::Future<void >> cleanups;
170
260
cleanups.reserve (cleanup_paths_.size ());
@@ -177,55 +267,30 @@ void FirebaseDatabaseTest::TearDown() {
177
267
}
178
268
cleanup_paths_.clear ();
179
269
}
180
-
181
- SignOut ();
182
- Terminate ();
183
270
}
184
-
271
+ TerminateDatabase ();
185
272
FirebaseTest::TearDown ();
186
273
}
187
274
188
- void FirebaseDatabaseTest::Initialize () {
189
- if (initialized_) return ;
190
-
191
- InitializeApp ();
192
-
193
- LogDebug (" Initializing Firebase Auth and Firebase Database." );
194
-
195
- // 0th element has a reference to this object, the rest have the initializer
196
- // targets.
197
- void * initialize_targets[] = {&auth_, &database_};
275
+ void FirebaseDatabaseTest::InitializeDatabase () {
276
+ LogDebug (" Initializing Firebase Database." );
198
277
199
- const firebase::ModuleInitializer::InitializerFn initializers[] = {
200
- [](::firebase::App* app, void * data) {
201
- void ** targets = reinterpret_cast <void **>(data);
202
- LogDebug (" Attempting to initialize Firebase Auth." );
203
- ::firebase::InitResult result;
204
- *reinterpret_cast <::firebase::auth::Auth**>(targets[0 ]) =
205
- ::firebase::auth::Auth::GetAuth (app, &result);
206
- return result;
207
- },
208
- [](::firebase::App* app, void * data) {
209
- void ** targets = reinterpret_cast <void **>(data);
278
+ ::firebase::ModuleInitializer initializer;
279
+ initializer.Initialize (
280
+ shared_app_, &database_, [](::firebase::App* app, void * target) {
210
281
LogDebug (" Attempting to initialize Firebase Database." );
211
282
::firebase::InitResult result;
212
- firebase::database::Database* database =
213
- firebase::database::Database::GetInstance (app, &result);
214
- *reinterpret_cast <::firebase::database::Database**>(targets[1 ]) =
215
- database;
283
+ *reinterpret_cast <firebase::database::Database**>(target) =
284
+ firebase::database::Database::GetInstance (app, &result);
216
285
return result;
217
- }};
218
-
219
- ::firebase::ModuleInitializer initializer;
220
- initializer.Initialize (app_, initialize_targets, initializers,
221
- sizeof (initializers) / sizeof (initializers[0 ]));
286
+ });
222
287
223
- WaitForCompletion (initializer.InitializeLastResult (), " Initialize " );
288
+ WaitForCompletion (initializer.InitializeLastResult (), " InitializeDatabase " );
224
289
225
290
ASSERT_EQ (initializer.InitializeLastResult ().error (), 0 )
226
291
<< initializer.InitializeLastResult ().error_message ();
227
292
228
- LogDebug (" Successfully initialized Firebase Auth and Firebase Database." );
293
+ LogDebug (" Successfully initialized Firebase Database." );
229
294
230
295
// The first time we initialize database, enable persistence on mobile.
231
296
// We need to do this here because on iOS you can only enable persistence
@@ -238,31 +303,27 @@ void FirebaseDatabaseTest::Initialize() {
238
303
initialized_ = true ;
239
304
}
240
305
241
- void FirebaseDatabaseTest::Terminate () {
306
+ void FirebaseDatabaseTest::TerminateDatabase () {
242
307
if (!initialized_) return ;
243
308
244
309
if (database_) {
245
310
LogDebug (" Shutdown the Database library." );
246
311
delete database_;
247
312
database_ = nullptr ;
248
313
}
249
- if (auth_) {
250
- LogDebug (" Shutdown the Auth library." );
251
- delete auth_;
252
- auth_ = nullptr ;
253
- }
254
-
255
- TerminateApp ();
256
-
257
314
initialized_ = false ;
258
315
259
316
ProcessEvents (100 );
260
317
}
261
318
262
319
void FirebaseDatabaseTest::SignIn () {
320
+ if (shared_auth_->current_user () != nullptr ) {
321
+ // Already signed in.
322
+ return ;
323
+ }
263
324
LogDebug (" Signing in." );
264
325
firebase::Future<firebase::auth::User*> sign_in_future =
265
- auth_ ->SignInAnonymously ();
326
+ shared_auth_ ->SignInAnonymously ();
266
327
WaitForCompletion (sign_in_future, " SignInAnonymously" );
267
328
if (sign_in_future.error () != 0 ) {
268
329
FAIL () << " Ensure your application has the Anonymous sign-in provider "
@@ -272,22 +333,22 @@ void FirebaseDatabaseTest::SignIn() {
272
333
}
273
334
274
335
void FirebaseDatabaseTest::SignOut () {
275
- if (auth_ == nullptr ) {
336
+ if (shared_auth_ == nullptr ) {
276
337
// Auth is not set up.
277
338
return ;
278
339
}
279
- if (auth_ ->current_user () == nullptr ) {
340
+ if (shared_auth_ ->current_user () == nullptr ) {
280
341
// Already signed out.
281
342
return ;
282
343
}
283
344
284
- auth_ ->SignOut ();
345
+ shared_auth_ ->SignOut ();
285
346
286
347
// Wait for the sign-out to finish.
287
- while (auth_ ->current_user () != nullptr ) {
348
+ while (shared_auth_ ->current_user () != nullptr ) {
288
349
if (ProcessEvents (100 )) break ;
289
350
}
290
- EXPECT_EQ (auth_ ->current_user (), nullptr );
351
+ EXPECT_EQ (shared_auth_ ->current_user (), nullptr );
291
352
}
292
353
293
354
firebase::database::DatabaseReference FirebaseDatabaseTest::CreateWorkingPath (
@@ -306,8 +367,7 @@ TEST_F(FirebaseDatabaseTest, TestInitializeAndTerminate) {
306
367
}
307
368
308
369
TEST_F (FirebaseDatabaseTest, TestSignIn) {
309
- SignIn ();
310
- EXPECT_NE (auth_->current_user (), nullptr );
370
+ EXPECT_NE (shared_auth_->current_user (), nullptr );
311
371
}
312
372
313
373
TEST_F (FirebaseDatabaseTest, TestCreateWorkingPath) {
@@ -456,7 +516,7 @@ TEST_F(FirebaseDatabaseTest, TestReadingFromPersistanceWhileOffline) {
456
516
// Shut down the realtime database and restart it, to make sure that
457
517
// persistence persists across database object instances.
458
518
delete database_;
459
- database_ = ::firebase::database::Database::GetInstance (app_ );
519
+ database_ = ::firebase::database::Database::GetInstance (shared_app_ );
460
520
461
521
// Offline mode. If persistence works, we should still be able to fetch
462
522
// our value even though we're offline.
@@ -1090,15 +1150,20 @@ TEST_F(FirebaseDatabaseTest, TestInvalidatingReferencesWhenDeletingApp) {
1090
1150
1091
1151
// Deleting App should invalidate all the objects and Futures, same as
1092
1152
// deleting Database.
1093
- delete app_ ;
1094
- app_ = nullptr ;
1153
+ delete shared_app_ ;
1154
+ shared_app_ = nullptr ;
1095
1155
1096
1156
EXPECT_FALSE (ref.is_valid ());
1097
1157
EXPECT_FALSE (query.is_valid ());
1098
1158
EXPECT_FALSE (snapshot.is_valid ());
1099
1159
EXPECT_EQ (set_future.status (), firebase::kFutureStatusInvalid );
1100
1160
EXPECT_EQ (get_future.status (), firebase::kFutureStatusInvalid );
1101
1161
EXPECT_EQ (delete_future.status (), firebase::kFutureStatusInvalid );
1162
+
1163
+ // Fully shut down App and Auth so they can be reinitialized.
1164
+ TerminateAppAndAuth ();
1165
+ // Reinitialize App and Auth.
1166
+ InitializeAppAndAuth ();
1102
1167
}
1103
1168
1104
1169
TEST_F (FirebaseDatabaseTest, TestInfoConnected) {
0 commit comments