Repository: serverless/serverless-azure-functions (ts)

Issue:
Listing Deployments: TypeError: Cannot convert undefined or null to object error
# This is a Bug Report

## Description

When attempting to deploy to Azure I'm getting a TypeError when the plugin is checking previous deployment templates.

```
TypeError: Cannot convert undefined or null to object
      at Function.keys (<anonymous>)
      at paramsNormalizer (/Users/brucestorrie/drds/azuretest/drdsfuncs/node_modules/serverless-azure-functions/lib/services/armService.js:259:31)
      at ArmService.areDeploymentsEqual (/Users/brucestorrie/drds/azuretest/drdsfuncs/node_modules/serverless-azure-functions/lib/services/armService.js:276:80)
      at ArmService.<anonymous> (/Users/brucestorrie/drds/azuretest/drdsfuncs/node_modules/serverless-azure-functions/lib/services/armService.js:193:34)
      at step (/Users/brucestorrie/drds/azuretest/drdsfuncs/node_modules/serverless-azure-functions/lib/services/armService.js:56:23)

```

## Additional Data

I've debugged the issue and identified that it's because the previous deployment template did not contain any parameters but there is a check within the code to compare templates which isn't catering for that scenario.




Pull request:
fix: Hot fix for undefined params
<!--
1. Please check out and follow our Contributing Guidelines: https://github.com/serverless/serverless-azure-functions/CONTRIBUTING.md
2. Do not remove any section of the template. If something is not applicable leave it empty but leave it in the PR
3. Please follow the template, otherwise we'll have to ask you to update it and it will take longer until your PR is merged
-->

## What did you implement:

Closes #410 

## How did you implement it:

Checked if params were undefined, return empty object if they are.

## How can we verify it:

Redeploy a function app that previously had no parameters. It used to be broken, now it's not :)

<!--
Add any applicable config, commands, screenshots or other resources
to make it easy for us to verify this works. The easier you make it for us
to review a PR, the faster we can review and merge it.

Examples:
* serverless.yml - Fully functioning to easily deploy changes
* Screenshots - Showing the difference between your output and the master
* Cloud Configuration - List cloud resources and show that the correct configuration is in place
* Other - Anything else that comes to mind to help us evaluate
-->

## Todos:

_**Note: Run `npm run test:ci` to run all validation checks on proposed changes**_

- [x] Ensure there are no lint errors.  
       **Validate via `npm run lint`**  
       _Note: Some reported issues can be automatically fixed by running `npm run lint:fix`_
- [x] Write tests and confirm existing functionality is not broken.  
       **Validate via `npm test`**
- [x] Write documentation
- [x] Provide verification config / commands / resources
- [x] Enable "Allow edits from maintainers" for this PR
- [x] Update the messages below

**_Is this ready for review?:_** YES 
**_Is it a breaking change?:_** NO


Patch:
diff --git a/src/services/armService.ts b/src/services/armService.ts
index f64f7e4..e967fa2 100644
--- a/src/services/armService.ts
+++ b/src/services/armService.ts
@@ -101,6 +101,8 @@ export class ArmService extends BaseService {
       return;
     }
 
+    deployment.parameters = deployment.parameters || {};
+    
     for (const key of Object.keys(deployment.parameters)) {
       if (!deployment.parameters[key].value) {
         delete deployment.parameters[key];
@@ -160,6 +162,9 @@ export class ArmService extends BaseService {
 
     const paramsNormalizer = (params: ArmParameters): ArmParameters => {
       const normalized = {};
+      if (!params) {
+        return normalized;
+      }
       const keys = Object.keys(params);
       for (const key of keys) {
         const original = params[key];
@@ -207,6 +212,8 @@ export class ArmService extends BaseService {
    */
   private mergeDefaultParams(parameters: ArmParameters, defaultParameters: ArmParameters): ArmParameters {
     const mergedParams: ArmParameters = {}
+    parameters = parameters || {};
+    defaultParameters = defaultParameters || {};
     Object.keys(defaultParameters).forEach((key) => {
       const defaultParam = defaultParameters[key];
       const param = parameters[key];


Test patch:
diff --git a/src/services/armService.test.ts b/src/services/armService.test.ts
index d2baa30..c0283cc 100644
--- a/src/services/armService.test.ts
+++ b/src/services/armService.test.ts
@@ -167,7 +167,16 @@ describe("Arm Service", () => {
         template: MockFactory.createTestArmTemplate()
       };
       await service.deployTemplate(deployment);
-      expect(Deployments.prototype.createOrUpdate).not.toBeCalled()
+      expect(Deployments.prototype.createOrUpdate).not.toBeCalled();
+    });
+
+    it("Does not crash if deployment parameters are undefined", async () => {
+      const deployment: ArmDeployment = {
+        parameters: undefined,
+        template: MockFactory.createTestArmTemplate(),
+      };
+      await service.deployTemplate(deployment);
+      expect(Deployments.prototype.createOrUpdate).toBeCalled();
     });
 
     it("Does not deploy if identity is only difference between deployments", async () => {