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.heos.internal.json;
15 import static java.lang.Long.valueOf;
16 import static org.junit.jupiter.api.Assertions.*;
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.junit.jupiter.api.Test;
20 import org.openhab.binding.heos.internal.json.dto.HeosCommunicationAttribute;
21 import org.openhab.binding.heos.internal.json.dto.HeosEvent;
22 import org.openhab.binding.heos.internal.json.dto.HeosEventObject;
25 * Tests to validate the functioning of the HeosJsonParser specifically for event objects
27 * @author Martin van Wingerden - Initial Contribution
30 public class HeosJsonParserEventTest {
32 private final HeosJsonParser subject = new HeosJsonParser();
35 public void event_now_playing_changed() {
36 HeosEventObject event = subject.parseEvent(
37 "{\"heos\": {\"command\": \"event/player_now_playing_changed\", \"message\": \"pid=1679855527\"}}");
39 assertEquals(HeosEvent.PLAYER_NOW_PLAYING_CHANGED, event.command);
40 assertEquals("event/player_now_playing_changed", event.rawCommand);
41 assertEquals(valueOf(1679855527), event.getNumericAttribute(HeosCommunicationAttribute.PLAYER_ID));
45 public void event_now_playing_progress() {
46 HeosEventObject event = subject.parseEvent(
47 "{\"heos\": {\"command\": \"event/player_now_playing_progress\", \"message\": \"pid=1679855527&cur_pos=224848000&duration=0\"}}");
49 assertEquals(HeosEvent.PLAYER_NOW_PLAYING_PROGRESS, event.command);
50 assertEquals("event/player_now_playing_progress", event.rawCommand);
51 assertEquals(valueOf(1679855527), event.getNumericAttribute(HeosCommunicationAttribute.PLAYER_ID));
52 assertEquals(valueOf(224848000), event.getNumericAttribute(HeosCommunicationAttribute.CURRENT_POSITION));
53 assertEquals(valueOf(0), event.getNumericAttribute(HeosCommunicationAttribute.DURATION));
57 public void event_state_changed() {
58 HeosEventObject event = subject.parseEvent(
59 "{\"heos\": {\"command\": \"event/player_state_changed\", \"message\": \"pid=1679855527&state=play\"}}");
61 assertEquals(HeosEvent.PLAYER_STATE_CHANGED, event.command);
62 assertEquals("event/player_state_changed", event.rawCommand);
63 assertEquals(valueOf(1679855527), event.getNumericAttribute(HeosCommunicationAttribute.PLAYER_ID));
64 assertEquals("play", event.getAttribute(HeosCommunicationAttribute.STATE));
68 public void event_playback_error() {
69 HeosEventObject event = subject.parseEvent(
70 "{\"heos\": {\"command\": \"event/player_playback_error\", \"message\": \"pid=1679855527&error=Could Not Download\"}}");
72 assertEquals(HeosEvent.PLAYER_PLAYBACK_ERROR, event.command);
73 assertEquals("event/player_playback_error", event.rawCommand);
74 assertEquals(valueOf(1679855527), event.getNumericAttribute(HeosCommunicationAttribute.PLAYER_ID));
75 assertEquals("Could Not Download", event.getAttribute(HeosCommunicationAttribute.ERROR));
79 public void event_volume_changed() {
80 HeosEventObject event = subject.parseEvent(
81 "{\"heos\": {\"command\": \"event/player_volume_changed\", \"message\": \"pid=1958912779&level=23&mute=off\"}}");
83 assertEquals(HeosEvent.PLAYER_VOLUME_CHANGED, event.command);
84 assertEquals("event/player_volume_changed", event.rawCommand);
85 assertEquals(valueOf(1958912779), event.getNumericAttribute(HeosCommunicationAttribute.PLAYER_ID));
86 assertEquals(valueOf(23), event.getNumericAttribute(HeosCommunicationAttribute.LEVEL));
87 assertFalse(event.getBooleanAttribute(HeosCommunicationAttribute.MUTE));
91 public void event_shuffle_mode_changed() {
92 HeosEventObject event = subject.parseEvent(
93 "{\"heos\": {\"command\": \"event/shuffle_mode_changed\", \"message\": \"pid=-831584083&shuffle=on\"}}");
95 assertEquals(HeosEvent.SHUFFLE_MODE_CHANGED, event.command);
96 assertEquals("event/shuffle_mode_changed", event.rawCommand);
97 assertEquals(valueOf(-831584083), event.getNumericAttribute(HeosCommunicationAttribute.PLAYER_ID));
98 assertTrue(event.getBooleanAttribute(HeosCommunicationAttribute.SHUFFLE));
102 public void event_sources_changed() {
103 HeosEventObject event = subject.parseEvent("{\"heos\": {\"command\": \"event/sources_changed\"}}");
105 assertEquals(HeosEvent.SOURCES_CHANGED, event.command);
106 assertEquals("event/sources_changed", event.rawCommand);
110 public void event_user_changed() {
111 HeosEventObject event = subject.parseEvent(
112 "{\"heos\": {\"command\": \"event/user_changed\", \"message\": \"signed_in&un=martinvw@mtin.nl\"}}");
114 assertEquals(HeosEvent.USER_CHANGED, event.command);
115 assertEquals("event/user_changed", event.rawCommand);
116 assertTrue(event.hasAttribute(HeosCommunicationAttribute.SIGNED_IN));
117 assertEquals("martinvw@mtin.nl", event.getAttribute(HeosCommunicationAttribute.USERNAME));
121 public void event_unknown_event() {
122 HeosEventObject event = subject.parseEvent("{\"heos\": {\"command\": \"event/does_not_exist\"}}");
124 assertNull(event.command);
125 assertEquals("event/does_not_exist", event.rawCommand);
129 public void event_duplicate_attributes() {
130 HeosEventObject event = subject.parseEvent(
131 "{\"heos\": {\"command\": \"event/does_not_exist\", \"message\": \"signed_in&un=test1&un=test2\"}}");
133 // the first one is ignored but it does not crash
134 assertEquals("test2", event.getAttribute(HeosCommunicationAttribute.USERNAME));
138 public void event_non_numeric() {
139 HeosEventObject event = subject
140 .parseEvent("{\"heos\": {\"command\": \"event/does_not_exist\", \"message\": \"pid=test\"}}");
142 // the first one is ignored but it does not crash
143 assertNull(event.getNumericAttribute(HeosCommunicationAttribute.PLAYER_ID));
147 public void event_numeric_missing() {
148 HeosEventObject event = subject.parseEvent("{\"heos\": {\"command\": \"event/does_not_exist\"}}");
150 // the first one is ignored but it does not crash
151 assertNull(event.getAttribute(HeosCommunicationAttribute.PLAYER_ID));
156 * {"heos": {"command": "browse/browse", "result": "success", "message": "command under process&sid=1025"}}
157 * {"heos": {"command": "browse/browse", "result": "success", "message": "command under process&sid=1028"}}
158 * {"heos": {"command": "browse/browse", "result": "success", "message": "sid=1025&returned=6&count=6"}, "payload":
159 * [{"container": "yes", "type": "playlist", "cid": "132562", "playable": "yes", "name":
160 * "Maaike Ouboter - En hoe het dan ook weer dag wordt", "image_url": ""}, {"container": "yes", "type": "playlist",
161 * "cid": "132563", "playable": "yes", "name": "Maaike Ouboter - Vanaf nu is het van jou", "image_url": ""},
162 * {"container": "yes", "type": "playlist", "cid": "162887", "playable": "yes", "name": "Easy listening",
163 * "image_url": ""}, {"container": "yes", "type": "playlist", "cid": "174461", "playable": "yes", "name":
164 * "Nieuwe muziek 5-2019", "image_url": ""}, {"container": "yes", "type": "playlist", "cid": "194000", "playable":
165 * "yes", "name": "Nieuwe muziek 2019-05", "image_url": ""}, {"container": "yes", "type": "playlist", "cid":
166 * "194001", "playable": "yes", "name": "Clean Bandit", "image_url": ""}]}
167 * {"heos": {"command": "browse/browse", "result": "success", "message": "sid=1028&returned=3&count=3"}, "payload":
168 * [{"container": "no", "mid": "s6707", "type": "station", "playable": "yes", "name":
169 * "NPO 3FM 96.8 (Top 40 %26 Pop Music)", "image_url":
170 * "http://cdn-profiles.tunein.com/s6707/images/logoq.png?t=636268"}, {"container": "no", "mid": "s2967", "type":
171 * "station", "playable": "yes", "name": "Classic FM Nederland (Classical Music)", "image_url":
172 * "http://cdn-radiotime-logos.tunein.com/s2967q.png"}, {"container": "no", "mid": "s1993", "type": "station",
173 * "playable": "yes", "name": "BNR Nieuwsradio", "image_url": "http://cdn-radiotime-logos.tunein.com/s1993q.png"}],
174 * "options": [{"browse": [{"id": 20, "name": "Remove from HEOS Favorites"}]}]}
175 * {"heos": {"command": "event/user_changed", "message": "signed_in&un=martinvw@mtin.nl"}}
176 * {"heos": {"command": "group/get_groups", "result": "success", "message": ""}, "payload": []}
177 * {"heos": {"command": "player/get_mute", "result": "fail", "message": "eid=2&text=ID Not Valid&pid=null"}}
178 * {"heos": {"command": "player/get_mute", "result": "success", "message": "pid=1958912779&state=off"}}
179 * {"heos": {"command": "player/get_mute", "result": "success", "message": "pid=1958912779&state=on"}}
180 * {"heos": {"command": "player/get_mute", "result": "success", "message": "pid=-831584083&state=off"}}
181 * {"heos": {"command": "player/get_mute", "result": "success", "message": "pid=-831584083&state=on"}}
182 * {"heos": {"command": "player/get_now_playing_media", "result": "fail", "message":
183 * "eid=2&text=ID Not Valid&pid=null"}}
184 * {"heos": {"command": "player/get_now_playing_media", "result": "success", "message": "pid=1679855527"},
185 * "payload": {"type": "song", "song": "", "album": "", "artist": "", "image_url": "", "album_id": "1", "mid": "1",
186 * "qid": 1, "sid": 1024}, "options": []}
187 * {"heos": {"command": "player/get_now_playing_media", "result": "success", "message": "pid=1958912779"},
188 * "payload": {"type": "song", "song": "Solo (feat. Demi Lovato)", "album": "What Is Love? (Deluxe)", "artist":
189 * "Clean Bandit", "image_url":
190 * "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",
191 * "album_id": "", "mid":
192 * "http://192.168.1.230:8015/m-1c176905-f6c7-d168-dc35-86b4735c5976/Clean+Bandit/What+Is+Love_+(Deluxe)/03+Solo+(feat.+Demi+Lovato).m4a",
193 * "qid": 1, "sid": 1024}, "options": []}
194 * {"heos": {"command": "player/get_now_playing_media", "result": "success", "message": "pid=1958912779"},
195 * "payload": {"type": "station", "song": "HEOS Bar - HDMI 2", "station": "HEOS Bar - HDMI 2", "album": "",
196 * "artist": "", "image_url": "", "album_id": "inputs", "mid": "inputs/hdmi_in_2", "qid": 1, "sid": 1027},
198 * {"heos": {"command": "player/get_now_playing_media", "result": "success", "message": "pid=1958912779"},
199 * "payload": {"type": "station", "song": "HEOS Bar - HDMI 3", "station": "HEOS Bar - HDMI 3", "album": "",
200 * "artist": "", "image_url": "", "album_id": "inputs", "mid": "inputs/hdmi_in_3", "qid": 1, "sid": 1027},
202 * {"heos": {"command": "player/get_now_playing_media", "result": "success", "message": "pid=-831584083"},
203 * "payload": {"type": "song", "song": "Applejack", "album":
204 * "The Real... Dolly Parton: The Ultimate Dolly Parton Collection", "artist": "Dolly Parton", "image_url":
205 * "http://192.168.1.230:8015/m-1c176905-f6c7-d168-dc35-86b4735c5976/getImageFromTag/Dolly%20Parton/The%20Real%20Dolly%20Parton%20%5bDisc%202%5d/2-07%20Applejack.m4a",
206 * "album_id": "m-1c176905-f6c7-d168-dc35-86b4735c5976/alb/a-418", "mid":
207 * "m-1c176905-f6c7-d168-dc35-86b4735c5976/alb/a-418/t-4150", "qid": 43, "sid": 1024}, "options": []}
208 * {"heos": {"command": "player/get_now_playing_media", "result": "success", "message": "pid=-831584083"},
209 * "payload": {"type": "song", "song": "Dancing Queen", "album": "ABBA Gold: Greatest Hits", "artist": "ABBA",
211 * "http://192.168.1.230:8015/m-1c176905-f6c7-d168-dc35-86b4735c5976/getImageFromTag/ABBA/ABBA%20Gold_%20Greatest%20Hits/01%20Dancing%20Queen%201.m4a",
212 * "album_id": "m-1c176905-f6c7-d168-dc35-86b4735c5976/alb/a-398", "mid":
213 * "m-1c176905-f6c7-d168-dc35-86b4735c5976/alb/a-398/t-4237", "qid": 1, "sid": 1024}, "options": []}
214 * {"heos": {"command": "player/get_now_playing_media", "result": "success", "message": "pid=-831584083"},
215 * "payload": {"type": "song", "song": "D.I.V.O.R.C.E.", "album":
216 * "The Real... Dolly Parton: The Ultimate Dolly Parton Collection", "artist": "Dolly Parton", "image_url":
217 * "http://192.168.1.230:8015/m-1c176905-f6c7-d168-dc35-86b4735c5976/getImageFromTag/Dolly%20Parton/The%20Real%20Dolly%20Parton%20%5bDisc%201%5d/1-03%20D.I.V.O.R.C.E.m4a",
218 * "album_id": "m-1c176905-f6c7-d168-dc35-86b4735c5976/alb/a-417", "mid":
219 * "m-1c176905-f6c7-d168-dc35-86b4735c5976/alb/a-417/t-4138", "qid": 22, "sid": 1024}, "options": []}
220 * {"heos": {"command": "player/get_now_playing_media", "result": "success", "message": "pid=-831584083"},
221 * "payload": {"type": "song", "song": "Homeward Bound", "album": "The Very Best Of Art Garfunkel: Across America",
222 * "artist": "Art Garfunkel", "image_url":
223 * "http://192.168.1.230:8015/m-1c176905-f6c7-d168-dc35-86b4735c5976/getImageFromTag/Art%20Garfunkel/The%20Very%20Best%20Of%20Art%20Garfunkel_%20Across%20A/06%20-%20Art%20Garfunkel%20-%20Homeward%20Bound.mp3",
224 * "album_id": "m-1c176905-f6c7-d168-dc35-86b4735c5976/alb/a-127", "mid":
225 * "m-1c176905-f6c7-d168-dc35-86b4735c5976/alb/a-127/t-1385", "qid": 80, "sid": 1024}, "options": []}
226 * {"heos": {"command": "player/get_player_info", "result": "success", "message": "pid=1958912779"}, "payload":
227 * {"name": "HEOS Bar", "pid": 1958912779, "model": "HEOS Bar", "version": "1.520.200", "ip": "192.168.1.195",
228 * "network": "wired", "lineout": 0, "serial": "ADAG9180917029"}}
229 * {"heos": {"command": "player/get_player_info", "result": "success", "message": "pid=-831584083"}, "payload":
230 * {"name": "Kantoor HEOS 3", "pid": -831584083, "model": "HEOS 3", "version": "1.520.200", "ip": "192.168.1.230",
231 * "network": "wired", "lineout": 0, "serial": "ACNG9180110887"}}
232 * {"heos": {"command": "player/get_players", "result": "success", "message": ""}, "payload": [{"name": "HEOS Bar",
233 * "pid": 1958912779, "model": "HEOS Bar", "version": "1.520.200", "ip": "192.168.1.195", "network": "wired",
234 * "lineout": 0, "serial": "ADAG9180917029"}, {"name": "Kantoor HEOS 3", "pid": -831584083, "model": "HEOS 3",
235 * "version": "1.520.200", "ip": "192.168.1.230", "network": "wired", "lineout": 0, "serial": "ACNG9180110887"}]}
236 * {"heos": {"command": "player/get_players", "result": "success", "message": ""}, "payload": [{"name":
237 * "Kantoor HEOS 3", "pid": -831584083, "model": "HEOS 3", "version": "1.520.200", "ip": "192.168.1.230", "network":
238 * "wired", "lineout": 0, "serial": "ACNG9180110887"}, {"name": "HEOS Bar", "pid": 1958912779, "model": "HEOS Bar",
239 * "version": "1.520.200", "ip": "192.168.1.195", "network": "wired", "lineout": 0, "serial": "ADAG9180917029"}]}
240 * {"heos": {"command": "player/get_play_mode", "result": "fail", "message": "eid=2&text=ID Not Valid&pid=null"}}
241 * {"heos": {"command": "player/get_play_mode", "result": "success", "message":
242 * "pid=1958912779&repeat=off&shuffle=off"}}
243 * {"heos": {"command": "player/get_play_mode", "result": "success", "message":
244 * "pid=-831584083&repeat=off&shuffle=on"}}
245 * {"heos": {"command": "player/get_play_state", "result": "fail", "message": "eid=2&text=ID Not Valid&pid=null"}}
246 * {"heos": {"command": "player/get_play_state", "result": "success", "message": "pid=1958912779&state=stop"}}
247 * {"heos": {"command": "player/get_play_state", "result": "success", "message": "pid=-831584083&state=pause"}}
248 * {"heos": {"command": "player/get_play_state", "result": "success", "message": "pid=-831584083&state=play"}}
249 * {"heos": {"command": "player/get_play_state", "result": "success", "message": "pid=-831584083&state=stop"}}
250 * {"heos": {"command": "player/get_volume", "result": "fail", "message": "eid=2&text=ID Not Valid&pid=null"}}
251 * {"heos": {"command": "player/get_volume", "result": "success", "message": "pid=1958912779&level=14"}}
252 * {"heos": {"command": "player/get_volume", "result": "success", "message": "pid=1958912779&level=21"}}
253 * {"heos": {"command": "player/get_volume", "result": "success", "message": "pid=1958912779&level=23"}}
254 * {"heos": {"command": "player/get_volume", "result": "success", "message": "pid=-831584083&level=12"}}
255 * {"heos": {"command": "player/get_volume", "result": "success", "message": "pid=-831584083&level=15"}}
256 * {"heos": {"command": "player/play_next", "result": "success", "message": "pid=-831584083"}}
257 * {"heos": {"command": "player/play_previous", "result": "success", "message": "pid=-831584083"}}
258 * {"heos": {"command": "player/set_mute", "result": "success", "message": "pid=1958912779&state=off"}}
259 * {"heos": {"command": "player/set_mute", "result": "success", "message": "pid=1958912779&state=on"}}
260 * {"heos": {"command": "player/set_mute", "result": "success", "message": "pid=-831584083&state=off"}}
261 * {"heos": {"command": "player/set_mute", "result": "success", "message": "pid=-831584083&state=on"}}
262 * {"heos": {"command": "player/set_play_mode", "result": "success", "message": "pid=-831584083&shuffle=off"}}
263 * {"heos": {"command": "player/set_play_mode", "result": "success", "message": "pid=-831584083&shuffle=on"}}
264 * {"heos": {"command": "player/set_play_state", "result": "success", "message": "pid=-831584083&state=pause"}}
265 * {"heos": {"command": "player/set_play_state", "result": "success", "message": "pid=-831584083&state=play"}}
266 * {"heos": {"command": "player/set_volume", "result": "fail", "message":
267 * "eid=9&text=Out of range&pid=-831584083&level=OFF"}}
268 * {"heos": {"command": "player/set_volume", "result": "success", "message": "pid=1958912779&level=14"}}
269 * {"heos": {"command": "player/set_volume", "result": "success", "message": "pid=1958912779&level=17"}}
270 * {"heos": {"command": "player/set_volume", "result": "success", "message": "pid=-831584083&level=10"}}
271 * {"heos": {"command": "player/set_volume", "result": "success", "message": "pid=-831584083&level=12"}}
272 * {"heos": {"command": "player/set_volume", "result": "success", "message": "pid=-831584083&level=14"}}
273 * {"heos": {"command": "player/set_volume", "result": "success", "message": "pid=-831584083&level=15"}}
274 * {"heos": {"command": "player/set_volume", "result": "success", "message": "pid=-831584083&level=16"}}
275 * {"heos": {"command": "player/set_volume", "result": "success", "message": "pid=-831584083&level=18"}}
276 * {"heos": {"command": "player/set_volume", "result": "success", "message": "pid=-831584083&level=21"}}
277 * {"heos": {"command": "player/set_volume", "result": "success", "message": "pid=-831584083&level=4"}}
278 * {"heos": {"command": "player/volume_down", "result": "success", "message": "pid=-831584083&step=1"}}
279 * {"heos": {"command": "system/heart_beat", "result": "success", "message": ""}}
280 * {"heos": {"command": "system/register_for_change_events", "result": "success", "message": "enable=off"}}
281 * {"heos": {"command": "system/register_for_change_events", "result": "success", "message": "enable=on"}}
282 * {"heos": {"command": "system/register_for_change_events", "reult": "success", "message": "enable=on"}}
283 * {"heos": {"command": "system/sign_in", "result": "success", "message":
284 * "command under process&un=martinvw@mtin.nl&pw=Pl7WUFC61Q7zdQD5"}}
285 * {"heos": {"command": "system/sign_in", "result": "success", "message": "signed_in&un=martinvw@mtin.nl"}}