1313# limitations under the License.
1414
1515"""Tests for firebase_admin.App."""
16+ from collections import namedtuple
1617import os
1718
1819import pytest
2223from firebase_admin import _utils
2324from tests import testutils
2425
25-
2626CREDENTIAL = credentials .Certificate (
2727 testutils .resource_filename ('service_account.json' ))
2828GCLOUD_PROJECT = 'GCLOUD_PROJECT'
29+ CONFIG_JSON = firebase_admin ._FIREBASE_CONFIG_ENV_VAR
30+
31+ # This fixture will ignore the environment variable pointing to the default
32+ # configuration for the duration of the tests.
2933
3034class CredentialProvider (object ):
3135 def init (self ):
@@ -74,7 +78,6 @@ class AppService(object):
7478 def __init__ (self , app ):
7579 self ._app = app
7680
77-
7881@pytest .fixture (params = [Cert (), RefreshToken (), ExplicitAppDefault (), ImplicitAppDefault ()],
7982 ids = ['cert' , 'refreshtoken' , 'explicit-appdefault' , 'implicit-appdefault' ])
8083def app_credential (request ):
@@ -90,6 +93,124 @@ def init_app(request):
9093 else :
9194 return firebase_admin .initialize_app (CREDENTIAL )
9295
96+ @pytest .fixture (scope = "function" )
97+ def env_test_case (request ):
98+ config_old = set_config_env (request .param .config_json )
99+ yield request .param
100+ revert_config_env (config_old )
101+
102+
103+ EnvOptionsTestCase = namedtuple ('EnvOptionsTestCase' ,
104+ 'name, config_json, init_options, want_options' )
105+ env_options_test_cases = [
106+ EnvOptionsTestCase (name = 'Environment var not set, initialized with an empty options dict' ,
107+ config_json = None ,
108+ init_options = {},
109+ want_options = {}),
110+ EnvOptionsTestCase (name = 'Environment var empty, initialized with an empty options dict' ,
111+ config_json = '' ,
112+ init_options = {},
113+ want_options = {}),
114+ EnvOptionsTestCase (name = 'Environment var not set, initialized with no options dict' ,
115+ config_json = None ,
116+ init_options = None ,
117+ want_options = {}),
118+ EnvOptionsTestCase (name = 'Environment empty, initialized with no options dict' ,
119+ config_json = '' ,
120+ init_options = None ,
121+ want_options = {}),
122+ EnvOptionsTestCase (name = 'Environment var not set, initialized with options dict' ,
123+ config_json = None ,
124+ init_options = {'storageBucket' : 'bucket1' },
125+ want_options = {'storageBucket' : 'bucket1' }),
126+ EnvOptionsTestCase (name = 'Environment var set to file but ignored, initialized with options' ,
127+ config_json = 'firebase_config.json' ,
128+ init_options = {'storageBucket' : 'bucket1' },
129+ want_options = {'storageBucket' : 'bucket1' }),
130+ EnvOptionsTestCase (name = 'Environment var set to json but ignored, initialized with options' ,
131+ config_json = '{"storageBucket": "hipster-chat.appspot.mock"}' ,
132+ init_options = {'storageBucket' : 'bucket1' },
133+ want_options = {'storageBucket' : 'bucket1' }),
134+ EnvOptionsTestCase (name = 'Environment var set to file, initialized with no options dict' ,
135+ config_json = 'firebase_config.json' ,
136+ init_options = None ,
137+ want_options = {'databaseAuthVariableOverride' : {'some_key' : 'some_val' },
138+ 'databaseURL' : 'https://hipster-chat.firebaseio.mock' ,
139+ 'projectId' : 'hipster-chat-mock' ,
140+ 'storageBucket' : 'hipster-chat.appspot.mock' }),
141+ EnvOptionsTestCase (name = 'Environment var set to json string, initialized with no options dict' ,
142+ config_json = '{"databaseAuthVariableOverride": {"some_key": "some_val"}, ' +
143+ '"databaseURL": "https://hipster-chat.firebaseio.mock", ' +
144+ '"projectId": "hipster-chat-mock",' +
145+ '"storageBucket": "hipster-chat.appspot.mock"}' ,
146+ init_options = None ,
147+ want_options = {'databaseAuthVariableOverride' : {'some_key' : 'some_val' },
148+ 'databaseURL' : 'https://hipster-chat.firebaseio.mock' ,
149+ 'projectId' : 'hipster-chat-mock' ,
150+ 'storageBucket' : 'hipster-chat.appspot.mock' }),
151+ EnvOptionsTestCase (name = 'Invalid key in json file is ignored, the rest of the values are used' ,
152+ config_json = 'firebase_config_invalid_key.json' ,
153+ init_options = None ,
154+ want_options = {'projectId' : 'hipster-chat-mock' }),
155+ EnvOptionsTestCase (name = 'Invalid key in json file is ignored, the rest of the values are used' ,
156+ config_json = '{"databaseUrrrrL": "https://hipster-chat.firebaseio.mock",' +
157+ '"projectId": "hipster-chat-mock"}' ,
158+ init_options = None ,
159+ want_options = {'projectId' : 'hipster-chat-mock' }),
160+ EnvOptionsTestCase (name = 'Environment var set to file but ignored, init empty options dict' ,
161+ config_json = 'firebase_config.json' ,
162+ init_options = {},
163+ want_options = {}),
164+ EnvOptionsTestCase (name = 'Environment var set to string but ignored, init empty options dict' ,
165+ config_json = '{"projectId": "hipster-chat-mock"}' ,
166+ init_options = {},
167+ want_options = {}),
168+ EnvOptionsTestCase (name = 'Environment variable set to json file with some options set' ,
169+ config_json = 'firebase_config_partial.json' ,
170+ init_options = None ,
171+ want_options = {'databaseURL' : 'https://hipster-chat.firebaseio.mock' ,
172+ 'projectId' : 'hipster-chat-mock' }),
173+ EnvOptionsTestCase (name = 'Environment variable set to json string with some options set' ,
174+ config_json = '{"databaseURL": "https://hipster-chat.firebaseio.mock",' +
175+ '"projectId": "hipster-chat-mock"}' ,
176+ init_options = None ,
177+ want_options = {'databaseURL' : 'https://hipster-chat.firebaseio.mock' ,
178+ 'projectId' : 'hipster-chat-mock' }),
179+ EnvOptionsTestCase (name = 'Environment var set to json file but ignored, init with options dict' ,
180+ config_json = 'firebase_config_partial.json' ,
181+ init_options = {'projectId' : 'pid1-mock' ,
182+ 'storageBucket' : 'sb1-mock' },
183+ want_options = {'projectId' : 'pid1-mock' ,
184+ 'storageBucket' : 'sb1-mock' }),
185+ EnvOptionsTestCase (name = 'Environment var set to file but ignored, init with full options dict' ,
186+ config_json = 'firebase_config.json' ,
187+ init_options = {'databaseAuthVariableOverride' : 'davy1-mock' ,
188+ 'databaseURL' : 'https://db1-mock' ,
189+ 'projectId' : 'pid1-mock' ,
190+ 'storageBucket' : 'sb1-.mock' },
191+ want_options = {'databaseAuthVariableOverride' : 'davy1-mock' ,
192+ 'databaseURL' : 'https://db1-mock' ,
193+ 'projectId' : 'pid1-mock' ,
194+ 'storageBucket' : 'sb1-.mock' })]
195+
196+ def set_config_env (config_json ):
197+ config_old = os .environ .get (CONFIG_JSON )
198+ if config_json is not None :
199+ if not config_json or config_json .startswith ('{' ):
200+ os .environ [CONFIG_JSON ] = config_json
201+ else :
202+ os .environ [CONFIG_JSON ] = testutils .resource_filename (
203+ config_json )
204+ elif os .environ .get (CONFIG_JSON ) is not None :
205+ del os .environ [CONFIG_JSON ]
206+ return config_old
207+
208+
209+ def revert_config_env (config_old ):
210+ if config_old is not None :
211+ os .environ [CONFIG_JSON ] = config_old
212+ elif os .environ .get (CONFIG_JSON ) is not None :
213+ del os .environ [CONFIG_JSON ]
93214
94215class TestFirebaseApp (object ):
95216 """Test cases for App initialization and life cycle."""
@@ -140,6 +261,30 @@ def test_app_init_with_invalid_name(self, name):
140261 with pytest .raises (ValueError ):
141262 firebase_admin .initialize_app (CREDENTIAL , name = name )
142263
264+
265+ @pytest .mark .parametrize ('bad_file_name' , ['firebase_config_empty.json' ,
266+ 'firebase_config_invalid.json' ,
267+ 'no_such_file' ])
268+ def test_app_init_with_invalid_config_file (self , bad_file_name ):
269+ config_old = set_config_env (bad_file_name )
270+ with pytest .raises (ValueError ):
271+ firebase_admin .initialize_app (CREDENTIAL )
272+ revert_config_env (config_old )
273+
274+ def test_app_init_with_invalid_config_string (self ):
275+ config_old = set_config_env ('{,,' )
276+ with pytest .raises (ValueError ):
277+ firebase_admin .initialize_app (CREDENTIAL )
278+ revert_config_env (config_old )
279+
280+
281+ @pytest .mark .parametrize ('env_test_case' , env_options_test_cases ,
282+ ids = [x .name for x in env_options_test_cases ],
283+ indirect = ['env_test_case' ])
284+ def test_app_init_with_default_config (self , env_test_case ):
285+ app = firebase_admin .initialize_app (CREDENTIAL , options = env_test_case .init_options )
286+ assert app .options ._options == env_test_case .want_options
287+
143288 def test_project_id_from_options (self , app_credential ):
144289 app = firebase_admin .initialize_app (
145290 app_credential , options = {'projectId' : 'test-project' }, name = 'myApp' )
0 commit comments