1/*
2 * Copyright 2008 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.fake.command
17
18import org.mockftpserver.test.AbstractGroovyTest
19import org.mockftpserver.core.NotLoggedInException
20import org.mockftpserver.core.IllegalStateException
21import org.mockftpserver.core.command.Command
22import org.mockftpserver.core.command.CommandHandler
23import org.mockftpserver.core.command.CommandNames
24import org.mockftpserver.core.session.Session
25import org.mockftpserver.core.session.StubSession
26import org.mockftpserver.core.session.SessionKeys
27import org.mockftpserver.fake.StubServerConfiguration
28import org.apache.log4j.Logger
29import org.mockftpserver.core.command.ReplyCodes
30import org.mockftpserver.core.CommandSyntaxException
31import org.mockftpserver.fake.user.UserAccount
32import org.mockftpserver.fake.filesystem.FakeUnixFileSystem
33import org.mockftpserver.fake.filesystem.NewFileOperationException
34import org.mockftpserver.fake.filesystem.ExistingFileOperationException
35import org.mockftpserver.fake.filesystem.InvalidFilenameException
36import org.mockftpserver.core.session.SessionKeys
37/**
38 * Tests for AbstractFakeCommandHandler
39 *
40 * @version $Revision: $ - $Date: $
41 *
42 * @author Chris Mair
43 */
44class AbstractFakeCommandHandlerClassTest extends AbstractGroovyTest {
45
46     static PATH = "some/path"
47     static REPLY_CODE = 99
48     static ARG = "ABC"
49     static MSG = "text {0}"
50     static MSG_WITH_ARG = "text ABC"
51     private commandHandler
52     private session
53     private serverConfiguration
54     private fileSystem
55
56     //-------------------------------------------------------------------------
57    // Tests
58    //-------------------------------------------------------------------------
59
60    void testHandleCommand() {
61         def command = new Command("C1", ["abc"])
62         commandHandler.handleCommand(command, session)
63         assert commandHandler.handled
64
65         assertHandleCommandReplyCode(new CommandSyntaxException(""), ReplyCodes.COMMAND_SYNTAX_ERROR)
66         assertHandleCommandReplyCode(new IllegalStateException(""), ReplyCodes.ILLEGAL_STATE)
67         assertHandleCommandReplyCode(new NotLoggedInException(""), ReplyCodes.NOT_LOGGED_IN)
68         assertHandleCommandReplyCode(new ExistingFileOperationException(""), ReplyCodes.EXISTING_FILE_ERROR)
69         assertHandleCommandReplyCode(new NewFileOperationException(""), ReplyCodes.NEW_FILE_ERROR)
70         assertHandleCommandReplyCode(new InvalidFilenameException(""), ReplyCodes.FILENAME_NOT_VALID)
71
72         shouldFail { commandHandler.handleCommand(null, session) }
73         shouldFail { commandHandler.handleCommand(command, null) }
74    }
75
76    void testSendReply() {
77         commandHandler.sendReply(session, REPLY_CODE)
78         assert session.sentReplies[0] == [REPLY_CODE, MSG], session.sentReplies[0]
79
80         commandHandler.sendReply(session, REPLY_CODE, [ARG])
81         assert session.sentReplies[1] == [REPLY_CODE, MSG_WITH_ARG], session.sentReplies[0]
82
83         shouldFail { commandHandler.sendReply(null, REPLY_CODE) }
84         shouldFail { commandHandler.sendReply(session, 0) }
85     }
86
87    void testAssertValidReplyCode() {
88         commandHandler.assertValidReplyCode(1)		// no exception expected
89         shouldFail { commandHandler.assertValidReplyCode(0) }
90     }
91
92    void testGetRequiredParameter() {
93         def command = new Command("C1", ["abc"])
94         assert commandHandler.getRequiredParameter(command) == "abc"
95         assert commandHandler.getRequiredParameter(command, 0) == "abc"
96         shouldFail(CommandSyntaxException) { commandHandler.getRequiredParameter(command, 1) }
97
98         command = new Command("C1", [])
99         shouldFail(CommandSyntaxException) { commandHandler.getRequiredParameter(command) }
100     }
101
102    void testGetRequiredSessionAttribute() {
103         shouldFail(IllegalStateException) { commandHandler.getRequiredSessionAttribute(session, "undefined") }
104
105         session.setAttribute("abc", "not empty")
106         commandHandler.getRequiredSessionAttribute(session, "abc") // no exception
107
108         session.setAttribute("abc", "")
109         commandHandler.getRequiredSessionAttribute(session, "abc") // no exception
110     }
111
112    void testVerifyLoggedIn() {
113         shouldFail(NotLoggedInException) { commandHandler.verifyLoggedIn(session) }
114         session.setAttribute(SessionKeys.USER_ACCOUNT, "OK")
115         commandHandler.verifyLoggedIn(session)		// no exception expected
116     }
117
118    void testVerifyForNewFile() {
119         commandHandler.verifyForNewFile(true, PATH)	// no exception expected
120         shouldFail(NewFileOperationException) { commandHandler.verifyForNewFile(false, PATH) }
121         shouldFail(NewFileOperationException) { commandHandler.verifyForNewFile([], PATH) }
122    }
123
124     void testVerifyForExistingFile() {
125         commandHandler.verifyForExistingFile(true, PATH)	// no exception expected
126         shouldFail(ExistingFileOperationException) { commandHandler.verifyForExistingFile(false, PATH) }
127         shouldFail(ExistingFileOperationException) { commandHandler.verifyForExistingFile([], PATH) }
128    }
129
130    void testGetRealPath() {
131        assert commandHandler.getRealPath(session, "/xxx") == "/xxx"
132
133        session.setAttribute(SessionKeys.CURRENT_DIRECTORY, "/usr/me")
134        assert commandHandler.getRealPath(session, null) == "/usr/me"
135        assert commandHandler.getRealPath(session, "/xxx") == "/xxx"
136        assert commandHandler.getRealPath(session, "xxx") == "/usr/me/xxx"
137    }
138
139    //-------------------------------------------------------------------------
140    // Test Setup
141    //-------------------------------------------------------------------------
142
143	void setUp() {
144	    super.setUp()
145	    commandHandler = new TestFakeCommandHandler()
146	    session = new StubSession()
147	    serverConfiguration = new StubServerConfiguration()
148	    fileSystem = new FakeUnixFileSystem()
149	    serverConfiguration.setFileSystem(fileSystem)
150	    serverConfiguration.setTextForReplyCode(REPLY_CODE, MSG)
151
152	    commandHandler.serverConfiguration = serverConfiguration
153	}
154
155    //-------------------------------------------------------------------------
156    // Helper Methods
157    //-------------------------------------------------------------------------
158
159    /**
160     * Assert that when the CommandHandler handleCommand() method throws the
161     * specified exception, that the expected reply is sent through the session.
162     */
163    private void assertHandleCommandReplyCode(Throwable exception, int expected) {
164        commandHandler.exception = exception
165        def command = new Command("C1", ["abc"])
166        session.sentReplies.clear()
167        commandHandler.handleCommand(command, session)
168        assert session.sentReplies[0][0] == expected
169    }
170
171 }
172
173/**
174 * Concrete subclass of AbstractFakeCommandHandler for testing
175 */
176private class TestFakeCommandHandler extends AbstractFakeCommandHandler {
177     boolean handled = false
178     def exception
179     protected void handle(Command command, Session session) {
180         if (exception) {
181             throw exception
182         }
183         this.handled = true
184     }
185}