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 AbstractFakeCommandHandlerTest {
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        assertSessionData(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    }
69
70    void testHandleCommand_NoPath_UseCurrentDirectory() {
71        final entry = new FileEntry(path: p(DIR, NAME), lastModified: LAST_MODIFIED, contents: "abc")
72        fileSystem.add(entry)
73        session.setAttribute(SessionKeys.CURRENT_DIRECTORY, DIR)
74        handleCommandAndVerifySendDataReplies([])
75        assertSessionData(listingFor(entry))
76    }
77
78    void testHandleCommand_EmptyDirectory() {
79        handleCommandAndVerifySendDataReplies([DIR])
80        assertSessionData("")
81    }
82
83    void testHandleCommand_PathSpecifiesAFile() {
84        final entry = new FileEntry(path: p(DIR, NAME), lastModified: LAST_MODIFIED, contents: "abc")
85        fileSystem.add(entry)
86        handleCommandAndVerifySendDataReplies([p(DIR, NAME)])
87        assertSessionData(listingFor(entry))
88    }
89
90    void testHandleCommand_PathDoesNotExist() {
91        handleCommandAndVerifySendDataReplies(["/DoesNotExist"])
92        assertSessionData("")
93    }
94
95    void testHandleCommand_NoReadAccessToDirectory() {
96        fileSystem.getEntry(DIR).permissions = new Permissions('-wx-wx-wx')
97        handleCommand([DIR])
98        assertSessionReply(0, ReplyCodes.TRANSFER_DATA_INITIAL_OK)
99        assertSessionReply(1, ReplyCodes.READ_FILE_ERROR, ['filesystem.cannotRead', DIR])
100    }
101
102    void testHandleCommand_ListFilesThrowsException() {
103        fileSystem.listFilesMethodException = new FileSystemException("bad", ERROR_MESSAGE_KEY)
104        handleCommand([DIR])
105        assertSessionReply(0, ReplyCodes.TRANSFER_DATA_INITIAL_OK)
106        assertSessionReply(1, ReplyCodes.SYSTEM_ERROR, ERROR_MESSAGE_KEY)
107    }
108
109    //-------------------------------------------------------------------------
110    // Helper Methods
111    //-------------------------------------------------------------------------
112
113    CommandHandler createCommandHandler() {
114        new ListCommandHandler()
115    }
116
117    Command createValidCommand() {
118        return new Command(CommandNames.LIST, [DIR])
119    }
120
121    void setUp() {
122        super.setUp()
123        createDirectory(DIR)
124        fileSystem.directoryListingFormatter = [format: {entry -> entry.toString()}] as DirectoryListingFormatter
125    }
126
127    private listingFor(FileSystemEntry fileSystemEntry) {
128        fileSystemEntry.toString()
129    }
130
131}