fix: Trim name on rename (#27332)

This commit is contained in:
Koen Kanters
2025-05-06 21:49:24 +02:00
committed by GitHub
parent 164c3222b9
commit 69364c958f
4 changed files with 33 additions and 3 deletions
+3 -2
View File
@@ -19,7 +19,7 @@ import Device from "../model/device";
import data from "../util/data";
import logger from "../util/logger";
import * as settings from "../util/settings";
import utils from "../util/utils";
import utils, {assertString} from "../util/utils";
import Extension from "./extension";
const REQUEST_REGEX = new RegExp(`${settings.get().mqtt.base_topic}/bridge/request/(.*)`);
@@ -564,7 +564,8 @@ export default class Bridge extends Extension {
}
const from = deviceAndHasLast ? this.lastJoinedDeviceIeeeAddr : message.from;
const to = message.to;
assertString(message.to, "to");
const to = message.to.trim();
const homeAssisantRename = message.homeassistant_rename !== undefined ? message.homeassistant_rename : false;
const entity = this.getEntity(entityType, from);
const oldFriendlyName = entity.options.friendly_name;
+6
View File
@@ -340,6 +340,12 @@ export function isLightExpose(expose: zhc.Expose): expose is zhc.Light {
return expose.type === "light";
}
export function assertString(value: unknown, property: string): asserts value is string {
if (typeof value !== "string") {
throw new Error(`${property} is not a string, got ${typeof value} (${value})`);
}
}
function getScenes(entity: zh.Endpoint | zh.Group): Zigbee2MQTTScene[] {
const scenes: {[id: number]: Zigbee2MQTTScene} = {};
const endpoints = isZHEndpoint(entity) ? [entity] : entity.members;
+18
View File
@@ -2994,6 +2994,24 @@ describe("Extension: Bridge", () => {
);
});
it("Should trim input when renaming device", async () => {
mockMQTTPublishAsync.mockClear();
mockMQTTEvents.message("zigbee2mqtt/bridge/request/device/rename", stringify({from: "bulb", to: " bulb_new_name "}));
await flushPromises();
expect(settings.getDevice("bulb")).toBeUndefined();
expect(settings.getDevice("bulb_new_name")).toStrictEqual({
ID: "0x000b57fffec6a5b2",
friendly_name: "bulb_new_name",
retain: true,
description: "this is my bulb",
});
expect(mockMQTTPublishAsync).toHaveBeenCalledWith(
"zigbee2mqtt/bridge/response/device/rename",
stringify({data: {from: "bulb", to: "bulb_new_name", homeassistant_rename: false}, status: "ok"}),
{},
);
});
it("Shouldnt allow rename device with to not allowed name containing a wildcard", async () => {
mockMQTTPublishAsync.mockClear();
mockMQTTEvents.message("zigbee2mqtt/bridge/request/device/rename", stringify({from: "bulb", to: "living_room/blinds#"}));
+6 -1
View File
@@ -2,7 +2,7 @@ import {exec} from "node:child_process";
import fs from "node:fs";
import path from "node:path";
import utils from "../lib/util/utils";
import utils, {assertString} from "../lib/util/utils";
// keep the implementations, just spy
vi.mock("node:child_process", {spy: true});
@@ -78,6 +78,11 @@ describe("Utils", () => {
expect(utils.formatDate(date, "ISO_8601_local").toString().endsWith("+01:00")).toBeTruthy();
});
it("Assert string", () => {
assertString("test", "property");
expect(() => assertString(1, "property")).toThrow("property is not a string, got number (1)");
});
it("Removes null properties from object", () => {
const obj1 = {
ab: 0,