diff options
Diffstat (limited to 'searx/tests')
| -rw-r--r-- | searx/tests/engines/test_bing_images.py | 2 | ||||
| -rw-r--r-- | searx/tests/engines/test_bing_news.py | 274 | ||||
| -rw-r--r-- | searx/tests/engines/test_flickr_noapi.py | 250 | ||||
| -rw-r--r-- | searx/tests/engines/test_google.py | 29 | ||||
| -rw-r--r-- | searx/tests/engines/test_qwant.py | 317 | ||||
| -rw-r--r-- | searx/tests/engines/test_swisscows.py | 128 | ||||
| -rw-r--r-- | searx/tests/engines/test_vimeo.py | 53 | ||||
| -rw-r--r-- | searx/tests/engines/test_www1x.py | 4 | ||||
| -rw-r--r-- | searx/tests/engines/test_yahoo_news.py | 19 | ||||
| -rw-r--r-- | searx/tests/engines/test_youtube_api.py | 111 | ||||
| -rw-r--r-- | searx/tests/engines/test_youtube_noapi.py | 154 | ||||
| -rw-r--r-- | searx/tests/test_engines.py | 4 | ||||
| -rw-r--r-- | searx/tests/test_plugins.py | 19 | ||||
| -rw-r--r-- | searx/tests/test_search.py | 25 |
14 files changed, 993 insertions, 396 deletions
diff --git a/searx/tests/engines/test_bing_images.py b/searx/tests/engines/test_bing_images.py index a1d96b06e..f869da79d 100644 --- a/searx/tests/engines/test_bing_images.py +++ b/searx/tests/engines/test_bing_images.py @@ -59,7 +59,7 @@ oh:"238",tft:"0",oi:"http://www.image.url/Images/Test%2 self.assertEqual(results[0]['title'], 'Test Query') self.assertEqual(results[0]['url'], 'http://www.page.url/') self.assertEqual(results[0]['content'], '') - self.assertEqual(results[0]['thumbnail_src'], 'http://ts1.mm.bing.net/th?id=HN.608003696942779811') + self.assertEqual(results[0]['thumbnail_src'], 'https://www.bing.com/th?id=HN.608003696942779811') self.assertEqual(results[0]['img_src'], 'http://test.url/Test%20Query.jpg') html = """ diff --git a/searx/tests/engines/test_bing_news.py b/searx/tests/engines/test_bing_news.py index f22b80e87..a64d59b7b 100644 --- a/searx/tests/engines/test_bing_news.py +++ b/searx/tests/engines/test_bing_news.py @@ -2,6 +2,7 @@ from collections import defaultdict import mock from searx.engines import bing_news from searx.testing import SearxTestCase +import lxml class TestBingNewsEngine(SearxTestCase): @@ -16,14 +17,10 @@ class TestBingNewsEngine(SearxTestCase): self.assertIn(query, params['url']) self.assertIn('bing.com', params['url']) self.assertIn('fr', params['url']) - self.assertIn('_FP', params['cookies']) - self.assertIn('en', params['cookies']['_FP']) dicto['language'] = 'all' params = bing_news.request(query, dicto) self.assertIn('en', params['url']) - self.assertIn('_FP', params['cookies']) - self.assertIn('en', params['cookies']['_FP']) def test_response(self): self.assertRaises(AttributeError, bing_news.response, None) @@ -37,200 +34,105 @@ class TestBingNewsEngine(SearxTestCase): response = mock.Mock(content='<html></html>') self.assertEqual(bing_news.response(response), []) - html = """ - <div class="sn_r"> - <div class="newstitle"> - <a href="http://url.of.article/" target="_blank" h="ID=news,5022.1"> - Title - </a> - </div> - <div class="sn_img"> - <a href="http://url.of.article2/" target="_blank" h="ID=news,5024.1"> - <img class="rms_img" height="80" id="emb1" src="/image.src" title="Title" width="80" /> - </a> - </div> - <div class="sn_txt"> - <div class="sn_oi"> - <span class="sn_snip">Article Content</span> - <span class="sn_ST"> - <cite class="sn_src">metronews.fr</cite> - ·  - <span class="sn_tm">44 minutes ago</span> - </span> - </div> - </div> - </div> - """ + html = """<?xml version="1.0" encoding="utf-8" ?> +<rss version="2.0" xmlns:News="https://www.bing.com:443/news/search?q=python&setmkt=en-US&first=1&format=RSS"> + <channel> + <title>python - Bing News</title> + <link>https://www.bing.com:443/news/search?q=python&setmkt=en-US&first=1&format=RSS</link> + <description>Search results</description> + <image> + <url>http://10.53.64.9/rsslogo.gif</url> + <title>test</title> + <link>https://www.bing.com:443/news/search?q=test&setmkt=en-US&first=1&format=RSS</link> + </image> + <copyright>Copyright</copyright> + <item> + <title>Title</title> + <link>https://www.bing.com/news/apiclick.aspx?ref=FexRss&aid=&tid=c237eccc50bd4758b106a5e3c94fce09&url=http%3a%2f%2furl.of.article%2f&c=xxxxxxxxx&mkt=en-us</link> + <description>Article Content</description> + <pubDate>Tue, 02 Jun 2015 13:37:00 GMT</pubDate> + <News:Source>Infoworld</News:Source> + <News:Image>http://a1.bing4.com/th?id=ON.13371337133713371337133713371337&pid=News</News:Image> + <News:ImageSize>w={0}&h={1}&c=7</News:ImageSize> + <News:ImageKeepOriginalRatio></News:ImageKeepOriginalRatio> + <News:ImageMaxWidth>620</News:ImageMaxWidth> + <News:ImageMaxHeight>413</News:ImageMaxHeight> + </item> + <item> + <title>Another Title</title> + <link>https://www.bing.com/news/apiclick.aspx?ref=FexRss&aid=&tid=c237eccc50bd4758b106a5e3c94fce09&url=http%3a%2f%2fanother.url.of.article%2f&c=xxxxxxxxx&mkt=en-us</link> + <description>Another Article Content</description> + <pubDate>Tue, 02 Jun 2015 13:37:00 GMT</pubDate> + </item> + </channel> +</rss>""" # noqa response = mock.Mock(content=html) results = bing_news.response(response) self.assertEqual(type(results), list) - self.assertEqual(len(results), 1) + self.assertEqual(len(results), 2) self.assertEqual(results[0]['title'], 'Title') self.assertEqual(results[0]['url'], 'http://url.of.article/') self.assertEqual(results[0]['content'], 'Article Content') + self.assertEqual(results[0]['thumbnail'], 'https://www.bing.com/th?id=ON.13371337133713371337133713371337') + self.assertEqual(results[1]['title'], 'Another Title') + self.assertEqual(results[1]['url'], 'http://another.url.of.article/') + self.assertEqual(results[1]['content'], 'Another Article Content') + self.assertNotIn('thumbnail', results[1]) - html = """ - <div class="sn_r"> - <div class="newstitle"> - <a href="http://url.of.article/" target="_blank" h="ID=news,5022.1"> - Title - </a> - </div> - <div class="sn_img"> - <a href="http://url.of.article2/" target="_blank" h="ID=news,5024.1"> - <img class="rms_img" height="80" id="emb1" src="/image.src" title="Title" width="80" /> - </a> - </div> - <div class="sn_txt"> - <div class="sn_oi"> - <span class="sn_snip">Article Content</span> - <span class="sn_ST"> - <cite class="sn_src">metronews.fr</cite> - ·  - <span class="sn_tm">44 minutes ago</span> - </span> - </div> - </div> - </div> - <div class="sn_r"> - <div class="newstitle"> - <a href="http://url.of.article/" target="_blank" h="ID=news,5022.1"> - Title - </a> - </div> - <div class="sn_img"> - <a href="http://url.of.article2/" target="_blank" h="ID=news,5024.1"> - <img class="rms_img" height="80" id="emb1" src="/image.src" title="Title" width="80" /> - </a> - </div> - <div class="sn_txt"> - <div class="sn_oi"> - <span class="sn_snip">Article Content</span> - <span class="sn_ST"> - <cite class="sn_src">metronews.fr</cite> - ·  - <span class="sn_tm">3 hours, 44 minutes ago</span> - </span> - </div> - </div> - </div> - <div class="sn_r"> - <div class="newstitle"> - <a href="http://url.of.article/" target="_blank" h="ID=news,5022.1"> - Title - </a> - </div> - <div class="sn_img"> - <a href="http://url.of.article2/" target="_blank" h="ID=news,5024.1"> - <img class="rms_img" height="80" id="emb1" src="/image.src" title="Title" width="80" /> - </a> - </div> - <div class="sn_txt"> - <div class="sn_oi"> - <span class="sn_snip">Article Content</span> - <span class="sn_ST"> - <cite class="sn_src">metronews.fr</cite> - ·  - <span class="sn_tm">44 hours ago</span> - </span> - </div> - </div> - </div> - <div class="sn_r"> - <div class="newstitle"> - <a href="http://url.of.article/" target="_blank" h="ID=news,5022.1"> - Title - </a> - </div> - <div class="sn_img"> - <a href="http://url.of.article2/" target="_blank" h="ID=news,5024.1"> - <img class="rms_img" height="80" id="emb1" src="/image.src" title="Title" width="80" /> - </a> - </div> - <div class="sn_txt"> - <div class="sn_oi"> - <span class="sn_snip">Article Content</span> - <span class="sn_ST"> - <cite class="sn_src">metronews.fr</cite> - ·  - <span class="sn_tm">2 days ago</span> - </span> - </div> - </div> - </div> - <div class="sn_r"> - <div class="newstitle"> - <a href="http://url.of.article/" target="_blank" h="ID=news,5022.1"> - Title - </a> - </div> - <div class="sn_img"> - <a href="http://url.of.article2/" target="_blank" h="ID=news,5024.1"> - <img class="rms_img" height="80" id="emb1" src="/image.src" title="Title" width="80" /> - </a> - </div> - <div class="sn_txt"> - <div class="sn_oi"> - <span class="sn_snip">Article Content</span> - <span class="sn_ST"> - <cite class="sn_src">metronews.fr</cite> - ·  - <span class="sn_tm">27/01/2015</span> - </span> - </div> - </div> - </div> - <div class="sn_r"> - <div class="newstitle"> - <a href="http://url.of.article/" target="_blank" h="ID=news,5022.1"> - Title - </a> - </div> - <div class="sn_img"> - <a href="http://url.of.article2/" target="_blank" h="ID=news,5024.1"> - <img class="rms_img" height="80" id="emb1" src="/image.src" title="Title" width="80" /> - </a> - </div> - <div class="sn_txt"> - <div class="sn_oi"> - <span class="sn_snip">Article Content</span> - <span class="sn_ST"> - <cite class="sn_src">metronews.fr</cite> - ·  - <span class="sn_tm">Il y a 3 heures</span> - </span> - </div> - </div> - </div> - """ + html = """<?xml version="1.0" encoding="utf-8" ?> +<rss version="2.0" xmlns:News="https://www.bing.com:443/news/search?q=python&setmkt=en-US&first=1&format=RSS"> + <channel> + <title>python - Bing News</title> + <link>https://www.bing.com:443/news/search?q=python&setmkt=en-US&first=1&format=RSS</link> + <description>Search results</description> + <image> + <url>http://10.53.64.9/rsslogo.gif</url> + <title>test</title> + <link>https://www.bing.com:443/news/search?q=test&setmkt=en-US&first=1&format=RSS</link> + </image> + <copyright>Copyright</copyright> + <item> + <title>Title</title> + <link>http://another.url.of.article/</link> + <description>Article Content</description> + <pubDate>garbage</pubDate> + <News:Source>Infoworld</News:Source> + <News:Image>http://another.bing.com/image</News:Image> + <News:ImageSize>w={0}&h={1}&c=7</News:ImageSize> + <News:ImageKeepOriginalRatio></News:ImageKeepOriginalRatio> + <News:ImageMaxWidth>620</News:ImageMaxWidth> + <News:ImageMaxHeight>413</News:ImageMaxHeight> + </item> + </channel> +</rss>""" # noqa response = mock.Mock(content=html) results = bing_news.response(response) self.assertEqual(type(results), list) - self.assertEqual(len(results), 6) + self.assertEqual(len(results), 1) + self.assertEqual(results[0]['title'], 'Title') + self.assertEqual(results[0]['url'], 'http://another.url.of.article/') + self.assertEqual(results[0]['content'], 'Article Content') + self.assertEqual(results[0]['thumbnail'], 'http://another.bing.com/image') + + html = """<?xml version="1.0" encoding="utf-8" ?> +<rss version="2.0" xmlns:News="https://www.bing.com:443/news/search?q=python&setmkt=en-US&first=1&format=RSS"> + <channel> + <title>python - Bing News</title> + <link>https://www.bing.com:443/news/search?q=python&setmkt=en-US&first=1&format=RSS</link> + <description>Search results</description> + <image> + <url>http://10.53.64.9/rsslogo.gif</url> + <title>test</title> + <link>https://www.bing.com:443/news/search?q=test&setmkt=en-US&first=1&format=RSS</link> + </image> + </channel> +</rss>""" # noqa - html = """ - <div class="newstitle"> - <a href="http://url.of.article/" target="_blank" h="ID=news,5022.1"> - Title - </a> - </div> - <div class="sn_img"> - <a href="http://url.of.article2/" target="_blank" h="ID=news,5024.1"> - <img class="rms_img" height="80" id="emb1" src="/image.src" title="Title" width="80" /> - </a> - </div> - <div class="sn_txt"> - <div class="sn_oi"> - <span class="sn_snip">Article Content</span> - <span class="sn_ST"> - <cite class="sn_src">metronews.fr</cite> - ·  - <span class="sn_tm">44 minutes ago</span> - </span> - </div> - </div> - """ response = mock.Mock(content=html) results = bing_news.response(response) self.assertEqual(type(results), list) self.assertEqual(len(results), 0) + + html = """<?xml version="1.0" encoding="utf-8" ?>gabarge""" + response = mock.Mock(content=html) + self.assertRaises(lxml.etree.XMLSyntaxError, bing_news.response, response) diff --git a/searx/tests/engines/test_flickr_noapi.py b/searx/tests/engines/test_flickr_noapi.py index a1de3a5e4..3b337a2d8 100644 --- a/searx/tests/engines/test_flickr_noapi.py +++ b/searx/tests/engines/test_flickr_noapi.py @@ -26,19 +26,29 @@ class TestFlickrNoapiEngine(SearxTestCase): self.assertRaises(AttributeError, flickr_noapi.response, '') self.assertRaises(AttributeError, flickr_noapi.response, '[]') - response = mock.Mock(text='"search-photos-models","photos":{},"totalItems":') + response = mock.Mock(text='"search-photos-lite-models","photos":{},"totalItems":') self.assertEqual(flickr_noapi.response(response), []) - response = mock.Mock(text='search-photos-models","photos":{"data": []},"totalItems":') + response = mock.Mock(text='search-photos-lite-models","photos":{"data": []},"totalItems":') self.assertEqual(flickr_noapi.response(response), []) + # everthing is ok test json = """ - "search-photos-models","photos": + "search-photos-lite-models","photos": { "_data": [ { - "_flickrModelRegistry": "photo-models", + "_flickrModelRegistry": "photo-lite-models", "title": "This is the title", + "username": "Owner", + "pathAlias": "klink692", + "realname": "Owner", + "license": 0, + "ownerNsid": "59729010@N00", + "canComment": false, + "commentCount": 14, + "faveCount": 21, + "id": "14001294434", "sizes": { "c": { "displayUrl": "//farm8.staticflickr.com/7246/14001294434_410f653777_c.jpg", @@ -117,40 +127,7 @@ class TestFlickrNoapiEngine(SearxTestCase): "url": "//c4.staticflickr.com/8/7246/14001294434_410f653777_z.jpg", "key": "z" } - }, - "canComment": false, - "rotation": 0, - "owner": { - "_flickrModelRegistry": "person-models", - "pathAlias": "klink692", - "username": "Owner", - "buddyicon": { - "retina": null, - "large": null, - "medium": null, - "small": null, - "default": "//c1.staticflickr.com/9/8108/buddyicons/59729010@N00.jpg?1361642376#59729010@N00" - }, - "isPro": true, - "id": "59729010@N00" - }, - "engagement": { - "_flickrModelRegistry": "photo-engagement-models", - "ownerNsid": "59729010@N00", - "faveCount": 21, - "commentCount": 14, - "viewCount": 10160, - "id": "14001294434" - }, - "description": "Description", - "isHD": false, - "secret": "410f653777", - "canAddMeta": false, - "license": 0, - "oWidth": 1803, - "oHeight": 2669, - "safetyLevel": 0, - "id": "14001294434" + } } ], "fetchedStart": true, @@ -168,15 +145,24 @@ class TestFlickrNoapiEngine(SearxTestCase): self.assertIn('k.jpg', results[0]['img_src']) self.assertIn('n.jpg', results[0]['thumbnail_src']) self.assertIn('Owner', results[0]['content']) - self.assertIn('Description', results[0]['content']) + # no n size, only the z size json = """ - "search-photos-models","photos": + "search-photos-lite-models","photos": { "_data": [ { - "_flickrModelRegistry": "photo-models", + "_flickrModelRegistry": "photo-lite-models", "title": "This is the title", + "username": "Owner", + "pathAlias": "klink692", + "realname": "Owner", + "license": 0, + "ownerNsid": "59729010@N00", + "canComment": false, + "commentCount": 14, + "faveCount": 21, + "id": "14001294434", "sizes": { "z": { "displayUrl": "//farm8.staticflickr.com/7246/14001294434_410f653777_z.jpg", @@ -185,40 +171,7 @@ class TestFlickrNoapiEngine(SearxTestCase): "url": "//c4.staticflickr.com/8/7246/14001294434_410f653777_z.jpg", "key": "z" } - }, - "canComment": false, - "rotation": 0, - "owner": { - "_flickrModelRegistry": "person-models", - "pathAlias": "klink692", - "username": "Owner", - "buddyicon": { - "retina": null, - "large": null, - "medium": null, - "small": null, - "default": "//c1.staticflickr.com/9/8108/buddyicons/59729010@N00.jpg?1361642376#59729010@N00" - }, - "isPro": true, - "id": "59729010@N00" - }, - "engagement": { - "_flickrModelRegistry": "photo-engagement-models", - "ownerNsid": "59729010@N00", - "faveCount": 21, - "commentCount": 14, - "viewCount": 10160, - "id": "14001294434" - }, - "description": "Description", - "isHD": false, - "secret": "410f653777", - "canAddMeta": false, - "license": 0, - "oWidth": 1803, - "oHeight": 2669, - "safetyLevel": 0, - "id": "14001294434" + } } ], "fetchedStart": true, @@ -235,15 +188,24 @@ class TestFlickrNoapiEngine(SearxTestCase): self.assertIn('z.jpg', results[0]['img_src']) self.assertIn('z.jpg', results[0]['thumbnail_src']) self.assertIn('Owner', results[0]['content']) - self.assertIn('Description', results[0]['content']) + # no z or n size json = """ - "search-photos-models","photos": + "search-photos-lite-models","photos": { "_data": [ { - "_flickrModelRegistry": "photo-models", + "_flickrModelRegistry": "photo-lite-models", "title": "This is the title", + "username": "Owner", + "pathAlias": "klink692", + "realname": "Owner", + "license": 0, + "ownerNsid": "59729010@N00", + "canComment": false, + "commentCount": 14, + "faveCount": 21, + "id": "14001294434", "sizes": { "o": { "displayUrl": "//farm8.staticflickr.com/7246/14001294434_410f653777_o.jpg", @@ -252,39 +214,7 @@ class TestFlickrNoapiEngine(SearxTestCase): "url": "//c4.staticflickr.com/8/7246/14001294434_410f653777_o.jpg", "key": "o" } - }, - "canComment": false, - "rotation": 0, - "owner": { - "_flickrModelRegistry": "person-models", - "pathAlias": "klink692", - "username": "Owner", - "buddyicon": { - "retina": null, - "large": null, - "medium": null, - "small": null, - "default": "//c1.staticflickr.com/9/8108/buddyicons/59729010@N00.jpg?1361642376#59729010@N00" - }, - "isPro": true, - "id": "59729010@N00" - }, - "engagement": { - "_flickrModelRegistry": "photo-engagement-models", - "ownerNsid": "59729010@N00", - "faveCount": 21, - "commentCount": 14, - "viewCount": 10160, - "id": "14001294434" - }, - "isHD": false, - "secret": "410f653777", - "canAddMeta": false, - "license": 0, - "oWidth": 1803, - "oHeight": 2669, - "safetyLevel": 0, - "id": "14001294434" + } } ], "fetchedStart": true, @@ -302,48 +232,25 @@ class TestFlickrNoapiEngine(SearxTestCase): self.assertIn('o.jpg', results[0]['thumbnail_src']) self.assertIn('Owner', results[0]['content']) + # no image test json = """ - "search-photos-models","photos": + "search-photos-lite-models","photos": { "_data": [ { - "_flickrModelRegistry": "photo-models", + "_flickrModelRegistry": "photo-lite-models", "title": "This is the title", - "sizes": { - }, - "canComment": false, - "rotation": 0, - "owner": { - "_flickrModelRegistry": "person-models", - "pathAlias": "klink692", - "username": "Owner", - "buddyicon": { - "retina": null, - "large": null, - "medium": null, - "small": null, - "default": "//c1.staticflickr.com/9/8108/buddyicons/59729010@N00.jpg?1361642376#59729010@N00" - }, - "isPro": true, - "id": "59729010@N00" - }, - "engagement": { - "_flickrModelRegistry": "photo-engagement-models", - "ownerNsid": "59729010@N00", - "faveCount": 21, - "commentCount": 14, - "viewCount": 10160, - "id": "14001294434" - }, - "description": "Description", - "isHD": false, - "secret": "410f653777", - "canAddMeta": false, + "username": "Owner", + "pathAlias": "klink692", + "realname": "Owner", "license": 0, - "oWidth": 1803, - "oHeight": 2669, - "safetyLevel": 0, - "id": "14001294434" + "ownerNsid": "59729010@N00", + "canComment": false, + "commentCount": 14, + "faveCount": 21, + "id": "14001294434", + "sizes": { + } } ], "fetchedStart": true, @@ -356,6 +263,7 @@ class TestFlickrNoapiEngine(SearxTestCase): self.assertEqual(type(results), list) self.assertEqual(len(results), 0) + # null test json = """ "search-photos-models","photos": { @@ -370,13 +278,22 @@ class TestFlickrNoapiEngine(SearxTestCase): self.assertEqual(type(results), list) self.assertEqual(len(results), 0) + # no ownerNsid test json = """ - "search-photos-models","photos": + "search-photos-lite-models","photos": { "_data": [ { - "_flickrModelRegistry": "photo-models", + "_flickrModelRegistry": "photo-lite-models", "title": "This is the title", + "username": "Owner", + "pathAlias": "klink692", + "realname": "Owner", + "license": 0, + "canComment": false, + "commentCount": 14, + "faveCount": 21, + "id": "14001294434", "sizes": { "o": { "displayUrl": "//farm8.staticflickr.com/7246/14001294434_410f653777_o.jpg", @@ -385,39 +302,7 @@ class TestFlickrNoapiEngine(SearxTestCase): "url": "//c4.staticflickr.com/8/7246/14001294434_410f653777_o.jpg", "key": "o" } - }, - "canComment": false, - "rotation": 0, - "owner": { - "_flickrModelRegistry": "person-models", - "pathAlias": "klink692", - "username": "Owner", - "buddyicon": { - "retina": null, - "large": null, - "medium": null, - "small": null, - "default": "//c1.staticflickr.com/9/8108/buddyicons/59729010@N00.jpg?1361642376#59729010@N00" - }, - "isPro": true - }, - "engagement": { - "_flickrModelRegistry": "photo-engagement-models", - "ownerNsid": "59729010@N00", - "faveCount": 21, - "commentCount": 14, - "viewCount": 10160, - "id": "14001294434" - }, - "description": "Description", - "isHD": false, - "secret": "410f653777", - "canAddMeta": false, - "license": 0, - "oWidth": 1803, - "oHeight": 2669, - "safetyLevel": 0, - "id": "14001294434" + } } ], "fetchedStart": true, @@ -430,6 +315,7 @@ class TestFlickrNoapiEngine(SearxTestCase): self.assertEqual(type(results), list) self.assertEqual(len(results), 0) + # garbage test json = """ {"toto":[ {"id":200,"name":"Artist Name", diff --git a/searx/tests/engines/test_google.py b/searx/tests/engines/test_google.py index 2a90fc5ec..b706e511d 100644 --- a/searx/tests/engines/test_google.py +++ b/searx/tests/engines/test_google.py @@ -8,6 +8,12 @@ from searx.testing import SearxTestCase class TestGoogleEngine(SearxTestCase): + def mock_response(self, text): + response = mock.Mock(text=text, url='https://www.google.com/search?q=test&start=0&gbv=1') + response.search_params = mock.Mock() + response.search_params.get = mock.Mock(return_value='www.google.com') + return response + def test_request(self): query = 'test_query' dicto = defaultdict(dict) @@ -16,14 +22,17 @@ class TestGoogleEngine(SearxTestCase): params = google.request(query, dicto) self.assertIn('url', params) self.assertIn(query, params['url']) - self.assertIn('google.com', params['url']) + self.assertIn('google.fr', params['url']) self.assertNotIn('PREF', params['cookies']) + self.assertIn('NID', params['cookies']) self.assertIn('fr', params['headers']['Accept-Language']) dicto['language'] = 'all' params = google.request(query, dicto) + self.assertIn('google.com', params['url']) self.assertIn('en', params['headers']['Accept-Language']) self.assertIn('PREF', params['cookies']) + self.assertIn('NID', params['cookies']) def test_response(self): self.assertRaises(AttributeError, google.response, None) @@ -31,7 +40,7 @@ class TestGoogleEngine(SearxTestCase): self.assertRaises(AttributeError, google.response, '') self.assertRaises(AttributeError, google.response, '[]') - response = mock.Mock(text='<html></html>') + response = self.mock_response('<html></html>') self.assertEqual(google.response(response), []) html = """ @@ -124,7 +133,7 @@ class TestGoogleEngine(SearxTestCase): </a> </p> """ - response = mock.Mock(text=html) + response = self.mock_response(html) results = google.response(response) self.assertEqual(type(results), list) self.assertEqual(len(results), 2) @@ -137,11 +146,21 @@ class TestGoogleEngine(SearxTestCase): <li class="b_algo" u="0|5109|4755453613245655|UAGjXgIrPH5yh-o5oNHRx_3Zta87f_QO"> </li> """ - response = mock.Mock(text=html) + response = self.mock_response(html) results = google.response(response) self.assertEqual(type(results), list) self.assertEqual(len(results), 0) + response = mock.Mock(text='<html></html>', url='https://sorry.google.com') + response.search_params = mock.Mock() + response.search_params.get = mock.Mock(return_value='www.google.com') + self.assertRaises(RuntimeWarning, google.response, response) + + response = mock.Mock(text='<html></html>', url='https://www.google.com/sorry/IndexRedirect') + response.search_params = mock.Mock() + response.search_params.get = mock.Mock(return_value='www.google.com') + self.assertRaises(RuntimeWarning, google.response, response) + def test_parse_images(self): html = """ <li> @@ -154,7 +173,7 @@ class TestGoogleEngine(SearxTestCase): </li> """ dom = lxml.html.fromstring(html) - results = google.parse_images(dom) + results = google.parse_images(dom, 'www.google.com') self.assertEqual(type(results), list) self.assertEqual(len(results), 1) self.assertEqual(results[0]['url'], 'http://this.is.the.url/') diff --git a/searx/tests/engines/test_qwant.py b/searx/tests/engines/test_qwant.py new file mode 100644 index 000000000..7d79d13d8 --- /dev/null +++ b/searx/tests/engines/test_qwant.py @@ -0,0 +1,317 @@ +from collections import defaultdict +import mock +from searx.engines import qwant +from searx.testing import SearxTestCase + + +class TestQwantEngine(SearxTestCase): + + def test_request(self): + query = 'test_query' + dicto = defaultdict(dict) + dicto['pageno'] = 0 + dicto['language'] = 'fr_FR' + qwant.categories = [''] + params = qwant.request(query, dicto) + self.assertIn('url', params) + self.assertIn(query, params['url']) + self.assertIn('web', params['url']) + self.assertIn('qwant.com', params['url']) + self.assertIn('fr_fr', params['url']) + + dicto['language'] = 'all' + qwant.categories = ['news'] + params = qwant.request(query, dicto) + self.assertFalse('fr' in params['url']) + self.assertIn('news', params['url']) + + def test_response(self): + self.assertRaises(AttributeError, qwant.response, None) + self.assertRaises(AttributeError, qwant.response, []) + self.assertRaises(AttributeError, qwant.response, '') + self.assertRaises(AttributeError, qwant.response, '[]') + + response = mock.Mock(text='{}') + self.assertEqual(qwant.response(response), []) + + response = mock.Mock(text='{"data": {}}') + self.assertEqual(qwant.response(response), []) + + json = """ + { + "status": "success", + "data": { + "query": { + "locale": "en_us", + "query": "Test", + "offset": 10 + }, + "result": { + "items": [ + { + "title": "Title", + "score": 9999, + "url": "http://www.url.xyz", + "source": "...", + "desc": "Description", + "date": "", + "_id": "db0aadd62c2a8565567ffc382f5c61fa", + "favicon": "https://s.qwant.com/fav.ico" + } + ], + "filters": [] + }, + "cache": { + "key": "e66aa864c00147a0e3a16ff7a5efafde", + "created": 1433092754, + "expiration": 259200, + "status": "miss", + "age": 0 + } + } + } + """ + response = mock.Mock(text=json) + qwant.categories = ['general'] + results = qwant.response(response) + self.assertEqual(type(results), list) + self.assertEqual(len(results), 1) + self.assertEqual(results[0]['title'], 'Title') + self.assertEqual(results[0]['url'], 'http://www.url.xyz') + self.assertEqual(results[0]['content'], 'Description') + + json = """ + { + "status": "success", + "data": { + "query": { + "locale": "en_us", + "query": "Test", + "offset": 10 + }, + "result": { + "items": [ + { + "title": "Title", + "score": 9999, + "url": "http://www.url.xyz", + "source": "...", + "media": "http://image.jpg", + "desc": "", + "thumbnail": "http://thumbnail.jpg", + "date": "", + "_id": "db0aadd62c2a8565567ffc382f5c61fa", + "favicon": "https://s.qwant.com/fav.ico" + } + ], + "filters": [] + }, + "cache": { + "key": "e66aa864c00147a0e3a16ff7a5efafde", + "created": 1433092754, + "expiration": 259200, + "status": "miss", + "age": 0 + } + } + } + """ + response = mock.Mock(text=json) + qwant.categories = ['images'] + results = qwant.response(response) + self.assertEqual(type(results), list) + self.assertEqual(len(results), 1) + self.assertEqual(results[0]['title'], 'Title') + self.assertEqual(results[0]['url'], 'http://www.url.xyz') + self.assertEqual(results[0]['content'], '') + self.assertEqual(results[0]['thumbnail_src'], 'http://thumbnail.jpg') + self.assertEqual(results[0]['img_src'], 'http://image.jpg') + + json = """ + { + "status": "success", + "data": { + "query": { + "locale": "en_us", + "query": "Test", + "offset": 10 + }, + "result": { + "items": [ + { + "title": "Title", + "score": 9999, + "url": "http://www.url.xyz", + "source": "...", + "desc": "Description", + "date": 1433260920, + "_id": "db0aadd62c2a8565567ffc382f5c61fa", + "favicon": "https://s.qwant.com/fav.ico" + } + ], + "filters": [] + }, + "cache": { + "key": "e66aa864c00147a0e3a16ff7a5efafde", + "created": 1433092754, + "expiration": 259200, + "status": "miss", + "age": 0 + } + } + } + """ + response = mock.Mock(text=json) + qwant.categories = ['news'] + results = qwant.response(response) + self.assertEqual(type(results), list) + self.assertEqual(len(results), 1) + self.assertEqual(results[0]['title'], 'Title') + self.assertEqual(results[0]['url'], 'http://www.url.xyz') + self.assertEqual(results[0]['content'], 'Description') + self.assertIn('publishedDate', results[0]) + + json = """ + { + "status": "success", + "data": { + "query": { + "locale": "en_us", + "query": "Test", + "offset": 10 + }, + "result": { + "items": [ + { + "title": "Title", + "score": 9999, + "url": "http://www.url.xyz", + "source": "...", + "desc": "Description", + "date": 1433260920, + "_id": "db0aadd62c2a8565567ffc382f5c61fa", + "favicon": "https://s.qwant.com/fav.ico" + } + ], + "filters": [] + }, + "cache": { + "key": "e66aa864c00147a0e3a16ff7a5efafde", + "created": 1433092754, + "expiration": 259200, + "status": "miss", + "age": 0 + } + } + } + """ + response = mock.Mock(text=json) + qwant.categories = ['social media'] + results = qwant.response(response) + self.assertEqual(type(results), list) + self.assertEqual(len(results), 1) + self.assertEqual(results[0]['title'], 'Title') + self.assertEqual(results[0]['url'], 'http://www.url.xyz') + self.assertEqual(results[0]['content'], 'Description') + self.assertIn('publishedDate', results[0]) + + json = """ + { + "status": "success", + "data": { + "query": { + "locale": "en_us", + "query": "Test", + "offset": 10 + }, + "result": { + "items": [ + { + "title": "Title", + "score": 9999, + "url": "http://www.url.xyz", + "source": "...", + "desc": "Description", + "date": 1433260920, + "_id": "db0aadd62c2a8565567ffc382f5c61fa", + "favicon": "https://s.qwant.com/fav.ico" + } + ], + "filters": [] + }, + "cache": { + "key": "e66aa864c00147a0e3a16ff7a5efafde", + "created": 1433092754, + "expiration": 259200, + "status": "miss", + "age": 0 + } + } + } + """ + response = mock.Mock(text=json) + qwant.categories = [''] + results = qwant.response(response) + self.assertEqual(type(results), list) + self.assertEqual(len(results), 0) + + json = """ + { + "status": "success", + "data": { + "query": { + "locale": "en_us", + "query": "Test", + "offset": 10 + }, + "result": { + "filters": [] + }, + "cache": { + "key": "e66aa864c00147a0e3a16ff7a5efafde", + "created": 1433092754, + "expiration": 259200, + "status": "miss", + "age": 0 + } + } + } + """ + response = mock.Mock(text=json) + results = qwant.response(response) + self.assertEqual(type(results), list) + self.assertEqual(len(results), 0) + + json = """ + { + "status": "success", + "data": { + "query": { + "locale": "en_us", + "query": "Test", + "offset": 10 + }, + "cache": { + "key": "e66aa864c00147a0e3a16ff7a5efafde", + "created": 1433092754, + "expiration": 259200, + "status": "miss", + "age": 0 + } + } + } + """ + response = mock.Mock(text=json) + results = qwant.response(response) + self.assertEqual(type(results), list) + self.assertEqual(len(results), 0) + + json = """ + { + "status": "success" + } + """ + response = mock.Mock(text=json) + results = qwant.response(response) + self.assertEqual(type(results), list) + self.assertEqual(len(results), 0) diff --git a/searx/tests/engines/test_swisscows.py b/searx/tests/engines/test_swisscows.py new file mode 100644 index 000000000..3b4ce7b0f --- /dev/null +++ b/searx/tests/engines/test_swisscows.py @@ -0,0 +1,128 @@ +from collections import defaultdict +import mock +from searx.engines import swisscows +from searx.testing import SearxTestCase + + +class TestSwisscowsEngine(SearxTestCase): + + def test_request(self): + query = 'test_query' + dicto = defaultdict(dict) + dicto['pageno'] = 1 + dicto['language'] = 'de_DE' + params = swisscows.request(query, dicto) + self.assertTrue('url' in params) + self.assertTrue(query in params['url']) + self.assertTrue('swisscows.ch' in params['url']) + self.assertTrue('uiLanguage=de' in params['url']) + self.assertTrue('region=de-DE' in params['url']) + + dicto['language'] = 'all' + params = swisscows.request(query, dicto) + self.assertTrue('uiLanguage=browser' in params['url']) + self.assertTrue('region=browser' in params['url']) + + dicto['category'] = 'images' + params = swisscows.request(query, dicto) + self.assertIn('image', params['url']) + + def test_response(self): + self.assertRaises(AttributeError, swisscows.response, None) + self.assertRaises(AttributeError, swisscows.response, []) + self.assertRaises(AttributeError, swisscows.response, '') + self.assertRaises(AttributeError, swisscows.response, '[]') + + response = mock.Mock(content='<html></html>') + self.assertEqual(swisscows.response(response), []) + + response = mock.Mock(content='<html></html>') + self.assertEqual(swisscows.response(response), []) + + html = u""" + <script> + App.Dispatcher.dispatch("initialize", { + html5history: true, + initialData: {"Request": + {"Page":1, + "ItemsCount":1, + "Query":"This should ", + "NormalizedQuery":"This should ", + "Region":"de-AT", + "UILanguage":"de"}, + "Results":{"items":[ + {"Title":"\uE000This should\uE001 be the title", + "Description":"\uE000This should\uE001 be the content.", + "Url":"http://this.should.be.the.link/", + "DisplayUrl":"www.\uE000this.should.be.the\uE001.link", + "Id":"782ef287-e439-451c-b380-6ebc14ba033d"}, + {"Title":"Datei:This should1.svg", + "Url":"https://i.swisscows.ch/?link=http%3a%2f%2fts2.mm.This/should1.png", + "SourceUrl":"http://de.wikipedia.org/wiki/Datei:This should1.svg", + "DisplayUrl":"de.wikipedia.org/wiki/Datei:This should1.svg", + "Width":950, + "Height":534, + "FileSize":92100, + "ContentType":"image/jpeg", + "Thumbnail":{ + "Url":"https://i.swisscows.ch/?link=http%3a%2f%2fts2.mm.This/should1.png", + "ContentType":"image/jpeg", + "Width":300, + "Height":168, + "FileSize":9134}, + "Id":"6a97a542-8f65-425f-b7f6-1178c3aba7be" + } + ],"TotalCount":55300, + "Query":"This should " + }, + "Images":[{"Title":"Datei:This should.svg", + "Url":"https://i.swisscows.ch/?link=http%3a%2f%2fts2.mm.This/should.png", + "SourceUrl":"http://de.wikipedia.org/wiki/Datei:This should.svg", + "DisplayUrl":"de.wikipedia.org/wiki/Datei:This should.svg", + "Width":1280, + "Height":677, + "FileSize":50053, + "ContentType":"image/png", + "Thumbnail":{"Url":"https://i.swisscows.ch/?link=http%3a%2f%2fts2.mm.This/should.png", + "ContentType":"image/png", + "Width":300, + "Height":158, + "FileSize":8023}, + "Id":"ae230fd8-a06a-47d6-99d5-e74766d8143a"}]}, + environment: "production" + }).then(function (options) { + $('#Search_Form').on('submit', function (e) { + if (!Modernizr.history) return; + e.preventDefault(); + + var $form = $(this), + $query = $('#Query'), + query = $.trim($query.val()), + path = App.Router.makePath($form.attr('action'), null, $form.serializeObject()) + + if (query.length) { + options.html5history ? + ReactRouter.HistoryLocation.push(path) : + ReactRouter.RefreshLocation.push(path); + } + else $('#Query').trigger('blur'); + }); + + }); + </script> + """ + response = mock.Mock(content=html) + results = swisscows.response(response) + self.assertEqual(type(results), list) + self.assertEqual(len(results), 3) + self.assertEqual(results[0]['title'], 'This should be the title') + self.assertEqual(results[0]['url'], 'http://this.should.be.the.link/') + self.assertEqual(results[0]['content'], 'This should be the content.') + self.assertEqual(results[1]['title'], 'Datei:This should1.svg') + self.assertEqual(results[1]['url'], 'http://de.wikipedia.org/wiki/Datei:This should1.svg') + self.assertEqual(results[1]['img_src'], 'http://ts2.mm.This/should1.png') + self.assertEqual(results[1]['template'], 'images.html') + self.assertEqual(results[2]['title'], 'Datei:This should.svg') + self.assertEqual(results[2]['url'], 'http://de.wikipedia.org/wiki/Datei:This should.svg') + self.assertEqual(results[2]['img_src'], 'http://ts2.mm.This/should.png') + self.assertEqual(results[2]['template'], 'images.html') diff --git a/searx/tests/engines/test_vimeo.py b/searx/tests/engines/test_vimeo.py index dad7239b4..50b1cb563 100644 --- a/searx/tests/engines/test_vimeo.py +++ b/searx/tests/engines/test_vimeo.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from collections import defaultdict import mock from searx.engines import vimeo @@ -25,26 +26,42 @@ class TestVimeoEngine(SearxTestCase): self.assertEqual(vimeo.response(response), []) html = """ - <div id="browse_content" class="" data-search-id="696d5f8366914ec4ffec33cf7652de384976d4f4"> - <ol class="js-browse_list clearfix browse browse_videos browse_videos_thumbnails kane" + <div id="browse_content" class="results_grid" data-search-id="696d5f8366914ec4ffec33cf7652de384976d4f4"> + <ul class="js-browse_list clearfix browse browse_videos browse_videos_thumbnails kane" data-stream="c2VhcmNoOjo6ZGVzYzp7InF1ZXJ5IjoidGVzdCJ9"> - <li id="clip_100785455" data-start-page="/search/page:1/sort:relevant/" data-position="1"> - <a href="/videoid" title="Futurama 3d (test shot)"> - <img src="http://image.url.webp" - srcset="http://i.vimeocdn.com/video/482375085_590x332.webp 2x" alt="" - class="thumbnail thumbnail_lg_wide"> - <div class="data"> - <p class="title"> - This is the title - </p> - <p class="meta"> - <time datetime="2014-07-15T04:16:27-04:00" - title="mardi 15 juillet 2014 04:16">Il y a 6 mois</time> - </p> - </div> - </a> + <li data-position="7" data-result-id="clip_79600943"> + <div class="clip_thumbnail"> + <a href="/videoid" class="js-result_url"> + <div class="thumbnail_wrapper"> + <img src="http://image.url.webp" class="js-clip_thumbnail_image"> + <div class="overlay overlay_clip_meta"> + <div class="meta_data_footer"> + <span class="clip_upload_date"> + <time datetime="2013-11-17T08:49:09-05:00" + title="dimanche 17 novembre 2013 08:49">Il y a 1 an</time> + </span> + <span class="clip_likes"> + <img src="https://f.vimeocdn.com/images_v6/svg/heart-icon.svg">2 215 + </span> + <span class="clip_comments"> + <img src="https://f.vimeocdn.com/images_v6/svg/comment-icon.svg">75 + </span> + <span class="overlay meta_data_footer clip_duration">01:12</span> + </div> + </div> + </div> + <span class="title">This is the title</span> + </a> + </div> + <div class="clip_thumbnail_attribution"> + <a href="/fedorshmidt"> + <img src="https://i.vimeocdn.com/portrait/6628061_100x100.jpg" class="avatar"> + <span class="display_name">Fedor Shmidt</span> + </a> + <span class="plays">2,1M lectures</span> + </div> </li> - </ol> + </ul> </div> """ response = mock.Mock(text=html) diff --git a/searx/tests/engines/test_www1x.py b/searx/tests/engines/test_www1x.py index ab4f282c1..9df8de6bf 100644 --- a/searx/tests/engines/test_www1x.py +++ b/searx/tests/engines/test_www1x.py @@ -51,7 +51,7 @@ class TestWww1xEngine(SearxTestCase): results = www1x.response(response) self.assertEqual(type(results), list) self.assertEqual(len(results), 1) - self.assertEqual(results[0]['url'], 'http://1x.com/photo/123456') - self.assertEqual(results[0]['thumbnail_src'], 'http://1x.com/images/user/testimage-123456.jpg') + self.assertEqual(results[0]['url'], 'https://1x.com/photo/123456') + self.assertEqual(results[0]['thumbnail_src'], 'https://1x.com/images/user/testimage-123456.jpg') self.assertEqual(results[0]['content'], '') self.assertEqual(results[0]['template'], 'images.html') diff --git a/searx/tests/engines/test_yahoo_news.py b/searx/tests/engines/test_yahoo_news.py index 94d819d61..4d7fc0a10 100644 --- a/searx/tests/engines/test_yahoo_news.py +++ b/searx/tests/engines/test_yahoo_news.py @@ -29,6 +29,13 @@ class TestYahooNewsEngine(SearxTestCase): self.assertIn('en', params['cookies']['sB']) self.assertIn('en', params['url']) + def test_sanitize_url(self): + url = "test.url" + self.assertEqual(url, yahoo_news.sanitize_url(url)) + + url = "www.yahoo.com/;_ylt=test" + self.assertEqual("www.yahoo.com/", yahoo_news.sanitize_url(url)) + def test_response(self): self.assertRaises(AttributeError, yahoo_news.response, None) self.assertRaises(AttributeError, yahoo_news.response, []) @@ -57,7 +64,17 @@ class TestYahooNewsEngine(SearxTestCase): This is the content </div> </li> - </div> + <li class="first"> + <div class="compTitle"> + <h3> + <a class="yschttl spt" target="_blank"> + </a> + </h3> + </div> + <div class="compText"> + </div> + </li> + </ol> """ response = mock.Mock(text=html) results = yahoo_news.response(response) diff --git a/searx/tests/engines/test_youtube_api.py b/searx/tests/engines/test_youtube_api.py new file mode 100644 index 000000000..0d4d478c3 --- /dev/null +++ b/searx/tests/engines/test_youtube_api.py @@ -0,0 +1,111 @@ +from collections import defaultdict +import mock +from searx.engines import youtube_api +from searx.testing import SearxTestCase + + +class TestYoutubeAPIEngine(SearxTestCase): + + def test_request(self): + query = 'test_query' + dicto = defaultdict(dict) + dicto['pageno'] = 0 + dicto['language'] = 'fr_FR' + params = youtube_api.request(query, dicto) + self.assertTrue('url' in params) + self.assertTrue(query in params['url']) + self.assertIn('googleapis.com', params['url']) + self.assertIn('youtube', params['url']) + self.assertIn('fr', params['url']) + + dicto['language'] = 'all' + params = youtube_api.request(query, dicto) + self.assertFalse('fr' in params['url']) + + def test_response(self): + self.assertRaises(AttributeError, youtube_api.response, None) + self.assertRaises(AttributeError, youtube_api.response, []) + self.assertRaises(AttributeError, youtube_api.response, '') + self.assertRaises(AttributeError, youtube_api.response, '[]') + + response = mock.Mock(text='{}') + self.assertEqual(youtube_api.response(response), []) + + response = mock.Mock(text='{"data": []}') + self.assertEqual(youtube_api.response(response), []) + + json = """ + { + "kind": "youtube#searchListResponse", + "etag": "xmg9xJZuZD438sF4hb-VcBBREXc/YJQDcTBCDcaBvl-sRZJoXdvy1ME", + "nextPageToken": "CAUQAA", + "pageInfo": { + "totalResults": 1000000, + "resultsPerPage": 20 + }, + "items": [ + { + "kind": "youtube#searchResult", + "etag": "xmg9xJZuZD438sF4hb-VcBBREXc/IbLO64BMhbHIgWLwLw7MDYe7Hs4", + "id": { + "kind": "youtube#video", + "videoId": "DIVZCPfAOeM" + }, + "snippet": { + "publishedAt": "2015-05-29T22:41:04.000Z", + "channelId": "UCNodmx1ERIjKqvcJLtdzH5Q", + "title": "Title", + "description": "Description", + "thumbnails": { + "default": { + "url": "https://i.ytimg.com/vi/DIVZCPfAOeM/default.jpg" + }, + "medium": { + "url": "https://i.ytimg.com/vi/DIVZCPfAOeM/mqdefault.jpg" + }, + "high": { + "url": "https://i.ytimg.com/vi/DIVZCPfAOeM/hqdefault.jpg" + } + }, + "channelTitle": "MinecraftUniverse", + "liveBroadcastContent": "none" + } + } + ] + } + """ + response = mock.Mock(text=json) + results = youtube_api.response(response) + self.assertEqual(type(results), list) + self.assertEqual(len(results), 1) + self.assertEqual(results[0]['title'], 'Title') + self.assertEqual(results[0]['url'], 'https://www.youtube.com/watch?v=DIVZCPfAOeM') + self.assertEqual(results[0]['content'], 'Description') + self.assertEqual(results[0]['thumbnail'], 'https://i.ytimg.com/vi/DIVZCPfAOeM/hqdefault.jpg') + self.assertTrue('DIVZCPfAOeM' in results[0]['embedded']) + + json = """ + { + "kind": "youtube#searchListResponse", + "etag": "xmg9xJZuZD438sF4hb-VcBBREXc/YJQDcTBCDcaBvl-sRZJoXdvy1ME", + "nextPageToken": "CAUQAA", + "pageInfo": { + "totalResults": 1000000, + "resultsPerPage": 20 + } + } + """ + response = mock.Mock(text=json) + results = youtube_api.response(response) + self.assertEqual(type(results), list) + self.assertEqual(len(results), 0) + + json = """ + {"toto":{"entry":[] + } + } + """ + response = mock.Mock(text=json) + results = youtube_api.response(response) + self.assertEqual(type(results), list) + self.assertEqual(len(results), 0) diff --git a/searx/tests/engines/test_youtube_noapi.py b/searx/tests/engines/test_youtube_noapi.py new file mode 100644 index 000000000..9fa8fd20e --- /dev/null +++ b/searx/tests/engines/test_youtube_noapi.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +from collections import defaultdict +import mock +from searx.engines import youtube_noapi +from searx.testing import SearxTestCase + + +class TestYoutubeNoAPIEngine(SearxTestCase): + + def test_request(self): + query = 'test_query' + dicto = defaultdict(dict) + dicto['pageno'] = 0 + params = youtube_noapi.request(query, dicto) + self.assertIn('url', params) + self.assertIn(query, params['url']) + self.assertIn('youtube.com', params['url']) + + def test_response(self): + self.assertRaises(AttributeError, youtube_noapi.response, None) + self.assertRaises(AttributeError, youtube_noapi.response, []) + self.assertRaises(AttributeError, youtube_noapi.response, '') + self.assertRaises(AttributeError, youtube_noapi.response, '[]') + + response = mock.Mock(text='<html></html>') + self.assertEqual(youtube_noapi.response(response), []) + + html = """ + <ol id="item-section-063864" class="item-section"> + <li> + <div class="yt-lockup yt-lockup-tile yt-lockup-video vve-check clearfix yt-uix-tile" + data-context-item-id="DIVZCPfAOeM" + data-visibility-tracking="CBgQ3DAYACITCPGXnYau6sUCFZEIHAod-VQASCj0JECx_-GK5uqMpcIB"> + <div class="yt-lockup-dismissable"><div class="yt-lockup-thumbnail contains-addto"> + <a aria-hidden="true" href="/watch?v=DIVZCPfAOeM" class=" yt-uix-sessionlink pf-link" + data-sessionlink="itct=CBgQ3DAYACITCPGXnYau6sUCFZEIHAod-VQASCj0JFIEdGVzdA"> + <div class="yt-thumb video-thumb"><img src="//i.ytimg.com/vi/DIVZCPfAOeM/mqdefault.jpg" + width="196" height="110"/></div><span class="video-time" aria-hidden="true">11:35</span></a> + <span class="thumb-menu dark-overflow-action-menu video-actions"> + </span> + </div> + <div class="yt-lockup-content"> + <h3 class="yt-lockup-title"> + <a href="/watch?v=DIVZCPfAOeM" + class="yt-uix-tile-link yt-ui-ellipsis yt-ui-ellipsis-2 yt-uix-sessionlink spf-link" + data-sessionlink="itct=CBgQ3DAYACITCPGXnYau6sUCFZEIHAod-VQASCj0JFIEdGVzdA" + title="Top Speed Test Kawasaki Ninja H2 (Thailand) By. MEHAY SUPERBIKE" + aria-describedby="description-id-259079" rel="spf-prefetch" dir="ltr"> + Title + </a> + <span class="accessible-description" id="description-id-259079"> - Durée : 11:35.</span> + </h3> + <div class="yt-lockup-byline">de + <a href="/user/mheejapan" class=" yt-uix-sessionlink spf-link g-hovercard" + data-sessionlink="itct=CBgQ3DAYACITCPGXnYau6sUCFZEIHAod-VQASCj0JA" data-ytid="UCzEesu54Hjs0uRKmpy66qeA" + data-name="">MEHAY SUPERBIKE</a></div><div class="yt-lockup-meta"> + <ul class="yt-lockup-meta-info"> + <li>il y a 20 heures</li> + <li>8 424 vues</li> + </ul> + </div> + <div class="yt-lockup-description yt-ui-ellipsis yt-ui-ellipsis-2" dir="ltr"> + Description + </div> + <div class="yt-lockup-badges"> + <ul class="yt-badge-list "> + <li class="yt-badge-item" > + <span class="yt-badge">Nouveauté</span> + </li> + <li class="yt-badge-item" ><span class="yt-badge " >HD</span></li> + </ul> + </div> + <div class="yt-lockup-action-menu yt-uix-menu-container"> + <div class="yt-uix-menu yt-uix-videoactionmenu hide-until-delayloaded" + data-video-id="DIVZCPfAOeM" data-menu-content-id="yt-uix-videoactionmenu-menu"> + </div> + </div> + </div> + </div> + </div> + </li> + </ol> + """ + response = mock.Mock(text=html) + results = youtube_noapi.response(response) + self.assertEqual(type(results), list) + self.assertEqual(len(results), 1) + self.assertEqual(results[0]['title'], 'Title') + self.assertEqual(results[0]['url'], 'https://www.youtube.com/watch?v=DIVZCPfAOeM') + self.assertEqual(results[0]['content'], 'Description') + self.assertEqual(results[0]['thumbnail'], 'https://i.ytimg.com/vi/DIVZCPfAOeM/hqdefault.jpg') + self.assertTrue('DIVZCPfAOeM' in results[0]['embedded']) + + html = """ + <ol id="item-section-063864" class="item-section"> + <li> + <div class="yt-lockup yt-lockup-tile yt-lockup-video vve-check clearfix yt-uix-tile" + data-context-item-id="DIVZCPfAOeM" + data-visibility-tracking="CBgQ3DAYACITCPGXnYau6sUCFZEIHAod-VQASCj0JECx_-GK5uqMpcIB"> + <div class="yt-lockup-dismissable"><div class="yt-lockup-thumbnail contains-addto"> + <a aria-hidden="true" href="/watch?v=DIVZCPfAOeM" class=" yt-uix-sessionlink pf-link" + data-sessionlink="itct=CBgQ3DAYACITCPGXnYau6sUCFZEIHAod-VQASCj0JFIEdGVzdA"> + <div class="yt-thumb video-thumb"><img src="//i.ytimg.com/vi/DIVZCPfAOeM/mqdefault.jpg" + width="196" height="110"/></div><span class="video-time" aria-hidden="true">11:35</span></a> + <span class="thumb-menu dark-overflow-action-menu video-actions"> + </span> + </div> + <div class="yt-lockup-content"> + <h3 class="yt-lockup-title"> + <span class="accessible-description" id="description-id-259079"> - Durée : 11:35.</span> + </h3> + <div class="yt-lockup-byline">de + <a href="/user/mheejapan" class=" yt-uix-sessionlink spf-link g-hovercard" + data-sessionlink="itct=CBgQ3DAYACITCPGXnYau6sUCFZEIHAod-VQASCj0JA" data-ytid="UCzEesu54Hjs0uRKmpy66qeA" + data-name="">MEHAY SUPERBIKE</a></div><div class="yt-lockup-meta"> + <ul class="yt-lockup-meta-info"> + <li>il y a 20 heures</li> + <li>8 424 vues</li> + </ul> + </div> + <div class="yt-lockup-badges"> + <ul class="yt-badge-list "> + <li class="yt-badge-item" > + <span class="yt-badge">Nouveauté</span> + </li> + <li class="yt-badge-item" ><span class="yt-badge " >HD</span></li> + </ul> + </div> + <div class="yt-lockup-action-menu yt-uix-menu-container"> + <div class="yt-uix-menu yt-uix-videoactionmenu hide-until-delayloaded" + data-video-id="DIVZCPfAOeM" data-menu-content-id="yt-uix-videoactionmenu-menu"> + </div> + </div> + </div> + </div> + </div> + </li> + </ol> + """ + response = mock.Mock(text=html) + results = youtube_noapi.response(response) + self.assertEqual(type(results), list) + self.assertEqual(len(results), 1) + + html = """ + <ol id="item-section-063864" class="item-section"> + <li> + </li> + </ol> + """ + response = mock.Mock(text=html) + results = youtube_noapi.response(response) + self.assertEqual(type(results), list) + self.assertEqual(len(results), 0) diff --git a/searx/tests/test_engines.py b/searx/tests/test_engines.py index 5770458f3..dc062e95f 100644 --- a/searx/tests/test_engines.py +++ b/searx/tests/test_engines.py @@ -25,6 +25,7 @@ from searx.tests.engines.test_mixcloud import * # noqa from searx.tests.engines.test_openstreetmap import * # noqa from searx.tests.engines.test_photon import * # noqa from searx.tests.engines.test_piratebay import * # noqa +from searx.tests.engines.test_qwant import * # noqa from searx.tests.engines.test_searchcode_code import * # noqa from searx.tests.engines.test_searchcode_doc import * # noqa from searx.tests.engines.test_soundcloud import * # noqa @@ -32,6 +33,7 @@ from searx.tests.engines.test_spotify import * # noqa from searx.tests.engines.test_stackoverflow import * # noqa from searx.tests.engines.test_startpage import * # noqa from searx.tests.engines.test_subtitleseeker import * # noqa +from searx.tests.engines.test_swisscows import * # noqa from searx.tests.engines.test_twitter import * # noqa from searx.tests.engines.test_vimeo import * # noqa from searx.tests.engines.test_www1x import * # noqa @@ -39,4 +41,6 @@ from searx.tests.engines.test_www500px import * # noqa from searx.tests.engines.test_yacy import * # noqa from searx.tests.engines.test_yahoo import * # noqa from searx.tests.engines.test_youtube import * # noqa +from searx.tests.engines.test_youtube_api import * # noqa +from searx.tests.engines.test_youtube_noapi import * # noqa from searx.tests.engines.test_yahoo_news import * # noqa diff --git a/searx/tests/test_plugins.py b/searx/tests/test_plugins.py index 8dcad1142..c5171127c 100644 --- a/searx/tests/test_plugins.py +++ b/searx/tests/test_plugins.py @@ -38,10 +38,11 @@ class SelfIPTest(SearxTestCase): def test_PluginStore_init(self): store = plugins.PluginStore() - store.register(plugins.self_ip) + store.register(plugins.self_info) self.assertTrue(len(store.plugins) == 1) + # IP test request = Mock(user_plugins=store.plugins, remote_addr='127.0.0.1') request.headers.getlist.return_value = [] @@ -49,3 +50,19 @@ class SelfIPTest(SearxTestCase): query='ip')} store.call('post_search', request, ctx) self.assertTrue('127.0.0.1' in ctx['search'].answers) + + # User agent test + request = Mock(user_plugins=store.plugins, + user_agent='Mock') + request.headers.getlist.return_value = [] + ctx = {'search': Mock(answers=set(), + query='user-agent')} + store.call('post_search', request, ctx) + self.assertTrue('Mock' in ctx['search'].answers) + ctx = {'search': Mock(answers=set(), + query='user agent')} + store.call('post_search', request, ctx) + self.assertTrue('Mock' in ctx['search'].answers) + ctx = {'search': Mock(answers=set(), + query='What is my User-Agent?')} + store.call('post_search', request, ctx) diff --git a/searx/tests/test_search.py b/searx/tests/test_search.py new file mode 100644 index 000000000..89d0b620d --- /dev/null +++ b/searx/tests/test_search.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +from searx.search import score_results +from searx.testing import SearxTestCase + + +def fake_result(url='https://aa.bb/cc?dd=ee#ff', + title='aaa', + content='bbb', + engine='wikipedia'): + return {'url': url, + 'title': title, + 'content': content, + 'engine': engine} + + +class ScoreResultsTestCase(SearxTestCase): + + def test_empty(self): + self.assertEqual(score_results(dict()), []) + + def test_urlparse(self): + results = score_results(dict(a=[fake_result(url='https://aa.bb/cc?dd=ee#ff')])) + parsed_url = results[0]['parsed_url'] + self.assertEqual(parsed_url.query, 'dd=ee') |