Skip to content

Commit

Permalink
[sonos] Unit tests added for OPML request parsing (openhab#13245)
Browse files Browse the repository at this point in the history
Fix a typo in previous unit tests

Signed-off-by: Laurent Garnier <[email protected]>
  • Loading branch information
lolodomo authored and andan67 committed Nov 5, 2022
1 parent ace8410 commit 9056cb4
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,13 @@
*/
package org.openhab.binding.sonos.internal.handler;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.sonos.internal.SonosMetaData;
import org.openhab.binding.sonos.internal.SonosXMLParser;
import org.openhab.core.io.net.http.HttpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* The {@link SonosMediaInformation} is responsible for extracting media information from XML metadata
Expand All @@ -32,10 +28,6 @@
@NonNullByDefault
public class SonosMediaInformation {

private static final int HTTP_TIMEOUT = 5000;

private static final Logger LOGGER = LoggerFactory.getLogger(SonosMediaInformation.class);

private @Nullable String artist;
private @Nullable String album;
private @Nullable String title;
Expand Down Expand Up @@ -79,34 +71,16 @@ public boolean needsUpdate() {
return needsUpdate;
}

public static SonosMediaInformation parseTuneInMediaInfo(@Nullable String opmlUrl, @Nullable String radioTitle,
public static SonosMediaInformation parseTuneInMediaInfo(@Nullable String opmlData, @Nullable String radioTitle,
@Nullable SonosMetaData trackMetaData) {
String title = null;
String combinedInfo = null;
if (opmlUrl != null) {
String response = null;
try {
response = HttpUtil.executeUrl("GET", opmlUrl, HTTP_TIMEOUT);
} catch (IOException e) {
LOGGER.debug("Request to device failed", e);
}

if (response != null) {
List<String> fields = SonosXMLParser.getRadioTimeFromXML(response);

if (!fields.isEmpty()) {
combinedInfo = "";
for (String field : fields) {
if (combinedInfo.isEmpty()) {
// radio name should be first field
title = field;
} else {
combinedInfo += " - ";
}
combinedInfo += field;
}
return new SonosMediaInformation(null, null, title, combinedInfo, true);
}
if (opmlData != null) {
List<String> fields = SonosXMLParser.getRadioTimeFromXML(opmlData);
if (!fields.isEmpty()) {
title = fields.get(0);
combinedInfo = String.join(" - ", fields);
return new SonosMediaInformation(null, null, title, combinedInfo, true);
}
}
if (radioTitle != null && !radioTitle.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import static org.openhab.binding.sonos.internal.SonosBindingConstants.*;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
Expand Down Expand Up @@ -164,6 +165,8 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
private static final int MIN_HEIGHT_LEVEL = -10;
private static final int MAX_HEIGHT_LEVEL = 10;

private static final int HTTP_TIMEOUT = 5000;

private final Logger logger = LoggerFactory.getLogger(ZonePlayerHandler.class);

private final ThingRegistry localThingRegistry;
Expand Down Expand Up @@ -1249,7 +1252,7 @@ protected void updateMediaInformation() {
else if (isPlayingStream(currentURI) || isPlayingRadioStartedByAmazonEcho(currentURI)) {
// Radio stream (tune-in)
stationID = extractStationId(currentURI);
mediaInfo = SonosMediaInformation.parseTuneInMediaInfo(buildOpmlUrl(stationID),
mediaInfo = SonosMediaInformation.parseTuneInMediaInfo(getOpmlData(stationID),
currentUriMetaData != null ? currentUriMetaData.getTitle() : null, currentTrack);
}

Expand Down Expand Up @@ -1308,14 +1311,21 @@ && hasValueChanged(albumArtURI, memberHandler.stateMap.get("CurrentAlbumArtURI")
}
}

private @Nullable String buildOpmlUrl(@Nullable String stationId) {
private @Nullable String getOpmlData(@Nullable String stationId) {
String url = opmlUrl;
if (url != null && stationId != null && !stationId.isEmpty()) {
String mac = getMACAddress();
if (mac != null && !mac.isEmpty()) {
url = url.replace("%id", stationId);
url = url.replace("%serial", mac);
return url;
String response = null;
try {
response = HttpUtil.executeUrl("GET", url, HTTP_TIMEOUT);
} catch (IOException e) {
logger.debug("OPML request failed ({})", url, e);
}
logger.trace("OPML response = {}", response);
return response;
}
}
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

import static org.junit.jupiter.api.Assertions.*;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.Test;
import org.openhab.binding.sonos.internal.handler.SonosMediaInformation;
Expand All @@ -26,23 +30,47 @@
@NonNullByDefault
public class SonosMediaInformationTest {

private static final SonosMetaData METADATA_STREAM_CONTENT = new SonosMetaData("yyy", "yyy", "yyy", "Morning Live",
"yyy", "yyy", "yyy", "yyy", "yyy", "yyy");
private static final SonosMetaData METADATA_EMPTY_STREAM_CONTENT = new SonosMetaData("yyy", "yyy", "yyy", "", "yyy",
"yyy", "yyy", "yyy", "yyy", "yyy");

private static final SonosMetaData METADATA_RADIOAPP_1 = new SonosMetaData("yyy", "yyy", "yyy",
"TYPE=SNG|TITLE Green Day - Time Of Your Life (Good Riddance)|ARTIST |ALBUM ", "yyy", "yyy", "yyy", "yyy",
"yyy", "yyy");
private static final SonosMetaData METADATA_RADIOAPP_2 = new SonosMetaData("yyy", "yyy", "yyy",
"TYPE=SNG|TITLE Time Of Your Life (Good Riddance)|ARTIST Green Day|ALBUM Nimrod", "yyy", "yyy", "yyy",
"yyy", "yyy", "yyy");
private static final SonosMetaData METADATA_RADIOAPP_ADVERTISEMENT = new SonosMetaData("yyy", "yyy", "yyy",
"TYPE=SNG|TITLE Advertisement_Stop|ARTIST |ALBUM ", "yyy", "yyy", "yyy", "yyy", "yyy", "yyy");

private static final SonosMetaData METADATA_ARTIST_ALBUM_TITLE = new SonosMetaData("xxx", "xxx", "xxx", "xxx",
"xxx", "Time Of Your Life (Good Riddance)", "xxx", "xxx", "Nimrod", "Green Day");
private static final SonosMetaData METADATA_EMPTY_CREATOR_ARTIST = new SonosMetaData("xxx", "xxx", "xxx", "xxx",
"xxx", "Time Of Your Life (Good Riddance)", "xxx", "", "Nimrod", "");
private static final SonosMetaData METADATA_EMPTY_ALBUM = new SonosMetaData("xxx", "xxx", "xxx", "xxx", "xxx",
"Time Of Your Life (Good Riddance)", "xxx", "Green Day", "", "");
private static final SonosMetaData METADATA_EMPTY_TITLE = new SonosMetaData("xxx", "xxx", "xxx", "xxx", "xxx", "",
"xxx", "xxx", "Nimrod", "Green Day");
private static final SonosMetaData METADATA_ONLY_TITLE = new SonosMetaData("", "", "", "", "",
"Time Of Your Life (Good Riddance)", "", "", "", "");
private static final SonosMetaData METADATA_EMPTY = new SonosMetaData("", "", "", "", "", "", "", "", "", "");

@Test
public void parseTuneInMediaInfoWithStreamContent() {
SonosMetaData trackMetaData = new SonosMetaData("yyy", "yyy", "yyy", "Mroning Live", "yyy", "yyy", "yyy", "yyy",
"yyy", "yyy");
SonosMediaInformation result = SonosMediaInformation.parseTuneInMediaInfo(null, "Radio One", trackMetaData);
SonosMediaInformation result = SonosMediaInformation.parseTuneInMediaInfo(null, "Radio One",
METADATA_STREAM_CONTENT);
assertNull(result.getArtist());
assertNull(result.getAlbum());
assertEquals("Radio One", result.getTitle());
assertEquals("Radio One - Mroning Live", result.getCombinedInfo());
assertEquals("Radio One - Morning Live", result.getCombinedInfo());
assertEquals(true, result.needsUpdate());
}

@Test
public void parseTuneInMediaInfoWithoutStreamContent() {
SonosMetaData trackMetaData = new SonosMetaData("yyy", "yyy", "yyy", "", "yyy", "yyy", "yyy", "yyy", "yyy",
"yyy");
SonosMediaInformation result = SonosMediaInformation.parseTuneInMediaInfo(null, "Radio One", trackMetaData);
SonosMediaInformation result = SonosMediaInformation.parseTuneInMediaInfo(null, "Radio One",
METADATA_EMPTY_STREAM_CONTENT);
assertNull(result.getArtist());
assertNull(result.getAlbum());
assertEquals("Radio One", result.getTitle());
Expand All @@ -52,9 +80,7 @@ public void parseTuneInMediaInfoWithoutStreamContent() {

@Test
public void parseTuneInMediaInfoWithoutTitle() {
SonosMetaData trackMetaData = new SonosMetaData("yyy", "yyy", "yyy", "Mroning Live", "yyy", "yyy", "yyy", "yyy",
"yyy", "yyy");
SonosMediaInformation result = SonosMediaInformation.parseTuneInMediaInfo(null, "", trackMetaData);
SonosMediaInformation result = SonosMediaInformation.parseTuneInMediaInfo(null, "", METADATA_STREAM_CONTENT);
assertNull(result.getArtist());
assertNull(result.getAlbum());
assertNull(result.getTitle());
Expand All @@ -72,12 +98,23 @@ public void parseTuneInMediaInfoWithNullParams() {
assertEquals(false, result.needsUpdate());
}

@Test
public void parseTuneInMediaInfoWithOPMLRequest() throws IOException {
InputStream resourceStream = getClass().getResourceAsStream("/OPML.xml");
assertNotNull(resourceStream);
final String opmlResult = new String(resourceStream.readAllBytes(), StandardCharsets.UTF_8);
SonosMediaInformation result = SonosMediaInformation.parseTuneInMediaInfo(opmlResult, "Radio One",
METADATA_STREAM_CONTENT);
assertNull(result.getArtist());
assertNull(result.getAlbum());
assertEquals("RTL2 105.9", result.getTitle());
assertEquals("RTL2 105.9 - Le Son Pop-Rock - Paris, France", result.getCombinedInfo());
assertEquals(true, result.needsUpdate());
}

@Test
public void parseRadioAppMediaInfoWithSongTitle() {
SonosMetaData trackMetaData = new SonosMetaData("yyy", "yyy", "yyy",
"TYPE=SNG|TITLE Green Day - Time Of Your Life (Good Riddance)|ARTIST |ALBUM ", "yyy", "yyy", "yyy",
"yyy", "yyy", "yyy");
SonosMediaInformation result = SonosMediaInformation.parseRadioAppMediaInfo("Radio Two", trackMetaData);
SonosMediaInformation result = SonosMediaInformation.parseRadioAppMediaInfo("Radio Two", METADATA_RADIOAPP_1);
assertEquals("Green Day", result.getArtist());
assertEquals("", result.getAlbum());
assertEquals("Time Of Your Life (Good Riddance)", result.getTitle());
Expand All @@ -87,10 +124,7 @@ public void parseRadioAppMediaInfoWithSongTitle() {

@Test
public void parseRadioAppMediaInfoWithSongTitleArtistAlbum() {
SonosMetaData trackMetaData = new SonosMetaData("yyy", "yyy", "yyy",
"TYPE=SNG|TITLE Time Of Your Life (Good Riddance)|ARTIST Green Day|ALBUM Nimrod", "yyy", "yyy", "yyy",
"yyy", "yyy", "yyy");
SonosMediaInformation result = SonosMediaInformation.parseRadioAppMediaInfo("Radio Two", trackMetaData);
SonosMediaInformation result = SonosMediaInformation.parseRadioAppMediaInfo("Radio Two", METADATA_RADIOAPP_2);
assertEquals("Green Day", result.getArtist());
assertEquals("Nimrod", result.getAlbum());
assertEquals("Time Of Your Life (Good Riddance)", result.getTitle());
Expand All @@ -100,9 +134,8 @@ public void parseRadioAppMediaInfoWithSongTitleArtistAlbum() {

@Test
public void parseRadioAppMediaInfoWithdvertisement() {
SonosMetaData trackMetaData = new SonosMetaData("yyy", "yyy", "yyy",
"TYPE=SNG|TITLE Advertisement_Stop|ARTIST |ALBUM ", "yyy", "yyy", "yyy", "yyy", "yyy", "yyy");
SonosMediaInformation result = SonosMediaInformation.parseRadioAppMediaInfo("Radio Two", trackMetaData);
SonosMediaInformation result = SonosMediaInformation.parseRadioAppMediaInfo("Radio Two",
METADATA_RADIOAPP_ADVERTISEMENT);
assertEquals("", result.getArtist());
assertEquals("", result.getAlbum());
assertEquals("Radio Two", result.getTitle());
Expand All @@ -112,9 +145,8 @@ public void parseRadioAppMediaInfoWithdvertisement() {

@Test
public void parseRadioAppMediaInfoWithoutStreamContent() {
SonosMetaData trackMetaData = new SonosMetaData("yyy", "yyy", "yyy", "", "yyy", "yyy", "yyy", "yyy", "yyy",
"yyy");
SonosMediaInformation result = SonosMediaInformation.parseRadioAppMediaInfo("Radio Two", trackMetaData);
SonosMediaInformation result = SonosMediaInformation.parseRadioAppMediaInfo("Radio Two",
METADATA_EMPTY_STREAM_CONTENT);
assertNull(result.getArtist());
assertNull(result.getAlbum());
assertEquals("Radio Two", result.getTitle());
Expand All @@ -124,10 +156,7 @@ public void parseRadioAppMediaInfoWithoutStreamContent() {

@Test
public void parseRadioAppMediaInfoWithoutTitle() {
SonosMetaData trackMetaData = new SonosMetaData("yyy", "yyy", "yyy",
"TYPE=SNG|TITLE Green Day - Time Of Your Life (Good Riddance)|ARTIST |ALBUM ", "yyy", "yyy", "yyy",
"yyy", "yyy", "yyy");
SonosMediaInformation result = SonosMediaInformation.parseRadioAppMediaInfo("", trackMetaData);
SonosMediaInformation result = SonosMediaInformation.parseRadioAppMediaInfo("", METADATA_RADIOAPP_1);
assertNull(result.getArtist());
assertNull(result.getAlbum());
assertNull(result.getTitle());
Expand All @@ -147,9 +176,7 @@ public void parseRadioAppMediaInfoWithNullParams() {

@Test
public void parseTrack() {
SonosMetaData trackMetaData = new SonosMetaData("xxx", "xxx", "xxx", "xxx", "xxx",
"Time Of Your Life (Good Riddance)", "xxx", "xxx", "Nimrod", "Green Day");
SonosMediaInformation result = SonosMediaInformation.parseTrack(trackMetaData);
SonosMediaInformation result = SonosMediaInformation.parseTrack(METADATA_ARTIST_ALBUM_TITLE);
assertEquals("Green Day", result.getArtist());
assertEquals("Nimrod", result.getAlbum());
assertEquals("Time Of Your Life (Good Riddance)", result.getTitle());
Expand All @@ -159,9 +186,7 @@ public void parseTrack() {

@Test
public void parseTrackWithoutArtist() {
SonosMetaData trackMetaData = new SonosMetaData("xxx", "xxx", "xxx", "xxx", "xxx",
"Time Of Your Life (Good Riddance)", "xxx", "", "Nimrod", "");
SonosMediaInformation result = SonosMediaInformation.parseTrack(trackMetaData);
SonosMediaInformation result = SonosMediaInformation.parseTrack(METADATA_EMPTY_CREATOR_ARTIST);
assertEquals("", result.getArtist());
assertEquals("Nimrod", result.getAlbum());
assertEquals("Time Of Your Life (Good Riddance)", result.getTitle());
Expand All @@ -171,9 +196,7 @@ public void parseTrackWithoutArtist() {

@Test
public void parseTrackWithoutAlbum() {
SonosMetaData trackMetaData = new SonosMetaData("xxx", "xxx", "xxx", "xxx", "xxx",
"Time Of Your Life (Good Riddance)", "xxx", "Green Day", "", "");
SonosMediaInformation result = SonosMediaInformation.parseTrack(trackMetaData);
SonosMediaInformation result = SonosMediaInformation.parseTrack(METADATA_EMPTY_ALBUM);
assertEquals("Green Day", result.getArtist());
assertEquals("", result.getAlbum());
assertEquals("Time Of Your Life (Good Riddance)", result.getTitle());
Expand All @@ -183,9 +206,7 @@ public void parseTrackWithoutAlbum() {

@Test
public void parseTrackWithoutTitle() {
SonosMetaData trackMetaData = new SonosMetaData("xxx", "xxx", "xxx", "xxx", "xxx", "", "xxx", "xxx", "Nimrod",
"Green Day");
SonosMediaInformation result = SonosMediaInformation.parseTrack(trackMetaData);
SonosMediaInformation result = SonosMediaInformation.parseTrack(METADATA_EMPTY_TITLE);
assertEquals("Green Day", result.getArtist());
assertEquals("Nimrod", result.getAlbum());
assertEquals("", result.getTitle());
Expand All @@ -195,9 +216,7 @@ public void parseTrackWithoutTitle() {

@Test
public void parseTrackWithOnlyTitle() {
SonosMetaData trackMetaData = new SonosMetaData("", "", "", "", "", "Time Of Your Life (Good Riddance)", "", "",
"", "");
SonosMediaInformation result = SonosMediaInformation.parseTrack(trackMetaData);
SonosMediaInformation result = SonosMediaInformation.parseTrack(METADATA_ONLY_TITLE);
assertEquals("", result.getArtist());
assertEquals("", result.getAlbum());
assertEquals("Time Of Your Life (Good Riddance)", result.getTitle());
Expand All @@ -207,8 +226,7 @@ public void parseTrackWithOnlyTitle() {

@Test
public void parseTrackWithEmptyMetaData() {
SonosMetaData trackMetaData = new SonosMetaData("", "", "", "", "", "", "", "", "", "");
SonosMediaInformation result = SonosMediaInformation.parseTrack(trackMetaData);
SonosMediaInformation result = SonosMediaInformation.parseTrack(METADATA_EMPTY);
assertEquals("", result.getArtist());
assertEquals("", result.getAlbum());
assertEquals("", result.getTitle());
Expand All @@ -228,9 +246,7 @@ public void parseTrackWithNullParam() {

@Test
public void parseTrackTitle() {
SonosMetaData trackMetaData = new SonosMetaData("xxx", "xxx", "xxx", "xxx", "xxx",
"Time Of Your Life (Good Riddance)", "xxx", "xxx", "Nimrod", "Green Day");
SonosMediaInformation result = SonosMediaInformation.parseTrackTitle(trackMetaData);
SonosMediaInformation result = SonosMediaInformation.parseTrackTitle(METADATA_ARTIST_ALBUM_TITLE);
assertNull(result.getArtist());
assertNull(result.getAlbum());
assertEquals("Time Of Your Life (Good Riddance)", result.getTitle());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@
*/
package org.openhab.binding.sonos.internal;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.*;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -60,4 +65,18 @@ public void buildThingTypeIdFromZP100Model() {
public void buildThingTypeIdFromModelWithAdditionalTextInParenthesis() {
assertEquals("OneSL", SonosXMLParser.buildThingTypeIdFromModelName("Sonos One SL (OpenHome)"));
}

@Test
public void getRadioTimeFromXML() throws IOException {
InputStream resourceStream = getClass().getResourceAsStream("/OPML.xml");
assertNotNull(resourceStream);
final String opmlResult = new String(resourceStream.readAllBytes(), StandardCharsets.UTF_8);
List<String> result = SonosXMLParser.getRadioTimeFromXML(opmlResult);
assertEquals(3, result.size());
if (result.size() == 3) {
assertEquals("RTL2 105.9", result.get(0));
assertEquals("Le Son Pop-Rock", result.get(1));
assertEquals("Paris, France", result.get(2));
}
}
}
Loading

0 comments on commit 9056cb4

Please sign in to comment.