def test_2_all_file_upload(self) -> None:
        """ Test that the all files method of uploading data is working.
        This test uses the `data` directory to upload to the S3 bucket in the environment var.
        """
        self._upload_all_files()

        # Assert that the finished label gets added
        self.assertEqual(self.mass_upload.update_label.cget('text'),
                         'Finished!')

        # Get all the files with their file size (bytes) from AWS
        all_files_in_s3_dict = AWS().get_bucket_objects_as_dict(
            os.environ.get('S3_BUCKET'))

        # Get all the local file names from the data folder
        all_local_files = []
        for a, b, filenames in os.walk(DATA_DIRECTORY_PATH):
            all_local_files = filenames

        # Assert that the file name and size are the same from local to AWS
        for s3_file, s3_file_size in all_files_in_s3_dict.items():
            # Get just the filename without the `data/` prefix
            s3_file = s3_file.split('/', 1)[1]

            try:
                local_file_size = os.path.getsize(
                    os.path.join(DATA_DIRECTORY_PATH, s3_file))
            except FileNotFoundError:
                pass

            self.assertIn(s3_file, all_local_files)
            self.assertEqual(local_file_size, s3_file_size)

        update_program_controller_loop(self.pc)
Exemple #2
0
    def test_3_different_local_output_extension_checkbox(self) -> None:
        """ Test that the local save output extension entry box gets added to the grid when clicking the checkbox. """
        # "Click" on the `Different local output extension` checkbox
        self.setup_window.local_save_different_extension_checkbox.invoke()
        update_program_controller_loop(self.pc)

        # Make sure that the save locally entry box and button get added to the grid
        self.assertTrue(
            self.setup_window.local_save_different_output_extension_input.grid_info(),
            msg='The local different output extension input field was not added to the grid.'
        )
Exemple #3
0
    def test_1_different_output_extension_for_aws_checkbox(self) -> None:
        """ Test that the different output extension for AWS entry box gets added to the grid when clicking the checkbox. """
        # "Click" on the `Different output extension for AWS` checkbox
        self.setup_window.different_ffmpeg_output_extension_checkbutton.invoke()
        update_program_controller_loop(self.pc)

        # Make sure that the different output extension entry box gets added to the grid
        self.assertTrue(
            self.setup_window.different_ffmpeg_output_extension_input.grid_info(),
            msg='The different output extension for AWS was not added to the grid.'
        )
Exemple #4
0
    def setUpClass(cls) -> None:
        ignore_aws_warning()
        DatabasePath.change_path(os.path.join(os.getcwd(), 'setup_window_test_db.sqlite3'))

        remove_db_file()

        cls.pc = open_program()
        cls.pc.add_frame_to_paned_window(SetupWindow)
        update_program_controller_loop(cls.pc)

        cls.setup_window = cls.pc.select_frame(SetupWindow)

        return super().setUpClass()
Exemple #5
0
    def test_2_save_locally_checkbox(self) -> None:
        """ Test that the local save entry box and button get added to the grid when clicking the checkbox. """
        # "Click" on the `Save locally` checkbox
        self.setup_window.local_save_checkbox.invoke()
        update_program_controller_loop(self.pc)

        # Make sure that the save locally entry box and button get added to the grid
        self.assertTrue(
            self.setup_window.local_save_path_input_field.grid_info(),
            msg='The local save path input field was not added to the grid.'
        )
        self.assertTrue(
            self.setup_window.local_save_path_button.grid_info(),
            msg='The local save path button was not added to the grid.'
        )
Exemple #6
0
    def setUpClass(cls) -> None:
        ignore_aws_warning()

        DatabasePath.change_path(
            os.path.join(os.getcwd(), 'update_database_test_db.sqlite3'))

        remove_db_file()

        cls.pc = open_program()
        cls.pc.add_frame_to_paned_window(UpdateDatabase)
        update_program_controller_loop(cls.pc)

        # MYPY ERROR: Incompatible types in assignment (expression has type "Union[MainWindow, SetupWindow, MassUpload, UpdateDatabase]", variable has type "UpdateDatabase")
        cls.update_window = cls.pc.select_frame(UpdateDatabase)  # type: ignore
        return super().setUpClass()
    def test_update_database_window_button(self) -> None:
        """ Test that when clicking the the Update Database button, the UpdateDatabase pane gets added and removed after clicking it again. """
        # Click on the Update Database button. This should add the UpdateDatabase pane.
        self.main_window.update_database_button.invoke()
        update_program_controller_loop(self.pc)

        # Make sure that there are 2 active panes (MainWindow & UpdateDatabase).
        self.assertEqual(len(self.pc.active_panes()), 2)
        self.assertIn('updatedatabase', self.pc.active_panes()[-1])

        # Click on the Update Database button again. This should make it that the MainWindow is the only active pane.
        self.main_window.update_database_button.invoke()
        update_program_controller_loop(self.pc)

        # Make sure that the UpdateDatabase pane actually gets closed.
        self.assertEqual(len(self.pc.active_panes()), 1)
        self.assertIn('mainwindow', self.pc.active_panes()[-1])
    def test_4_ffmpeg_file_upload(self) -> None:
        """ Test that the ffmpeg upload function works. """
        self.pc.add_frame_to_paned_window(MassUpload)
        update_program_controller_loop(self.pc)

        # Add data directory path to mass upload path entry box
        self.mass_upload.mass_upload_path.set(DATA_DIRECTORY_PATH)

        # Set bucket to use from env var
        self.mass_upload.s3_bucket_name.set(os.environ.get('S3_BUCKET'))

        # Click on the Videos Only radio button
        self.mass_upload.radio_button_video.invoke()

        # Click on the Use ffmpeg button
        self.mass_upload.use_ffmpeg_checkbox.invoke()

        # Click on the start upload button
        self.mass_upload.start_upload_button.invoke()

        # Have to run a new thread that would kill the mainloop after the upload is done.
        # This needs to be done because once the mainloop gets called it won't stop unless it is done
        #   this way or manually by clicking the X.
        threading.Thread(target=self._quit_mainloop_once_upload_is_done,
                         args=(self.mass_upload, True)).start()

        # Run the mainloop so that the upload will execute on the same thread as the mainloop
        # If the mainloop is not called, then an exception will be raised
        #   `RuntimeError: main thread is not in main loop`
        self.pc.mainloop()

        # Get the data from AWS
        bucket_files_and_sizes = AWS().get_bucket_objects_as_dict(
            os.environ.get('S3_BUCKET'))

        # Assert that the converted video is the right name and size
        self.assertIn('data/test_video_converted.mp4', bucket_files_and_sizes)

        # Get the original video file size
        og_file_size = os.path.getsize(
            os.path.join(DATA_DIRECTORY_PATH, 'test_video.mp4'))

        # Assert that the converted file is smaller than the original file
        # Can't check for specific size because each computer makes the converted file a different size by a few bytes
        self.assertTrue(bucket_files_and_sizes['data/test_video_converted.mp4']
                        < og_file_size)
    def _quit_mainloop_once_upload_is_done(self,
                                           mass_upload,
                                           first_time=False) -> None:
        """ Check if the upload finished every second and once it is finished close the mainloop.
        If the update label is not `Finished!`, then an after loop will start for after 500ms to run this function recursively.
        If the update label is equal to `Finished!`, then the mainloop will exit using the quit() function 
            and the program controller gets updated to actually remove the GUI from the screen.
        """
        if first_time:
            time.sleep(1)

        if mass_upload._upload_is_done is False:
            self.pc.after(5000, self._quit_mainloop_once_upload_is_done,
                          mass_upload)
        else:
            self.pc.quit()
            # Need to update the program controller loop so that the GUI actually gets removed from screen
            update_program_controller_loop(self.pc)
Exemple #10
0
    def test_database_update(self) -> None:
        """ Test that the Update Database functionality on the program works. """
        # Assert that the database doesn't already have the tests table
        with Database() as DB:
            self.assertIsNone(DB.get_tests_table())

        # Update the database using the database file
        sql_file_path = os.path.join(
            os.path.dirname(os.path.realpath(__file__)), 'data',
            'update_db.sql')

        self.update_window.file_path.set(sql_file_path)
        self.update_window.update_button.invoke()

        update_program_controller_loop(self.pc)

        # Assert that the database actually got updated with the sql file
        with Database() as DB:
            self.assertEqual(DB.get_tests_table()[0], "This is a test.")
    def test_mass_upload_window_button(self) -> None:
        """ Test that when clicking the the Start Mass Upload button, the MassUpload pane gets added and removed after clicking it again. """
        # Enable the Start Mass Upload button since there is no configuration saved in the DB.
        self.main_window.mass_upload_window_button.configure(state='normal')

        # Click on the Start Mass Upload button. This should add the MassUpload pane.
        self.main_window.mass_upload_window_button.invoke()
        update_program_controller_loop(self.pc)

        # Make sure that there are 2 active panes (MainWindow & MassUpload).
        self.assertEqual(len(self.pc.active_panes()), 2)
        self.assertIn('massupload', self.pc.active_panes()[-1])

        # Click on the Start Mass Upload button again. This should make it that the MainWindow is the only active pane.
        self.main_window.mass_upload_window_button.invoke()
        update_program_controller_loop(self.pc)

        # Make sure that the MassUpload pane actually gets closed.
        self.assertEqual(len(self.pc.active_panes()), 1)
        self.assertIn('mainwindow', self.pc.active_panes()[-1])
    def test_1_refresh_aws_s3_buckets(self) -> None:
        """ Test that the S3 bucket update button works correctly. """
        self._setup_app_data()

        self.pc.add_frame_to_paned_window(MassUpload)
        update_program_controller_loop(self.pc)

        # Assert that there is no data for S3 buckets
        self.assertFalse(self.mass_upload.s3_bucket_selector.cget('values'))

        # Click on refresh aws s3 bucket button
        self.mass_upload.refresh_s3_buckets_button.invoke()
        update_program_controller_loop(self.pc)

        # Assert that the updated label gets added
        self.assertEqual(self.mass_upload.update_label.cget('text'),
                         'S3 buckets updated')

        # Assert that the buckets get updated
        self.assertTrue(self.mass_upload.s3_bucket_selector.cget('values'))
    def test_mixing_buttons(self) -> None:
        """ Test that when clicking any button the correct pane gets added after removing the pane that was currently open.

        This test differs from the ones above because it isn't clicking the same button to close the pane.
        Instead, it is clicking another window button.
            This makes the previous window pane get removed and add the pane from the button clicked.
        """
        # Enable the Start Mass Upload button since there is no configuration saved in the DB.
        self.main_window.mass_upload_window_button.configure(state='normal')

        # Click the Setup button.
        self.main_window.main_window_setup_button.invoke()
        update_program_controller_loop(self.pc)

        # Make sure that the SetupWindow pane is active
        self.assertIn('setupwindow', self.pc.active_panes()[-1])

        # Click the Update Database button.
        self.main_window.update_database_button.invoke()
        update_program_controller_loop(self.pc)

        # Make sure that the UpdateDatabase pane is active
        self.assertIn('updatedatabase', self.pc.active_panes()[-1])

        # Click the Mass Upload button
        self.main_window.mass_upload_window_button.invoke()
        update_program_controller_loop(self.pc)

        # Make sure that the MassUpload pane is active
        self.assertIn('massupload', self.pc.active_panes()[-1])
    def _upload_all_files(self) -> None:
        self.pc.add_frame_to_paned_window(MassUpload)
        update_program_controller_loop(self.pc)

        # Add data directory path to mass upload path entry box
        self.mass_upload.mass_upload_path.set(DATA_DIRECTORY_PATH)

        # Set bucket to use from env var
        self.mass_upload.s3_bucket_name.set(os.environ.get('S3_BUCKET'))

        # Click on the start upload button
        self.mass_upload.start_upload_button.invoke()

        # Have to run a new thread that would kill the mainloop after the upload is done.
        # This needs to be done because once the mainloop gets called it won't stop unless it is done
        #   this way or manually by clicking the X.
        threading.Thread(target=self._quit_mainloop_once_upload_is_done,
                         args=(self.mass_upload, True)).start()

        # Run the mainloop so that the upload will execute on the same thread as the mainloop
        # If the mainloop is not called, then an exception will be raised
        #   `RuntimeError: main thread is not in main loop`
        self.pc.mainloop()
Exemple #15
0
    def test_setup_window_on_fresh_database(self) -> None:
        """ Test that everyting in the setup window is working correctly. """

        self.pc.add_frame_to_paned_window(SetupWindow)
        setup_window: Any = self.pc.select_frame(
            SetupWindow)  # TODO: Figure out how to effectively annotate this

        update_program_controller_loop(self.pc)

        # Interact with the UI to add the AWS keys, region name, and "click" the save button
        setup_window.access_key_id_string.set(
            os.environ.get('AWS_ACCESS_KEY_ID'))
        setup_window.secret_key_string.set(os.environ.get('AWS_SECRET_KEY'))
        setup_window.region_name_var.set(os.environ.get('AWS_REGION_NAME'))
        setup_window.save_button.invoke()

        update_program_controller_loop(self.pc)

        # Make sure that the settings saved message gets displayed.
        self.assertEqual(
            setup_window.setup_window_output_message_variable.get(),
            'Settings saved.')

        # Make sure that the save button/command actually locked the settings.
        self.assertFalse(setup_window.save_button.grid_info(),
                         msg="Save button still on grid.")
        self.assertEqual(
            str(setup_window.access_key_id_input_field.cget('state')),
            'disabled')
        self.assertEqual(
            str(setup_window.secret_key_input_field.cget('state')), 'disabled')
        self.assertEqual(
            str(setup_window.region_name_input_field.cget('state')),
            'disabled')

        # Interact with the UI to unlock the settings
        setup_window.lock_unlock_button.invoke()
        update_program_controller_loop(self.pc)

        # Make sure that the unlock button actually unlocks the settings
        self.assertTrue(setup_window.save_button.grid_info(),
                        msg="Save button not on grid.")
        self.assertEqual(
            str(setup_window.access_key_id_input_field.cget('state')),
            'normal')
        self.assertEqual(
            str(setup_window.secret_key_input_field.cget('state')), 'normal')
        self.assertEqual(
            str(setup_window.region_name_input_field.cget('state')),
            'readonly')
    def _setup_app_data(self) -> None:
        self.pc.add_frame_to_paned_window(SetupWindow)
        update_program_controller_loop(self.pc)

        setup_window: Any = self.pc.select_frame(
            SetupWindow)  # TODO: Figure out how to effectively annotate this

        setup_window.access_key_id_string.set(
            os.environ.get('AWS_ACCESS_KEY_ID'))
        setup_window.secret_key_string.set(os.environ.get('AWS_SECRET_KEY'))
        setup_window.region_name_var.set(os.environ.get('AWS_REGION_NAME'))
        setup_window.ffmpeg_input_var.set("-vcodec libx264 -crf 40")
        setup_window.save_button.invoke()

        update_program_controller_loop(self.pc)

        self.pc.remove_paned_window_frame(self.pc.active_panes()[-1])

        update_program_controller_loop(self.pc)