class TestConfig(unittest.TestCase): def setUp(self): ''' Stardard init method: runs before each test_* method Initializes a PluginManager ''' self.profile_manager = ProfileManager(tempfile.mkdtemp()) self.profile = self.profile_manager.get('testing') self.config = self.profile.get_config('freeseer.conf', settings.FreeseerConfig, ['Global'], read_only=False) def tearDown(self): ''' Generic unittest.TestCase.tearDown() ''' shutil.rmtree(self.profile_manager._base_folder) def test_save(self): ''' Tests that the config file was created after being saved. ''' filepath = self.profile.get_filepath('freeseer.conf') self.config.save() self.assertTrue(os.path.exists(filepath))
class TestReportEditorApp(unittest.TestCase): ''' Test cases for ReportEditorApp. ''' def setUp(self): ''' Stardard init method: runs before each test_* method Initializes a QtGui.QApplication and ReportEditorApp object. ReportEditorApp() causes the UI to be rendered. ''' self.profile_manager = ProfileManager(tempfile.mkdtemp()) profile = self.profile_manager.get('testing') config = profile.get_config('freeseer.conf', settings.FreeseerConfig, storage_args=['Global'], read_only=False) db = profile.get_database() self.app = QtGui.QApplication([]) self.report_editor = ReportEditorApp(config, db) self.report_editor.show() def tearDown(self): shutil.rmtree(self.profile_manager._base_folder) del self.app del self.report_editor.app def test_close_report_editor(self): ''' Tests closing the ReportEditorApp ''' QtTest.QTest.mouseClick(self.report_editor.editorWidget.closeButton, Qt.Qt.LeftButton) self.assertFalse(self.report_editor.editorWidget.isVisible()) def test_file_menu_quit(self): ''' Tests ReportEditorApp's File->Quit ''' self.assertTrue(self.report_editor.isVisible()) # File->Menu self.report_editor.actionExit.trigger() self.assertFalse(self.report_editor.isVisible()) def test_help_menu_about(self): ''' Tests ReportEditorApp's Help->About ''' self.assertTrue(self.report_editor.isVisible()) # Help->About self.report_editor.actionAbout.trigger() self.assertFalse(self.report_editor.hasFocus()) self.assertTrue(self.report_editor.aboutDialog.isVisible()) # Click "Close" QtTest.QTest.mouseClick(self.report_editor.aboutDialog.closeButton, Qt.Qt.LeftButton) self.assertFalse(self.report_editor.aboutDialog.isVisible())
class TestConfig(unittest.TestCase): def setUp(self): ''' Stardard init method: runs before each test_* method Initializes a PluginManager ''' self.profile_manager = ProfileManager(tempfile.mkdtemp()) self.profile = self.profile_manager.get('testing') self.config = self.profile.get_config('freeseer.conf', settings.FreeseerConfig, ['Global'], read_only=False) def tearDown(self): ''' Generic unittest.TestCase.tearDown() ''' shutil.rmtree(self.profile_manager._base_folder) def test_save(self): ''' Tests that the config file was created after being saved. ''' filepath = self.profile.get_filepath('freeseer.conf') self.config.save() self.assertTrue(os.path.exists(filepath))
class TestProfileManager(unittest.TestCase): """Tests the ProfileManager.""" def setUp(self): self.profiles_path = tempfile.mkdtemp() self.profile_manager = ProfileManager(self.profiles_path) def tearDown(self): shutil.rmtree(self.profiles_path) def test_get(self): """Tests that get returns a Profile instance.""" profile = self.profile_manager.get('testing') self.assertIsInstance(profile, Profile) def test_get_cache(self): """Tests that get caching is working as expected.""" profile1 = self.profile_manager.get('testing') profile2 = self.profile_manager.get('testing') self.assertEqual(profile1, profile2)
def recording(self, request, test_client, monkeypatch, tmpdir): recording = server.app.blueprints['recording'] monkeypatch.setattr(settings, 'configdir', str(tmpdir.mkdir('configdir'))) test_client.get('/recordings') profile_manager = ProfileManager(str(tmpdir.mkdir('profile'))) recording.profile = profile_manager.get('testing') recording.config = recording.profile.get_config('freeseer.conf', settings.FreeseerConfig, ['Global'], read_only=True) recording.config.videodir = str(tmpdir.mkdir('Videos')) recording.plugin_manager = PluginManager(recording.profile) return recording
def recording(self, request, test_client, monkeypatch, tmpdir): recording = server.app.blueprints['recording'] monkeypatch.setattr(settings, 'configdir', str(tmpdir.mkdir('configdir'))) test_client.get('/recordings') profile_manager = ProfileManager(str(tmpdir.mkdir('profile'))) recording.profile = profile_manager.get('testing') recording.config = recording.profile.get_config( 'freeseer.conf', settings.FreeseerConfig, ['Global'], read_only=True) recording.config.videodir = str(tmpdir.mkdir('Videos')) recording.plugin_manager = PluginManager(recording.profile) return recording
class TestMultimedia(unittest.TestCase): def setUp(self): self.profile_manager = ProfileManager(tempfile.mkdtemp()) self.temp_video_dir = tempfile.mkdtemp() profile = self.profile_manager.get('testing') config = profile.get_config('freeseer.conf', settings.FreeseerConfig, ['Global'], read_only=True) config.videodir = self.temp_video_dir plugin_manager = PluginManager(profile) self.multimedia = Multimedia(config, plugin_manager) def tearDown(self): shutil.rmtree(self.temp_video_dir) shutil.rmtree(self.profile_manager._base_folder) def test_load_backend(self): self.multimedia.load_backend(filename=u"test.ogg") def test_record_functions(self): self.multimedia.load_backend(filename=u"test.ogg") self.multimedia.record() self.multimedia.pause() self.multimedia.stop() def test_current_state_is_record(self): self.multimedia.record() self.assertEqual(self.multimedia.current_state, self.multimedia.RECORD) self.assertEqual(self.multimedia.player.get_state()[1], gst.STATE_PLAYING) def test_current_state_is_pause(self): self.multimedia.pause() self.assertEqual(self.multimedia.current_state, self.multimedia.PAUSE) self.assertEqual(self.multimedia.player.get_state()[1], gst.STATE_PAUSED) def test_current_state_is_not_stop(self): self.multimedia.player.set_state(gst.STATE_NULL) self.multimedia.stop() self.assertNotEqual(self.multimedia.current_state, self.multimedia.STOP) self.assertEqual(self.multimedia.player.get_state()[1], gst.STATE_NULL)
class TestMultimedia(unittest.TestCase): def setUp(self): self.profile_manager = ProfileManager(tempfile.mkdtemp()) profile = self.profile_manager.get('testing') config = profile.get_config('freeseer.conf', settings.FreeseerConfig, ['Global'], read_only=True) plugin_manager = PluginManager(profile) self.multimedia = Multimedia(config, plugin_manager) def tearDown(self): shutil.rmtree(self.profile_manager._base_folder) def test_load_backend(self): self.multimedia.load_backend(filename=u"test.ogg") def test_record_functions(self): self.multimedia.load_backend(filename=u"test.ogg") self.multimedia.record() self.multimedia.pause() self.multimedia.stop()
class TestMultimedia(unittest.TestCase): def setUp(self): self.profile_manager = ProfileManager(tempfile.mkdtemp()) profile = self.profile_manager.get('testing') config = profile.get_config('freeseer.conf', settings.FreeseerConfig, ['Global'], read_only=True) plugin_manager = PluginManager(profile) self.multimedia = Multimedia(config, plugin_manager) def tearDown(self): shutil.rmtree(self.profile_manager._base_folder) def test_load_backend(self): self.multimedia.load_backend(filename=u"test.ogg") def test_record_functions(self): self.multimedia.load_backend(filename=u"test.ogg") self.multimedia.record() self.multimedia.pause() self.multimedia.stop()
class TestMultimedia(unittest.TestCase): def setUp(self): self.profile_manager = ProfileManager(tempfile.mkdtemp()) self.temp_video_dir = tempfile.mkdtemp() profile = self.profile_manager.get('testing') config = profile.get_config('freeseer.conf', settings.FreeseerConfig, ['Global'], read_only=True) config.videodir = self.temp_video_dir plugin_manager = PluginManager(profile) self.multimedia = Multimedia(config, plugin_manager) def tearDown(self): shutil.rmtree(self.temp_video_dir) shutil.rmtree(self.profile_manager._base_folder) def test_load_backend(self): self.multimedia.load_backend(filename=u"test.ogg") def test_record_functions(self): self.multimedia.load_backend(filename=u"test.ogg") self.multimedia.record() self.multimedia.pause() self.multimedia.stop() def test_current_state_is_record(self): self.multimedia.record() self.assertEqual(self.multimedia.current_state, self.multimedia.RECORD) self.assertEqual(self.multimedia.player.get_state()[1], gst.STATE_PLAYING) def test_current_state_is_pause(self): self.multimedia.pause() self.assertEqual(self.multimedia.current_state, self.multimedia.PAUSE) self.assertEqual(self.multimedia.player.get_state()[1], gst.STATE_PAUSED) def test_current_state_is_not_stop(self): self.multimedia.player.set_state(self.multimedia.NULL) # set to NULL self.multimedia.stop() self.assertNotEqual(self.multimedia.current_state, self.multimedia.STOP) self.assertEqual(self.multimedia.player.get_state()[1], gst.STATE_NULL)
class TestRecordApp(unittest.TestCase): ''' Test suite to verify the functionality of the RecordApp class. Tests interact like an end user (using QtTest). Expect the app to be rendered. ''' def setUp(self): ''' Stardard init method: runs before each test_* method Initializes a QtGui.QApplication and RecordApp object. RecordApp.show() causes the UI to be rendered. ''' self.profile_manager = ProfileManager(tempfile.mkdtemp()) profile = self.profile_manager.get('testing') config = profile.get_config('freeseer.conf', settings.FreeseerConfig, storage_args=['Global'], read_only=False) self.app = QtGui.QApplication([]) self.record_app = RecordApp(profile, config) self.record_app.show() def tearDown(self): ''' Generic unittest.TestCase.tearDown() ''' shutil.rmtree(self.profile_manager._base_folder) self.record_app.actionExit.trigger() del self.app def test_init_conditions(self): ''' Tests the initial state of the RecordApp ''' # TODO pass def test_standby_to_recording(self): ''' Tests pre and post conditions when entering Standby, Record, Stop modes ''' # TODO: ROADBLOCK # The Gstreamer takes a while to initialize the preview. # Due to this, when the unitest clicks "Record", the preview has not yet been initialized # and Freeseer freezes # It is not trivial or clear how to detect whether or not the preview has loaded # It turns out that even if the state is Multimedia.PAUSE, the preview has not quite loaded # self.assertTrue(self.record_app.mainWidget.standbyPushButton.isVisible(), "[PRE STANDBY] Expected Standby button to be visible") # self.assertFalse(self.record_app.mainWidget.recordPushButton.isVisible(), "[PRE STANDBY] Expected Record button to be invisible") # Click the Standby button with the left mouse button # QtTest.QTest.mouseClick(self.record_app.mainWidget.standbyPushButton, Qt.Qt.LeftButton) # self.assertFalse(self.record_app.mainWidget.standbyPushButton.isVisible(), "[STANDBY] Expected Standby button to be invisible") # self.assertTrue(self.record_app.mainWidget.recordPushButton.isVisible(), "[STANDBY] Expected Record button to be visible") # TODO: Check if preview has loaded # Click the Record button with the left mouse button # QtTest.QTest.mouseClick(self.record_app.mainWidget.recordPushButton, Qt.Qt.LeftButton) # self.assertFalse(self.record_app.mainWidget.standbyPushButton.isVisible(), "[RECORDING] Expected Standby button to be invisible") # self.assertTrue(self.record_app.mainWidget.recordPushButton.isVisible(), "[RECORDING] Expected Record button to be visible") # self.assertTrue(self.record_app.mainWidget.recordPushButton.text() == self.record_app.stopString, "[RECORDING] Incorrect button text for this phase") # Click the Record button again in 5 seconds with the left mouse button # QtTest.QTest.mouseClick(self.record_app.mainWidget.recordPushButton, Qt.Qt.LeftButton) def test_reset_timer(self): ''' Tests RecordApp.reset_timer() ''' # set our own values self.record_app.time_minutes = 15 self.record_app.time_seconds = 30 # reset timer and check that the values are 0 self.record_app.reset_timer() self.assertTrue(self.record_app.time_minutes == 0 and self.record_app.time_seconds == 0) def test_file_menu_quit(self): ''' Tests RecordApp's File->Quit ''' self.assertTrue(self.record_app.isVisible()) # File->Menu self.record_app.actionExit.trigger() self.assertFalse(self.record_app.isVisible()) def test_help_menu_about(self): ''' Tests RecordApp's Help->About ''' self.assertTrue(self.record_app.isVisible()) # Help->About self.record_app.actionAbout.trigger() self.assertFalse(self.record_app.hasFocus()) self.assertTrue(self.record_app.aboutDialog.isVisible()) # Click "Close" QtTest.QTest.mouseClick(self.record_app.aboutDialog.closeButton, Qt.Qt.LeftButton) self.assertFalse(self.record_app.aboutDialog.isVisible()) def test_pep8(self): checker = pep8.StyleGuide(**pep8_options) report = checker.check_files(['freeseer/tests/frontend/record', 'freeseer/frontend/record']) pep8_report(self, report)
class TestProfileManager(unittest.TestCase): """Tests the ProfileManager.""" def setUp(self): self.profiles_path = tempfile.mkdtemp() self.profile_manager = ProfileManager(self.profiles_path) def tearDown(self): shutil.rmtree(self.profiles_path) def test_get(self): """Tests that get returns a Profile instance.""" profile = self.profile_manager.get('testing') self.assertIsInstance(profile, Profile) def test_get_non_existent(self): """Test for non-existent profile.""" self.assertRaises(ProfileDoesNotExist, self.profile_manager.get, 'non-existent_profile', create_if_needed=False) def test_get_non_existent_creates(self): """Test that get creates non-existent profile if create_if_needed=True.""" self.assertRaises(ProfileDoesNotExist, self.profile_manager.get, 'non-existent_profile', create_if_needed=False) profile = self.profile_manager.get('non_existent_profile') self.assertIsInstance(profile, Profile) def test_get_cache(self): """Tests that get caching is working as expected.""" profile1 = self.profile_manager.get('testing') profile2 = self.profile_manager.get('testing') self.assertEqual(profile1, profile2) def test_list_profiles(self): """Tests that list_profiles returns all profiles on file.""" self.profile_manager.create('testing1') self.profile_manager.create('testing2') profiles = self.profile_manager.list_profiles() self.assertItemsEqual(['testing1', 'testing2'], profiles) def test_create_profile(self): """Tests that create_profile returns an instance of Profile..""" profile = self.profile_manager.create('testing1') self.assertIsInstance(profile, Profile) def test_create_profile_existing(self): """Tests that exception is raised if trying to overwrite existing profile.""" self.profile_manager.create('testing1') self.assertRaises(ProfileAlreadyExists, self.profile_manager.create, 'testing1') def test_create_profile_caches(self): """Tests that create_profile adds the new Profile instance to cache.""" self.assertNotIn('testing1', self.profile_manager._cache) self.profile_manager.create('testing1') self.assertIn('testing1', self.profile_manager._cache) def test_delete_profile_existing(self): """Tests that delete_profile deletes the profile from cache and file.""" self.profile_manager.create('testing1') self.profile_manager.delete('testing1') self.assertRaises(ProfileDoesNotExist, self.profile_manager.get, 'testing1', create_if_needed=False) def test_delete_profile_non_existing(self): """Non-existent profiles can't be deleted.""" self.assertRaises(ProfileDoesNotExist, self.profile_manager.delete, 'testing')
class TestConfigToolApp(unittest.TestCase): ''' Test suite to verify the functionality of the ConfigToolApp class. Tests interact like an end user (using QtTest). Expect the app to be rendered. NOTE: most tests will follow this format: 1. Get current config setting 2. Make UI change (config change happens immediately) 3. Reparse config file 4. Test that has changed (using the previous and new) ''' def setUp(self): ''' Stardard init method: runs before each test_* method Initializes a QtGui.QApplication and ConfigToolApp object. ConfigToolApp.show() causes the UI to be rendered. ''' self.profile_manager = ProfileManager(tempfile.mkdtemp()) profile = self.profile_manager.get('testing') config = profile.get_config('freeseer.conf', settings.FreeseerConfig, storage_args=['Global'], read_only=False) self.app = QtGui.QApplication([]) self.config_tool = ConfigToolApp(profile, config) self.config_tool.show() def tearDown(self): ''' Standard tear down method. Runs after each test_* method. This method closes the ConfigToolApp by clicking the "close" button ''' QtTest.QTest.mouseClick(self.config_tool.mainWidget.closePushButton, Qt.Qt.LeftButton) shutil.rmtree(self.profile_manager._base_folder) del self.config_tool.app self.app.deleteLater() def test_default_widget(self): self.assertTrue(self.config_tool.currentWidget == self.config_tool.generalWidget) def test_general_settings(self): ''' Tests for the config tool's General Tab ''' # Select "General" tab item = self.config_tool.mainWidget.optionsTreeWidget.findItems(self.config_tool.generalString, QtCore.Qt.MatchExactly) self.assertFalse(not item or item[0] is None) self.config_tool.mainWidget.optionsTreeWidget.setCurrentItem(item[0]) QtTest.QTest.mouseClick(self.config_tool.mainWidget.optionsTreeWidget, Qt.Qt.LeftButton) # Language drop-down # TODO # Record directory # TODO # AutoHide Checkbox for i in range(2): state = self.config_tool.currentWidget.autoHideCheckBox.checkState() expected_state = QtCore.Qt.Unchecked if state == QtCore.Qt.Unchecked: expected_state = QtCore.Qt.Checked self.config_tool.currentWidget.autoHideCheckBox.click() self.assertEquals( self.config_tool.currentWidget.autoHideCheckBox.checkState(), expected_state) self.assertEquals(self.config_tool.config.auto_hide, expected_state == QtCore.Qt.Checked) def test_recording_settings(self): ''' Tests for config tool's Recording tab ''' # Select "Recording" tab item = self.config_tool.mainWidget.optionsTreeWidget.findItems(self.config_tool.avString, QtCore.Qt.MatchExactly) self.assertFalse(not item or item[0] is None) self.config_tool.mainWidget.optionsTreeWidget.setCurrentItem(item[0]) QtTest.QTest.mouseClick(self.config_tool.mainWidget.optionsTreeWidget, Qt.Qt.LeftButton) # Recording tab self.assertTrue(self.config_tool.currentWidget == self.config_tool.avWidget) # Audio Input # Checkbox for i in range(2): #self.config_tool.config.readConfig() if self.config_tool.currentWidget.audioGroupBox.isChecked(): self.assertTrue(self.config_tool.config.enable_audio_recording) self.assertTrue(self.config_tool.config.audiomixer == "Audio Passthrough" or self.config_tool.config.audiomixer == "Multiple Audio Inputs") self.config_tool.currentWidget.audioGroupBox.setChecked(False) else: self.assertFalse(self.config_tool.config.enable_audio_recording) self.config_tool.currentWidget.audioGroupBox.setChecked(True) # Dropdown # TODO # Video Input # Checkbox for i in range(2): #self.config_tool.config.readConfig() if self.config_tool.currentWidget.videoGroupBox.isChecked(): self.assertTrue(self.config_tool.config.enable_video_recording) # TODO: Write better test case for this self.assertTrue(self.config_tool.config.videomixer == "Video Passthrough" or self.config_tool.config.videomixer == "Picture-In-Picture") self.config_tool.currentWidget.videoGroupBox.setChecked(False) else: self.assertFalse(self.config_tool.config.enable_video_recording) self.config_tool.currentWidget.videoGroupBox.setChecked(True) # Dropdown # TODO # Record to File # Checkbox for i in range(2): #self.config_tool.config.readConfig() if self.config_tool.currentWidget.fileGroupBox.isChecked(): self.assertTrue(self.config_tool.config.record_to_file) # TODO: Write better test case for this self.assertTrue(self.config_tool.config.record_to_file_plugin == "Ogg Output" or self.config_tool.config.record_to_file_plugin == "WebM Output") self.config_tool.currentWidget.fileGroupBox.setChecked(False) else: self.assertFalse(self.config_tool.config.record_to_file) self.config_tool.currentWidget.fileGroupBox.setChecked(True) # Dropdown # TODO # Record to Stream # Checkbox for i in range(2): #self.config_tool.config.readConfig() if self.config_tool.currentWidget.streamGroupBox.isChecked(): self.assertTrue(self.config_tool.config.record_to_stream) # TODO: Write better test case for this #self.assertTrue(self.config_tool.config.record_to_stream_plugin == None) self.config_tool.currentWidget.streamGroupBox.setChecked(False) else: self.assertFalse(self.config_tool.config.record_to_stream) self.config_tool.currentWidget.streamGroupBox.setChecked(True) # Dropdown # TODO def test_plugin_audio_input_settings(self): ''' Tests for config tool's Plugins->Audio Input tab ''' # TODO pass def test_plugin_audio_mixer_settings(self): ''' Tests for config tool's Plugins->Audio Mixer tab ''' # TODO pass def test_plugin_video_input_settings(self): ''' Tests for config tool's Plugins->Video Input tab ''' # TODO pass def test_plugin_video_mixer_settings(self): ''' Tests for config tool's Plugins->Video Mixer tab ''' # TODO pass def test_plugin_output_settings(self): ''' Tests for config tool's Plugins->Output tab ''' # TODO pass def test_logger_settings(self): ''' Tests for config tool's Logger tab Needs to be tested differently since the Config instance isn't affected by changes in this tab. ''' # TODO pass def test_close_configtool(self): ''' Tests for config tool's close button ''' self.assertTrue(self.config_tool.mainWidget.isVisible()) QtTest.QTest.mouseClick(self.config_tool.mainWidget.closePushButton, Qt.Qt.LeftButton) self.assertFalse(self.config_tool.mainWidget.isVisible()) def test_file_menu_quit(self): ''' Tests for config tool's File->Quit ''' self.assertTrue(self.config_tool.isVisible()) # File->Quit self.config_tool.actionExit.trigger() self.assertFalse(self.config_tool.isVisible()) def test_help_menu_about(self): ''' Tests for config tool's Help->About ''' self.assertTrue(self.config_tool.isVisible()) # Help->About self.config_tool.actionAbout.trigger() self.assertFalse(self.config_tool.hasFocus()) self.assertTrue(self.config_tool.aboutDialog.isVisible()) # Click "Close" QtTest.QTest.mouseClick(self.config_tool.aboutDialog.closeButton, Qt.Qt.LeftButton) self.assertFalse(self.config_tool.aboutDialog.isVisible())
class TestPlugins(unittest.TestCase): def setUp(self): ''' Stardard init method: runs before each test_* method Initializes a PluginManager ''' self.profile_manager = ProfileManager(tempfile.mkdtemp()) profile = self.profile_manager.get('testing') self.plugman = PluginManager(profile) def tearDown(self): ''' Generic unittest.TestCase.tearDown() ''' shutil.rmtree(self.profile_manager._base_folder) def test_audio_input_bin(self): '''Check that audio input plugins are returning a gst.Bin object Verifies that get_audioinput_bin() is returning the proper object. ''' plugins = self.plugman.get_plugins_of_category("AudioInput") for plugin in plugins: plugin.plugin_object.load_config(self.plugman) plugin_bin = plugin.plugin_object.get_audioinput_bin() self.assertIsInstance(plugin_bin, gst.Bin, "%s did not return a gst.Bin object" % plugin.name) def test_audio_mixer_bin(self): '''Check that audio mixer plugins are returning a gst.Bin object Verifies that get_audioinput_bin() is returning the proper object. ''' plugins = self.plugman.get_plugins_of_category("AudioMixer") for plugin in plugins: plugin.plugin_object.load_config(self.plugman) plugin_bin = plugin.plugin_object.get_audiomixer_bin() self.assertIsInstance(plugin_bin, gst.Bin, "%s did not return a gst.Bin object" % plugin.name) def test_video_input_bin(self): '''Check that video input plugins are returning a gst.Bin object Verifies that get_videoinput_bin() is returning the proper object. ''' plugins = self.plugman.get_plugins_of_category("VideoInput") for plugin in plugins: plugin.plugin_object.load_config(self.plugman) if plugin.name == "Firewire Source": # There is an issue with Firewire Source in testing # Skip until this is resolved continue plugin_bin = plugin.plugin_object.get_videoinput_bin() self.assertIsInstance(plugin_bin, gst.Bin, "%s did not return a gst.Bin object" % plugin.name) def test_video_mixer_bin(self): '''Check that video mixer plugins are returning a gst.Bin object Verifies that get_videomixer_bin() is returning the proper object. ''' plugins = self.plugman.get_plugins_of_category("VideoMixer") for plugin in plugins: plugin.plugin_object.load_config(self.plugman) plugin_bin = plugin.plugin_object.get_videomixer_bin() self.assertIsInstance(plugin_bin, gst.Bin, "%s did not return a gst.Bin object" % plugin.name) def test_output_bin(self): '''Check that output plugins are returning a gst.Bin object Verifies that get_output_bin() is returning the proper object. ''' plugins = self.plugman.get_plugins_of_category("Output") for plugin in plugins: plugin.plugin_object.load_config(self.plugman) plugin_bin = plugin.plugin_object.get_output_bin() self.assertIsInstance(plugin_bin, gst.Bin, "%s did not return a gst.Bin object" % plugin.name)
class TestTalkEditorApp(unittest.TestCase): ''' Test suite to verify the functionality of the TalkEditorApp class. Tests interact like an end user (using QtTest). Expect the app to be rendered. ''' def setUp(self): ''' Stardard init method: runs before each test_* method Initializes a QtGui.QApplication and TalkEditorApp object. TalkEditorApp.show() causes the UI to be rendered. ''' self.profile_manager = ProfileManager(tempfile.mkdtemp()) profile = self.profile_manager.get('testing') config = profile.get_config('freeseer.conf', settings.FreeseerConfig, storage_args=['Global'], read_only=True) db = profile.get_database() self.app = QtGui.QApplication([]) self.talk_editor = TalkEditorApp(config, db) self.talk_editor.show() def tearDown(self): ''' Standard tear down method. Runs after each test_* method. This method closes the TalkEditorApp by clicking the "close" button ''' shutil.rmtree(self.profile_manager._base_folder) del self.app self.talk_editor.app.deleteLater() # def test_add_talk(self): # ''' # Tests a user creating a talk and adding it. # ''' # QtTest.QTest.mouseClick(self.talk_editor.editorWidget.addButton, Qt.Qt.LeftButton) # self.assertFalse(self.talk_editor.editorWidget.isVisible()) # self.assertTrue(self.talk_editor.addTalkWidget.isVisible()) # mTitle = "This is a test" # mPresenter = "Me, myself, and I" # mEvent = "0 THIS St." # mRoom = "Room 13" # # populate talk data (date and time are prepopulated) # self.talk_editor.addTalkWidget.titleLineEdit.setText(mTitle) # self.talk_editor.addTalkWidget.presenterLineEdit.setText(mPresenter) # self.talk_editor.addTalkWidget.eventLineEdit.setText(mEvent) # self.talk_editor.addTalkWidget.roomLineEdit.setText(mRoom) # # add in the talk # QtTest.QTest.mouseClick(self.talk_editor.addTalkWidget.addButton, Qt.Qt.LeftButton) # # find our talk (ensure it was added) # found = False # row_count = self.talk_editor.editorWidget.editor.model().rowCount() - 1 # while row_count >= 0 and not found: # should be at the end, but you never know # if self.talk_editor.editorWidget.editor.model().index(row_count, 1).data() == mTitle and \ # self.talk_editor.editorWidget.editor.model().index(row_count, 2).data() == mPresenter and \ # self.talk_editor.editorWidget.editor.model().index(row_count, 5).data() == mEvent and \ # self.talk_editor.editorWidget.editor.model().index(row_count, 6).data() == mRoom: # found = True # # TODO: Select this row # row_count -= 1 # self.assertTrue(found, "Couldn't find talk just inserted...") # # now delete the talk we just created # QtTest.QTest.mouseClick(self.talk_editor.editorWidget.removeButton, Qt.Qt.LeftButton) def test_file_menu_quit(self): ''' Tests TalkEditorApp's File->Quit ''' self.assertTrue(self.talk_editor.isVisible()) # File->Quit self.talk_editor.actionExit.trigger() self.assertFalse(self.talk_editor.isVisible()) def test_help_menu_about(self): ''' Tests TalkEditorApp's Help->About ''' self.assertTrue(self.talk_editor.isVisible()) # Help->About self.talk_editor.actionAbout.trigger() self.assertFalse(self.talk_editor.hasFocus()) self.assertTrue(self.talk_editor.aboutDialog.isVisible()) # Click "Close" QtTest.QTest.mouseClick(self.talk_editor.aboutDialog.closeButton, Qt.Qt.LeftButton) self.assertFalse(self.talk_editor.aboutDialog.isVisible())
def plugin_manager(tmpdir): """Constructs a plugin manager using a fake profile with a temporary directory.""" profile_manager = ProfileManager(str(tmpdir)) profile = profile_manager.get('testing') return PluginManager(profile)
class TestConfig(unittest.TestCase): def setUp(self): ''' Stardard init method: runs before each test_* method Initializes a PluginManager ''' self.profile_manager = ProfileManager(tempfile.mkdtemp()) self.profile = self.profile_manager.get('testing') self.config = self.profile.get_config('freeseer.conf', settings.FreeseerConfig, ['Global'], read_only=False) def tearDown(self): ''' Generic unittest.TestCase.tearDown() ''' shutil.rmtree(self.profile_manager._base_folder) def test_save(self): ''' Tests that the config file was created after being saved. ''' filepath = self.profile.get_filepath('freeseer.conf') self.config.save() self.assertTrue(os.path.exists(filepath)) def test_schema(self): """Tests that the settings Config returns the correct schema based on all its options.""" settings_schema = { 'type': 'object', 'properties': { 'videodir': { 'default': '~/Videos', 'type': 'string', }, 'auto_hide': { 'default': False, 'type': 'boolean', }, 'enable_audio_recording': { 'default': True, 'type': 'boolean', }, 'enable_video_recording': { 'default': True, 'type': 'boolean', }, 'videomixer': { 'default': 'Video Passthrough', 'type': 'string', }, 'video_quality': { 'default': 3, 'type': 'integer', }, 'audiomixer': { 'default': 'Audio Passthrough', 'type': 'string', }, 'audio_quality': { 'default': 3, 'type': 'integer', }, 'record_to_file': { 'default': True, 'type': 'boolean', }, 'record_to_file_plugin': { 'default': 'Ogg Output', 'type': 'string', }, 'record_to_stream': { 'default': False, 'type': 'boolean', }, 'record_to_stream_plugin': { 'default': 'RTMP Streaming', 'type': 'string', }, 'audio_feedback': { 'default': False, 'type': 'boolean', }, 'video_preview': { 'default': True, 'type': 'boolean', }, 'default_language': { 'default': 'tr_en_US.qm', 'type': 'string', }, }, } self.assertDictEqual(self.config.schema(), settings_schema) def test_schema_validate(self): """Tests that schemas validate valid configs.""" config = { 'default_language': 'tr_en_US.qm', 'auto_hide': True } self.assertIsNone(validate(config, self.config.schema())) def test_schema_invalidate(self): """Tests that schemas invalidate an invalid config.""" config = { 'default_language': False, 'auto_hide': 5 } self.assertRaises(ValidationError, validate, config, self.config.schema())
class TestServerApp(unittest.TestCase): ''' Test cases for Server. ''' def setUp(self): ''' Stardard init method: runs before each test_* method ''' server.app.config['TESTING'] = True server.app.storage_file_path = "test_storage_file" self.app = server.app.test_client() self.recording = server.app.blueprints['recording'] # token call to fire configuration logic self.app.get('/recordings') print self.recording.record_config.videodir self.profile_manager = ProfileManager(tempfile.mkdtemp()) self.temp_video_dir = tempfile.mkdtemp() self.recording.record_config.videodir = self.temp_video_dir self.recording.record_profile = self.profile_manager.get('testing') self.recording.record_config = self.recording.record_profile.get_config('freeseer.conf', settings.FreeseerConfig, ['Global'], read_only=True) self.recording.record_plugin_manager = PluginManager(self.recording.record_profile) self.recording.media_dict = {} # mock media self.mock_media_1 = MockMedia() self.mock_media_2 = MockMedia() self.test_media_dict_1 = {} filepath1 = os.path.join(self.recording.record_config.videodir, 'mock_media_1') filepath2 = os.path.join(self.recording.record_config.videodir, 'mock_media_1') self.test_media_dict_1[1] = {'media': self.mock_media_1, 'filename': 'mock_media_1', 'filepath': filepath1} self.test_media_dict_1[2] = {'media': self.mock_media_2, 'filename': 'mock_media_2', 'filepath': filepath2} def tearDown(self): ''' Generic unittest.TestCase.tearDown() ''' shutil.rmtree(self.profile_manager._base_folder) shutil.rmtree(self.temp_video_dir) del self.app def test_get_all_recordings_empty_media_dict(self): ''' Tests GET request retrieving all recordings with from an empty media dict ''' response = self.app.get('/recordings') response_data = json.loads(response.data) self.assertTrue('recordings' in response_data) self.assertTrue(response_data['recordings'] == []) def test_get_nonexistent_recording_id(self): ''' Tests GET request retrieving non-existent recording ''' response = self.app.get('/recordings/1') response_data = json.loads(response.data) self.assertEqual(response_data['error_message'], "recording id could not be found") self.assertEqual(response_data['error_code'], 404) self.assertEqual(response.status_code, 404) def test_get_all_recordings(self): ''' Tests GET request all recordings with 2 entries in media dict ''' self.recording.media_dict = self.test_media_dict_1 response = self.app.get('/recordings') response_data = json.loads(response.data) self.assertTrue('recordings' in response_data) self.assertTrue(response_data['recordings'] == [1, 2]) def test_get_recording_id(self): ''' Tests GET request specific valid recording ''' self.recording.media_dict = self.test_media_dict_1 response = self.app.get('/recordings/1') response_data = json.loads(response.data) self.assertTrue('recordings' not in response_data) self.assertTrue('filename' in response_data) self.assertTrue('filesize' in response_data) self.assertTrue('status' in response_data) self.assertEqual(response.status_code, 200) self.assertEqual(response_data['filename'], 'mock_media_1') self.assertEqual(response_data['filesize'], 'NA') self.assertEqual(response_data['id'], 1) self.assertEqual(response_data['status'], 'NULL') def test_get_invalid_recording_id(self): ''' Tests GET request with an invalid id (a non integer id) ''' self.recording.media_dict = self.test_media_dict_1 response = self.app.get('/recordings/abc') self.assertEqual(response.status_code, 404) response = self.app.get('/recordings/1.0') self.assertEqual(response.status_code, 404) def test_patch_no_id(self): ''' Tests a PATCH request without a recording id ''' response = self.app.patch('/recordings') self.assertEqual(response.status_code, 405) def test_patch_nonexistant_id(self): ''' Tests a PATCH request with non-existant recording id ''' self.recording.media_dict = self.test_media_dict_1 response = self.app.patch('/recordings/100') self.assertEqual(response.status_code, 404) def test_patch_no_command(self): ''' Tests a PATCH request without a command ''' self.recording.media_dict = self.test_media_dict_1 response = self.app.patch('/recordings/1') self.assertEqual(response.status_code, 400) def test_patch_invalid_command(self): ''' Tests a Patch request with an invalid command ''' self.recording.media_dict = self.test_media_dict_1 data_to_send = {'command': 'invalid command'} response = self.app.patch('/recordings/1', data=data_to_send) self.assertEqual(response.status_code, 400) def test_patch_start(self): ''' Tests a Patch request to start a recording ''' self.mock_media_1.current_state = Multimedia.NULL self.recording.media_dict = self.test_media_dict_1 data_to_send = {'command': 'start'} response = self.app.patch('/recordings/1', data=data_to_send) self.assertEqual(response.status_code, 200) self.assertEqual(self.mock_media_1.num_times_record_called, 1) self.mock_media_1.num_times_record_called = 0 self.mock_media_1.current_state = Multimedia.PAUSE self.recording.media_dict = self.test_media_dict_1 data_to_send = {'command': 'start'} response = self.app.patch('/recordings/1', data=data_to_send) self.assertEqual(response.status_code, 200) self.assertEqual(self.mock_media_1.num_times_record_called, 1) def test_patch_start_invalid(self): ''' Tests a Patch request to start a recording with an invalid media state ''' self.mock_media_1.current_state = Multimedia.STOP self.recording.media_dict = self.test_media_dict_1 data_to_send = {'command': 'start'} response = self.app.patch('/recordings/1', data=data_to_send) self.assertEqual(response.status_code, 400) self.assertEqual(self.mock_media_1.num_times_record_called, 0) self.mock_media_1.num_times_record_called = 0 self.mock_media_1.current_state = Multimedia.RECORD self.recording.media_dict = self.test_media_dict_1 data_to_send = {'command': 'start'} response = self.app.patch('/recordings/1', data=data_to_send) self.assertEqual(response.status_code, 400) self.assertEqual(self.mock_media_1.num_times_record_called, 0) def test_patch_pause(self): ''' Tests a Patch request to pause a recording ''' self.mock_media_1.current_state = Multimedia.RECORD self.recording.media_dict = self.test_media_dict_1 data_to_send = {'command': 'pause'} response = self.app.patch('/recordings/1', data=data_to_send) self.assertEqual(response.status_code, 200) self.assertEqual(self.mock_media_1.num_times_pause_called, 1) def test_patch_pause_invalid(self): ''' Tests a Patch request to pause a recording with an invalid media state ''' self.mock_media_1.current_state = Multimedia.NULL self.recording.media_dict = self.test_media_dict_1 data_to_send = {'command': 'pause'} response = self.app.patch('/recordings/1', data=data_to_send) self.assertEqual(response.status_code, 400) self.assertEqual(self.mock_media_1.num_times_pause_called, 0) self.mock_media_1.current_state = Multimedia.PAUSE self.recording.media_dict = self.test_media_dict_1 data_to_send = {'command': 'pause'} response = self.app.patch('/recordings/1', data=data_to_send) self.assertEqual(response.status_code, 400) self.assertEqual(self.mock_media_1.num_times_pause_called, 0) self.mock_media_1.current_state = Multimedia.STOP self.recording.media_dict = self.test_media_dict_1 data_to_send = {'command': 'pause'} response = self.app.patch('/recordings/1', data=data_to_send) self.assertEqual(response.status_code, 400) self.assertEqual(self.mock_media_1.num_times_pause_called, 0) def test_patch_stop(self): ''' Tests a Patch request to stop a recording ''' self.mock_media_1.current_state = Multimedia.RECORD self.recording.media_dict = self.test_media_dict_1 data_to_send = {'command': 'stop'} response = self.app.patch('/recordings/1', data=data_to_send) self.assertEqual(response.status_code, 200) self.assertEqual(self.mock_media_1.num_times_stop_called, 1) self.mock_media_1.num_times_stop_called = 0 self.mock_media_1.current_state = Multimedia.PAUSE self.recording.media_dict = self.test_media_dict_1 data_to_send = {'command': 'stop'} response = self.app.patch('/recordings/1', data=data_to_send) self.assertEqual(response.status_code, 200) self.assertEqual(self.mock_media_1.num_times_stop_called, 1) def test_patch_stop_invalid(self): ''' Tests a Patch request to stop a recording with an invalid media state ''' self.mock_media_1.current_state = Multimedia.STOP self.recording.media_dict = self.test_media_dict_1 data_to_send = {'command': 'stop'} response = self.app.patch('/recordings/1', data=data_to_send) self.assertEqual(response.status_code, 400) self.assertEqual(self.mock_media_1.num_times_stop_called, 0) self.mock_media_1.num_times_stop_called = 0 self.mock_media_1.current_state = Multimedia.NULL self.recording.media_dict = self.test_media_dict_1 data_to_send = {'command': 'stop'} response = self.app.patch('/recordings/1', data=data_to_send) self.assertEqual(response.status_code, 400) self.assertEqual(self.mock_media_1.num_times_stop_called, 0) def test_post_no_filename(self): ''' Tests a POST request without a filename ''' response = self.app.post('/recordings') self.assertEqual(response.status_code, 400) def test_post_empty_filename(self): ''' Tests a POST request with an empty filename ''' data_to_send = {'filename': ''} response = self.app.post('/recordings', data=data_to_send) self.assertEqual(response.status_code, 400) def test_post_invalid_filename(self): ''' Tests a POST request with an invalid filename ''' data_to_send = {'filename': 'abc/123'} response = self.app.post('/recordings', data=data_to_send) self.assertEqual(response.status_code, 400) def test_post(self): ''' Tests a regular POST request ''' self.assertTrue(len(self.recording.media_dict.keys()) == 0) data_to_send = {'filename': 'test'} response = self.app.post('/recordings', data=data_to_send) self.assertTrue(len(self.recording.media_dict.keys()) == 1) self.assertEqual(response.status_code, 201) self.assertEqual(self.recording.media_dict.keys(), [1]) self.assertEqual(self.recording.media_dict[1]['filename'], 'test.ogg') def test_delete_no_recording_id(self): ''' Tests a DELETE request without a provided recording id ''' response = self.app.delete('/recordings') self.assertEqual(response.status_code, 405) def test_delete_nonexistant_recording_id(self): ''' Tests a DELETE request with a recording id that doesn't exist ''' response = self.app.delete('/recordings/100') self.assertEqual(response.status_code, 404) def test_delete_invalid_recording_id(self): ''' Tests a DELETE request with an invalid recording id ''' response = self.app.delete('/recordings/abc') self.assertEqual(response.status_code, 404) response = self.app.delete('/recordings/1.0') self.assertEqual(response.status_code, 404) def test_delete_in_progress_recording(self): ''' Tests a DELETE request for a recording that is paused or in progress ''' self.recording.media_dict = self.test_media_dict_1 # delete a recording that is in the middle of recording self.mock_media_1.current_state = Multimedia.RECORD response = self.app.delete('/recordings/1') self.assertEqual(response.status_code, 204) self.assertEqual(self.mock_media_1.num_times_stop_called, 1) self.assertEqual(self.recording.media_dict.keys(), [2]) # delete a recording that is paused self.mock_media_2.current_state = Multimedia.PAUSE response = self.app.delete('/recordings/2') self.assertEqual(response.status_code, 204) self.assertEqual(self.mock_media_2.num_times_stop_called, 1) self.assertEqual(self.recording.media_dict.keys(), []) def test_delete_recording_id_and_file(self): ''' Tests a DELETE request where the recording has a specified file ''' # setup - create the file to be deleted file_base_name = 'testDeleteFile' file_to_delete = file_base_name file_to_delete_path = os.path.join(self.recording.record_config.videodir, file_to_delete) counter = 1 while os.path.isfile(file_to_delete_path): file_to_delete = file_base_name + str(counter) file_to_delete_path = os.path.join(self.recording.record_config.videodir, file_to_delete) counter += 1 test_file = open(file_to_delete_path, 'a') test_file.close() # assert the file exists self.assertTrue(os.path.isfile(file_to_delete_path)) # setup - set the file as the file for the Media instance self.recording.media_dict[1] = {'media': self.mock_media_1, 'filename': file_to_delete, 'filepath': file_to_delete_path} response = self.app.delete('/recordings/1') self.assertEqual(response.status_code, 204) self.assertEqual(self.recording.media_dict.keys(), []) # assert the file no longer exists self.assertFalse(os.path.isfile(file_to_delete_path))
class TestProfileManager(unittest.TestCase): """Tests the ProfileManager.""" def setUp(self): self.profiles_path = tempfile.mkdtemp() self.profile_manager = ProfileManager(self.profiles_path) def tearDown(self): shutil.rmtree(self.profiles_path) def test_get(self): """Tests that get returns a Profile instance.""" profile = self.profile_manager.get('testing') self.assertIsInstance(profile, Profile) def test_get_non_existent(self): """Test for non-existent profile.""" self.assertRaises(ProfileDoesNotExist, self.profile_manager.get, 'non-existent_profile', create_if_needed=False) def test_get_non_existent_creates(self): """Test that get creates non-existent profile if create_if_needed=True.""" self.assertRaises(ProfileDoesNotExist, self.profile_manager.get, 'non-existent_profile', create_if_needed=False) profile = self.profile_manager.get('non_existent_profile') self.assertIsInstance(profile, Profile) def test_get_cache(self): """Tests that get caching is working as expected.""" profile1 = self.profile_manager.get('testing') profile2 = self.profile_manager.get('testing') self.assertEqual(profile1, profile2) def test_list_profiles(self): """Tests that list_profiles returns all profiles on file.""" self.profile_manager.create('testing1') self.profile_manager.create('testing2') profiles = self.profile_manager.list_profiles() self.assertItemsEqual(['testing1', 'testing2'], profiles) def test_create_profile(self): """Tests that create_profile returns an instance of Profile..""" profile = self.profile_manager.create('testing1') self.assertIsInstance(profile, Profile) def test_create_profile_existing(self): """Tests that exception is raised if trying to overwrite existing profile.""" self.profile_manager.create('testing1') self.assertRaises(ProfileAlreadyExists, self.profile_manager.create, 'testing1') def test_create_profile_caches(self): """Tests that create_profile adds the new Profile instance to cache.""" self.assertNotIn('testing1', self.profile_manager._cache) self.profile_manager.create('testing1') self.assertIn('testing1', self.profile_manager._cache) def test_delete_profile_existing(self): """Tests that delete_profile deletes the profile from cache and file.""" self.profile_manager.create('testing1') self.profile_manager.delete('testing1') self.assertRaises(ProfileDoesNotExist, self.profile_manager.get, 'testing1', create_if_needed=False) def test_delete_profile_non_existing(self): """Non-existent profiles can't be deleted.""" self.assertRaises(ProfileDoesNotExist, self.profile_manager.delete, 'testing')
class TestRecordApp(unittest.TestCase): ''' Test suite to verify the functionality of the RecordApp class. Tests interact like an end user (using QtTest). Expect the app to be rendered. ''' def setUp(self): ''' Stardard init method: runs before each test_* method Initializes a QtGui.QApplication and RecordApp object. RecordApp.show() causes the UI to be rendered. ''' self.profile_manager = ProfileManager(tempfile.mkdtemp()) profile = self.profile_manager.get('testing') config = profile.get_config('freeseer.conf', settings.FreeseerConfig, storage_args=['Global'], read_only=False) self.app = QtGui.QApplication([]) self.record_app = RecordApp(profile, config) self.record_app.show() def tearDown(self): ''' Generic unittest.TestCase.tearDown() ''' shutil.rmtree(self.profile_manager._base_folder) self.record_app.actionExit.trigger() self.app.deleteLater() def test_init_conditions(self): ''' Tests the initial state of the RecordApp ''' # TODO pass def test_standby_to_recording(self): ''' Tests pre and post conditions when entering Standby, Record, Stop modes ''' # TODO: ROADBLOCK # The Gstreamer takes a while to initialize the preview. # Due to this, when the unitest clicks "Record", the preview has not yet been initialized # and Freeseer freezes # It is not trivial or clear how to detect whether or not the preview has loaded # It turns out that even if the state is Multimedia.PAUSE, the preview has not quite loaded # self.assertTrue(self.record_app.mainWidget.standbyPushButton.isVisible(), "[PRE STANDBY] Expected Standby button to be visible") # self.assertFalse(self.record_app.mainWidget.recordPushButton.isVisible(), "[PRE STANDBY] Expected Record button to be invisible") # Click the Standby button with the left mouse button # QtTest.QTest.mouseClick(self.record_app.mainWidget.standbyPushButton, Qt.Qt.LeftButton) # self.assertFalse(self.record_app.mainWidget.standbyPushButton.isVisible(), "[STANDBY] Expected Standby button to be invisible") # self.assertTrue(self.record_app.mainWidget.recordPushButton.isVisible(), "[STANDBY] Expected Record button to be visible") # TODO: Check if preview has loaded # Click the Record button with the left mouse button # QtTest.QTest.mouseClick(self.record_app.mainWidget.recordPushButton, Qt.Qt.LeftButton) # self.assertFalse(self.record_app.mainWidget.standbyPushButton.isVisible(), "[RECORDING] Expected Standby button to be invisible") # self.assertTrue(self.record_app.mainWidget.recordPushButton.isVisible(), "[RECORDING] Expected Record button to be visible") # self.assertTrue(self.record_app.mainWidget.recordPushButton.text() == self.record_app.stopString, "[RECORDING] Incorrect button text for this phase") # Click the Record button again in 5 seconds with the left mouse button # QtTest.QTest.mouseClick(self.record_app.mainWidget.recordPushButton, Qt.Qt.LeftButton) def test_reset_timer(self): ''' Tests RecordApp.reset_timer() ''' # set our own values self.record_app.time_minutes = 15 self.record_app.time_seconds = 30 # reset timer and check that the values are 0 self.record_app.reset_timer() self.assertTrue(self.record_app.time_minutes == 0 and self.record_app.time_seconds == 0) def test_file_menu_quit(self): ''' Tests RecordApp's File->Quit ''' self.assertTrue(self.record_app.isVisible()) # File->Menu self.record_app.actionExit.trigger() self.assertFalse(self.record_app.isVisible()) def test_help_menu_about(self): ''' Tests RecordApp's Help->About ''' self.assertTrue(self.record_app.isVisible()) # Help->About self.record_app.actionAbout.trigger() self.assertFalse(self.record_app.hasFocus()) self.assertTrue(self.record_app.aboutDialog.isVisible()) # Click "Close" QtTest.QTest.mouseClick(self.record_app.aboutDialog.closeButton, Qt.Qt.LeftButton) self.assertFalse(self.record_app.aboutDialog.isVisible())
class TestUtil(unittest.TestCase): def setUp(self): self.config_dir = tempfile.mkdtemp() self.profile_manager = ProfileManager(os.path.join(self.config_dir, 'profiles')) def tearDown(self): shutil.rmtree(self.config_dir) def test_reset(self): """Test Resetting the configuration directory""" profile = self.profile_manager.get('default') open(profile.get_filepath('freeseer.conf'), 'w+') open(profile.get_filepath('plugin.conf'), 'w+') open(profile.get_filepath('presentations.db'), 'w+') self.assertTrue(os.path.exists(self.config_dir)) with mock.patch('__builtin__.raw_input', return_value='yes'): reset(self.config_dir) self.assertFalse(os.path.exists(self.config_dir)) # recreate the config_dir for tearDown() # while we're at it test that passing a none "yes" answer results in directory not removed os.makedirs(self.config_dir) with mock.patch('__builtin__.raw_input', return_value='no'): reset(self.config_dir) self.assertTrue(os.path.exists(self.config_dir)) def test_reset_configuration(self): """Test Resetting configuration files""" # Test resetting the default profile (no profile arguments passed) profile = self.profile_manager.get('default') open(profile.get_filepath('freeseer.conf'), 'w+') open(profile.get_filepath('plugin.conf'), 'w+') self.assertTrue(os.path.exists(profile.get_filepath('plugin.conf'))) self.assertTrue(os.path.exists(profile.get_filepath('freeseer.conf'))) reset_configuration(self.config_dir) self.assertFalse(os.path.exists(profile.get_filepath('plugin.conf'))) self.assertFalse(os.path.exists(profile.get_filepath('freeseer.conf'))) # Test resetting a non-default profile profile = self.profile_manager.get('not-default') open(profile.get_filepath('freeseer.conf'), 'w+') open(profile.get_filepath('plugin.conf'), 'w+') self.assertTrue(os.path.exists(profile.get_filepath('plugin.conf'))) self.assertTrue(os.path.exists(profile.get_filepath('freeseer.conf'))) reset_configuration(self.config_dir, 'not-default') self.assertFalse(os.path.exists(profile.get_filepath('plugin.conf'))) self.assertFalse(os.path.exists(profile.get_filepath('freeseer.conf'))) def test_reset_database(self): """Test Resetting database file""" # Test resetting the default profile (no profile arguments passed) profile = self.profile_manager.get('default') open(profile.get_filepath('presentations.db'), 'w+') self.assertTrue(os.path.exists(profile.get_filepath('presentations.db'))) reset_database(self.config_dir) self.assertFalse(os.path.exists(profile.get_filepath('presentations.db'))) # Test resetting a non-default profile profile = self.profile_manager.get('not-default') open(profile.get_filepath('presentations.db'), 'w+') self.assertTrue(os.path.exists(profile.get_filepath('presentations.db'))) reset_database(self.config_dir, 'not-default') self.assertFalse(os.path.exists(profile.get_filepath('presentations.db')))
def plugin_manager(tmpdir): """Constructs a plugin manager using a fake profile with a temporary directory.""" profile_manager = ProfileManager(str(tmpdir)) profile = profile_manager.get('testing') return PluginManager(profile)
class TestConfigToolApp(unittest.TestCase): """ Test suite to verify the functionality of the ConfigToolApp class. Tests interact like an end user (using QtTest). Expect the app to be rendered. NOTE: most tests will follow this format: 1. Get current config setting 2. Make UI change (config change happens immediately) 3. Reparse config file 4. Test that has changed (using the previous and new) """ def setUp(self): """ Stardard init method: runs before each test_* method Initializes a QtGui.QApplication and ConfigToolApp object. ConfigToolApp.show() causes the UI to be rendered. """ self.profile_manager = ProfileManager(tempfile.mkdtemp()) profile = self.profile_manager.get('testing') config = profile.get_config('freeseer.conf', settings.FreeseerConfig, storage_args=['Global'], read_only=False) self.app = QtGui.QApplication([]) self.config_tool = ConfigToolApp(profile, config) self.config_tool.show() def tearDown(self): """ Standard tear down method. Runs after each test_* method. This method closes the ConfigToolApp by clicking the "close" button """ QtTest.QTest.mouseClick(self.config_tool.mainWidget.closePushButton, Qt.Qt.LeftButton) shutil.rmtree(self.profile_manager._base_folder) del self.config_tool.app self.app.deleteLater() def test_default_widget(self): self.assertEqual(self.config_tool.currentWidget, self.config_tool.generalWidget) def check_combobox_corner_cases_frontend(self, combobox_widget): """ Tests that a given QtComboBox has: - a default selected item - does not blow up on the minimum and maximum index item in the combobox list """ index = combobox_widget.currentIndex() combobox_widget.setCurrentIndex(0) self.assertEquals(combobox_widget.currentIndex(), 0) self.assertIsNot(combobox_widget.currentText(), None) combobox_widget.setCurrentIndex(combobox_widget.count() - 1) self.assertEquals(combobox_widget.currentIndex(), (combobox_widget.count() - 1)) self.assertIsNot(combobox_widget.currentText(), None) combobox_widget.setCurrentIndex(index) self.assertEquals(combobox_widget.currentIndex(), index) self.assertIsNot(combobox_widget.currentText(), None) def select_general_settings_tab(self): # Select "General" tab item = self.config_tool.mainWidget.optionsTreeWidget.findItems(self.config_tool.generalString, QtCore.Qt.MatchExactly) self.assertFalse(not item or item[0] is None) self.config_tool.mainWidget.optionsTreeWidget.setCurrentItem(item[0]) QtTest.QTest.mouseClick(self.config_tool.mainWidget.optionsTreeWidget, Qt.Qt.LeftButton) def test_general_settings_checkbox(self): """ Test the config tool's General Tab auto-hide system tray icon checkbox with simulated user input """ self.select_general_settings_tab() # Test disabled checkbox self.config_tool.currentWidget.autoHideCheckBox.setChecked(False) self.assertEqual(self.config_tool.currentWidget.autoHideCheckBox.checkState(), QtCore.Qt.Unchecked) self.assertFalse(self.config_tool.config.auto_hide) # Test enabled checkbox self.config_tool.currentWidget.autoHideCheckBox.setChecked(True) self.assertEqual(self.config_tool.currentWidget.autoHideCheckBox.checkState(), QtCore.Qt.Checked) self.assertTrue(self.config_tool.config.auto_hide) def test_general_settings_dropdown_menu(self): """ Test the config tool's General Tab language selection drop down menu with simulated user input """ self.select_general_settings_tab() # Test dropdown menu language_combo_box = self.config_tool.generalWidget.languageComboBox self.check_combobox_corner_cases_frontend(language_combo_box) QtTest.QTest.keyClick(language_combo_box, QtCore.Qt.Key_PageUp) # Test simulated user interaction with drop down list for i in range(language_combo_box.count() - 2): last_language = self.config_tool.config.default_language QtTest.QTest.keyClick(language_combo_box, QtCore.Qt.Key_Down) current_language = self.config_tool.config.default_language self.assertNotEqual(last_language, current_language) # Test frontend constants self.assertNotEqual(language_combo_box.findText('Deutsch'), -1) # Assert there are multiple languages in the menu self.assertNotEqual(language_combo_box.findText('English'), -1) self.assertNotEqual(language_combo_box.findText('Nederlands'), -1) def test_general_settings_help_reset(self): """ Test the config tool's General Tab help link and reset button with simulated user input """ self.select_general_settings_tab() # Test that Help us translate tries to open a web url. QtGui.QDesktopServices.openUrl = MagicMock(return_value=None) self.config_tool.open_translate_url() QtGui.QDesktopServices.openUrl.assert_called_with( QtCore.QUrl("http://freeseer.readthedocs.org/en/latest/contribute/translation.html") ) # Reset # The reset test should set the backend config_tool values, simulate a user clicking through the reset popup and # verify that the backend config_tool values have been set to defaults. # TODO: FIXME. Related to gh#631. The buttons on the dialog cause segfaults in the test environment and prevent # the test from being implemented at the present time. # self.config_tool.confirm_reset() def select_recording_tab(self): """ Helper function used to open up the recording tab for recording tab related tests """ item = self.config_tool.mainWidget.optionsTreeWidget.findItems(self.config_tool.avString, QtCore.Qt.MatchExactly) self.assertFalse(not item or item[0] is None) self.config_tool.mainWidget.optionsTreeWidget.setCurrentItem(item[0]) QtTest.QTest.mouseClick(self.config_tool.mainWidget.optionsTreeWidget, Qt.Qt.LeftButton) self.assertEqual(self.config_tool.currentWidget, self.config_tool.avWidget) def test_recording_settings_file(self): """ Simulates a user interacting with the config tool record to file settings. """ self.select_recording_tab() # Test disabled checkbox self.config_tool.currentWidget.fileGroupBox.setChecked(False) self.assertFalse(self.config_tool.config.record_to_file) # Test enabled checkbox self.config_tool.currentWidget.fileGroupBox.setChecked(True) self.assertTrue(self.config_tool.config.record_to_file) self.assertIn(self.config_tool.config.record_to_file_plugin, ['Ogg Output', 'WebM Output', 'Raw Output']) # Test combo box file_combo_box = self.config_tool.avWidget.fileComboBox self.check_combobox_corner_cases_frontend(file_combo_box) QtTest.QTest.keyClick(file_combo_box, QtCore.Qt.Key_PageUp) # Simulate user input to test backend and frontend for i in range(file_combo_box.count() - 2): last_plugin = self.config_tool.config.record_to_file_plugin QtTest.QTest.keyClick(file_combo_box, QtCore.Qt.Key_Down) current_plugin = self.config_tool.config.record_to_file_plugin self.assertNotEqual(last_plugin, current_plugin) # Test frontend text values self.assertNotEqual(file_combo_box.findText('Ogg Output'), -1) self.assertNotEqual(file_combo_box.findText('WebM Output'), -1) self.assertNotEqual(file_combo_box.findText('Raw Output'), -1) def test_recording_settings_stream(self): """ Simulates a user interacting with the config tool record to output stream settings. """ self.select_recording_tab() # Test disabled checkbox self.config_tool.currentWidget.streamGroupBox.setChecked(False) self.assertFalse(self.config_tool.config.record_to_stream) # Test enabled checkbox self.config_tool.currentWidget.streamGroupBox.setChecked(True) self.assertTrue(self.config_tool.config.record_to_stream) # Test combo box stream_combo_box = self.config_tool.avWidget.streamComboBox self.check_combobox_corner_cases_frontend(stream_combo_box) QtTest.QTest.keyClick(stream_combo_box, QtCore.Qt.Key_PageUp) # Simulate user input to test backend and frontend for i in range(stream_combo_box.count() - 2): last_plugin = self.config_tool.plugman.get_plugin_by_name(stream_combo_box.currentText(), 'Output') QtTest.QTest.keyClick(stream_combo_box, QtCore.Qt.Key_Down) current_plugin = self.config_tool.plugman.get_plugin_by_name(stream_combo_box.currentText(), 'Output') self.assertNotEqual(last_plugin, current_plugin) # Test frontend text values self.assertNotEqual(stream_combo_box.findText('RTMP Streaming'), -1) self.assertNotEqual(stream_combo_box.findText('Ogg Icecast'), -1) def test_recording_settings_video_input(self): """ Simulates a user interacting with the config tool record to video input setting. """ self.select_recording_tab() # Test disabled checkbox self.config_tool.currentWidget.videoGroupBox.setChecked(False) self.assertFalse(self.config_tool.config.enable_video_recording) # Test enabled checkbox self.config_tool.currentWidget.videoGroupBox.setChecked(True) self.assertTrue(self.config_tool.config.enable_video_recording) self.assertIn(self.config_tool.config.videomixer, ['Video Passthrough', 'Picture-In-Picture']) # Test combo box video_mixer_combo_box = self.config_tool.avWidget.videoMixerComboBox self.check_combobox_corner_cases_frontend(video_mixer_combo_box) QtTest.QTest.keyClick(video_mixer_combo_box, QtCore.Qt.Key_PageUp) # Simulate user to test backend/frontend for i in range(video_mixer_combo_box.count() - 2): last_plugin = self.config_tool.videomixer QtTest.QTest.keyClick(video_mixer_combo_box, QtCore.Qt.Key_Down) current_plugin = self.config_tool.videomixer self.assertNotEqual(last_plugin, current_plugin) # Test frontend text values self.assertTrue(video_mixer_combo_box.findText('Video Passthrough') != -1) self.assertTrue(video_mixer_combo_box.findText('Picture-In-Picture') != -1) def test_recording_settings_audio_input(self): """ Simulates a user interacting with the config tool record to audio input settings. """ self.select_recording_tab() # Test disabled checkbox self.config_tool.currentWidget.audioGroupBox.setChecked(False) self.assertFalse(self.config_tool.config.enable_audio_recording) # Test enabled checkbox self.config_tool.currentWidget.audioGroupBox.setChecked(True) self.assertTrue(self.config_tool.config.enable_audio_recording) self.assertIn(self.config_tool.config.audiomixer, ['Audio Passthrough', 'Multiple Audio Inputs']) # Test combo box audio_mixer_combo_box = self.config_tool.avWidget.audioMixerComboBox self.check_combobox_corner_cases_frontend(audio_mixer_combo_box) QtTest.QTest.keyClick(audio_mixer_combo_box, QtCore.Qt.Key_PageUp) # Simulate user to test backend/frontend for i in range(audio_mixer_combo_box.count() - 2): last_plugin = self.config_tool.audiomixer QtTest.QTest.keyClick(audio_mixer_combo_box, QtCore.Qt.Key_Down) current_plugin = self.config_tool.audiomixer self.assertNotEqual(last_plugin, current_plugin) # Test frontend text values self.assertNotEqual(audio_mixer_combo_box.findText('Audio Passthrough'), -1) self.assertNotEqual(audio_mixer_combo_box.findText('Multiple Audio Inputs'), -1) def test_plugin_settings(self): """ Simulate a user going through the list of plugins in the plugin settings page of the config tool. This test builds a dictionary value based on a traversal of the QTreeWidget that contains the plugins displayed in the GUI. The dictionary is then used to assert that plugins exist in the appropriate categories. This test also uses a map to relate the GUI's category names to the backend's category names since the two differ. """ item = self.config_tool.mainWidget.optionsTreeWidget.findItems(self.config_tool.pluginsString, QtCore.Qt.MatchExactly) self.assertFalse(not item or item[0] is None) self.config_tool.mainWidget.optionsTreeWidget.setCurrentItem(item[0]) QtTest.QTest.mouseClick(self.config_tool.mainWidget.optionsTreeWidget, Qt.Qt.LeftButton) self.assertEqual(self.config_tool.currentWidget, self.config_tool.pluginWidget) # GUI names categories are different than the backend. Define a translation from GUI -> backend gui_category_to_backend_category = { 'Audio Input': 'AudioInput', 'Audio Mixer': 'AudioMixer', 'Video Input': 'VideoInput', 'Video Mixer': 'VideoMixer', 'Output': 'Output', 'Input': 'Importer' } QtTest.QTest.keyClick(self.config_tool.pluginWidget.list, QtCore.Qt.Key_PageUp) root = self.config_tool.pluginWidget.list.invisibleRootItem() plugin_category = {} # A dictionary of plugin -> category for category_index in range(root.childCount()): category = str(self.config_tool.pluginWidget.list.currentItem().text(0)) QtTest.QTest.keyClick(self.config_tool.pluginWidget.list, QtCore.Qt.Key_Down) for plugin_index in range(root.child(category_index).childCount()): plugin_name = str(self.config_tool.pluginWidget.list.currentItem().text(0)) plugin_category[plugin_name] = gui_category_to_backend_category[category] QtTest.QTest.keyClick(self.config_tool.pluginWidget.list, QtCore.Qt.Key_Down) # Assert expected categories exist. self.assertIn('AudioInput', plugin_category.values()) self.assertIn('AudioMixer', plugin_category.values()) self.assertIn('VideoInput', plugin_category.values()) self.assertIn('VideoMixer', plugin_category.values()) self.assertIn('Output', plugin_category.values()) self.assertIn('Importer', plugin_category.values()) for category in ['AudioInput', 'AudioMixer', 'VideoInput', 'VideoMixer', 'Output', 'Importer']: for plugin in self.config_tool.get_plugins(category): self.assertIn(plugin.plugin_object.name, plugin_category) self.assertEqual(plugin_category[plugin.plugin_object.name], category) self.assertEqual(category, plugin.plugin_object.CATEGORY) def test_logger_settings(self): """ Tests for config tool's Logger tab Needs to be tested differently since the Config instance isn't affected by changes in this tab. """ # TODO pass def test_close_configtool(self): """ Tests for config tool's close button """ self.assertTrue(self.config_tool.mainWidget.isVisible()) QtTest.QTest.mouseClick(self.config_tool.mainWidget.closePushButton, Qt.Qt.LeftButton) self.assertFalse(self.config_tool.mainWidget.isVisible()) def test_file_menu_quit(self): """ Tests for config tool's File->Quit """ self.assertTrue(self.config_tool.isVisible()) # File->Quit self.config_tool.actionExit.trigger() self.assertFalse(self.config_tool.isVisible()) def test_help_menu_about(self): """ Tests for config tool's Help->About """ self.assertTrue(self.config_tool.isVisible()) # Help->About self.config_tool.actionAbout.trigger() self.assertFalse(self.config_tool.hasFocus()) self.assertTrue(self.config_tool.aboutDialog.isVisible()) # Click "Close" QtTest.QTest.mouseClick(self.config_tool.aboutDialog.closeButton, Qt.Qt.LeftButton) self.assertFalse(self.config_tool.aboutDialog.isVisible())
class TestUtil(unittest.TestCase): def setUp(self): self.config_dir = tempfile.mkdtemp() self.profile_manager = ProfileManager( os.path.join(self.config_dir, 'profiles')) def tearDown(self): shutil.rmtree(self.config_dir) def test_reset(self): """Test Resetting the configuration directory""" profile = self.profile_manager.get('default') open(profile.get_filepath('freeseer.conf'), 'w+') open(profile.get_filepath('plugin.conf'), 'w+') open(profile.get_filepath('presentations.db'), 'w+') self.assertTrue(os.path.exists(self.config_dir)) with mock.patch('__builtin__.raw_input', return_value='yes'): reset(self.config_dir) self.assertFalse(os.path.exists(self.config_dir)) # recreate the config_dir for tearDown() # while we're at it test that passing a none "yes" answer results in directory not removed os.makedirs(self.config_dir) with mock.patch('__builtin__.raw_input', return_value='no'): reset(self.config_dir) self.assertTrue(os.path.exists(self.config_dir)) def test_reset_configuration(self): """Test Resetting configuration files""" # Test resetting the default profile (no profile arguments passed) profile = self.profile_manager.get('default') open(profile.get_filepath('freeseer.conf'), 'w+') open(profile.get_filepath('plugin.conf'), 'w+') self.assertTrue(os.path.exists(profile.get_filepath('plugin.conf'))) self.assertTrue(os.path.exists(profile.get_filepath('freeseer.conf'))) reset_configuration(self.config_dir) self.assertFalse(os.path.exists(profile.get_filepath('plugin.conf'))) self.assertFalse(os.path.exists(profile.get_filepath('freeseer.conf'))) # Test resetting a non-default profile profile = self.profile_manager.get('not-default') open(profile.get_filepath('freeseer.conf'), 'w+') open(profile.get_filepath('plugin.conf'), 'w+') self.assertTrue(os.path.exists(profile.get_filepath('plugin.conf'))) self.assertTrue(os.path.exists(profile.get_filepath('freeseer.conf'))) reset_configuration(self.config_dir, 'not-default') self.assertFalse(os.path.exists(profile.get_filepath('plugin.conf'))) self.assertFalse(os.path.exists(profile.get_filepath('freeseer.conf'))) def test_reset_database(self): """Test Resetting database file""" # Test resetting the default profile (no profile arguments passed) profile = self.profile_manager.get('default') open(profile.get_filepath('presentations.db'), 'w+') self.assertTrue( os.path.exists(profile.get_filepath('presentations.db'))) reset_database(self.config_dir) self.assertFalse( os.path.exists(profile.get_filepath('presentations.db'))) # Test resetting a non-default profile profile = self.profile_manager.get('not-default') open(profile.get_filepath('presentations.db'), 'w+') self.assertTrue( os.path.exists(profile.get_filepath('presentations.db'))) reset_database(self.config_dir, 'not-default') self.assertFalse( os.path.exists(profile.get_filepath('presentations.db')))
class TestTalkEditorApp(unittest.TestCase): ''' Test suite to verify the functionality of the TalkEditorApp class. Tests interact like an end user (using QtTest). Expect the app to be rendered. ''' def setUp(self): ''' Stardard init method: runs before each test_* method Initializes a QtGui.QApplication and TalkEditorApp object. TalkEditorApp.show() causes the UI to be rendered. ''' self.profile_manager = ProfileManager(tempfile.mkdtemp()) profile = self.profile_manager.get('testing') config = profile.get_config('freeseer.conf', settings.FreeseerConfig, storage_args=['Global'], read_only=True) db = profile.get_database() self.app = QtGui.QApplication([]) self.talk_editor = TalkEditorApp(config, db) self.talk_editor.show() def tearDown(self): ''' Standard tear down method. Runs after each test_* method. This method closes the TalkEditorApp by clicking the "close" button ''' shutil.rmtree(self.profile_manager._base_folder) del self.app del self.talk_editor.app # def test_add_talk(self): # ''' # Tests a user creating a talk and adding it. # ''' # QtTest.QTest.mouseClick(self.talk_editor.editorWidget.addButton, Qt.Qt.LeftButton) # self.assertFalse(self.talk_editor.editorWidget.isVisible()) # self.assertTrue(self.talk_editor.addTalkWidget.isVisible()) # mTitle = "This is a test" # mPresenter = "Me, myself, and I" # mEvent = "0 THIS St." # mRoom = "Room 13" # # populate talk data (date and time are prepopulated) # self.talk_editor.addTalkWidget.titleLineEdit.setText(mTitle) # self.talk_editor.addTalkWidget.presenterLineEdit.setText(mPresenter) # self.talk_editor.addTalkWidget.eventLineEdit.setText(mEvent) # self.talk_editor.addTalkWidget.roomLineEdit.setText(mRoom) # # add in the talk # QtTest.QTest.mouseClick(self.talk_editor.addTalkWidget.addButton, Qt.Qt.LeftButton) # # find our talk (ensure it was added) # found = False # row_count = self.talk_editor.editorWidget.editor.model().rowCount() - 1 # while row_count >= 0 and not found: # should be at the end, but you never know # if self.talk_editor.editorWidget.editor.model().index(row_count, 1).data() == mTitle and \ # self.talk_editor.editorWidget.editor.model().index(row_count, 2).data() == mPresenter and \ # self.talk_editor.editorWidget.editor.model().index(row_count, 5).data() == mEvent and \ # self.talk_editor.editorWidget.editor.model().index(row_count, 6).data() == mRoom: # found = True # # TODO: Select this row # row_count -= 1 # self.assertTrue(found, "Couldn't find talk just inserted...") # # now delete the talk we just created # QtTest.QTest.mouseClick(self.talk_editor.editorWidget.removeButton, Qt.Qt.LeftButton) def test_file_menu_quit(self): ''' Tests TalkEditorApp's File->Quit ''' self.assertTrue(self.talk_editor.isVisible()) # File->Quit self.talk_editor.actionExit.trigger() self.assertFalse(self.talk_editor.isVisible()) def test_help_menu_about(self): ''' Tests TalkEditorApp's Help->About ''' self.assertTrue(self.talk_editor.isVisible()) # Help->About self.talk_editor.actionAbout.trigger() self.assertFalse(self.talk_editor.hasFocus()) self.assertTrue(self.talk_editor.aboutDialog.isVisible()) # Click "Close" QtTest.QTest.mouseClick(self.talk_editor.aboutDialog.closeButton, Qt.Qt.LeftButton) self.assertFalse(self.talk_editor.aboutDialog.isVisible())
class TestConfigToolApp(unittest.TestCase): """ Test suite to verify the functionality of the ConfigToolApp class. Tests interact like an end user (using QtTest). Expect the app to be rendered. NOTE: most tests will follow this format: 1. Get current config setting 2. Make UI change (config change happens immediately) 3. Reparse config file 4. Test that has changed (using the previous and new) """ def setUp(self): """ Stardard init method: runs before each test_* method Initializes a QtGui.QApplication and ConfigToolApp object. ConfigToolApp.show() causes the UI to be rendered. """ self.profile_manager = ProfileManager(tempfile.mkdtemp()) profile = self.profile_manager.get('testing') config = profile.get_config('freeseer.conf', settings.FreeseerConfig, storage_args=['Global'], read_only=False) self.app = QtGui.QApplication([]) self.config_tool = ConfigToolApp(profile, config) self.config_tool.show() def tearDown(self): """ Standard tear down method. Runs after each test_* method. This method closes the ConfigToolApp by clicking the "close" button """ QtTest.QTest.mouseClick(self.config_tool.mainWidget.closePushButton, Qt.Qt.LeftButton) shutil.rmtree(self.profile_manager._base_folder) del self.config_tool.app self.app.deleteLater() def test_default_widget(self): self.assertEqual(self.config_tool.currentWidget, self.config_tool.generalWidget) def check_combobox_corner_cases_frontend(self, combobox_widget): """ Tests that a given QtComboBox has: - a default selected item - does not blow up on the minimum and maximum index item in the combobox list """ index = combobox_widget.currentIndex() combobox_widget.setCurrentIndex(0) self.assertEquals(combobox_widget.currentIndex(), 0) self.assertIsNot(combobox_widget.currentText(), None) combobox_widget.setCurrentIndex(combobox_widget.count() - 1) self.assertEquals(combobox_widget.currentIndex(), (combobox_widget.count() - 1)) self.assertIsNot(combobox_widget.currentText(), None) combobox_widget.setCurrentIndex(index) self.assertEquals(combobox_widget.currentIndex(), index) self.assertIsNot(combobox_widget.currentText(), None) def select_general_settings_tab(self): # Select "General" tab item = self.config_tool.mainWidget.optionsTreeWidget.findItems( self.config_tool.generalString, QtCore.Qt.MatchExactly) self.assertFalse(not item or item[0] is None) self.config_tool.mainWidget.optionsTreeWidget.setCurrentItem(item[0]) QtTest.QTest.mouseClick(self.config_tool.mainWidget.optionsTreeWidget, Qt.Qt.LeftButton) def test_general_settings_checkbox(self): """ Test the config tool's General Tab auto-hide system tray icon checkbox with simulated user input """ self.select_general_settings_tab() # Test disabled checkbox self.config_tool.currentWidget.autoHideCheckBox.setChecked(False) self.assertEqual( self.config_tool.currentWidget.autoHideCheckBox.checkState(), QtCore.Qt.Unchecked) self.assertFalse(self.config_tool.config.auto_hide) # Test enabled checkbox self.config_tool.currentWidget.autoHideCheckBox.setChecked(True) self.assertEqual( self.config_tool.currentWidget.autoHideCheckBox.checkState(), QtCore.Qt.Checked) self.assertTrue(self.config_tool.config.auto_hide) def test_general_settings_dropdown_menu(self): """ Test the config tool's General Tab language selection drop down menu with simulated user input """ self.select_general_settings_tab() # Test dropdown menu language_combo_box = self.config_tool.generalWidget.languageComboBox self.check_combobox_corner_cases_frontend(language_combo_box) QtTest.QTest.keyClick( language_combo_box, QtCore.Qt.Key_PageUp ) # Test simulated user interaction with drop down list for i in range(language_combo_box.count() - 2): last_language = self.config_tool.config.default_language QtTest.QTest.keyClick(language_combo_box, QtCore.Qt.Key_Down) current_language = self.config_tool.config.default_language self.assertNotEqual(last_language, current_language) # Test frontend constants self.assertNotEqual( language_combo_box.findText('Deutsch'), -1) # Assert there are multiple languages in the menu self.assertNotEqual(language_combo_box.findText('English'), -1) self.assertNotEqual(language_combo_box.findText('Nederlands'), -1) def test_general_settings_help_reset(self): """ Test the config tool's General Tab help link and reset button with simulated user input """ self.select_general_settings_tab() # Test that Help us translate tries to open a web url. QtGui.QDesktopServices.openUrl = MagicMock(return_value=None) self.config_tool.open_translate_url() QtGui.QDesktopServices.openUrl.assert_called_with( QtCore.QUrl( "http://freeseer.readthedocs.org/en/latest/contribute/translation.html" )) # Reset # The reset test should set the backend config_tool values, simulate a user clicking through the reset popup and # verify that the backend config_tool values have been set to defaults. # TODO: FIXME. Related to gh#631. The buttons on the dialog cause segfaults in the test environment and prevent # the test from being implemented at the present time. # self.config_tool.confirm_reset() def select_recording_tab(self): """ Helper function used to open up the recording tab for recording tab related tests """ item = self.config_tool.mainWidget.optionsTreeWidget.findItems( self.config_tool.avString, QtCore.Qt.MatchExactly) self.assertFalse(not item or item[0] is None) self.config_tool.mainWidget.optionsTreeWidget.setCurrentItem(item[0]) QtTest.QTest.mouseClick(self.config_tool.mainWidget.optionsTreeWidget, Qt.Qt.LeftButton) self.assertEqual(self.config_tool.currentWidget, self.config_tool.avWidget) def test_recording_settings_file(self): """ Simulates a user interacting with the config tool record to file settings. """ self.select_recording_tab() # Test disabled checkbox self.config_tool.currentWidget.fileGroupBox.setChecked(False) self.assertFalse(self.config_tool.config.record_to_file) # Test enabled checkbox self.config_tool.currentWidget.fileGroupBox.setChecked(True) self.assertTrue(self.config_tool.config.record_to_file) self.assertIn(self.config_tool.config.record_to_file_plugin, ['Ogg Output', 'WebM Output', 'Raw Output']) # Test combo box file_combo_box = self.config_tool.avWidget.fileComboBox self.check_combobox_corner_cases_frontend(file_combo_box) QtTest.QTest.keyClick( file_combo_box, QtCore.Qt.Key_PageUp ) # Simulate user input to test backend and frontend for i in range(file_combo_box.count() - 2): last_plugin = self.config_tool.config.record_to_file_plugin QtTest.QTest.keyClick(file_combo_box, QtCore.Qt.Key_Down) current_plugin = self.config_tool.config.record_to_file_plugin self.assertNotEqual(last_plugin, current_plugin) # Test frontend text values self.assertNotEqual(file_combo_box.findText('Ogg Output'), -1) self.assertNotEqual(file_combo_box.findText('WebM Output'), -1) self.assertNotEqual(file_combo_box.findText('Raw Output'), -1) def test_recording_settings_stream(self): """ Simulates a user interacting with the config tool record to output stream settings. """ self.select_recording_tab() # Test disabled checkbox self.config_tool.currentWidget.streamGroupBox.setChecked(False) self.assertFalse(self.config_tool.config.record_to_stream) # Test enabled checkbox self.config_tool.currentWidget.streamGroupBox.setChecked(True) self.assertTrue(self.config_tool.config.record_to_stream) # Test combo box stream_combo_box = self.config_tool.avWidget.streamComboBox self.check_combobox_corner_cases_frontend(stream_combo_box) QtTest.QTest.keyClick( stream_combo_box, QtCore.Qt.Key_PageUp ) # Simulate user input to test backend and frontend for i in range(stream_combo_box.count() - 2): last_plugin = self.config_tool.plugman.get_plugin_by_name( stream_combo_box.currentText(), 'Output') QtTest.QTest.keyClick(stream_combo_box, QtCore.Qt.Key_Down) current_plugin = self.config_tool.plugman.get_plugin_by_name( stream_combo_box.currentText(), 'Output') self.assertNotEqual(last_plugin, current_plugin) # Test frontend text values self.assertNotEqual(stream_combo_box.findText('RTMP Streaming'), -1) self.assertNotEqual(stream_combo_box.findText('Ogg Icecast'), -1) def test_recording_settings_video_input(self): """ Simulates a user interacting with the config tool record to video input setting. """ self.select_recording_tab() # Test disabled checkbox self.config_tool.currentWidget.videoGroupBox.setChecked(False) self.assertFalse(self.config_tool.config.enable_video_recording) # Test enabled checkbox self.config_tool.currentWidget.videoGroupBox.setChecked(True) self.assertTrue(self.config_tool.config.enable_video_recording) self.assertIn(self.config_tool.config.videomixer, ['Video Passthrough', 'Picture-In-Picture']) # Test combo box video_mixer_combo_box = self.config_tool.avWidget.videoMixerComboBox self.check_combobox_corner_cases_frontend(video_mixer_combo_box) QtTest.QTest.keyClick( video_mixer_combo_box, QtCore.Qt.Key_PageUp) # Simulate user to test backend/frontend for i in range(video_mixer_combo_box.count() - 2): last_plugin = self.config_tool.videomixer QtTest.QTest.keyClick(video_mixer_combo_box, QtCore.Qt.Key_Down) current_plugin = self.config_tool.videomixer self.assertNotEqual(last_plugin, current_plugin) # Test frontend text values self.assertTrue( video_mixer_combo_box.findText('Video Passthrough') != -1) self.assertTrue( video_mixer_combo_box.findText('Picture-In-Picture') != -1) def test_recording_settings_audio_input(self): """ Simulates a user interacting with the config tool record to audio input settings. """ self.select_recording_tab() # Test disabled checkbox self.config_tool.currentWidget.audioGroupBox.setChecked(False) self.assertFalse(self.config_tool.config.enable_audio_recording) # Test enabled checkbox self.config_tool.currentWidget.audioGroupBox.setChecked(True) self.assertTrue(self.config_tool.config.enable_audio_recording) self.assertIn(self.config_tool.config.audiomixer, ['Audio Passthrough', 'Multiple Audio Inputs']) # Test combo box audio_mixer_combo_box = self.config_tool.avWidget.audioMixerComboBox self.check_combobox_corner_cases_frontend(audio_mixer_combo_box) QtTest.QTest.keyClick( audio_mixer_combo_box, QtCore.Qt.Key_PageUp) # Simulate user to test backend/frontend for i in range(audio_mixer_combo_box.count() - 2): last_plugin = self.config_tool.audiomixer QtTest.QTest.keyClick(audio_mixer_combo_box, QtCore.Qt.Key_Down) current_plugin = self.config_tool.audiomixer self.assertNotEqual(last_plugin, current_plugin) # Test frontend text values self.assertNotEqual( audio_mixer_combo_box.findText('Audio Passthrough'), -1) self.assertNotEqual( audio_mixer_combo_box.findText('Multiple Audio Inputs'), -1) def test_plugin_settings(self): """ Simulate a user going through the list of plugins in the plugin settings page of the config tool. This test builds a dictionary value based on a traversal of the QTreeWidget that contains the plugins displayed in the GUI. The dictionary is then used to assert that plugins exist in the appropriate categories. This test also uses a map to relate the GUI's category names to the backend's category names since the two differ. """ item = self.config_tool.mainWidget.optionsTreeWidget.findItems( self.config_tool.pluginsString, QtCore.Qt.MatchExactly) self.assertFalse(not item or item[0] is None) self.config_tool.mainWidget.optionsTreeWidget.setCurrentItem(item[0]) QtTest.QTest.mouseClick(self.config_tool.mainWidget.optionsTreeWidget, Qt.Qt.LeftButton) self.assertEqual(self.config_tool.currentWidget, self.config_tool.pluginWidget) # GUI names categories are different than the backend. Define a translation from GUI -> backend gui_category_to_backend_category = { 'Audio Input': 'AudioInput', 'Audio Mixer': 'AudioMixer', 'Video Input': 'VideoInput', 'Video Mixer': 'VideoMixer', 'Output': 'Output', 'Input': 'Importer' } QtTest.QTest.keyClick(self.config_tool.pluginWidget.list, QtCore.Qt.Key_PageUp) root = self.config_tool.pluginWidget.list.invisibleRootItem() plugin_category = {} # A dictionary of plugin -> category for category_index in range(root.childCount()): category = str( self.config_tool.pluginWidget.list.currentItem().text(0)) QtTest.QTest.keyClick(self.config_tool.pluginWidget.list, QtCore.Qt.Key_Down) for plugin_index in range(root.child(category_index).childCount()): plugin_name = str( self.config_tool.pluginWidget.list.currentItem().text(0)) plugin_category[ plugin_name] = gui_category_to_backend_category[category] QtTest.QTest.keyClick(self.config_tool.pluginWidget.list, QtCore.Qt.Key_Down) # Assert expected categories exist. self.assertIn('AudioInput', plugin_category.values()) self.assertIn('AudioMixer', plugin_category.values()) self.assertIn('VideoInput', plugin_category.values()) self.assertIn('VideoMixer', plugin_category.values()) self.assertIn('Output', plugin_category.values()) self.assertIn('Importer', plugin_category.values()) for category in [ 'AudioInput', 'AudioMixer', 'VideoInput', 'VideoMixer', 'Output', 'Importer' ]: for plugin in self.config_tool.get_plugins(category): self.assertIn(plugin.plugin_object.name, plugin_category) self.assertEqual(plugin_category[plugin.plugin_object.name], category) self.assertEqual(category, plugin.plugin_object.CATEGORY) def test_logger_settings(self): """ Tests for config tool's Logger tab Needs to be tested differently since the Config instance isn't affected by changes in this tab. """ # TODO pass def test_close_configtool(self): """ Tests for config tool's close button """ self.assertTrue(self.config_tool.mainWidget.isVisible()) QtTest.QTest.mouseClick(self.config_tool.mainWidget.closePushButton, Qt.Qt.LeftButton) self.assertFalse(self.config_tool.mainWidget.isVisible()) def test_file_menu_quit(self): """ Tests for config tool's File->Quit """ self.assertTrue(self.config_tool.isVisible()) # File->Quit self.config_tool.actionExit.trigger() self.assertFalse(self.config_tool.isVisible()) def test_help_menu_about(self): """ Tests for config tool's Help->About """ self.assertTrue(self.config_tool.isVisible()) # Help->About self.config_tool.actionAbout.trigger() self.assertFalse(self.config_tool.hasFocus()) self.assertTrue(self.config_tool.aboutDialog.isVisible()) # Click "Close" QtTest.QTest.mouseClick(self.config_tool.aboutDialog.closeButton, Qt.Qt.LeftButton) self.assertFalse(self.config_tool.aboutDialog.isVisible())