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 */ 16 package org.mockftpserver.fake.command 17 18 import org.mockftpserver.core.CommandSyntaxException 19 import org.mockftpserver.core.IllegalStateException 20 import org.mockftpserver.core.NotLoggedInException 21 import org.mockftpserver.core.command.Command 22 import org.mockftpserver.core.command.ReplyCodes 23 import org.mockftpserver.core.session.Session 24 import org.mockftpserver.core.session.SessionKeys 25 import org.mockftpserver.core.session.StubSession 26 import org.mockftpserver.fake.StubServerConfiguration 27 import org.mockftpserver.fake.UserAccount 28 import org.mockftpserver.fake.filesystem.FileSystemException 29 import org.mockftpserver.fake.filesystem.InvalidFilenameException 30 import org.mockftpserver.fake.filesystem.UnixFakeFileSystem 31 import org.mockftpserver.test.AbstractGroovyTestCase 32 import org.mockftpserver.test.StubResourceBundle 33 34 /** 35 * Tests for AbstractFakeCommandHandler 36 * 37 * @version $Revision$ - $Date$ 38 * 39 * @author Chris Mair 40 */ 41 class AbstractFakeCommandHandlerClassTest extends AbstractGroovyTestCase { 42 43 static PATH = "some/path" 44 static REPLY_CODE = 99 45 static MESSAGE_KEY = "99.WithFilename" 46 static ARG = "ABC" 47 static MSG = "text {0}" 48 static MSG_WITH_ARG = "text ABC" 49 static MSG_FOR_KEY = "some other message" 50 static INTERNAL_ERROR = AbstractFakeCommandHandler.INTERNAL_ERROR_KEY 51 static MSG_INTERNAL_ERROR = "internal error message {0}" 52 private AbstractFakeCommandHandler commandHandler 53 private session 54 private serverConfiguration 55 private replyTextBundle 56 private fileSystem 57 private userAccount 58 59 //------------------------------------------------------------------------- 60 // Tests 61 //------------------------------------------------------------------------- 62 63 void testHandleCommand() { 64 def command = new Command("C1", ["abc"]) 65 commandHandler.handleCommand(command, session) 66 assert commandHandler.handled 67 68 assertHandleCommandReplyCode(new CommandSyntaxException(""), ReplyCodes.COMMAND_SYNTAX_ERROR) 69 assertHandleCommandReplyCode(new IllegalStateException(""), ReplyCodes.ILLEGAL_STATE) 70 assertHandleCommandReplyCode(new NotLoggedInException(""), ReplyCodes.NOT_LOGGED_IN) 71 assertHandleCommandReplyCode(new InvalidFilenameException(""), ReplyCodes.FILENAME_NOT_VALID) 72 73 shouldFail { commandHandler.handleCommand(null, session) } 74 shouldFail { commandHandler.handleCommand(command, null) } 75 } 76 77 void testHandleCommand_FileSystemException() { 78 assertHandleCommandReplyCode(new FileSystemException(PATH, ''), ReplyCodes.READ_FILE_ERROR, PATH) 79 commandHandler.replyCodeForFileSystemException = ReplyCodes.WRITE_FILE_ERROR 80 assertHandleCommandReplyCode(new FileSystemException(PATH, ''), ReplyCodes.WRITE_FILE_ERROR, PATH) 81 } 82 83 void testSendReply() { 84 commandHandler.sendReply(session, REPLY_CODE) 85 assert session.sentReplies[0] == [REPLY_CODE, MSG], session.sentReplies[0] 86 87 commandHandler.sendReply(session, REPLY_CODE, [ARG]) 88 assert session.sentReplies[1] == [REPLY_CODE, MSG_WITH_ARG], session.sentReplies[0] 89 90 shouldFailWithMessageContaining('session') { commandHandler.sendReply(null, REPLY_CODE) } 91 shouldFailWithMessageContaining('reply code') { commandHandler.sendReply(session, 0) } 92 } 93 94 void testSendReply_MessageKey() { 95 commandHandler.sendReply(session, REPLY_CODE, MESSAGE_KEY) 96 assert session.sentReplies[0] == [REPLY_CODE, MSG_FOR_KEY], session.sentReplies[0] 97 98 shouldFailWithMessageContaining('session') { commandHandler.sendReply(null, REPLY_CODE, MESSAGE_KEY) } 99 shouldFailWithMessageContaining('reply code') { commandHandler.sendReply(session, 0, MESSAGE_KEY) } 100 } 101 102 void testSendReply_NullMessageKey() { 103 commandHandler.sendReply(session, REPLY_CODE, null, null) 104 assert session.sentReplies[0] == [REPLY_CODE, MSG_INTERNAL_ERROR], session.sentReplies[0] 105 } 106 107 void testAssertValidReplyCode() { 108 commandHandler.assertValidReplyCode(1) // no exception expected 109 shouldFail { commandHandler.assertValidReplyCode(0) } 110 } 111 112 void testGetRequiredSessionAttribute() { 113 shouldFail(IllegalStateException) { commandHandler.getRequiredSessionAttribute(session, "undefined") } 114 115 session.setAttribute("abc", "not empty") 116 commandHandler.getRequiredSessionAttribute(session, "abc") // no exception 117 118 session.setAttribute("abc", "") 119 commandHandler.getRequiredSessionAttribute(session, "abc") // no exception 120 } 121 122 void testVerifyLoggedIn() { 123 shouldFail(NotLoggedInException) { commandHandler.verifyLoggedIn(session) } 124 session.setAttribute(SessionKeys.USER_ACCOUNT, userAccount) 125 commandHandler.verifyLoggedIn(session) // no exception expected 126 } 127 128 void testGetUserAccount() { 129 assert commandHandler.getUserAccount(session) == null 130 session.setAttribute(SessionKeys.USER_ACCOUNT, userAccount) 131 assert commandHandler.getUserAccount(session) 132 } 133 134 void testVerifyFileSystemCondition() { 135 commandHandler.verifyFileSystemCondition(true, PATH, '') // no exception expected 136 shouldFail(FileSystemException) { commandHandler.verifyFileSystemCondition(false, PATH, '') } 137 } 138 139 void testGetRealPath() { 140 assert commandHandler.getRealPath(session, "/xxx") == "/xxx" 141 142 session.setAttribute(SessionKeys.CURRENT_DIRECTORY, "/usr/me") 143 assert commandHandler.getRealPath(session, null) == "/usr/me" 144 assert commandHandler.getRealPath(session, "/xxx") == "/xxx" 145 assert commandHandler.getRealPath(session, "xxx") == "/usr/me/xxx" 146 assert commandHandler.getRealPath(session, "../xxx") == "/usr/xxx" 147 assert commandHandler.getRealPath(session, "./xxx") == "/usr/me/xxx" 148 } 149 150 //------------------------------------------------------------------------- 151 // Test Setup 152 //------------------------------------------------------------------------- 153 154 void setUp() { 155 super.setUp() 156 commandHandler = new TestFakeCommandHandler() 157 session = new StubSession() 158 serverConfiguration = new StubServerConfiguration() 159 replyTextBundle = new StubResourceBundle() 160 userAccount = new UserAccount() 161 fileSystem = new UnixFakeFileSystem() 162 serverConfiguration.setFileSystem(fileSystem) 163 164 replyTextBundle.put(REPLY_CODE as String, MSG) 165 replyTextBundle.put(MESSAGE_KEY as String, MSG_FOR_KEY) 166 replyTextBundle.put(INTERNAL_ERROR as String, MSG_INTERNAL_ERROR) 167 168 commandHandler.serverConfiguration = serverConfiguration 169 commandHandler.replyTextBundle = replyTextBundle 170 } 171 172 //------------------------------------------------------------------------- 173 // Helper Methods 174 //------------------------------------------------------------------------- 175 176 /** 177 * Assert that when the CommandHandler handleCommand() method throws the 178 * specified exception, that the expected reply is sent through the session. 179 */ 180 private void assertHandleCommandReplyCode(Throwable exception, int expected, text = null) { 181 commandHandler.exception = exception 182 def command = new Command("C1", ["abc"]) 183 session.sentReplies.clear() 184 commandHandler.handleCommand(command, session) 185 def sentReply = session.sentReplies[0][0] 186 assert sentReply == expected 187 if (text) { 188 def sentMessage = session.sentReplies[0][1] 189 assert sentMessage.contains(text), "sentMessage=[$sentMessage] text=[$text]" 190 } 191 } 192 193 } 194 195 /** 196 * Concrete subclass of AbstractFakeCommandHandler for testing 197 */ 198 class TestFakeCommandHandler extends AbstractFakeCommandHandler { 199 boolean handled = false 200 def exception 201 202 protected void handle(Command command, Session session) { 203 if (exception) { 204 throw exception 205 } 206 this.handled = true 207 } 208 }