org.pentaho.di.trans.steps.mailinput.ParseMailInputTest.java Source code

Java tutorial

Introduction

Here is the source code for org.pentaho.di.trans.steps.mailinput.ParseMailInputTest.java

Source

/*! ******************************************************************************
 *
 * Pentaho Data Integration
 *
 * Copyright (C) 2002-2013 by Pentaho : http://www.pentaho.com
 *
 *******************************************************************************
 *
 * Licensed 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.pentaho.di.trans.steps.mailinput;

import static org.mockito.AdditionalMatchers.aryEq;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.regex.Pattern;

import javax.mail.Address;
import javax.mail.Header;
import javax.mail.Message;
import javax.mail.MessagingException;

import org.apache.commons.lang.StringUtils;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.logging.LoggingObjectInterface;
import org.pentaho.di.core.row.RowDataUtil;
import org.pentaho.di.job.entries.getpop.MailConnection;
import org.pentaho.di.trans.step.StepDataInterface;
import org.pentaho.di.trans.steps.mailinput.MailInput.MessageParser;
import org.pentaho.di.trans.steps.mock.StepMockHelper;

public class ParseMailInputTest {

    // mock is existed per-class instance loaded by junit loader
    private static StepMockHelper<MailInputMeta, StepDataInterface> stepMockHelper;

    // test data
    public static final int MSG_NUMB = 3;
    public static final String MSG_BODY = "msg_body";
    public static final String FLD_NAME = "junit_folder";
    public static final int ATTCH_COUNT = 3;
    public static final String CNTNT_TYPE = "text/html";
    public static final String FROM1 = "localhost_1";
    public static final String FROM2 = "localhost_2";
    public static final String REP1 = "127.0.0.1";
    public static final String REP2 = "127.0.0.2";
    public static final String REC1 = "Vasily";
    public static final String REC2 = "Pupkin";
    public static final String SUBJ = "mocktest";
    public static final String DESC = "desc";
    public static final Date DATE1 = new Date(0);
    public static final Date DATE2 = new Date(60000);
    public static final String CNTNT_TYPE_EMAIL = "application/acad";
    public static int CNTNT_SIZE = 23;
    public static String HDR_EX1 = "header_ex1";
    public static String HDR_EX1V = "header_ex1_value";
    public static String HDR_EX2 = "header_ex2";
    public static String HDR_EX2V = "header_ex2_value";

    // this objects re-created for every test method
    private Message message;
    private MailInputData data;
    private MailInputMeta meta;
    private MailInput mailInput;

    @BeforeClass
    public static void setup() {
        stepMockHelper = new StepMockHelper<MailInputMeta, StepDataInterface>("ABORT TEST", MailInputMeta.class,
                StepDataInterface.class);
        when(stepMockHelper.logChannelInterfaceFactory.create(any(), any(LoggingObjectInterface.class)))
                .thenReturn(stepMockHelper.logChannelInterface);
        when(stepMockHelper.trans.isRunning()).thenReturn(true);
    }

    @AfterClass
    public static void tearDown() {
        stepMockHelper.cleanUp();
    }

    @Before
    public void beforeTest() throws MessagingException, IOException, KettleException {
        message = Mockito.mock(Message.class);

        MailConnection conn = mock(MailConnection.class);
        when(conn.getMessageBody(any(Message.class))).thenReturn(MSG_BODY);
        when(conn.getFolderName()).thenReturn(FLD_NAME);
        when(conn.getAttachedFilesCount(any(Message.class), any(Pattern.class))).thenReturn(ATTCH_COUNT);
        when(conn.getMessageBodyContentType(any(Message.class))).thenReturn(CNTNT_TYPE);
        data = mock(MailInputData.class);
        data.mailConn = conn;

        mailInput = new MailInput(stepMockHelper.stepMeta, data, 0, stepMockHelper.transMeta, stepMockHelper.trans);

        Address addrFrom1 = mock(Address.class);
        when(addrFrom1.toString()).thenReturn(FROM1);
        Address addrFrom2 = mock(Address.class);
        when(addrFrom2.toString()).thenReturn(FROM2);
        Address addrRep1 = mock(Address.class);
        when(addrRep1.toString()).thenReturn(REP1);
        Address addrRep2 = mock(Address.class);
        when(addrRep2.toString()).thenReturn(REP2);
        Address allRec1 = mock(Address.class);
        when(allRec1.toString()).thenReturn(REC1);
        Address allRec2 = mock(Address.class);
        when(allRec2.toString()).thenReturn(REC2);

        Address[] adrFr = { addrFrom1, addrFrom2 };
        Address[] adrRep = { addrRep1, addrRep2 };
        Address[] adrRecip = { allRec1, allRec2 };

        message = Mockito.mock(Message.class);
        when(message.getMessageNumber()).thenReturn(MSG_NUMB);
        when(message.getSubject()).thenReturn(SUBJ);

        when(message.getFrom()).thenReturn(adrFr);
        when(message.getReplyTo()).thenReturn(adrRep);
        when(message.getAllRecipients()).thenReturn(adrRecip);
        when(message.getDescription()).thenReturn(DESC);
        when(message.getReceivedDate()).thenReturn(DATE1);
        when(message.getSentDate()).thenReturn(DATE2);
        when(message.getContentType()).thenReturn(CNTNT_TYPE_EMAIL);
        when(message.getSize()).thenReturn(CNTNT_SIZE);

        Header ex1 = new Header(HDR_EX1, HDR_EX1V);
        Header ex2 = new Header(HDR_EX2, HDR_EX2V);

        // for fixed [PDI-6532]
        when(message.getMatchingHeaders(aryEq(new String[] { HDR_EX1 }))).thenReturn(getEnum(new Header[] { ex1 }));
        when(message.getMatchingHeaders(aryEq(new String[] { HDR_EX2 }))).thenReturn(getEnum(new Header[] { ex2 }));
        when(message.getMatchingHeaders(aryEq(new String[] { HDR_EX1, HDR_EX2 })))
                .thenReturn(getEnum(new Header[] { ex1, ex2 }));

        // for previous implementation
        when(message.getHeader(eq(HDR_EX1))).thenReturn(new String[] { ex1.getValue() });
        when(message.getHeader(eq(HDR_EX2))).thenReturn(new String[] { ex2.getValue() });
    }

    /**
     * [PDI-6532] When mail header is found returns his actual value.
     *
     * @throws Exception
     * @throws KettleException
     */
    @Test
    public void testHeadersParsedPositive() throws Exception {
        // add expected fields:
        int[] fields = { MailInputField.COLUMN_HEADER };
        MailInputField[] farr = this.getDefaultInputFields(fields);
        // points to existed header
        farr[0].setName(HDR_EX1);

        this.mockMailInputMeta(farr);

        try {
            mailInput.processRow(meta, data);
        } catch (KettleException e) {
            // don't worry about it
        }
        MessageParser underTest = mailInput.new MessageParser();
        Object[] r = RowDataUtil.allocateRowData(data.nrFields);
        underTest.parseToArray(r, message);

        Assert.assertEquals("Header is correct", HDR_EX1V, String.class.cast(r[0]));
    }

    /**
     * [PDI-6532] When mail header is not found returns empty String
     *
     * @throws Exception
     *
     */
    @Test
    public void testHeadersParsedNegative() throws Exception {
        int[] fields = { MailInputField.COLUMN_HEADER };
        MailInputField[] farr = this.getDefaultInputFields(fields);
        farr[0].setName(HDR_EX1 + "salt");

        this.mockMailInputMeta(farr);

        try {
            mailInput.processRow(meta, data);
        } catch (KettleException e) {
            // don't worry about it
        }
        MessageParser underTest = mailInput.new MessageParser();
        Object[] r = RowDataUtil.allocateRowData(data.nrFields);
        underTest.parseToArray(r, message);

        Assert.assertEquals("Header is correct", "", String.class.cast(r[0]));
    }

    /**
     * Test, message number can be parsed correctly
     *
     * @throws Exception
     */
    @Test
    public void testMessageNumberIsParsed() throws Exception {
        int[] fields = { MailInputField.COLUMN_MESSAGE_NR };
        MailInputField[] farr = this.getDefaultInputFields(fields);
        this.mockMailInputMeta(farr);
        try {
            mailInput.processRow(meta, data);
        } catch (KettleException e) {
            // don't worry about it
        }
        MessageParser underTest = mailInput.new MessageParser();
        Object[] r = RowDataUtil.allocateRowData(data.nrFields);
        underTest.parseToArray(r, message);
        Assert.assertEquals("Message number is correct", new Long(MSG_NUMB), Long.class.cast(r[0]));
    }

    /**
     * Test message subject can be parsed
     *
     * @throws Exception
     */
    @Test
    public void testMessageSubjectIsParsed() throws Exception {
        int[] fields = { MailInputField.COLUMN_SUBJECT };
        MailInputField[] farr = this.getDefaultInputFields(fields);
        this.mockMailInputMeta(farr);
        try {
            mailInput.processRow(meta, data);
        } catch (KettleException e) {
            // don't worry about it
        }
        MessageParser underTest = mailInput.new MessageParser();
        Object[] r = RowDataUtil.allocateRowData(data.nrFields);
        underTest.parseToArray(r, message);
        Assert.assertEquals("Message subject is correct", SUBJ, String.class.cast(r[0]));
    }

    /**
     * Test message From can be parsed correctly
     *
     * @throws Exception
     */
    @Test
    public void testMessageFromIsParsed() throws Exception {
        int[] fields = { MailInputField.COLUMN_SENDER };
        MailInputField[] farr = this.getDefaultInputFields(fields);
        this.mockMailInputMeta(farr);
        try {
            mailInput.processRow(meta, data);
        } catch (KettleException e) {
            // don't worry about it
        }
        MessageParser underTest = mailInput.new MessageParser();
        Object[] r = RowDataUtil.allocateRowData(data.nrFields);
        underTest.parseToArray(r, message);

        // expect, that from is concatenated with ';'
        String expected = StringUtils.join(new String[] { FROM1, FROM2 }, ";");
        Assert.assertEquals("Message From is correct", expected, String.class.cast(r[0]));
    }

    /**
     * Test message ReplayTo can be parsed correctly
     *
     * @throws Exception
     */
    @Test
    public void testMessageReplayToIsParsed() throws Exception {
        int[] fields = { MailInputField.COLUMN_REPLY_TO };
        MailInputField[] farr = this.getDefaultInputFields(fields);
        this.mockMailInputMeta(farr);
        try {
            mailInput.processRow(meta, data);
        } catch (KettleException e) {
            // don't worry about it
        }
        MessageParser underTest = mailInput.new MessageParser();
        Object[] r = RowDataUtil.allocateRowData(data.nrFields);
        underTest.parseToArray(r, message);

        // is concatenated with ';'
        String expected = StringUtils.join(new String[] { REP1, REP2 }, ";");
        Assert.assertEquals("Message ReplayTo is correct", expected, String.class.cast(r[0]));
    }

    /**
     * Test message recipients can be parsed
     *
     * @throws Exception
     */
    @Test
    public void testMessageRecipientsIsParsed() throws Exception {
        int[] fields = { MailInputField.COLUMN_RECIPIENTS };
        MailInputField[] farr = this.getDefaultInputFields(fields);
        this.mockMailInputMeta(farr);
        try {
            mailInput.processRow(meta, data);
        } catch (KettleException e) {
            // don't worry about it
        }
        MessageParser underTest = mailInput.new MessageParser();
        Object[] r = RowDataUtil.allocateRowData(data.nrFields);
        underTest.parseToArray(r, message);

        // is concatenated with ';'
        String expected = StringUtils.join(new String[] { REC1, REC2 }, ";");
        Assert.assertEquals("Message Recipients is correct", expected, String.class.cast(r[0]));
    }

    /**
     * Test message description is correct
     *
     * @throws Exception
     */
    @Test
    public void testMessageDescriptionIsParsed() throws Exception {
        int[] fields = { MailInputField.COLUMN_DESCRIPTION };
        MailInputField[] farr = this.getDefaultInputFields(fields);
        this.mockMailInputMeta(farr);
        try {
            mailInput.processRow(meta, data);
        } catch (KettleException e) {
            // don't worry about it
        }
        MessageParser underTest = mailInput.new MessageParser();
        Object[] r = RowDataUtil.allocateRowData(data.nrFields);
        underTest.parseToArray(r, message);

        Assert.assertEquals("Message Description is correct", DESC, String.class.cast(r[0]));
    }

    /**
     * Test message received date is correct
     *
     * @throws Exception
     */
    @Test
    public void testMessageRecivedDateIsParsed() throws Exception {
        int[] fields = { MailInputField.COLUMN_RECEIVED_DATE };
        MailInputField[] farr = this.getDefaultInputFields(fields);
        this.mockMailInputMeta(farr);
        try {
            mailInput.processRow(meta, data);
        } catch (KettleException e) {
            // don't worry about it
        }
        MessageParser underTest = mailInput.new MessageParser();
        Object[] r = RowDataUtil.allocateRowData(data.nrFields);
        underTest.parseToArray(r, message);

        Assert.assertEquals("Message Recived date is correct", DATE1, Date.class.cast(r[0]));
    }

    /**
     * Test message sent date is correct
     *
     * @throws Exception
     */
    @Test
    public void testMessageSentDateIsParsed() throws Exception {
        int[] fields = { MailInputField.COLUMN_SENT_DATE };
        MailInputField[] farr = this.getDefaultInputFields(fields);
        this.mockMailInputMeta(farr);
        try {
            mailInput.processRow(meta, data);
        } catch (KettleException e) {
            // don't worry about it
        }
        MessageParser underTest = mailInput.new MessageParser();
        Object[] r = RowDataUtil.allocateRowData(data.nrFields);
        underTest.parseToArray(r, message);

        Assert.assertEquals("Message Sent date is correct", DATE2, Date.class.cast(r[0]));
    }

    /**
     * Message content type is correct
     *
     * @throws Exception
     */
    @Test
    public void testMessageContentTypeIsParsed() throws Exception {
        int[] fields = { MailInputField.COLUMN_CONTENT_TYPE };
        MailInputField[] farr = this.getDefaultInputFields(fields);
        this.mockMailInputMeta(farr);
        try {
            mailInput.processRow(meta, data);
        } catch (KettleException e) {
            // don't worry about it
        }
        MessageParser underTest = mailInput.new MessageParser();
        Object[] r = RowDataUtil.allocateRowData(data.nrFields);
        underTest.parseToArray(r, message);

        Assert.assertEquals("Message Content type is correct", CNTNT_TYPE_EMAIL, String.class.cast(r[0]));
    }

    /**
     * Test message size is correct
     *
     * @throws Exception
     */
    @Test
    public void testMessageSizeIsParsed() throws Exception {
        int[] fields = { MailInputField.COLUMN_SIZE };
        MailInputField[] farr = this.getDefaultInputFields(fields);
        this.mockMailInputMeta(farr);
        try {
            mailInput.processRow(meta, data);
        } catch (KettleException e) {
            // don't worry about it
        }
        MessageParser underTest = mailInput.new MessageParser();
        Object[] r = RowDataUtil.allocateRowData(data.nrFields);
        underTest.parseToArray(r, message);

        Assert.assertEquals("Message Size is correct", new Long(CNTNT_SIZE), Long.class.cast(r[0]));
    }

    /**
     * Test that message body can be parsed correctly
     *
     * @throws Exception
     */
    @Test
    public void testMessageBodyIsParsed() throws Exception {
        int[] fields = { MailInputField.COLUMN_BODY };
        MailInputField[] farr = this.getDefaultInputFields(fields);
        this.mockMailInputMeta(farr);
        try {
            mailInput.processRow(meta, data);
        } catch (KettleException e) {
            // don't worry about it
        }
        MessageParser underTest = mailInput.new MessageParser();
        Object[] r = RowDataUtil.allocateRowData(data.nrFields);
        underTest.parseToArray(r, message);

        Assert.assertEquals("Message Body is correct", MSG_BODY, String.class.cast(r[0]));
    }

    /**
     * Test that message folder name can be parsed correctly
     *
     * @throws Exception
     */
    @Test
    public void testMessageFolderNameIsParsed() throws Exception {
        int[] fields = { MailInputField.COLUMN_FOLDER_NAME };
        MailInputField[] farr = this.getDefaultInputFields(fields);
        this.mockMailInputMeta(farr);
        try {
            mailInput.processRow(meta, data);
        } catch (KettleException e) {
            // don't worry about it
        }
        MessageParser underTest = mailInput.new MessageParser();
        Object[] r = RowDataUtil.allocateRowData(data.nrFields);
        underTest.parseToArray(r, message);

        Assert.assertEquals("Message Folder Name is correct", FLD_NAME, String.class.cast(r[0]));
    }

    /**
     * Test that message folder name can be parsed correctly
     *
     * @throws Exception
     */
    @Test
    public void testMessageAttachedFilesCountNameIsParsed() throws Exception {
        int[] fields = { MailInputField.COLUMN_ATTACHED_FILES_COUNT };
        MailInputField[] farr = this.getDefaultInputFields(fields);
        this.mockMailInputMeta(farr);
        try {
            mailInput.processRow(meta, data);
        } catch (KettleException e) {
            // don't worry about it
        }
        MessageParser underTest = mailInput.new MessageParser();
        Object[] r = RowDataUtil.allocateRowData(data.nrFields);
        underTest.parseToArray(r, message);

        Assert.assertEquals("Message Attached files count is correct", new Long(ATTCH_COUNT),
                Long.class.cast(r[0]));
    }

    /**
     * Test that message body content type can be parsed correctly
     *
     * @throws Exception
     */
    @Test
    public void testMessageBodyContentTypeIsParsed() throws Exception {
        int[] fields = { MailInputField.COLUMN_BODY_CONTENT_TYPE };
        MailInputField[] farr = this.getDefaultInputFields(fields);
        this.mockMailInputMeta(farr);
        try {
            mailInput.processRow(meta, data);
        } catch (KettleException e) {
            // don't worry about it
        }
        MessageParser underTest = mailInput.new MessageParser();
        Object[] r = RowDataUtil.allocateRowData(data.nrFields);
        underTest.parseToArray(r, message);

        Assert.assertEquals("Message body content type is correct", CNTNT_TYPE, String.class.cast(r[0]));
    }

    private void mockMailInputMeta(MailInputField[] arr) {
        data.nrFields = arr.length;
        meta = mock(MailInputMeta.class);
        when(meta.getInputFields()).thenReturn(arr);
    }

    private MailInputField[] getDefaultInputFields(int[] arr) {
        MailInputField[] fields = new MailInputField[arr.length];
        for (int i = 0; i < arr.length; i++) {
            fields[i] = new MailInputField();
            fields[i].setColumn(arr[i]);
            fields[i].setName(MailInputField.getColumnDesc(arr[i]));
        }
        return fields;
    }

    private Enumeration<?> getEnum(Header[] headers) {
        return Collections.enumeration(Arrays.asList(headers));
    }
}