/**
* Copyright (c) 2010-2016 by the respective copyright holders.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.openhab.binding.mqtt.internal;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.openhab.binding.mqtt.internal.AbstractMqttMessagePubSub.MessageType;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.HSBType;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.OpenClosedType;
import org.openhab.core.library.types.PercentType;
import org.openhab.core.library.types.StringType;
import org.openhab.core.library.types.UpDownType;
import org.openhab.core.transform.TransformationService;
import org.openhab.core.types.Command;
import org.openhab.core.types.State;
import org.openhab.io.transport.mqtt.MqttSenderChannel;
import org.openhab.model.item.binding.BindingConfigParseException;
/**
* @author Davy Vanherbergen
* @since 1.3.0
*/
@RunWith(MockitoJUnitRunner.class)
public class MqttMessagePublisherTest {
@Mock
private TransformationService transformer;
private void validateConfig(String configString, String broker, String topic, MessageType type, String trigger,
String transformString) throws BindingConfigParseException {
MqttMessagePublisher publisher = new MqttMessagePublisher(configString);
if (publisher.getTransformationServiceName() != null) {
publisher.setTransformationService(transformer);
}
assertEquals(broker, publisher.getBroker());
assertEquals(topic, publisher.getTopic());
assertEquals(type, publisher.getMessageType());
assertEquals(trigger, publisher.getTrigger());
assertEquals(transformString, publisher.getTransformationRule());
}
private void validateBadConfig(String configString) {
try {
new MqttMessagePublisher(configString);
fail("Missing exception..");
} catch (BindingConfigParseException e) {
return;
}
}
@Test
public void canParseValidConfigurations() throws BindingConfigParseException {
validateConfig("mybroker:/mytopic:command:ON:1", "mybroker", "/mytopic", MessageType.COMMAND, "ON", "1");
validateConfig("mybroker1:/a/long/topic/goes/here:command:ON:default", "mybroker1", "/a/long/topic/goes/here",
MessageType.COMMAND, "ON", "default");
validateConfig("mybroker1:/wildcard/not/topic:command:ON:xslt(myfile.xslt)", "mybroker1", "/wildcard/not/topic",
MessageType.COMMAND, "ON", "xslt(myfile.xslt)");
validateConfig("mybroker:/mytopic:command:*:file(/tmp/myfile.txt)", "mybroker", "/mytopic", MessageType.COMMAND,
"*", "file(/tmp/myfile.txt)");
validateConfig("mybroker:/mytopic:command:*:file(/tmp/myfile.txt)", "mybroker", "/mytopic", MessageType.COMMAND,
"*", "file(/tmp/myfile.txt)");
String jsonMessage = "{\"message\"\\: \"command\",\"origin\"\\: \"openhab\",\"data\"\\: {\"lamp1\"\\: \"ON\"}} ";
String jsonMessageNoEsc = "{\"message\": \"command\",\"origin\": \"openhab\",\"data\": {\"lamp1\": \"ON\"}}";
validateConfig("testbroker:/mytopic:state:OFF:" + jsonMessage + "", "testbroker", "/mytopic", MessageType.STATE,
"OFF", jsonMessageNoEsc);
}
@Test
public void canDetectInvalidConfigurations() {
validateBadConfig(":/mytopic:command:ON:1");
validateBadConfig("mybroker::command:ON:1:99");
validateBadConfig("mybroker:/mytopic:command:ON:");
validateBadConfig("mybroker:command:ON:1");
validateBadConfig("mybroker:/mytopic:command2:ON:1");
validateBadConfig("mybroker:/test:/mytopic:command:ON:1");
validateBadConfig(null);
validateBadConfig("");
validateBadConfig(" mybroker ; /mytopic : command : * : file(/tmp/myfile.txt)");
}
private void testStateSupport(String configString, State state, boolean expectedStateSupport)
throws BindingConfigParseException {
MqttMessagePublisher publisher = new MqttMessagePublisher(configString);
assertEquals(expectedStateSupport, publisher.supportsState(state));
}
private void testCommandSupport(String configString, Command command, boolean expectedStateSupport)
throws BindingConfigParseException {
MqttMessagePublisher publisher = new MqttMessagePublisher(configString);
assertEquals(expectedStateSupport, publisher.supportsCommand(command));
}
@Test
public void canDetectSupportForStates() throws BindingConfigParseException {
testStateSupport("broker:/topic:state:OFF:0", OnOffType.OFF, true);
testStateSupport("broker:/topic:state:OFF:0", OnOffType.ON, false);
testStateSupport("broker:/topic:state:*:0", OnOffType.OFF, true);
testStateSupport("broker:/topic:state:off:0", OnOffType.OFF, true);
testStateSupport("broker:/topic:stAte:100:0", DecimalType.valueOf("100"), true);
testStateSupport("broker:/topic:state:100:0", DecimalType.valueOf("99"), false);
testStateSupport("broker:/topic:state:20:0", PercentType.HUNDRED, false);
testStateSupport("broker:/topic:state:100:0", PercentType.HUNDRED, true);
testStateSupport("broker:/topic:state:100:0", PercentType.ZERO, false);
testStateSupport("broker:/topic:state:0:0", PercentType.ZERO, true);
testStateSupport("broker:/topic:state:CLOSED:0", OpenClosedType.CLOSED, true);
testStateSupport("broker:/topic:state:OPEN:0", OpenClosedType.CLOSED, false);
testStateSupport("broker:/topic:command:*:0", OpenClosedType.CLOSED, false);
testStateSupport("broker:/topic:command:CLOSED:0", OpenClosedType.CLOSED, false);
testStateSupport("broker:/topic:state:240.0,100.0,100.0:0", HSBType.BLUE, true);
}
@Test
public void canDetectSupportForCommands() throws BindingConfigParseException {
testCommandSupport("broker:/topic:command:OFF:0", OnOffType.OFF, true);
testCommandSupport("broker:/topic:command:OFF:0", OnOffType.ON, false);
testCommandSupport("broker:/topic:command:*:0", OnOffType.OFF, true);
testCommandSupport("broker:/topic:command:off:0", OnOffType.OFF, true);
testCommandSupport("broker:/topic:commAnd:100:0", DecimalType.valueOf("100"), true);
testCommandSupport("broker:/topic:command:100:0", DecimalType.valueOf("99"), false);
testCommandSupport("broker:/topic:command:20:0", PercentType.HUNDRED, false);
testCommandSupport("broker:/topic:command:100:0", PercentType.HUNDRED, true);
testCommandSupport("broker:/topic:command:100:0", PercentType.ZERO, false);
testCommandSupport("broker:/topic:command:5:0", PercentType.ZERO, false);
testCommandSupport("broker:/topic:command:CLOSED:0", OpenClosedType.CLOSED, true);
testCommandSupport("broker:/topic:command:OPEN:0", OpenClosedType.CLOSED, false);
testCommandSupport("broker:/topic:state:*:0", OpenClosedType.CLOSED, false);
testCommandSupport("broker:/topic:state:CLOSED:0", OpenClosedType.CLOSED, false);
System.out.println(HSBType.BLUE);
testCommandSupport("broker:/topic:command:240.0,100.0,100.0:0", HSBType.BLUE, true);
}
@Test
public void canCreateMessageFromCommandOrStateWithStaticTransformation() throws Exception {
assertEquals("test", getPublishedMessage("broker:/topic:command:*:test", "dummy"));
assertEquals("test", getPublishedMessage("broker:/topic:state:*:test", "dummy"));
assertEquals("eisen", getPublishedMessage("broker:/topic:state:*:eisen", OnOffType.ON.toString()));
assertEquals("funk", getPublishedMessage("broker:/topic:state:*:funk", OnOffType.ON.toString()));
assertEquals("{\"person\"{\"name\":\"me\"}}",
getPublishedMessage("broker:/topic:state:*:{\"person\"{\"name\"\\:\"me\"}}", OnOffType.ON.toString()));
assertEquals("ON", getPublishedMessage("broker:/topic:command:*:default", OnOffType.ON.toString()));
assertEquals("OFF", getPublishedMessage("broker:/topic:command:*:default", OnOffType.OFF.toString()));
assertEquals("UP", getPublishedMessage("broker:/topic:command:*:default", UpDownType.UP.toString()));
assertEquals("100", getPublishedMessage("broker:/topic:command:*:default", PercentType.HUNDRED.toString()));
assertEquals("80,81,82",
getPublishedMessage("broker:/topic:command:*:default", HSBType.valueOf("80,81,82").toString()));
assertEquals("0", getPublishedMessage("broker:/topic:command:*:default", DecimalType.ZERO.toString()));
assertEquals("ahah",
getPublishedMessage("broker:/topic:command:*:default", StringType.valueOf("ahah").toString()));
}
private String getPublishedMessage(String configString, String message) throws BindingConfigParseException {
final List<String> sentMessage = new ArrayList<String>();
MqttMessagePublisher publisher = new MqttMessagePublisher(configString);
publisher.setSenderChannel(new MqttSenderChannel() {
@Override
public void publish(String topic, byte[] message) {
sentMessage.add(new String(message));
}
});
publisher.publish(publisher.getTopic(), message.getBytes());
return sentMessage.get(0);
}
}