/** * 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); } }