matterbridge-lg-thinq-plugin 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/CLAUDE.md +43 -0
- package/.claude/agents/compiler.md +91 -0
- package/.claude/agents/direct-executor.md +98 -0
- package/.claude/agents/documenter.md +78 -0
- package/.claude/agents/finalizer.md +233 -0
- package/.claude/agents/implementer.md +112 -0
- package/.claude/agents/investigator.md +100 -0
- package/.claude/agents/release-manager.md +203 -0
- package/.claude/agents/reviewer.md +131 -0
- package/.claude/agents/technical-architect.md +403 -0
- package/.claude/agents/test-writer.md +159 -0
- package/.claude/agents/wiki-manager.md +147 -0
- package/.claude/instructions/agent-prompts.md +90 -0
- package/.claude/instructions/shared-rules.md +11 -0
- package/.claude/instructions/team-orchestrator-policy.md +165 -0
- package/.claude/memory.md +186 -0
- package/.claude/output-styles/engineer-manager.md +38 -0
- package/.claude/settings.json +40 -0
- package/.claude/settings.local.json +30 -0
- package/.claude/skills/load-policy/SKILL.md +13 -0
- package/.claude/skills/ref-idea/SKILL.md +44 -0
- package/.claude/skills/status-of/SKILL.md +38 -0
- package/.claude/skills/workspace-console/SKILL.md +49 -0
- package/.claude/statusline-command.sh +130 -0
- package/.claude/statusline.md +53 -0
- package/.claude/templates/approval-packet.template.html +171 -0
- package/.claude/templates/reference-workspaces.md +16 -0
- package/.claude/tools/cli-runner-server.cjs +220 -0
- package/.claude/tools/discord-send-server.cjs +188 -0
- package/.claude/tools/github-release-server.cjs +181 -0
- package/.claude/tools/glob-grep-server.cjs +267 -0
- package/.claude/tools/read-log-server.cjs +175 -0
- package/.github/codeql/codeql-config.yml +14 -0
- package/.github/workflows/build.yml +54 -0
- package/.github/workflows/codeql.yml +59 -0
- package/.github/workflows/coverage.yml +70 -0
- package/.github/workflows/publish.yml +103 -0
- package/.mcp.json +34 -0
- package/CHANGELOG.md +195 -0
- package/LICENSE +21 -0
- package/dist/cli/commands/devices.js +52 -0
- package/dist/cli/commands/energy.js +122 -0
- package/dist/cli/commands/login.js +54 -0
- package/dist/cli/help.js +50 -0
- package/dist/cli/main.js +56 -0
- package/dist/cli/session.js +13 -0
- package/dist/cli/types.js +1 -0
- package/dist/cli/utils.js +29 -0
- package/dist/cli.js +2 -0
- package/dist/constants/index.js +1 -0
- package/dist/core/domain/entities/ThinqDevice.js +43 -0
- package/dist/core/domain/value-objects/AirConditionerCapabilities.js +22 -0
- package/dist/core/domain/value-objects/ThinqFilterState.js +35 -0
- package/dist/core/domain/value-objects/ThinqSnapshot.js +125 -0
- package/dist/errors/AuthenticationError.js +26 -0
- package/dist/errors/BaseError.js +23 -0
- package/dist/errors/index.js +2 -0
- package/dist/model/LgThinkqPluginPlatformConfig.js +23 -0
- package/dist/model/LgThinqPluginPlatformConfig.js +23 -0
- package/dist/module.js +212 -0
- package/dist/platform/deviceRegistry.js +26 -0
- package/dist/platform/platformConfigManager.js +89 -0
- package/dist/platform/platformState.js +9 -0
- package/dist/platform/thinq/thinqAirConditionerCommandHandlers.js +190 -0
- package/dist/platform/thinq/thinqAirConditionerEndpointFactory.js +53 -0
- package/dist/platform/thinq/thinqAirConditionerFilterResetCommandHandler.js +54 -0
- package/dist/platform/thinq/thinqAirConditionerFilterStateSync.js +19 -0
- package/dist/platform/thinq/thinqAirConditionerStateSync.js +205 -0
- package/dist/platform/thinq/thinqDeviceConfigReconciler.js +26 -0
- package/dist/platform/thinq/thinqDeviceConfigurator.js +124 -0
- package/dist/platform/thinq/thinqDeviceDiscovery.js +33 -0
- package/dist/platform/thinq/thinqWasherCommandHandlers.js +54 -0
- package/dist/platform/thinq/thinqWasherEndpointFactory.js +6 -0
- package/dist/platform/thinq/thinqWasherStateSync.js +31 -0
- package/dist/platform/thinq/thinqWasherStopCommandResolver.js +38 -0
- package/dist/services/authentication/AccountAuthStrategy.js +135 -0
- package/dist/services/authentication/AuthContext.js +1 -0
- package/dist/services/authentication/AuthenticationCoordinator.js +29 -0
- package/dist/services/authentication/IAuthStrategy.js +1 -0
- package/dist/services/authentication/TokenAuthStrategy.js +27 -0
- package/dist/services/authentication/UserDataRepository.js +32 -0
- package/dist/services/thinq/gateway.js +61 -0
- package/dist/services/thinq/mqtt/mqttCertificate.js +63 -0
- package/dist/services/thinq/mqtt/mqttConnectionEvents.js +37 -0
- package/dist/services/thinq/mqtt/mqttKeyRepository.js +33 -0
- package/dist/services/thinq/mqtt/mqttRetry.js +25 -0
- package/dist/services/thinq/mqtt/thinqMqttListener.js +97 -0
- package/dist/services/thinq/serviceContainer.js +73 -0
- package/dist/services/thinq/session.js +48 -0
- package/dist/services/thinq/thinqApiClient.js +258 -0
- package/dist/services/thinq/thinqDeviceService.js +75 -0
- package/dist/services/thinq/thinqFilterMonitoringService.js +40 -0
- package/dist/settings.js +9 -0
- package/dist/tests/helpers/testUtils.js +87 -0
- package/dist/utils/mask.js +39 -0
- package/docs/README_CLI.md +166 -0
- package/eslint.config.js +194 -0
- package/matterbridge-lg-thinq-plugin.config.json +27 -0
- package/matterbridge-lg-thinq-plugin.schema.json +520 -0
- package/package.json +107 -0
- package/prettier.config.js +49 -0
- package/scripts/parse-junit-failures.mjs +45 -0
- package/scripts/parse-tsc-failures.mjs +48 -0
- package/scripts/run-build-local-summary.mjs +29 -0
- package/scripts/run-format-summary.mjs +36 -0
- package/scripts/run-lint-fix-summary.mjs +38 -0
- package/scripts/run-precommit-summary.mjs +94 -0
- package/src/cli/commands/devices.ts +67 -0
- package/src/cli/commands/energy.ts +160 -0
- package/src/cli/commands/login.ts +74 -0
- package/src/cli/help.ts +53 -0
- package/src/cli/main.ts +66 -0
- package/src/cli/session.ts +15 -0
- package/src/cli/types.ts +10 -0
- package/src/cli/utils.ts +30 -0
- package/src/cli.ts +3 -0
- package/src/constants/index.ts +8 -0
- package/src/core/domain/entities/ThinqDevice.test.ts +224 -0
- package/src/core/domain/entities/ThinqDevice.ts +74 -0
- package/src/core/domain/value-objects/AirConditionerCapabilities.ts +50 -0
- package/src/core/domain/value-objects/ThinqFilterState.ts +50 -0
- package/src/core/domain/value-objects/ThinqSnapshot.ts +162 -0
- package/src/errors/AuthenticationError.ts +37 -0
- package/src/errors/BaseError.ts +38 -0
- package/src/errors/index.ts +24 -0
- package/src/model/LgThinqPluginPlatformConfig.ts +94 -0
- package/src/module.ts +298 -0
- package/src/platform/deviceRegistry.ts +58 -0
- package/src/platform/platformConfigManager.ts +133 -0
- package/src/platform/platformState.ts +16 -0
- package/src/platform/thinq/thinqAirConditionerCommandHandlers.ts +291 -0
- package/src/platform/thinq/thinqAirConditionerEndpointFactory.ts +145 -0
- package/src/platform/thinq/thinqAirConditionerFilterResetCommandHandler.ts +96 -0
- package/src/platform/thinq/thinqAirConditionerFilterStateSync.ts +42 -0
- package/src/platform/thinq/thinqAirConditionerStateSync.ts +343 -0
- package/src/platform/thinq/thinqDeviceConfigReconciler.ts +42 -0
- package/src/platform/thinq/thinqDeviceConfigurator.test.ts +90 -0
- package/src/platform/thinq/thinqDeviceConfigurator.ts +191 -0
- package/src/platform/thinq/thinqDeviceDiscovery.test.ts +173 -0
- package/src/platform/thinq/thinqDeviceDiscovery.ts +51 -0
- package/src/platform/thinq/thinqWasherCommandHandlers.ts +120 -0
- package/src/platform/thinq/thinqWasherEndpointFactory.ts +37 -0
- package/src/platform/thinq/thinqWasherStateSync.ts +60 -0
- package/src/platform/thinq/thinqWasherStopCommandResolver.ts +62 -0
- package/src/services/authentication/AccountAuthStrategy.test.ts +358 -0
- package/src/services/authentication/AccountAuthStrategy.ts +209 -0
- package/src/services/authentication/AuthContext.ts +19 -0
- package/src/services/authentication/AuthenticationCoordinator.test.ts +217 -0
- package/src/services/authentication/AuthenticationCoordinator.ts +59 -0
- package/src/services/authentication/IAuthStrategy.ts +10 -0
- package/src/services/authentication/TokenAuthStrategy.test.ts +167 -0
- package/src/services/authentication/TokenAuthStrategy.ts +40 -0
- package/src/services/authentication/UserDataRepository.test.ts +149 -0
- package/src/services/authentication/UserDataRepository.ts +46 -0
- package/src/services/thinq/gateway.ts +86 -0
- package/src/services/thinq/mqtt/mqttCertificate.test.ts +344 -0
- package/src/services/thinq/mqtt/mqttCertificate.ts +102 -0
- package/src/services/thinq/mqtt/mqttConnectionEvents.test.ts +276 -0
- package/src/services/thinq/mqtt/mqttConnectionEvents.ts +76 -0
- package/src/services/thinq/mqtt/mqttKeyRepository.test.ts +164 -0
- package/src/services/thinq/mqtt/mqttKeyRepository.ts +43 -0
- package/src/services/thinq/mqtt/mqttRetry.test.ts +239 -0
- package/src/services/thinq/mqtt/mqttRetry.ts +43 -0
- package/src/services/thinq/mqtt/thinqMqttListener.test.ts +349 -0
- package/src/services/thinq/mqtt/thinqMqttListener.ts +120 -0
- package/src/services/thinq/serviceContainer.test.ts +203 -0
- package/src/services/thinq/serviceContainer.ts +105 -0
- package/src/services/thinq/session.test.ts +287 -0
- package/src/services/thinq/session.ts +69 -0
- package/src/services/thinq/thinqApiClient.test.ts +702 -0
- package/src/services/thinq/thinqApiClient.ts +418 -0
- package/src/services/thinq/thinqDeviceService.test.ts +415 -0
- package/src/services/thinq/thinqDeviceService.ts +101 -0
- package/src/services/thinq/thinqFilterMonitoringService.test.ts +264 -0
- package/src/services/thinq/thinqFilterMonitoringService.ts +53 -0
- package/src/settings.ts +18 -0
- package/src/tests/cli/commands/devices.test.ts +293 -0
- package/src/tests/cli/commands/login.test.ts +240 -0
- package/src/tests/cli/help.test.ts +46 -0
- package/src/tests/cli/main.test.ts +214 -0
- package/src/tests/cli/session.test.ts +198 -0
- package/src/tests/cli/utils.test.ts +194 -0
- package/src/tests/core/domain/value-objects/AirConditionerCapabilities.test.ts +685 -0
- package/src/tests/core/domain/value-objects/ThinqFilterState.test.ts +210 -0
- package/src/tests/core/domain/value-objects/ThinqSnapshot.test.ts +1035 -0
- package/src/tests/helpers/testUtils.ts +118 -0
- package/src/tests/model/LgThinqPluginPlatformConfig.test.ts +81 -0
- package/src/tests/platform/deviceRegistry.test.ts +177 -0
- package/src/tests/platform/platformConfigManager.test.ts +790 -0
- package/src/tests/platform/platformState.test.ts +41 -0
- package/src/tests/platform/thinq/thinqAirConditionerCommandHandlers.test.ts +879 -0
- package/src/tests/platform/thinq/thinqAirConditionerEndpointFactory.test.ts +993 -0
- package/src/tests/platform/thinq/thinqAirConditionerFilterResetCommandHandler.test.ts +508 -0
- package/src/tests/platform/thinq/thinqAirConditionerFilterStateSync.test.ts +212 -0
- package/src/tests/platform/thinq/thinqAirConditionerStateSync.test.ts +1586 -0
- package/src/tests/platform/thinq/thinqDeviceConfigReconciler.test.ts +269 -0
- package/src/tests/platform/thinq/thinqDeviceConfigurator.test.ts +492 -0
- package/src/tests/platform/thinq/thinqWasherCommandHandlers.test.ts +594 -0
- package/src/tests/platform/thinq/thinqWasherEndpointFactory.test.ts +84 -0
- package/src/tests/platform/thinq/thinqWasherStateSync.test.ts +373 -0
- package/src/tests/platform/thinq/thinqWasherStopCommandResolver.test.ts +392 -0
- package/src/tests/settings.test.ts +33 -0
- package/src/utils/mask.ts +50 -0
- package/tsconfig.base.json +25 -0
- package/tsconfig.json +9 -0
- package/tsconfig.production.json +13 -0
- package/tsconfig.vitest.json +5 -0
- package/vite.config.ts +43 -0
- package/wiki/memory-archive.md +12 -0
- package/wiki/reference-workspaces.md +23 -0
|
@@ -0,0 +1,685 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
DEFAULT_AIR_CONDITIONER_CAPABILITIES,
|
|
5
|
+
resolveAirConditionerCapabilities,
|
|
6
|
+
} from '../../../../core/domain/value-objects/AirConditionerCapabilities.js';
|
|
7
|
+
import type { ThinqDeviceConfigEntry } from '../../../../model/LgThinqPluginPlatformConfig.js';
|
|
8
|
+
|
|
9
|
+
describe('AirConditionerCapabilities', () => {
|
|
10
|
+
describe('DEFAULT_AIR_CONDITIONER_CAPABILITIES', () => {
|
|
11
|
+
it('should have existing capabilities set to true', () => {
|
|
12
|
+
// Assert
|
|
13
|
+
expect(DEFAULT_AIR_CONDITIONER_CAPABILITIES.supportsHeat).toBe(true);
|
|
14
|
+
expect(DEFAULT_AIR_CONDITIONER_CAPABILITIES.supportsFanSpeedControl).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('should have Phase B swing mode capability set to false (opt-in)', () => {
|
|
18
|
+
// Assert
|
|
19
|
+
expect(DEFAULT_AIR_CONDITIONER_CAPABILITIES.supportsSwingMode).toBe(false);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should have Phase C sensor capabilities set to false (opt-in)', () => {
|
|
23
|
+
// Assert
|
|
24
|
+
expect(DEFAULT_AIR_CONDITIONER_CAPABILITIES.supportsHumiditySensor).toBe(false);
|
|
25
|
+
expect(DEFAULT_AIR_CONDITIONER_CAPABILITIES.supportsAirQualitySensor).toBe(false);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should have Phase D energy monitoring capability set to false (opt-in)', () => {
|
|
29
|
+
// Assert
|
|
30
|
+
expect(DEFAULT_AIR_CONDITIONER_CAPABILITIES.supportsEnergyMonitoring).toBe(false);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('should have filter monitoring capability set to false (opt-in)', () => {
|
|
34
|
+
// Assert
|
|
35
|
+
expect(DEFAULT_AIR_CONDITIONER_CAPABILITIES.supportsFilterMonitoring).toBe(false);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('resolveAirConditionerCapabilities', () => {
|
|
40
|
+
it('should return all-true default when devices array is undefined', () => {
|
|
41
|
+
// Arrange & Act
|
|
42
|
+
const result = resolveAirConditionerCapabilities(undefined, 'device-123');
|
|
43
|
+
|
|
44
|
+
// Assert
|
|
45
|
+
expect(result).toEqual(DEFAULT_AIR_CONDITIONER_CAPABILITIES);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('should return all-true default when devices array is empty', () => {
|
|
49
|
+
// Arrange & Act
|
|
50
|
+
const result = resolveAirConditionerCapabilities([], 'device-123');
|
|
51
|
+
|
|
52
|
+
// Assert
|
|
53
|
+
expect(result).toEqual(DEFAULT_AIR_CONDITIONER_CAPABILITIES);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should return all-true default when device is not found in array', () => {
|
|
57
|
+
// Arrange
|
|
58
|
+
const devices: ThinqDeviceConfigEntry[] = [{ deviceId: 'device-999', capabilities: { supportsHeat: false } }];
|
|
59
|
+
|
|
60
|
+
// Act
|
|
61
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
62
|
+
|
|
63
|
+
// Assert
|
|
64
|
+
expect(result).toEqual(DEFAULT_AIR_CONDITIONER_CAPABILITIES);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should return all-true default when device is found but has no capabilities key', () => {
|
|
68
|
+
// Arrange
|
|
69
|
+
const devices: ThinqDeviceConfigEntry[] = [{ deviceId: 'device-123' }];
|
|
70
|
+
|
|
71
|
+
// Act
|
|
72
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
73
|
+
|
|
74
|
+
// Assert
|
|
75
|
+
expect(result).toEqual(DEFAULT_AIR_CONDITIONER_CAPABILITIES);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('should override supportsHeat only when specified', () => {
|
|
79
|
+
// Arrange
|
|
80
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
81
|
+
{
|
|
82
|
+
deviceId: 'device-123',
|
|
83
|
+
capabilities: { supportsHeat: false },
|
|
84
|
+
},
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
// Act
|
|
88
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
89
|
+
|
|
90
|
+
// Assert
|
|
91
|
+
expect(result.supportsHeat).toBe(false);
|
|
92
|
+
expect(result.supportsFanSpeedControl).toBe(true); // default
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('should override supportsFanSpeedControl only when specified', () => {
|
|
96
|
+
// Arrange
|
|
97
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
98
|
+
{
|
|
99
|
+
deviceId: 'device-123',
|
|
100
|
+
capabilities: { supportsFanSpeedControl: false },
|
|
101
|
+
},
|
|
102
|
+
];
|
|
103
|
+
|
|
104
|
+
// Act
|
|
105
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
106
|
+
|
|
107
|
+
// Assert
|
|
108
|
+
expect(result.supportsHeat).toBe(true); // default
|
|
109
|
+
expect(result.supportsFanSpeedControl).toBe(false);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('should override all three flags when all are specified as false', () => {
|
|
113
|
+
// Arrange
|
|
114
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
115
|
+
{
|
|
116
|
+
deviceId: 'device-123',
|
|
117
|
+
capabilities: {
|
|
118
|
+
supportsHeat: false,
|
|
119
|
+
supportsFanSpeedControl: false,
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
];
|
|
123
|
+
|
|
124
|
+
// Act
|
|
125
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
126
|
+
|
|
127
|
+
// Assert
|
|
128
|
+
expect(result.supportsHeat).toBe(false);
|
|
129
|
+
expect(result.supportsFanSpeedControl).toBe(false);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('should resolve correct device from multiple entries in array', () => {
|
|
133
|
+
// Arrange
|
|
134
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
135
|
+
{ deviceId: 'device-001', capabilities: { supportsHeat: false } },
|
|
136
|
+
{ deviceId: 'device-123', capabilities: { supportsSwingMode: true } },
|
|
137
|
+
{ deviceId: 'device-999', capabilities: { supportsFanSpeedControl: false } },
|
|
138
|
+
];
|
|
139
|
+
|
|
140
|
+
// Act
|
|
141
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
142
|
+
|
|
143
|
+
// Assert
|
|
144
|
+
expect(result.supportsHeat).toBe(true); // default
|
|
145
|
+
expect(result.supportsSwingMode).toBe(true); // from device-123
|
|
146
|
+
expect(result.supportsFanSpeedControl).toBe(true); // default
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it('should preserve readonly properties', () => {
|
|
150
|
+
// Arrange
|
|
151
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
152
|
+
{
|
|
153
|
+
deviceId: 'device-123',
|
|
154
|
+
capabilities: { supportsHeat: false, supportsFanSpeedControl: true },
|
|
155
|
+
},
|
|
156
|
+
];
|
|
157
|
+
|
|
158
|
+
// Act
|
|
159
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
160
|
+
|
|
161
|
+
// Assert
|
|
162
|
+
expect(Object.getOwnPropertyDescriptor(result, 'supportsHeat')?.writable).not.toBe(false);
|
|
163
|
+
// Result is not frozen, it's just a regular object with readonly interface
|
|
164
|
+
expect(result).toEqual({
|
|
165
|
+
supportsHeat: false,
|
|
166
|
+
supportsFanSpeedControl: true,
|
|
167
|
+
supportsSwingMode: false,
|
|
168
|
+
supportsHumiditySensor: false,
|
|
169
|
+
supportsAirQualitySensor: false,
|
|
170
|
+
supportsEnergyMonitoring: false,
|
|
171
|
+
supportsFilterMonitoring: false,
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it('should handle device with capabilities object but undefined individual properties', () => {
|
|
176
|
+
// Arrange
|
|
177
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
178
|
+
{
|
|
179
|
+
deviceId: 'device-123',
|
|
180
|
+
capabilities: {
|
|
181
|
+
supportsHeat: undefined,
|
|
182
|
+
supportsFanSpeedControl: undefined,
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
];
|
|
186
|
+
|
|
187
|
+
// Act
|
|
188
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
189
|
+
|
|
190
|
+
// Assert
|
|
191
|
+
expect(result.supportsHeat).toBe(true); // defaults to true when undefined
|
|
192
|
+
expect(result.supportsFanSpeedControl).toBe(true); // defaults to true when undefined
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('should handle explicit true values for all capabilities', () => {
|
|
196
|
+
// Arrange
|
|
197
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
198
|
+
{
|
|
199
|
+
deviceId: 'device-123',
|
|
200
|
+
capabilities: {
|
|
201
|
+
supportsHeat: true,
|
|
202
|
+
supportsFanSpeedControl: true,
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
];
|
|
206
|
+
|
|
207
|
+
// Act
|
|
208
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
209
|
+
|
|
210
|
+
// Assert
|
|
211
|
+
expect(result).toEqual(DEFAULT_AIR_CONDITIONER_CAPABILITIES);
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('should default supportsSwingMode to false when undefined (Phase B)', () => {
|
|
215
|
+
// Arrange
|
|
216
|
+
const devices: ThinqDeviceConfigEntry[] = [{ deviceId: 'device-123', capabilities: {} }];
|
|
217
|
+
|
|
218
|
+
// Act
|
|
219
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
220
|
+
|
|
221
|
+
// Assert
|
|
222
|
+
expect(result.supportsSwingMode).toBe(false);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it('should override supportsSwingMode when specified as true (Phase B)', () => {
|
|
226
|
+
// Arrange
|
|
227
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
228
|
+
{
|
|
229
|
+
deviceId: 'device-123',
|
|
230
|
+
capabilities: { supportsSwingMode: true },
|
|
231
|
+
},
|
|
232
|
+
];
|
|
233
|
+
|
|
234
|
+
// Act
|
|
235
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
236
|
+
|
|
237
|
+
// Assert
|
|
238
|
+
expect(result.supportsSwingMode).toBe(true);
|
|
239
|
+
// Verify other flags remain at their defaults
|
|
240
|
+
expect(result.supportsHeat).toBe(true);
|
|
241
|
+
expect(result.supportsFanSpeedControl).toBe(true);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
it('should override supportsSwingMode when specified as false (Phase B)', () => {
|
|
245
|
+
// Arrange
|
|
246
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
247
|
+
{
|
|
248
|
+
deviceId: 'device-123',
|
|
249
|
+
capabilities: { supportsSwingMode: false },
|
|
250
|
+
},
|
|
251
|
+
];
|
|
252
|
+
|
|
253
|
+
// Act
|
|
254
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
255
|
+
|
|
256
|
+
// Assert
|
|
257
|
+
expect(result.supportsSwingMode).toBe(false);
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it('should enable supportsSwingMode with other capabilities (Phase B)', () => {
|
|
261
|
+
// Arrange
|
|
262
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
263
|
+
{
|
|
264
|
+
deviceId: 'device-123',
|
|
265
|
+
capabilities: {
|
|
266
|
+
supportsSwingMode: true,
|
|
267
|
+
supportsHeat: true,
|
|
268
|
+
supportsFanSpeedControl: true,
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
];
|
|
272
|
+
|
|
273
|
+
// Act
|
|
274
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
275
|
+
|
|
276
|
+
// Assert
|
|
277
|
+
expect(result.supportsSwingMode).toBe(true);
|
|
278
|
+
expect(result.supportsHeat).toBe(true);
|
|
279
|
+
expect(result.supportsFanSpeedControl).toBe(true);
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
it('should default supportsHumiditySensor to false when undefined (Phase C)', () => {
|
|
283
|
+
// Arrange
|
|
284
|
+
const devices: ThinqDeviceConfigEntry[] = [{ deviceId: 'device-123', capabilities: {} }];
|
|
285
|
+
|
|
286
|
+
// Act
|
|
287
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
288
|
+
|
|
289
|
+
// Assert
|
|
290
|
+
expect(result.supportsHumiditySensor).toBe(false);
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
it('should override supportsHumiditySensor when specified as true (Phase C)', () => {
|
|
294
|
+
// Arrange
|
|
295
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
296
|
+
{
|
|
297
|
+
deviceId: 'device-123',
|
|
298
|
+
capabilities: { supportsHumiditySensor: true },
|
|
299
|
+
},
|
|
300
|
+
];
|
|
301
|
+
|
|
302
|
+
// Act
|
|
303
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
304
|
+
|
|
305
|
+
// Assert
|
|
306
|
+
expect(result.supportsHumiditySensor).toBe(true);
|
|
307
|
+
// Verify other flags remain at their defaults
|
|
308
|
+
expect(result.supportsHeat).toBe(true);
|
|
309
|
+
expect(result.supportsFanSpeedControl).toBe(true);
|
|
310
|
+
expect(result.supportsAirQualitySensor).toBe(false);
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it('should default supportsAirQualitySensor to false when undefined (Phase C)', () => {
|
|
314
|
+
// Arrange
|
|
315
|
+
const devices: ThinqDeviceConfigEntry[] = [{ deviceId: 'device-123', capabilities: {} }];
|
|
316
|
+
|
|
317
|
+
// Act
|
|
318
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
319
|
+
|
|
320
|
+
// Assert
|
|
321
|
+
expect(result.supportsAirQualitySensor).toBe(false);
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
it('should override supportsAirQualitySensor when specified as true (Phase C)', () => {
|
|
325
|
+
// Arrange
|
|
326
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
327
|
+
{
|
|
328
|
+
deviceId: 'device-123',
|
|
329
|
+
capabilities: { supportsAirQualitySensor: true },
|
|
330
|
+
},
|
|
331
|
+
];
|
|
332
|
+
|
|
333
|
+
// Act
|
|
334
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
335
|
+
|
|
336
|
+
// Assert
|
|
337
|
+
expect(result.supportsAirQualitySensor).toBe(true);
|
|
338
|
+
// Verify other flags remain at their defaults
|
|
339
|
+
expect(result.supportsHeat).toBe(true);
|
|
340
|
+
expect(result.supportsFanSpeedControl).toBe(true);
|
|
341
|
+
expect(result.supportsHumiditySensor).toBe(false);
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
it('should enable both Phase C sensor flags simultaneously', () => {
|
|
345
|
+
// Arrange
|
|
346
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
347
|
+
{
|
|
348
|
+
deviceId: 'device-123',
|
|
349
|
+
capabilities: {
|
|
350
|
+
supportsHumiditySensor: true,
|
|
351
|
+
supportsAirQualitySensor: true,
|
|
352
|
+
},
|
|
353
|
+
},
|
|
354
|
+
];
|
|
355
|
+
|
|
356
|
+
// Act
|
|
357
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
358
|
+
|
|
359
|
+
// Assert
|
|
360
|
+
expect(result.supportsHumiditySensor).toBe(true);
|
|
361
|
+
expect(result.supportsAirQualitySensor).toBe(true);
|
|
362
|
+
// Verify existing flags still default to true
|
|
363
|
+
expect(result.supportsHeat).toBe(true);
|
|
364
|
+
expect(result.supportsFanSpeedControl).toBe(true);
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
it('should isolate Phase C sensor flags across multiple devices', () => {
|
|
368
|
+
// Arrange
|
|
369
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
370
|
+
{
|
|
371
|
+
deviceId: 'device-001',
|
|
372
|
+
capabilities: { supportsHumiditySensor: true },
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
deviceId: 'device-002',
|
|
376
|
+
capabilities: { supportsAirQualitySensor: true },
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
deviceId: 'device-003',
|
|
380
|
+
capabilities: {},
|
|
381
|
+
},
|
|
382
|
+
];
|
|
383
|
+
|
|
384
|
+
// Act
|
|
385
|
+
const result001 = resolveAirConditionerCapabilities(devices, 'device-001');
|
|
386
|
+
const result002 = resolveAirConditionerCapabilities(devices, 'device-002');
|
|
387
|
+
const result003 = resolveAirConditionerCapabilities(devices, 'device-003');
|
|
388
|
+
|
|
389
|
+
// Assert
|
|
390
|
+
expect(result001.supportsHumiditySensor).toBe(true);
|
|
391
|
+
expect(result001.supportsAirQualitySensor).toBe(false);
|
|
392
|
+
expect(result002.supportsHumiditySensor).toBe(false);
|
|
393
|
+
expect(result002.supportsAirQualitySensor).toBe(true);
|
|
394
|
+
expect(result003.supportsHumiditySensor).toBe(false);
|
|
395
|
+
expect(result003.supportsAirQualitySensor).toBe(false);
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
it('should preserve full default object with all Phase C flags included', () => {
|
|
399
|
+
// Arrange
|
|
400
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
401
|
+
{
|
|
402
|
+
deviceId: 'device-123',
|
|
403
|
+
capabilities: {
|
|
404
|
+
supportsHeat: true,
|
|
405
|
+
supportsFanSpeedControl: true,
|
|
406
|
+
},
|
|
407
|
+
},
|
|
408
|
+
];
|
|
409
|
+
|
|
410
|
+
// Act
|
|
411
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
412
|
+
|
|
413
|
+
// Assert
|
|
414
|
+
expect(result).toEqual({
|
|
415
|
+
supportsHeat: true,
|
|
416
|
+
supportsFanSpeedControl: true,
|
|
417
|
+
supportsSwingMode: false,
|
|
418
|
+
supportsHumiditySensor: false,
|
|
419
|
+
supportsAirQualitySensor: false,
|
|
420
|
+
supportsEnergyMonitoring: false,
|
|
421
|
+
supportsFilterMonitoring: false,
|
|
422
|
+
});
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
it('should default supportsEnergyMonitoring to false when undefined (Phase D)', () => {
|
|
426
|
+
// Arrange
|
|
427
|
+
const devices: ThinqDeviceConfigEntry[] = [{ deviceId: 'device-123', capabilities: {} }];
|
|
428
|
+
|
|
429
|
+
// Act
|
|
430
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
431
|
+
|
|
432
|
+
// Assert
|
|
433
|
+
expect(result.supportsEnergyMonitoring).toBe(false);
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
it('should override supportsEnergyMonitoring when specified as true (Phase D)', () => {
|
|
437
|
+
// Arrange
|
|
438
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
439
|
+
{
|
|
440
|
+
deviceId: 'device-123',
|
|
441
|
+
capabilities: { supportsEnergyMonitoring: true },
|
|
442
|
+
},
|
|
443
|
+
];
|
|
444
|
+
|
|
445
|
+
// Act
|
|
446
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
447
|
+
|
|
448
|
+
// Assert
|
|
449
|
+
expect(result.supportsEnergyMonitoring).toBe(true);
|
|
450
|
+
// Verify other flags remain at their defaults
|
|
451
|
+
expect(result.supportsHeat).toBe(true);
|
|
452
|
+
expect(result.supportsFanSpeedControl).toBe(true);
|
|
453
|
+
expect(result.supportsHumiditySensor).toBe(false);
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
it('should override supportsEnergyMonitoring when specified as false (Phase D)', () => {
|
|
457
|
+
// Arrange
|
|
458
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
459
|
+
{
|
|
460
|
+
deviceId: 'device-123',
|
|
461
|
+
capabilities: { supportsEnergyMonitoring: false },
|
|
462
|
+
},
|
|
463
|
+
];
|
|
464
|
+
|
|
465
|
+
// Act
|
|
466
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
467
|
+
|
|
468
|
+
// Assert
|
|
469
|
+
expect(result.supportsEnergyMonitoring).toBe(false);
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
it('should combine supportsEnergyMonitoring with other Phase D and earlier flags', () => {
|
|
473
|
+
// Arrange
|
|
474
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
475
|
+
{
|
|
476
|
+
deviceId: 'device-123',
|
|
477
|
+
capabilities: {
|
|
478
|
+
supportsEnergyMonitoring: true,
|
|
479
|
+
supportsHumiditySensor: true,
|
|
480
|
+
supportsAirQualitySensor: true,
|
|
481
|
+
supportsSwingMode: true,
|
|
482
|
+
},
|
|
483
|
+
},
|
|
484
|
+
];
|
|
485
|
+
|
|
486
|
+
// Act
|
|
487
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
488
|
+
|
|
489
|
+
// Assert
|
|
490
|
+
expect(result.supportsEnergyMonitoring).toBe(true);
|
|
491
|
+
expect(result.supportsHumiditySensor).toBe(true);
|
|
492
|
+
expect(result.supportsAirQualitySensor).toBe(true);
|
|
493
|
+
expect(result.supportsSwingMode).toBe(true);
|
|
494
|
+
// Existing flags should still default to true
|
|
495
|
+
expect(result.supportsHeat).toBe(true);
|
|
496
|
+
expect(result.supportsFanSpeedControl).toBe(true);
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
it('should isolate Phase D energy monitoring flag across multiple devices', () => {
|
|
500
|
+
// Arrange
|
|
501
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
502
|
+
{
|
|
503
|
+
deviceId: 'device-001',
|
|
504
|
+
capabilities: { supportsEnergyMonitoring: true },
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
deviceId: 'device-002',
|
|
508
|
+
capabilities: { supportsEnergyMonitoring: false },
|
|
509
|
+
},
|
|
510
|
+
{
|
|
511
|
+
deviceId: 'device-003',
|
|
512
|
+
capabilities: {},
|
|
513
|
+
},
|
|
514
|
+
];
|
|
515
|
+
|
|
516
|
+
// Act
|
|
517
|
+
const result001 = resolveAirConditionerCapabilities(devices, 'device-001');
|
|
518
|
+
const result002 = resolveAirConditionerCapabilities(devices, 'device-002');
|
|
519
|
+
const result003 = resolveAirConditionerCapabilities(devices, 'device-003');
|
|
520
|
+
|
|
521
|
+
// Assert
|
|
522
|
+
expect(result001.supportsEnergyMonitoring).toBe(true);
|
|
523
|
+
expect(result002.supportsEnergyMonitoring).toBe(false);
|
|
524
|
+
expect(result003.supportsEnergyMonitoring).toBe(false);
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
it('should preserve full default object with all Phase D flags included', () => {
|
|
528
|
+
// Arrange
|
|
529
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
530
|
+
{
|
|
531
|
+
deviceId: 'device-123',
|
|
532
|
+
capabilities: {
|
|
533
|
+
supportsHeat: true,
|
|
534
|
+
supportsFanSpeedControl: true,
|
|
535
|
+
supportsEnergyMonitoring: false,
|
|
536
|
+
},
|
|
537
|
+
},
|
|
538
|
+
];
|
|
539
|
+
|
|
540
|
+
// Act
|
|
541
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
542
|
+
|
|
543
|
+
// Assert
|
|
544
|
+
expect(result).toEqual({
|
|
545
|
+
supportsHeat: true,
|
|
546
|
+
supportsFanSpeedControl: true,
|
|
547
|
+
supportsSwingMode: false,
|
|
548
|
+
supportsHumiditySensor: false,
|
|
549
|
+
supportsAirQualitySensor: false,
|
|
550
|
+
supportsEnergyMonitoring: false,
|
|
551
|
+
supportsFilterMonitoring: false,
|
|
552
|
+
});
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
it('should default supportsFilterMonitoring to false when undefined', () => {
|
|
556
|
+
// Arrange
|
|
557
|
+
const devices: ThinqDeviceConfigEntry[] = [{ deviceId: 'device-123', capabilities: {} }];
|
|
558
|
+
|
|
559
|
+
// Act
|
|
560
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
561
|
+
|
|
562
|
+
// Assert
|
|
563
|
+
expect(result.supportsFilterMonitoring).toBe(false);
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
it('should override supportsFilterMonitoring when specified as true', () => {
|
|
567
|
+
// Arrange
|
|
568
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
569
|
+
{
|
|
570
|
+
deviceId: 'device-123',
|
|
571
|
+
capabilities: { supportsFilterMonitoring: true },
|
|
572
|
+
},
|
|
573
|
+
];
|
|
574
|
+
|
|
575
|
+
// Act
|
|
576
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
577
|
+
|
|
578
|
+
// Assert
|
|
579
|
+
expect(result.supportsFilterMonitoring).toBe(true);
|
|
580
|
+
// Verify other flags remain at their defaults
|
|
581
|
+
expect(result.supportsHeat).toBe(true);
|
|
582
|
+
expect(result.supportsFanSpeedControl).toBe(true);
|
|
583
|
+
expect(result.supportsEnergyMonitoring).toBe(false);
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
it('should override supportsFilterMonitoring when specified as false', () => {
|
|
587
|
+
// Arrange
|
|
588
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
589
|
+
{
|
|
590
|
+
deviceId: 'device-123',
|
|
591
|
+
capabilities: { supportsFilterMonitoring: false },
|
|
592
|
+
},
|
|
593
|
+
];
|
|
594
|
+
|
|
595
|
+
// Act
|
|
596
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
597
|
+
|
|
598
|
+
// Assert
|
|
599
|
+
expect(result.supportsFilterMonitoring).toBe(false);
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
it('should combine supportsFilterMonitoring with other flags', () => {
|
|
603
|
+
// Arrange
|
|
604
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
605
|
+
{
|
|
606
|
+
deviceId: 'device-123',
|
|
607
|
+
capabilities: {
|
|
608
|
+
supportsFilterMonitoring: true,
|
|
609
|
+
supportsEnergyMonitoring: true,
|
|
610
|
+
supportsHumiditySensor: true,
|
|
611
|
+
supportsSwingMode: true,
|
|
612
|
+
},
|
|
613
|
+
},
|
|
614
|
+
];
|
|
615
|
+
|
|
616
|
+
// Act
|
|
617
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
618
|
+
|
|
619
|
+
// Assert
|
|
620
|
+
expect(result.supportsFilterMonitoring).toBe(true);
|
|
621
|
+
expect(result.supportsEnergyMonitoring).toBe(true);
|
|
622
|
+
expect(result.supportsHumiditySensor).toBe(true);
|
|
623
|
+
expect(result.supportsSwingMode).toBe(true);
|
|
624
|
+
// Existing flags should still default to true
|
|
625
|
+
expect(result.supportsHeat).toBe(true);
|
|
626
|
+
expect(result.supportsFanSpeedControl).toBe(true);
|
|
627
|
+
});
|
|
628
|
+
|
|
629
|
+
it('should isolate filter monitoring flag across multiple devices', () => {
|
|
630
|
+
// Arrange
|
|
631
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
632
|
+
{
|
|
633
|
+
deviceId: 'device-001',
|
|
634
|
+
capabilities: { supportsFilterMonitoring: true },
|
|
635
|
+
},
|
|
636
|
+
{
|
|
637
|
+
deviceId: 'device-002',
|
|
638
|
+
capabilities: { supportsFilterMonitoring: false },
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
deviceId: 'device-003',
|
|
642
|
+
capabilities: {},
|
|
643
|
+
},
|
|
644
|
+
];
|
|
645
|
+
|
|
646
|
+
// Act
|
|
647
|
+
const result001 = resolveAirConditionerCapabilities(devices, 'device-001');
|
|
648
|
+
const result002 = resolveAirConditionerCapabilities(devices, 'device-002');
|
|
649
|
+
const result003 = resolveAirConditionerCapabilities(devices, 'device-003');
|
|
650
|
+
|
|
651
|
+
// Assert
|
|
652
|
+
expect(result001.supportsFilterMonitoring).toBe(true);
|
|
653
|
+
expect(result002.supportsFilterMonitoring).toBe(false);
|
|
654
|
+
expect(result003.supportsFilterMonitoring).toBe(false);
|
|
655
|
+
});
|
|
656
|
+
|
|
657
|
+
it('should preserve full default object with all flags including filter monitoring', () => {
|
|
658
|
+
// Arrange
|
|
659
|
+
const devices: ThinqDeviceConfigEntry[] = [
|
|
660
|
+
{
|
|
661
|
+
deviceId: 'device-123',
|
|
662
|
+
capabilities: {
|
|
663
|
+
supportsHeat: true,
|
|
664
|
+
supportsFanSpeedControl: true,
|
|
665
|
+
supportsFilterMonitoring: true,
|
|
666
|
+
},
|
|
667
|
+
},
|
|
668
|
+
];
|
|
669
|
+
|
|
670
|
+
// Act
|
|
671
|
+
const result = resolveAirConditionerCapabilities(devices, 'device-123');
|
|
672
|
+
|
|
673
|
+
// Assert
|
|
674
|
+
expect(result).toEqual({
|
|
675
|
+
supportsHeat: true,
|
|
676
|
+
supportsFanSpeedControl: true,
|
|
677
|
+
supportsSwingMode: false,
|
|
678
|
+
supportsHumiditySensor: false,
|
|
679
|
+
supportsAirQualitySensor: false,
|
|
680
|
+
supportsEnergyMonitoring: false,
|
|
681
|
+
supportsFilterMonitoring: true,
|
|
682
|
+
});
|
|
683
|
+
});
|
|
684
|
+
});
|
|
685
|
+
});
|