# Path: responsebot/models.py
# class TweetFilter(object):
#     """
#     Define criteria to filter tweets from Twitter's public stream. See `track` and `follow` parameters in `here <https://dev.twitter.com/streaming/overview/request-parameters>`_.
#     """
#     def __init__(self, track=[], follow=[]):
#         """
# 
#         :param track: A list of keywords to follow (each could also be a @mention or a #hashtag)
#         :param follow: A list of user ID strings to follow
#         :return:
#         """
#         self.track = track
#         self.follow = follow
# 
#     def match_tweet(self, tweet, user_stream):
#         """
#         Check if a tweet matches the defined criteria
# 
#         :param tweet: The tweet in question
#         :type tweet: :class:`~responsebot.models.Tweet`
#         :return: True if matched, False otherwise
#         """
#         if user_stream:
#             if len(self.track) > 0:
#                 return self.is_tweet_match_track(tweet)
# 
#             return True
# 
#         return self.is_tweet_match_track(tweet) or self.is_tweet_match_follow(tweet)
# 
#     def is_tweet_match_track(self, tweet):
#         tweet_text = tweet.text.lower()
#         for value in self.track:
#             if value.lower() in tweet_text:
#                 return True
# 
#         return False
# 
#     def is_tweet_match_follow(self, tweet):
#         user_mentions = [x['id'] for x in tweet.entities.get('user_mentions', [])]
#         for value in self.follow:
#             int_value = int(value)
#             if tweet.user.id == int_value or int_value in user_mentions:
#                 return True
# 
#         return False
# 
# class Tweet(object):
#     """
#     Represents a tweet. E.g. you can get a tweet's text via it's :code:`text` property (:code:`tweet.text`).
#     All properties except :code:`retweeted_status`, :code:`quoted_status`, :code:`quoted_status_id_str`, :code:`in_reply_to_status_id`
#     and :code:`in_reply_sto_status_id_str` have the same name as Twitter defined them `here <https://dev.twitter.com/overview/api/tweets>`_.
#     :code:`retweeted_status` is renamed to :code:`retweeted_tweet`, similar for other properties above.
#     """
#     def __init__(self, data):
#         """
#         :param data: Parsed JSON data
#         :type data: dictionary
#         """
#         self.raw_data = data
# 
#         # TODO: handle place. source, quoted_status_id_str
#         for key, value in data.items():
#             if key == 'user':
#                 setattr(self, key, User(value))
#             elif key == 'created_at':
#                 setattr(self, key, parse(value))
#             elif key == 'retweeted_status':
#                 setattr(self, 'retweeted_tweet', Tweet(value))
#             elif key == 'quoted_status':
#                 setattr(self, 'quoted_tweet', Tweet(value))
#             elif key == 'quoted_status_id_str':
#                 setattr(self, 'quoted_tweet_id_str', value)
#             elif key == 'in_reply_to_status_id':
#                 setattr(self, 'in_reply_to_tweet_id', value)
#             elif key == 'in_reply_to_status_id_str':
#                 setattr(self, 'in_reply_to_tweet_id_str', value)
#             else:
#                 setattr(self, key, value)


from unittest.case import TestCase
from responsebot.models import TweetFilter, Tweet



class TweetFilterModelTestCase(TestCase):
    def setUp(self):
        self.filter = TweetFilter(track=['keyword'], follow=[123])

    def test_match_tracked_keyword(self):
        match = Tweet({'text': 'keyword text', 'entities': {}, 'user': {'id': 1}})
        unmatched = Tweet({'text': 'text otherkey', 'entities': {}, 'user': {'id': 1}})

        self.assertTrue(self.filter.match_tweet(match, user_stream=False))
        self.assertFalse(self.filter.match_tweet(unmatched, user_stream=False))

    def test_match_tweet_posters(self):
        match = Tweet({'text': 'text', 'entities': {}, 'user': {'id': 123}})
        unmatched = Tweet({'text': 'text', 'entities': {}, 'user': {'id': 1}})

        self.assertTrue(self.filter.match_tweet(match, user_stream=False))
        self.assertFalse(self.filter.match_tweet(unmatched, user_stream=False))

    def test_match_user_mentions(self):
        match = Tweet({'text': 'text', 'entities': {'user_mentions': [{'id': 123}]}, 'user': {'id': 1}})
        unmatched = Tweet({'text': 'text', 'entities': {'user_mentions': [{'id': 1}]}, 'user': {'id': 1}})

        self.assertTrue(self.filter.match_tweet(match, user_stream=False))
        self.assertFalse(self.filter.match_tweet(unmatched, user_stream=False))

    def test_match_user_stream_no_track(self):

# Path: responsebot/models.py
# class TweetFilter(object):
#     """
#     Define criteria to filter tweets from Twitter's public stream. See `track` and `follow` parameters in `here <https://dev.twitter.com/streaming/overview/request-parameters>`_.
#     """
#     def __init__(self, track=[], follow=[]):
#         """
# 
#         :param track: A list of keywords to follow (each could also be a @mention or a #hashtag)
#         :param follow: A list of user ID strings to follow
#         :return:
#         """
#         self.track = track
#         self.follow = follow
# 
#     def match_tweet(self, tweet, user_stream):
#         """
#         Check if a tweet matches the defined criteria
# 
#         :param tweet: The tweet in question
#         :type tweet: :class:`~responsebot.models.Tweet`
#         :return: True if matched, False otherwise
#         """
#         if user_stream:
#             if len(self.track) > 0:
#                 return self.is_tweet_match_track(tweet)
# 
#             return True
# 
#         return self.is_tweet_match_track(tweet) or self.is_tweet_match_follow(tweet)
# 
#     def is_tweet_match_track(self, tweet):
#         tweet_text = tweet.text.lower()
#         for value in self.track:
#             if value.lower() in tweet_text:
#                 return True
# 
#         return False
# 
#     def is_tweet_match_follow(self, tweet):
#         user_mentions = [x['id'] for x in tweet.entities.get('user_mentions', [])]
#         for value in self.follow:
#             int_value = int(value)
#             if tweet.user.id == int_value or int_value in user_mentions:
#                 return True
# 
#         return False
# 
# class Tweet(object):
#     """
#     Represents a tweet. E.g. you can get a tweet's text via it's :code:`text` property (:code:`tweet.text`).
#     All properties except :code:`retweeted_status`, :code:`quoted_status`, :code:`quoted_status_id_str`, :code:`in_reply_to_status_id`
#     and :code:`in_reply_sto_status_id_str` have the same name as Twitter defined them `here <https://dev.twitter.com/overview/api/tweets>`_.
#     :code:`retweeted_status` is renamed to :code:`retweeted_tweet`, similar for other properties above.
#     """
#     def __init__(self, data):
#         """
#         :param data: Parsed JSON data
#         :type data: dictionary
#         """
#         self.raw_data = data
# 
#         # TODO: handle place. source, quoted_status_id_str
#         for key, value in data.items():
#             if key == 'user':
#                 setattr(self, key, User(value))
#             elif key == 'created_at':
#                 setattr(self, key, parse(value))
#             elif key == 'retweeted_status':
#                 setattr(self, 'retweeted_tweet', Tweet(value))
#             elif key == 'quoted_status':
#                 setattr(self, 'quoted_tweet', Tweet(value))
#             elif key == 'quoted_status_id_str':
#                 setattr(self, 'quoted_tweet_id_str', value)
#             elif key == 'in_reply_to_status_id':
#                 setattr(self, 'in_reply_to_tweet_id', value)
#             elif key == 'in_reply_to_status_id_str':
#                 setattr(self, 'in_reply_to_tweet_id_str', value)
#             else:
#                 setattr(self, key, value)


# Path: tests/unit_tests/models/test_tweet_filter_model.py
from unittest.case import TestCase
from responsebot.models import TweetFilter, Tweet




class TweetFilterModelTestCase(TestCase):
    def setUp(self):
        self.filter = TweetFilter(track=['keyword'], follow=[123])

    def test_match_tracked_keyword(self):
        match = Tweet({'text': 'keyword text', 'entities': {}, 'user': {'id': 1}})
        unmatched = Tweet({'text': 'text otherkey', 'entities': {}, 'user': {'id': 1}})

        self.assertTrue(self.filter.match_tweet(match, user_stream=False))
        self.assertFalse(self.filter.match_tweet(unmatched, user_stream=False))

    def test_match_tweet_posters(self):
        match = Tweet({'text': 'text', 'entities': {}, 'user': {'id': 123}})
        unmatched = Tweet({'text': 'text', 'entities': {}, 'user': {'id': 1}})

        self.assertTrue(self.filter.match_tweet(match, user_stream=False))
        self.assertFalse(self.filter.match_tweet(unmatched, user_stream=False))

    def test_match_user_mentions(self):
        match = Tweet({'text': 'text', 'entities': {'user_mentions': [{'id': 123}]}, 'user': {'id': 1}})
        unmatched = Tweet({'text': 'text', 'entities': {'user_mentions': [{'id': 1}]}, 'user': {'id': 1}})

        self.assertTrue(self.filter.match_tweet(match, user_stream=False))
        self.assertFalse(self.filter.match_tweet(unmatched, user_stream=False))

    def test_match_user_stream_no_track(self):

        self.filter = TweetFilter(track=[])