示例#1
0
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)
示例#2
0
    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
示例#4
0
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
示例#5
0
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])
示例#7
0
    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)
示例#8
0
    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)
示例#9
0
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'])
示例#10
0
    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))
示例#11
0
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))
示例#12
0
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']))
示例#13
0
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()
示例#14
0
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&region=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']))
示例#15
0
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
示例#16
0
 def get_api(self):
     return API(apikey=self.apikey)
示例#17
0
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"
示例#18
0
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
示例#19
0
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()
示例#20
0
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)
示例#21
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])
示例#22
0
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']])
示例#23
0
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)
示例#24
0
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']]))