]> git.basschouten.com Git - openhab-addons.git/blob
e2f496173f4b7437dd4515c62756660fa2cfbdf3
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.heos.internal.json;
14
15 import static org.junit.jupiter.api.Assertions.*;
16 import static org.openhab.binding.heos.internal.json.dto.HeosCommunicationAttribute.*;
17
18 import java.util.List;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.junit.jupiter.api.Test;
22 import org.openhab.binding.heos.internal.json.dto.HeosCommand;
23 import org.openhab.binding.heos.internal.json.dto.HeosCommandGroup;
24 import org.openhab.binding.heos.internal.json.dto.HeosErrorCode;
25 import org.openhab.binding.heos.internal.json.dto.HeosResponseObject;
26 import org.openhab.binding.heos.internal.json.payload.BrowseResult;
27 import org.openhab.binding.heos.internal.json.payload.BrowseResultType;
28 import org.openhab.binding.heos.internal.json.payload.Group;
29 import org.openhab.binding.heos.internal.json.payload.GroupPlayerRole;
30 import org.openhab.binding.heos.internal.json.payload.Media;
31 import org.openhab.binding.heos.internal.json.payload.Player;
32 import org.openhab.binding.heos.internal.json.payload.YesNoEnum;
33
34 /**
35  * Tests to validate the functioning of the HeosJsonParser specifically for response objects
36  *
37  * @author Martin van Wingerden - Initial Contribution
38  */
39 @NonNullByDefault
40 public class HeosJsonParserResponseTest {
41
42     private final HeosJsonParser subject = new HeosJsonParser();
43
44     @Test
45     public void sign_in() {
46         HeosResponseObject<Void> response = subject.parseResponse(
47                 "{\"heos\": {\"command\": \"system/sign_in\", \"result\": \"success\", \"message\": \"signed_in&un=test@example.org\"}}",
48                 Void.class);
49
50         assertEquals(HeosCommandGroup.SYSTEM, response.heosCommand.commandGroup);
51         assertEquals(HeosCommand.SIGN_IN, response.heosCommand.command);
52         assertTrue(response.result);
53
54         assertEquals("test@example.org", response.getAttribute(USERNAME));
55         assertTrue(response.hasAttribute(SIGNED_IN));
56     }
57
58     @Test
59     public void sign_in_under_process() {
60         HeosResponseObject<Void> response = subject.parseResponse(
61                 "{\"heos\": {\"command\": \"system/sign_in\", \"message\": \"command under process\"}}", Void.class);
62
63         assertEquals(HeosCommandGroup.SYSTEM, response.heosCommand.commandGroup);
64         assertEquals(HeosCommand.SIGN_IN, response.heosCommand.command);
65         assertFalse(response.result);
66         assertFalse(response.isFinished());
67     }
68
69     @Test
70     public void sign_in_failed() {
71         HeosResponseObject<Void> response = subject.parseResponse(
72                 "{\"heos\": {\"command\": \"system/sign_in\", \"message\": \"eid=10&text=User not found\"}}",
73                 Void.class);
74
75         assertEquals(HeosCommandGroup.SYSTEM, response.heosCommand.commandGroup);
76         assertEquals(HeosCommand.SIGN_IN, response.heosCommand.command);
77         assertFalse(response.result);
78         assertTrue(response.isFinished());
79
80         assertEquals(HeosErrorCode.USER_NOT_FOUND, response.getError().code);
81     }
82
83     @Test
84     public void get_mute() {
85         HeosResponseObject<Void> response = subject.parseResponse(
86                 "{\"heos\": {\"command\": \"player/get_mute\", \"result\": \"success\", \"message\": \"pid=1958912779&state=on\"}}",
87                 Void.class);
88
89         assertEquals(HeosCommandGroup.PLAYER, response.heosCommand.commandGroup);
90         assertEquals(HeosCommand.GET_MUTE, response.heosCommand.command);
91         assertTrue(response.result);
92
93         assertEquals(Long.valueOf(1958912779), response.getNumericAttribute(PLAYER_ID));
94         assertTrue(response.getBooleanAttribute(STATE));
95     }
96
97     @Test
98     public void get_mute_error() {
99         HeosResponseObject<Void> response = subject.parseResponse(
100                 "{\"heos\": {\"command\": \"player/get_mute\", \"result\": \"fail\", \"message\": \"eid=2&text=ID Not Valid&pid=null\"}}",
101                 Void.class);
102
103         assertEquals(HeosCommandGroup.PLAYER, response.heosCommand.commandGroup);
104         assertEquals(HeosCommand.GET_MUTE, response.heosCommand.command);
105         assertFalse(response.result);
106
107         assertEquals(HeosErrorCode.INVALID_ID, response.getError().code);
108     }
109
110     @Test
111     public void browse_browse_under_process() {
112         HeosResponseObject<Void> response = subject.parseResponse(
113                 "{\"heos\": {\"command\": \"browse/browse\", \"result\": \"success\", \"message\": \"command under process&sid=1025\"}}",
114                 Void.class);
115
116         assertEquals(HeosCommandGroup.BROWSE, response.heosCommand.commandGroup);
117         assertEquals(HeosCommand.BROWSE, response.heosCommand.command);
118         assertTrue(response.result);
119
120         assertEquals(Long.valueOf(1025), response.getNumericAttribute(SOURCE_ID));
121         assertFalse(response.isFinished());
122     }
123
124     @Test
125     public void incorrect_level() {
126         HeosResponseObject<Void> response = subject.parseResponse(
127                 "{\"heos\": {\"command\": \"player/set_volume\", \"result\": \"fail\", \"message\": \"eid=9&text=Parameter out of range&pid=-831584083&level=OFF\"}}",
128                 Void.class);
129
130         assertEquals(HeosCommandGroup.PLAYER, response.heosCommand.commandGroup);
131         assertEquals(HeosCommand.SET_VOLUME, response.heosCommand.command);
132         assertFalse(response.result);
133
134         assertEquals(HeosErrorCode.PARAMETER_OUT_OF_RANGE, response.getError().code);
135         assertEquals("#9: Parameter out of range", response.getError().code.toString());
136     }
137
138     @Test
139     public void get_players() {
140         HeosResponseObject<Player[]> response = subject.parseResponse(
141                 """
142                         {"heos": {"command": "player/get_players", "result": "success", "message": ""}, "payload": [\
143                         {"name": "Kantoor HEOS 3", "pid": -831584083, "model": "HEOS 3", "version": "1.520.200", "ip": "192.168.1.230", "network": "wired", "lineout": 0, "serial": "ACNG9180110887"}, \
144                         {"name": "HEOS Bar", "pid": 1958912779, "model": "HEOS Bar", "version": "1.520.200", "ip": "192.168.1.195", "network": "wired", "lineout": 0, "serial": "ADAG9180917029"}]}\
145                         """,
146                 Player[].class);
147
148         assertEquals(HeosCommandGroup.PLAYER, response.heosCommand.commandGroup);
149         assertEquals(HeosCommand.GET_PLAYERS, response.heosCommand.command);
150         assertTrue(response.result);
151
152         assertEquals(2, response.payload.length);
153         Player player0 = response.payload[0];
154
155         assertEquals("Kantoor HEOS 3", player0.name);
156         assertEquals(-831584083, player0.playerId);
157         assertEquals("HEOS 3", player0.model);
158         assertEquals("1.520.200", player0.version);
159         assertEquals("192.168.1.230", player0.ip);
160         assertEquals("wired", player0.network);
161         assertEquals(0, player0.lineout);
162         assertEquals("ACNG9180110887", player0.serial);
163
164         Player player1 = response.payload[1];
165
166         assertEquals("HEOS Bar", player1.name);
167         assertEquals(1958912779, player1.playerId);
168         assertEquals("HEOS Bar", player1.model);
169         assertEquals("1.520.200", player1.version);
170         assertEquals("192.168.1.195", player1.ip);
171         assertEquals("wired", player1.network);
172         assertEquals(0, player1.lineout);
173         assertEquals("ADAG9180917029", player1.serial);
174     }
175
176     @Test
177     public void get_player_info() {
178         HeosResponseObject<Player> response = subject.parseResponse(
179                 "{\"heos\": {\"command\": \"player/get_player_info\", \"result\": \"success\", \"message\": \"pid=1958912779\"}, \"payload\": {\"name\": \"HEOS Bar\", \"pid\": 1958912779, \"model\": \"HEOS Bar\", \"version\": \"1.520.200\", \"ip\": \"192.168.1.195\", \"network\": \"wired\", \"lineout\": 0, \"serial\": \"ADAG9180917029\"}}",
180                 Player.class);
181
182         assertEquals(HeosCommandGroup.PLAYER, response.heosCommand.commandGroup);
183         assertEquals(HeosCommand.GET_PLAYER_INFO, response.heosCommand.command);
184         assertTrue(response.result);
185
186         assertEquals("HEOS Bar", response.payload.name);
187         assertEquals(1958912779, response.payload.playerId);
188         assertEquals("HEOS Bar", response.payload.model);
189         assertEquals("1.520.200", response.payload.version);
190         assertEquals("192.168.1.195", response.payload.ip);
191         assertEquals("wired", response.payload.network);
192         assertEquals(0, response.payload.lineout);
193         assertEquals("ADAG9180917029", response.payload.serial);
194     }
195
196     @Test
197     public void get_now_playing_media() {
198         HeosResponseObject<Media> response = subject.parseResponse(
199                 """
200                         {"heos": {"command": "player/get_now_playing_media", "result": "success", "message": "pid=1958912779"}, "payload": \
201                         {"type": "song", "song": "Solo (feat. Demi Lovato)", "album": "What Is Love? (Deluxe)", "artist": "Clean Bandit", "image_url": "http://192.168.1.230:8015//m-browsableMediaUri/getImageFromTag/mnt/326C72A3E307501E47DE2B0F47D90EB8/Clean%20Bandit/What%20Is%20Love_%20(Deluxe)/03%20Solo%20(feat.%20Demi%20Lovato).m4a", "album_id": "", "mid": "http://192.168.1.230:8015/m-1c176905-f6c7-d168-dc35-86b4735c5976/Clean+Bandit/What+Is+Love_+(Deluxe)/03+Solo+(feat.+Demi+Lovato).m4a", "qid": 1, "sid": 1024}, "options": []}
202                         """,
203                 Media.class);
204
205         assertEquals(HeosCommandGroup.PLAYER, response.heosCommand.commandGroup);
206         assertEquals(HeosCommand.GET_NOW_PLAYING_MEDIA, response.heosCommand.command);
207         assertTrue(response.result);
208
209         assertEquals(Long.valueOf(1958912779), response.getNumericAttribute(PLAYER_ID));
210
211         assertEquals("song", response.payload.type);
212         assertEquals("Solo (feat. Demi Lovato)", response.payload.song);
213         assertEquals("What Is Love? (Deluxe)", response.payload.album);
214         assertEquals("Clean Bandit", response.payload.artist);
215         assertEquals(
216                 "http://192.168.1.230:8015//m-browsableMediaUri/getImageFromTag/mnt/326C72A3E307501E47DE2B0F47D90EB8/Clean%20Bandit/What%20Is%20Love_%20(Deluxe)/03%20Solo%20(feat.%20Demi%20Lovato).m4a",
217                 response.payload.imageUrl);
218         assertEquals("", response.payload.albumId);
219         assertEquals(
220                 "http://192.168.1.230:8015/m-1c176905-f6c7-d168-dc35-86b4735c5976/Clean+Bandit/What+Is+Love_+(Deluxe)/03+Solo+(feat.+Demi+Lovato).m4a",
221                 response.payload.mediaId);
222         assertEquals(1, response.payload.queueId);
223         assertEquals(1024, response.payload.sourceId);
224     }
225
226     @Test
227     public void browse_playlist() {
228         HeosResponseObject<BrowseResult[]> response = subject.parseResponse(
229                 """
230                         {"heos": {"command": "browse/browse", "result": "success", "message": "sid=1025&returned=6&count=6"}, "payload": [\
231                         {"container": "yes", "type": "playlist", "cid": "132562", "playable": "yes", "name": "Maaike Ouboter - En hoe het dan ook weer dag wordt", "image_url": ""}, \
232                         {"container": "yes", "type": "playlist", "cid": "132563", "playable": "yes", "name": "Maaike Ouboter - Vanaf nu is het van jou", "image_url": ""}, \
233                         {"container": "yes", "type": "playlist", "cid": "162887", "playable": "yes", "name": "Easy listening", "image_url": ""}, \
234                         {"container": "yes", "type": "playlist", "cid": "174461", "playable": "yes", "name": "Nieuwe muziek 5-2019", "image_url": ""}, \
235                         {"container": "yes", "type": "playlist", "cid": "194000", "playable": "yes", "name": "Nieuwe muziek 2019-05", "image_url": ""}, \
236                         {"container": "yes", "type": "playlist", "cid": "194001", "playable": "yes", "name": "Clean Bandit", "image_url": ""}]}\
237                         """,
238                 BrowseResult[].class);
239
240         assertEquals(HeosCommandGroup.BROWSE, response.heosCommand.commandGroup);
241         assertEquals(HeosCommand.BROWSE, response.heosCommand.command);
242         assertTrue(response.result);
243
244         assertEquals(Long.valueOf(1025), response.getNumericAttribute(SOURCE_ID));
245         assertEquals(Long.valueOf(6), response.getNumericAttribute(RETURNED));
246         assertEquals(Long.valueOf(6), response.getNumericAttribute(COUNT));
247
248         BrowseResult result = response.payload[5];
249
250         assertEquals(YesNoEnum.YES, result.container);
251         assertEquals(BrowseResultType.PLAYLIST, result.type);
252         assertEquals(YesNoEnum.YES, result.playable);
253         assertEquals("194001", result.containerId);
254         assertEquals("Clean Bandit", result.name);
255         assertEquals("", result.imageUrl);
256     }
257
258     @Test
259     public void browse_favorites() {
260         HeosResponseObject<BrowseResult[]> response = subject.parseResponse(
261                 """
262                         {"heos": {"command": "browse/browse", "result": "success", "message": "sid=1028&returned=3&count=3"}, "payload": [\
263                         {"container": "no", "mid": "s6707", "type": "station", "playable": "yes", "name": "NPO 3FM 96.8 (Top 40 %26 Pop Music)", "image_url": "http://cdn-profiles.tunein.com/s6707/images/logoq.png?t=636268"}, \
264                         {"container": "no", "mid": "s2967", "type": "station", "playable": "yes", "name": "Classic FM Nederland (Classical Music)", "image_url": "http://cdn-radiotime-logos.tunein.com/s2967q.png"}, \
265                         {"container": "no", "mid": "s1993", "type": "station", "playable": "yes", "name": "BNR Nieuwsradio", "image_url": "http://cdn-radiotime-logos.tunein.com/s1993q.png"}], \
266                         "options": [{"browse": [{"id": 20, "name": "Remove from HEOS Favorites"}]}]}\
267                         """,
268                 BrowseResult[].class);
269
270         assertEquals(HeosCommandGroup.BROWSE, response.heosCommand.commandGroup);
271         assertEquals(HeosCommand.BROWSE, response.heosCommand.command);
272         assertTrue(response.result);
273
274         assertEquals(Long.valueOf(1028), response.getNumericAttribute(SOURCE_ID));
275         assertEquals(Long.valueOf(3), response.getNumericAttribute(RETURNED));
276         assertEquals(Long.valueOf(3), response.getNumericAttribute(COUNT));
277
278         BrowseResult result = response.payload[0];
279
280         assertEquals(YesNoEnum.NO, result.container);
281         assertEquals("s6707", result.mediaId);
282         assertEquals(BrowseResultType.STATION, result.type);
283         assertEquals(YesNoEnum.YES, result.playable);
284         assertEquals("NPO 3FM 96.8 (Top 40 %26 Pop Music)", result.name);
285         assertEquals("http://cdn-profiles.tunein.com/s6707/images/logoq.png?t=636268", result.imageUrl);
286
287         // TODO validate options
288     }
289
290     @Test
291     public void get_groups() {
292         HeosResponseObject<Group[]> response = subject.parseResponse(
293                 """
294                         {"heos": {"command": "group/get_groups", "result": "success", "message": ""}, "payload": [ \
295                         {"name": "Group 1", "gid": "214243242", "players": [ {"name": "HEOS 1", "pid": "2142443242", "role": "leader"}, {"name": "HEOS 3", "pid": "32432423432", "role": "member"}, {"name": "HEOS 5", "pid": "342423564", "role": "member"}]}, \
296                         {"name": "Group 2", "gid": "2142432342", "players": [ {"name": "HEOS 3", "pid": "32432423432", "role": "member"}, {"name": "HEOS 5", "pid": "342423564", "role": "member"}]}]}\
297                         """,
298                 Group[].class);
299
300         assertEquals(HeosCommandGroup.GROUP, response.heosCommand.commandGroup);
301         assertEquals(HeosCommand.GET_GROUPS, response.heosCommand.command);
302         assertTrue(response.result);
303
304         Group group = response.payload[0];
305
306         assertEquals("Group 1", group.name);
307         assertEquals("214243242", group.id);
308
309         List<Group.Player> players = group.players;
310
311         Group.Player player0 = players.get(0);
312         assertEquals("HEOS 1", player0.name);
313         assertEquals("2142443242", player0.id);
314         assertEquals(GroupPlayerRole.LEADER, player0.role);
315
316         Group.Player player1 = players.get(1);
317         assertEquals("HEOS 3", player1.name);
318         assertEquals("32432423432", player1.id);
319         assertEquals(GroupPlayerRole.MEMBER, player1.role);
320     }
321 }