diff --git a/lib/util/settings.ts b/lib/util/settings.ts index 27b7ee1c69..ce4da97498 100644 --- a/lib/util/settings.ts +++ b/lib/util/settings.ts @@ -32,7 +32,7 @@ export type LogLevel = typeof LOG_LEVELS[number]; // DEPRECATED ZIGBEE2MQTT_CONFIG: https://github.com/Koenkk/zigbee2mqtt/issues/4697 const file = process.env.ZIGBEE2MQTT_CONFIG ?? data.joinPath('configuration.yaml'); -const nullPropertiesIgnoreList = ['homeassistant']; +const NULLABLE_SETTINGS = ['homeassistant']; const ajvSetting = new Ajv({allErrors: true}).addKeyword('requiresRestart').compile(schemaJson); const ajvRestartRequired = new Ajv({allErrors: true}) .addKeyword({keyword: 'requiresRestart', validate: (s: unknown) => !s}).compile(schemaJson); @@ -485,7 +485,7 @@ export function apply(settings: Record): boolean { getInternalSettings(); // Ensure _settings is initialized. /* eslint-disable-line */ // @ts-ignore const newSettings = objectAssignDeep.noMutate(_settings, settings); - utils.removeNullPropertiesFromObject(newSettings, nullPropertiesIgnoreList); + utils.removeNullPropertiesFromObject(newSettings, NULLABLE_SETTINGS); ajvSetting(newSettings); const errors = ajvSetting.errors && ajvSetting.errors.filter((e) => e.keyword !== 'required'); if (errors?.length) { @@ -696,11 +696,11 @@ export function changeEntityOptions(IDorName: string, newOptions: KeyValue): boo let validator: ValidateFunction; if (getDevice(IDorName)) { objectAssignDeep(settings.devices[getDevice(IDorName).ID], newOptions); - utils.removeNullPropertiesFromObject(settings.devices[getDevice(IDorName).ID], nullPropertiesIgnoreList); + utils.removeNullPropertiesFromObject(settings.devices[getDevice(IDorName).ID], NULLABLE_SETTINGS); validator = ajvRestartRequiredDeviceOptions; } else if (getGroup(IDorName)) { objectAssignDeep(settings.groups[getGroup(IDorName).ID], newOptions); - utils.removeNullPropertiesFromObject(settings.groups[getGroup(IDorName).ID], nullPropertiesIgnoreList ); + utils.removeNullPropertiesFromObject(settings.groups[getGroup(IDorName).ID], NULLABLE_SETTINGS ); validator = ajvRestartRequiredGroupOptions; } else { throw new Error(`Device or group '${IDorName}' does not exist`); diff --git a/lib/util/utils.ts b/lib/util/utils.ts index 88f2159fc4..f49e622f0a 100644 --- a/lib/util/utils.ts +++ b/lib/util/utils.ts @@ -162,14 +162,20 @@ export function* loadExternalConverter(moduleName: string): Generator { expect(utils.formatDate(date, 'ISO_8601_local').endsWith('+01:00')).toBeTruthy(); Date.prototype.getTimezoneOffset = getTimezoneOffset; }) + it('Removes null properties from object', () => { + const obj1 = { + ab: 0, + cd: false, + ef: null, + gh: '', + homeassistant: { + xyz: 'mock', + abcd: null, + }, + nested: { + homeassistant: { + abcd: true, + xyz: null, + }, + abc: {}, + def: null, + }, + }; + + utils.removeNullPropertiesFromObject(obj1); + expect(obj1).toStrictEqual({ + ab: 0, + cd: false, + gh: '', + homeassistant: { + xyz: 'mock', + }, + nested: { + homeassistant: { + abcd: true, + }, + abc: {}, + }, + }); + + const obj2 = { + ab: 0, + cd: false, + ef: null, + gh: '', + homeassistant: { + xyz: 'mock', + abcd: null, + }, + nested: { + homeassistant: { + abcd: true, + xyz: null, + }, + abc: {}, + def: null, + }, + }; + utils.removeNullPropertiesFromObject(obj2, ['homeassistant']); + expect(obj2).toStrictEqual({ + ab: 0, + cd: false, + gh: '', + homeassistant: { + xyz: 'mock', + abcd: null, + }, + nested: { + homeassistant: { + abcd: true, + xyz: null, + }, + abc: {}, + }, + }); + }); });