@@ -16,6 +16,7 @@ package firebase
16
16
17
17
import (
18
18
"io/ioutil"
19
+ "log"
19
20
"net/http"
20
21
"net/http/httptest"
21
22
"os"
@@ -35,6 +36,17 @@ import (
35
36
"google.golang.org/api/option"
36
37
)
37
38
39
+ const credEnvVar = "GOOGLE_APPLICATION_CREDENTIALS"
40
+
41
+ func TestMain (m * testing.M ) {
42
+ // This isolates the tests from a possiblity that the default config env
43
+ // variable is set to a valid file containing the wanted default config,
44
+ // but we the test is not expecting it.
45
+ configOld := overwriteEnv (firebaseEnvName , "" )
46
+ defer reinstateEnv (firebaseEnvName , configOld )
47
+ os .Exit (m .Run ())
48
+ }
49
+
38
50
func TestServiceAcctFile (t * testing.T ) {
39
51
app , err := NewApp (context .Background (), nil , option .WithCredentialsFile ("testdata/service_account.json" ))
40
52
if err != nil {
@@ -151,13 +163,12 @@ func TestRefreshTokenWithEnvVar(t *testing.T) {
151
163
}
152
164
153
165
func TestAppDefault (t * testing.T ) {
154
- varName := "GOOGLE_APPLICATION_CREDENTIALS"
155
- current := os .Getenv (varName )
166
+ current := os .Getenv (credEnvVar )
156
167
157
- if err := os .Setenv (varName , "testdata/service_account.json" ); err != nil {
168
+ if err := os .Setenv (credEnvVar , "testdata/service_account.json" ); err != nil {
158
169
t .Fatal (err )
159
170
}
160
- defer os .Setenv (varName , current )
171
+ defer os .Setenv (credEnvVar , current )
161
172
162
173
app , err := NewApp (context .Background (), nil )
163
174
if err != nil {
@@ -175,13 +186,12 @@ func TestAppDefault(t *testing.T) {
175
186
}
176
187
177
188
func TestAppDefaultWithInvalidFile (t * testing.T ) {
178
- varName := "GOOGLE_APPLICATION_CREDENTIALS"
179
- current := os .Getenv (varName )
189
+ current := os .Getenv (credEnvVar )
180
190
181
- if err := os .Setenv (varName , "testdata/non_existing.json" ); err != nil {
191
+ if err := os .Setenv (credEnvVar , "testdata/non_existing.json" ); err != nil {
182
192
t .Fatal (err )
183
193
}
184
- defer os .Setenv (varName , current )
194
+ defer os .Setenv (credEnvVar , current )
185
195
186
196
app , err := NewApp (context .Background (), nil )
187
197
if app != nil || err == nil {
@@ -337,6 +347,139 @@ func TestVersion(t *testing.T) {
337
347
}
338
348
}
339
349
}
350
+ func TestAutoInit (t * testing.T ) {
351
+ tests := []struct {
352
+ name string
353
+ optionsConfig string
354
+ initOptions * Config
355
+ wantOptions * Config
356
+ }{
357
+ {
358
+ "No environment variable, no explicit options" ,
359
+ "" ,
360
+ nil ,
361
+ & Config {ProjectID : "mock-project-id" }, // from default creds here and below.
362
+ }, {
363
+ "Environment variable set to file, no explicit options" ,
364
+ "testdata/firebase_config.json" ,
365
+ nil ,
366
+ & Config {
367
+ ProjectID : "hipster-chat-mock" ,
368
+ StorageBucket : "hipster-chat.appspot.mock" ,
369
+ },
370
+ }, {
371
+ "Environment variable set to string, no explicit options" ,
372
+ `{
373
+ "projectId": "hipster-chat-mock",
374
+ "storageBucket": "hipster-chat.appspot.mock"
375
+ }` ,
376
+ nil ,
377
+ & Config {
378
+ ProjectID : "hipster-chat-mock" ,
379
+ StorageBucket : "hipster-chat.appspot.mock" ,
380
+ },
381
+ }, {
382
+ "Environment variable set to file with some values missing, no explicit options" ,
383
+ "testdata/firebase_config_partial.json" ,
384
+ nil ,
385
+ & Config {ProjectID : "hipster-chat-mock" },
386
+ }, {
387
+ "Environment variable set to string with some values missing, no explicit options" ,
388
+ `{"projectId": "hipster-chat-mock"}` ,
389
+ nil ,
390
+ & Config {ProjectID : "hipster-chat-mock" },
391
+ }, {
392
+ "Environment variable set to file which is ignored as some explicit options are passed" ,
393
+ "testdata/firebase_config_partial.json" ,
394
+ & Config {StorageBucket : "sb1-mock" },
395
+ & Config {
396
+ ProjectID : "mock-project-id" ,
397
+ StorageBucket : "sb1-mock" ,
398
+ },
399
+ }, {
400
+ "Environment variable set to string which is ignored as some explicit options are passed" ,
401
+ `{"projectId": "hipster-chat-mock"}` ,
402
+ & Config {StorageBucket : "sb1-mock" },
403
+ & Config {
404
+ ProjectID : "mock-project-id" ,
405
+ StorageBucket : "sb1-mock" ,
406
+ },
407
+ }, {
408
+ "Environment variable set to file which is ignored as options are explicitly empty" ,
409
+ "testdata/firebase_config_partial.json" ,
410
+ & Config {},
411
+ & Config {ProjectID : "mock-project-id" },
412
+ }, {
413
+ "Environment variable set to file with an unknown key which is ignored, no explicit options" ,
414
+ "testdata/firebase_config_invalid_key.json" ,
415
+ nil ,
416
+ & Config {
417
+ ProjectID : "mock-project-id" , // from default creds
418
+ StorageBucket : "hipster-chat.appspot.mock" ,
419
+ },
420
+ }, {
421
+ "Environment variable set to string with an unknown key which is ignored, no explicit options" ,
422
+ `{
423
+ "obviously_bad_key": "hipster-chat-mock",
424
+ "storageBucket": "hipster-chat.appspot.mock"
425
+ }` ,
426
+ nil ,
427
+ & Config {
428
+ ProjectID : "mock-project-id" ,
429
+ StorageBucket : "hipster-chat.appspot.mock" ,
430
+ },
431
+ },
432
+ }
433
+
434
+ credOld := overwriteEnv (credEnvVar , "testdata/service_account.json" )
435
+ defer reinstateEnv (credEnvVar , credOld )
436
+
437
+ for _ , test := range tests {
438
+ t .Run (test .name , func (t * testing.T ) {
439
+ overwriteEnv (firebaseEnvName , test .optionsConfig )
440
+ app , err := NewApp (context .Background (), test .initOptions )
441
+ if err != nil {
442
+ t .Error (err )
443
+ } else {
444
+ compareConfig (app , test .wantOptions , t )
445
+ }
446
+ })
447
+ }
448
+ }
449
+
450
+ func TestAutoInitInvalidFiles (t * testing.T ) {
451
+ tests := []struct {
452
+ name string
453
+ filename string
454
+ wantError string
455
+ }{
456
+ {
457
+ "nonexistant file" ,
458
+ "testdata/no_such_file.json" ,
459
+ "open testdata/no_such_file.json: no such file or directory" ,
460
+ }, {
461
+ "invalid JSON" ,
462
+ "testdata/firebase_config_invalid.json" ,
463
+ "invalid character 'b' looking for beginning of value" ,
464
+ }, {
465
+ "empty file" ,
466
+ "testdata/firebase_config_empty.json" ,
467
+ "unexpected end of JSON input" ,
468
+ },
469
+ }
470
+ credOld := overwriteEnv (credEnvVar , "testdata/service_account.json" )
471
+ defer reinstateEnv (credEnvVar , credOld )
472
+
473
+ for _ , test := range tests {
474
+ t .Run (test .name , func (t * testing.T ) {
475
+ overwriteEnv (firebaseEnvName , test .filename )
476
+ _ , err := NewApp (context .Background (), nil )
477
+ if err == nil || err .Error () != test .wantError {
478
+ t .Errorf ("got error = %s; want = %s" , err , test .wantError )
479
+ }
480
+ })
481
+ }
482
+ }
340
483
341
484
type testTokenSource struct {
342
485
AccessToken string
@@ -350,6 +493,15 @@ func (t *testTokenSource) Token() (*oauth2.Token, error) {
350
493
}, nil
351
494
}
352
495
496
+ func compareConfig (got * App , want * Config , t * testing.T ) {
497
+ if got .projectID != want .ProjectID {
498
+ t .Errorf ("app.projectID = %q; want = %q" , got .projectID , want .ProjectID )
499
+ }
500
+ if got .storageBucket != want .StorageBucket {
501
+ t .Errorf ("app.storageBucket = %q; want = %q" , got .storageBucket , want .StorageBucket )
502
+ }
503
+ }
504
+
353
505
// mockServiceAcct generates a service account configuration with the provided URL as the
354
506
// token_url value.
355
507
func mockServiceAcct (tokenURL string ) ([]byte , error ) {
@@ -379,3 +531,25 @@ func initMockTokenServer() *httptest.Server {
379
531
}` ))
380
532
}))
381
533
}
534
+
535
+ // overwriteEnv overwrites env variables, used in testsing.
536
+ func overwriteEnv (varName , newVal string ) string {
537
+ oldVal := os .Getenv (varName )
538
+ if newVal == "" {
539
+ if err := os .Unsetenv (varName ); err != nil {
540
+ log .Fatal (err )
541
+ }
542
+ } else if err := os .Setenv (varName , newVal ); err != nil {
543
+ log .Fatal (err )
544
+ }
545
+ return oldVal
546
+ }
547
+
548
+ // reinstateEnv restores the enviornment variable, will usually be used deferred with overwriteEnv.
549
+ func reinstateEnv (varName , oldVal string ) {
550
+ if len (varName ) > 0 {
551
+ os .Setenv (varName , oldVal )
552
+ } else {
553
+ os .Unsetenv (varName )
554
+ }
555
+ }
0 commit comments