added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.fsinternetradio.internal.handler;
|
||||
|
||||
import org.openhab.binding.fsinternetradio.internal.radio.FrontierSiliconRadio;
|
||||
|
||||
/**
|
||||
* Utils for the handler.
|
||||
*
|
||||
* @author Markus Rathgeb - Initial contribution
|
||||
*/
|
||||
|
||||
public class HandlerUtils {
|
||||
|
||||
/**
|
||||
* Get the radio of a radio handler.
|
||||
*
|
||||
* @param handler the handler
|
||||
* @return the managed radio object
|
||||
*/
|
||||
public static FrontierSiliconRadio getRadio(final FSInternetRadioHandler handler) {
|
||||
return handler.radio;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.fsinternetradio.test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.jupnp.model.ValidationException;
|
||||
import org.jupnp.model.meta.DeviceDetails;
|
||||
import org.jupnp.model.meta.ManufacturerDetails;
|
||||
import org.jupnp.model.meta.ModelDetails;
|
||||
import org.jupnp.model.meta.RemoteDevice;
|
||||
import org.jupnp.model.meta.RemoteDeviceIdentity;
|
||||
import org.jupnp.model.meta.RemoteService;
|
||||
import org.jupnp.model.types.DeviceType;
|
||||
import org.jupnp.model.types.UDN;
|
||||
import org.openhab.binding.fsinternetradio.internal.FSInternetRadioBindingConstants;
|
||||
import org.openhab.binding.fsinternetradio.internal.FSInternetRadioDiscoveryParticipant;
|
||||
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||
import org.openhab.core.config.discovery.upnp.UpnpDiscoveryParticipant;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
|
||||
/**
|
||||
* OSGi tests for the {@link FSInternetRadioDiscoveryParticipant}.
|
||||
*
|
||||
* @author Mihaela Memova - Initial contribution
|
||||
* @author Markus Rathgeb - Migrated from Groovy to pure Java test, made more robust
|
||||
* @author Velin Yordanov - Migrated to mockito
|
||||
*
|
||||
*/
|
||||
public class FSInternetRadioDiscoveryParticipantJavaTest {
|
||||
UpnpDiscoveryParticipant discoveryParticipant;
|
||||
|
||||
// default device variables used in the tests
|
||||
DeviceType DEFAULT_TYPE = new DeviceType("namespace", "type");
|
||||
String DEFAULT_UPC = "upc";
|
||||
URI DEFAULT_URI = null;
|
||||
|
||||
// default radio variables used in most of the tests
|
||||
private static final RemoteDeviceIdentity DEFAULT_RADIO_IDENTITY;
|
||||
private static final URL DEFAULT_RADIO_BASE_URL;
|
||||
String DEFAULT_RADIO_NAME = "HamaRadio";
|
||||
static {
|
||||
try {
|
||||
DEFAULT_RADIO_IDENTITY = new RemoteDeviceIdentity(new UDN("radioUDN"), 60,
|
||||
new URL("http://radioDescriptiveURL"), null, null);
|
||||
DEFAULT_RADIO_BASE_URL = new URL("http://radioBaseURL");
|
||||
} catch (final MalformedURLException ex) {
|
||||
throw new Error("Initialization error", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The default radio is chosen from the {@link FrontierSiliconRadioDiscoveryParticipant}'s
|
||||
* set of supported radios
|
||||
*/
|
||||
String DEFAULT_RADIO_MANIFACTURER = "HAMA";
|
||||
String DEFAULT_RADIO_MODEL_NAME = "IR";
|
||||
String DEFAULT_RADIO_MODEL_DESCRIPTION = "IR Radio";
|
||||
String DEFAULT_RADIO_MODEL_NUMBER = "IR100";
|
||||
String DEFAULT_RADIO_SERIAL_NUMBER = "serialNumber123";
|
||||
|
||||
String RADIO_BINDING_ID = "fsinternetradio"; // taken from the binding.xml file
|
||||
String RADIO_THING_TYPE_ID = "radio"; // taken from the thing-types.xml file
|
||||
String DEFAULT_RADIO_THING_UID = String.format("%s:%s:%s", RADIO_BINDING_ID, RADIO_THING_TYPE_ID,
|
||||
DEFAULT_RADIO_SERIAL_NUMBER);
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
discoveryParticipant = new FSInternetRadioDiscoveryParticipant();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify correct supported types.
|
||||
*/
|
||||
@Test
|
||||
public void correctSupportedTypes() {
|
||||
assertEquals(1, discoveryParticipant.getSupportedThingTypeUIDs().size());
|
||||
assertEquals(FSInternetRadioBindingConstants.THING_TYPE_RADIO,
|
||||
discoveryParticipant.getSupportedThingTypeUIDs().iterator().next());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify valid DiscoveryResult with completeFSInterntRadioDevice.
|
||||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
@Test
|
||||
public void validDiscoveryResultWithComplete() throws ValidationException {
|
||||
RemoteDevice completeFSInternetRadioDevice = createDefaultFSInternetRadioDevice(DEFAULT_RADIO_BASE_URL);
|
||||
final DiscoveryResult result = discoveryParticipant.createResult(completeFSInternetRadioDevice);
|
||||
assertEquals(new ThingUID(DEFAULT_RADIO_THING_UID), result.getThingUID());
|
||||
assertEquals(FSInternetRadioBindingConstants.THING_TYPE_RADIO, result.getThingTypeUID());
|
||||
assertEquals(DEFAULT_RADIO_MANIFACTURER,
|
||||
result.getProperties().get(FSInternetRadioBindingConstants.PROPERTY_MANUFACTURER));
|
||||
assertEquals(DEFAULT_RADIO_MODEL_NUMBER,
|
||||
result.getProperties().get(FSInternetRadioBindingConstants.PROPERTY_MODEL));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify no discovery result for unknown device.
|
||||
*
|
||||
* @throws ValidationException
|
||||
* @throws MalformedURLException
|
||||
*/
|
||||
@Test
|
||||
public void noDiscoveryResultIfUnknown() throws MalformedURLException, ValidationException {
|
||||
RemoteDevice unknownRemoteDevice = createUnknownRemoteDevice();
|
||||
assertNull(discoveryParticipant.createResult(unknownRemoteDevice));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify valid DiscoveryResult with FSInterntRadio device without base URL.
|
||||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
@Test
|
||||
public void validDiscoveryResultIfWithoutBaseUrl() throws ValidationException {
|
||||
RemoteDevice fsInternetRadioDeviceWithoutUrl = createDefaultFSInternetRadioDevice(null);
|
||||
final DiscoveryResult result = discoveryParticipant.createResult(fsInternetRadioDeviceWithoutUrl);
|
||||
assertEquals(new ThingUID(DEFAULT_RADIO_THING_UID), result.getThingUID());
|
||||
assertEquals(FSInternetRadioBindingConstants.THING_TYPE_RADIO, result.getThingTypeUID());
|
||||
assertEquals(DEFAULT_RADIO_MANIFACTURER,
|
||||
result.getProperties().get(FSInternetRadioBindingConstants.PROPERTY_MANUFACTURER));
|
||||
assertEquals(DEFAULT_RADIO_MODEL_NUMBER,
|
||||
result.getProperties().get(FSInternetRadioBindingConstants.PROPERTY_MODEL));
|
||||
}
|
||||
|
||||
private RemoteDevice createDefaultFSInternetRadioDevice(URL baseURL) throws ValidationException {
|
||||
ManufacturerDetails manifacturerDetails = new ManufacturerDetails(DEFAULT_RADIO_MANIFACTURER);
|
||||
ModelDetails modelDetails = new ModelDetails(DEFAULT_RADIO_MODEL_NAME, DEFAULT_RADIO_MODEL_DESCRIPTION,
|
||||
DEFAULT_RADIO_MODEL_NUMBER);
|
||||
DeviceDetails deviceDetails = new DeviceDetails(baseURL, DEFAULT_RADIO_NAME, manifacturerDetails, modelDetails,
|
||||
DEFAULT_RADIO_SERIAL_NUMBER, DEFAULT_UPC, DEFAULT_URI);
|
||||
|
||||
final RemoteService remoteService = null;
|
||||
return new RemoteDevice(DEFAULT_RADIO_IDENTITY, DEFAULT_TYPE, deviceDetails, remoteService);
|
||||
}
|
||||
|
||||
private RemoteDevice createUnknownRemoteDevice() throws ValidationException, MalformedURLException {
|
||||
int deviceIdentityMaxAgeSeconds = 60;
|
||||
RemoteDeviceIdentity identity = new RemoteDeviceIdentity(new UDN("unknownUDN"), deviceIdentityMaxAgeSeconds,
|
||||
new URL("http://unknownDescriptorURL"), null, null);
|
||||
URL anotherBaseURL = new URL("http://unknownBaseUrl");
|
||||
String friendlyName = "Unknown remote device";
|
||||
ManufacturerDetails manifacturerDetails = new ManufacturerDetails("UnknownManifacturer");
|
||||
ModelDetails modelDetails = new ModelDetails("unknownModel");
|
||||
String serialNumber = "unknownSerialNumber";
|
||||
|
||||
DeviceDetails deviceDetails = new DeviceDetails(anotherBaseURL, friendlyName, manifacturerDetails, modelDetails,
|
||||
serialNumber, DEFAULT_UPC, DEFAULT_URI);
|
||||
|
||||
final RemoteService remoteService = null;
|
||||
return new RemoteDevice(identity, DEFAULT_TYPE, deviceDetails, remoteService);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,896 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.fsinternetradio.test;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.ArgumentMatchers.isA;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.openhab.binding.fsinternetradio.internal.FSInternetRadioBindingConstants.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.openhab.binding.fsinternetradio.internal.FSInternetRadioBindingConstants;
|
||||
import org.openhab.binding.fsinternetradio.internal.handler.FSInternetRadioHandler;
|
||||
import org.openhab.binding.fsinternetradio.internal.handler.HandlerUtils;
|
||||
import org.openhab.binding.fsinternetradio.internal.radio.FrontierSiliconRadio;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.items.Item;
|
||||
import org.openhab.core.library.items.DimmerItem;
|
||||
import org.openhab.core.library.items.NumberItem;
|
||||
import org.openhab.core.library.items.StringItem;
|
||||
import org.openhab.core.library.items.SwitchItem;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.IncreaseDecreaseType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.PercentType;
|
||||
import org.openhab.core.library.types.UpDownType;
|
||||
import org.openhab.core.test.TestPortUtil;
|
||||
import org.openhab.core.test.TestServer;
|
||||
import org.openhab.core.test.java.JavaTest;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingStatusInfo;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.thing.binding.ThingHandlerCallback;
|
||||
import org.openhab.core.thing.binding.builder.ChannelBuilder;
|
||||
import org.openhab.core.thing.binding.builder.ThingBuilder;
|
||||
import org.openhab.core.thing.binding.builder.ThingStatusInfoBuilder;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
|
||||
/**
|
||||
* OSGi tests for the {@link FSInternetRadioHandler}.
|
||||
*
|
||||
* @author Mihaela Memova - Initial contribution
|
||||
* @author Markus Rathgeb - Migrated from Groovy to pure Java test, made more robust
|
||||
* @author Velin Yordanov - Migrated to mockito
|
||||
*
|
||||
*/
|
||||
public class FSInternetRadioHandlerJavaTest extends JavaTest {
|
||||
private static final String DEFAULT_TEST_THING_NAME = "testRadioThing";
|
||||
private static final String DEFAULT_TEST_ITEM_NAME = "testItem";
|
||||
private final String VOLUME = "volume";
|
||||
|
||||
// The request send for preset is "SET/netRemote.nav.action.selectPreset";
|
||||
private static final String PRESET = "Preset";
|
||||
private static final int TIMEOUT = 10 * 1000;
|
||||
private static final ThingTypeUID DEFAULT_THING_TYPE_UID = FSInternetRadioBindingConstants.THING_TYPE_RADIO;
|
||||
private static final ThingUID DEFAULT_THING_UID = new ThingUID(DEFAULT_THING_TYPE_UID, DEFAULT_TEST_THING_NAME);
|
||||
private static final RadioServiceDummy radioServiceDummy = new RadioServiceDummy();
|
||||
|
||||
/**
|
||||
* In order to test a specific channel, it is necessary to create a Thing with two channels - CHANNEL_POWER
|
||||
* and the tested channel. So before each test, the power channel is created and added
|
||||
* to an ArrayList of channels. Then in the tests an additional channel is created and added to the ArrayList
|
||||
* when it's needed.
|
||||
*/
|
||||
private Channel powerChannel;
|
||||
|
||||
private ThingHandlerCallback callback;
|
||||
|
||||
private static TestServer server;
|
||||
|
||||
/**
|
||||
* A HashMap which saves all the 'channel-acceppted_item_type' pairs.
|
||||
* It is set before all the tests.
|
||||
*/
|
||||
private static Map<String, String> acceptedItemTypes;
|
||||
|
||||
/**
|
||||
* ArrayList of channels which is used to initialize a radioThing in the test cases.
|
||||
*/
|
||||
private final List<Channel> channels = new ArrayList<>();
|
||||
|
||||
private FSInternetRadioHandler radioHandler;
|
||||
private Thing radioThing;
|
||||
|
||||
private static HttpClient httpClient;
|
||||
|
||||
// default configuration properties
|
||||
private static final String DEFAULT_CONFIG_PROPERTY_IP = "127.0.0.1";
|
||||
private static final String DEFAULT_CONFIG_PROPERTY_PIN = "1234";
|
||||
private static final int DEFAULT_CONFIG_PROPERTY_PORT = TestPortUtil.findFreePort();
|
||||
|
||||
/** The default refresh interval is 60 seconds. For the purposes of the tests it is set to 1 second */
|
||||
private static final String DEFAULT_CONFIG_PROPERTY_REFRESH = "1";
|
||||
private static final Configuration DEFAULT_COMPLETE_CONFIGURATION = createDefaultConfiguration();
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpClass() throws Exception {
|
||||
ServletHolder holder = new ServletHolder(radioServiceDummy);
|
||||
server = new TestServer(DEFAULT_CONFIG_PROPERTY_IP, DEFAULT_CONFIG_PROPERTY_PORT, TIMEOUT, holder);
|
||||
setTheChannelsMap();
|
||||
server.startServer();
|
||||
httpClient = new HttpClient();
|
||||
httpClient.start();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
createThePowerChannel();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownClass() throws Exception {
|
||||
server.stopServer();
|
||||
httpClient.stop();
|
||||
}
|
||||
|
||||
private static @NonNull Channel getChannel(final @NonNull Thing thing, final @NonNull String channelId) {
|
||||
final Channel channel = thing.getChannel(channelId);
|
||||
Assert.assertNotNull(channel);
|
||||
return channel;
|
||||
}
|
||||
|
||||
private static @NonNull ChannelUID getChannelUID(final @NonNull Thing thing, final @NonNull String channelId) {
|
||||
final ChannelUID channelUID = getChannel(thing, channelId).getUID();
|
||||
Assert.assertNotNull(channelUID);
|
||||
return channelUID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify OFFLINE Thing status when the IP is NULL.
|
||||
*/
|
||||
@Test
|
||||
public void offlineIfNullIp() {
|
||||
Configuration config = createConfiguration(null, DEFAULT_CONFIG_PROPERTY_PIN,
|
||||
String.valueOf(DEFAULT_CONFIG_PROPERTY_PORT), DEFAULT_CONFIG_PROPERTY_REFRESH);
|
||||
Thing radioThingWithNullIP = initializeRadioThing(config);
|
||||
testRadioThingConsideringConfiguration(radioThingWithNullIP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify OFFLINE Thing status when the PIN is empty String.
|
||||
*/
|
||||
@Test
|
||||
public void offlineIfEmptyPIN() {
|
||||
Configuration config = createConfiguration(DEFAULT_CONFIG_PROPERTY_IP, "",
|
||||
String.valueOf(DEFAULT_CONFIG_PROPERTY_PORT), DEFAULT_CONFIG_PROPERTY_REFRESH);
|
||||
Thing radioThingWithEmptyPIN = initializeRadioThing(config);
|
||||
testRadioThingConsideringConfiguration(radioThingWithEmptyPIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify OFFLINE Thing status when the PORT is zero.
|
||||
*/
|
||||
@Test
|
||||
public void offlineIfZeroPort() {
|
||||
Configuration config = createConfiguration(DEFAULT_CONFIG_PROPERTY_IP, DEFAULT_CONFIG_PROPERTY_PIN, "0",
|
||||
DEFAULT_CONFIG_PROPERTY_REFRESH);
|
||||
Thing radioThingWithZeroPort = initializeRadioThing(config);
|
||||
testRadioThingConsideringConfiguration(radioThingWithZeroPort);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify OFFLINE Thing status when the PIN is wrong.
|
||||
*/
|
||||
@Test
|
||||
public void offlineIfWrongPIN() {
|
||||
final String wrongPin = "5678";
|
||||
Configuration config = createConfiguration(DEFAULT_CONFIG_PROPERTY_IP, wrongPin,
|
||||
String.valueOf(DEFAULT_CONFIG_PROPERTY_PORT), DEFAULT_CONFIG_PROPERTY_REFRESH);
|
||||
initializeRadioThing(config);
|
||||
waitForAssert(() -> {
|
||||
String exceptionMessage = "Radio does not allow connection, maybe wrong pin?";
|
||||
verifyCommunicationError(exceptionMessage);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify OFFLINE Thing status when the HTTP response cannot be parsed correctly.
|
||||
*/
|
||||
@Test
|
||||
public void offlineIfParseError() {
|
||||
// create a thing with two channels - the power channel and any of the others
|
||||
String modeChannelID = FSInternetRadioBindingConstants.CHANNEL_MODE;
|
||||
String acceptedItemType = acceptedItemTypes.get(modeChannelID);
|
||||
createChannel(DEFAULT_THING_UID, modeChannelID, acceptedItemType);
|
||||
|
||||
Thing radioThing = initializeRadioThing(DEFAULT_COMPLETE_CONFIGURATION);
|
||||
testRadioThingConsideringConfiguration(radioThing);
|
||||
|
||||
ChannelUID modeChannelUID = getChannelUID(radioThing, modeChannelID);
|
||||
|
||||
/*
|
||||
* Setting the isInvalidResponseExpected variable to true
|
||||
* in order to get the incorrect XML response from the servlet
|
||||
*/
|
||||
radioServiceDummy.setInvalidResponse(true);
|
||||
|
||||
// try to handle a command
|
||||
radioHandler.handleCommand(modeChannelUID, DecimalType.valueOf("1"));
|
||||
|
||||
waitForAssert(() -> {
|
||||
String exceptionMessage = "java.io.IOException: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 2;";
|
||||
verifyCommunicationError(exceptionMessage);
|
||||
});
|
||||
radioServiceDummy.setInvalidResponse(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the HTTP status is handled correctly when it is not OK_200.
|
||||
*/
|
||||
@Test
|
||||
public void httpStatusNokHandling() {
|
||||
// create a thing with two channels - the power channel and any of the others
|
||||
String modeChannelID = FSInternetRadioBindingConstants.CHANNEL_MODE;
|
||||
String acceptedItemType = acceptedItemTypes.get(modeChannelID);
|
||||
createChannel(DEFAULT_THING_UID, modeChannelID, acceptedItemType);
|
||||
|
||||
Thing radioThing = initializeRadioThing(DEFAULT_COMPLETE_CONFIGURATION);
|
||||
testRadioThingConsideringConfiguration(radioThing);
|
||||
|
||||
// turn-on the radio
|
||||
turnTheRadioOn(radioThing);
|
||||
|
||||
/*
|
||||
* Setting the needed boolean variable to false, so we can be sure
|
||||
* that the XML response won't have a OK_200 status
|
||||
*/
|
||||
ChannelUID modeChannelUID = getChannelUID(radioThing, modeChannelID);
|
||||
Item modeTestItem = initializeItem(modeChannelUID, CHANNEL_MODE, acceptedItemType);
|
||||
|
||||
// try to handle a command
|
||||
radioHandler.handleCommand(modeChannelUID, DecimalType.valueOf("1"));
|
||||
|
||||
waitForAssert(() -> {
|
||||
assertSame(UnDefType.NULL, modeTestItem.getState());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify ONLINE status of a Thing with complete configuration.
|
||||
*/
|
||||
@Test
|
||||
public void verifyOnlineStatus() {
|
||||
Thing radioThing = initializeRadioThing(DEFAULT_COMPLETE_CONFIGURATION);
|
||||
testRadioThingConsideringConfiguration(radioThing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the power channel is updated.
|
||||
*/
|
||||
@Test
|
||||
public void powerChannelUpdated() {
|
||||
Thing radioThing = initializeRadioThing(DEFAULT_COMPLETE_CONFIGURATION);
|
||||
testRadioThingConsideringConfiguration(radioThing);
|
||||
|
||||
ChannelUID powerChannelUID = powerChannel.getUID();
|
||||
initializeItem(powerChannelUID, DEFAULT_TEST_ITEM_NAME,
|
||||
acceptedItemTypes.get(FSInternetRadioBindingConstants.CHANNEL_POWER));
|
||||
|
||||
radioHandler.handleCommand(powerChannelUID, OnOffType.ON);
|
||||
waitForAssert(() -> {
|
||||
assertTrue("We should be able to turn on the radio",
|
||||
radioServiceDummy.containsRequestParameter(1, CHANNEL_POWER));
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
|
||||
radioHandler.handleCommand(powerChannelUID, OnOffType.OFF);
|
||||
waitForAssert(() -> {
|
||||
assertTrue("We should be able to turn off the radio",
|
||||
radioServiceDummy.containsRequestParameter(0, CHANNEL_POWER));
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
|
||||
/*
|
||||
* Setting the needed boolean variable to true, so we can be sure
|
||||
* that an invalid value will be returned in the XML response
|
||||
*/
|
||||
radioHandler.handleCommand(powerChannelUID, OnOffType.ON);
|
||||
waitForAssert(() -> {
|
||||
assertTrue("We should be able to turn on the radio",
|
||||
radioServiceDummy.containsRequestParameter(1, CHANNEL_POWER));
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the mute channel is updated.
|
||||
*/
|
||||
@Test
|
||||
public void muteChhannelUpdated() {
|
||||
String muteChannelID = FSInternetRadioBindingConstants.CHANNEL_MUTE;
|
||||
String acceptedItemType = acceptedItemTypes.get(muteChannelID);
|
||||
createChannel(DEFAULT_THING_UID, muteChannelID, acceptedItemType);
|
||||
|
||||
Thing radioThing = initializeRadioThing(DEFAULT_COMPLETE_CONFIGURATION);
|
||||
testRadioThingConsideringConfiguration(radioThing);
|
||||
|
||||
turnTheRadioOn(radioThing);
|
||||
|
||||
ChannelUID muteChannelUID = getChannelUID(radioThing, FSInternetRadioBindingConstants.CHANNEL_MUTE);
|
||||
initializeItem(muteChannelUID, DEFAULT_TEST_ITEM_NAME, acceptedItemType);
|
||||
|
||||
radioHandler.handleCommand(muteChannelUID, OnOffType.ON);
|
||||
waitForAssert(() -> {
|
||||
assertTrue("We should be able to mute the radio",
|
||||
radioServiceDummy.containsRequestParameter(1, CHANNEL_MUTE));
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
|
||||
radioHandler.handleCommand(muteChannelUID, OnOffType.OFF);
|
||||
waitForAssert(() -> {
|
||||
assertTrue("We should be able to unmute the radio",
|
||||
radioServiceDummy.containsRequestParameter(0, CHANNEL_MUTE));
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
|
||||
/*
|
||||
* Setting the needed boolean variable to true, so we can be sure
|
||||
* that an invalid value will be returned in the XML response
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the mode channel is updated.
|
||||
*/
|
||||
@Test
|
||||
public void modeChannelUdpated() {
|
||||
String modeChannelID = FSInternetRadioBindingConstants.CHANNEL_MODE;
|
||||
String acceptedItemType = acceptedItemTypes.get(modeChannelID);
|
||||
createChannel(DEFAULT_THING_UID, modeChannelID, acceptedItemType);
|
||||
|
||||
Thing radioThing = initializeRadioThing(DEFAULT_COMPLETE_CONFIGURATION);
|
||||
testRadioThingConsideringConfiguration(radioThing);
|
||||
|
||||
turnTheRadioOn(radioThing);
|
||||
|
||||
ChannelUID modeChannelUID = getChannelUID(radioThing, modeChannelID);
|
||||
initializeItem(modeChannelUID, DEFAULT_TEST_ITEM_NAME, acceptedItemType);
|
||||
|
||||
radioHandler.handleCommand(modeChannelUID, DecimalType.valueOf("1"));
|
||||
waitForAssert(() -> {
|
||||
assertTrue("We should be able to update the mode channel correctly",
|
||||
radioServiceDummy.containsRequestParameter(1, CHANNEL_MODE));
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
|
||||
/*
|
||||
* Setting the needed boolean variable to true, so we can be sure
|
||||
* that an invalid value will be returned in the XML response
|
||||
*/
|
||||
radioHandler.handleCommand(modeChannelUID, DecimalType.valueOf("3"));
|
||||
waitForAssert(() -> {
|
||||
assertTrue("We should be able to update the mode channel correctly",
|
||||
radioServiceDummy.containsRequestParameter(3, CHANNEL_MODE));
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the volume is updated through the CHANNEL_VOLUME_ABSOLUTE using INCREASE and DECREASE commands.
|
||||
*/
|
||||
@Test
|
||||
public void volumechannelUpdatedAbsIncDec() {
|
||||
String absoluteVolumeChannelID = FSInternetRadioBindingConstants.CHANNEL_VOLUME_ABSOLUTE;
|
||||
String absoluteAcceptedItemType = acceptedItemTypes.get(absoluteVolumeChannelID);
|
||||
createChannel(DEFAULT_THING_UID, absoluteVolumeChannelID, absoluteAcceptedItemType);
|
||||
|
||||
Thing radioThing = initializeRadioThing(DEFAULT_COMPLETE_CONFIGURATION);
|
||||
testRadioThingConsideringConfiguration(radioThing);
|
||||
|
||||
turnTheRadioOn(radioThing);
|
||||
|
||||
ChannelUID absoluteVolumeChannelUID = getChannelUID(radioThing, absoluteVolumeChannelID);
|
||||
Item volumeTestItem = initializeItem(absoluteVolumeChannelUID, DEFAULT_TEST_ITEM_NAME,
|
||||
absoluteAcceptedItemType);
|
||||
|
||||
testChannelWithINCREASEAndDECREASECommands(absoluteVolumeChannelUID, volumeTestItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the volume is updated through the CHANNEL_VOLUME_ABSOLUTE using UP and DOWN commands.
|
||||
*/
|
||||
@Test
|
||||
public void volumeChannelUpdatedAbsUpDown() {
|
||||
String absoluteVolumeChannelID = FSInternetRadioBindingConstants.CHANNEL_VOLUME_ABSOLUTE;
|
||||
String absoluteAcceptedItemType = acceptedItemTypes.get(absoluteVolumeChannelID);
|
||||
createChannel(DEFAULT_THING_UID, absoluteVolumeChannelID, absoluteAcceptedItemType);
|
||||
|
||||
Thing radioThing = initializeRadioThing(DEFAULT_COMPLETE_CONFIGURATION);
|
||||
testRadioThingConsideringConfiguration(radioThing);
|
||||
|
||||
turnTheRadioOn(radioThing);
|
||||
|
||||
ChannelUID absoluteVolumeChannelUID = getChannelUID(radioThing, absoluteVolumeChannelID);
|
||||
Item volumeTestItem = initializeItem(absoluteVolumeChannelUID, DEFAULT_TEST_ITEM_NAME,
|
||||
absoluteAcceptedItemType);
|
||||
|
||||
testChannelWithUPAndDOWNCommands(absoluteVolumeChannelUID, volumeTestItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the invalid values when updating CHANNEL_VOLUME_ABSOLUTE are handled correctly.
|
||||
*/
|
||||
@Test
|
||||
public void invalidAbsVolumeValues() {
|
||||
String absoluteVolumeChannelID = FSInternetRadioBindingConstants.CHANNEL_VOLUME_ABSOLUTE;
|
||||
String absoluteAcceptedItemType = acceptedItemTypes.get(absoluteVolumeChannelID);
|
||||
createChannel(DEFAULT_THING_UID, absoluteVolumeChannelID, absoluteAcceptedItemType);
|
||||
|
||||
Thing radioThing = initializeRadioThing(DEFAULT_COMPLETE_CONFIGURATION);
|
||||
testRadioThingConsideringConfiguration(radioThing);
|
||||
|
||||
turnTheRadioOn(radioThing);
|
||||
|
||||
ChannelUID absoluteVolumeChannelUID = getChannelUID(radioThing, absoluteVolumeChannelID);
|
||||
initializeItem(absoluteVolumeChannelUID, DEFAULT_TEST_ITEM_NAME, absoluteAcceptedItemType);
|
||||
|
||||
// Trying to set a value that is greater than the maximum volume
|
||||
radioHandler.handleCommand(absoluteVolumeChannelUID, DecimalType.valueOf("36"));
|
||||
|
||||
waitForAssert(() -> {
|
||||
assertTrue("The volume should not exceed the maximum value",
|
||||
radioServiceDummy.containsRequestParameter(32, VOLUME));
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
|
||||
// Trying to increase the volume more than its maximum value using the INCREASE command
|
||||
radioHandler.handleCommand(absoluteVolumeChannelUID, IncreaseDecreaseType.INCREASE);
|
||||
|
||||
waitForAssert(() -> {
|
||||
assertTrue("The volume should not be increased above the maximum value",
|
||||
radioServiceDummy.areRequestParametersEmpty());
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
|
||||
// Trying to increase the volume more than its maximum value using the UP command
|
||||
radioHandler.handleCommand(absoluteVolumeChannelUID, UpDownType.UP);
|
||||
|
||||
waitForAssert(() -> {
|
||||
assertTrue("The volume should not be increased above the maximum value",
|
||||
radioServiceDummy.areRequestParametersEmpty());
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
|
||||
// Trying to set a value that is lower than the minimum volume value
|
||||
radioHandler.handleCommand(absoluteVolumeChannelUID, DecimalType.valueOf("-10"));
|
||||
waitForAssert(() -> {
|
||||
assertTrue("The volume should not be decreased below 0",
|
||||
radioServiceDummy.containsRequestParameter(0, VOLUME));
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
|
||||
/*
|
||||
* Setting the needed boolean variable to true, so we can be sure
|
||||
* that an invalid value will be returned in the XML response
|
||||
*/
|
||||
|
||||
// trying to set the volume
|
||||
radioHandler.handleCommand(absoluteVolumeChannelUID, DecimalType.valueOf("15"));
|
||||
waitForAssert(() -> {
|
||||
assertTrue("We should be able to set the volume correctly",
|
||||
radioServiceDummy.containsRequestParameter(15, VOLUME));
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the volume is updated through the CHANNEL_VOLUME_PERCENT using INCREASE and DECREASE commands.
|
||||
*/
|
||||
@Test
|
||||
public void volumeChannelUpdatedPercIncDec() {
|
||||
/*
|
||||
* The volume is set through the CHANNEL_VOLUME_PERCENT in order to check if
|
||||
* the absolute volume will be updated properly.
|
||||
*/
|
||||
String absoluteVolumeChannelID = FSInternetRadioBindingConstants.CHANNEL_VOLUME_ABSOLUTE;
|
||||
String absoluteAcceptedItemType = acceptedItemTypes.get(absoluteVolumeChannelID);
|
||||
createChannel(DEFAULT_THING_UID, absoluteVolumeChannelID, absoluteAcceptedItemType);
|
||||
|
||||
String percentVolumeChannelID = FSInternetRadioBindingConstants.CHANNEL_VOLUME_PERCENT;
|
||||
String percentAcceptedItemType = acceptedItemTypes.get(percentVolumeChannelID);
|
||||
createChannel(DEFAULT_THING_UID, percentVolumeChannelID, percentAcceptedItemType);
|
||||
|
||||
Thing radioThing = initializeRadioThing(DEFAULT_COMPLETE_CONFIGURATION);
|
||||
testRadioThingConsideringConfiguration(radioThing);
|
||||
|
||||
turnTheRadioOn(radioThing);
|
||||
|
||||
ChannelUID absoluteVolumeChannelUID = getChannelUID(radioThing, absoluteVolumeChannelID);
|
||||
Item volumeTestItem = initializeItem(absoluteVolumeChannelUID, DEFAULT_TEST_ITEM_NAME,
|
||||
absoluteAcceptedItemType);
|
||||
|
||||
ChannelUID percentVolumeChannelUID = getChannelUID(radioThing, percentVolumeChannelID);
|
||||
|
||||
testChannelWithINCREASEAndDECREASECommands(percentVolumeChannelUID, volumeTestItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the volume is updated through the CHANNEL_VOLUME_PERCENT using UP and DOWN commands.
|
||||
*/
|
||||
@Test
|
||||
public void volumeChannelUpdatedPercUpDown() {
|
||||
/*
|
||||
* The volume is set through the CHANNEL_VOLUME_PERCENT in order to check if
|
||||
* the absolute volume will be updated properly.
|
||||
*/
|
||||
String absoluteVolumeChannelID = FSInternetRadioBindingConstants.CHANNEL_VOLUME_ABSOLUTE;
|
||||
String absoluteAcceptedItemType = acceptedItemTypes.get(absoluteVolumeChannelID);
|
||||
createChannel(DEFAULT_THING_UID, absoluteVolumeChannelID, absoluteAcceptedItemType);
|
||||
|
||||
String percentVolumeChannelID = FSInternetRadioBindingConstants.CHANNEL_VOLUME_PERCENT;
|
||||
String percentAcceptedItemType = acceptedItemTypes.get(percentVolumeChannelID);
|
||||
createChannel(DEFAULT_THING_UID, percentVolumeChannelID, percentAcceptedItemType);
|
||||
|
||||
Thing radioThing = initializeRadioThing(DEFAULT_COMPLETE_CONFIGURATION);
|
||||
testRadioThingConsideringConfiguration(radioThing);
|
||||
|
||||
turnTheRadioOn(radioThing);
|
||||
|
||||
ChannelUID absoluteVolumeChannelUID = getChannelUID(radioThing, absoluteVolumeChannelID);
|
||||
Item volumeTestItem = initializeItem(absoluteVolumeChannelUID, DEFAULT_TEST_ITEM_NAME,
|
||||
absoluteAcceptedItemType);
|
||||
|
||||
ChannelUID percentVolumeChannelUID = getChannelUID(radioThing, percentVolumeChannelID);
|
||||
|
||||
testChannelWithUPAndDOWNCommands(percentVolumeChannelUID, volumeTestItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the valid and invalid values when updating CHANNEL_VOLUME_PERCENT are handled correctly.
|
||||
*/
|
||||
@Test
|
||||
public void validInvalidPercVolume() {
|
||||
String absoluteVolumeChannelID = FSInternetRadioBindingConstants.CHANNEL_VOLUME_ABSOLUTE;
|
||||
String absoluteAcceptedItemType = acceptedItemTypes.get(absoluteVolumeChannelID);
|
||||
createChannel(DEFAULT_THING_UID, absoluteVolumeChannelID, absoluteAcceptedItemType);
|
||||
|
||||
String percentVolumeChannelID = FSInternetRadioBindingConstants.CHANNEL_VOLUME_PERCENT;
|
||||
String percentAcceptedItemType = acceptedItemTypes.get(percentVolumeChannelID);
|
||||
createChannel(DEFAULT_THING_UID, percentVolumeChannelID, percentAcceptedItemType);
|
||||
|
||||
Thing radioThing = initializeRadioThing(DEFAULT_COMPLETE_CONFIGURATION);
|
||||
testRadioThingConsideringConfiguration(radioThing);
|
||||
|
||||
turnTheRadioOn(radioThing);
|
||||
|
||||
ChannelUID absoluteVolumeChannelUID = getChannelUID(radioThing, absoluteVolumeChannelID);
|
||||
initializeItem(absoluteVolumeChannelUID, DEFAULT_TEST_ITEM_NAME, absoluteAcceptedItemType);
|
||||
|
||||
ChannelUID percentVolumeChannelUID = getChannelUID(radioThing, percentVolumeChannelID);
|
||||
|
||||
/*
|
||||
* Giving the handler a valid percent value. According to the FrontierSiliconRadio's
|
||||
* documentation 100 percents correspond to 32 absolute value
|
||||
*/
|
||||
radioHandler.handleCommand(percentVolumeChannelUID, PercentType.valueOf("50"));
|
||||
waitForAssert(() -> {
|
||||
assertTrue("We should be able to set the volume correctly using percentages.",
|
||||
radioServiceDummy.containsRequestParameter(16, VOLUME));
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
|
||||
radioHandler.handleCommand(percentVolumeChannelUID, PercentType.valueOf("15"));
|
||||
|
||||
waitForAssert(() -> {
|
||||
assertTrue("We should be able to set the volume correctly using percentages.",
|
||||
radioServiceDummy.containsRequestParameter(4, VOLUME));
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
}
|
||||
|
||||
private void testChannelWithINCREASEAndDECREASECommands(ChannelUID channelUID, Item item) {
|
||||
synchronized (channelUID) {
|
||||
// First we have to make sure that the item state is 0
|
||||
radioHandler.handleCommand(channelUID, DecimalType.valueOf("0"));
|
||||
waitForAssert(() -> {
|
||||
assertTrue("We should be able to turn on the radio",
|
||||
radioServiceDummy.containsRequestParameter(1, CHANNEL_POWER));
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
|
||||
radioHandler.handleCommand(channelUID, IncreaseDecreaseType.INCREASE);
|
||||
|
||||
waitForAssert(() -> {
|
||||
assertTrue("We should be able to increase the volume correctly",
|
||||
radioServiceDummy.containsRequestParameter(1, VOLUME));
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
|
||||
radioHandler.handleCommand(channelUID, IncreaseDecreaseType.DECREASE);
|
||||
waitForAssert(() -> {
|
||||
assertTrue("We should be able to increase the volume correctly",
|
||||
radioServiceDummy.containsRequestParameter(0, VOLUME));
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
|
||||
// Trying to decrease one more time
|
||||
radioHandler.handleCommand(channelUID, IncreaseDecreaseType.DECREASE);
|
||||
waitForAssert(() -> {
|
||||
assertFalse("We should be able to decrease the volume correctly",
|
||||
radioServiceDummy.containsRequestParameter(0, VOLUME));
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void testChannelWithUPAndDOWNCommands(ChannelUID channelUID, Item item) {
|
||||
synchronized (channelUID) {
|
||||
// First we have to make sure that the item state is 0
|
||||
radioHandler.handleCommand(channelUID, DecimalType.valueOf("0"));
|
||||
waitForAssert(() -> {
|
||||
assertTrue("We should be able to turn on the radio",
|
||||
radioServiceDummy.containsRequestParameter(1, CHANNEL_POWER));
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
|
||||
radioHandler.handleCommand(channelUID, UpDownType.UP);
|
||||
waitForAssert(() -> {
|
||||
assertTrue("We should be able to increase the volume correctly",
|
||||
radioServiceDummy.containsRequestParameter(1, VOLUME));
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
|
||||
radioHandler.handleCommand(channelUID, UpDownType.DOWN);
|
||||
waitForAssert(() -> {
|
||||
assertTrue("We should be able to decrease the volume correctly",
|
||||
radioServiceDummy.containsRequestParameter(0, VOLUME));
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
|
||||
// Trying to decrease one more time
|
||||
radioHandler.handleCommand(channelUID, UpDownType.DOWN);
|
||||
waitForAssert(() -> {
|
||||
assertTrue("We shouldn't be able to decrease the volume below 0",
|
||||
radioServiceDummy.areRequestParametersEmpty());
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the preset channel is updated.
|
||||
*/
|
||||
@Test
|
||||
public void presetChannelUpdated() {
|
||||
String presetChannelID = FSInternetRadioBindingConstants.CHANNEL_PRESET;
|
||||
String acceptedItemType = acceptedItemTypes.get(presetChannelID);
|
||||
createChannel(DEFAULT_THING_UID, presetChannelID, acceptedItemType);
|
||||
|
||||
Thing radioThing = initializeRadioThing(DEFAULT_COMPLETE_CONFIGURATION);
|
||||
testRadioThingConsideringConfiguration(radioThing);
|
||||
turnTheRadioOn(radioThing);
|
||||
|
||||
ChannelUID presetChannelUID = getChannelUID(radioThing, FSInternetRadioBindingConstants.CHANNEL_PRESET);
|
||||
initializeItem(presetChannelUID, DEFAULT_TEST_ITEM_NAME, acceptedItemType);
|
||||
|
||||
radioHandler.handleCommand(presetChannelUID, DecimalType.valueOf("100"));
|
||||
waitForAssert(() -> {
|
||||
assertTrue("We should be able to set value to the preset",
|
||||
radioServiceDummy.containsRequestParameter(100, PRESET));
|
||||
radioServiceDummy.clearRequestParameters();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the playInfoName channel is updated.
|
||||
*/
|
||||
@Test
|
||||
public void playInfoNameChannelUpdated() {
|
||||
String playInfoNameChannelID = FSInternetRadioBindingConstants.CHANNEL_PLAY_INFO_NAME;
|
||||
String acceptedItemType = acceptedItemTypes.get(playInfoNameChannelID);
|
||||
createChannel(DEFAULT_THING_UID, playInfoNameChannelID, acceptedItemType);
|
||||
|
||||
Thing radioThing = initializeRadioThingWithMockedHandler(DEFAULT_COMPLETE_CONFIGURATION);
|
||||
testRadioThingConsideringConfiguration(radioThing);
|
||||
|
||||
turnTheRadioOn(radioThing);
|
||||
|
||||
ChannelUID playInfoNameChannelUID = getChannelUID(radioThing,
|
||||
FSInternetRadioBindingConstants.CHANNEL_PLAY_INFO_NAME);
|
||||
initializeItem(playInfoNameChannelUID, DEFAULT_TEST_ITEM_NAME, acceptedItemType);
|
||||
|
||||
waitForAssert(() -> {
|
||||
verifyOnlineStatusIsSet();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the playInfoText channel is updated.
|
||||
*/
|
||||
@Test
|
||||
public void playInfoTextChannelUpdated() {
|
||||
String playInfoTextChannelID = FSInternetRadioBindingConstants.CHANNEL_PLAY_INFO_TEXT;
|
||||
String acceptedItemType = acceptedItemTypes.get(playInfoTextChannelID);
|
||||
createChannel(DEFAULT_THING_UID, playInfoTextChannelID, acceptedItemType);
|
||||
|
||||
Thing radioThing = initializeRadioThingWithMockedHandler(DEFAULT_COMPLETE_CONFIGURATION);
|
||||
testRadioThingConsideringConfiguration(radioThing);
|
||||
|
||||
turnTheRadioOn(radioThing);
|
||||
ChannelUID playInfoTextChannelUID = getChannelUID(radioThing,
|
||||
FSInternetRadioBindingConstants.CHANNEL_PLAY_INFO_TEXT);
|
||||
initializeItem(playInfoTextChannelUID, DEFAULT_TEST_ITEM_NAME, acceptedItemType);
|
||||
|
||||
waitForAssert(() -> {
|
||||
verifyOnlineStatusIsSet();
|
||||
});
|
||||
}
|
||||
|
||||
private static Configuration createDefaultConfiguration() {
|
||||
return createConfiguration(DEFAULT_CONFIG_PROPERTY_IP, DEFAULT_CONFIG_PROPERTY_PIN,
|
||||
String.valueOf(DEFAULT_CONFIG_PROPERTY_PORT), DEFAULT_CONFIG_PROPERTY_REFRESH);
|
||||
}
|
||||
|
||||
private static Configuration createConfiguration(String ip, String pin, String port, String refresh) {
|
||||
Configuration config = new Configuration();
|
||||
config.put(FSInternetRadioBindingConstants.CONFIG_PROPERTY_IP, ip);
|
||||
config.put(FSInternetRadioBindingConstants.CONFIG_PROPERTY_PIN, pin);
|
||||
config.put(FSInternetRadioBindingConstants.CONFIG_PROPERTY_PORT, new BigDecimal(port));
|
||||
config.put(FSInternetRadioBindingConstants.CONFIG_PROPERTY_REFRESH, new BigDecimal(refresh));
|
||||
return config;
|
||||
}
|
||||
|
||||
private static void setTheChannelsMap() {
|
||||
acceptedItemTypes = new HashMap<>();
|
||||
acceptedItemTypes.put(FSInternetRadioBindingConstants.CHANNEL_POWER, "Switch");
|
||||
acceptedItemTypes.put(FSInternetRadioBindingConstants.CHANNEL_MODE, "Number");
|
||||
acceptedItemTypes.put(FSInternetRadioBindingConstants.CHANNEL_MUTE, "Switch");
|
||||
acceptedItemTypes.put(FSInternetRadioBindingConstants.CHANNEL_PLAY_INFO_NAME, "String");
|
||||
acceptedItemTypes.put(FSInternetRadioBindingConstants.CHANNEL_PLAY_INFO_TEXT, "String");
|
||||
acceptedItemTypes.put(FSInternetRadioBindingConstants.CHANNEL_PRESET, "Number");
|
||||
acceptedItemTypes.put(FSInternetRadioBindingConstants.CHANNEL_VOLUME_ABSOLUTE, "Number");
|
||||
acceptedItemTypes.put(FSInternetRadioBindingConstants.CHANNEL_VOLUME_PERCENT, "Dimmer");
|
||||
}
|
||||
|
||||
private void createThePowerChannel() {
|
||||
String powerChannelID = FSInternetRadioBindingConstants.CHANNEL_POWER;
|
||||
String acceptedItemType = acceptedItemTypes.get(powerChannelID);
|
||||
powerChannel = createChannel(DEFAULT_THING_UID, powerChannelID, acceptedItemType);
|
||||
}
|
||||
|
||||
private Item initializeItem(ChannelUID channelUID, String itemName, String acceptedItemType) {
|
||||
Item item = null;
|
||||
|
||||
switch (acceptedItemType) {
|
||||
case "Number":
|
||||
item = new NumberItem(itemName);
|
||||
break;
|
||||
|
||||
case "String":
|
||||
item = new StringItem(itemName);
|
||||
break;
|
||||
|
||||
case "Switch":
|
||||
item = new SwitchItem(itemName);
|
||||
break;
|
||||
|
||||
case "Dimmer":
|
||||
item = new DimmerItem(itemName);
|
||||
break;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private Channel createChannel(ThingUID thingUID, String channelID, String acceptedItemType) {
|
||||
ChannelUID channelUID = new ChannelUID(thingUID, channelID);
|
||||
|
||||
Channel radioChannel = ChannelBuilder.create(channelUID, acceptedItemType).build();
|
||||
channels.add(radioChannel);
|
||||
return radioChannel;
|
||||
}
|
||||
|
||||
private void testRadioThingConsideringConfiguration(Thing thing) {
|
||||
Configuration config = thing.getConfiguration();
|
||||
if (isConfigurationComplete(config)) {
|
||||
waitForAssert(() -> {
|
||||
verifyOnlineStatusIsSet();
|
||||
});
|
||||
} else {
|
||||
waitForAssert(() -> {
|
||||
verifyConfigurationError();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isConfigurationComplete(Configuration config) {
|
||||
String ip = (String) config.get(FSInternetRadioBindingConstants.CONFIG_PROPERTY_IP);
|
||||
BigDecimal port = (BigDecimal) config.get(FSInternetRadioBindingConstants.CONFIG_PROPERTY_PORT.toString());
|
||||
String pin = (String) config.get(FSInternetRadioBindingConstants.CONFIG_PROPERTY_PIN.toString());
|
||||
|
||||
if (ip == null || port.compareTo(BigDecimal.ZERO) == 0 || StringUtils.isEmpty(pin)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("null")
|
||||
private Thing initializeRadioThing(Configuration config) {
|
||||
radioThing = ThingBuilder.create(DEFAULT_THING_TYPE_UID, DEFAULT_THING_UID).withConfiguration(config)
|
||||
.withChannels(channels).build();
|
||||
|
||||
callback = mock(ThingHandlerCallback.class);
|
||||
|
||||
radioHandler = new FSInternetRadioHandler(radioThing, httpClient);
|
||||
radioHandler.setCallback(callback);
|
||||
radioThing.setHandler(radioHandler);
|
||||
radioThing.getHandler().initialize();
|
||||
|
||||
return radioThing;
|
||||
}
|
||||
|
||||
@SuppressWarnings("null")
|
||||
private Thing initializeRadioThingWithMockedHandler(Configuration config) {
|
||||
radioThing = ThingBuilder.create(DEFAULT_THING_TYPE_UID, DEFAULT_THING_UID).withConfiguration(config)
|
||||
.withChannels(channels).build();
|
||||
|
||||
callback = mock(ThingHandlerCallback.class);
|
||||
|
||||
radioHandler = new MockedRadioHandler(radioThing, httpClient);
|
||||
radioHandler.setCallback(callback);
|
||||
radioThing.setHandler(radioHandler);
|
||||
radioThing.getHandler().initialize();
|
||||
|
||||
return radioThing;
|
||||
}
|
||||
|
||||
private void turnTheRadioOn(Thing radioThing) {
|
||||
radioHandler.handleCommand(getChannelUID(radioThing, FSInternetRadioBindingConstants.CHANNEL_POWER),
|
||||
OnOffType.ON);
|
||||
|
||||
final FrontierSiliconRadio radio = HandlerUtils.getRadio(radioHandler);
|
||||
|
||||
waitForAssert(() -> {
|
||||
try {
|
||||
assertTrue(radio.getPower());
|
||||
} catch (IOException ex) {
|
||||
throw new AssertionError("I/O error", ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void verifyOnlineStatusIsSet() {
|
||||
ThingStatusInfoBuilder statusBuilder = ThingStatusInfoBuilder.create(ThingStatus.ONLINE,
|
||||
ThingStatusDetail.NONE);
|
||||
ThingStatusInfo statusInfo = statusBuilder.withDescription(null).build();
|
||||
verify(callback, atLeast(1)).statusUpdated(radioThing, statusInfo);
|
||||
}
|
||||
|
||||
private void verifyConfigurationError() {
|
||||
ThingStatusInfoBuilder statusBuilder = ThingStatusInfoBuilder.create(ThingStatus.OFFLINE,
|
||||
ThingStatusDetail.CONFIGURATION_ERROR);
|
||||
ThingStatusInfo statusInfo = statusBuilder.withDescription("Configuration incomplete").build();
|
||||
verify(callback, atLeast(1)).statusUpdated(radioThing, statusInfo);
|
||||
}
|
||||
|
||||
private void verifyCommunicationError(String exceptionMessage) {
|
||||
ArgumentCaptor<ThingStatusInfo> captor = ArgumentCaptor.forClass(ThingStatusInfo.class);
|
||||
verify(callback, atLeast(1)).statusUpdated(isA(Thing.class), captor.capture());
|
||||
ThingStatusInfo status = captor.getValue();
|
||||
assertThat(status.getStatus(), is(ThingStatus.OFFLINE));
|
||||
assertThat(status.getStatusDetail(), is(ThingStatusDetail.COMMUNICATION_ERROR));
|
||||
assertThat(status.getDescription().contains(exceptionMessage), is(true));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.fsinternetradio.test;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.openhab.binding.fsinternetradio.internal.handler.FSInternetRadioHandler;
|
||||
import org.openhab.core.thing.Thing;
|
||||
|
||||
/**
|
||||
* A mock of FSInternetRadioHandler to enable testing.
|
||||
*
|
||||
* @author Velin Yordanov - initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class MockedRadioHandler extends FSInternetRadioHandler {
|
||||
|
||||
public MockedRadioHandler(Thing thing, HttpClient client) {
|
||||
super(thing, client);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isLinked(String channelUID) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.fsinternetradio.test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.openhab.binding.fsinternetradio.internal.radio.FrontierSiliconRadioConstants;
|
||||
|
||||
/**
|
||||
* Radio service mock.
|
||||
*
|
||||
* @author Markus Rathgeb - Initial contribution
|
||||
* @author Velin Yordanov - Small adjustments
|
||||
*/
|
||||
public class RadioServiceDummy extends HttpServlet {
|
||||
private static Map<Integer, String> requestParameters = new ConcurrentHashMap<>();
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final String MOCK_RADIO_PIN = "1234";
|
||||
|
||||
private static final String REQUEST_SET_POWER = "/" + FrontierSiliconRadioConstants.REQUEST_SET_POWER;
|
||||
private static final String REQUEST_GET_POWER = "/" + FrontierSiliconRadioConstants.REQUEST_GET_POWER;
|
||||
private static final String REQUEST_GET_MODE = "/" + FrontierSiliconRadioConstants.REQUEST_GET_MODE;
|
||||
private static final String REQUEST_SET_MODE = "/" + FrontierSiliconRadioConstants.REQUEST_SET_MODE;
|
||||
private static final String REQUEST_SET_VOLUME = "/" + FrontierSiliconRadioConstants.REQUEST_SET_VOLUME;
|
||||
private static final String REQUEST_GET_VOLUME = "/" + FrontierSiliconRadioConstants.REQUEST_GET_VOLUME;
|
||||
private static final String REQUEST_SET_MUTE = "/" + FrontierSiliconRadioConstants.REQUEST_SET_MUTE;
|
||||
private static final String REQUEST_GET_MUTE = "/" + FrontierSiliconRadioConstants.REQUEST_GET_MUTE;
|
||||
private static final String REQUEST_SET_PRESET_ACTION = "/"
|
||||
+ FrontierSiliconRadioConstants.REQUEST_SET_PRESET_ACTION;
|
||||
private static final String REQUEST_GET_PLAY_INFO_TEXT = "/"
|
||||
+ FrontierSiliconRadioConstants.REQUEST_GET_PLAY_INFO_TEXT;
|
||||
private static final String REQUEST_GET_PLAY_INFO_NAME = "/"
|
||||
+ FrontierSiliconRadioConstants.REQUEST_GET_PLAY_INFO_NAME;
|
||||
private static final String VALUE = "value";
|
||||
|
||||
/*
|
||||
* For the purposes of the tests it is assumed that the current station and the additional information
|
||||
* are always the same (random_station and additional_info)
|
||||
*/
|
||||
private final String playInfoNameValue = "random_station";
|
||||
private final String playInfoNameTag = makeC8_arrayTag(playInfoNameValue);
|
||||
|
||||
private final String playInfoTextValue = "additional_info";
|
||||
private final String playInfoTextTag = makeC8_arrayTag(playInfoTextValue);
|
||||
|
||||
private final int httpStatus;
|
||||
|
||||
private String tagToReturn = "";
|
||||
private String responseToReturn = "";
|
||||
|
||||
private boolean isInvalidResponseExpected;
|
||||
private boolean isInvalidValueExpected;
|
||||
private boolean isOKAnswerExpected = true;
|
||||
|
||||
private String powerValue;
|
||||
private String powerTag = "";
|
||||
|
||||
private String muteValue;
|
||||
private String muteTag = "";
|
||||
|
||||
private String absoluteVolumeValue;
|
||||
private String absoluteVolumeTag = "";
|
||||
|
||||
private String modeValue;
|
||||
private String modeTag = "";
|
||||
|
||||
private String radioStation = "";
|
||||
|
||||
public RadioServiceDummy() {
|
||||
this.httpStatus = HttpStatus.OK_200;
|
||||
}
|
||||
|
||||
public String getRadioStation() {
|
||||
return radioStation;
|
||||
}
|
||||
|
||||
public void setRadioStation(final String radioStation) {
|
||||
this.radioStation = radioStation;
|
||||
}
|
||||
|
||||
public void setInvalidResponseExpected(boolean isInvalidResponseExpected) {
|
||||
this.isInvalidResponseExpected = isInvalidResponseExpected;
|
||||
}
|
||||
|
||||
public void setOKAnswerExpected(boolean isOKAnswerExpected) {
|
||||
this.isOKAnswerExpected = isOKAnswerExpected;
|
||||
}
|
||||
|
||||
public boolean containsRequestParameter(int value, String parameter) {
|
||||
String url = requestParameters.get(value);
|
||||
if (url == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return url.contains(parameter);
|
||||
}
|
||||
|
||||
public void clearRequestParameters() {
|
||||
requestParameters.clear();
|
||||
}
|
||||
|
||||
public boolean areRequestParametersEmpty() {
|
||||
return requestParameters.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
String queryString = request.getQueryString();
|
||||
Collection<String> requestParameterNames = Collections.list(request.getParameterNames());
|
||||
if (queryString != null && requestParameterNames.contains(VALUE)) {
|
||||
StringBuffer fullUrl = request.getRequestURL().append("?").append(queryString);
|
||||
int value = Integer.parseInt(request.getParameter(VALUE));
|
||||
requestParameters.put(value, fullUrl.toString());
|
||||
}
|
||||
|
||||
String pin = request.getParameter("pin");
|
||||
if (!MOCK_RADIO_PIN.equals(pin)) {
|
||||
response.setStatus(HttpStatus.FORBIDDEN_403);
|
||||
} else if (!isOKAnswerExpected) {
|
||||
response.setStatus(HttpStatus.NOT_FOUND_404);
|
||||
} else {
|
||||
response.setStatus(HttpStatus.OK_200);
|
||||
response.setContentType("text/xml");
|
||||
String commandString = request.getPathInfo();
|
||||
|
||||
switch (commandString) {
|
||||
case (REQUEST_SET_POWER):
|
||||
if (isInvalidValueExpected) {
|
||||
powerValue = null;
|
||||
} else {
|
||||
powerValue = request.getParameter(VALUE);
|
||||
}
|
||||
|
||||
case (REQUEST_GET_POWER):
|
||||
powerTag = makeU8Tag(powerValue);
|
||||
tagToReturn = powerTag;
|
||||
break;
|
||||
|
||||
case (REQUEST_SET_MUTE):
|
||||
if (isInvalidValueExpected) {
|
||||
muteValue = null;
|
||||
} else {
|
||||
muteValue = request.getParameter(VALUE);
|
||||
}
|
||||
|
||||
case (REQUEST_GET_MUTE):
|
||||
muteTag = makeU8Tag(muteValue);
|
||||
tagToReturn = muteTag;
|
||||
break;
|
||||
|
||||
case (REQUEST_SET_MODE):
|
||||
if (isInvalidValueExpected) {
|
||||
modeValue = null;
|
||||
} else {
|
||||
modeValue = request.getParameter(VALUE);
|
||||
}
|
||||
|
||||
case (REQUEST_GET_MODE):
|
||||
modeTag = makeU32Tag(modeValue);
|
||||
tagToReturn = modeTag;
|
||||
break;
|
||||
|
||||
case (REQUEST_SET_VOLUME):
|
||||
if (isInvalidValueExpected) {
|
||||
absoluteVolumeValue = null;
|
||||
} else {
|
||||
absoluteVolumeValue = request.getParameter(VALUE);
|
||||
}
|
||||
|
||||
case (REQUEST_GET_VOLUME):
|
||||
absoluteVolumeTag = makeU8Tag(absoluteVolumeValue);
|
||||
tagToReturn = absoluteVolumeTag;
|
||||
break;
|
||||
|
||||
case (REQUEST_SET_PRESET_ACTION):
|
||||
final String station = request.getParameter(VALUE);
|
||||
setRadioStation(station);
|
||||
break;
|
||||
|
||||
case (REQUEST_GET_PLAY_INFO_NAME):
|
||||
tagToReturn = playInfoNameTag;
|
||||
break;
|
||||
|
||||
case (REQUEST_GET_PLAY_INFO_TEXT):
|
||||
tagToReturn = playInfoTextTag;
|
||||
break;
|
||||
|
||||
default:
|
||||
tagToReturn = "";
|
||||
break;
|
||||
}
|
||||
|
||||
if (isInvalidResponseExpected) {
|
||||
responseToReturn = makeInvalidXMLResponse();
|
||||
} else {
|
||||
responseToReturn = makeValidXMLResponse();
|
||||
}
|
||||
PrintWriter out = response.getWriter();
|
||||
out.print(responseToReturn);
|
||||
}
|
||||
}
|
||||
|
||||
protected String makeU8Tag(final String value) {
|
||||
return String.format("<value><u8>%s</u8></value>", value);
|
||||
}
|
||||
|
||||
protected String makeU32Tag(final String value) {
|
||||
return String.format("<value><u32>%s</u32></value>", value);
|
||||
}
|
||||
|
||||
protected String makeC8_arrayTag(final String value) {
|
||||
return String.format("<value><c8_array>%s</c8_array></value>", value);
|
||||
}
|
||||
|
||||
private String makeValidXMLResponse() throws IOException {
|
||||
return IOUtils.toString(getClass().getResourceAsStream("/validXml.xml"));
|
||||
}
|
||||
|
||||
private String makeInvalidXMLResponse() throws IOException {
|
||||
return IOUtils.toString(getClass().getResourceAsStream("/invalidXml.xml"));
|
||||
}
|
||||
|
||||
public void setInvalidResponse(boolean value) {
|
||||
isInvalidResponseExpected = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<--xmmmmt version="1.0" encoding="UTF-8"?>
|
||||
<pre>
|
||||
<sessionId>111</sessionId>
|
||||
<xmp>
|
||||
<fsapiResponse>
|
||||
<status>FS_OK</status>
|
||||
</fsapiResponse>
|
||||
</xmp>
|
||||
</pre>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<pre>
|
||||
<sessionId>111</sessionId>
|
||||
<xmp>
|
||||
<fsapiResponse>
|
||||
<value>
|
||||
<u8>1</u8>
|
||||
</value>
|
||||
<status>FS_OK</status>
|
||||
</fsapiResponse>
|
||||
</xmp>
|
||||
</pre>
|
||||
Reference in New Issue
Block a user