2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.hdpowerview.internal;
15 import static org.junit.jupiter.api.Assertions.*;
16 import static org.openhab.binding.hdpowerview.internal.dto.CoordinateSystem.*;
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.nio.charset.StandardCharsets;
21 import java.util.List;
22 import java.util.Objects;
24 import org.eclipse.jdt.annotation.NonNullByDefault;
25 import org.junit.jupiter.api.Test;
26 import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase;
27 import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase.Capabilities;
28 import org.openhab.binding.hdpowerview.internal.dto.BatteryKind;
29 import org.openhab.binding.hdpowerview.internal.dto.Scene;
30 import org.openhab.binding.hdpowerview.internal.dto.SceneCollection;
31 import org.openhab.binding.hdpowerview.internal.dto.ShadeData;
32 import org.openhab.binding.hdpowerview.internal.dto.ShadePosition;
33 import org.openhab.binding.hdpowerview.internal.dto.responses.SceneCollections;
34 import org.openhab.binding.hdpowerview.internal.dto.responses.Scenes;
35 import org.openhab.binding.hdpowerview.internal.dto.responses.Shades;
36 import org.openhab.core.library.types.PercentType;
37 import org.openhab.core.types.State;
38 import org.openhab.core.types.UnDefType;
40 import com.google.gson.Gson;
43 * Unit tests for HD PowerView binding.
45 * @author Andrew Fiddian-Green - Initial contribution
46 * @author Jacob Laursen - Add support for scene groups
49 public class HDPowerViewJUnitTests {
51 private Gson gson = new Gson();
53 private <T> T getObjectFromJson(String filename, Class<T> clazz) throws IOException {
54 try (InputStream inputStream = HDPowerViewJUnitTests.class.getResourceAsStream(filename)) {
55 if (inputStream == null) {
56 throw new IOException("inputstream is null");
58 byte[] bytes = inputStream.readAllBytes();
60 throw new IOException("Resulting byte-array empty");
62 String json = new String(bytes, StandardCharsets.UTF_8);
63 return Objects.requireNonNull(gson.fromJson(json, clazz));
68 * Test generic JSON shades response.
71 public void shadeNameIsDecoded() throws IOException {
72 Shades shades = getObjectFromJson("shades.json", Shades.class);
73 List<ShadeData> shadeData = shades.shadeData;
74 assertNotNull(shadeData);
75 assertEquals(3, shadeData.size());
76 ShadeData shade = shadeData.get(0);
77 assertEquals("Shade 2", shade.getName());
81 * Test the BatteryKind decoding.
84 public void testBatteryKind() throws IOException {
85 Shades shades = getObjectFromJson("shades.json", Shades.class);
86 List<ShadeData> shadeData = shades.shadeData;
87 assertNotNull(shadeData);
88 ShadeData shade = shadeData.get(0);
89 assertEquals(BatteryKind.HARDWIRED_POWER_SUPPLY, shade.getBatteryKind());
90 shade = shadeData.get(1);
91 assertEquals(BatteryKind.ERROR_UNKNOWN, shade.getBatteryKind());
95 * Test generic JSON scene response.
98 public void sceneNameIsDecoded() throws IOException {
99 Scenes scenes = getObjectFromJson("scenes.json", Scenes.class);
100 List<Scene> sceneData = scenes.sceneData;
101 assertNotNull(sceneData);
102 assertEquals(4, sceneData.size());
103 Scene scene = sceneData.get(0);
104 assertEquals("Door Open", scene.getName());
108 * Test generic JSON scene collection response.
111 public void sceneCollectionNameIsDecoded() throws IOException {
112 SceneCollections sceneCollections = getObjectFromJson("sceneCollections.json", SceneCollections.class);
114 List<SceneCollection> sceneCollectionData = sceneCollections.sceneCollectionData;
115 assertNotNull(sceneCollectionData);
116 assertEquals(1, sceneCollectionData.size());
118 SceneCollection sceneCollection = sceneCollectionData.get(0);
119 assertEquals("Børn op", sceneCollection.getName());
123 * Test the JSON parsing for a duette top down bottom up shade.
126 public void duetteTopDownBottomUpShadeIsParsedCorrectly() throws IOException {
127 Shades shades = getObjectFromJson("duette.json", Shades.class);
128 List<ShadeData> shadesData = shades.shadeData;
129 assertNotNull(shadesData);
131 assertEquals(1, shadesData.size());
132 ShadeData shadeData = shadesData.get(0);
133 assertNotNull(shadeData);
135 assertEquals("Gardin 1", shadeData.getName());
136 assertEquals(63778, shadeData.id);
138 ShadePosition shadePos = shadeData.positions;
139 assertNotNull(shadePos);
141 Integer capabilitiesValue = shadeData.capabilities;
142 assertNotNull(capabilitiesValue);
143 assertEquals(7, capabilitiesValue.intValue());
144 ShadeCapabilitiesDatabase db = new ShadeCapabilitiesDatabase();
145 Capabilities capabilities = db.getCapabilities(capabilitiesValue);
147 State pos = shadePos.getState(capabilities, PRIMARY_POSITION);
148 assertEquals(PercentType.class, pos.getClass());
149 assertEquals(59, ((PercentType) pos).intValue());
151 pos = shadePos.getState(capabilities, SECONDARY_POSITION);
152 assertEquals(PercentType.class, pos.getClass());
153 assertEquals(35, ((PercentType) pos).intValue());
155 pos = shadePos.getState(capabilities, VANE_TILT_POSITION);
156 assertEquals(UnDefType.class, pos.getClass());
158 assertEquals(3, shadeData.batteryStatus);
160 assertEquals(4, shadeData.signalStrength);
162 assertEquals(8, shadeData.type);
164 assertTrue(db.isTypeInDatabase(shadeData.type));
165 assertTrue(db.isCapabilitiesInDatabase(capabilitiesValue.intValue()));
167 assertEquals(db.getType(shadeData.type).getCapabilities(), capabilitiesValue.intValue());
169 assertTrue(db.getCapabilities(capabilitiesValue.intValue()).supportsSecondary());
170 assertNotEquals(db.getType(shadeData.type).getCapabilities(), capabilitiesValue.intValue() + 1);
172 // ==== when changing position1, position2 value is not changed (vice-versa) ====
173 ShadePosition shadePosition = shadeData.positions;
174 assertNotNull(shadePosition);
175 // ==== position2 ====
176 State position2Old = shadePosition.getState(capabilities, SECONDARY_POSITION);
177 shadePosition.setPosition(capabilities, PRIMARY_POSITION, 99);
178 State position2New = shadePosition.getState(capabilities, SECONDARY_POSITION);
179 assertEquals(PercentType.class, position2Old.getClass());
180 assertEquals(PercentType.class, position2New.getClass());
181 assertEquals(((PercentType) position2Old).intValue(), ((PercentType) position2New).intValue());
183 // ==== position2 ====
184 State position1Old = shadePosition.getState(capabilities, PRIMARY_POSITION);
185 shadePosition.setPosition(capabilities, SECONDARY_POSITION, 99);
186 State position1New = shadePosition.getState(capabilities, PRIMARY_POSITION);
187 assertEquals(PercentType.class, position1Old.getClass());
188 assertEquals(PercentType.class, position1New.getClass());
189 assertEquals(((PercentType) position1Old).intValue(), ((PercentType) position1New).intValue());