@@ -36,6 +36,11 @@ describe("Function App Service", () => {
3636 const syncTriggersUrl = `${ baseUrl } ${ app . id } /syncfunctiontriggers?api-version=2016-08-01` ;
3737 const listFunctionsUrl = `${ baseUrl } ${ app . id } /functions?api-version=2016-08-01` ;
3838
39+ const appSettings = {
40+ setting1 : "value1" ,
41+ setting2 : "value2" ,
42+ }
43+
3944 beforeAll ( ( ) => {
4045 const axiosMock = new MockAdapter ( axios ) ;
4146
@@ -65,6 +70,8 @@ describe("Function App Service", () => {
6570 WebSiteManagementClient . prototype . webApps = {
6671 get : jest . fn ( ( ) => app ) ,
6772 deleteFunction : jest . fn ( ) ,
73+ listApplicationSettings : jest . fn ( ( ) => Promise . resolve ( { properties : { ...appSettings } } ) ) ,
74+ updateApplicationSettings : jest . fn ( ) ,
6875 } as any ;
6976 ( FunctionAppService . prototype as any ) . sendFile = jest . fn ( ) ;
7077 } ) ;
@@ -155,11 +162,22 @@ describe("Function App Service", () => {
155162
156163 beforeEach ( ( ) => {
157164 FunctionAppService . prototype . get = jest . fn ( ( ) => Promise . resolve ( expectedSite ) ) ;
165+ ( FunctionAppService . prototype as any ) . sendFile = jest . fn ( ) ;
158166 ArmService . prototype . createDeploymentFromConfig = jest . fn ( ( ) => Promise . resolve ( expectedDeployment ) ) ;
159167 ArmService . prototype . createDeploymentFromType = jest . fn ( ( ) => Promise . resolve ( expectedDeployment ) ) ;
160168 ArmService . prototype . deployTemplate = jest . fn ( ( ) => Promise . resolve ( null ) ) ;
169+ WebSiteManagementClient . prototype . webApps = {
170+ get : jest . fn ( ( ) => app ) ,
171+ deleteFunction : jest . fn ( ) ,
172+ listApplicationSettings : jest . fn ( ( ) => Promise . resolve ( { properties : { ...appSettings } } ) ) ,
173+ updateApplicationSettings : jest . fn ( ) ,
174+ } as any ;
161175 } ) ;
162176
177+ afterEach ( ( ) => {
178+ jest . restoreAllMocks ( ) ;
179+ } )
180+
163181 it ( "deploys ARM templates with custom configuration" , async ( ) => {
164182 slsService . provider [ "armTemplate" ] = { } ;
165183
@@ -184,63 +202,6 @@ describe("Function App Service", () => {
184202 expect ( ArmService . prototype . deployTemplate ) . toBeCalledWith ( expectedDeployment ) ;
185203 } ) ;
186204
187- it ( "deploys ARM template with SAS URL if running from blob URL" , async ( ) => {
188- const sasUrl = "sasUrl" ;
189- AzureBlobStorageService . prototype . generateBlobSasTokenUrl = jest . fn ( ( ) => Promise . resolve ( sasUrl ) ) ;
190-
191- const newSlsService = MockFactory . createTestService ( ) ;
192- newSlsService . provider [ "armTemplate" ] = null ;
193- newSlsService . provider [ "deployment" ] = {
194- runFromBlobUrl : true ,
195- }
196-
197- const service = createService ( MockFactory . createTestServerless ( {
198- service : newSlsService ,
199- } ) ) ;
200-
201- const site = await service . deploy ( ) ;
202-
203- // Deploy should upload to blob FIRST and then set the SAS URL
204- // as the WEBSITE_RUN_FROM_PACKAGE setting in the template
205- const uploadFileCalls = ( AzureBlobStorageService . prototype . uploadFile as any ) . mock . calls ;
206- expect ( uploadFileCalls ) . toHaveLength ( 1 ) ;
207- const call = uploadFileCalls [ 0 ] ;
208- expect ( call [ 0 ] ) . toEqual ( "app.zip" ) ;
209- expect ( call [ 1 ] ) . toEqual ( "deployment-artifacts" ) ;
210- expect ( call [ 2 ] ) . toMatch ( / m y D e p l o y m e n t N a m e - t ( [ 0 - 9 ] ) + .z i p / ) ;
211-
212- expect ( site ) . toEqual ( expectedSite ) ;
213- expect ( ArmService . prototype . createDeploymentFromConfig ) . not . toBeCalled ( ) ;
214- expect ( ArmService . prototype . createDeploymentFromType ) . toBeCalledWith ( ArmTemplateType . Consumption ) ;
215- // Should set parameter of arm template to include SAS URL
216- expect ( ArmService . prototype . deployTemplate ) . toBeCalledWith ( {
217- ...expectedDeployment ,
218- parameters : {
219- ...expectedDeployment . parameters ,
220- functionAppRunFromPackage : sasUrl ,
221- }
222- } ) ;
223- } ) ;
224-
225- it ( "does not generate SAS URL if not configured" , async ( ) => {
226- AzureBlobStorageService . prototype . generateBlobSasTokenUrl = jest . fn ( ) ;
227-
228- const newSlsService = MockFactory . createTestService ( ) ;
229- newSlsService . provider [ "armTemplate" ] = null ;
230- newSlsService . provider [ "deployment" ] = {
231- runFromBlobUrl : false ,
232- }
233-
234- const service = createService ( MockFactory . createTestServerless ( {
235- service : newSlsService ,
236- } ) ) ;
237-
238- await service . deploy ( ) ;
239-
240- expect ( AzureBlobStorageService . prototype . generateBlobSasTokenUrl ) . not . toBeCalled ( ) ;
241- expect ( ArmService . prototype . deployTemplate ) . toBeCalledWith ( expectedDeployment ) ;
242- } ) ;
243-
244205 it ( "deploys ARM template from well-known configuration" , async ( ) => {
245206 slsService . provider [ "armTemplate" ] = null ;
246207 slsService . provider [ "type" ] = "premium" ;
@@ -354,4 +315,75 @@ describe("Function App Service", () => {
354315 const service = createService ( sls , options ) ;
355316 expect ( service . getFunctionZipFile ( ) ) . toEqual ( "fake.zip" )
356317 } ) ;
318+
319+ it ( "adds a new function app setting" , async ( ) => {
320+ const service = createService ( ) ;
321+ const settingName = "TEST_SETTING" ;
322+ const settingValue = "TEST_VALUE"
323+ await service . updateFunctionAppSetting ( app , settingName , settingValue ) ;
324+ expect ( WebSiteManagementClient . prototype . webApps . updateApplicationSettings ) . toBeCalledWith (
325+ "myResourceGroup" ,
326+ "Test" ,
327+ {
328+ ...appSettings ,
329+ TEST_SETTING : settingValue
330+ }
331+ )
332+ } ) ;
333+
334+ it ( "updates an existing function app setting" , async ( ) => {
335+ const service = createService ( ) ;
336+ const settingName = "setting1" ;
337+ const settingValue = "TEST_VALUE"
338+ await service . updateFunctionAppSetting ( app , settingName , settingValue ) ;
339+ expect ( WebSiteManagementClient . prototype . webApps . updateApplicationSettings ) . toBeCalledWith (
340+ "myResourceGroup" ,
341+ "Test" ,
342+ {
343+ setting1 : settingValue ,
344+ setting2 : appSettings . setting2
345+ }
346+ ) ;
347+ } ) ;
348+
349+ describe ( "Updating Function App Settings" , ( ) => {
350+
351+ const sasUrl = "sasUrl"
352+
353+ beforeEach ( ( ) => {
354+ FunctionAppService . prototype . updateFunctionAppSetting = jest . fn ( ) ;
355+ AzureBlobStorageService . prototype . generateBlobSasTokenUrl = jest . fn ( ( ) => Promise . resolve ( sasUrl ) ) ;
356+ } ) ;
357+
358+ afterEach ( ( ) => {
359+ ( FunctionAppService . prototype . updateFunctionAppSetting as any ) . mockRestore ( ) ;
360+ } ) ;
361+
362+ it ( "updates WEBSITE_RUN_FROM_PACKAGE with SAS URL if configured to run from blob" , async ( ) => {
363+ const newSlsService = MockFactory . createTestService ( ) ;
364+ newSlsService . provider [ "deployment" ] = {
365+ runFromBlobUrl : true ,
366+ }
367+
368+ const service = createService ( MockFactory . createTestServerless ( {
369+ service : newSlsService ,
370+ } ) ) ;
371+ await service . uploadFunctions ( app ) ;
372+ expect ( AzureBlobStorageService . prototype . generateBlobSasTokenUrl ) . toBeCalled ( ) ;
373+ expect ( FunctionAppService . prototype . updateFunctionAppSetting ) . toBeCalledWith (
374+ app ,
375+ "WEBSITE_RUN_FROM_PACKAGE" ,
376+ sasUrl
377+ ) ;
378+ } ) ;
379+
380+ it ( "does not generate SAS URL or update WEBSITE_RUN_FROM_PACKAGE if not configured to run from blob" , async ( ) => {
381+ const service = createService ( ) ;
382+ await service . uploadFunctions ( app ) ;
383+ expect ( AzureBlobStorageService . prototype . generateBlobSasTokenUrl ) . not . toBeCalled ( ) ;
384+ expect ( FunctionAppService . prototype . updateFunctionAppSetting ) . not . toBeCalled ( ) ;
385+ } ) ;
386+ } ) ;
387+
388+
357389} ) ;
0 commit comments