Exemplo n.º 1
0
    def setUp(self, *args, **kwargs):
        yield super(TestTwitterWeb, self).setUp(*args, **kwargs)
        self.service = TwitterWeb(
            datastore=self.app.db,
        )
        self.daemon = self.service.daemon_object()

        recorder.wrap(self.service.actually_request)
        recorder.wrap(self.daemon.actually_request)
        recorder.wrap(requests.request)
Exemplo n.º 2
0
class TestTwitterWeb(TestTwitter):
    @defer.inlineCallbacks
    def setUp(self, *args, **kwargs):
        yield super(TestTwitterWeb, self).setUp(*args, **kwargs)
        self.service = TwitterWeb(
            datastore=self.app.db,
        )
        self.daemon = self.service.daemon_object()

        recorder.wrap(self.service.actually_request)
        recorder.wrap(self.daemon.actually_request)
        recorder.wrap(requests.request)
        # recorder.record()

    def tearDown(self):
        recorder.save()
        super(TestTwitterWeb, self).tearDown()

    def submit_login_form(self, uri, args):
        login_form = requests.get(
            uri,
            headers=self.headers(),
        )
        self.assertNotEqual(login_form.status_code, 404)

        # Get the request to be the actual request we need for the CSRF bypass
        # in the post() below.
        login_form = self.follow_redirect_until_not(
            login_form,
            r'twitter.com/',
        )
        soup = BeautifulSoup(login_form.content)

        arguments = self.extract_form_fields(soup.form)
        arguments['session[username_or_email]'] = args['username']
        arguments['session[password]'] = args['password']
        del arguments['cancel']

        return requests.post(
            soup.form['action'],
            headers=self.headers(),
            data=arguments,
            cookies=login_form.cookies,
            # We need to trap the redirect back to localhost:5000
            allow_redirects=False,
        )

    @defer.inlineCallbacks
    def test_authorize(self):
        redir_uri = 'https://lg-local.example.com/id/auth/callback/twitter'

        # Just match a regex since we'll also get back a requestToken from
        # this since it's an OAuth 1.0 Service.

        expected_redirect = r'https://api.twitter.com/oauth/authorize\?oauth_token='

        # resp = self.get_and_verify(
        #     path='/auth',
        #     args=dict(service='twitter', redirect_uri=redir_uri),
        #     response_code=200,
        # )
        redirect_uri = yield self.service.start_authorization(
            client_name='testing',
            args={'redirect_uri': redir_uri},
        )
        self.assertRegexpMatches(redirect_uri, expected_redirect)
        response = self.submit_login_form(
            uri=redirect_uri,
            args=dict(
                username=AUTHN_TEST_USER['email'],
                password=AUTHN_TEST_USER['password'],
            ),
        )

        self.assertNotEqual(response.status_code, 404)
        response = self.follow_redirect_until_not(response, r'twitter.com')

        # So, Twitter's super cool and doesn't 302 us.
        # Instead, we get back a 200 page with a meta http-equiv refresh set
        # to our callback page. Here, we parse this page and grab the args.
        # This is pretty brittle.
        self.assertEqual(response.status_code, 200)
        soup = BeautifulSoup(response.content)
        meta_redir = soup.findAll('meta', {'http-equiv': 'refresh'})[0]
        # Strip off the URL and get the QS
        meta_qs = meta_redir['content'][6:].split('?')[1]
        args = dict(parse_qsl(meta_qs))

        auth = yield self.service.finish_authorization(
            client_name='testing',
            args=args,
        )

        oauth_token = auth.token
        user_id = auth.user_id
        oauth_secret = auth.secret

        self.assertEqual(AUTHN_TEST_USER['id'], user_id)
        yield self.set_authorization(
            user_id=user_id,
            token=oauth_token,
            secret=oauth_secret
        )

        yield self.run_daemon()
        profile = yield self.call_method('profile')

        expected_profile = dict(
            name=AUTHN_TEST_USER['name'],
            username=AUTHN_TEST_USER['username'],
            bio=AUTHN_TEST_USER['bio'],
            profile_link=AUTHN_TEST_USER['profile_link'],
            profile_picture_link=AUTHN_TEST_USER['profile_picture_link'],
        )
        self._test_method_result_keys('profile', profile, expected_profile)

        num_followers = yield self.call_method('num_followers')
        self.assertEqual(
            num_followers, {'num': AUTHN_TEST_USER['num_followers']}
        )
        num_following = yield self.call_method('num_following')
        self.assertEqual(
            num_following, {'num': AUTHN_TEST_USER['num_following']}
        )
        num_tweets = yield self.call_method('num_tweets')
        self.assertEqual(
            num_tweets, {'num': AUTHN_TEST_USER['num_tweets']}
        )
        num_favorites = yield self.call_method('num_favorites')
        self.assertEqual(
            num_favorites, {'num': AUTHN_TEST_USER['num_favorites']}
        )
        num_listed = yield self.call_method('num_listed')
        self.assertEqual(
            num_listed, {'num': AUTHN_TEST_USER['num_listed']}
        )
        num_follow_requests = yield self.call_method('num_follow_requests')
        self.assertEqual(
            num_follow_requests, {'num': AUTHN_TEST_USER['num_follow_requests']}
        )
        num_retweets = yield self.call_method('num_retweets')
        self.assertEqual(
            num_retweets, {'num': AUTHN_TEST_USER['num_retweets']}
        )
        num_mentions = yield self.call_method('num_mentions')
        self.assertEqual(
            num_mentions, {'num': AUTHN_TEST_USER['num_mentions']}
        )
        num_direct_messages = yield self.call_method('num_direct_messages')
        self.assertEqual(
            num_direct_messages, {'num': AUTHN_TEST_USER['num_direct_messages']}
        )
        account_created_timestamp = yield self.call_method('account_created_timestamp')
        self.assertEqual(
            account_created_timestamp, {'timestamp': AUTHN_TEST_USER['account_created_timestamp']}
        )

    def test_methods(self):
        self.assertEqual(self.service.methods(), {
            'GET': {
                'most_recent_activity': "The most recent activity on this service's feed",
                'profile': "Returns this user's profile.",
                'person_mentioned': 'Retrieve data for all mentions, storing the results granularly.',
                'num_followers': 'Number of followers',
                'num_followers_interval': 'Number of followers over time',
                'num_following': 'Number of users followed',
                'num_following_interval': 'Number of users followed over time',
                'num_tweets': 'Number of tweets',
                'num_tweets_interval': 'Number of tweets over time',
                'num_favorites': 'Number of favorites',
                'num_favorites_interval': 'Number of favorites over time',
                'num_listed': 'Number of times listed',
                'num_listed_interval': 'Number of times listed over time',
                'num_follow_requests': 'Number of follow requests',
                'num_follow_requests_interval': 'Number of follow requests over time',
                'num_retweets': 'Number of retweets',
                'num_retweets_interval': 'Number of retweets over time',
                'num_mentions': 'Number of mentions',
                'num_mentions_interval': 'Number of mentions over time',
                'num_direct_messages': 'Number of direct_messages',
                'num_direct_messages_interval': 'Number of direct_messages over time',
                'account_created_timestamp': 'Returns the timestamp this user account was created on',
            },
            'POST': {
                'create_tweet': 'Create a tweet on behalf of a user',
                'favorite_tweet': 'Favorite a tweet on behalf of a user',
                'unfavorite_tweet': 'Unfavorite a tweet on behalf of a user',
                'retweet_tweet': 'Retweet a tweet on behalf of a user',
                'reply_to_tweet': 'Reply to a tweet on behalf of a user',
            },
        })

    @defer.inlineCallbacks
    def test_num_followers_and_interval(self, **kwargs):
        yield self.set_authorization()

        yield self.write_value(method='num_followers', data='10', timestamp=100)
        rv = yield self.call_method('num_followers')
        self.assertEqual(rv, {'num': 10})
        rv = yield self.call_method('num_followers_interval',
            arguments=dict(start=90, end=110),
        )
        self.assertEqual(rv, {'data': [
            {'timestamp': '100', 'num': 10},
        ]})

        yield self.write_value(method='num_followers', data='12', timestamp=105)
        rv = yield self.call_method('num_followers')
        self.assertEqual(rv, {'num': 12})
        rv = yield self.call_method('num_followers_interval',
            arguments=dict(start=90, end=110),
        )
        self.assertEqual(rv, {'data': [
            {'timestamp': '100', 'num': 10},
            {'timestamp': '105', 'num': 12},
        ]})

    @defer.inlineCallbacks
    def test_num_following_and_interval(self, **kwargs):
        yield self.set_authorization()

        yield self.write_value(method='num_following', data='10', timestamp=100)
        rv = yield self.call_method('num_following')
        self.assertEqual(rv, {'num': 10})
        rv = yield self.call_method('num_following_interval',
            arguments=dict(start=90, end=110),
        )
        self.assertEqual(rv, {'data': [
            {'timestamp': '100', 'num': 10},
        ]})

        yield self.write_value(method='num_following', data='12', timestamp=105)
        rv = yield self.call_method('num_following')
        self.assertEqual(rv, {'num': 12})
        rv = yield self.call_method('num_following_interval',
            arguments=dict(start=90, end=110),
        )
        self.assertEqual(rv, {'data': [
            {'timestamp': '100', 'num': 10},
            {'timestamp': '105', 'num': 12},
        ]})

    @defer.inlineCallbacks
    def test_num_tweets_and_interval(self, **kwargs):
        yield self.set_authorization()

        yield self.write_value(method='num_tweets', data='10', timestamp=100)
        rv = yield self.call_method('num_tweets')
        self.assertEqual(rv, {'num': 10})
        rv = yield self.call_method('num_tweets_interval',
            arguments=dict(start=90, end=110),
        )
        self.assertEqual(rv, {'data': [
            {'timestamp': '100', 'num': 10},
        ]})

        yield self.write_value(method='num_tweets', data='12', timestamp=105)
        rv = yield self.call_method('num_tweets')
        self.assertEqual(rv, {'num': 12})
        rv = yield self.call_method('num_tweets_interval',
            arguments=dict(start=90, end=110),
        )
        self.assertEqual(rv, {'data': [
            {'timestamp': '100', 'num': 10},
            {'timestamp': '105', 'num': 12},
        ]})

    @defer.inlineCallbacks
    def test_num_favorites_and_interval(self, **kwargs):
        yield self.set_authorization()

        yield self.write_value(method='num_favorites', data='10', timestamp=100)
        rv = yield self.call_method('num_favorites')
        self.assertEqual(rv, {'num': 10})
        rv = yield self.call_method('num_favorites_interval',
            arguments=dict(start=90, end=110),
        )
        self.assertEqual(rv, {'data': [
            {'timestamp': '100', 'num': 10},
        ]})

        yield self.write_value(method='num_favorites', data='12', timestamp=105)
        rv = yield self.call_method('num_favorites')
        self.assertEqual(rv, {'num': 12})
        rv = yield self.call_method('num_favorites_interval',
            arguments=dict(start=90, end=110),
        )
        self.assertEqual(rv, {'data': [
            {'timestamp': '100', 'num': 10},
            {'timestamp': '105', 'num': 12},
        ]})

    @defer.inlineCallbacks
    def test_num_listed_and_interval(self, **kwargs):
        yield self.set_authorization()

        yield self.write_value(method='num_listed', data='10', timestamp=100)
        rv = yield self.call_method('num_listed')
        self.assertEqual(rv, {'num': 10})
        rv = yield self.call_method('num_listed_interval',
            arguments=dict(start=90, end=110),
        )
        self.assertEqual(rv, {'data': [
            {'timestamp': '100', 'num': 10},
        ]})

        yield self.write_value(method='num_listed', data='12', timestamp=105)
        rv = yield self.call_method('num_listed')
        self.assertEqual(rv, {'num': 12})
        rv = yield self.call_method('num_listed_interval',
            arguments=dict(start=90, end=110),
        )
        self.assertEqual(rv, {'data': [
            {'timestamp': '100', 'num': 10},
            {'timestamp': '105', 'num': 12},
        ]})

    @defer.inlineCallbacks
    def test_num_follow_requests_and_interval(self, **kwargs):
        yield self.set_authorization()

        yield self.write_value(method='num_follow_requests', data='10', timestamp=100)
        rv = yield self.call_method('num_follow_requests')
        self.assertEqual(rv, {'num': 10})
        rv = yield self.call_method('num_follow_requests_interval',
            arguments=dict(start=90, end=110),
        )
        self.assertEqual(rv, {'data': [
            {'timestamp': '100', 'num': 10},
        ]})

        yield self.write_value(method='num_follow_requests', data='12', timestamp=105)
        rv = yield self.call_method('num_follow_requests')
        self.assertEqual(rv, {'num': 12})
        rv = yield self.call_method('num_follow_requests_interval',
            arguments=dict(start=90, end=110),
        )
        self.assertEqual(rv, {'data': [
            {'timestamp': '100', 'num': 10},
            {'timestamp': '105', 'num': 12},
        ]})

    @defer.inlineCallbacks
    def test_num_retweets_and_interval(self, **kwargs):
        yield self.set_authorization()

        yield self.write_value(method='num_retweets', data='10', timestamp=100)
        rv = yield self.call_method('num_retweets')
        self.assertEqual(rv, {'num': 10})
        rv = yield self.call_method('num_retweets_interval',
            arguments=dict(start=90, end=110),
        )
        self.assertEqual(rv, {'data': [
            {'timestamp': '100', 'num': 10},
        ]})

        yield self.write_value(method='num_retweets', data='12', timestamp=105)
        rv = yield self.call_method('num_retweets')
        self.assertEqual(rv, {'num': 12})
        rv = yield self.call_method('num_retweets_interval',
            arguments=dict(start=90, end=110),
        )
        self.assertEqual(rv, {'data': [
            {'timestamp': '100', 'num': 10},
            {'timestamp': '105', 'num': 12},
        ]})

    @defer.inlineCallbacks
    def test_num_mentions_and_interval(self, **kwargs):
        yield self.set_authorization()

        yield self.write_value(method='num_mentions', data='10', timestamp=100)
        rv = yield self.call_method('num_mentions')
        self.assertEqual(rv, {'num': 10})
        rv = yield self.call_method('num_mentions_interval',
            arguments=dict(start=90, end=110),
        )
        self.assertEqual(rv, {'data': [
            {'timestamp': '100', 'num': 10},
        ]})

        yield self.write_value(method='num_mentions', data='12', timestamp=105)
        rv = yield self.call_method('num_mentions')
        self.assertEqual(rv, {'num': 12})
        rv = yield self.call_method('num_mentions_interval',
            arguments=dict(start=90, end=110),
        )
        self.assertEqual(rv, {'data': [
            {'timestamp': '100', 'num': 10},
            {'timestamp': '105', 'num': 12},
        ]})

    @defer.inlineCallbacks
    def test_num_direct_messages_and_interval(self, **kwargs):
        yield self.set_authorization()

        yield self.write_value(method='num_direct_messages', data='10', timestamp=100)
        rv = yield self.call_method('num_direct_messages')
        self.assertEqual(rv, {'num': 10})
        rv = yield self.call_method('num_direct_messages_interval',
            arguments=dict(start=90, end=110),
        )
        self.assertEqual(rv, {'data': [
            {'timestamp': '100', 'num': 10},
        ]})

        yield self.write_value(method='num_direct_messages', data='12', timestamp=105)
        rv = yield self.call_method('num_direct_messages')
        self.assertEqual(rv, {'num': 12})
        rv = yield self.call_method('num_direct_messages_interval',
            arguments=dict(start=90, end=110),
        )
        self.assertEqual(rv, {'data': [
            {'timestamp': '100', 'num': 10},
            {'timestamp': '105', 'num': 12},
        ]})