153295844df24dff0a1f59e1104795e640b54c2efchrismair/*
253295844df24dff0a1f59e1104795e640b54c2efchrismair * Copyright 2007 the original author or authors.
353295844df24dff0a1f59e1104795e640b54c2efchrismair *
453295844df24dff0a1f59e1104795e640b54c2efchrismair * Licensed under the Apache License, Version 2.0 (the "License");
553295844df24dff0a1f59e1104795e640b54c2efchrismair * you may not use this file except in compliance with the License.
653295844df24dff0a1f59e1104795e640b54c2efchrismair * You may obtain a copy of the License at
753295844df24dff0a1f59e1104795e640b54c2efchrismair *
853295844df24dff0a1f59e1104795e640b54c2efchrismair *      http://www.apache.org/licenses/LICENSE-2.0
953295844df24dff0a1f59e1104795e640b54c2efchrismair *
1053295844df24dff0a1f59e1104795e640b54c2efchrismair * Unless required by applicable law or agreed to in writing, software
1153295844df24dff0a1f59e1104795e640b54c2efchrismair * distributed under the License is distributed on an "AS IS" BASIS,
1253295844df24dff0a1f59e1104795e640b54c2efchrismair * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1353295844df24dff0a1f59e1104795e640b54c2efchrismair * See the License for the specific language governing permissions and
1453295844df24dff0a1f59e1104795e640b54c2efchrismair * limitations under the License.
1553295844df24dff0a1f59e1104795e640b54c2efchrismair */
1653295844df24dff0a1f59e1104795e640b54c2efchrismairpackage org.mockftpserver.stub.command;
1753295844df24dff0a1f59e1104795e640b54c2efchrismair
1853295844df24dff0a1f59e1104795e640b54c2efchrismairimport java.text.MessageFormat;
1953295844df24dff0a1f59e1104795e640b54c2efchrismairimport java.util.ListResourceBundle;
2053295844df24dff0a1f59e1104795e640b54c2efchrismairimport java.util.ResourceBundle;
2153295844df24dff0a1f59e1104795e640b54c2efchrismair
2253295844df24dff0a1f59e1104795e640b54c2efchrismairimport org.apache.log4j.Logger;
2353295844df24dff0a1f59e1104795e640b54c2efchrismairimport org.easymock.MockControl;
2453295844df24dff0a1f59e1104795e640b54c2efchrismairimport org.mockftpserver.core.command.AbstractCommandHandler;
2553295844df24dff0a1f59e1104795e640b54c2efchrismairimport org.mockftpserver.core.command.Command;
2653295844df24dff0a1f59e1104795e640b54c2efchrismairimport org.mockftpserver.core.command.InvocationHistory;
2753295844df24dff0a1f59e1104795e640b54c2efchrismairimport org.mockftpserver.core.command.InvocationRecord;
2853295844df24dff0a1f59e1104795e640b54c2efchrismairimport org.mockftpserver.core.session.Session;
2953295844df24dff0a1f59e1104795e640b54c2efchrismairimport org.mockftpserver.core.util.AssertFailedException;
3053295844df24dff0a1f59e1104795e640b54c2efchrismairimport org.mockftpserver.test.AbstractTest;
3153295844df24dff0a1f59e1104795e640b54c2efchrismair
3253295844df24dff0a1f59e1104795e640b54c2efchrismair/**
3353295844df24dff0a1f59e1104795e640b54c2efchrismair * Abstract superclass for CommandHandler tests
3453295844df24dff0a1f59e1104795e640b54c2efchrismair *
3553295844df24dff0a1f59e1104795e640b54c2efchrismair * @version $Revision$ - $Date$
3653295844df24dff0a1f59e1104795e640b54c2efchrismair *
3753295844df24dff0a1f59e1104795e640b54c2efchrismair * @author Chris Mair
3853295844df24dff0a1f59e1104795e640b54c2efchrismair */
3953295844df24dff0a1f59e1104795e640b54c2efchrismairpublic abstract class AbstractCommandHandlerTest extends AbstractTest {
4053295844df24dff0a1f59e1104795e640b54c2efchrismair
4153295844df24dff0a1f59e1104795e640b54c2efchrismair    private static final Logger LOG = Logger.getLogger(AbstractCommandHandlerTest.class);
4253295844df24dff0a1f59e1104795e640b54c2efchrismair
4353295844df24dff0a1f59e1104795e640b54c2efchrismair    // Some common test constants
4453295844df24dff0a1f59e1104795e640b54c2efchrismair    protected static final String DIR1 = "dir1";
4553295844df24dff0a1f59e1104795e640b54c2efchrismair    protected static final String DIR2 = "dir2";
4653295844df24dff0a1f59e1104795e640b54c2efchrismair    protected static final String FILENAME1 = "sample1.txt";
4753295844df24dff0a1f59e1104795e640b54c2efchrismair    protected static final String FILENAME2 = "sample2.txt";
4853295844df24dff0a1f59e1104795e640b54c2efchrismair
4953295844df24dff0a1f59e1104795e640b54c2efchrismair    protected Session session;
5053295844df24dff0a1f59e1104795e640b54c2efchrismair    protected ResourceBundle replyTextBundle;
5153295844df24dff0a1f59e1104795e640b54c2efchrismair
5253295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
5353295844df24dff0a1f59e1104795e640b54c2efchrismair     * Test the handleCommand() method, when one or more parameter is missing or invalid
5453295844df24dff0a1f59e1104795e640b54c2efchrismair     *
5553295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param commandHandler - the CommandHandler to test
5653295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param commandName - the name for the Command
5753295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param parameters - the Command parameters
5853295844df24dff0a1f59e1104795e640b54c2efchrismair     */
5953295844df24dff0a1f59e1104795e640b54c2efchrismair    protected void testHandleCommand_InvalidParameters(AbstractCommandHandler commandHandler,
6053295844df24dff0a1f59e1104795e640b54c2efchrismair            String commandName, String[] parameters) throws Exception {
6153295844df24dff0a1f59e1104795e640b54c2efchrismair
6253295844df24dff0a1f59e1104795e640b54c2efchrismair        try {
6353295844df24dff0a1f59e1104795e640b54c2efchrismair            commandHandler.handleCommand(new Command(commandName, parameters), session);
6453295844df24dff0a1f59e1104795e640b54c2efchrismair            fail("Expected AssertFailedException");
6553295844df24dff0a1f59e1104795e640b54c2efchrismair        }
6653295844df24dff0a1f59e1104795e640b54c2efchrismair        catch (AssertFailedException expected) {
6753295844df24dff0a1f59e1104795e640b54c2efchrismair            LOG.info("Expected: " + expected);
6853295844df24dff0a1f59e1104795e640b54c2efchrismair            assertTrue("Error message must contain [" + commandName + "]", expected.getMessage().indexOf(
6953295844df24dff0a1f59e1104795e640b54c2efchrismair                    commandName) != -1);
7053295844df24dff0a1f59e1104795e640b54c2efchrismair        }
7153295844df24dff0a1f59e1104795e640b54c2efchrismair        verifyNumberOfInvocations(commandHandler, 1);
7253295844df24dff0a1f59e1104795e640b54c2efchrismair    }
7353295844df24dff0a1f59e1104795e640b54c2efchrismair
7453295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
7553295844df24dff0a1f59e1104795e640b54c2efchrismair     * Verify that the CommandHandler contains the specified number of invocation records
7653295844df24dff0a1f59e1104795e640b54c2efchrismair     *
7753295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param commandHandler - the CommandHandler
7853295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param expected - the expected number of invocations
7953295844df24dff0a1f59e1104795e640b54c2efchrismair     */
8053295844df24dff0a1f59e1104795e640b54c2efchrismair    protected void verifyNumberOfInvocations(InvocationHistory commandHandler, int expected) {
8153295844df24dff0a1f59e1104795e640b54c2efchrismair        assertEquals("number of invocations", expected, commandHandler.numberOfInvocations());
8253295844df24dff0a1f59e1104795e640b54c2efchrismair    }
8353295844df24dff0a1f59e1104795e640b54c2efchrismair
8453295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
8553295844df24dff0a1f59e1104795e640b54c2efchrismair     * Verify that the InvocationRecord contains no data elements
8653295844df24dff0a1f59e1104795e640b54c2efchrismair     *
8753295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param invocationRecord - the InvocationRecord
8853295844df24dff0a1f59e1104795e640b54c2efchrismair     */
8953295844df24dff0a1f59e1104795e640b54c2efchrismair    protected void verifyNoDataElements(InvocationRecord invocationRecord) {
9053295844df24dff0a1f59e1104795e640b54c2efchrismair        LOG.info("Verifying: " + invocationRecord);
9153295844df24dff0a1f59e1104795e640b54c2efchrismair        assertEquals("number of data elements", 0, invocationRecord.keySet().size());
9253295844df24dff0a1f59e1104795e640b54c2efchrismair    }
9353295844df24dff0a1f59e1104795e640b54c2efchrismair
9453295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
9553295844df24dff0a1f59e1104795e640b54c2efchrismair     * Verify that the InvocationRecord contains exactly one data element, with the specified key
9653295844df24dff0a1f59e1104795e640b54c2efchrismair     * and value.
9753295844df24dff0a1f59e1104795e640b54c2efchrismair     *
9853295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param invocationRecord - the InvocationRecord
9953295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param key - the expected key
10053295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param value - the expected value
10153295844df24dff0a1f59e1104795e640b54c2efchrismair     */
10253295844df24dff0a1f59e1104795e640b54c2efchrismair    protected void verifyOneDataElement(InvocationRecord invocationRecord, String key, Object value) {
10353295844df24dff0a1f59e1104795e640b54c2efchrismair        LOG.info("Verifying: " + invocationRecord);
10453295844df24dff0a1f59e1104795e640b54c2efchrismair        assertEquals("number of data elements", 1, invocationRecord.keySet().size());
10553295844df24dff0a1f59e1104795e640b54c2efchrismair        assertEqualsAllTypes("value:" + value, value, invocationRecord.getObject(key));
10653295844df24dff0a1f59e1104795e640b54c2efchrismair    }
10753295844df24dff0a1f59e1104795e640b54c2efchrismair
10853295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
10953295844df24dff0a1f59e1104795e640b54c2efchrismair     * Verify that the InvocationRecord contains exactly two data element, with the specified keys
11053295844df24dff0a1f59e1104795e640b54c2efchrismair     * and values.
11153295844df24dff0a1f59e1104795e640b54c2efchrismair     *
11253295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param invocationRecord - the InvocationRecord
11353295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param key1 - the expected key1
11453295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param value1 - the expected value1
11553295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param key2 - the expected key2
11653295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param value12- the expected value2
11753295844df24dff0a1f59e1104795e640b54c2efchrismair     */
11853295844df24dff0a1f59e1104795e640b54c2efchrismair    protected void verifyTwoDataElements(InvocationRecord invocationRecord, String key1, Object value1,
11953295844df24dff0a1f59e1104795e640b54c2efchrismair            String key2, Object value2) {
12053295844df24dff0a1f59e1104795e640b54c2efchrismair
12153295844df24dff0a1f59e1104795e640b54c2efchrismair        LOG.info("Verifying: " + invocationRecord);
12253295844df24dff0a1f59e1104795e640b54c2efchrismair        assertEquals("number of data elements", 2, invocationRecord.keySet().size());
12353295844df24dff0a1f59e1104795e640b54c2efchrismair        assertEqualsAllTypes("value1:" + value1, value1, invocationRecord.getObject(key1));
12453295844df24dff0a1f59e1104795e640b54c2efchrismair        assertEqualsAllTypes("value2:" + value2, value2, invocationRecord.getObject(key2));
12553295844df24dff0a1f59e1104795e640b54c2efchrismair    }
12653295844df24dff0a1f59e1104795e640b54c2efchrismair
12753295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
12853295844df24dff0a1f59e1104795e640b54c2efchrismair     * Assert that the actual is equal to the expected, using arrays equality comparison if
12953295844df24dff0a1f59e1104795e640b54c2efchrismair     * necessary
13053295844df24dff0a1f59e1104795e640b54c2efchrismair     *
13153295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param message - the message, used if the comparison fails
13253295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param expected - the expected value
13353295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param actual - the actual value
13453295844df24dff0a1f59e1104795e640b54c2efchrismair     */
13553295844df24dff0a1f59e1104795e640b54c2efchrismair    private void assertEqualsAllTypes(String message, Object expected, Object actual) {
13653295844df24dff0a1f59e1104795e640b54c2efchrismair
13753295844df24dff0a1f59e1104795e640b54c2efchrismair        if (expected instanceof byte[] || actual instanceof byte[]) {
13853295844df24dff0a1f59e1104795e640b54c2efchrismair            assertEquals(message, (byte[]) expected, (byte[]) actual);
13953295844df24dff0a1f59e1104795e640b54c2efchrismair        }
14053295844df24dff0a1f59e1104795e640b54c2efchrismair        else if (expected instanceof Object[] || actual instanceof Object[]) {
14153295844df24dff0a1f59e1104795e640b54c2efchrismair            assertEquals(message, (Object[]) expected, (Object[]) actual);
14253295844df24dff0a1f59e1104795e640b54c2efchrismair        }
14353295844df24dff0a1f59e1104795e640b54c2efchrismair        else {
14453295844df24dff0a1f59e1104795e640b54c2efchrismair            assertEquals(message, expected, actual);
14553295844df24dff0a1f59e1104795e640b54c2efchrismair        }
14653295844df24dff0a1f59e1104795e640b54c2efchrismair    }
14753295844df24dff0a1f59e1104795e640b54c2efchrismair
14853295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
14953295844df24dff0a1f59e1104795e640b54c2efchrismair     * Perform setup before each test
15053295844df24dff0a1f59e1104795e640b54c2efchrismair     *
15153295844df24dff0a1f59e1104795e640b54c2efchrismair     * @see org.mockftpserver.test.AbstractTest#setUp()
15253295844df24dff0a1f59e1104795e640b54c2efchrismair     */
15353295844df24dff0a1f59e1104795e640b54c2efchrismair    protected void setUp() throws Exception {
15453295844df24dff0a1f59e1104795e640b54c2efchrismair        super.setUp();
15553295844df24dff0a1f59e1104795e640b54c2efchrismair
15653295844df24dff0a1f59e1104795e640b54c2efchrismair        session = (Session) createMock(Session.class);
15753295844df24dff0a1f59e1104795e640b54c2efchrismair        control(session).setDefaultMatcher(MockControl.ARRAY_MATCHER);
15853295844df24dff0a1f59e1104795e640b54c2efchrismair        control(session).expectAndDefaultReturn(session.getClientHost(), DEFAULT_HOST);
15953295844df24dff0a1f59e1104795e640b54c2efchrismair
16053295844df24dff0a1f59e1104795e640b54c2efchrismair        replyTextBundle = new ListResourceBundle() {
16153295844df24dff0a1f59e1104795e640b54c2efchrismair            protected Object[][] getContents() {
16253295844df24dff0a1f59e1104795e640b54c2efchrismair                return new Object[][] {
16353295844df24dff0a1f59e1104795e640b54c2efchrismair                        { "150", replyTextFor(150) },
16453295844df24dff0a1f59e1104795e640b54c2efchrismair                        { "200", replyTextFor(200) },
16553295844df24dff0a1f59e1104795e640b54c2efchrismair                        { "211", replyTextWithParameterFor(211) },
16653295844df24dff0a1f59e1104795e640b54c2efchrismair                        { "213", replyTextWithParameterFor(213) },
16753295844df24dff0a1f59e1104795e640b54c2efchrismair                        { "214", replyTextWithParameterFor(214) },
16853295844df24dff0a1f59e1104795e640b54c2efchrismair                        { "215", replyTextWithParameterFor(215) },
16953295844df24dff0a1f59e1104795e640b54c2efchrismair                        { "220", replyTextFor(220) },
17053295844df24dff0a1f59e1104795e640b54c2efchrismair                        { "221", replyTextFor(221) },
17153295844df24dff0a1f59e1104795e640b54c2efchrismair                        { "226", replyTextFor(226) },
17253295844df24dff0a1f59e1104795e640b54c2efchrismair                        { "226.WithFilename", replyTextWithParameterFor("226.WithFilename") },
17353295844df24dff0a1f59e1104795e640b54c2efchrismair                        { "227", replyTextWithParameterFor(227) },
17453295844df24dff0a1f59e1104795e640b54c2efchrismair                        { "230", replyTextFor(230) },
17553295844df24dff0a1f59e1104795e640b54c2efchrismair                        { "250", replyTextFor(250) },
17653295844df24dff0a1f59e1104795e640b54c2efchrismair                        { "257", replyTextWithParameterFor(257) },
17753295844df24dff0a1f59e1104795e640b54c2efchrismair                        { "331", replyTextFor(331) },
17853295844df24dff0a1f59e1104795e640b54c2efchrismair                        { "350", replyTextFor(350) },
17953295844df24dff0a1f59e1104795e640b54c2efchrismair                };
18053295844df24dff0a1f59e1104795e640b54c2efchrismair            }
18153295844df24dff0a1f59e1104795e640b54c2efchrismair        };
18253295844df24dff0a1f59e1104795e640b54c2efchrismair    }
18353295844df24dff0a1f59e1104795e640b54c2efchrismair
18453295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
18553295844df24dff0a1f59e1104795e640b54c2efchrismair     * Return the test-specific reply text for the specified reply code
18653295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param replyCode - the reply code
18753295844df24dff0a1f59e1104795e640b54c2efchrismair     * @return the reply text for the specified reply code
18853295844df24dff0a1f59e1104795e640b54c2efchrismair     */
18953295844df24dff0a1f59e1104795e640b54c2efchrismair    protected String replyTextFor(int replyCode) {
19053295844df24dff0a1f59e1104795e640b54c2efchrismair        return "Reply for " + replyCode;
19153295844df24dff0a1f59e1104795e640b54c2efchrismair    }
19253295844df24dff0a1f59e1104795e640b54c2efchrismair
19353295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
19453295844df24dff0a1f59e1104795e640b54c2efchrismair     * Return the test-specific parameterized reply text for the specified reply code
19553295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param replyCode - the reply code
19653295844df24dff0a1f59e1104795e640b54c2efchrismair     * @return the reply text for the specified reply code
19753295844df24dff0a1f59e1104795e640b54c2efchrismair     */
19853295844df24dff0a1f59e1104795e640b54c2efchrismair    protected String replyTextWithParameterFor(int replyCode) {
19953295844df24dff0a1f59e1104795e640b54c2efchrismair        return "Reply for " + replyCode + ":{0}";
20053295844df24dff0a1f59e1104795e640b54c2efchrismair    }
20153295844df24dff0a1f59e1104795e640b54c2efchrismair
20253295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
20353295844df24dff0a1f59e1104795e640b54c2efchrismair     * Return the test-specific parameterized reply text for the specified messageKey
20453295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param messageKey - the messageKey
20553295844df24dff0a1f59e1104795e640b54c2efchrismair     * @return the reply text for the specified messageKey
20653295844df24dff0a1f59e1104795e640b54c2efchrismair     */
20753295844df24dff0a1f59e1104795e640b54c2efchrismair    protected String replyTextWithParameterFor(String messageKey) {
20853295844df24dff0a1f59e1104795e640b54c2efchrismair        return "Reply for " + messageKey + ":{0}";
20953295844df24dff0a1f59e1104795e640b54c2efchrismair    }
21053295844df24dff0a1f59e1104795e640b54c2efchrismair
21153295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
21253295844df24dff0a1f59e1104795e640b54c2efchrismair     * Return the test-specific reply text for the specified reply code and message parameter
21353295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param replyCode - the reply code
21453295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param parameter - the message parameter value
21553295844df24dff0a1f59e1104795e640b54c2efchrismair     * @return the reply text for the specified reply code
21653295844df24dff0a1f59e1104795e640b54c2efchrismair     */
21753295844df24dff0a1f59e1104795e640b54c2efchrismair    protected String formattedReplyTextFor(int replyCode, Object parameter) {
21853295844df24dff0a1f59e1104795e640b54c2efchrismair        return MessageFormat.format(replyTextWithParameterFor(replyCode), objArray(parameter));
21953295844df24dff0a1f59e1104795e640b54c2efchrismair    }
22053295844df24dff0a1f59e1104795e640b54c2efchrismair
22153295844df24dff0a1f59e1104795e640b54c2efchrismair    /**
22253295844df24dff0a1f59e1104795e640b54c2efchrismair     * Return the test-specific reply text for the specified message key and message parameter
22353295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param messageKey - the messageKey
22453295844df24dff0a1f59e1104795e640b54c2efchrismair     * @param parameter - the message parameter value
22553295844df24dff0a1f59e1104795e640b54c2efchrismair     * @return the reply text for the specified message key and parameter
22653295844df24dff0a1f59e1104795e640b54c2efchrismair     */
22753295844df24dff0a1f59e1104795e640b54c2efchrismair    protected String formattedReplyTextFor(String messageKey, Object parameter) {
22853295844df24dff0a1f59e1104795e640b54c2efchrismair        return MessageFormat.format(replyTextWithParameterFor(messageKey), objArray(parameter));
22953295844df24dff0a1f59e1104795e640b54c2efchrismair    }
23053295844df24dff0a1f59e1104795e640b54c2efchrismair
23153295844df24dff0a1f59e1104795e640b54c2efchrismair}
232