conftest.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. import pytest
  2. from datetime import datetime
  3. from click.testing import CliRunner
  4. from bs4 import BeautifulSoup
  5. from twhatter.client import ClientTimeline
  6. from twhatter.parser import tweet_factory
  7. from typing import NamedTuple, List
  8. from twhatter.parser.media import MediaBase
  9. @pytest.fixture
  10. def cli_runner():
  11. """Runner for Click"""
  12. return CliRunner()
  13. @pytest.fixture(scope="session")
  14. def user():
  15. return "the_english_way"
  16. @pytest.fixture(scope="session")
  17. def user_prolific():
  18. return "realDonaldTrump"
  19. @pytest.fixture(scope="session")
  20. def tweet_limit():
  21. return 10
  22. # Fixtures for extraction of specific tweets of several kinds, whose author
  23. # and id are known in advance
  24. class MediaInfo(NamedTuple):
  25. """Class to hold information about a media that is already known"""
  26. image_links: List[str] = []
  27. def __eq__(self, other):
  28. """Override of __eq__ to check against `MediaBase` instance"""
  29. return (isinstance(other, MediaBase)
  30. and other.image_links == self.image_links)
  31. class TweetInfo(NamedTuple):
  32. """Class to hold information about a tweet that is already known"""
  33. id: int
  34. screen_name: str
  35. user_id: int
  36. permalink: str
  37. timestamp: datetime = None
  38. text: str = None
  39. comments_nb: int = None
  40. retweets_nb: int = None
  41. likes_nb: int = None
  42. hashtag_list: List[str] = None
  43. mention_list: List[int] = None
  44. retweeter: str = None
  45. retweet_id: int = None
  46. reacted_id: int = None
  47. reacted_user_id: int = None
  48. link_to: str = None
  49. media: MediaInfo = None
  50. @pytest.fixture(scope="session")
  51. def tweet_collection():
  52. return {
  53. 'plain': TweetInfo(
  54. id=1077838164813848576,
  55. screen_name="the_english_way",
  56. user_id=943804775942033408,
  57. timestamp=datetime.utcfromtimestamp(1545811618),
  58. permalink="/the_english_way/status/1077838164813848576",
  59. text="""Ca y est j'ai un pipeline Concourse avec un job qui builde une image @Docker qui affiche un "Hello World" dans un autre job \o/
  60. ........... je suis pas sûr de savoir ce que ça veut dire, mais en tout cas c'était mon objectif de la matinée """
  61. ),
  62. 'reaction_tweet': TweetInfo(
  63. id=1078281840945963008,
  64. screen_name="the_english_way",
  65. user_id=943804775942033408,
  66. timestamp=datetime.utcfromtimestamp(1545917399),
  67. permalink="/the_english_way/status/1078281840945963008",
  68. reacted_id=1078277316193726464,
  69. reacted_user_id=19976004
  70. ),
  71. 'with_link': TweetInfo(
  72. id=1077505613079429120,
  73. screen_name="the_english_way",
  74. user_id=943804775942033408,
  75. timestamp=datetime.utcfromtimestamp(1545732331),
  76. permalink="/the_english_way/status/1077505613079429120",
  77. link_to="https://t.co/el5VJucLRz"
  78. ),
  79. 'retweet': TweetInfo(
  80. id=1055037291108974592,
  81. screen_name="Senficon",
  82. user_id=14861745,
  83. retweeter="the_english_way",
  84. retweet_id=1055098556300828672,
  85. timestamp=datetime.utcfromtimestamp(1540375466),
  86. permalink="/Senficon/status/1055037291108974592",
  87. ),
  88. 'hashtags': TweetInfo(
  89. id=1039969574555471873,
  90. screen_name="BurgerQuizOff",
  91. user_id=949604705772228608,
  92. retweeter="the_english_way",
  93. permalink="/BurgerQuizOff/status/1039969574555471873",
  94. hashtag_list=["Nuggets", "BurgerQuiz", "PrivacyMonCul"]
  95. ),
  96. 'mentions': TweetInfo(
  97. id=1077838164813848576,
  98. screen_name="the_english_way",
  99. user_id=943804775942033408,
  100. timestamp=datetime.utcfromtimestamp(1545811618),
  101. permalink="/the_english_way/status/1077838164813848576",
  102. mention_list=[1138959692]
  103. ),
  104. 'stats': TweetInfo(
  105. id=1039969574555471873,
  106. screen_name="BurgerQuizOff",
  107. user_id=949604705772228608,
  108. permalink="/BurgerQuizOff/status/1039969574555471873",
  109. retweeter="the_english_way",
  110. comments_nb=12,
  111. retweets_nb=176,
  112. likes_nb=555
  113. ),
  114. 'media':TweetInfo(
  115. id=1086327536726900736,
  116. screen_name="the_english_way",
  117. user_id=943804775942033408,
  118. permalink="/the_english_way/status/1086327536726900736",
  119. media=MediaInfo(
  120. image_links=["https://pbs.twimg.com/media/DxNof6AXQAAu2oU.jpg"]
  121. )
  122. ),
  123. }
  124. @pytest.fixture(scope="session")
  125. def raw_html_user_initial_page_factory():
  126. def _raw_html_user_initial_page(user):
  127. a = ClientTimeline(user)
  128. response = a.get_user_timeline(user)
  129. return BeautifulSoup(response.text, "lxml")
  130. return _raw_html_user_initial_page
  131. @pytest.fixture(scope="session")
  132. def raw_html_user_initial_page(raw_html_user_initial_page_factory, user):
  133. return raw_html_user_initial_page_factory(user)
  134. @pytest.fixture(scope="session")
  135. def raw_tweet_factory(raw_html_user_initial_page_factory):
  136. def _raw_tweet_factory(tweet_info):
  137. user_page = tweet_info.retweeter or tweet_info.screen_name
  138. soup = raw_html_user_initial_page_factory(user_page)
  139. return soup.find(id="stream-item-tweet-{}".format(tweet_info.id))
  140. return _raw_tweet_factory
  141. @pytest.fixture(scope="session")
  142. def tweet_test_data_factory(raw_tweet_factory, tweet_collection):
  143. def _tweet_test_data_factory(tweet_type):
  144. tweet_info = tweet_collection[tweet_type]
  145. raw_tweet = raw_tweet_factory(tweet_info)
  146. return tweet_factory(raw_tweet), tweet_info
  147. return _tweet_test_data_factory
  148. class UserInfo(NamedTuple):
  149. """Class to hold information about an user that is already known"""
  150. id: int
  151. screen_name: str
  152. join_date: datetime
  153. tweets_nb: int = None
  154. following_nb: int = None
  155. followers_nb: int = None
  156. likes_nb: int = None
  157. @pytest.fixture(scope="session")
  158. def user_collection():
  159. return {
  160. 'Marlene_beadles': UserInfo(
  161. id=295177446,
  162. screen_name="Marlene Hansen",
  163. join_date=datetime(2011, 5, 8, 0, 0),
  164. tweets_nb=25,
  165. following_nb=342,
  166. followers_nb=81,
  167. likes_nb=4
  168. ),
  169. 'the_english_way': UserInfo(
  170. id=943804775942033408,
  171. screen_name="theenglishway",
  172. join_date=datetime(2017, 12, 21, 0, 0),
  173. ),
  174. }