Home | History | Annotate | Download | only in command
      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 }