def test_all_protected_playlists_exist_returns_false_if_l_any_protected_playlist_uri_is_not_matched_in_the_users_collab_playlists( self, helper_stub): protected_playlists = [{ 'pllabel1': { 'uri': self.generate_playlist_uri(), 'owner': { 'id': 'creator_id' } } }, { 'pllabel2': { 'uri': self.generate_playlist_uri(), 'owner': { 'id': 'creator_id' } } }] helper_obj = Mock() helper_obj.get_all_collab_playlists.return_value = [ protected_playlists[0]['pllabel1'] ] helper_stub.return_value = helper_obj validator = ConfigValidator( {'PROTECTED_PLAYLISTS': protected_playlists}, {}, {'USERNAME': '******'}) self.assertFalse( validator.all_protected_playlists_exist(spotipy.client.Spotify()))
def test_all_protected_playlists_exist_returns_false_if_a_playlist_has_more_than_one_label( self, helper_stub): protected_playlists = [{ 'pllabel1': { 'uri': self.generate_playlist_uri(), 'owner': { 'id': 'creator_id' } }, 'anotherlabelforsame': { 'uri': self.generate_playlist_uri(), 'owner': { 'id': 'creator_id' } } }, { 'pllabel2': { 'uri': self.generate_playlist_uri(), 'owner': { 'id': 'creator_id' } } }] helper_obj = Mock() helper_obj.get_all_collab_playlists.return_value = [ protected_playlists[0]['pllabel1'] ] helper_stub.return_value = helper_obj validator = ConfigValidator( {'PROTECTED_PLAYLISTS': protected_playlists}, {}, {'USERNAME': '******'}) self.assertFalse( validator.all_protected_playlists_exist(spotipy.client.Spotify()))
def test_validate_log_config_returns_true_all_fields_provided_and_log_levels_are_valid( self): validator = ConfigValidator(log={ 'FILE': 'file', 'FILE_LEVEL': 'error', 'CONSOLE_LEVEL': 'error' }) self.assertTrue(validator.validate_log_config())
def test_validate_log_config_returns_false_if_console_level_is_not_a_valid_log_level( self): validator = ConfigValidator( log={ 'FILE': 'file', 'FILE_LEVEL': 'error', 'CONSOLE_LEVEL': 'not_a_real_log_level' }) self.assertFalse(validator.validate_log_config())
def test_validate_account_config_returns_true_if_all_account_info_is_set( self): validator = ConfigValidator( account={ 'CLIENT_ID': 'id', 'CLIENT_SECRET': 'secret', 'REDIRECT_URI': 'uri', 'USERNAME': '******' }) self.assertTrue(validator.validate_account_config())
def main(): if '-h' in sys.argv or '--help' in sys.argv: print_help_information() exit_with_code(0) elif '--rdc' in sys.argv: exit_with_code(restore_default_config_file()) try: logger = default_logger( ) # used for error logging before custom logger can be configured (playlist_config, log_config, account_config) = load_configurations(path=get_config_filepath()) config_validator = ConfigValidator(playlist_config, log_config, account_config) if not config_validator.is_valid(): raise Exception( 'Invalid configuration file - check \'data/config.yaml\'') logger = setup_logger( log_config) # custom logger based on user's config logger.info('Starting new session of SpotifyAutoModerator') api_client = SpotifyHelper(logger).configure_api( account_config['CLIENT_ID'], account_config['CLIENT_SECRET'], account_config['REDIRECT_URI']) if not isinstance(api_client, spotipy.client.Spotify): raise Exception('Failed to authenticate with Spotify') elif not config_validator.all_protected_playlists_exist(api_client): raise Exception( 'Could not find all protected playlists in Spotify') moderate_playlists(logger, api_client, account_config['USERNAME'], playlist_config) except OSError as err: logger.error('Error: \'%s\'', err) if 'Address already in use' in str(err): logger.error('Redirect URI \'%s\' is already in use', account_config['REDIRECT_URI']) logger.error( 'Try to use a different (free) port number and add this address to the' + 'application in the Spotify Developer Dashboard') exit_with_code(1) except Exception as err: logger.error('Error: \'%s\'', err) if '401' in str(err): logger.error('Confirm your account/client details are correct') exit_with_code(1) exit_with_code(0)
def test_validate_playlist_config_returns_false_if_global_mode_is_whitelist_and_global_whitelist_not_set( self): validator = ConfigValidator( playlist={ 'DELAY_BETWEEN_SCANS': 90, 'GLOBAL_BLACKLIST': [], 'PROTECT_ALL': False, 'GLOBAL_MODE': 'whitelist', 'BACKUP_PATH': 'data/test/backup/some_path', 'MAX_BACKUPS_PER_PLAYLIST': 2, 'PROTECTED_PLAYLISTS': [] }) validator.validate_protected_playlists = Mock(return_value=True) self.assertFalse(validator.validate_playlist_config())
def test_validate_playlist_config_returns_false_if_backup_path_is_not_a_string( self): validator = ConfigValidator( playlist={ 'DELAY_BETWEEN_SCANS': 90, 'GLOBAL_WHITELIST': [], 'GLOBAL_BLACKLIST': [], 'PROTECT_ALL': False, 'GLOBAL_MODE': 'blacklist', 'BACKUP_PATH': 900, 'MAX_BACKUPS_PER_PLAYLIST': 2, 'PROTECTED_PLAYLISTS': [] }) self.assertFalse(validator.validate_playlist_config())
def test_validate_playlist_config_returns_false_if_global_whitelist_is_set_but_is_not_a_list( self): validator = ConfigValidator( playlist={ 'DELAY_BETWEEN_SCANS': 90, 'GLOBAL_WHITELIST': 'not_a_list', 'GLOBAL_BLACKLIST': [], 'PROTECT_ALL': False, 'GLOBAL_MODE': 'blacklist', 'BACKUP_PATH': 'data/test/backup/some_path', 'MAX_BACKUPS_PER_PLAYLIST': 2, 'PROTECTED_PLAYLISTS': [] }) self.assertFalse(validator.validate_playlist_config())
def test_validate_playlist_config_returns_false_if_delay_between_scans_is_less_than_1_minute( self): validator = ConfigValidator( playlist={ 'DELAY_BETWEEN_SCANS': 0, 'GLOBAL_WHITELIST': [], 'GLOBAL_BLACKLIST': [], 'PROTECT_ALL': False, 'GLOBAL_MODE': 'blacklist', 'BACKUP_PATH': 'data/test/backup/some_path', 'MAX_BACKUPS_PER_PLAYLIST': 2, 'PROTECTED_PLAYLISTS': [] }) self.assertFalse(validator.validate_playlist_config())
def test_validate_playlist_config_returns_true_if_all_fields_valid_and_protected_playlists_are_valid( self): validator = ConfigValidator( playlist={ 'DELAY_BETWEEN_SCANS': 90, 'GLOBAL_WHITELIST': [], 'GLOBAL_BLACKLIST': [], 'PROTECT_ALL': False, 'GLOBAL_MODE': 'blacklist', 'BACKUP_PATH': 'data/test/backup/some_path', 'MAX_BACKUPS_PER_PLAYLIST': 2, 'PROTECTED_PLAYLISTS': [] }) validator.validate_protected_playlists = Mock(return_value=True) self.assertTrue(validator.validate_playlist_config())
def test_validate_protected_playlist_returns_true_if_all_playlists_have_a_valid_uri( self): # empty whitelist and no whitelist are considered the same thing validator = ConfigValidator( playlist={ 'GLOBAL_MODE': 'blacklist', 'GLOBAL_WHITELIST': [], 'GLOBAL_BLACKLIST': [], 'PROTECTED_PLAYLISTS': [{ 'playlist1label': { 'uri': self.generate_playlist_uri() } }, { 'playlist2label': { 'uri': self.generate_playlist_uri() } }] }) self.assertTrue(validator.validate_protected_playlists())
def test_validate_protected_playlist_returns_false_if_any_playlists_has_no_uri( self): validator = ConfigValidator( playlist={ 'GLOBAL_MODE': 'blacklist', 'GLOBAL_WHITELIST': [], 'GLOBAL_BLACKLIST': [], 'PROTECTED_PLAYLISTS': [{ 'pl1label': { 'uri': self.generate_playlist_uri(), 'blacklist': [] } }, { 'pl2label': { 'blacklist': [] } }] }) self.assertFalse(validator.validate_protected_playlists())
def test_validate_playlist_config_returns_false_if_max_backups_per_playlist_is_not_a_positive_integer( self): validator = ConfigValidator( playlist={ 'DELAY_BETWEEN_SCANS': 90, 'GLOBAL_WHITELIST': [], 'GLOBAL_BLACKLIST': [], 'PROTECT_ALL': False, 'GLOBAL_MODE': 'blacklist', 'BACKUP_PATH': 'data/test/backup/some_path', 'MAX_BACKUPS_PER_PLAYLIST': 'not_an_int', 'PROTECTED_PLAYLISTS': [] }) self.assertFalse(validator.validate_playlist_config()) validator = ConfigValidator( playlist={ 'DELAY_BETWEEN_SCANS': 90, 'GLOBAL_WHITELIST': [], 'GLOBAL_BLACKLIST': [], 'PROTECT_ALL': False, 'GLOBAL_MODE': 'blacklist', 'BACKUP_PATH': 'data/test/backup/some_path', 'MAX_BACKUPS_PER_PLAYLIST': 0, 'PROTECTED_PLAYLISTS': [] }) self.assertFalse(validator.validate_playlist_config())
def test_validate_log_config_returns_false_if_any_required_field_is_missing( self): validator = ConfigValidator(log={ 'FILE': 'file', 'FILE_LEVEL': 'error' }) self.assertFalse(validator.validate_log_config()) validator = ConfigValidator(log={ 'FILE': 'file', 'CONSOLE_LEVEL': 'error' }) self.assertFalse(validator.validate_log_config()) validator = ConfigValidator(log={ 'FILE_LEVEL': 'error', 'CONSOLE_LEVEL': 'error' }) self.assertFalse(validator.validate_log_config())
def test_validate_protected_playlist_returns_false_if_a_playlist_has_more_than_one_label( self): # empty whitelist and no whitelist are considered the same thing validator = ConfigValidator( playlist={ 'GLOBAL_MODE': 'blacklist', 'GLOBAL_WHITELIST': [], 'GLOBAL_BLACKLIST': [], 'PROTECTED_PLAYLISTS': [{ 'playlist1label': { 'uri': self.generate_playlist_uri() }, 'playlist1label2': { 'uri': self.generate_playlist_uri() } }, { 'playlist2label': { 'uri': self.generate_playlist_uri() } }] }) self.assertFalse(validator.validate_protected_playlists())
def test_validate_account_config_returns_false_if_any_account_info_is_missing( self): validator = ConfigValidator(account={ 'CLIENT_ID': 'id', 'CLIENT_SECRET': 'secret', 'REDIRECT_URI': 'uri' }) self.assertFalse(validator.validate_account_config()) validator = ConfigValidator(account={ 'CLIENT_ID': 'id', 'CLIENT_SECRET': 'secret', 'USERNAME': '******' }) self.assertFalse(validator.validate_account_config()) validator = ConfigValidator(account={ 'CLIENT_ID': 'id', 'USERNAME': '******', 'REDIRECT_URI': 'uri' }) self.assertFalse(validator.validate_account_config()) validator = ConfigValidator( account={ 'CLIENT_SECRET': 'secret', 'USERNAME': '******', 'REDIRECT_URI': 'uri' }) self.assertFalse(validator.validate_account_config())
def test_validate_playlist_config_returns_false_if_any_required_field_is_missing( self): validator = ConfigValidator( playlist={ 'DELAY_BETWEEN_SCANS': 90, 'PROTECT_ALL': False, 'GLOBAL_MODE': 'blacklist', 'PROTECTED_PLAYLISTS': [], 'BACKUP_PATH': 'data/test/backup/some_path' }) self.assertFalse(validator.validate_playlist_config()) validator = ConfigValidator( playlist={ 'DELAY_BETWEEN_SCANS': 90, 'PROTECT_ALL': False, 'GLOBAL_MODE': 'blacklist', 'PROTECTED_PLAYLISTS': [], 'MAX_BACKUPS_PER_PLAYLIST': 2 }) self.assertFalse(validator.validate_playlist_config()) validator = ConfigValidator( playlist={ 'DELAY_BETWEEN_SCANS': 90, 'PROTECT_ALL': False, 'GLOBAL_MODE': 'blacklist', 'BACKUP_PATH': 'data/test/backup/some_path', 'MAX_BACKUPS_PER_PLAYLIST': 2 }) self.assertFalse(validator.validate_playlist_config()) validator = ConfigValidator( playlist={ 'DELAY_BETWEEN_SCANS': 90, 'PROTECT_ALL': False, 'PROTECTED_PLAYLISTS': [], 'BACKUP_PATH': 'data/test/backup/some_path', 'MAX_BACKUPS_PER_PLAYLIST': 2 }) self.assertFalse(validator.validate_playlist_config()) validator = ConfigValidator( playlist={ 'DELAY_BETWEEN_SCANS': 90, 'GLOBAL_MODE': 'blacklist', 'PROTECTED_PLAYLISTS': [], 'BACKUP_PATH': 'data/test/backup/some_path', 'MAX_BACKUPS_PER_PLAYLIST': 2 }) self.assertFalse(validator.validate_playlist_config()) validator = ConfigValidator( playlist={ 'PROTECT_ALL': False, 'GLOBAL_MODE': 'blacklist', 'PROTECTED_PLAYLISTS': [], 'BACKUP_PATH': 'data/test/backup/some_path', 'MAX_BACKUPS_PER_PLAYLIST': 2 }) self.assertFalse(validator.validate_playlist_config())
def test_is_valid_returns_true_if_all_config_types_are_valid(self): validator = ConfigValidator(playlist={}, log={}, account={}) validator.validate_playlist_config = Mock(return_value=True) validator.validate_log_config = Mock(return_value=True) validator.validate_account_config = Mock(return_value=True) self.assertTrue(validator.is_valid())
def test_all_protected_playlists_exist_returns_false_if_playlist_config_does_not_have_a_list_of_protected_playlists( self): validator = ConfigValidator({}, {}, {}) self.assertFalse( validator.all_protected_playlists_exist(spotipy.client.Spotify()))
def test_is_valid_returns_false_if_account_config_is_invalid(self): validator = ConfigValidator(playlist={}, log={}, account={}) validator.validate_playlist_config = Mock(return_value=True) validator.validate_log_config = Mock(return_value=True) validator.validate_account_config = Mock(return_value=False) self.assertFalse(validator.is_valid())