def test_invalid_commands_do_not_invoke_put_function(capsys, sftp):
    """Tests that writing invalid commands doesn't invoke the put action."""

    # See tests/integration/test_close.py for details.
    with mock_input("putty"):
        main_loop(sftp)
        assert "not recognized" in capsys.readouterr().out
예제 #2
0
def test_controller_continues_after_oserror(sftp, monkeypatch, capsys):
    """This test verifies that the controller prints an OSError message
    when it receives it and then continues execution (rather than quitting).
    """

    oserror_message = "THIS IS A TEST"

    def mock_put(s, f):
        """A mock put action that simply raises a known exception."""

        raise OSError(1, oserror_message)

    # Patch in our mocked put function.
    monkeypatch.setattr(put_file_onto_remote_server, "put", mock_put)

    # Our strategy here is to invoke two actions: our mock put, then an
    # invalid command. This will allow us to test for correct behavior, because
    # the controller will print its error message for unrecognized commands
    # if and only if it continues execution after handling the OSError.

    inputs = """
             put file
             hooligan town banana republic
             """
    with mock_input(inputs):
        main_loop(sftp)
        output = capsys.readouterr().out
        assert oserror_message in output

        # Now, we want to ensure that the error for unrecognized commands
        # is displayed AFTER the message we just asserted. So we'll split
        # the output on the message and check the second half.

        assert ERROR_MESSAGE_NOT_RECOGNIZED in \
            output.split(oserror_message, 1)[1]
def test_user_prompt(capsys):
    """Test that the user prompt is printed correctly."""

    prompt = DEFAULT_USER_PROMPT

    with mock_input("Any string will do"):
        read_user_input(prompt)

    assert capsys.readouterr().out == prompt
예제 #4
0
def test_invalid_commands_do_not_invoke_rm_function(capsys, sftp):
    """Tests that writing invalid commands doesn't invoke the rm action."""

    # See tests/integration/test_close.py for details.
    test_cases = """rm
                    rm one two
                 """
    with mock_input(test_cases):
        main_loop(sftp)
        assert SUCCESS_STRING not in capsys.readouterr().out
def test_invalid_commands_do_not_invoke_mput_function(capsys, sftp):
    """Tests that writing invalid commands doesn't invoke the mput action."""

    inputs = """
             cluckcluckcluck
             mput
             """
    with mock_input(inputs):
        main_loop(sftp)
        assert SUCCESS_STRING not in capsys.readouterr().out
def test_main_loop_disconnection(sftp):
    """Tests that the app handles disconnects gracefully."""

    # In order to test unexpected disconnects, we'll pass the controller
    # a disconnected sftp object and send a request take some basic action
    # that uses it.

    sftp.close()
    with mock_input("ls"):
        assert main_loop(sftp) == -1
def test_invalid_commands_do_not_invoke_put_function(capsys, sftp):
    """Tests that writing invalid commands doesn't invoke the put action."""

    # See tests/integration/test_close.py for details.
    test_input = """
                 definitely_not_a_command
                 ls mydir
                 """
    with mock_input(test_input):
        main_loop(sftp)
        assert SUCCESS_STRING not in capsys.readouterr().out
def test_input_length():
    """Test that app.read_user_input() returns the correct number of tokens."""

    # To mock standard input for specific values, we'll set module.input
    # to various lambdas that return the string our "user" types.
    # We'll test various edge cases, starting with the simplest: nothing.

    # Capture empty user input. Oddly, we have to pass "\n" rather than
    # "" or input() will see EOF and throw an exception (as though the
    # user had pressed Ctrl-D, which is a different test case).
    with mock_input("\n"):
        assert len(read_user_input()) == 0

    # One-word input
    with mock_input("Hi1234@#$"):
        assert len(read_user_input()) == 1

    # Multi-word input
    with mock_input("A B C 3 #"):
        assert len(read_user_input()) == 5
예제 #9
0
def test_invalid_commands_do_not_invoke_close_function(capsys, sftp):
    """Tests that writing invalid commands doesn't invoke the close action."""

    # Pass a fake command to main_loop() and verify that it detects that the
    # command is not recognized. Note that main_loop() terminates because
    # it reaches EOF in our simulated stdin, so it's impractical for us to
    # monkeypatch mock_close in and verify that it was NOT called. Even if
    # we could prevent main_loop from calling it, we would prevent main_loop
    # from terminating, most likely, so our test would never conclude.
    with mock_input("sayonara"):
        main_loop(sftp)
        assert "not recognized" in capsys.readouterr().out
def test_invalid_commands_do_not_invoke_put_r_function(capsys, sftp):
    """Tests that writing invalid commands doesn't invoke the rename action."""

    # Test inputs. They need to be a single sequence, or we'll send EOF
    # and close our SFTP connection after the first test.
    test_inputs = """doesnotexist
                     put -r 
                     put -r ham sandwich"""
    for test in test_inputs:
        with mock_input(test):
            main_loop(sftp)
            assert SUCCESS_STRING not in capsys.readouterr().out
def test_rename_invokes_rename_action(capsys, monkeypatch, sftp):
    """Tests that writing text like 'rename from to' calls the rename action
    and passes 'from' and 'to' as before and after, respectively.
    """

    # Replace the real action with our mocked function
    monkeypatch.setattr(rename, "rename_remote_file", mock_rename)

    # Pass in a valid input
    with mock_input("rename {} {}".format(FROM, TO)):
        main_loop(sftp)

    assert SUCCESS_STRING in capsys.readouterr().out
def test_put_file_invokes_put_function(capsys, monkeypatch, sftp):
    """Tests that writing 'put file' calls the put action and passes 'file'
    as the filename.
    """

    # Replace put_file_onto_remote_server.put with our mocked function
    monkeypatch.setattr(put_file_onto_remote_server, "put", mock_put)

    # Pass in a valid input
    with mock_input("put " + FILENAME):
        main_loop(sftp)

    assert SUCCESS_STRING in capsys.readouterr().out
예제 #13
0
def test_chmod_invokes_chmod_action(capsys, monkeypatch, sftp):
    """Tests that writing text like 'chmod 555 mydir' calls the rename action
    and passes 777 and 'mydir' as permissions and filename, respectively.
    """

    # Replace the real action with our mocked function
    monkeypatch.setattr(chmod, "change_permissions", mock_chmod)

    # Pass in a valid input
    with mock_input("chmod {} {}".format(MODE, PATH)):
        main_loop(sftp)

    assert SUCCESS_STRING in capsys.readouterr().out
def test_put_file_invokes_put_function(capsys, monkeypatch, sftp):
    """Tests that writing 'mput file1 file1' calls the mput action and passes
    the list ["file1", "file2"] as filenames.
    """

    # Replace put_file_onto_remote_server.put with our mocked function
    monkeypatch.setattr(mput, "put_multiple", mock_mput)

    # Pass in a valid input
    with mock_input("mput " + FILENAMES):
        main_loop(sftp)

    assert SUCCESS_STRING in capsys.readouterr().out
def test_lsearch_invokes_lsearch_action(capsys, monkeypatch, sftp):
    """Tests that writing text like 'lsearch myname' calls the lsearch action and
    passes 'myname' as name.
    """

    # Replace the real action with our mocked function
    monkeypatch.setattr(lsearch, "search_local_files", mock_lsearch)

    # Pass in a valid input
    with mock_input("lsearch {}".format(NAME)):
        main_loop(sftp)

    assert SUCCESS_STRING in capsys.readouterr().out
def test_invalid_commands_do_not_invoke_lsearch_function(capsys, sftp):
    """Tests that writing invalid commands doesn't invoke the lsearch action."""

    # See tests/integration/test_close.py for details.
    test_inputs = [
        "doesnotexist",
        "lsearch",  # No files
        "lsearch onefile twofile"
    ]
    for test in test_inputs:
        with mock_input(test):
            main_loop(sftp)
            assert SUCCESS_STRING not in capsys.readouterr().out
예제 #17
0
def test_mkdir_invokes_create_folder_action(capsys, monkeypatch, sftp):
    """Tests that writing text like 'mkdir foldername' calls the put action and
    passes 'foldername' as the remote path to create.
    """

    # Replace the real action with our mocked function
    monkeypatch.setattr(mkdir, "create_dir_remote", mock_mkdir)

    # Pass in a valid input
    with mock_input("mkdir {}".format(FOLDER)):
        main_loop(sftp)

    assert SUCCESS_STRING in capsys.readouterr().out
예제 #18
0
def test_lls_invokes_list_files_local_action(capsys, monkeypatch, sftp):
    """Tests that writing 'lls' calls the 'list files local' action."""

    # Replace the real function with our mocked function
    monkeypatch.setattr(list_files_local,
                        "display_local_files",
                        mock_list_local_files)

    # Pass in a valid input
    with mock_input("lls"):
        main_loop(sftp)

    assert SUCCESS_STRING in capsys.readouterr().out
def test_put_file_invokes_put_function(monkeypatch, capsys, sftp):
    """Tests that writing 'put file' calls the put action and passes 'file'
    as the filename.
    """

    # Replace the action with our mocked function
    monkeypatch.setattr(list_files_remote, "list_dir", mock_list_dir)

    # Pass in a valid input
    with mock_input("ls"):
        main_loop(sftp)

    assert SUCCESS_STRING in capsys.readouterr().out
예제 #20
0
def test_lrename_invokes_rename_action(capsys, monkeypatch, sftp):
    """Tests that writing text like 'lrename from to' calls the put action and
    passes 'from' as the original filename and 'to' as the new filename.
    """

    # Replace the real action with our mocked function
    monkeypatch.setattr(rename_files_local, "rename_local_file", mock_rename)

    # Pass in a valid input
    with mock_input("lrename {} {}".format(FROM, TO)):
        main_loop(sftp)

    assert SUCCESS_STRING in capsys.readouterr().out
def test_put_r_invokes_put_folder_action(capsys, monkeypatch, sftp):
    """Tests that writing text like 'lrename from to' calls the put action and
    passes 'from' as the original filename and 'to' as the new filename.
    """

    # Replace the real action with our mocked function
    monkeypatch.setattr(put_folder, "put_r", mock_put_r)

    # Pass in a valid input
    with mock_input("put -r {}".format(FOLDER)):
        main_loop(sftp)

    assert SUCCESS_STRING in capsys.readouterr().out
예제 #22
0
def test_invalid_commands_do_not_invoke_rename_function(capsys, sftp):
    """Tests that writing invalid commands doesn't invoke the rename action."""

    # See tests/integration/test_close.py for details.
    test_inputs = [
        "doesnotexist",
        "lrename",  # No files
        "lrename onefile",
        "lrename onefile twofile threefile"
    ]
    for test in test_inputs:
        with mock_input(test):
            main_loop(sftp)
            assert "not recognized" in capsys.readouterr().out
예제 #23
0
def test_close_commands_invoke_close_function(monkeypatch, capsys, sftp):
    """Tests that writing any valid close command at the program's main prompt,
    e.g. 'bye', 'exit', or 'quit', calls the close action.
    """

    # Replace the real close action with our mocked version.
    monkeypatch.setattr(close, "close", mock_close)

    # For each input, invoke the main loop with an open connection,
    # pass in the input, and verify that mock_close() was called.
    for input in INPUTS:
        with mock_input(input):
            main_loop(sftp)
            assert SUCCESS_STRING in capsys.readouterr().out
예제 #24
0
def test_remove_file_invokes_remove_function(capsys, monkeypatch, sftp):
    """Tests that writing 'rm file' calls the remove_from_remote_server action and passes 'file'
    as the filename.
    """

    # Replace remove_from_remote_server.remove_from_remote_server with our mocked function
    monkeypatch.setattr(remove_from_remote_server, "remove_from_remote_server",
                        mock_rm)

    # Pass in a valid input
    with mock_input("rm " + FILENAME):
        main_loop(sftp)

    assert SUCCESS_STRING in capsys.readouterr().out
def test_end_of_file(sftp, capsys):
    """Tests that the app handles the EOF character (e.g. Ctrl-D)
    gracefully.
    """

    with mock_input(""):
        retval = main_loop(sftp)
        stdout = capsys.readouterr().out
        assert retval == 0, \
            "Controller should return 0 after receiving EOF."
        assert ("connection closed" in stdout.lower()), \
            "EOF response message should include 'connection closed'."
        assert stdout.startswith("\n", len(DEFAULT_USER_PROMPT)), \
            "EOF response message should start with a newline."
def test_correct_tokenization():
    """Test that read_app.read_user_input() returns the correct tokenizations
    for both simple and complex input cases.
    """

    # In order to reduce redundancy and make it easier to add test cases,
    # we'll define our test cases as a list, and we'll run each list item
    # as a test case.
    #
    # test_cases: a list of test cases. Each test case has the format:
    #   [input string, correct tokenization]
    #
    # Note that there are lots of crazy, wacky corner cases involving
    # file names that no one should ever really use (e.g. file names
    # with quotes or backslashes in them), and app.read_user_input()
    # should capture them correctly, but we're not testing for them.
    test_cases = [
        # Case: one-word file name.
        ["First", ["First"]],

        # Case: two one-word file names.
        ["Hello, Dolly", ["Hello,", "Dolly"]],

        # Case: one escaped-space multi-word file name.
        [
            r"Filename\ with\ escaped\ spaces",
            [r"Filename with escaped spaces"]
        ],

        # Case: one double-quoted multi-word file name.
        ['"Filename with double quotes"', ['Filename with double quotes']],

        # Case: one single-quoted multi-word file name.
        ["'Filename with single quotes'", ["Filename with single quotes"]],

        # Case: multi-word filenames, one of each.
        [
            r'''"File 1.png" 'File 2.png' File\ 3.png''',
            ['File 1.png', "File 2.png", r"File 3.png"]
        ],

        # Case: whitespace.
        ["   file   edit   tools  ", ["file", "edit", "tools"]],

        # Cases: escaped quotes.
        [r'\"', ['"']],
        [r"\'", ["'"]],

        # Cases: escaped quotes in other settings.
        [
            r"'\'a'",  # '\'a' -> 'a
            ["'a"]
        ],
        [
            r'"\"a"',  # "\"a" -> "a
            ['"a']
        ],
        [
            r'''"Hello\" asdf" "what " " and "''',
            ['Hello" asdf', 'what ', ' and ']
        ]
    ]

    for input_string, tokens in test_cases:
        with mock_input(input_string):
            assert read_user_input() == tokens