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,790 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import type { LgThinqPluginPlatformConfig } from '../../model/LgThinqPluginPlatformConfig.js';
|
|
4
|
+
import { PlatformConfigManager } from '../../platform/platformConfigManager.js';
|
|
5
|
+
import { asPartial, createMockLogger } from '../helpers/testUtils.js';
|
|
6
|
+
|
|
7
|
+
describe('PlatformConfigManager', () => {
|
|
8
|
+
let mockLogger: ReturnType<typeof createMockLogger>;
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
vi.clearAllMocks();
|
|
12
|
+
mockLogger = createMockLogger();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
describe('create', () => {
|
|
16
|
+
it('should apply defaults when thinq/webos/advancedFeature are undefined', () => {
|
|
17
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({});
|
|
18
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
19
|
+
|
|
20
|
+
expect(manager.rawConfig.thinq).toEqual({
|
|
21
|
+
loginType: 'account',
|
|
22
|
+
country: 'US',
|
|
23
|
+
language: 'en-US',
|
|
24
|
+
devices: [],
|
|
25
|
+
});
|
|
26
|
+
expect(manager.rawConfig.webos).toEqual({ devices: [] });
|
|
27
|
+
expect(manager.rawConfig.advancedFeature).toEqual({
|
|
28
|
+
settings: {
|
|
29
|
+
debug: false,
|
|
30
|
+
clearStorageOnStartup: false,
|
|
31
|
+
forceAuthentication: false,
|
|
32
|
+
unregisterOnShutdown: false,
|
|
33
|
+
overrideMatterConfiguration: false,
|
|
34
|
+
matterOverrideSettings: {
|
|
35
|
+
matterVendorName: 'Matterbridge',
|
|
36
|
+
matterVendorId: 0xfff1,
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('should preserve existing values and not overwrite them', () => {
|
|
43
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
44
|
+
thinq: {
|
|
45
|
+
loginType: 'token',
|
|
46
|
+
country: 'KR',
|
|
47
|
+
language: 'ko-KR',
|
|
48
|
+
refreshToken: 'test-token',
|
|
49
|
+
devices: [],
|
|
50
|
+
},
|
|
51
|
+
webos: { devices: ['device1'] as unknown as unknown[] },
|
|
52
|
+
advancedFeature: {
|
|
53
|
+
settings: {
|
|
54
|
+
debug: true,
|
|
55
|
+
clearStorageOnStartup: true,
|
|
56
|
+
forceAuthentication: true,
|
|
57
|
+
unregisterOnShutdown: true,
|
|
58
|
+
overrideMatterConfiguration: false,
|
|
59
|
+
matterOverrideSettings: {
|
|
60
|
+
matterVendorName: 'Matterbridge',
|
|
61
|
+
matterVendorId: 0xfff1,
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
67
|
+
|
|
68
|
+
expect(manager.rawConfig.thinq.loginType).toBe('token');
|
|
69
|
+
expect(manager.rawConfig.thinq.country).toBe('KR');
|
|
70
|
+
expect(manager.rawConfig.thinq.language).toBe('ko-KR');
|
|
71
|
+
expect(manager.rawConfig.advancedFeature.settings.debug).toBe(true);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
describe('rawConfig getter', () => {
|
|
76
|
+
it('should return the raw config object', () => {
|
|
77
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
78
|
+
thinq: { loginType: 'token', country: 'US', language: 'en-US', refreshToken: 'token', devices: [] },
|
|
79
|
+
});
|
|
80
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
81
|
+
|
|
82
|
+
expect(manager.rawConfig).toBe(config);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
describe('debug getter', () => {
|
|
87
|
+
it('should return debug setting from advancedFeature', () => {
|
|
88
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
89
|
+
advancedFeature: {
|
|
90
|
+
settings: {
|
|
91
|
+
debug: true,
|
|
92
|
+
clearStorageOnStartup: false,
|
|
93
|
+
forceAuthentication: false,
|
|
94
|
+
unregisterOnShutdown: false,
|
|
95
|
+
overrideMatterConfiguration: false,
|
|
96
|
+
matterOverrideSettings: {
|
|
97
|
+
matterVendorName: 'Matterbridge',
|
|
98
|
+
matterVendorId: 0xfff1,
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
104
|
+
|
|
105
|
+
expect(manager.debug).toBe(true);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
describe('isClearStorageOnStartupEnabled getter', () => {
|
|
110
|
+
it('should return clearStorageOnStartup setting', () => {
|
|
111
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
112
|
+
advancedFeature: {
|
|
113
|
+
settings: {
|
|
114
|
+
debug: false,
|
|
115
|
+
clearStorageOnStartup: true,
|
|
116
|
+
forceAuthentication: false,
|
|
117
|
+
unregisterOnShutdown: false,
|
|
118
|
+
overrideMatterConfiguration: false,
|
|
119
|
+
matterOverrideSettings: {
|
|
120
|
+
matterVendorName: 'Matterbridge',
|
|
121
|
+
matterVendorId: 0xfff1,
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
127
|
+
|
|
128
|
+
expect(manager.isClearStorageOnStartupEnabled).toBe(true);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
describe('isForceAuthenticationEnabled getter', () => {
|
|
133
|
+
it('should return forceAuthentication setting', () => {
|
|
134
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
135
|
+
advancedFeature: {
|
|
136
|
+
settings: {
|
|
137
|
+
debug: false,
|
|
138
|
+
clearStorageOnStartup: false,
|
|
139
|
+
forceAuthentication: true,
|
|
140
|
+
unregisterOnShutdown: false,
|
|
141
|
+
overrideMatterConfiguration: false,
|
|
142
|
+
matterOverrideSettings: {
|
|
143
|
+
matterVendorName: 'Matterbridge',
|
|
144
|
+
matterVendorId: 0xfff1,
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
150
|
+
|
|
151
|
+
expect(manager.isForceAuthenticationEnabled).toBe(true);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
describe('unregisterOnShutdown getter', () => {
|
|
156
|
+
it('should return unregisterOnShutdown setting', () => {
|
|
157
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
158
|
+
advancedFeature: {
|
|
159
|
+
settings: {
|
|
160
|
+
debug: false,
|
|
161
|
+
clearStorageOnStartup: false,
|
|
162
|
+
forceAuthentication: false,
|
|
163
|
+
unregisterOnShutdown: true,
|
|
164
|
+
overrideMatterConfiguration: false,
|
|
165
|
+
matterOverrideSettings: {
|
|
166
|
+
matterVendorName: 'Matterbridge',
|
|
167
|
+
matterVendorId: 0xfff1,
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
173
|
+
|
|
174
|
+
expect(manager.unregisterOnShutdown).toBe(true);
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
describe('thinqLoginType getter', () => {
|
|
179
|
+
it('should return loginType from thinq config', () => {
|
|
180
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
181
|
+
thinq: { loginType: 'token', country: 'US', language: 'en-US', devices: [] },
|
|
182
|
+
});
|
|
183
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
184
|
+
|
|
185
|
+
expect(manager.thinqLoginType).toBe('token');
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
describe('thinqUsername getter', () => {
|
|
190
|
+
it('should return username from thinq config', () => {
|
|
191
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
192
|
+
thinq: { loginType: 'account', username: 'test@example.com', country: 'US', language: 'en-US', devices: [] },
|
|
193
|
+
});
|
|
194
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
195
|
+
|
|
196
|
+
expect(manager.thinqUsername).toBe('test@example.com');
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
describe('thinqPassword getter', () => {
|
|
201
|
+
it('should return password from thinq config', () => {
|
|
202
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
203
|
+
thinq: { loginType: 'account', password: 'secret', country: 'US', language: 'en-US', devices: [] },
|
|
204
|
+
});
|
|
205
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
206
|
+
|
|
207
|
+
expect(manager.thinqPassword).toBe('secret');
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
describe('thinqRefreshToken getter', () => {
|
|
212
|
+
it('should return refreshToken from thinq config', () => {
|
|
213
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
214
|
+
thinq: { loginType: 'token', refreshToken: 'refresh-token', country: 'US', language: 'en-US', devices: [] },
|
|
215
|
+
});
|
|
216
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
217
|
+
|
|
218
|
+
expect(manager.thinqRefreshToken).toBe('refresh-token');
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
describe('country getter', () => {
|
|
223
|
+
it('should return country from thinq config', () => {
|
|
224
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
225
|
+
thinq: { loginType: 'account', country: 'KR', language: 'en-US', devices: [] },
|
|
226
|
+
});
|
|
227
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
228
|
+
|
|
229
|
+
expect(manager.country).toBe('KR');
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
describe('language getter', () => {
|
|
234
|
+
it('should return language from thinq config', () => {
|
|
235
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
236
|
+
thinq: { loginType: 'account', country: 'US', language: 'ko-KR', devices: [] },
|
|
237
|
+
});
|
|
238
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
239
|
+
|
|
240
|
+
expect(manager.language).toBe('ko-KR');
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
describe('thinqRefreshIntervalSeconds getter', () => {
|
|
245
|
+
it('should return configured refresh interval when set', () => {
|
|
246
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
247
|
+
thinq: { loginType: 'account', country: 'US', language: 'en-US', refreshIntervalSeconds: 10, devices: [] },
|
|
248
|
+
});
|
|
249
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
250
|
+
|
|
251
|
+
expect(manager.thinqRefreshIntervalSeconds).toBe(10);
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it('should return default refresh interval when not configured', () => {
|
|
255
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
256
|
+
thinq: { loginType: 'account', country: 'US', language: 'en-US', devices: [] },
|
|
257
|
+
});
|
|
258
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
259
|
+
|
|
260
|
+
expect(manager.thinqRefreshIntervalSeconds).toBe(60);
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
describe('thinqFilterMonitoringIntervalSeconds getter', () => {
|
|
265
|
+
it('should return configured filter monitoring interval when set', () => {
|
|
266
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
267
|
+
thinq: {
|
|
268
|
+
loginType: 'account',
|
|
269
|
+
country: 'US',
|
|
270
|
+
language: 'en-US',
|
|
271
|
+
filterMonitoringIntervalSeconds: 900,
|
|
272
|
+
devices: [],
|
|
273
|
+
},
|
|
274
|
+
});
|
|
275
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
276
|
+
|
|
277
|
+
expect(manager.thinqFilterMonitoringIntervalSeconds).toBe(900);
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
it('should return default filter monitoring interval when not configured', () => {
|
|
281
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
282
|
+
thinq: { loginType: 'account', country: 'US', language: 'en-US', devices: [] },
|
|
283
|
+
});
|
|
284
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
285
|
+
|
|
286
|
+
expect(manager.thinqFilterMonitoringIntervalSeconds).toBe(3600);
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
it('should allow custom interval independent of refresh interval', () => {
|
|
290
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
291
|
+
thinq: {
|
|
292
|
+
loginType: 'account',
|
|
293
|
+
country: 'US',
|
|
294
|
+
language: 'en-US',
|
|
295
|
+
refreshIntervalSeconds: 60,
|
|
296
|
+
filterMonitoringIntervalSeconds: 1800,
|
|
297
|
+
devices: [],
|
|
298
|
+
},
|
|
299
|
+
});
|
|
300
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
301
|
+
|
|
302
|
+
expect(manager.thinqRefreshIntervalSeconds).toBe(60);
|
|
303
|
+
expect(manager.thinqFilterMonitoringIntervalSeconds).toBe(1800);
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
describe('validateConfig', () => {
|
|
308
|
+
it('should return true when loginType is token and refreshToken is set', () => {
|
|
309
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
310
|
+
thinq: { loginType: 'token', refreshToken: 'token', country: 'US', language: 'en-US', devices: [] },
|
|
311
|
+
});
|
|
312
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
313
|
+
|
|
314
|
+
expect(manager.validateConfig()).toBe(true);
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
it('should return false when loginType is token and refreshToken is not set', () => {
|
|
318
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
319
|
+
thinq: { loginType: 'token', country: 'US', language: 'en-US', devices: [] },
|
|
320
|
+
});
|
|
321
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
322
|
+
|
|
323
|
+
expect(manager.validateConfig()).toBe(false);
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
it('should return true when loginType is account and both username and password are set', () => {
|
|
327
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
328
|
+
thinq: {
|
|
329
|
+
loginType: 'account',
|
|
330
|
+
username: 'test@example.com',
|
|
331
|
+
password: 'secret',
|
|
332
|
+
country: 'US',
|
|
333
|
+
language: 'en-US',
|
|
334
|
+
devices: [],
|
|
335
|
+
},
|
|
336
|
+
});
|
|
337
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
338
|
+
|
|
339
|
+
expect(manager.validateConfig()).toBe(true);
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
it('should return false when loginType is account and username is missing', () => {
|
|
343
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
344
|
+
thinq: { loginType: 'account', password: 'secret', country: 'US', language: 'en-US', devices: [] },
|
|
345
|
+
});
|
|
346
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
347
|
+
|
|
348
|
+
expect(manager.validateConfig()).toBe(false);
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
it('should return false when loginType is account and password is missing', () => {
|
|
352
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
353
|
+
thinq: { loginType: 'account', username: 'test@example.com', country: 'US', language: 'en-US', devices: [] },
|
|
354
|
+
});
|
|
355
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
356
|
+
|
|
357
|
+
expect(manager.validateConfig()).toBe(false);
|
|
358
|
+
});
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
describe('getDeviceCapabilities', () => {
|
|
362
|
+
it('should delegate to resolveAirConditionerCapabilities', () => {
|
|
363
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
364
|
+
thinq: {
|
|
365
|
+
loginType: 'account',
|
|
366
|
+
country: 'US',
|
|
367
|
+
language: 'en-US',
|
|
368
|
+
devices: [
|
|
369
|
+
{
|
|
370
|
+
deviceId: 'device-1',
|
|
371
|
+
capabilities: { supportsHeat: false, supportsFanSpeedControl: true },
|
|
372
|
+
},
|
|
373
|
+
],
|
|
374
|
+
},
|
|
375
|
+
});
|
|
376
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
377
|
+
|
|
378
|
+
const capabilities = manager.getDeviceCapabilities('device-1');
|
|
379
|
+
expect(capabilities.supportsHeat).toBe(false);
|
|
380
|
+
expect(capabilities.supportsFanSpeedControl).toBe(true);
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
it('should return defaults for device not in config', () => {
|
|
384
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
385
|
+
thinq: { loginType: 'account', country: 'US', language: 'en-US', devices: [] },
|
|
386
|
+
});
|
|
387
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
388
|
+
|
|
389
|
+
const capabilities = manager.getDeviceCapabilities('unknown-device');
|
|
390
|
+
expect(capabilities.supportsHeat).toBe(true);
|
|
391
|
+
expect(capabilities.supportsFanSpeedControl).toBe(true);
|
|
392
|
+
});
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
describe('overrideMatterConfiguration getter', () => {
|
|
396
|
+
it('should return true when configured', () => {
|
|
397
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
398
|
+
advancedFeature: {
|
|
399
|
+
settings: {
|
|
400
|
+
debug: false,
|
|
401
|
+
clearStorageOnStartup: false,
|
|
402
|
+
forceAuthentication: false,
|
|
403
|
+
unregisterOnShutdown: false,
|
|
404
|
+
overrideMatterConfiguration: true,
|
|
405
|
+
matterOverrideSettings: {
|
|
406
|
+
matterVendorName: 'LG',
|
|
407
|
+
matterVendorId: 0x1234,
|
|
408
|
+
},
|
|
409
|
+
},
|
|
410
|
+
},
|
|
411
|
+
});
|
|
412
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
413
|
+
|
|
414
|
+
expect(manager.overrideMatterConfiguration).toBe(true);
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
it('should return false when configured', () => {
|
|
418
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
419
|
+
advancedFeature: {
|
|
420
|
+
settings: {
|
|
421
|
+
debug: false,
|
|
422
|
+
clearStorageOnStartup: false,
|
|
423
|
+
forceAuthentication: false,
|
|
424
|
+
unregisterOnShutdown: false,
|
|
425
|
+
overrideMatterConfiguration: false,
|
|
426
|
+
matterOverrideSettings: {
|
|
427
|
+
matterVendorName: 'Matterbridge',
|
|
428
|
+
matterVendorId: 0xfff1,
|
|
429
|
+
},
|
|
430
|
+
},
|
|
431
|
+
},
|
|
432
|
+
});
|
|
433
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
434
|
+
|
|
435
|
+
expect(manager.overrideMatterConfiguration).toBe(false);
|
|
436
|
+
});
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
describe('matterOverrideSettings getter', () => {
|
|
440
|
+
it('should return configured settings verbatim', () => {
|
|
441
|
+
const customSettings = {
|
|
442
|
+
matterVendorName: 'Custom Vendor',
|
|
443
|
+
matterVendorId: 0xabcd,
|
|
444
|
+
matterProductName: 'Premium AC',
|
|
445
|
+
matterProductId: 0xef01,
|
|
446
|
+
};
|
|
447
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
448
|
+
advancedFeature: {
|
|
449
|
+
settings: {
|
|
450
|
+
debug: false,
|
|
451
|
+
clearStorageOnStartup: false,
|
|
452
|
+
forceAuthentication: false,
|
|
453
|
+
unregisterOnShutdown: false,
|
|
454
|
+
overrideMatterConfiguration: true,
|
|
455
|
+
matterOverrideSettings: customSettings,
|
|
456
|
+
},
|
|
457
|
+
},
|
|
458
|
+
});
|
|
459
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
460
|
+
|
|
461
|
+
expect(manager.matterOverrideSettings).toEqual(customSettings);
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
it('should return default settings when not explicitly configured', () => {
|
|
465
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({});
|
|
466
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
467
|
+
|
|
468
|
+
expect(manager.matterOverrideSettings).toEqual({
|
|
469
|
+
matterVendorName: 'Matterbridge',
|
|
470
|
+
matterVendorId: 0xfff1,
|
|
471
|
+
});
|
|
472
|
+
});
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
describe('getProductNameForDevice', () => {
|
|
476
|
+
it('should return undefined when overrideMatterConfiguration is false', () => {
|
|
477
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
478
|
+
thinq: {
|
|
479
|
+
loginType: 'account',
|
|
480
|
+
country: 'US',
|
|
481
|
+
language: 'en-US',
|
|
482
|
+
devices: [
|
|
483
|
+
{
|
|
484
|
+
deviceId: 'device-1',
|
|
485
|
+
productName: 'Custom AC',
|
|
486
|
+
},
|
|
487
|
+
],
|
|
488
|
+
},
|
|
489
|
+
advancedFeature: {
|
|
490
|
+
settings: {
|
|
491
|
+
debug: false,
|
|
492
|
+
clearStorageOnStartup: false,
|
|
493
|
+
forceAuthentication: false,
|
|
494
|
+
unregisterOnShutdown: false,
|
|
495
|
+
overrideMatterConfiguration: false,
|
|
496
|
+
matterOverrideSettings: {
|
|
497
|
+
matterVendorName: 'Matterbridge',
|
|
498
|
+
matterVendorId: 0xfff1,
|
|
499
|
+
},
|
|
500
|
+
},
|
|
501
|
+
},
|
|
502
|
+
});
|
|
503
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
504
|
+
|
|
505
|
+
expect(manager.getProductNameForDevice('device-1')).toBeUndefined();
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
it('should return undefined when device not found', () => {
|
|
509
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
510
|
+
thinq: {
|
|
511
|
+
loginType: 'account',
|
|
512
|
+
country: 'US',
|
|
513
|
+
language: 'en-US',
|
|
514
|
+
devices: [],
|
|
515
|
+
},
|
|
516
|
+
advancedFeature: {
|
|
517
|
+
settings: {
|
|
518
|
+
debug: false,
|
|
519
|
+
clearStorageOnStartup: false,
|
|
520
|
+
forceAuthentication: false,
|
|
521
|
+
unregisterOnShutdown: false,
|
|
522
|
+
overrideMatterConfiguration: true,
|
|
523
|
+
matterOverrideSettings: {
|
|
524
|
+
matterVendorName: 'Matterbridge',
|
|
525
|
+
matterVendorId: 0xfff1,
|
|
526
|
+
},
|
|
527
|
+
},
|
|
528
|
+
},
|
|
529
|
+
});
|
|
530
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
531
|
+
|
|
532
|
+
expect(manager.getProductNameForDevice('unknown-device')).toBeUndefined();
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
it('should return undefined when device found but productName is unset', () => {
|
|
536
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
537
|
+
thinq: {
|
|
538
|
+
loginType: 'account',
|
|
539
|
+
country: 'US',
|
|
540
|
+
language: 'en-US',
|
|
541
|
+
devices: [
|
|
542
|
+
{
|
|
543
|
+
deviceId: 'device-1',
|
|
544
|
+
},
|
|
545
|
+
],
|
|
546
|
+
},
|
|
547
|
+
advancedFeature: {
|
|
548
|
+
settings: {
|
|
549
|
+
debug: false,
|
|
550
|
+
clearStorageOnStartup: false,
|
|
551
|
+
forceAuthentication: false,
|
|
552
|
+
unregisterOnShutdown: false,
|
|
553
|
+
overrideMatterConfiguration: true,
|
|
554
|
+
matterOverrideSettings: {
|
|
555
|
+
matterVendorName: 'Matterbridge',
|
|
556
|
+
matterVendorId: 0xfff1,
|
|
557
|
+
},
|
|
558
|
+
},
|
|
559
|
+
},
|
|
560
|
+
});
|
|
561
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
562
|
+
|
|
563
|
+
expect(manager.getProductNameForDevice('device-1')).toBeUndefined();
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
it('should return product name when device found with productName set and override enabled', () => {
|
|
567
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
568
|
+
thinq: {
|
|
569
|
+
loginType: 'account',
|
|
570
|
+
country: 'US',
|
|
571
|
+
language: 'en-US',
|
|
572
|
+
devices: [
|
|
573
|
+
{
|
|
574
|
+
deviceId: 'device-1',
|
|
575
|
+
productName: 'Custom AC',
|
|
576
|
+
},
|
|
577
|
+
],
|
|
578
|
+
},
|
|
579
|
+
advancedFeature: {
|
|
580
|
+
settings: {
|
|
581
|
+
debug: false,
|
|
582
|
+
clearStorageOnStartup: false,
|
|
583
|
+
forceAuthentication: false,
|
|
584
|
+
unregisterOnShutdown: false,
|
|
585
|
+
overrideMatterConfiguration: true,
|
|
586
|
+
matterOverrideSettings: {
|
|
587
|
+
matterVendorName: 'Matterbridge',
|
|
588
|
+
matterVendorId: 0xfff1,
|
|
589
|
+
},
|
|
590
|
+
},
|
|
591
|
+
},
|
|
592
|
+
});
|
|
593
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
594
|
+
|
|
595
|
+
expect(manager.getProductNameForDevice('device-1')).toBe('Custom AC');
|
|
596
|
+
});
|
|
597
|
+
});
|
|
598
|
+
|
|
599
|
+
describe('getWasherControlConfig', () => {
|
|
600
|
+
it('should return washerControl config when device found with washerControl set', () => {
|
|
601
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
602
|
+
thinq: {
|
|
603
|
+
loginType: 'account',
|
|
604
|
+
country: 'US',
|
|
605
|
+
language: 'en-US',
|
|
606
|
+
devices: [
|
|
607
|
+
{
|
|
608
|
+
deviceId: 'washer-123',
|
|
609
|
+
washerControl: { allowRemoteStop: true },
|
|
610
|
+
},
|
|
611
|
+
],
|
|
612
|
+
},
|
|
613
|
+
});
|
|
614
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
615
|
+
|
|
616
|
+
const result = manager.getWasherControlConfig('washer-123');
|
|
617
|
+
|
|
618
|
+
expect(result).toEqual({ allowRemoteStop: true });
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
it('should return empty object when device found but washerControl not set', () => {
|
|
622
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
623
|
+
thinq: {
|
|
624
|
+
loginType: 'account',
|
|
625
|
+
country: 'US',
|
|
626
|
+
language: 'en-US',
|
|
627
|
+
devices: [
|
|
628
|
+
{
|
|
629
|
+
deviceId: 'washer-123',
|
|
630
|
+
},
|
|
631
|
+
],
|
|
632
|
+
},
|
|
633
|
+
});
|
|
634
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
635
|
+
|
|
636
|
+
const result = manager.getWasherControlConfig('washer-123');
|
|
637
|
+
|
|
638
|
+
expect(result).toEqual({});
|
|
639
|
+
});
|
|
640
|
+
|
|
641
|
+
it('should return empty object when device not found', () => {
|
|
642
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
643
|
+
thinq: {
|
|
644
|
+
loginType: 'account',
|
|
645
|
+
country: 'US',
|
|
646
|
+
language: 'en-US',
|
|
647
|
+
devices: [],
|
|
648
|
+
},
|
|
649
|
+
});
|
|
650
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
651
|
+
|
|
652
|
+
const result = manager.getWasherControlConfig('unknown-device');
|
|
653
|
+
|
|
654
|
+
expect(result).toEqual({});
|
|
655
|
+
});
|
|
656
|
+
|
|
657
|
+
it('should return empty object when thinq.devices is undefined', () => {
|
|
658
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
659
|
+
thinq: {
|
|
660
|
+
loginType: 'account',
|
|
661
|
+
country: 'US',
|
|
662
|
+
language: 'en-US',
|
|
663
|
+
devices: [],
|
|
664
|
+
},
|
|
665
|
+
});
|
|
666
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
667
|
+
|
|
668
|
+
const result = manager.getWasherControlConfig('washer-123');
|
|
669
|
+
|
|
670
|
+
expect(result).toEqual({});
|
|
671
|
+
});
|
|
672
|
+
|
|
673
|
+
it('should return allowRemoteStop false when explicitly set', () => {
|
|
674
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
675
|
+
thinq: {
|
|
676
|
+
loginType: 'account',
|
|
677
|
+
country: 'US',
|
|
678
|
+
language: 'en-US',
|
|
679
|
+
devices: [
|
|
680
|
+
{
|
|
681
|
+
deviceId: 'washer-123',
|
|
682
|
+
washerControl: { allowRemoteStop: false },
|
|
683
|
+
},
|
|
684
|
+
],
|
|
685
|
+
},
|
|
686
|
+
});
|
|
687
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
688
|
+
|
|
689
|
+
const result = manager.getWasherControlConfig('washer-123');
|
|
690
|
+
|
|
691
|
+
expect(result).toEqual({ allowRemoteStop: false });
|
|
692
|
+
});
|
|
693
|
+
});
|
|
694
|
+
|
|
695
|
+
describe('getAcFilterControlConfig', () => {
|
|
696
|
+
it('should return acFilterControl config when device found with acFilterControl set', () => {
|
|
697
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
698
|
+
thinq: {
|
|
699
|
+
loginType: 'account',
|
|
700
|
+
country: 'US',
|
|
701
|
+
language: 'en-US',
|
|
702
|
+
devices: [
|
|
703
|
+
{
|
|
704
|
+
deviceId: 'ac-123',
|
|
705
|
+
acFilterControl: { allowFilterReset: true },
|
|
706
|
+
},
|
|
707
|
+
],
|
|
708
|
+
},
|
|
709
|
+
});
|
|
710
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
711
|
+
|
|
712
|
+
const result = manager.getAcFilterControlConfig('ac-123');
|
|
713
|
+
|
|
714
|
+
expect(result).toEqual({ allowFilterReset: true });
|
|
715
|
+
});
|
|
716
|
+
|
|
717
|
+
it('should return empty object when device found but acFilterControl not set', () => {
|
|
718
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
719
|
+
thinq: {
|
|
720
|
+
loginType: 'account',
|
|
721
|
+
country: 'US',
|
|
722
|
+
language: 'en-US',
|
|
723
|
+
devices: [
|
|
724
|
+
{
|
|
725
|
+
deviceId: 'ac-123',
|
|
726
|
+
},
|
|
727
|
+
],
|
|
728
|
+
},
|
|
729
|
+
});
|
|
730
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
731
|
+
|
|
732
|
+
const result = manager.getAcFilterControlConfig('ac-123');
|
|
733
|
+
|
|
734
|
+
expect(result).toEqual({});
|
|
735
|
+
});
|
|
736
|
+
|
|
737
|
+
it('should return empty object when device not found', () => {
|
|
738
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
739
|
+
thinq: {
|
|
740
|
+
loginType: 'account',
|
|
741
|
+
country: 'US',
|
|
742
|
+
language: 'en-US',
|
|
743
|
+
devices: [],
|
|
744
|
+
},
|
|
745
|
+
});
|
|
746
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
747
|
+
|
|
748
|
+
const result = manager.getAcFilterControlConfig('unknown-device');
|
|
749
|
+
|
|
750
|
+
expect(result).toEqual({});
|
|
751
|
+
});
|
|
752
|
+
|
|
753
|
+
it('should return empty object when thinq.devices is undefined', () => {
|
|
754
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
755
|
+
thinq: {
|
|
756
|
+
loginType: 'account',
|
|
757
|
+
country: 'US',
|
|
758
|
+
language: 'en-US',
|
|
759
|
+
devices: [],
|
|
760
|
+
},
|
|
761
|
+
});
|
|
762
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
763
|
+
|
|
764
|
+
const result = manager.getAcFilterControlConfig('ac-123');
|
|
765
|
+
|
|
766
|
+
expect(result).toEqual({});
|
|
767
|
+
});
|
|
768
|
+
|
|
769
|
+
it('should return allowFilterReset false when explicitly set', () => {
|
|
770
|
+
const config = asPartial<LgThinqPluginPlatformConfig>({
|
|
771
|
+
thinq: {
|
|
772
|
+
loginType: 'account',
|
|
773
|
+
country: 'US',
|
|
774
|
+
language: 'en-US',
|
|
775
|
+
devices: [
|
|
776
|
+
{
|
|
777
|
+
deviceId: 'ac-123',
|
|
778
|
+
acFilterControl: { allowFilterReset: false },
|
|
779
|
+
},
|
|
780
|
+
],
|
|
781
|
+
},
|
|
782
|
+
});
|
|
783
|
+
const manager = PlatformConfigManager.create(config, mockLogger);
|
|
784
|
+
|
|
785
|
+
const result = manager.getAcFilterControlConfig('ac-123');
|
|
786
|
+
|
|
787
|
+
expect(result).toEqual({ allowFilterReset: false });
|
|
788
|
+
});
|
|
789
|
+
});
|
|
790
|
+
});
|