content: /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License.  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.activemq.artemis.cli.commands.messages;
  
  import static org.junit.jupiter.api.Assertions.assertEquals;
  import static org.junit.jupiter.api.Assertions.fail;
  
  import javax.jms.JMSException;
  import javax.jms.Message;
  
  import org.apache.activemq.artemis.jms.client.ActiveMQDestination;
  import org.apache.activemq.artemis.utils.RandomUtil;
  import org.apache.activemq.cli.test.TestActionContext;
  import org.junit.jupiter.api.BeforeEach;
  import org.junit.jupiter.api.Test;
  import org.mockito.Mockito;
  
  public class ProducerThreadTest {
  
     ProducerThread producer;
     Message mockMessage;
  
     @BeforeEach
     public void setUp() {
        producer = new ProducerThread(null, ActiveMQDestination.createQueue(RandomUtil.randomUUIDString()), 0, null);
        mockMessage = Mockito.mock(Message.class);
     }
  
     @Test
     public void testBooleanPropertyTrue() throws Exception {
        doBooleanPropertyTestImpl("myTrueBoolean", true);
     }
  
     @Test
     public void testBooleanPropertyFalse() throws Exception {
        doBooleanPropertyTestImpl("myFalseBoolean", false);
     }
  
     private void doBooleanPropertyTestImpl(String key, boolean value) throws JMSException {
        producer.setProperties(createJsonProperty(boolean.class.getSimpleName(), key, String.valueOf(value)));
        producer.applyProperties(mockMessage);
  
        Mockito.verify(mockMessage).setBooleanProperty(key, value);
        Mockito.verifyNoMoreInteractions(mockMessage);
     }
  
     @Test
     public void testIntProperty() throws Exception {
        String key = "myInt";
        int value = RandomUtil.randomInt();
  
        producer.setProperties(createJsonProperty(int.class.getSimpleName(), key, String.valueOf(value)));
        producer.applyProperties(mockMessage);
  
        Mockito.verify(mockMessage).setIntProperty(key, value);
        Mockito.verifyNoMoreInteractions(mockMessage);
  
        // Now with a bad int value
        producer.setProperties(createJsonProperty(int.class.getSimpleName(), key, "badInt"));
        try {
           producer.applyProperties(mockMessage);
           fail("should have thrown");
        } catch (NumberFormatException e) {
           // expected
        }
  
        Mockito.verifyNoMoreInteractions(mockMessage);
     }
  
     @Test
     public void testLongProperty() throws Exception {
        String key = "myLong";
        long value = RandomUtil.randomLong();
  
        producer.setProperties(createJsonProperty(long.class.getSimpleName(), key, String.valueOf(value)));
        producer.applyProperties(mockMessage);
  
        Mockito.verify(mockMessage).setLongProperty(key, value);
        Mockito.verifyNoMoreInteractions(mockMessage);
  
        // Now with a bad long value
        producer.setProperties(createJsonProperty(long.class.getSimpleName(), key, "badLong"));
        try {
           producer.applyProperties(mockMessage);
           fail("should have thrown");
        } catch (NumberFormatException e) {
           // expected
        }
  
        Mockito.verifyNoMoreInteractions(mockMessage);
     }
  
     @Test
     public void testByteProperty() throws Exception {
        String key = "myByte";
        byte value = RandomUtil.randomByte();
  
        producer.setProperties(createJsonProperty(byte.class.getSimpleName(), key, String.valueOf(value)));
        producer.applyProperties(mockMessage);
  
        Mockito.verify(mockMessage).setByteProperty(key, value);
        Mockito.verifyNoMoreInteractions(mockMessage);
  
        // Now with a bad byte value
        producer.setProperties(createJsonProperty(byte.class.getSimpleName(), key, "128"));
        try {
           producer.applyProperties(mockMessage);
           fail("should have thrown");
        } catch (NumberFormatException e) {
           // expected
        }
  
        Mockito.verifyNoMoreInteractions(mockMessage);
     }
  
     @Test
     public void testShortProperty() throws Exception {
        String key = "myShort";
        short value = RandomUtil.randomShort();
  
        producer.setProperties(createJsonProperty(short.class.getSimpleName(), key, String.valueOf(value)));
        producer.applyProperties(mockMessage);
  
        Mockito.verify(mockMessage).setShortProperty(key, value);
        Mockito.verifyNoMoreInteractions(mockMessage);
  
        // Now with a bad short value
        producer.setProperties(createJsonProperty(short.class.getSimpleName(), key, "badShort"));
        try {
           producer.applyProperties(mockMessage);
           fail("should have thrown");
        } catch (NumberFormatException e) {
           // expected
        }
  
        Mockito.verifyNoMoreInteractions(mockMessage);
     }
  
     @Test
     public void testFloatProperty() throws Exception {
        String key = "myFloat";
        float value = RandomUtil.randomFloat();
  
        producer.setProperties(createJsonProperty(float.class.getSimpleName(), key, String.valueOf(value)));
        producer.applyProperties(mockMessage);
  
        Mockito.verify(mockMessage).setFloatProperty(key, value);
        Mockito.verifyNoMoreInteractions(mockMessage);
  
        // Now with a bad float value
        producer.setProperties(createJsonProperty(float.class.getSimpleName(), key, "badFloat"));
        try {
           producer.applyProperties(mockMessage);
           fail("should have thrown");
        } catch (NumberFormatException e) {
           // expected
        }
  
        Mockito.verifyNoMoreInteractions(mockMessage);
     }
  
     @Test
     public void testDoubleProperty() throws Exception {
        String key = "myDouble";
        double value = RandomUtil.randomDouble();
  
        producer.setProperties(createJsonProperty(double.class.getSimpleName(), key, String.valueOf(value)));
        producer.applyProperties(mockMessage);
  
        Mockito.verify(mockMessage).setDoubleProperty(key, value);
        Mockito.verifyNoMoreInteractions(mockMessage);
  
        // Now with a bad double value
        producer.setProperties(createJsonProperty(double.class.getSimpleName(), key, "badDouble"));
        try {
           producer.applyProperties(mockMessage);
           fail("should have thrown");
        } catch (NumberFormatException e) {
           // expected
        }
  
        Mockito.verifyNoMoreInteractions(mockMessage);
     }
  
     @Test
     public void testStringProperty() throws Exception {
        doStringPropertyTestImpl("string");
     }
  
     private void doStringPropertyTestImpl(String type) throws JMSException {
        String key = "myString";
        String value = RandomUtil.randomUUIDString();
  
        producer.setProperties(createJsonProperty(type, key, value));
        producer.applyProperties(mockMessage);
  
        Mockito.verify(mockMessage).setStringProperty(key, value);
        Mockito.verifyNoMoreInteractions(mockMessage);
     }
  
     @Test
     public void testPropertyTypeIsCaseInsensitive() throws Exception {
        doStringPropertyTestImpl("String");
     }
  
     @Test
     public void testBadMessagePropertyType() throws Exception {
        TestActionContext context = new TestActionContext();
        producer = new ProducerThread(null, ActiveMQDestination.createQueue(RandomUtil.randomUUIDString()), 0, context);
  
        producer.setProperties(createJsonProperty("myType", "myKey", "myValue"));
        producer.applyProperties(mockMessage);
  
        assertEquals("Unable to set property: myKey. Did not recognize type: myType. Supported types are: boolean, int, long, byte, short, float, double, string.\n", context.getStderr());
     }
  
     private static String createJsonProperty(String type, String key, String value) {
        return ("[{'type':'" + type + "','key':'" + key + "','value':'" + value + "'}]").replaceAll("'", "\"");
     }
  }
  