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
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
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
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
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
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
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
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
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
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
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