--- /dev/null
+/**
+ * Copyright (c) 2010-2022 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+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
+ *
+ * @author Laurent Garnier - Initial contribution
+ */
+@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;
+ private @Nullable String combinedInfo;
+ private boolean needsUpdate;
+
+ public SonosMediaInformation() {
+ this(false);
+ }
+
+ public SonosMediaInformation(boolean needsUpdate) {
+ this(null, null, null, null, needsUpdate);
+ }
+
+ public SonosMediaInformation(@Nullable String artist, @Nullable String album, @Nullable String title,
+ @Nullable String combinedInfo, boolean needsUpdate) {
+ this.artist = artist;
+ this.album = album;
+ this.title = title;
+ this.combinedInfo = combinedInfo;
+ this.needsUpdate = needsUpdate;
+ }
+
+ public @Nullable String getArtist() {
+ return artist;
+ }
+
+ public @Nullable String getAlbum() {
+ return album;
+ }
+
+ public @Nullable String getTitle() {
+ return title;
+ }
+
+ public @Nullable String getCombinedInfo() {
+ return combinedInfo;
+ }
+
+ public boolean needsUpdate() {
+ return needsUpdate;
+ }
+
+ public static SonosMediaInformation parseTuneInMediaInfo(@Nullable String opmlUrl, @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 (radioTitle != null && !radioTitle.isEmpty()) {
+ title = radioTitle;
+ combinedInfo = title;
+ if (trackMetaData != null && !trackMetaData.getStreamContent().isEmpty()) {
+ combinedInfo += " - " + trackMetaData.getStreamContent();
+ }
+ return new SonosMediaInformation(null, null, title, combinedInfo, true);
+ }
+ return new SonosMediaInformation(false);
+ }
+
+ public static SonosMediaInformation parseRadioAppMediaInfo(@Nullable String radioTitle,
+ @Nullable SonosMetaData trackMetaData) {
+ if (radioTitle != null && !radioTitle.isEmpty()) {
+ String artist = null;
+ String album = null;
+ String title = radioTitle;
+ String combinedInfo = title;
+ if (trackMetaData != null) {
+ String[] contents = trackMetaData.getStreamContent().split("\\|");
+ String contentTitle = null;
+ for (int i = 0; i < contents.length; i++) {
+ if (contents[i].startsWith("TITLE ")) {
+ contentTitle = contents[i].substring(6).trim();
+ }
+ if (contents[i].startsWith("ARTIST ")) {
+ artist = contents[i].substring(7).trim();
+ }
+ if (contents[i].startsWith("ALBUM ")) {
+ album = contents[i].substring(6).trim();
+ }
+ }
+ if ((artist == null || artist.isEmpty()) && contentTitle != null && !contentTitle.isEmpty()
+ && !contentTitle.startsWith("Advertisement_")) {
+ // Try to extract artist and song title from contentTitle
+ int idx = contentTitle.indexOf(" - ");
+ if (idx > 0) {
+ artist = contentTitle.substring(0, idx);
+ title = contentTitle.substring(idx + 3);
+ }
+ } else if (artist != null && !artist.isEmpty() && album != null && !album.isEmpty()
+ && contentTitle != null && !contentTitle.isEmpty()) {
+ title = contentTitle;
+ }
+ if (artist != null && !artist.isEmpty()) {
+ combinedInfo += " - " + artist;
+ }
+ if (album != null && !album.isEmpty()) {
+ combinedInfo += " - " + album;
+ }
+ if (!radioTitle.equals(title)) {
+ combinedInfo += " - " + title;
+ } else if (contentTitle != null && !contentTitle.isEmpty()
+ && !contentTitle.startsWith("Advertisement_")) {
+ combinedInfo += " - " + contentTitle;
+ }
+ }
+ return new SonosMediaInformation(artist, album, title, combinedInfo, true);
+ }
+ return new SonosMediaInformation(false);
+ }
+
+ public static SonosMediaInformation parseTrack(@Nullable SonosMetaData trackMetaData) {
+ if (trackMetaData != null) {
+ List<String> infos = new ArrayList<>();
+ String artist = !trackMetaData.getAlbumArtist().isEmpty() ? trackMetaData.getAlbumArtist()
+ : trackMetaData.getCreator();
+ if (!artist.isEmpty()) {
+ infos.add(artist);
+ }
+ String album = trackMetaData.getAlbum();
+ if (!album.isEmpty()) {
+ infos.add(album);
+ }
+ String title = trackMetaData.getTitle();
+ if (!title.isEmpty()) {
+ infos.add(title);
+ }
+ return new SonosMediaInformation(artist, album, title, String.join(" - ", infos), true);
+ }
+ return new SonosMediaInformation(false);
+ }
+
+ public static SonosMediaInformation parseTrackTitle(@Nullable SonosMetaData trackMetaData) {
+ if (trackMetaData != null) {
+ String title = trackMetaData.getTitle();
+ return new SonosMediaInformation(null, null, title, title, true);
+ }
+ return new SonosMediaInformation(false);
+ }
+}
import static org.openhab.binding.sonos.internal.SonosBindingConstants.*;
-import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
private static final String STREAM_URI = "x-sonosapi-stream:";
private static final String RADIO_URI = "x-sonosapi-radio:";
private static final String RADIO_MP3_URI = "x-rincon-mp3radio:";
+ private static final String RADIOAPP_URI = "x-sonosapi-hls:radioapp_";
private static final String OPML_TUNE = "http://opml.radiotime.com/Tune.ashx";
private static final String FILE_URI = "x-file-cifs:";
private static final String SPDIF = ":spdif";
private static final String ACTION_SET_LOUDNESS = "SetLoudness";
private static final String ACTION_SET_EQ = "SetEQ";
- private static final int SOCKET_TIMEOUT = 5000;
-
private static final int TUNEIN_DEFAULT_SERVICE_TYPE = 65031;
private static final int MIN_BASS = -10;
SonosMetaData currentTrack = getTrackMetadata();
SonosMetaData currentUriMetaData = getCurrentURIMetadata();
- String artist = null;
- String album = null;
- String title = null;
- String resultString = null;
String stationID = null;
- boolean needsUpdating = false;
+ SonosMediaInformation mediaInfo = new SonosMediaInformation();
// if currentURI == null, we do nothing
if (currentURI != null) {
if (currentURI.isEmpty()) {
// Reset data
- needsUpdating = true;
+ mediaInfo = new SonosMediaInformation(true);
}
// if (currentURI.contains(GROUP_URI)) we do nothing, because
else if (isPlayingStream(currentURI) || isPlayingRadioStartedByAmazonEcho(currentURI)) {
// Radio stream (tune-in)
- boolean opmlUrlSucceeded = false;
stationID = extractStationId(currentURI);
- String url = opmlUrl;
- if (url != null) {
- String mac = getMACAddress();
- if (stationID != null && !stationID.isEmpty() && mac != null && !mac.isEmpty()) {
- url = url.replace("%id", stationID);
- url = url.replace("%serial", mac);
-
- String response = null;
- try {
- response = HttpUtil.executeUrl("GET", url, SOCKET_TIMEOUT);
- } catch (IOException e) {
- logger.debug("Request to device failed", e);
- }
-
- if (response != null) {
- List<String> fields = SonosXMLParser.getRadioTimeFromXML(response);
-
- if (!fields.isEmpty()) {
- opmlUrlSucceeded = true;
-
- resultString = "";
- for (String field : fields) {
- if (resultString.isEmpty()) {
- // radio name should be first field
- title = field;
- } else {
- resultString += " - ";
- }
- resultString += field;
- }
+ mediaInfo = SonosMediaInformation.parseTuneInMediaInfo(buildOpmlUrl(stationID),
+ currentUriMetaData != null ? currentUriMetaData.getTitle() : null, currentTrack);
+ }
- needsUpdating = true;
- }
- }
- }
- }
- if (!opmlUrlSucceeded) {
- if (currentUriMetaData != null) {
- title = currentUriMetaData.getTitle();
- if (currentTrack == null || currentTrack.getStreamContent().isEmpty()) {
- resultString = title;
- } else {
- resultString = title + " - " + currentTrack.getStreamContent();
- }
- needsUpdating = true;
- }
- }
+ else if (isPlayingRadioApp(currentURI)) {
+ mediaInfo = SonosMediaInformation.parseRadioAppMediaInfo(
+ currentUriMetaData != null ? currentUriMetaData.getTitle() : null, currentTrack);
}
else if (isPlayingLineIn(currentURI)) {
- if (currentTrack != null) {
- title = currentTrack.getTitle();
- resultString = title;
- needsUpdating = true;
- }
+ mediaInfo = SonosMediaInformation.parseTrackTitle(currentTrack);
}
else if (isPlayingRadio(currentURI)
|| (!currentURI.contains("x-rincon-mp3") && !currentURI.contains("x-sonosapi"))) {
- // isPlayingRadio(currentURI) is true for Google Play Music radio or Apple Music radio
- if (currentTrack != null) {
- artist = !currentTrack.getAlbumArtist().isEmpty() ? currentTrack.getAlbumArtist()
- : currentTrack.getCreator();
- album = currentTrack.getAlbum();
- title = currentTrack.getTitle();
- resultString = artist + " - " + album + " - " + title;
- needsUpdating = true;
- }
+ mediaInfo = SonosMediaInformation.parseTrack(currentTrack);
}
}
}
memberHandler.onValueReceived("CurrentTuneInStationId", (stationID != null) ? stationID : "",
SERVICE_AV_TRANSPORT);
- if (needsUpdating) {
+ if (mediaInfo.needsUpdate()) {
+ String artist = mediaInfo.getArtist();
+ String album = mediaInfo.getAlbum();
+ String title = mediaInfo.getTitle();
+ String combinedInfo = mediaInfo.getCombinedInfo();
memberHandler.onValueReceived("CurrentArtist", (artist != null) ? artist : "",
SERVICE_AV_TRANSPORT);
memberHandler.onValueReceived("CurrentAlbum", (album != null) ? album : "",
SERVICE_AV_TRANSPORT);
memberHandler.onValueReceived("CurrentTitle", (title != null) ? title : "",
SERVICE_AV_TRANSPORT);
- memberHandler.onValueReceived("CurrentURIFormatted", (resultString != null) ? resultString : "",
+ memberHandler.onValueReceived("CurrentURIFormatted", (combinedInfo != null) ? combinedInfo : "",
SERVICE_AV_TRANSPORT);
memberHandler.onValueReceived("CurrentAlbumArtURI", albumArtURI, SERVICE_AV_TRANSPORT);
}
logger.debug("Cannot update media data for group member ({})", e.getMessage());
}
}
- if (needsUpdating && handlerForImageUpdate != null) {
+ if (mediaInfo.needsUpdate() && handlerForImageUpdate != null) {
handlerForImageUpdate.updateAlbumArtChannel(true);
}
}
+ private @Nullable String buildOpmlUrl(@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;
+ }
+ }
+ return null;
+ }
+
private @Nullable String extractStationId(String uri) {
String stationID = null;
if (isPlayingStream(uri)) {
savedState.volume = getVolume();
if (currentURI != null) {
- if (isPlayingStream(currentURI) || isPlayingRadioStartedByAmazonEcho(currentURI)
- || isPlayingRadio(currentURI)) {
+ if (isPlayingStreamOrRadio(currentURI)) {
// we are streaming music, like tune-in radio or Google Play Music radio
SonosMetaData track = getTrackMetadata();
SonosMetaData current = getCurrentURIMetadata();
logger.debug("playNotificationSoundURI: currentURI {} metadata {}", currentURI,
coordinator.getCurrentURIMetadataAsString());
- if (isPlayingStream(currentURI) || isPlayingRadioStartedByAmazonEcho(currentURI)
- || isPlayingRadio(currentURI)) {
+ if (isPlayingStreamOrRadio(currentURI)) {
handleNotifForRadioStream(currentURI, notificationURL, coordinator);
} else if (isPlayingLineIn(currentURI)) {
handleNotifForLineIn(currentURI, notificationURL, coordinator);
}
private boolean isPlayingRadio(@Nullable String currentURI) {
+ // Google Play Music radio or Apple Music radio
return currentURI != null && currentURI.contains(RADIO_URI);
}
+ private boolean isPlayingRadioApp(@Nullable String currentURI) {
+ // RadioApp music service
+ return currentURI != null && currentURI.contains(RADIOAPP_URI);
+ }
+
private boolean isPlayingRadioStartedByAmazonEcho(@Nullable String currentURI) {
return currentURI != null && currentURI.contains(RADIO_MP3_URI) && currentURI.contains(OPML_TUNE);
}
+ private boolean isPlayingStreamOrRadio(@Nullable String currentURI) {
+ return isPlayingStream(currentURI) || isPlayingRadioStartedByAmazonEcho(currentURI)
+ || isPlayingRadio(currentURI) || isPlayingRadioApp(currentURI);
+ }
+
private boolean isPlayingLineIn(@Nullable String currentURI) {
return currentURI != null && (isPlayingAnalogLineIn(currentURI) || isPlayingOpticalLineIn(currentURI));
}
--- /dev/null
+/**
+ * Copyright (c) 2010-2022 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.sonos.internal;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.junit.jupiter.api.Test;
+import org.openhab.binding.sonos.internal.handler.SonosMediaInformation;
+
+/**
+ * Test for class SonosMediaInformation
+ *
+ * @author Laurent Garnier - Initial contribution
+ */
+@NonNullByDefault
+public class SonosMediaInformationTest {
+
+ @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);
+ assertNull(result.getArtist());
+ assertNull(result.getAlbum());
+ assertEquals("Radio One", result.getTitle());
+ assertEquals("Radio One - Mroning 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);
+ assertNull(result.getArtist());
+ assertNull(result.getAlbum());
+ assertEquals("Radio One", result.getTitle());
+ assertEquals("Radio One", result.getCombinedInfo());
+ assertEquals(true, result.needsUpdate());
+ }
+
+ @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);
+ assertNull(result.getArtist());
+ assertNull(result.getAlbum());
+ assertNull(result.getTitle());
+ assertNull(result.getCombinedInfo());
+ assertEquals(false, result.needsUpdate());
+ }
+
+ @Test
+ public void parseTuneInMediaInfoWithNullParams() {
+ SonosMediaInformation result = SonosMediaInformation.parseTuneInMediaInfo(null, null, null);
+ assertNull(result.getArtist());
+ assertNull(result.getAlbum());
+ assertNull(result.getTitle());
+ assertNull(result.getCombinedInfo());
+ assertEquals(false, 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);
+ assertEquals("Green Day", result.getArtist());
+ assertEquals("", result.getAlbum());
+ assertEquals("Time Of Your Life (Good Riddance)", result.getTitle());
+ assertEquals("Radio Two - Green Day - Time Of Your Life (Good Riddance)", result.getCombinedInfo());
+ assertEquals(true, result.needsUpdate());
+ }
+
+ @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);
+ assertEquals("Green Day", result.getArtist());
+ assertEquals("Nimrod", result.getAlbum());
+ assertEquals("Time Of Your Life (Good Riddance)", result.getTitle());
+ assertEquals("Radio Two - Green Day - Nimrod - Time Of Your Life (Good Riddance)", result.getCombinedInfo());
+ assertEquals(true, result.needsUpdate());
+ }
+
+ @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);
+ assertEquals("", result.getArtist());
+ assertEquals("", result.getAlbum());
+ assertEquals("Radio Two", result.getTitle());
+ assertEquals("Radio Two", result.getCombinedInfo());
+ assertEquals(true, result.needsUpdate());
+ }
+
+ @Test
+ public void parseRadioAppMediaInfoWithoutStreamContent() {
+ SonosMetaData trackMetaData = new SonosMetaData("yyy", "yyy", "yyy", "", "yyy", "yyy", "yyy", "yyy", "yyy",
+ "yyy");
+ SonosMediaInformation result = SonosMediaInformation.parseRadioAppMediaInfo("Radio Two", trackMetaData);
+ assertNull(result.getArtist());
+ assertNull(result.getAlbum());
+ assertEquals("Radio Two", result.getTitle());
+ assertEquals("Radio Two", result.getCombinedInfo());
+ assertEquals(true, result.needsUpdate());
+ }
+
+ @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);
+ assertNull(result.getArtist());
+ assertNull(result.getAlbum());
+ assertNull(result.getTitle());
+ assertNull(result.getCombinedInfo());
+ assertEquals(false, result.needsUpdate());
+ }
+
+ @Test
+ public void parseRadioAppMediaInfoWithNullParams() {
+ SonosMediaInformation result = SonosMediaInformation.parseRadioAppMediaInfo(null, null);
+ assertNull(result.getArtist());
+ assertNull(result.getAlbum());
+ assertNull(result.getTitle());
+ assertNull(result.getCombinedInfo());
+ assertEquals(false, result.needsUpdate());
+ }
+
+ @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);
+ assertEquals("Green Day", result.getArtist());
+ assertEquals("Nimrod", result.getAlbum());
+ assertEquals("Time Of Your Life (Good Riddance)", result.getTitle());
+ assertEquals("Green Day - Nimrod - Time Of Your Life (Good Riddance)", result.getCombinedInfo());
+ assertEquals(true, result.needsUpdate());
+ }
+
+ @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);
+ assertEquals("", result.getArtist());
+ assertEquals("Nimrod", result.getAlbum());
+ assertEquals("Time Of Your Life (Good Riddance)", result.getTitle());
+ assertEquals("Nimrod - Time Of Your Life (Good Riddance)", result.getCombinedInfo());
+ assertEquals(true, result.needsUpdate());
+ }
+
+ @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);
+ assertEquals("Green Day", result.getArtist());
+ assertEquals("", result.getAlbum());
+ assertEquals("Time Of Your Life (Good Riddance)", result.getTitle());
+ assertEquals("Green Day - Time Of Your Life (Good Riddance)", result.getCombinedInfo());
+ assertEquals(true, result.needsUpdate());
+ }
+
+ @Test
+ public void parseTrackWithoutTitle() {
+ SonosMetaData trackMetaData = new SonosMetaData("xxx", "xxx", "xxx", "xxx", "xxx", "", "xxx", "xxx", "Nimrod",
+ "Green Day");
+ SonosMediaInformation result = SonosMediaInformation.parseTrack(trackMetaData);
+ assertEquals("Green Day", result.getArtist());
+ assertEquals("Nimrod", result.getAlbum());
+ assertEquals("", result.getTitle());
+ assertEquals("Green Day - Nimrod", result.getCombinedInfo());
+ assertEquals(true, result.needsUpdate());
+ }
+
+ @Test
+ public void parseTrackWithOnlyTitle() {
+ SonosMetaData trackMetaData = new SonosMetaData("", "", "", "", "", "Time Of Your Life (Good Riddance)", "", "",
+ "", "");
+ SonosMediaInformation result = SonosMediaInformation.parseTrack(trackMetaData);
+ assertEquals("", result.getArtist());
+ assertEquals("", result.getAlbum());
+ assertEquals("Time Of Your Life (Good Riddance)", result.getTitle());
+ assertEquals("Time Of Your Life (Good Riddance)", result.getCombinedInfo());
+ assertEquals(true, result.needsUpdate());
+ }
+
+ @Test
+ public void parseTrackWithEmptyMetaData() {
+ SonosMetaData trackMetaData = new SonosMetaData("", "", "", "", "", "", "", "", "", "");
+ SonosMediaInformation result = SonosMediaInformation.parseTrack(trackMetaData);
+ assertEquals("", result.getArtist());
+ assertEquals("", result.getAlbum());
+ assertEquals("", result.getTitle());
+ assertEquals("", result.getCombinedInfo());
+ assertEquals(true, result.needsUpdate());
+ }
+
+ @Test
+ public void parseTrackWithNullParam() {
+ SonosMediaInformation result = SonosMediaInformation.parseTrack(null);
+ assertNull(result.getArtist());
+ assertNull(result.getAlbum());
+ assertNull(result.getTitle());
+ assertNull(result.getCombinedInfo());
+ assertEquals(false, result.needsUpdate());
+ }
+
+ @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);
+ assertNull(result.getArtist());
+ assertNull(result.getAlbum());
+ assertEquals("Time Of Your Life (Good Riddance)", result.getTitle());
+ assertEquals("Time Of Your Life (Good Riddance)", result.getCombinedInfo());
+ assertEquals(true, result.needsUpdate());
+ }
+
+ @Test
+ public void parseTrackTitleWithNullParam() {
+ SonosMediaInformation result = SonosMediaInformation.parseTrackTitle(null);
+ assertNull(result.getArtist());
+ assertNull(result.getAlbum());
+ assertNull(result.getTitle());
+ assertNull(result.getCombinedInfo());
+ assertEquals(false, result.needsUpdate());
+ }
+}