Ejemplo n.º 1
0
class FakeStream(object):
    def __init__(self):
        self.resp = FakeResponse(None)
        self._message_types = {}

    def add_message_type(self, message_type, predicate):
        self._message_types[message_type] = predicate

    def accepts(self, message_type, data):
        predicate = self._message_types.get(message_type)
        return predicate is not None and predicate(data)

    def deliver(self, data):
        self.resp.deliver_data(json.dumps(data))
        self.resp.deliver_data('\r\n')
Ejemplo n.º 2
0
    def test_stream_filter_track(self):
        agent, client = self._agent_and_TwitterClient()
        uri = 'https://stream.twitter.com/1.1/statuses/filter.json'
        stream = FakeResponse(None)
        agent.add_expected_request('POST', uri, {'track': 'foo,bar'}, stream)

        connected = Deferred()
        tweets = []
        svc = client.stream_filter(tweets.append, track=['foo', 'bar'])
        svc.set_connect_callback(connected.callback)
        svc.startService()
        connected_svc = yield connected
        self.assertIs(svc, connected_svc)
        self.assertEqual(tweets, [])

        stream.deliver_data(
            '{"id_str": "1", "text": "Tweet 1", "user": {}}\r\n')
        self.assertEqual(tweets, [
            {"id_str": "1", "text": "Tweet 1", "user": {}},
        ])
        stream.deliver_data(
            '{"id_str": "2", "text": "Tweet 2", "user": {}}\r\n')
        self.assertEqual(tweets, [
            {"id_str": "1", "text": "Tweet 1", "user": {}},
            {"id_str": "2", "text": "Tweet 2", "user": {}},
        ])
        yield svc.stopService()
        stream.finished()
Ejemplo n.º 3
0
    def test_userstream_user_with_user(self):
        agent, client = self._agent_and_TwitterClient()
        uri = 'https://userstream.twitter.com/1.1/user.json'
        stream = FakeResponse(None)
        agent.add_expected_request('GET', uri, {
            'stringify_friend_ids': 'true',
            'with': 'user',
        }, stream)

        connected = Deferred()
        tweets = []
        svc = client.userstream_user(tweets.append, with_='user')
        svc.set_connect_callback(connected.callback)
        svc.startService()
        connected_svc = yield connected
        self.assertIs(svc, connected_svc)
        self.assertEqual(tweets, [])

        stream.deliver_data(
            '{"friends_str": []}\r\n'
            '{"id_str": "1", "text": "Tweet 1", "user": {}}\r\n')
        self.assertEqual(tweets, [
            {"friends_str": []},
            {"id_str": "1", "text": "Tweet 1", "user": {}},
        ])
        stream.deliver_data(
            '{"id_str": "2", "text": "Tweet 2", "user": {}}\r\n')
        self.assertEqual(tweets, [
            {"friends_str": []},
            {"id_str": "1", "text": "Tweet 1", "user": {}},
            {"id_str": "2", "text": "Tweet 2", "user": {}},
        ])
        yield svc.stopService()
        stream.finished()
Ejemplo n.º 4
0
    def test_HTTP_500_schedules_reconnect(self):
        """
        An HTTP error should schedule a reconnection attempt.
        """
        d = Deferred()
        svc = self._TwitterStreamService(lambda: d, None)
        svc.clock = Clock()
        svc.startService()

        d.callback(FakeResponse(None, 500))
        self.assertEqual(svc._connect, svc._reconnect_delayedcall.func)
Ejemplo n.º 5
0
    def test_stream_filter_all_params(self):
        agent, client = self._agent_and_TwitterClient()
        uri = 'https://stream.twitter.com/1.1/statuses/filter.json'
        stream = FakeResponse(None)
        expected_params = {
            'follow': 'Alice,Bob',
            'track': 'foo,bar',
            'stall_warnings': 'true',
        }
        agent.add_expected_request('POST', uri, expected_params, stream)

        connected = Deferred()
        svc = client.stream_filter(
            lambda tweet: None, follow=['Alice', 'Bob'], track=['foo', 'bar'],
            stall_warnings=True)
        svc.set_connect_callback(connected.callback)
        svc.startService()
        connected_svc = yield connected
        self.assertIs(svc, connected_svc)
        yield svc.stopService()
        stream.finished()
Ejemplo n.º 6
0
 def test_connect_callback(self):
     """
     The connect callback should be called on a successful connection.
     """
     d = Deferred()
     called = []
     svc = self._TwitterStreamService(lambda: d, None)
     svc.set_connect_callback(lambda s: called.append(s))
     svc.startService()
     self.assertEqual(called, [])
     d.callback(FakeResponse(None))
     self.assertEqual(called, [svc])
Ejemplo n.º 7
0
    def test_userstream_user_all_params(self):
        agent, client = self._agent_and_TwitterClient()
        uri = 'https://userstream.twitter.com/1.1/user.json'
        stream = FakeResponse(None)
        agent.add_expected_request('GET', uri, {
            'stringify_friend_ids': 'true',
            'stall_warnings': 'true',
            'with': 'user',
            'replies': 'all',
        }, stream)

        connected = Deferred()
        svc = client.userstream_user(
            lambda tweet: None, stall_warnings=True, with_='user',
            replies='all')
        svc.set_connect_callback(connected.callback)
        svc.startService()
        connected_svc = yield connected
        self.assertIs(svc, connected_svc)
        yield svc.stopService()
        stream.finished()
Ejemplo n.º 8
0
    def test_rate_limit_second_reconnect_delay(self):
        """
        The second HTTP rate limit response should double the reconnect delay.
        """
        d = Deferred()
        svc = self._TwitterStreamService(lambda: d, None)
        svc.clock = Clock()
        svc.reconnect_delay = 60
        svc.startService()

        d.callback(FakeResponse(None, 420))
        self.assertEqual(svc.reconnect_delay, 120)
Ejemplo n.º 9
0
    def test_reconnect(self):
        """
        A reconnect should wait for the required amount of time and then
        attempt to connect again.
        """
        d1 = Deferred()
        d2 = Deferred()
        connect_deferreds = [d1, d2]
        called = []
        svc = self._TwitterStreamService(
            lambda: connect_deferreds.pop(0), None)
        svc.set_connect_callback(lambda s: called.append(s))
        svc.clock = Clock()
        svc.startService()
        d1.callback(FakeResponse(None, 500))
        self.assertEqual([], called)

        svc.clock.advance(svc.reconnect_delay)
        self.assertEqual(svc._reconnect_delayedcall, None)
        d2.callback(FakeResponse(None))
        self.assertEqual([svc], called)
Ejemplo n.º 10
0
    def test_userstream_user_with_user(self):
        agent, client = self._agent_and_TwitterClient()
        uri = 'https://userstream.twitter.com/1.1/user.json'
        stream = FakeResponse(None)
        agent.add_expected_request('GET', uri, {
            'stringify_friend_ids': 'true',
            'with': 'user',
        }, stream)

        connected = Deferred()
        tweets = []
        svc = client.userstream_user(tweets.append, with_='user')
        svc.set_connect_callback(connected.callback)
        svc.startService()
        connected_svc = yield connected
        self.assertIs(svc, connected_svc)
        self.assertEqual(tweets, [])

        stream.deliver_data(
            '{"friends_str": []}\r\n'
            '{"id_str": "1", "text": "Tweet 1", "user": {}}\r\n')
        self.assertEqual(tweets, [
            {
                "friends_str": []
            },
            {
                "id_str": "1",
                "text": "Tweet 1",
                "user": {}
            },
        ])
        stream.deliver_data(
            '{"id_str": "2", "text": "Tweet 2", "user": {}}\r\n')
        self.assertEqual(tweets, [
            {
                "friends_str": []
            },
            {
                "id_str": "1",
                "text": "Tweet 1",
                "user": {}
            },
            {
                "id_str": "2",
                "text": "Tweet 2",
                "user": {}
            },
        ])
        yield svc.stopService()
        stream.finished()
Ejemplo n.º 11
0
    def test_HTTP_500_max_reconnect_delay(self):
        """
        The reconnect delay should never go over the maximum of ten minutes.
        """
        d = Deferred()
        svc = self._TwitterStreamService(lambda: d, None)
        svc.clock = Clock()
        svc.reconnect_delay = 60 * 60 * 24
        svc.startService()

        self.assertEqual(svc.reconnect_delay, 60 * 60 * 24)
        d.callback(FakeResponse(None, 500))
        self.assertEqual(svc.reconnect_delay, 60 * 10)
Ejemplo n.º 12
0
    def test_rate_limit_initial_reconnect_delay_existing_delay(self):
        """
        The first HTTP rate limit response should set the reconnect delay to
        one minute if there is an existing delay less than this.
        """
        d = Deferred()
        svc = self._TwitterStreamService(lambda: d, None)
        svc.clock = Clock()
        svc.reconnect_delay = 16
        svc.startService()

        d.callback(FakeResponse(None, 420))
        self.assertEqual(svc.reconnect_delay, 60)
Ejemplo n.º 13
0
    def test_stream_filter_all_params(self):
        agent, client = self._agent_and_TwitterClient()
        uri = 'https://stream.twitter.com/1.1/statuses/filter.json'
        stream = FakeResponse(None)
        expected_params = {
            'follow': 'Alice,Bob',
            'track': 'foo,bar',
            'stall_warnings': 'true',
        }
        agent.add_expected_request('POST', uri, expected_params, stream)

        connected = Deferred()
        svc = client.stream_filter(lambda tweet: None,
                                   follow=['Alice', 'Bob'],
                                   track=['foo', 'bar'],
                                   stall_warnings=True)
        svc.set_connect_callback(connected.callback)
        svc.startService()
        connected_svc = yield connected
        self.assertIs(svc, connected_svc)
        yield svc.stopService()
        stream.finished()
Ejemplo n.º 14
0
    def test_HTTP_500_initial_reconnect_delay(self):
        """
        The first HTTP error response should set the initial reconnect delay to
        one second.
        """
        d = Deferred()
        svc = self._TwitterStreamService(lambda: d, None)
        svc.clock = Clock()
        svc.startService()

        self.assertEqual(svc.reconnect_delay, 0)
        d.callback(FakeResponse(None, 500))
        self.assertEqual(svc.reconnect_delay, 1)
Ejemplo n.º 15
0
    def test_HTTP_500_second_reconnect_delay(self):
        """
        An HTTP error response when we already have a reconnect delay should
        double the delay and attempt to reconnect again.
        """
        d = Deferred()
        svc = self._TwitterStreamService(lambda: d, None)
        svc.clock = Clock()
        svc.reconnect_delay = 1
        svc.startService()

        self.assertEqual(svc.reconnect_delay, 1)
        d.callback(FakeResponse(None, 500))
        self.assertEqual(svc.reconnect_delay, 2)
Ejemplo n.º 16
0
    def test_userstream_user_all_params(self):
        agent, client = self._agent_and_TwitterClient()
        uri = 'https://userstream.twitter.com/1.1/user.json'
        stream = FakeResponse(None)
        agent.add_expected_request(
            'GET', uri, {
                'stringify_friend_ids': 'true',
                'stall_warnings': 'true',
                'with': 'user',
                'replies': 'all',
            }, stream)

        connected = Deferred()
        svc = client.userstream_user(lambda tweet: None,
                                     stall_warnings=True,
                                     with_='user',
                                     replies='all')
        svc.set_connect_callback(connected.callback)
        svc.startService()
        connected_svc = yield connected
        self.assertIs(svc, connected_svc)
        yield svc.stopService()
        stream.finished()
Ejemplo n.º 17
0
    def test_HTTP_500_calls_disconnect_callback(self):
        """
        An HTTP error should schedule a reconnection attempt.
        """
        from txtwitter.error import TwitterAPIError
        d = Deferred()
        called = []
        svc = self._TwitterStreamService(lambda: d, None)
        svc.set_disconnect_callback(lambda s, r: called.append(r))
        svc.clock = Clock()
        svc.startService()

        d.callback(FakeResponse(None, 500))
        [failure] = called
        self.assertEqual(TwitterAPIError, type(failure.value))
Ejemplo n.º 18
0
    def test_stop_service_connected(self):
        """
        Stopping a connected service should close the connection cleanly.
        """
        d = Deferred()
        called = []
        svc = self._TwitterStreamService(lambda: d, None)
        svc.set_disconnect_callback(lambda s, r: called.append(r))
        svc.startService()
        d.callback(FakeResponse(None))
        self.assertEqual(svc.running, True)

        svc.stopService()
        self.assertEqual(svc.running, False)
        [failure] = called
        self.assertEqual(ResponseDone, type(failure.value))
Ejemplo n.º 19
0
    def test_connect_callback_None(self):
        """
        The connect callback should not be called if it is unset.

        It's hard to assert that something /doesn't/ happen, so we make sure we
        see something else that happens at connect time and assert that no
        errors were logged.
        """
        d = Deferred()
        svc = self._TwitterStreamService(lambda: d, None)
        svc.startService()
        self.assertEqual(None, svc.connect_callback)
        self.assertEqual(None, svc._stream_response)
        d.callback(FakeResponse(None))
        self.assertNotEqual(None, svc._stream_response)
        self.assertEqual([], self.flushLoggedErrors())
Ejemplo n.º 20
0
    def test_stream_filter_track(self):
        agent, client = self._agent_and_TwitterClient()
        uri = 'https://stream.twitter.com/1.1/statuses/filter.json'
        stream = FakeResponse(None)
        agent.add_expected_request('POST', uri, {'track': 'foo,bar'}, stream)

        connected = Deferred()
        tweets = []
        svc = client.stream_filter(tweets.append, track=['foo', 'bar'])
        svc.set_connect_callback(connected.callback)
        svc.startService()
        connected_svc = yield connected
        self.assertIs(svc, connected_svc)
        self.assertEqual(tweets, [])

        stream.deliver_data(
            '{"id_str": "1", "text": "Tweet 1", "user": {}}\r\n')
        self.assertEqual(tweets, [
            {
                "id_str": "1",
                "text": "Tweet 1",
                "user": {}
            },
        ])
        stream.deliver_data(
            '{"id_str": "2", "text": "Tweet 2", "user": {}}\r\n')
        self.assertEqual(tweets, [
            {
                "id_str": "1",
                "text": "Tweet 1",
                "user": {}
            },
            {
                "id_str": "2",
                "text": "Tweet 2",
                "user": {}
            },
        ])
        yield svc.stopService()
        stream.finished()
Ejemplo n.º 21
0
    def test_stop_service_pending_reconnect(self):
        """
        Stopping a service with a pending reconnect should cancel the
        reconnect.
        """
        d = Deferred()
        called = []
        svc = self._TwitterStreamService(lambda: d, None)
        svc.set_disconnect_callback(lambda s, r: called.append(r))
        svc.clock = Clock()
        svc.startService()
        d.callback(FakeResponse(None, 500))
        self.assertEqual(svc.running, True)
        self.assertNotEqual(svc._reconnect_delayedcall, None)
        self.assertEqual(len(called), 1)
        self.assertNotEqual(svc.reconnect_delay, 0)

        svc.stopService()
        self.assertEqual(svc.running, False)
        self.assertEqual(svc._reconnect_delayedcall, None)
        self.assertEqual(svc.reconnect_delay, 0)
Ejemplo n.º 22
0
 def __init__(self):
     self.resp = FakeResponse(None)
     self._message_types = {}
Ejemplo n.º 23
0
 def _resp_json(self, data, code=200):
     return FakeResponse(json.dumps(data), code)