iobroker.roborock
Version:
99 lines (87 loc) • 3.36 kB
text/typescript
import { beforeEach, describe, expect, it } from "vitest";
import { Feature } from "../features/features.enum";
import { V1VacuumFeatures } from "../features/vacuum/v1VacuumFeatures";
import { MockAdapter } from "./MockAdapter";
import { MockRobot } from "./MockRobot";
class TestVacuum extends V1VacuumFeatures {
protected getDynamicFeatures(): Set<Feature> {
return new Set();
}
public async detectAndApplyRuntimeFeatures(): Promise<boolean> {
return false;
}
}
describe("Error Resilience", () => {
let mockAdapter: MockAdapter;
let mockRobot: MockRobot;
let vacuumFeatures: TestVacuum;
let depsMock: any;
beforeEach(async () => {
mockAdapter = new MockAdapter();
mockRobot = new MockRobot();
depsMock = {
adapter: mockAdapter,
log: mockAdapter.log,
ensureState: async (id: string, common: any) => {
await mockAdapter.setObjectNotExistsAsync(id, { type: "state", common });
},
ensureFolder: async (id: string) => {
await mockAdapter.setObjectNotExistsAsync(id, { type: "folder", common: { name: id } });
},
config: { staticFeatures: [] },
http_api: {
getFwFeaturesResult: () => mockRobot.features,
storeFwFeaturesResult: () => {},
getRobotModel: () => mockRobot.model
},
requestsHandler: {
sendRequest: async (duid: string, method: string, params: any[]) => {
// Simulate error for specific method
if (method === "get_status_fail") {
throw new Error("Simulated Timeout");
}
if (duid !== mockRobot.duid) return [];
return mockRobot.handleRequest(method, params);
},
command: async () => {}
}
};
mockAdapter.requestsHandler = depsMock.requestsHandler;
mockAdapter.http_api = depsMock.http_api;
vacuumFeatures = new TestVacuum(depsMock, mockRobot.duid, mockRobot.model, { staticFeatures: [] });
await vacuumFeatures.initialize();
});
it("should handle request failures gracefully", async () => {
// We override requestAndProcess in the test instance or mock the deps?
// requestAndProcess uses this.deps.adapter.requestsHandler.sendRequest
// We can define a new method on vacuumFeatures that uses a failing command, OR
// just call sendRequest directly and verify it throws/catches.
// BaseDeviceFeatures.updateStatus uses "get_status".
// Let's force sendRequest to fail for "get_status".
const originalSendRequest = depsMock.requestsHandler.sendRequest;
depsMock.requestsHandler.sendRequest = async (duid: string, method: string, params: any[]) => {
if (method === "get_status" || method === "get_prop") {
throw new Error("Network Error");
}
return originalSendRequest(duid, method, params);
};
// Spy on log.warn to verify error is caught and logged
let warnCalled = false;
const originalWarn = mockAdapter.log.warn.bind(mockAdapter.log);
mockAdapter.log.warn = (msg: string) => {
if (msg.includes("Network Error") || msg.toLowerCase().includes("failed")) {
warnCalled = true;
}
originalWarn(msg);
};
const originalError = mockAdapter.log.error.bind(mockAdapter.log);
mockAdapter.log.error = (msg: string) => {
if (msg.includes("Network Error") || msg.includes("Failed")) {
warnCalled = true;
}
originalError(msg);
};
await expect(vacuumFeatures.updateStatus()).rejects.toThrow("Network Error");
expect(warnCalled).to.be.true;
});
});