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.CommandHandler
20import org.mockftpserver.core.command.CommandNames
21import org.mockftpserver.core.command.ReplyCodes
22import org.mockftpserver.core.session.SessionKeys
23import org.mockftpserver.fake.filesystem.DirectoryEntry
24import org.mockftpserver.fake.filesystem.DirectoryListingFormatter
25import org.mockftpserver.fake.filesystem.FileEntry
26import org.mockftpserver.fake.filesystem.FileSystemEntry
27import org.mockftpserver.fake.filesystem.FileSystemException
28import org.mockftpserver.fake.filesystem.Permissions
29
30/**
31 * Tests for ListCommandHandler
32 *
33 * @version $Revision$ - $Date$
34 *
35 * @author Chris Mair
36 */
37class ListCommandHandlerTest extends AbstractFakeCommandHandlerTestCase {
38
39    private static final DIR = "/usr"
40    private static final NAME = "abc.txt"
41    private static final LAST_MODIFIED = new Date()
42
43    void testHandleCommand_SingleFile() {
44        final entry = new FileEntry(path: p(DIR, NAME), lastModified: LAST_MODIFIED, contents: "abc")
45        fileSystem.add(entry)
46        handleCommandAndVerifySendDataReplies([DIR])
47        assertSessionDataWithEndOfLine(listingFor(entry))
48    }
49
50    void testHandleCommand_FilesAndDirectories() {
51        def DATA3 = "".padRight(1000, 'x')
52        final entry1 = new FileEntry(path: p(DIR, "abc.txt"), lastModified: LAST_MODIFIED, contents: "abc")
53        final entry2 = new DirectoryEntry(path: p(DIR, "OtherFiles"), lastModified: LAST_MODIFIED)
54        final entry3 = new FileEntry(path: p(DIR, "another_file.doc"), lastModified: LAST_MODIFIED, contents: DATA3)
55        fileSystem.add(entry1)
56        fileSystem.add(entry2)
57        fileSystem.add(entry3)
58
59        handleCommandAndVerifySendDataReplies([DIR])
60
61        def actualLines = session.sentData[0].tokenize(endOfLine()) as Set
62        LOG.info("actualLines=$actualLines")
63        def EXPECTED = [
64                listingFor(entry1),
65                listingFor(entry2),
66                listingFor(entry3)] as Set
67        assert actualLines == EXPECTED
68        assertSessionDataEndsWithEndOfLine()
69    }
70
71    void testHandleCommand_NoPath_UseCurrentDirectory() {
72        final entry = new FileEntry(path: p(DIR, NAME), lastModified: LAST_MODIFIED, contents: "abc")
73        fileSystem.add(entry)
74        session.setAttribute(SessionKeys.CURRENT_DIRECTORY, DIR)
75        handleCommandAndVerifySendDataReplies([])
76        assertSessionDataWithEndOfLine(listingFor(entry))
77    }
78
79    void testHandleCommand_EmptyDirectory() {
80        handleCommandAndVerifySendDataReplies([DIR])
81        assertSessionData("")
82    }
83
84    void testHandleCommand_PathSpecifiesAFile() {
85        final entry = new FileEntry(path: p(DIR, NAME), lastModified: LAST_MODIFIED, contents: "abc")
86        fileSystem.add(entry)
87        handleCommandAndVerifySendDataReplies([p(DIR, NAME)])
88        assertSessionDataWithEndOfLine(listingFor(entry))
89    }
90
91    void testHandleCommand_PathDoesNotExist() {
92        handleCommandAndVerifySendDataReplies(["/DoesNotExist"])
93        assertSessionData("")
94    }
95
96    void testHandleCommand_NoReadAccessToDirectory() {
97        fileSystem.getEntry(DIR).permissions = new Permissions('-wx-wx-wx')
98        handleCommand([DIR])
99        assertSessionReply(0, ReplyCodes.TRANSFER_DATA_INITIAL_OK)
100        assertSessionReply(1, ReplyCodes.READ_FILE_ERROR, ['filesystem.cannotRead', DIR])
101    }
102
103    void testHandleCommand_ListFilesThrowsException() {
104        fileSystem.listFilesMethodException = new FileSystemException("bad", ERROR_MESSAGE_KEY)
105        handleCommand([DIR])
106        assertSessionReply(0, ReplyCodes.TRANSFER_DATA_INITIAL_OK)
107        assertSessionReply(1, ReplyCodes.SYSTEM_ERROR, ERROR_MESSAGE_KEY)
108    }
109
110    //-------------------------------------------------------------------------
111    // Helper Methods
112    //-------------------------------------------------------------------------
113
114    CommandHandler createCommandHandler() {
115        new ListCommandHandler()
116    }
117
118    Command createValidCommand() {
119        return new Command(CommandNames.LIST, [DIR])
120    }
121
122    void setUp() {
123        super.setUp()
124        createDirectory(DIR)
125        fileSystem.directoryListingFormatter = [format: {entry -> entry.toString()}] as DirectoryListingFormatter
126    }
127
128    private listingFor(FileSystemEntry fileSystemEntry) {
129        fileSystemEntry.toString()
130    }
131
132}