test_profile.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import os
  2. import unittest
  3. from base import BaseTestCase, Profile
  4. from parameterized import parameterized
  5. profiles = [
  6. ['mobile_test', 'Test account',
  7. 'Test Account. test test Testing username with @mobile_test_2 and a #hashtag',
  8. 'San Francisco, CA', 'example.com/foobar', 'Joined October 2009', '97'],
  9. ['mobile_test_2', 'mobile test 2', '', '', '', 'Joined January 2011', '13']
  10. ]
  11. verified = [['jack'], ['elonmusk']]
  12. protected = [
  13. ['mobile_test_7', 'mobile test 7', ''],
  14. ['Poop', 'Randy', 'Social media fanatic.']
  15. ]
  16. invalid = [['thisprofiledoesntexist']]
  17. malformed = [
  18. ['${userId}'],
  19. ['$%7BuserId%7D'], # URL encoded version
  20. ['%'], # Percent sign is invalid
  21. ['user@name'],
  22. ['user.name'],
  23. ['user-name'],
  24. ['user$name'],
  25. ['user{name}'],
  26. ['user name'], # space
  27. ]
  28. banner_image = [
  29. ['mobile_test', 'profile_banners%2F82135242%2F1384108037%2F1500x500']
  30. ]
  31. # (user_id, expected_username) — resolving a numeric id to a profile (issue #1433)
  32. id_redirects = [
  33. ['12', 'jack'],
  34. ['44196397', 'elonmusk']
  35. ]
  36. class ProfileTest(BaseTestCase):
  37. @parameterized.expand(profiles)
  38. def test_data(self, username, fullname, bio, location, website, joinDate, mediaCount):
  39. self.open_nitter(username)
  40. self.assert_exact_text(fullname, Profile.fullname)
  41. self.assert_exact_text(f'@{username}', Profile.username)
  42. tests = [
  43. (bio, Profile.bio),
  44. (location, Profile.location),
  45. (website, Profile.website),
  46. (joinDate, Profile.joinDate),
  47. (mediaCount + " Photos and videos", Profile.mediaCount)
  48. ]
  49. for text, selector in tests:
  50. if len(text) > 0:
  51. self.assert_exact_text(text, selector)
  52. else:
  53. self.assert_element_absent(selector)
  54. @parameterized.expand(verified)
  55. def test_verified(self, username):
  56. self.open_nitter(username)
  57. self.assert_element_visible(Profile.verified)
  58. @parameterized.expand(protected)
  59. def test_protected(self, username, fullname, bio):
  60. self.open_nitter(username)
  61. self.assert_element_visible(Profile.protected)
  62. self.assert_exact_text(fullname, Profile.fullname)
  63. self.assert_exact_text(f'@{username}', Profile.username)
  64. if len(bio) > 0:
  65. self.assert_text(bio, Profile.bio)
  66. else:
  67. self.assert_element_absent(Profile.bio)
  68. @parameterized.expand(invalid)
  69. def test_invalid_username(self, username):
  70. self.open_nitter(username)
  71. self.assert_text(f'User "{username}" not found')
  72. @parameterized.expand(malformed)
  73. def test_malformed_username(self, username):
  74. """Test that malformed usernames (with invalid characters) return 404"""
  75. self.open_nitter(username)
  76. # Malformed usernames should return 404 page not found, not try to fetch from Twitter
  77. self.assert_text('Page not found')
  78. def test_suspended(self):
  79. self.open_nitter('suspendme')
  80. self.assert_text('User "suspendme" has been suspended')
  81. @parameterized.expand(banner_image)
  82. def test_banner_image(self, username, url):
  83. self.open_nitter(username)
  84. banner = self.find_element(Profile.banner + ' img')
  85. self.assertIn(url, banner.get_attribute('src'))
  86. # UserByRestId clears Cloudflare from residential IPs and via the cloaking
  87. # proxy, but CF's edge rule on that endpoint rejects GitHub Actions' datacenter
  88. # ASN regardless of headers, so these live redirects can't pass in CI (#1433).
  89. @unittest.skipIf(os.environ.get('GITHUB_ACTIONS') == 'true',
  90. 'UserByRestId is Cloudflare-blocked from GitHub datacenter IPs')
  91. class UserIdRedirectTest(BaseTestCase):
  92. @parameterized.expand(id_redirects)
  93. def test_i_user_redirect(self, user_id, username):
  94. """/i/user/<id> resolves the numeric id and redirects to the profile (issue #1433)"""
  95. self.open_nitter(f'i/user/{user_id}')
  96. self.assert_true(self.get_current_url().rstrip('/').endswith(f'/{username}'))
  97. self.assert_exact_text(f'@{username}', Profile.username)
  98. @parameterized.expand(id_redirects)
  99. def test_intent_user_redirect(self, user_id, username):
  100. """/intent/user?user_id=<id> redirects to the profile (issue #1433)"""
  101. self.open_nitter(f'intent/user?user_id={user_id}')
  102. self.assert_true(self.get_current_url().rstrip('/').endswith(f'/{username}'))
  103. self.assert_exact_text(f'@{username}', Profile.username)