class TestUserAPI(unittest.TestCase): org = 1 api = API(org=1) def test_login(self): me = self.api.login(email=settings.ADMIN_EMAIL, password=settings.ADMIN_PASSWORD) assert True def test_get(self): me = self.api.me.get() assert self.org in [o['id'] for o in me['orgs']] assert True def test_update_name(self): me1 = self.api.me.get() me2 = self.api.me.update(name=fake.name()) assert me1['name'] != me2['name'] me3 = self.api.me.update(name=me1['name']) assert me1['name'] == me3['name'] def test_update_email(self): me1 = self.api.me.get() me2 = self.api.me.update(email=fake.name()) assert me1['email'] != me2['email'] me3 = self.api.me.update(email=settings.ADMIN_EMAIL) assert me1['email'] == me3['email'] def test_update_password(self): self.api.me.update(old_password=settings.ADMIN_PASSWORD, new_password='******') self.api.me.update(old_password='******', new_password=settings.ADMIN_PASSWORD) self.api.login(email=settings.ADMIN_EMAIL, password=settings.ADMIN_PASSWORD)
def __init__(self, **kw): # parse kwargs org = kw.get('org') recipe = kw.get('recipe') apikey = kw.get('apikey') if not org or not recipe or not apikey: raise SousChefInitError( 'A SousChef requires a "org", "recipe", and "apikey" to run.') # api connection self.api = API(apikey=apikey, org=org['id']) # full org object self.auths = org.pop('auths') self.settings = org.pop('settings') self.users = org.pop('users') self.org = org # options for this recipe self.options = recipe['options'] self.recipe_id = recipe['id'] # passthrough options between jobs. self.last_job = recipe['last_job'] self.next_job = defaultdict()
class TestMetricsAPI(unittest.TestCase): org = 1 api = API(org=1) def test_all(self): resp = self.api.metrics.list() assert (resp['facets'].keys() > 1) assert (len(resp['metrics']) > 1) resp = self.api.metrics.list(content_levels='timeseries') assert (resp['facets'].keys() > 1) for m in resp['metrics']: assert ('timeseries' in m['content_levels']) m = self.api.metrics.list()['metrics'][0] n = fake.name() m2 = self.api.metrics.update(m['id'], name='foo', display_name=n) assert (m2['name'] != 'foo') assert (m['display_name'] != m2['display_name']) r = self.api.metrics.delete(m['id']) assert (r) try: self.api.metrics.get(m['id']) assert False except: assert True
def setup(parser): # dynamically list collections from newslynx.client import API api = API() collections = [c.replace('_', "-") for c in dir(api) if _keep(c)] api_parser = parser.add_parser("api", help="Access API methods.") api_parser.add_argument('collection', type=str, help='The API collection to access.', choices=collections) api_parser.add_argument( 'method', type=str, default=None, help= 'The method for the collection. Use "ls" to list all methods for a given collection.' ) api_parser.add_argument( "-d", "--data", dest="data", help="a .json / .yaml file, or a json string of the request's body") api_parser.add_argument( "-e", "--raise-errors", action='store_true', default=False, help="Raise Errors as statements. If missing, will return JSON.") api_parser.add_argument( '-u', '--apiurl', type=str, default=os.getenv('NEWSLYNX_API_URL'), help="The base url of Newslynx's API. Will default to $NEWSLYNX_API_URL" ) api_parser.add_argument( '-k', '--apikey', dest="apikey", type=str, default=os.getenv('NEWSLYNX_APIKEY'), help="Your API key. Will default to $NEWSLYNX_APIKEY") api_parser.add_argument( '-o', '--org', dest="org", type=str, help="The ID/Slug of the organization you'd like to access. " "Will default to $NEWSLYNX_ORG", default=os.getenv('NEWSLYNX_ORG')) return 'api', run
class TestRecipeAPI(unittest.TestCase): org = 1 api = API(org=1) def test_create(self): recipe = self.api.recipes.get(1) print recipe assert (recipe['status'] == 'uninitialized') recipe = self.api.recipes.update(1, feed_url='yo') print recipe assert (recipe['status'] == 'stable') self.api.recipes.delete(recipe['id']) recipe = self.api.recipes.get(recipe['id']) assert (recipe['status'] == 'inactive')
class TestSettingsAPI(unittest.TestCase): org = 1 api = API(org=1) def test_create(self): n = fake.name() s = self.api.settings.create(name=n, value='bar') assert s['name'] == n # def test_timezone_hack(self): # n = 'timezone' # s = self.api.settings.create(name=n, value='UTC') # assert s['name'] == n # org = self.api.orgs.get(self.org) # assert org.timezone == 'America/New_York' def test_create_json_value(self): n = fake.name() s = self.api.settings.create(name=n, value=['bar'], json_value=True) assert s['json_value'] assert isinstance(s['value'], list) def test_update(self): n = fake.name() s1 = self.api.settings.create(name=n, value='bar') s2 = self.api.settings.update(s1['name'], value='bar2') assert s2['value'] != s1['value'] def test_update_json_vlue(self): n = fake.name() s1 = self.api.settings.create(name=n, value=['bar'], json_value=True) s2 = self.api.settings.update(s1['name'], value=['bar2'], json_value=True) assert s2['value'] != s1['value'] def test_get(self): n = fake.name() s1 = self.api.settings.create(name=n, value='bar') assert s1['name'] == n s2 = self.api.settings.get(n) assert s1['name'] == s2['name'] def test_list(self): n = fake.name() s = self.api.settings.create(name=n, value='bar') assert s['name'] == n s = self.api.settings.list() assert(isinstance(s, list)) assert(n in [ss['name'] for ss in s])
def __init__(self, **kw): # parse required kwargs self.org = kw.pop('org') self.apikey = kw.pop('apikey') self.recipe = kw.pop('recipe', {'id': None}) self.config = copy.copy(settings.CONFIG) if not self.org or not self.recipe or not self.apikey: raise SousChefInitError( 'A SousChef requires a "org", "recipe", and "apikey" to run.') self.passthrough = kw.pop('passthrough', False) self.log = logging.getLogger( self.recipe.get('sous_chef', self.__class__.__name__)) # api connection self.api = API(apikey=self.apikey, org=self.org['id']) # full org object self.auths = self.org.pop('auths', {}) self.settings = self.org.pop('settings', {}) self.users = self.org.pop('users', []) # options for this recipe # allow arbitrary runtime arguments. self.options = self.recipe.get('options', {}) self.recipe_id = self.recipe.get('id', None) # handle cache-clears between jobs. self.next_job = defaultdict(dict) if not self.passthrough: lj = self.recipe.get('last_job', None) if lj is None: self.last_job = defaultdict(dict) elif not isinstance(lj, dict): self.last_job = defaultdict(dict) else: self.last_job = lj # passthrough jobs should not use contextual # variables. else: self.last_job = defaultdict(dict)
def run_recipe(self, recipe, daily=False): """ Run a scheduled recipe indefinitely """ if daily: time_of_day = dates.parse_time_of_day(recipe.time_of_day) seconds_until = dates.seconds_until(time_of_day) time.sleep(seconds_until) # one day in seconds interval = 24 * 60 * 60 else: interval = copy.copy(recipe.interval) while 1: print 'Running: {} at {}'.format(recipe, dates.now()) api = API(apikey=recipe.user.apikey, org=recipe.org_id) # api.recipes.run(recipe.id) time.sleep(interval)
class TestOrgAPI(unittest.TestCase): org = 1 api = API(org=1) # def test_list(self): # orgs = self.api.orgs.list() # assert(isinstance(orgs, list)) # assert(self.org in [o['id'] for o in orgs]) # def test_get(self): # org1 = self.api.orgs.get() # org2 = self.api.orgs.get(org=self.org) # assert org1['id'] is not None and org1['id'] == org2['id'] def test_create(self): n = fake.name() org1 = self.api.orgs.create(name=n, timezone='America/New_York') assert org1['name'] == n assert (settings.SUPER_USER_EMAIL in [u['email'] for u in org1['users']]) self.api.orgs.delete(org1['id'])
def cook(self, recipe): """ Cook a recipe. """ log.info('cooking: {}'.format(self.fmt(recipe))) start = time.time() # api connection. api = API(apikey=recipe.user.apikey, org=recipe.org_id) # cook the recipe try: job = api.recipes.cook(recipe.id) except: log.error('error cooking: {}'.format(self.fmt(recipe))) log.error(format_exc()) else: log.warning('running job {job_id} for: {0}'.format( self.fmt(recipe), **job)) try: # poll the job's status for res in api.jobs.poll(**job): log.warning(res) except: log.error('error loading: {}'.format(self.fmt(recipe))) log.error(format_exc()) else: duration = round((time.time() - start), 2) log.info('cooked in {1}s: {0}'.format(self.fmt(recipe), duration))
def run(opts, **kw): from newslynx.sc import sc_exec from newslynx.lib import serialize from newslynx.cli.common import load_data from newslynx.client import API # connect to the api and fetch org kw['apikey'] = opts.apikey kw['api_url'] = opts.apiurl api = API(apikey=opts.apikey, org=opts.org, api_url=opts.apiurl, raise_errors=True) try: kw['org'] = api.orgs.get(opts.org) except: log.warning('Cannot connect to the API. Running in dev mode.') kw['org'] = {'id': opts.org} # parse body file / json string. recipe = load_data(opts.recipe) if recipe: kw.update(recipe) res = sc_exec.run(opts.sous_chef, **kw) if not res: return # stream output if isgenerator(res): for r in res: sys.stdout.write(serialize.obj_to_json(r) + "\n") # stream else: sys.stdout.write(serialize.obj_to_json(res))
class TestAuthorsAPI(unittest.TestCase): org = 1 api = API(org=1) def test_all(self): n1 = fake.name() a1 = self.api.authors.create(name=n1) assert a1['name'] == n1 n2 = fake.name() a2 = self.api.authors.update(a1['id'], name=n2) assert (a1['name'] != a2['name']) a3 = self.api.authors.get(a2['id']) assert (a3['name'] == a2['name']) n3 = fake.name() a4 = self.api.authors.create(name=n3) ci = self.api.content.get(1) a4 = self.api.authors.add_content_item(a4['id'], ci['id']) a4 = self.api.authors.get(a4['id'], incl_content=True) assert ('content_items' in a4) a5 = self.api.authors.remove_content_item(a4['id'], ci['id']) assert (a5) a6 = self.api.authors.get(a2['id'], incl_content=True) assert (len(a6['content_items']) == 0) a7 = self.api.authors.add_content_item(a4['id'], ci['id']) assert (len(a7['content_items'])) a1 = self.api.authors.merge(a4['id'], a1['id']) assert (len(a1['content_items']))
import gevent import gevent.monkey gevent.monkey.patch_all() from datetime import timedelta from random import choice import requests import time from newslynx.client import API from newslynx.lib import dates from newslynx.lib import rss from newslynx.models import (ExtractCache, URLCache, ThumbnailCache) api = API(org=1, raise_errors=True) # # flush the cache to ensure realstic times. # URLCache.flush() # ExtractCache.flush() # ThumbnailCache.flush() def poll_status_url(status_url): """ Pool a job's status url. """ time.sleep(2) while True: r = requests.get(status_url) time.sleep(1) d = r.json()
class TestContentAPI(unittest.TestCase): org = 1 api = API(org=1) def test_create_content_item_manual_extract(self): c = { 'url': 'https://projects.propublica.org/killing-the-colorado/story/wasting-water-out-west-use-it-or-lose-it', 'type': 'article', 'tag_ids': [13, 14] } c = self.api.content.create(extract=True, **c) assert (len(c['subject_tag_ids']) == 2) assert (len(c['authors']) == 1) assert (c['provenance'] == 'manual') def test_create_content_item_recipe_extract(self): c = { 'url': 'http://www.nytimes.com/2015/06/10/world/middleeast/us-adding-military-advisers-to-reclaim-iraqi-city-officials-say.html?hp&action=click&pgtype=Homepage&module=first-column-region®ion=top-news&WT.nav=top-news', 'type': 'article', 'recipe_id': 1, } c = self.api.content.create(extract=True, **c) assert (c['provenance'] == 'recipe') def test_create_content_item_non_extract_author_ids(self): c = { 'url': 'http://labs.enigma.io/climate-change-map', 'type': 'interactive', 'title': 'This was a story about global warming.', 'authors': [1, 2] } c = self.api.content.create(extract=False, **c) assert (len(c['authors']) == 2) def test_content_facets(self): c = self.api.content.search(facets='all') assert len(c['facets'].keys()) == len(CONTENT_ITEM_FACETS) def test_content_search(self): c = self.api.content.get(1) cis = self.api.content.search(q=c['title'], search='title', sort='relevance') assert (cis['content_items'][0]['title'] == c['title']) def test_content_bad_type(self): try: self.api.content.search(type='foo') except Exception as e: assert (e.status_code == 400) else: assert (False) def test_content_bad_provenance(self): try: self.api.content.search(provenance='foo') except Exception as e: assert (e.status_code == 400) else: assert (False) def test_content_domain_filter(self): cis = self.api.content.search(domain='foodflikjalsdf') assert (len(cis['content_items']) == 0) def test_content_url_regex(self): cis = self.api.content.search(url_regex='.*example.*') if len(cis['content_items']): assert (re.search('.*example.*', cis['content_items'][0]['url'])) def test_update_content(self): n = fake.name() c = self.api.content.get(1) c1 = self.api.content.update(1, title=n) assert (c1['title'] == n) assert (c1['title'] != c['title']) def test_delete_content(self): cis = self.api.content.search(sort='created') c = cis['content_items'][0] ts = self.api.content.get_timeseries(c['id']) assert (len(ts)) r = self.api.content.delete(c['id']) assert (r) try: self.api.content.get_timeseries(c['id']) except Exception as e: assert (e.status_code == 404) def test_add_remove_subject_tag(self): tags = self.api.tags.list(type='subject') t = choice(tags['tags']) cis = self.api.content.search(sort='id', tag_ids='!{}'.format(t['id'])) c1 = choice(cis['content_items']) c2 = self.api.content.add_tag(c1['id'], t['id']) assert (len(c2['subject_tag_ids']) > len(c1['subject_tag_ids'])) c3 = self.api.content.remove_tag(c1['id'], t['id']) assert (len(c3['subject_tag_ids']) == len(c1['subject_tag_ids']))
from newslynx.client import API from pprint import pprint # connect to the API. api = API(apikey="mj", org="texas-tribune") # print the users in this org print "Current Users" print "*" * 60 pprint(api.orgs.list_users()) print "*" * 60 # create a user user = api.orgs.create_user(name="Taylor Swift", email="*****@*****.**", password="******") print "New User" print "*" * 60 pprint(user) print "*" * 60 # login as this user user = api.login(email="*****@*****.**", password="******") print "Tay Tay's API Key" print "*" * 60 pprint(user["apikey"]) print "*" * 60
def get_api(self): return API(apikey=self.apikey)
from newslynx.client import API from pprint import pprint # connect to the API. api = API(apikey='mj') # print the list of orgs you have access to: print api.me.orgs() # >>> [] # create an organization. org = api.orgs.create(name='Texas Tribune', timezone='US/Mountain') print "New Org" print "*" * 60 pprint(org) print "*" * 60 # set this org as the one you want to access api = API(apikey='mj', org=1) # you should now have access to default tags and recipes. tags = api.tags.list() print "New Tags" print "*" * 60 for tag in tags['tags']: print "{slug} {type}".format(**tag) print "*" * 60 # you should now have access to default tags and recipes. recipes = api.recipes.list() print "New Recipes"
from newslynx.client import API from pprint import pprint # connect to the API. api = API(apikey='mj', org='texas-tribune') # print the users in this org print "Current Users" print "*" * 60 pprint(api.orgs.list_users()) print "*" * 60 # create a user user = api.orgs.create_user(name='Taylor Swift', email='*****@*****.**', password='******') print "New User" print "*" * 60 pprint(user) print "*" * 60 # login as this user user = api.login(email='*****@*****.**', password='******') print "Tay Tay's API Key" print "*" * 60 pprint(user['apikey']) print "*" * 60
import gevent import gevent.monkey gevent.monkey.patch_all() from datetime import timedelta from random import choice import requests import time from newslynx.client import API from newslynx.lib import dates from newslynx.lib import rss from newslynx.models import (ExtractCache, URLCache, ThumbnailCache) api = API(org=1) # # flush the cache to ensure realstic times. # URLCache.flush() # ExtractCache.flush() # ThumbnailCache.flush() def poll_status_url(status_url): """ Pool a job's status url. """ time.sleep(2) while True: r = requests.get(status_url) time.sleep(1) d = r.json()
def run(opts, **kwargs): from newslynx.lib import serialize from newslynx.cli.common import load_data # dynamically list collections from newslynx.client import API # connect to the api api = API(apikey=opts.apikey, org=opts.org, api_url=opts.apiurl, raise_errors=opts.raise_errors) # get the collection cobj = None if opts.collection: cobj = getattr(api, opts.collection.replace('-', '_'), None) if not cobj: # report options collections = [c.replace('_', "-") for c in dir(api) if _keep(c)] log.error("Collection '{}' does not exist.".format(opts.collection)) log.warning("Choose from the following collections:\n\t- {}".format( opts.collection, "\n\t- {}".join(collections))) sys.exit(1) # get the method mobj = None if opts.method: mobj = getattr(cobj, opts.method.replace('-', '_'), None) if not mobj: # report options if opts.method != 'ls': log.warning( "Method '{}' does not exist for collection '{}'".format( opts.method, opts.collection)) # compute the tree here to save on processing time. options = [m.replace('_', '-') for m in dir(cobj) if _keep(m)] # list of methods for this collection msg = "choose from the following methods:\n\t- {}"\ .format("\n\t- ".join(options)) log.warning("\n/{}\n".format(opts.collection) + msg) sys.exit(0) # parse body file / json string. d = load_data(opts.data) if d: kwargs.update(d) # execute method try: res = mobj(**kwargs) except KeyboardInterrupt as e: log.warning("\nInterrupted by user. Exiting...\n") sys.exit(2) # interrupt except Exception as e: log.error(format_exc()) sys.exit(1) # stream output if isgenerator(res): for r in res: sys.stdout.write(serialize.obj_to_json(r) + "\n") # stream else: sys.stdout.write(serialize.obj_to_json(res)) sys.stdout.write("\n") sys.exit(0)
class TestTagsAPI(unittest.TestCase): org = 1 api = API(org=1) def test_create_subject_tag(self): n = fake.name() t = self.api.tags.create(name=n, type='subject', color='#fc0') assert t['name'] == n def test_list(self): n = fake.name() t = self.api.tags.create(name=n, type='subject', color='#fc0') assert t['name'] == n tags = self.api.tags.list() assert (n in [t['name'] for t in tags['tags']]) assert (set(['types', 'levels', 'categories']) == set(tags['facets'].keys())) assert (tags['facets']['types']['subject'] > 1) def test_create_impact_tag(self): n = fake.name() t = self.api.tags.create(name=n, type='impact', color='#fc0', category='promotion', level='media') assert (t['name'] == n) def test_create_subject_tag_error(self): n = fake.name() try: t = self.api.tags.create(name=n, type='subject', color='#fc0', category='promotion', level='media') except Exception as e: assert e.status_code == 400 def test_update_tag(self): n = fake.name() t1 = self.api.tags.create(name=n, type='impact', color='#fc0', category='promotion', level='media') t2 = self.api.tags.update(t1['id'], color='#cf0', category='change', level='institution') assert t1['color'] != t2['color'] assert t1['category'] != t2['category'] assert t1['level'] != t2['level'] def test_delete_tag(self): n = fake.name() t1 = self.api.tags.create(name=n, type='impact', color='#fc0', category='promotion', level='media') resp = self.api.tags.delete(t1['id']) assert resp tags = self.api.tags.list()['tags'] assert (t1['id'] not in [t['id'] for t in tags])
class TestOrgAPI(unittest.TestCase): org = 1 api = API(org=1) def test_list(self): orgs = self.api.orgs.list() assert (isinstance(orgs, list)) assert (self.org in [o['id'] for o in orgs]) def test_get(self): org1 = self.api.orgs.get() org2 = self.api.orgs.get(org=self.org) assert org1['id'] is not None and org1['id'] == org2['id'] def test_create(self): n = fake.name() org1 = self.api.orgs.create(name=n, timezone='America/New_York') assert org1['name'] == n assert (settings.SUPER_USER_EMAIL in [u['email'] for u in org1['users']]) self.api.orgs.delete(org1['id']) def test_update(self): n = fake.name() org1 = self.api.orgs.update(org=self.org, name=n) assert org1['name'] == n def test_delete(self): n = fake.name() org1 = self.api.orgs.create(name=n, timezone='America/New_York') resp = self.api.orgs.delete(org=org1['id']) assert resp orgs = self.api.orgs.list() assert (org1['id'] not in [o['id'] for o in orgs]) def test_list_users(self): users = self.api.orgs.list_users() assert (settings.SUPER_USER_EMAIL in [u['email'] for u in users]) def test_get_user(self): user = self.api.orgs.get_user(user=settings.SUPER_USER_EMAIL) assert (self.org in [o['id'] for o in user['orgs']]) def test_create_user(self): email = fake.name().replace(' ', '').strip() + "@foo.com" user = self.api.orgs.create_user(email=email, password='******', name=fake.name()) assert (self.org in [o['id'] for o in user['orgs']]) def test_remove_user(self): email = fake.name().replace(' ', '').strip() + "@foo.com" user = self.api.orgs.create_user(email=email, password='******', name=fake.name()) resp = self.api.orgs.remove_user(user=user['id']) assert resp org = self.api.orgs.get(org=self.org) assert (user['id'] not in [u['id'] for u in org['users']]) def test_add_user(self): email = fake.name().replace(' ', '').strip() + "@foo.com" user = self.api.orgs.create_user(email=email, password='******', name=fake.name()) resp = self.api.orgs.remove_user(user=user['id']) assert resp user = self.api.orgs.add_user(user=user['id']) org = self.api.orgs.get(org=self.org) assert (user['id'] in [u['id'] for u in org['users']])
from newslynx.client import API from pprint import pprint # connect to the API. api = API(apikey='mj', org='texas-tribune') # get recipes associated with the rss feed sous chef recipes = api.recipes.list(sous_chefs='rss-feed-to-article') r = recipes['recipes'][0] pprint(r)
class TestEventsAPI(unittest.TestCase): org = 1 api = API(org=1) def test_create_recipe_event_not_approved(self): e = { 'source_id': '09ac-11e5-8e2a-6c4008aeb606', 'description': 'eos aliquid mollitia dicta', 'body': 'foo bar', 'created': '2015-05-15 09:54:46+00:00', 'url': 'http://example.com/a81857dc-09ac-11e5-8e2a-6c4008aeb606/', 'tag_ids': [1, 2, 3], 'recipe_id': 1, 'authors': ['Stanford Feeney'], 'title': 'laboriosam facilis q', 'img_url': 'http://example.com/a818591c-09ac-11e5-8e9f-6c4008aeb606.jpg', } event = self.api.events.create(**e) assert (event['source_id'] != e['source_id']) assert (not event['source_id'].startswith('manual')) assert (e['tag_ids'] == event['tag_ids']) assert (event['provenance'] == 'recipe') assert (event['status'] != 'approved') def test_create_recipe_event_pending(self): e = { 'source_id': '09ac-11fdasfde5-8e2a-6c4008aeb606', 'description': 'eos aliquid mollitia dicta', 'body': 'foo bar', 'created': '2015-05-15 09:54:46+00:00', 'url': 'http://example.com/a81857dc-09ac-11e5-8e2a-6c4008aeb606/', 'recipe_id': 1, 'authors': ['Stanford Feeney'], 'title': 'laboriosam facilis q', 'img_url': 'http://example.com/a818591c-09ac-11e5-8e9f-6c4008aeb606.jpg', } event = self.api.events.create(**e) assert (event['source_id'] != e['source_id']) assert (not event['source_id'].startswith('manual')) assert (len(event['tag_ids']) == 0) assert (event['provenance'] == 'recipe') assert (event['status'] == 'pending') def test_create_manual_event_not_approved(self): e = { 'source_id': '09ac-11fdasfsafasdfasde5-8e2a-6c4008aeb606', 'description': 'eos aliquid mollitia dicta', 'body': 'foo bar', 'created': '2015-05-15 09:54:46+00:00', 'url': 'http://example.com/a81857dc-09ac-11e5-8e2a-6c4008aeb606/', 'tag_ids': [1, 2, 3], 'authors': ['Stanford Feeney'], 'title': 'laboriosam facilis q', 'img_url': 'http://example.com/a818591c-09ac-11e5-8e9f-6c4008aeb606.jpg', } event = self.api.events.create(**e) assert (event['source_id'] != e['source_id']) assert (event['source_id'].startswith('manual')) assert (len(event['tag_ids']) == 3) assert (event['provenance'] == 'manual') assert (event['status'] != 'approved') def test_create_manual_event_pending(self): e = { 'source_id': '09ac-11fdasffsafddsfsafasdfasdefdsaf5-8e2a-6c4008aeb606', 'description': 'eos aliquid mollitia dicta', 'body': 'foo bar', 'created': '2015-05-15 09:54:46+00:00', 'url': 'http://example.com/a81857dc-09ac-11e5-8e2a-6c4008aeb606/', 'authors': ['Stanford Feeney'], 'title': 'laboriosam facilis q', 'img_url': 'http://example.com/a818591c-09ac-11e5-8e9f-6c4008aeb606.jpg', } event = self.api.events.create(**e) assert (event['source_id'] != e['source_id']) assert (event['source_id'].startswith('manual')) assert (len(event['tag_ids']) == 0) assert (event['provenance'] == 'manual') assert (event['status'] == 'pending') # def test_create_event_with_content_string(self): # t = self.api.content.get(1) # e = { # 'source_id': '09ac-11fdasfsafasdfasdfdsafdfefdsaf5-8e2a-6c4008aeb606', # 'description': 'eos aliquid mollitia dicta', # 'body': 'foo bar {}'.format(t['url']), # 'created': '2015-05-15 09:54:46+00:00', # 'url': 'http://example.com/a81857dc-09ac-11e5-8e2a-6c4008aeb606/', # 'authors': ['Stanford Feeney'], # 'title': 'laboriosam facilis q', # 'img_url': 'http://example.com/a818591c-09ac-11e5-8e9f-6c4008aeb606.jpg', # } # event = self.api.events.create(**e) # assert(len(event['content_items'])) # def test_create_event_with_content_html(self): # t = self.api.content.get(1) # e = { # 'source_id': '09ac-11fdasfsafasdfasdfdsafdfefdsaf5-8e2a-6c4008aeb606', # 'description': 'eos aliquid mollitia dicta', # 'body': 'foo bar <a href="{}"></a>'.format(t['url']), # 'created': '2015-05-15 09:54:46+00:00', # 'url': 'http://example.com/a81857dc-09ac-11e5-8e2a-6c4008aeb606/', # 'authors': ['Stanford Feeney'], # 'title': 'laboriosam facilis q', # 'img_url': 'http://example.com/a818591c-09ac-11e5-8e9f-6c4008aeb606.jpg', # } # event = self.api.events.create(**e) # assert(len(event['content_items'])) def test_search_and_delete_events(self): s = 'this is a unique string' e = { 'source_id': '09ac-11fdasfsafasdfdasfddsafasdfdsafdfefdsaf5-8e2a-6c4008aeb606', 'description': 'eos aliquid mollitia dicta', 'body': s, 'created': '2015-05-15 09:54:46+00:00', 'url': 'http://example.com/a81857dc-09ac-11e5-8e2a-6c4008aeb606/', 'authors': ['Stanford Feeney'], 'title': 'laboriosam facilis q', 'img_url': 'http://example.com/a818591c-09ac-11e5-8e9f-6c4008aeb606.jpg', } self.api.events.create(**e) results = self.api.events.search(q=s, incl_body=True) for r in results['events']: assert (s in r['body']) self.api.events.delete(r['id'], force=True) def test_error_on_create_deleted_events(self): event = self.api.events.search(status='deleted', provenance='recipe') e = event['events'][0] e.pop('status', None) e['source_id'] = e['source_id'].split(':')[1] try: self.api.events.create(**e) except Exception as e: assert (e.status_code == 422) else: assert False def test_null_on_create_event_with_no_content_items(self): r = self.api.events.search(status='pending', incl_body=True) e = r['events'][0] e.pop('id') e['must_link'] = True resp = self.api.events.create(**e) assert (resp is None) def test_event_update(self): res = self.api.events.search(status='pending', provenance='recipe', incl_body=True) event = res['events'][0] event['content_item_ids'] = [1, 2] event['tag_ids'] = [1, 2] event['status'] = 'approved' event = self.api.events.update(event['id'], **event) assert (len(event['content_items'])) assert (len(event['tag_ids'])) assert (event['status'] == 'approved') def test_event_delete_no_force(self): res = self.api.events.search(status='pending') event = res['events'][0] resp = self.api.events.delete(event['id']) assert (resp) resp = self.api.events.get(event['id']) assert (resp['id'] == event['id']) assert (resp['status'] == 'deleted') def test_event_delete_force(self): res = self.api.events.search(status='pending') event = res['events'][0] resp = self.api.events.delete(event['id'], force=True) assert (resp) try: self.api.events.get(event['id']) except Exception as e: assert (e.status_code == 404) else: assert False def test_event_add_delete_tag(self): res = self.api.events.search(status='approved', per_page=1) event = res['events'][0] event = self.api.events.add_tag(event['id'], 1) assert (1 in event['tag_ids']) event = self.api.events.remove_tag(event['id'], 1) assert (1 not in event['tag_ids']) def test_event_add_delete_content_item(self): res = self.api.events.search(status='approved', per_page=1) event = res['events'][0] event = self.api.events.add_content_item(event['id'], 1) assert (1 in [t['id'] for t in event['content_items']]) event = self.api.events.remove_content_item(event['id'], 1) assert (1 not in [t['id'] for t in event['content_items']]) def test_event_facet_by_provenance(self): res = self.api.events.search(status='approved', per_page=1, facets='provenances') assert (res['total'] == sum( [f['count'] for f in res['facets']['provenances']])) def test_event_facet_by_status(self): res = self.api.events.search(status='approved', per_page=1, facets='statuses') assert (res['total'] == sum( [f['count'] for f in res['facets']['statuses']]))