1/*
2 * Copyright 2007 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.mockftpserver.core.command;
17
18import java.util.ListResourceBundle;
19import java.util.ResourceBundle;
20
21import org.apache.log4j.Logger;
22import org.easymock.MockControl;
23import org.mockftpserver.core.session.Session;
24import org.mockftpserver.core.util.AssertFailedException;
25import org.mockftpserver.stub.command.AbstractStubCommandHandler;
26import org.mockftpserver.test.AbstractTest;
27
28/**
29 * Tests for the AbstractCommandHandler class. The class name is prefixed with an underscore
30 * so that it is not filtered out by Maven's Surefire test plugin.
31 *
32 * @version $Revision$ - $Date$
33 *
34 * @author Chris Mair
35 */
36public final class _AbstractCommandHandlerTest extends AbstractTest {
37
38    private static final Logger LOG = Logger.getLogger(_AbstractCommandHandlerTest.class);
39    private static final String COMMAND_NAME = "abc";
40    private static final Object ARG = "123";
41    private static final Object[] ARGS = { ARG };
42    private static final Command COMMAND = new Command(COMMAND_NAME, EMPTY);
43    private static final Command COMMAND_WITH_ARGS = new Command(COMMAND_NAME, EMPTY);
44    private static final int REPLY_CODE1 = 777;
45    private static final int REPLY_CODE2 = 888;
46    private static final int REPLY_CODE3 = 999;
47    private static final String REPLY_TEXT1 = "reply1 ... abcdef";
48    private static final String REPLY_TEXT2 = "abc {0} def";
49    private static final String REPLY_TEXT2_FORMATTED = "abc 123 def";
50    private static final String OVERRIDE_REPLY_TEXT = "overridden reply ... abcdef";
51    private static final String MESSAGE_KEY = "key.123";
52    private static final String MESSAGE_TEXT = "message.123";
53
54    private AbstractCommandHandler commandHandler;
55    private Session session;
56    private ResourceBundle replyTextBundle;
57
58    /**
59     * Test the handleCommand(Command,Session) method
60     */
61    public void testHandleCommand() throws Exception {
62        assertEquals("before", 0, commandHandler.numberOfInvocations());
63        commandHandler.handleCommand(COMMAND, session);
64        assertEquals("after", 1, commandHandler.numberOfInvocations());
65        assertTrue("locked", commandHandler.getInvocation(0).isLocked());
66    }
67
68    /**
69     * Test the handleCommand(Command,Session) method, passing in a null Command
70     */
71    public void testHandleCommand_NullCommand() throws Exception {
72        try {
73            commandHandler.handleCommand(null, session);
74            fail("Expected AssertFailedException");
75        }
76        catch (AssertFailedException expected) {
77            LOG.info("Expected: " + expected);
78        }
79    }
80
81    /**
82     * Test the handleCommand(Command,Session) method, passing in a null Session
83     */
84    public void testHandleCommand_NullSession() throws Exception {
85        try {
86            commandHandler.handleCommand(COMMAND, null);
87            fail("Expected AssertFailedException");
88        }
89        catch (AssertFailedException expected) {
90            LOG.info("Expected: " + expected);
91        }
92    }
93
94    /**
95     * Test the numberOfInvocations(), addInvocationRecord() and clearInvocationRecord() methods
96     */
97    public void testInvocationHistory() throws Exception {
98        control(session).expectAndDefaultReturn(session.getClientHost(), DEFAULT_HOST);
99        replay(session);
100
101        assertEquals("none", 0, commandHandler.numberOfInvocations());
102        commandHandler.handleCommand(COMMAND, session);
103        assertEquals("1", 1, commandHandler.numberOfInvocations());
104        commandHandler.handleCommand(COMMAND, session);
105        assertEquals("2", 2, commandHandler.numberOfInvocations());
106        commandHandler.clearInvocations();
107        assertEquals("cleared", 0, commandHandler.numberOfInvocations());
108    }
109
110    /**
111     * Test the getInvocation() method
112     * @throws Exception
113     */
114    public void testGetInvocation() throws Exception {
115        control(session).expectAndDefaultReturn(session.getClientHost(), DEFAULT_HOST);
116        replay(session);
117
118        commandHandler.handleCommand(COMMAND, session);
119        commandHandler.handleCommand(COMMAND_WITH_ARGS, session);
120        assertSame("1", COMMAND, commandHandler.getInvocation(0).getCommand());
121        assertSame("2", COMMAND_WITH_ARGS, commandHandler.getInvocation(1).getCommand());
122    }
123
124    /**
125     * Test the getInvocation() method, passing in an invalid index
126     */
127    public void testGetInvocation_IndexOutOfBounds() throws Exception {
128        commandHandler.handleCommand(COMMAND, session);
129        try {
130            commandHandler.getInvocation(2);
131            fail("Expected IndexOutOfBoundsException");
132        }
133        catch (IndexOutOfBoundsException expected) {
134            LOG.info("Expected: " + expected);
135        }
136    }
137
138    /**
139     * Test the quotes utility method
140     */
141    public void testQuotes() {
142        assertEquals("abc", "\"abc\"", AbstractStubCommandHandler.quotes("abc"));
143        assertEquals("<empty>", "\"\"", AbstractStubCommandHandler.quotes(""));
144    }
145
146    /**
147     * Test the quotes utility method, passing in a null
148     */
149    public void testQuotes_Null() {
150        try {
151            AbstractStubCommandHandler.quotes(null);
152            fail("Expected AssertFailedException");
153        }
154        catch (AssertFailedException expected) {
155            LOG.info("Expected: " + expected);
156        }
157    }
158
159    /**
160     * Test the assertValidReplyCode() method
161     */
162    public void testAssertValidReplyCode() {
163        // These are valid, so expect no exceptions
164        commandHandler.assertValidReplyCode(1);
165        commandHandler.assertValidReplyCode(100);
166
167        // These are invalid
168        testAssertValidReplyCodeWithInvalid(0);
169        testAssertValidReplyCodeWithInvalid(-1);
170    }
171
172    /**
173     * Test the assertValidReplyCode() method , passing in an invalid replyCode value
174     */
175    private void testAssertValidReplyCodeWithInvalid(int invalidReplyCode) {
176        try {
177            commandHandler.assertValidReplyCode(invalidReplyCode);
178            fail("Expected AssertFailedException");
179        }
180        catch (AssertFailedException expected) {
181            LOG.info("Expected: " + expected);
182        }
183    }
184
185    /**
186     * Test the sendReply() method, when no message arguments are specified
187     */
188    public void testSendReply() {
189        session.sendReply(REPLY_CODE1, REPLY_TEXT1);
190        session.sendReply(REPLY_CODE1, MESSAGE_TEXT);
191        session.sendReply(REPLY_CODE1, OVERRIDE_REPLY_TEXT);
192        session.sendReply(REPLY_CODE3, null);
193        replay(session);
194
195        commandHandler.sendReply(session, REPLY_CODE1, null, null, null);
196        commandHandler.sendReply(session, REPLY_CODE1, MESSAGE_KEY, null, null);
197        commandHandler.sendReply(session, REPLY_CODE1, MESSAGE_KEY, OVERRIDE_REPLY_TEXT, null);
198        commandHandler.sendReply(session, REPLY_CODE3, null, null, null);
199
200        verify(session);
201    }
202
203    /**
204     * Test the sendReply() method, passing in message arguments
205     */
206    public void testSendReply_WithMessageArguments() {
207        session.sendReply(REPLY_CODE1, REPLY_TEXT2_FORMATTED);
208        replay(session);
209
210        commandHandler.sendReply(session, REPLY_CODE1, null, REPLY_TEXT2, ARGS);
211
212        verify(session);
213    }
214
215    /**
216     * Test the sendReply() method, passing in a null Session
217     */
218    public void testSendReply_NullSession() {
219        try {
220            commandHandler.sendReply(null, REPLY_CODE1, REPLY_TEXT1, null, null);
221            fail("Expected AssertFailedException");
222        }
223        catch (AssertFailedException expected) {
224            LOG.info("Expected: " + expected);
225        }
226    }
227
228    /**
229     * Test the sendReply() method, passing in an invalid replyCode
230     */
231    public void testSendReply_InvalidReplyCode() {
232        try {
233            commandHandler.sendReply(session, 0, REPLY_TEXT1, null, null);
234            fail("Expected AssertFailedException");
235        }
236        catch (AssertFailedException expected) {
237            LOG.info("Expected: " + expected);
238        }
239    }
240
241    //-------------------------------------------------------------------------
242    // Test setup
243    //-------------------------------------------------------------------------
244
245    /**
246     * Perform initialization before each test
247     * @see org.mockftpserver.test.AbstractTest#setUp()
248     */
249    protected void setUp() throws Exception {
250        super.setUp();
251        session = (Session) createMock(Session.class);
252        control(session).setDefaultMatcher(MockControl.ARRAY_MATCHER);
253        commandHandler = new AbstractCommandHandler() {
254            public void handleCommand(Command command, Session session, InvocationRecord invocationRecord) throws Exception {
255            }
256        };
257        replyTextBundle = new ListResourceBundle() {
258            protected Object[][] getContents() {
259                return new Object[][] {
260                        { Integer.toString(REPLY_CODE1), REPLY_TEXT1 },
261                        { Integer.toString(REPLY_CODE2), REPLY_TEXT2 },
262                        { MESSAGE_KEY, MESSAGE_TEXT }
263                };
264            }
265        };
266        commandHandler.setReplyTextBundle(replyTextBundle);
267    }
268
269}
270