script/lib/tweetstream/tests/test_tweetstream.py
changeset 527 80e5b9543cac
parent 207 621fa6caec0c
parent 14 10e7a0c7c64f
equal deleted inserted replaced
526:3c14302784f8 527:80e5b9543cac
     1 import contextlib
     1 import contextlib
     2 import threading
     2 import threading
     3 import time
     3 import time
     4 from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
       
     5 
     4 
     6 from tweetstream import TweetStream, FollowStream, TrackStream, LocationStream
     5 from tweetstream import TweetStream, FollowStream, TrackStream, LocationStream
     7 from tweetstream import ConnectionError, AuthenticationError, SampleStream
     6 from tweetstream import ConnectionError, AuthenticationError, SampleStream, FilterStream
     8 from tweepy.auth import BasicAuthHandler   
     7 from tweepy.auth import BasicAuthHandler   
     9 
     8 
    10 import pytest
     9 import pytest
    11 from pytest import raises
    10 from pytest import raises
    12 slow = pytest.mark.slow
    11 slow = pytest.mark.slow
    13 
    12 
    14 from servercontext import test_server
    13 from servercontext import test_server
    15 
    14 
    16 single_tweet = r"""{"in_reply_to_status_id":null,"in_reply_to_user_id":null,"favorited":false,"created_at":"Tue Jun 16 10:40:14 +0000 2009","in_reply_to_screen_name":null,"text":"record industry just keeps on amazing me: http:\/\/is.gd\/13lFo - $150k per song you've SHARED, not that somebody has actually DOWNLOADED.","user":{"notifications":null,"profile_background_tile":false,"followers_count":206,"time_zone":"Copenhagen","utc_offset":3600,"friends_count":191,"profile_background_color":"ffffff","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/250715794\/profile_normal.png","description":"Digital product developer, currently at Opera Software. My tweets are my opinions, not those of my employer.","verified_profile":false,"protected":false,"favourites_count":0,"profile_text_color":"3C3940","screen_name":"eiriksnilsen","name":"Eirik Stridsklev N.","following":null,"created_at":"Tue May 06 12:24:12 +0000 2008","profile_background_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_background_images\/10531192\/160x600opera15.gif","profile_link_color":"0099B9","profile_sidebar_fill_color":"95E8EC","url":"http:\/\/www.stridsklev-nilsen.no\/eirik","id":14672543,"statuses_count":506,"profile_sidebar_border_color":"5ED4DC","location":"Oslo, Norway"},"id":2190767504,"truncated":false,"source":"<a href=\"http:\/\/widgets.opera.com\/widget\/7206\">Twitter Opera widget<\/a>"}"""
    15 single_tweet = r"""{"in_reply_to_status_id":null,"in_reply_to_user_id":null,"favorited":false,"created_at":"Tue Jun 16 10:40:14 +0000 2009","in_reply_to_screen_name":null,"text":"record industry just keeps on amazing me: http:\/\/is.gd\/13lFo - $150k per song you've SHARED, not that somebody has actually DOWNLOADED.","user":{"notifications":null,"profile_background_tile":false,"followers_count":206,"time_zone":"Copenhagen","utc_offset":3600,"friends_count":191,"profile_background_color":"ffffff","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/250715794\/profile_normal.png","description":"Digital product developer, currently at Opera Software. My tweets are my opinions, not those of my employer.","verified_profile":false,"protected":false,"favourites_count":0,"profile_text_color":"3C3940","screen_name":"eiriksnilsen","name":"Eirik Stridsklev N.","following":null,"created_at":"Tue May 06 12:24:12 +0000 2008","profile_background_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_background_images\/10531192\/160x600opera15.gif","profile_link_color":"0099B9","profile_sidebar_fill_color":"95E8EC","url":"http:\/\/www.stridsklev-nilsen.no\/eirik","id":14672543,"statuses_count":506,"profile_sidebar_border_color":"5ED4DC","location":"Oslo, Norway"},"id":2190767504,"truncated":false,"source":"<a href=\"http:\/\/widgets.opera.com\/widget\/7206\">Twitter Opera widget<\/a>"}""" + "\r"
    17 
    16 
    18 
    17 
    19 def parameterized(funcarglist):
    18 def parameterized(funcarglist):
    20     def wrapper(function):
    19     def wrapper(function):
    21         function.funcarglist = funcarglist
    20         function.funcarglist = funcarglist
    28 
    27 
    29 
    28 
    30 streamtypes = [
    29 streamtypes = [
    31     dict(cls=TweetStream, args=[], kwargs=dict()),
    30     dict(cls=TweetStream, args=[], kwargs=dict()),
    32     dict(cls=SampleStream, args=[], kwargs=dict()),
    31     dict(cls=SampleStream, args=[], kwargs=dict()),
       
    32     dict(cls=FilterStream, args=[], kwargs=dict(track=("test",))),
    33     dict(cls=FollowStream, args=[[1, 2, 3]], kwargs=dict()),
    33     dict(cls=FollowStream, args=[[1, 2, 3]], kwargs=dict()),
    34     dict(cls=TrackStream, args=["opera"], kwargs=dict()),
    34     dict(cls=TrackStream, args=["opera"], kwargs=dict()),
    35     dict(cls=LocationStream, args=["123,4321"], kwargs=dict())
    35     dict(cls=LocationStream, args=["123,4321"], kwargs=dict())
    36 ]
    36 ]
    37 
    37 
    41     """Test that the proper exception is raised when the user could not be
    41     """Test that the proper exception is raised when the user could not be
    42     authenticated"""
    42     authenticated"""
    43     def auth_denied(request):
    43     def auth_denied(request):
    44         request.send_error(401)
    44         request.send_error(401)
    45 
    45 
    46     with test_server(handler=auth_denied, methods=("post", "get"), port="random") as server:
    46     with raises(AuthenticationError):
    47         auth = BasicAuthHandler("user", "passwd")
    47         with test_server(handler=auth_denied, methods=("post", "get"), port="random") as server:
    48         stream = cls(auth, *args, url=server.baseurl)
    48             auth = BasicAuthHandler("user", "passwd")
       
    49             stream = cls(auth, *args, url=server.baseurl)
       
    50             for e in stream: pass
    49 
    51 
    50 
    52 
    51 @parameterized(streamtypes)
    53 @parameterized(streamtypes)
    52 def test_404_url(cls, args, kwargs):
    54 def test_404_url(cls, args, kwargs):
    53     """Test that the proper exception is raised when the stream URL can't be
    55     """Test that the proper exception is raised when the stream URL can't be
    54     found"""
    56     found"""
    55     def not_found(request):
    57     def not_found(request):
    56         request.send_error(404)
    58         request.send_error(404)
    57 
    59 
    58     with test_server(handler=not_found, methods=("post", "get"), port="random") as server:
    60     with raises(ConnectionError):
    59         auth = BasicAuthHandler("user", "passwd")
    61         with test_server(handler=not_found, methods=("post", "get"), port="random") as server:
    60         stream = cls(auth, *args, url=server.baseurl)
    62             auth = BasicAuthHandler("user", "passwd")
       
    63             stream = cls(auth, *args, url=server.baseurl)
       
    64             for e in stream: pass
    61 
    65 
    62 
    66 
    63 @parameterized(streamtypes)
    67 @parameterized(streamtypes)
    64 def test_bad_content(cls, args, kwargs):
    68 def test_bad_content(cls, args, kwargs):
    65     """Test error handling if we are given invalid data"""
    69     """Test error handling if we are given invalid data"""
    66     def bad_content(request):
    70     def bad_content(request):
    67         for n in xrange(10):
    71         for n in xrange(10):
    68             # what json we pass doesn't matter. It's not verifying the
    72             # what json we pass doesn't matter. It's not verifying the
    69             # strcuture, only checking that it's parsable
    73             # strcuture, only checking that it's parsable
    70             yield "[1,2,3]"
    74             yield "[1,2,3]\r"
    71         yield "[1,2, I need no stinking close brace"
    75         yield "[1,2, I need no stinking close brace\r"
    72         yield "[1,2,3]"
    76         yield "[1,2,3]\r"
    73 
    77 
    74 
    78 
    75     with raises(ConnectionError):
    79     with raises(ConnectionError):
    76         with test_server(handler=bad_content, methods=("post", "get"), port="random") as server:
    80         with test_server(handler=bad_content, methods=("post", "get"), port="random") as server:
    77             auth = BasicAuthHandler("user", "passwd")
    81             auth = BasicAuthHandler("user", "passwd")
    86     cnt = 1000
    90     cnt = 1000
    87     def bad_content(request):
    91     def bad_content(request):
    88         for n in xrange(cnt):
    92         for n in xrange(cnt):
    89             # what json we pass doesn't matter. It's not verifying the
    93             # what json we pass doesn't matter. It's not verifying the
    90             # strcuture, only checking that it's parsable
    94             # strcuture, only checking that it's parsable
    91             yield "[1,2,3]"
    95             yield "[1,2,3]\r"
    92 
    96 
    93     with raises(ConnectionError):
    97     with raises(ConnectionError):
    94         with test_server(handler=bad_content, methods=("post", "get"), port="random") as server:
    98         with test_server(handler=bad_content, methods=("post", "get"), port="random") as server:
    95             auth = BasicAuthHandler("foo", "bar")
    99             auth = BasicAuthHandler("foo", "bar")
    96             stream = cls(auth, *args, url=server.baseurl)
   100             stream = cls(auth, *args, url=server.baseurl)