123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. # -*- coding: utf-8 -*-
  2. from collections import defaultdict
  3. import mock
  4. import lxml
  5. from searx.engines import google
  6. from searx.testing import SearxTestCase
  7. class TestGoogleEngine(SearxTestCase):
  8. def mock_response(self, text):
  9. response = mock.Mock(text=text, url='https://www.google.com/search?q=test&start=0&gbv=1&gws_rd=cr')
  10. response.search_params = mock.Mock()
  11. response.search_params.get = mock.Mock(return_value='www.google.com')
  12. return response
  13. def test_request(self):
  14. query = 'test_query'
  15. dicto = defaultdict(dict)
  16. dicto['pageno'] = 1
  17. dicto['language'] = 'fr-FR'
  18. dicto['time_range'] = ''
  19. params = google.request(query, dicto)
  20. self.assertIn('url', params)
  21. self.assertIn(query, params['url'])
  22. self.assertIn('google.fr', params['url'])
  23. self.assertIn('fr', params['headers']['Accept-Language'])
  24. dicto['language'] = 'en-US'
  25. params = google.request(query, dicto)
  26. self.assertIn('google.co', params['url'])
  27. self.assertIn('en', params['headers']['Accept-Language'])
  28. def test_response(self):
  29. self.assertRaises(AttributeError, google.response, None)
  30. self.assertRaises(AttributeError, google.response, [])
  31. self.assertRaises(AttributeError, google.response, '')
  32. self.assertRaises(AttributeError, google.response, '[]')
  33. response = self.mock_response('<html></html>')
  34. self.assertEqual(google.response(response), [])
  35. html = """
  36. <div class="g">
  37. <h3 class="r">
  38. <a href="http://this.should.be.the.link/">
  39. <b>This</b> is <b>the</b> title
  40. </a>
  41. </h3>
  42. <div class="s">
  43. <div class="kv" style="margin-bottom:2px">
  44. <cite>
  45. <b>test</b>.psychologies.com/
  46. </cite>
  47. <div class="_nBb">‎
  48. <div style="display:inline" onclick="google.sham(this);" aria-expanded="false"
  49. aria-haspopup="true" tabindex="0" data-ved="0CBUQ7B0wAA">
  50. <span class="_O0">
  51. </span>
  52. </div>
  53. <div style="display:none" class="am-dropdown-menu" role="menu" tabindex="-1">
  54. <ul>
  55. <li class="_Ykb">
  56. <a class="_Zkb" href="http://www.google.fr/url?url=http://webcache.googleusercontent
  57. .com/search%3Fcache:R1Z_4pGXjuIJ:http://test.psychologies.com/">
  58. En cache
  59. </a>
  60. </li>
  61. <li class="_Ykb">
  62. <a class="_Zkb" href="/search?safe=off&amp;q=related:test.psy.com/">
  63. Pages similaires
  64. </a>
  65. </li>
  66. </ul>
  67. </div>
  68. </div>
  69. </div>
  70. <span class="st">
  71. This should be the content.
  72. </span>
  73. <br>
  74. <div class="osl">‎
  75. <a href="http://www.google.fr/url?url=http://test.psychologies.com/tests/">
  76. Test Personnalité
  77. </a> - ‎
  78. <a href="http://www.google.fr/url?url=http://test.psychologies.com/test/">
  79. Tests - Moi
  80. </a> - ‎
  81. <a href="http://www.google.fr/url?url=http://test.psychologies.com/test/tests-couple">
  82. Test Couple
  83. </a>
  84. - ‎
  85. <a href="http://www.google.fr/url?url=http://test.psychologies.com/tests/tests-amour">
  86. Test Amour
  87. </a>
  88. </div>
  89. </div>
  90. </div>
  91. <div class="g">
  92. <h3 class="r">
  93. <a href="http://www.google.com/images?q=toto">
  94. <b>This</b>
  95. </a>
  96. </h3>
  97. </div>
  98. <div class="g">
  99. <h3 class="r">
  100. <a href="http://www.google.com/search?q=toto">
  101. <b>This</b> is
  102. </a>
  103. </h3>
  104. </div>
  105. <div class="g">
  106. <h3 class="r">
  107. <a href="€">
  108. <b>This</b> is <b>the</b>
  109. </a>
  110. </h3>
  111. </div>
  112. <div class="g">
  113. <h3 class="r">
  114. <a href="/url?q=url">
  115. <b>This</b> is <b>the</b>
  116. </a>
  117. </h3>
  118. </div>
  119. <p class="_Bmc" style="margin:3px 8px">
  120. <a href="/search?num=20&amp;safe=off&amp;q=t&amp;revid=1754833769&amp;sa=X&amp;ei=-&amp;ved=">
  121. suggestion <b>title</b>
  122. </a>
  123. </p>
  124. """
  125. response = self.mock_response(html)
  126. results = google.response(response)
  127. self.assertEqual(type(results), list)
  128. self.assertEqual(len(results), 2)
  129. self.assertEqual(results[0]['title'], 'This is the title')
  130. self.assertEqual(results[0]['url'], 'http://this.should.be.the.link/')
  131. self.assertEqual(results[0]['content'], 'This should be the content.')
  132. self.assertEqual(results[1]['suggestion'], 'suggestion title')
  133. html = """
  134. <li class="b_algo" u="0|5109|4755453613245655|UAGjXgIrPH5yh-o5oNHRx_3Zta87f_QO">
  135. </li>
  136. """
  137. response = self.mock_response(html)
  138. results = google.response(response)
  139. self.assertEqual(type(results), list)
  140. self.assertEqual(len(results), 0)
  141. response = mock.Mock(text='<html></html>', url='https://sorry.google.com')
  142. response.search_params = mock.Mock()
  143. response.search_params.get = mock.Mock(return_value='www.google.com')
  144. self.assertRaises(RuntimeWarning, google.response, response)
  145. response = mock.Mock(text='<html></html>', url='https://www.google.com/sorry/IndexRedirect')
  146. response.search_params = mock.Mock()
  147. response.search_params.get = mock.Mock(return_value='www.google.com')
  148. self.assertRaises(RuntimeWarning, google.response, response)
  149. def test_parse_images(self):
  150. html = """
  151. <li>
  152. <div>
  153. <a href="http://www.google.com/url?q=http://this.is.the.url/">
  154. <img style="margin:3px 0;margin-right:6px;padding:0" height="90"
  155. src="https://this.is.the.image/image.jpg" width="60" align="middle" alt="" border="0">
  156. </a>
  157. </div>
  158. </li>
  159. """
  160. dom = lxml.html.fromstring(html)
  161. results = google.parse_images(dom, 'www.google.com')
  162. self.assertEqual(type(results), list)
  163. self.assertEqual(len(results), 1)
  164. self.assertEqual(results[0]['url'], 'http://this.is.the.url/')
  165. self.assertEqual(results[0]['title'], '')
  166. self.assertEqual(results[0]['content'], '')
  167. self.assertEqual(results[0]['img_src'], 'https://this.is.the.image/image.jpg')
  168. def test_fetch_supported_languages(self):
  169. html = """<html></html>"""
  170. response = mock.Mock(text=html)
  171. languages = google._fetch_supported_languages(response)
  172. self.assertEqual(type(languages), dict)
  173. self.assertEqual(len(languages), 0)
  174. html = u"""
  175. <html>
  176. <body>
  177. <table>
  178. <tbody>
  179. <tr>
  180. <td>
  181. <font>
  182. <label>
  183. <span id="ten">English</span>
  184. </label>
  185. </font>
  186. </td>
  187. <td>
  188. <font>
  189. <label>
  190. <span id="tzh-CN">中文 (简体)</span>
  191. </label>
  192. <label>
  193. <span id="tzh-TW">中文 (繁體)</span>
  194. </label>
  195. </font>
  196. </td>
  197. </tr>
  198. </tbody>
  199. </table>
  200. </body>
  201. </html>
  202. """
  203. response = mock.Mock(text=html)
  204. languages = google._fetch_supported_languages(response)
  205. self.assertEqual(type(languages), dict)
  206. self.assertEqual(len(languages), 3)
  207. self.assertIn('en', languages)
  208. self.assertIn('zh-CN', languages)
  209. self.assertIn('zh-TW', languages)
  210. self.assertEquals(type(languages['en']), dict)
  211. self.assertEquals(type(languages['zh-CN']), dict)
  212. self.assertEquals(type(languages['zh-TW']), dict)
  213. self.assertIn('name', languages['en'])
  214. self.assertIn('name', languages['zh-CN'])
  215. self.assertIn('name', languages['zh-TW'])
  216. self.assertEquals(languages['en']['name'], 'English')
  217. self.assertEquals(languages['zh-CN']['name'], u'中文 (简体)')
  218. self.assertEquals(languages['zh-TW']['name'], u'中文 (繁體)')