def test_movie_list_movies(self, api_client, schema_match): payload = {'name': 'name'} # Create list rsp = api_client.json_post('/movie_list/', data=json.dumps(payload)) assert rsp.status_code == 201, 'Response code is %s' % rsp.status_code movie_data = {'movie_name': 'title'} # Add movie to list rsp = api_client.json_post('/movie_list/1/movies/', data=json.dumps(movie_data)) assert rsp.status_code == 201, 'Response code is %s' % rsp.status_code movie = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.movie_list_object, movie) assert not errors # Get movies from list rsp = api_client.get('/movie_list/1/movies/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.return_movies, data) assert not errors assert data[0] == movie # Get movies from non-existent list rsp = api_client.get('/movie_list/10/movies/') assert rsp.status_code == 404, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors
def test_pending_api_get_all(self, api_client, schema_match): rsp = api_client.get('/pending/') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.pending_entry_list, data) assert not errors e1 = Entry(title='test.title1', url='http://bla.com') e2 = Entry(title='test.title1', url='http://bla.com') with Session() as session: pe1 = PendingEntry('test_task', e1) pe2 = PendingEntry('test_task', e2) session.bulk_save_objects([pe1, pe2]) rsp = api_client.get('/pending/') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.pending_entry_list, data) assert not errors assert len(data) == 2 assert all(e['approved'] is False for e in data)
def test_movie_list_movies_with_identifiers(self, api_client, schema_match): payload = {'name': 'name'} # Create list rsp = api_client.json_post('/movie_list/', data=json.dumps(payload)) assert rsp.status_code == 201, 'Response code is %s' % rsp.status_code identifier = {'imdb_id': 'tt1234567'} movie_data = {'movie_name': 'title', 'movie_identifiers': [identifier]} # Add movie to list rsp = api_client.json_post('/movie_list/1/movies/', data=json.dumps(movie_data)) assert rsp.status_code == 201, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.movie_list_object, data) assert not errors # Get movies from list rsp = api_client.get('/movie_list/1/movies/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.return_movies, data) assert not errors returned_identifier = data['movies'][0]['movies_list_ids'][0] assert returned_identifier['id_name'], returned_identifier['id_value'] == identifier.items()[0]
def test_rejected_delete_entry(self, api_client, schema_match): add_rejected_entry(self.entry) rsp = api_client.get('/rejected/1/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.rejected_entry_object, data) assert not errors rsp = api_client.delete('/rejected/1/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors rsp = api_client.delete('/rejected/1/') assert rsp.status_code == 404, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors rsp = api_client.get('/rejected/1/') assert rsp.status_code == 404, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors
def test_imdb_search(self, api_client, schema_match): # No params rsp = api_client.get('/imdb/search/') assert rsp.status_code == 404, 'Response code is %s' % rsp.status_code # Lookup by title rsp = api_client.get('/imdb/search/matrix/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.return_object, data) assert not errors assert len(data) > 1 # Lookup by IMDB ID rsp = api_client.get('/imdb/search/tt0234215/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.return_object, data) assert not errors assert len(data) == 1 # Lookup non-existing title rsp = api_client.get('/imdb/search/sdfgsdfgsdfgsdfg/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.return_object, data) assert not errors assert len(data) == 0
def test_schedules_id_delete(self, mocked_save_config, api_client, schema_match): # Get schedules to get their IDs rsp = api_client.get('/schedules/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.schedules_list, data) assert not errors schedule_id = data[0]['id'] rsp = api_client.delete('/schedules/{}/'.format(schedule_id)) assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors assert mocked_save_config.called rsp = api_client.delete('/schedules/111/') assert rsp.status_code == 404, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors assert mocked_save_config.called
def test_change_password(self, execute_task, api_client, schema_match): weak_password = {'password': '******'} medium_password = {'password': '******'} strong_password = {'password': '******'} rsp = api_client.json_put('/user/', data=json.dumps(weak_password)) assert rsp.status_code == 400 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors rsp = api_client.json_put('/user/', data=json.dumps(medium_password)) assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors rsp = api_client.json_put('/user/', data=json.dumps(strong_password)) assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors
def test_rejected_get_entry(self, api_client, schema_match): add_rejected_entry(self.entry) rsp = api_client.get('/rejected/1/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.rejected_entry_object, data) assert not errors values = { 'id': 1, 'title': self.entry['test_title'], 'url': self.entry['test_url'], 'rejected_by': self.entry['rejected_by'], 'reason': self.entry['reason'] } for field, value in values.items(): assert data.get(field) == value rsp = api_client.get('/rejected/10/') assert rsp.status_code == 404, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors
def test_schedules_id_put(self, mocked_save_config, api_client, schema_match): # Get schedules to get their IDs rsp = api_client.get('/schedules/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.schedules_list, data) assert not errors schedule_id = data[0]['id'] payload = {'tasks': ['test2', 'test3'], 'interval': {'minutes': 10}} rsp = api_client.json_put('/schedules/{}/'.format(schedule_id), data=json.dumps(payload)) assert rsp.status_code == 201, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.schedule_object, data) assert not errors assert mocked_save_config.called del data['id'] assert data == payload rsp = api_client.json_put('/schedules/1011/', data=json.dumps(payload)) assert rsp.status_code == 404, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors
def test_schedules_id_get(self, api_client, schema_match): # Get schedules to get their IDs rsp = api_client.get('/schedules/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.schedules_list, data) assert not errors schedule_id = data[0]['id'] # Real schedule ID rsp = api_client.get('/schedules/{}/'.format(schedule_id)) assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.schedule_object, data) assert not errors for key, value in self.schedule.items(): assert data[key] == value # Non-existent schedule ID rsp = api_client.get('/schedules/12312/') assert rsp.status_code == 404, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors
def test_seen_get_delete_id(self, api_client, schema_match): self.add_seen_entries() rsp = api_client.delete('/seen/1/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors rsp = api_client.get('/seen/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.seen_search_object, data) assert not errors assert len(data) == 1 rsp = api_client.delete('/seen/10/') assert rsp.status_code == 404, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors
def test_tvmaze_series_lookup_by_name(self, api_client, schema_match): values = { 'language': 'English', 'name': 'The X-Files', 'network': 'FOX', 'show_type': 'Scripted', 'tvdb_id': 77398, 'tvmaze_id': 430, 'tvrage_id': 6312, 'url': 'http://www.tvmaze.com/shows/430/the-x-files', 'webchannel': None, 'year': 1993 } rsp = api_client.get('/tvmaze/series/The X-Files/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.tvmaze_series_object, data) assert not errors for field, value in values.items(): assert data.get(field) == value rsp = api_client.get('/tvmaze/series/sdfgv35wvg23vg2/') assert rsp.status_code == 404, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors
def test_seen_pagination(self, api_client, link_headers): base_seen_entry = dict(title='test_title_', task='test_task_', reason='test_reason_') base_seen_field = dict(field='test_field_', value='test_value_') number_of_entries = 200 with Session() as session: for i in range(number_of_entries): entry = copy.deepcopy(base_seen_entry) field = copy.deepcopy(base_seen_field) for key, value in entry.items(): entry[key] = value + str(i) for key, value in field.items(): field[key] = value + str(i) seen_entry = SeenEntry(**entry) session.add(seen_entry) seen_entry.fields = [SeenField(**field)] # Default values rsp = api_client.get('/seen/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) assert len(data) == 50 assert int(rsp.headers['total-count']) == 200 assert int(rsp.headers['count']) == 50 links = link_headers(rsp) assert links['last']['page'] == 4 assert links['next']['page'] == 2 # Change page size rsp = api_client.get('/seen/?per_page=100') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) assert len(data) == 100 assert int(rsp.headers['total-count']) == 200 assert int(rsp.headers['count']) == 100 links = link_headers(rsp) assert links['last']['page'] == 2 assert links['next']['page'] == 2 # Get different page rsp = api_client.get('/seen/?page=2') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) assert len(data) == 50 assert int(rsp.headers['total-count']) == 200 assert int(rsp.headers['count']) == 50 links = link_headers(rsp) assert links['last']['page'] == 4 assert links['next']['page'] == 3 assert links['prev']['page'] == 1
def on_task_metainfo(self, task, config): # NOQA if not config: return for entry in task.entries: if entry.get('series_id_type') == 'ep': if 'tvdb_id' in entry: log.info('The entry has a tvdb_id and will be used for mapping') else: log.info('The entry doesn\'t have tvdb_id, will check xem\'s list of shows') try: response = session.get('http://thexem.de/map/allNames?origin=tvdb&defaultNames=1&season=eq%s' % entry['series_season']) except requests.RequestException as e: log.info('Error looking up show by name on thexem %s' % e) continue shownames = json.loads(response.content) for tvdb_id in shownames['data'].keys(): if entry['series_name'] in shownames['data'][tvdb_id]: entry['tvdb_id'] = tvdb_id log.info('The tvdb_id for %s is %s', entry['series_name'], entry['tvdb_id']) break if 'tvdb_id' not in entry: log.info('An tvdb_id was not found, will search the xem\'s site') try: response = session.get('http://thexem.de/search?q=%s' % entry['series_name']) except requests.RequestException as e: log.debug('Error searching for tvdb_id on thexem %s' % e) continue if response.url.startswith('http://thexem.de/xem/show/'): soup = get_soup(response.content) try: entry['tvdb_id'] = soup.findAll('a', {'href': re.compile('^http://thetvdb.com/\?tab=series')})[0].next log.info('The tvdb_id for %s is %s', entry['series_name'], entry['tvdb_id']) except: pass if 'tvdb_id' not in entry: log.error('Unable to find a tvdb_id for %s, manually specify a tvdb_id using set', entry['series_name']) log.info('http://thexem.de/map/all?id=%s&origin=tvdb',entry['tvdb_id']) try: response = session.get('http://thexem.de/map/all?id=%s&origin=tvdb' % entry['tvdb_id']) except requests.RequestException as e: log.debug('Error getting episode map from thexem %s' % e) continue episode_map = json.loads(response.content) if episode_map['result'] == 'success': try: for episode_entry in episode_map['data']: if episode_entry[config['source']]['season'] == entry['series_season'] and episode_entry[config['source']]['episode'] == entry['series_episode']: log.info('An XEM entry was found for %s, %s episode S%02dE%02d maps to %s episode S%02dE%02d' % (entry['series_name'], config['source'], entry['series_season'], entry['series_episode'], config['destination'], episode_entry[config['destination']]['season'], episode_entry[config['destination']]['episode'])) if 'description' in entry: entry['description'] = entry['description'].replace('Season: %s; Episode: %s' % (entry['series_season'], entry['series_episode']), 'Season: %s; Episode: %s' % (episode_entry[config['destination']]['season'], episode_entry[config['destination']]['episode'])) entry['series_season'] = episode_entry[config['destination']]['season'] entry['series_episode'] = episode_entry[config['destination']]['episode'] entry['series_id'] = 'S%02dE%02d' % (episode_entry[config['destination']]['season'], episode_entry[config['destination']]['episode']) break except: log.error('Error in thexem plugin for entry %s (tvdb_id: %s)' % (entry['title'], entry['tvdb_id'])) log.error('Content was: %s' % response.content)
def test_rejected_pagination(self, api_client, link_headers): base_reject_entry = dict( title='test_title_', url='test_url_', rejected_by='rejected_by_', reason='reason_' ) number_of_entries = 200 with Session() as session: task = RememberTask(name='rejected API test') session.add(task) session.commit() for i in range(number_of_entries): r_entry = copy.deepcopy(base_reject_entry) for key, value in r_entry.items(): r_entry[key] = value + str(i) expires = datetime.now() + parse_timedelta('1 hours') session.add(RememberEntry(expires=expires, task_id=task.id, **r_entry)) # Default values rsp = api_client.get('/rejected/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) assert len(data) == 50 assert int(rsp.headers['total-count']) == 200 assert int(rsp.headers['count']) == 50 links = link_headers(rsp) assert links['last']['page'] == 4 assert links['next']['page'] == 2 # Change page size rsp = api_client.get('/rejected/?per_page=100') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) assert len(data) == 100 assert int(rsp.headers['total-count']) == 200 assert int(rsp.headers['count']) == 100 links = link_headers(rsp) assert links['last']['page'] == 2 assert links['next']['page'] == 2 # Get different page rsp = api_client.get('/rejected/?page=2') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) assert len(data) == 50 assert int(rsp.headers['total-count']) == 200 assert int(rsp.headers['count']) == 50 links = link_headers(rsp) assert links['last']['page'] == 4 assert links['next']['page'] == 3 assert links['prev']['page'] == 1
def test_executions_pagination(self, api_client, link_headers): base_start_time = datetime.now() - timedelta(days=7) number_of_entries = 200 with Session() as session: st1 = StatusTask() st1.name = 'status task 1' session.add(st1) for i in range(number_of_entries): ex = TaskExecution() ex.task = st1 ex.produced = i ex.rejected = i ex.accepted = i ex.start = base_start_time + timedelta(hours=i) ex.end = datetime.now() rsp = api_client.get('/status/1/executions/') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) assert len(data) == 50 assert int(rsp.headers['total-count']) == 200 assert int(rsp.headers['count']) == 50 links = link_headers(rsp) assert links['last']['page'] == 4 assert links['next']['page'] == 2 # Change page size rsp = api_client.get('/status/1/executions/?per_page=100') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) assert len(data) == 100 assert int(rsp.headers['total-count']) == 200 assert int(rsp.headers['count']) == 100 links = link_headers(rsp) assert links['last']['page'] == 2 assert links['next']['page'] == 2 # Get different page rsp = api_client.get('/status/1/executions/?page=2') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) assert len(data) == 50 assert int(rsp.headers['total-count']) == 200 assert int(rsp.headers['count']) == 50 links = link_headers(rsp) assert links['last']['page'] == 4 assert links['next']['page'] == 3 assert links['prev']['page'] == 1
def test_movie_list_movie(self, api_client, schema_match): payload = {'name': 'name'} # Create list rsp = api_client.json_post('/movie_list/', data=json.dumps(payload)) assert rsp.status_code == 201, 'Response code is %s' % rsp.status_code identifier = {'imdb_id': 'tt1234567'} movie_data = {'movie_name': 'title', 'movie_identifiers': [identifier]} # Add movie to list rsp = api_client.json_post('/movie_list/1/movies/', data=json.dumps(movie_data)) assert rsp.status_code == 201, 'Response code is %s' % rsp.status_code # Get specific movie from list rsp = api_client.get('/movie_list/1/movies/1/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.movie_list_object, data) assert not errors returned_identifier = data['movies_list_ids'][0] assert returned_identifier['id_name'], returned_identifier['id_value'] == identifier.items()[0] identifiers = [{'trakt_movie_id': '12345'}] # Change specific movie from list rsp = api_client.json_put('/movie_list/1/movies/1/', data=json.dumps(identifiers)) assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.movie_list_object, data) assert not errors returned_identifier = data['movies_list_ids'][0] assert returned_identifier['id_name'], returned_identifier['id_value'] == identifiers[0].items() # Delete specific movie from list rsp = api_client.delete('/movie_list/1/movies/1/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(empty_response, data) assert not errors # Get non existent movie from list rsp = api_client.get('/movie_list/1/movies/1/') assert rsp.status_code == 404, 'Response code is %s' % rsp.status_code # Delete non existent movie from list rsp = api_client.delete('/movie_list/1/movies/1/') assert rsp.status_code == 404, 'Response code is %s' % rsp.status_code
def test_entry_list_pagination(self, api_client, link_headers): base_entry = dict(title='test_title_', original_url='url_') number_of_entries = 200 with Session() as session: entry_list = EntryListList(name='test list') session.add(entry_list) for i in range(number_of_entries): entry = copy.deepcopy(base_entry) for k, v in entry.items(): entry[k] = v + str(i) e = Entry(entry) entry_list.entries.append(EntryListEntry(e, entry_list.id)) # Default values rsp = api_client.get('/entry_list/1/entries/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) assert len(data) == 50 assert int(rsp.headers['total-count']) == 200 assert int(rsp.headers['count']) == 50 links = link_headers(rsp) assert links['last']['page'] == 4 assert links['next']['page'] == 2 # Change page size rsp = api_client.get('/entry_list/1/entries/?per_page=100') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) assert len(data) == 100 assert int(rsp.headers['total-count']) == 200 assert int(rsp.headers['count']) == 100 links = link_headers(rsp) assert links['last']['page'] == 2 assert links['next']['page'] == 2 # Get different page rsp = api_client.get('/entry_list/1/entries/?page=2') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) assert len(data) == 50 assert int(rsp.headers['total-count']) == 200 assert int(rsp.headers['count']) == 50 links = link_headers(rsp) assert links['last']['page'] == 4 assert links['next']['page'] == 3 assert links['prev']['page'] == 1
def test_secrets_put(self, api_client): rsp = api_client.get('/secrets/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code assert json.loads(rsp.get_data(as_text=True)) == {} rsp = api_client.json_put('/secrets/', data=json.dumps(self.secrets_dict)) assert rsp.status_code == 201, 'Response code is %s' % rsp.status_code assert json.loads(rsp.get_data(as_text=True)) == self.secrets_dict rsp = api_client.get('/secrets/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code assert json.loads(rsp.get_data(as_text=True)) == self.secrets_dict
def test_retry_failed_all(self, api_client, schema_match): rsp = api_client.get('/failed/') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.retry_entries_list_object, data) assert not errors failed_entry_dict_1 = dict( title='Failed title1', url='http://123.com', reason='Test reason1' ) failed_entry_dict_2 = dict( title='Failed title2', url='http://124.com', reason='Test reason2' ) failed_entry_dict_3 = dict( title='Failed title3', url='http://125.com', reason='Test reason3' ) failed_entries = sorted( [failed_entry_dict_1, failed_entry_dict_2, failed_entry_dict_3], key=lambda x: x['title'], ) with Session() as session: failed_entry1 = FailedEntry(**failed_entry_dict_1) failed_entry2 = FailedEntry(**failed_entry_dict_2) failed_entry3 = FailedEntry(**failed_entry_dict_3) session.bulk_save_objects([failed_entry1, failed_entry2, failed_entry3]) session.commit() rsp = api_client.get('/failed/') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.retry_entries_list_object, data) assert not errors # Sorted for result comparison data = sorted(data, key=lambda x: x['title']) for idx, entry in enumerate(failed_entries): for key, value in entry.items(): assert data[idx].get(key) == failed_entries[idx].get(key) rsp = api_client.delete('/failed/') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors rsp = api_client.get('/failed/') assert rsp.status_code == 200 assert json.loads(rsp.get_data(as_text=True)) == []
def test_history(self, api_client, schema_match): rsp = api_client.get('/history/') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.history_list_object, data) assert not errors assert data == [] history_entry = dict( task='test_task1', title='test_title1', url='test_url1', filename='test_filename1', details='test_details1', ) with Session() as session: item = History() for key, value in history_entry.items(): setattr(item, key, value) session.add(item) session.commit() rsp = api_client.get('/history/') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.history_list_object, data) assert not errors for key, value in history_entry.items(): assert data[0][key] == value rsp = api_client.get('/history/?task=test_task1') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.history_list_object, data) assert not errors for key, value in history_entry.items(): assert data[0][key] == value rsp = api_client.get('/history/?task=bla') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.history_list_object, data) assert not errors assert data == []
def test_movie_list_pagination(self, api_client, link_headers): base_movie = dict(title='title_', year=1900) number_of_movies = 200 with Session() as session: movie_list = MovieListList(name='test_list') session.add(movie_list) for i in range(number_of_movies): movie = copy.deepcopy(base_movie) movie['title'] += str(i) movie['year'] += i movie_list.movies.append(MovieListMovie(**movie)) # Default values rsp = api_client.get('/movie_list/1/movies/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) assert len(data) == 50 # Default page size assert int(rsp.headers['total-count']) == 200 assert int(rsp.headers['count']) == 50 links = link_headers(rsp) assert links['last']['page'] == 4 assert links['next']['page'] == 2 # Change page size rsp = api_client.get('/movie_list/1/movies/?per_page=100') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) assert len(data) == 100 assert int(rsp.headers['total-count']) == 200 assert int(rsp.headers['count']) == 100 links = link_headers(rsp) assert links['last']['page'] == 2 assert links['next']['page'] == 2 # Get different page rsp = api_client.get('/movie_list/1/movies/?page=2') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) assert len(data) == 50 # Default page size assert int(rsp.headers['total-count']) == 200 assert int(rsp.headers['count']) == 50 links = link_headers(rsp) assert links['last']['page'] == 4 assert links['next']['page'] == 3 assert links['prev']['page'] == 1
def test_seen_delete_all(self, api_client, schema_match): entries = self.add_seen_entries() rsp = api_client.get('/seen/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.seen_search_object, data) assert not errors for idx, value in enumerate(sorted(data, key=lambda entry: entry['title'])): for k, v in entries[idx].items(): assert value[k] == v rsp = api_client.delete('/seen/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors assert data['message'] == 'successfully deleted 2 entries' self.add_seen_entries() rsp = api_client.delete('/seen/?local=true') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors assert data['message'] == 'successfully deleted 1 entries' rsp = api_client.delete('/seen/?value=test_value_2') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors assert data['message'] == 'successfully deleted 1 entries' rsp = api_client.get('/seen/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.seen_search_object, data) assert not errors assert data == []
def test_movie_list_list_id(self, api_client, schema_match): payload = {'name': 'test'} # Create list rsp = api_client.json_post('/movie_list/', data=json.dumps(payload)) assert rsp.status_code == 201, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.list_object, data) assert not errors values = { 'name': 'test', 'id': 1 } for field, value in values.items(): assert data.get(field) == value # Get list rsp = api_client.get('/movie_list/1/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.list_object, data) assert not errors values = { 'name': 'test', 'id': 1 } for field, value in values.items(): assert data.get(field) == value # Delete list rsp = api_client.delete('/movie_list/1/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors # Get non existent list rsp = api_client.get('/movie_list/1/') assert rsp.status_code == 404, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors # Delete non existent list rsp = api_client.delete('/movie_list/1/') assert rsp.status_code == 404, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors
def test_movie_list_list(self, api_client, schema_match): # No params rsp = api_client.get('/movie_list/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.return_lists, data) assert not errors assert data == [] # Named param rsp = api_client.get('/movie_list/?name=name') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.return_lists, data) assert not errors payload = {'name': 'test'} # Create list rsp = api_client.json_post('/movie_list/', data=json.dumps(payload)) assert rsp.status_code == 201, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.list_object, data) assert not errors values = { 'name': 'test', 'id': 1 } for field, value in values.items(): assert data.get(field) == value rsp = api_client.get('/movie_list/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.return_lists, data) assert not errors for field, value in values.items(): assert data[0].get(field) == value # Try to Create existing list rsp = api_client.json_post('/movie_list/', data=json.dumps(payload)) assert rsp.status_code == 409, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors
def test_seen_get_all(self, api_client, schema_match): rsp = api_client.get('/seen/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.seen_search_object, data) assert not errors entries = self.add_seen_entries() rsp = api_client.get('/seen/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.seen_search_object, data) assert not errors for idx, value in enumerate(sorted(data, key=lambda entry: entry['title'])): for k, v in entries[idx].items(): assert value[k] == v assert len(data) == 2 rsp = api_client.get('/seen/?local=true') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.seen_search_object, data) assert not errors assert len(data) == 1 rsp = api_client.get('/seen/?value=test_value_2') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.seen_search_object, data) assert not errors assert len(data) == 1 rsp = api_client.get('/seen/?value=bla') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.seen_search_object, data) assert not errors assert len(data) == 0
def test_entry_list_sorting(self, api_client): base_entry_1 = dict(title='test_title_1', original_url='url_c') base_entry_2 = dict(title='test_title_2', original_url='url_b') base_entry_3 = dict(title='test_title_3', original_url='url_a') with Session() as session: entry_list = EntryListList(name='test list') session.add(entry_list) e1 = Entry(base_entry_1) e2 = Entry(base_entry_2) e3 = Entry(base_entry_3) entry_list.entries.append(EntryListEntry(e1, entry_list.id)) entry_list.entries.append(EntryListEntry(e2, entry_list.id)) entry_list.entries.append(EntryListEntry(e3, entry_list.id)) # Sort by title rsp = api_client.get('/entry_list/1/entries/?sort_by=title') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) assert data[0]['title'] == 'test_title_3' rsp = api_client.get('/entry_list/1/entries/?sort_by=title&order=asc') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) assert data[0]['title'] == 'test_title_1' # Sort by original url rsp = api_client.get('/entry_list/1/entries/?sort_by=original_url') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) assert data[0]['original_url'] == 'url_c' rsp = api_client.get('/entry_list/1/entries/?sort_by=original_url&order=asc') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) assert data[0]['original_url'] == 'url_a' # Combine sorting and pagination rsp = api_client.get('/entry_list/1/entries/?sort_by=title&per_page=2&page=2') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) assert data[0]['title'] == 'test_title_1'
def test_retry_failed_get_all(self, api_client): rsp = api_client.get('/retry_failed/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code assert json.loads(rsp.get_data(as_text=True))['number_of_failed_entries'] == 0 with Session() as session: failed_entry = FailedEntry(title='Failed title', url='http://123.com', reason='Test reason') session.add(failed_entry) session.commit() rsp = api_client.get('/retry_failed/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code assert json.loads(rsp.get_data(as_text=True))['number_of_failed_entries'] == 1
def test_pending_list_list_id(self, api_client, schema_match): payload = {'name': 'test_list'} # Create list rsp = api_client.json_post('/pending_list/', data=json.dumps(payload)) assert rsp.status_code == 201 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.pending_list_base_object, data) assert not errors for field, value in payload.items(): assert data.get(field) == value # Get list rsp = api_client.get('/pending_list/1/') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.pending_list_base_object, data) assert not errors for field, value in payload.items(): assert data.get(field) == value # Delete list rsp = api_client.delete('/pending_list/1/') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors # Try to get list rsp = api_client.get('/pending_list/1/') assert rsp.status_code == 404 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors # Try to Delete list rsp = api_client.delete('/pending_list/1/') assert rsp.status_code == 404 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors
def test_pending_api_put_entry(self, api_client, schema_match): e1 = Entry(title='test.title1', url='http://bla.com') e2 = Entry(title='test.title1', url='http://bla.com') with Session() as session: pe1 = PendingEntry('test_task', e1) pe2 = PendingEntry('test_task', e2) session.bulk_save_objects([pe1, pe2]) payload = {'operation': 'approve'} rsp = api_client.json_put('/pending/1/', data=json.dumps(payload)) assert rsp.status_code == 201 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.pending_entry_object, data) assert not errors assert data['approved'] is True rsp = api_client.json_put('/pending/1/', data=json.dumps(payload)) assert rsp.status_code == 400 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors payload = {'operation': 'reject'} rsp = api_client.json_put('/pending/1/', data=json.dumps(payload)) assert rsp.status_code == 201 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.pending_entry_object, data) assert not errors assert data['approved'] is False rsp = api_client.json_put('/pending/1/', data=json.dumps(payload)) assert rsp.status_code == 400 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors
def test_entry_list_entry(self, api_client): payload = {'name': 'name'} # Create list rsp = api_client.json_post('/entry_list/', data=json.dumps(payload)) assert rsp.status_code == 201, 'Response code is %s' % rsp.status_code entry_data = {'title': 'title', 'original_url': 'http://test.com'} # Add entry to list rsp = api_client.json_post('/entry_list/1/entries/', data=json.dumps(entry_data)) assert rsp.status_code == 201, 'Response code is %s' % rsp.status_code # Get entries from list rsp = api_client.get('/entry_list/1/entries/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code assert json.loads(rsp.get_data(as_text=True))['entries'][0]['entry'] == entry_data # Get specific entry from list rsp = api_client.get('/entry_list/1/entries/1/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code assert json.loads(rsp.get_data(as_text=True))['entry'] == entry_data new_entry_data = {'title': 'title2', 'original_url': 'http://test2.com'} # Change specific entry from list rsp = api_client.json_put('/entry_list/1/entries/1/', data=json.dumps(new_entry_data)) assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code assert json.loads(rsp.get_data(as_text=True))['entry'] == new_entry_data # Delete specific entry from list rsp = api_client.delete('/entry_list/1/entries/1/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code # Get non existent entry from list rsp = api_client.get('/entry_list/1/entries/1/') assert rsp.status_code == 404, 'Response code is %s' % rsp.status_code # Delete non existent entry from list rsp = api_client.delete('/entry_list/1/entries/1/') assert rsp.status_code == 404, 'Response code is %s' % rsp.status_code
def test_entry_list_list(self, api_client, schema_match): # No params rsp = api_client.get('/entry_list/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.entry_list_return_lists, data) assert not errors payload = {'name': 'test_list'} # Create list rsp = api_client.json_post('/entry_list/', data=json.dumps(payload)) assert rsp.status_code == 201, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.entry_list_base_object, data) assert not errors for field, value in payload.items(): assert data.get(field) == value # Named param rsp = api_client.get('/entry_list/?name=test_list') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.entry_list_return_lists, data) assert not errors for field, value in payload.items(): assert data[0].get(field) == value # Try to Create list again rsp = api_client.json_post('/entry_list/', data=json.dumps(payload)) assert rsp.status_code == 409, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors
def test_rejected_delete_all(self, api_client, schema_match): add_rejected_entry(self.entry) rsp = api_client.get('/rejected/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.rejected_entry_object, data[0]) assert not errors rsp = api_client.delete('/rejected/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) assert data == { 'status': 'success', 'status_code': 200, 'message': 'successfully deleted 1 rejected entries', }
def test_tvdb_search_with_language(self, api_client, schema_match): rsp = api_client.get('/tvdb/search/?language=nl&search_name=Tegenlicht') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.search_results_object, data) assert not errors values = {'series_name': "Tegenlicht", 'tvdb_id': 252712} for field, value in values.items(): assert data[0].get(field) == value
def test_schedules_post(self, api_client, schema_match): payload = { 'tasks': ['test2', 'test3'], 'interval': {'minutes': 10} } rsp = api_client.json_post('/schedules/', data=json.dumps(payload)) assert rsp.status_code == 409, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors
def test_tmdb_movies_lookup_backdrops_params(self, api_client, schema_match): rsp = api_client.get( '/tmdb/movies/?title=the matrix&include_backdrops=true') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(oc.movie_object, data) assert not errors assert 'backdrops' in data assert len(data['backdrops']) > 0
def test_variables_patch(self, api_client): data = {'a': 'b', 'c': 'd'} api_client.json_put('/variables/', data=json.dumps(data)) new_data = {'a': [1, 2, 3], 'foo': 'bar'} rsp = api_client.json_patch('/variables/', data=json.dumps(new_data)) assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code assert json.loads(rsp.get_data(as_text=True)) == { 'a': [1, 2, 3], 'foo': 'bar', 'c': 'd' }
def test_trakt_series_lookup_with_trakt_id_param(self, api_client, schema_match): values = {'id': 75481, 'title': 'The Flash', 'year': 1967} rsp = api_client.get('/trakt/series/the flash/?trakt_id=75481') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(oc.series_return_object, data) assert not errors for field, value in values.items(): assert data.get(field) == value
def test_trakt_series_lookup_with_actors_param(self, api_client, schema_match): rsp = api_client.get( '/trakt/series/?title=the x-files&include_actors=true') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(oc.series_return_object, data) assert not errors assert 'actors' in data assert len(data['actors']) > 0
def test_tvdb_search_results_by_imdb_id(self, api_client, schema_match): rsp = api_client.get('/tvdb/search/?imdb_id=tt0944947') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.search_results_object, data) assert not errors values = {'series_name': "Game of Thrones", 'tvdb_id': 121361} for field, value in values.items(): assert data[0].get(field) == value
def test_tvdb_search_results_by_zap2it_id(self, api_client, schema_match): rsp = api_client.get('/tvdb/search/?zap2it_id=EP01922936') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.search_results_object, data) assert not errors values = {'series_name': "The Flash (2014)", 'tvdb_id': 279121} for field, value in values.items(): assert data[0].get(field) == value
def test_trakt_series_lookup_with_trakt_id_param(self, api_client): exact_match = { 'id': 75481, 'title': 'The Flash', 'year': 1967 } rsp = api_client.get('/trakt/series/the flash/?trakt_id=75481') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) check_trakt_fields(data, exact=exact_match)
def test_pending_api_put_all(self, api_client, schema_match): e1 = Entry(title='test.title1', url='http://bla.com') e2 = Entry(title='test.title1', url='http://bla.com') with Session() as session: pe1 = PendingEntry('test_task', e1) pe2 = PendingEntry('test_task', e2) session.bulk_save_objects([pe1, pe2]) payload = {'operation': 'approve'} rsp = api_client.json_put('/pending/', data=json.dumps(payload)) assert rsp.status_code == 201 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.pending_entry_list, data) assert not errors assert len(data) == 2 assert all(e['approved'] is True for e in data) rsp = api_client.json_put('/pending/', data=json.dumps(payload)) assert rsp.status_code == 204 payload = {'operation': 'reject'} rsp = api_client.json_put('/pending/', data=json.dumps(payload)) assert rsp.status_code == 201 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.pending_entry_list, data) assert not errors assert len(data) == 2 assert all(e['approved'] is False for e in data) rsp = api_client.json_put('/pending/', data=json.dumps(payload)) assert rsp.status_code == 204
def send_push(self, task, auth_token, room_key, color, notify, title, message, url): body = '%s %s' % (title, message) data = { 'color': color, 'message': body, 'notify': notify, 'message_format': "text" } # Check for test mode if task.options.test: log.info('Test mode. Hipchat notification would be:') log.info(' Auth Token: %s' % auth_token) log.info(' Room Key: %s' % room_key) log.info(' Color: %s' % color) log.info(' Notify: %s' % notify) log.info(' Title: %s' % title) log.info(' Message: %s' % message) log.info(' URL: %s' % url) log.info(' Raw Data: %s' % json.dumps(data)) # Test mode. Skip remainder. return # Make the request headers = {'Content-Type': 'application/json'} response = task.requests.post(url, headers=headers, data=json.dumps(data), raise_status=False) # Check if it succeeded request_status = response.status_code # error codes and messages from Hipchat API if request_status == 200: log.debug('Hipchat notification sent') elif request_status == 500: log.warning( 'Hipchat notification failed, Hipchat API having issues') # TODO: Implement retrying. API requests 5 seconds between retries. elif request_status >= 400: if response.content: try: error = json.loads(response.content)['error'] except ValueError: error = 'Unknown Error (Invalid JSON returned)' log.error('Hipchat API error: %s' % error['message']) else: log.error('Unknown error when sending Hipchat notification')
def upgrade(ver, session): if ver is None: # Make sure there is no data we can't load in the backlog table backlog_table = table_schema('backlog', session) try: for item in session.query('entry').select_from( backlog_table).all(): pickle.loads(item.entry) except (ImportError, TypeError): # If there were problems, we can drop the data. logger.info( 'Backlog table contains unloadable data, clearing old data.') session.execute(backlog_table.delete()) ver = 0 if ver == 0: backlog_table = table_schema('backlog', session) logger.info('Creating index on backlog table.') Index('ix_backlog_feed_expire', backlog_table.c.feed, backlog_table.c.expire).create(bind=session.bind) ver = 1 if ver == 1: table = table_schema('backlog', session) table_add_column(table, 'json', Unicode, session) # Make sure we get the new schema with the added column table = table_schema('backlog', session) for row in session.execute(select([table.c.id, table.c.entry])): try: p = pickle.loads(row['entry']) session.execute( table.update().where(table.c.id == row['id']).values( json=json.dumps(p, encode_datetime=True))) except KeyError as e: logger.error( 'Unable error upgrading backlog pickle object due to {}', str(e)) ver = 2 if ver == 2: table = table_schema('backlog', session) for row in session.execute(select([table.c.id, table.c.json])): if not row['json']: # Seems there could be invalid data somehow. See #2590 continue data = json.loads(row['json'], decode_datetime=True) # If title looked like a date, make sure it's a string title = str(data.pop('title')) e = Entry(title=title, **data) session.execute(table.update().where( table.c.id == row['id']).values(json=serialization.dumps(e))) ver = 3 return ver
def test_trakt_movies_lookup_no_params(self, api_client): # Bad API call rsp = api_client.get('/trakt/movies/') assert rsp.status_code == 404, 'Response code is %s' % rsp.status_code rsp = api_client.get('/trakt/movies/the matrix/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) assert data.get('id') == 481 assert data.get('year') == 1999 assert data.get('tmdb_id') == 603 assert data.get('imdb_id') == 'tt0133093'
def test_tvdb_search_results_by_name(self, api_client, schema_match): rsp = api_client.get('/tvdb/search/?search_name=supernatural') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.search_results_object, data) assert not errors values = {'series_name': "Supernatural", 'tvdb_id': 78901} for field, value in values.items(): assert data[0].get(field) == value
def test_retry_failed_delete_all(self, api_client): rsp = api_client.get('/failed/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code assert json.loads(rsp.get_data(as_text=True))['number_of_failed_entries'] == 0 with Session() as session: failed_entry = FailedEntry(title='Failed title', url='http://123.com', reason='Test reason') session.add(failed_entry) session.commit() rsp = api_client.get('/failed/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code assert json.loads(rsp.get_data(as_text=True))['number_of_failed_entries'] == 1 rsp = api_client.delete('/failed/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code rsp = api_client.get('/failed/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code assert json.loads(rsp.get_data(as_text=True))['number_of_failed_entries'] == 0
def test_schedules_post(self, mocked_save_config, api_client, schema_match): payload = {'tasks': ['test2', 'test3'], 'interval': {'minutes': 10}} rsp = api_client.json_post('/schedules/', data=json.dumps(payload)) assert rsp.status_code == 201, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.schedule_object, data) assert not errors assert mocked_save_config.called del data['id'] assert data == payload
def test_tvmaze_episode_by_air_date(self, api_client, schema_match): rsp = api_client.get('/tvmaze/episode/3928/?air_date=2016-09-12') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.tvmaze_episode_object, data) assert not errors values = { 'number': 113, 'runtime': 30, 'season_number': 2016, 'series_id': 3928, 'summary': '<p>Rapper T.I. Harris.</p>', 'title': 'T.I. Harris', 'tvmaze_id': 925421, 'url': 'http://www.tvmaze.com/episodes/925421/the-daily-show-with-trevor-noah-2016-09-12-ti-harris' } for field, value in values.items(): assert data.get(field) == value rsp = api_client.get('/tvmaze/episode/3928/') assert rsp.status_code == 400, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors rsp = api_client.get('/tvmaze/episode/3928/?season_num=1') assert rsp.status_code == 400, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors
def test_pending_list_filter_entries(self, api_client, schema_match): payload = {'name': 'test_list'} rsp = api_client.json_post('/pending_list/', data=json.dumps(payload)) assert rsp.status_code == 201 entry_1_data = {'title': 'Foobaz', 'original_url': 'http://test1.com'} entry_2_data = {'title': 'fooBar', 'original_url': 'http://test2.com'} rsp = api_client.json_post('/pending_list/1/entries/', data=json.dumps(entry_1_data)) assert rsp.status_code == 201 rsp = api_client.json_post('/pending_list/1/entries/', data=json.dumps(entry_2_data)) assert rsp.status_code == 201 rsp = api_client.get('/pending_list/1/entries?filter=bar') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.pending_lists_entries_return_object, data) assert not errors assert len(data) == 1 assert data[0]['title'] == 'fooBar' rsp = api_client.get('/pending_list/1/entries?filter=foo') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) assert len(data) == 2 rsp = api_client.get('/pending_list/1/entries?filter=bla') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) assert not data
def test_pending_list_entries_batch_remove(self, api_client, schema_match): payload = {'name': 'test_list'} # Create list api_client.json_post('/pending_list/', data=json.dumps(payload)) # Add 3 entries to list for i in range(3): payload = { 'title': f'title {i}', 'original_url': f'http://{i}test.com' } rsp = api_client.json_post('/pending_list/1/entries/', data=json.dumps(payload)) assert rsp.status_code == 201 # get entries is correct rsp = api_client.get('/pending_list/1/entries/') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.pending_lists_entries_return_object, data) assert not errors assert len(data) == 3 payload = {'ids': [1, 2, 3]} rsp = api_client.json_delete('pending_list/1/entries/batch', data=json.dumps(payload)) assert rsp.status_code == 204 rsp = api_client.get('/pending_list/1/entries/') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.pending_lists_entries_return_object, data) assert not errors assert not data
def test_tmdb_movies_lookup_by_title(self, api_client, schema_match): # Bad API call rsp = api_client.get('/tmdb/movies/') assert rsp.status_code == 400, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors rsp = api_client.get('/tmdb/movies/?title=the matrix/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(oc.movie_object, data) assert not errors values = { 'id': 603, 'name': 'The Matrix', 'year': 1999, 'imdb_id': 'tt0133093' } for field, value in values.items(): assert data.get(field) == value
def test_movie_list_list_id(self, api_client, schema_match): payload = {'name': 'test'} # Create list rsp = api_client.json_post('/movie_list/', data=json.dumps(payload)) assert rsp.status_code == 201, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.list_object, data) assert not errors values = { 'name': 'test', 'id': 1 } for field, value in values.items(): assert data.get(field) == value # Get list rsp = api_client.get('/movie_list/1/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.list_object, data) assert not errors values = { 'name': 'test', 'id': 1 } for field, value in values.items(): assert data.get(field) == value # Delete list rsp = api_client.delete('/movie_list/1/') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(empty_response, data) assert not errors
def test_pending_api_delete_entry(self, api_client, schema_match): e1 = Entry(title='test.title1', url='http://bla.com') e2 = Entry(title='test.title1', url='http://bla.com') with Session() as session: pe1 = PendingEntry('test_task', e1) pe2 = PendingEntry('test_task', e2) session.bulk_save_objects([pe1, pe2]) rsp = api_client.delete('/pending/1/') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors rsp = api_client.delete('/pending/1/') assert rsp.status_code == 404 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors
def test_status_get_by_id(self, api_client, schema_match): rsp = api_client.get('/status/1/') assert rsp.status_code == 404 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(base_message, data) assert not errors with Session() as session: st1 = StatusTask() st1.name = 'status task 1' st2 = StatusTask() st2.name = 'status task 2' session.bulk_save_objects([st1, st2]) rsp = api_client.get('/status/1/') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.task_status_schema, data) assert not errors assert data['name'] == 'status task 1'
def test_status_get_all(self, api_client, schema_match): rsp = api_client.get('/status/') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.task_status_list_schema, data) assert not errors with Session() as session: st1 = StatusTask() st1.name = 'status task 1' st2 = StatusTask() st2.name = 'status task 2' session.bulk_save_objects([st1, st2]) rsp = api_client.get('/status/') assert rsp.status_code == 200 data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(OC.task_status_list_schema, data) assert not errors assert len(data) == 2
def test_tmdb_movies_lookup_year_param(self, api_client, schema_match): rsp = api_client.get('/tmdb/movies/?title=the matrix&year=2003') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) errors = schema_match(oc.movie_object, data) assert not errors values = { 'id': 605, 'name': 'The Matrix Revolutions', 'year': 2003, 'imdb_id': 'tt0242653' } for field, value in values.items(): assert data.get(field) == value
def upgrade(ver, session): if ver == 0: table = table_schema('pending_entries', session) for row in session.execute(select([table.c.id, table.c.json])): if not row['json']: # Seems there could be invalid data somehow. See #2590 continue data = json.loads(row['json'], decode_datetime=True) # If title looked like a date, make sure it's a string title = str(data.pop('title')) e = Entry(title=title, **data) session.execute(table.update().where( table.c.id == row['id']).values(json=serialization.dumps(e))) ver = 1 return ver
def test_trakt_series_lookup_with_tvrage_id_param(self, api_client): exact_match = { 'id': 60300, 'imdb_id': 'tt3107288', 'title': 'The Flash', 'tmdb_id': 60735, 'tvdb_id': 279121, 'tvrage_id': 36939, 'year': 2014 } rsp = api_client.get('/trakt/series/the flash/?tvrage_id=36939') assert rsp.status_code == 200, 'Response code is %s' % rsp.status_code data = json.loads(rsp.get_data(as_text=True)) check_trakt_fields(data, exact=exact_match)