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.core.command.Command
19import org.mockftpserver.core.command.CommandNames
20import org.mockftpserver.core.command.ReplyCodes
21import org.mockftpserver.fake.filesystem.FileEntry
22import org.mockftpserver.fake.filesystem.FileSystemEntry
23import org.mockftpserver.fake.filesystem.FileSystemException
24import org.mockftpserver.fake.filesystem.Permissions
25
26/**
27 * Abstract superclass for tests of Fake CommandHandlers that store a file (STOR, STOU, APPE)
28 *
29 * @version $Revision$ - $Date$
30 *
31 * @author Chris Mair
32 */
33abstract class AbstractStoreFileCommandHandlerTest extends AbstractFakeCommandHandlerTest {
34
35    protected static final DIR = "/"
36    protected static final FILENAME = "file.txt"
37    protected static final FILE = p(DIR, FILENAME)
38    protected static final CONTENTS = "abc"
39
40    //-------------------------------------------------------------------------
41    // Tests Common to All Subclasses
42    //-------------------------------------------------------------------------
43
44    void testHandleCommand_NoWriteAccessToExistingFile() {
45        fileSystem.add(new FileEntry(path: FILE))
46        fileSystem.getEntry(FILE).permissions = Permissions.NONE
47        handleCommand([FILE])
48        assertSessionReply(ReplyCodes.WRITE_FILE_ERROR, ['filesystem.cannotWrite', FILE])
49    }
50
51    void testHandleCommand_NoWriteAccessToDirectoryForNewFile() {
52        fileSystem.getEntry(DIR).permissions = new Permissions('r-xr-xr-x')
53        handleCommand([FILE])
54        assertSessionReply(ReplyCodes.WRITE_FILE_ERROR, ['filesystem.cannotWrite', DIR])
55    }
56
57    void testHandleCommand_NoExecuteAccessToDirectory() {
58        fileSystem.add(new FileEntry(path: FILE))
59        fileSystem.getEntry(DIR).permissions = new Permissions('rw-rw-rw-')
60        handleCommand([FILE])
61        assertSessionReply(ReplyCodes.WRITE_FILE_ERROR, ['filesystem.cannotExecute', DIR])
62    }
63
64    void testHandleCommand_ThrowsFileSystemException() {
65        fileSystem.addMethodException = new FileSystemException("bad", ERROR_MESSAGE_KEY)
66
67        handleCommand([FILE])
68        assertSessionReply(0, ReplyCodes.TRANSFER_DATA_INITIAL_OK)
69        assertSessionReply(1, ReplyCodes.WRITE_FILE_ERROR, ERROR_MESSAGE_KEY)
70    }
71
72    //-------------------------------------------------------------------------
73    // Abstract Method Declarations
74    //-------------------------------------------------------------------------
75
76    /**
77     * Verify the created output file and return its full path
78     * @return the full path to the created output file; the path may be absolute or relative
79     */
80    protected abstract String verifyOutputFile()
81
82    //-------------------------------------------------------------------------
83    // Helper Methods
84    //-------------------------------------------------------------------------
85
86    protected void testHandleCommand(List parameters, String messageKey, String contents) {
87        session.dataToRead = CONTENTS.bytes
88        handleCommand(parameters)
89        assertSessionReply(0, ReplyCodes.TRANSFER_DATA_INITIAL_OK)
90        assertSessionReply(1, ReplyCodes.TRANSFER_DATA_FINAL_OK, messageKey)
91
92        def outputFile = verifyOutputFile()
93
94        FileSystemEntry fileEntry = fileSystem.getEntry(outputFile)
95        def actualContents = fileEntry.createInputStream().text
96        assert actualContents == contents
97        assert fileEntry.permissions == userAccount.defaultPermissionsForNewFile
98    }
99
100    Command createValidCommand() {
101        return new Command(CommandNames.APPE, [FILE])
102    }
103
104    void setUp() {
105        super.setUp()
106        createDirectory(DIR)
107    }
108
109}