diff --git a/.gitignore b/.gitignore index 0b9057a41..0f347d81a 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,7 @@ setup.cfg bin/ build/ -covearge/ +coverage/ develop-eggs/ dist/ eggs/ diff --git a/searx/tests/test_unit.py b/searx/tests/test_unit.py deleted file mode 100644 index 8d57d0a46..000000000 --- a/searx/tests/test_unit.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- - -from searx.testing import SearxTestCase - - -class UnitTestCase(SearxTestCase): - - def test_flask(self): - import flask - self.assertIn('Flask', dir(flask)) diff --git a/searx/tests/test_webapp.py b/searx/tests/test_webapp.py new file mode 100644 index 000000000..e69129d3a --- /dev/null +++ b/searx/tests/test_webapp.py @@ -0,0 +1,167 @@ +# -*- coding: utf-8 -*- + +from mock import patch +from searx import webapp +from searx.testing import SearxTestCase +from urlparse import ParseResult + + +import json + + +class ViewsTestCase(SearxTestCase): + + def setUp(self): + webapp.app.config['TESTING'] = True # to get better error messages + self.app = webapp.app.test_client() + + # set some defaults + self.test_results = [ + { + 'content': 'first test content', + 'title': 'First Test', + 'url': 'http://first.test.xyz', + 'engines': ['youtube', 'startpage'], + 'engine': 'startpage', + 'parsed_url': ParseResult(scheme='http', netloc='first.test.xyz', path='/', params='', query='', fragment=''), # noqa + }, { + 'content': 'second test content', + 'title': 'Second Test', + 'url': 'http://second.test.xyz', + 'engines': ['youtube', 'startpage'], + 'engine': 'youtube', + 'parsed_url': ParseResult(scheme='http', netloc='second.test.xyz', path='/', params='', query='', fragment=''), # noqa + }, + ] + + self.maxDiff = None # to see full diffs + + def test_index_empty(self): + result = self.app.post('/') + self.assertEqual(result.status_code, 200) + self.assertIn('

searx

', result.data) + + @patch('searx.webapp.search') + def test_index_html(self, search): + search.return_value = ( + self.test_results, + set() + ) + result = self.app.post('/', data={'q': 'test'}) + self.assertIn( + '

First Test

', # noqa + result.data + ) + self.assertIn( + '

first test content

', + result.data + ) + + @patch('searx.webapp.search') + def test_index_json(self, search): + search.return_value = ( + self.test_results, + set() + ) + result = self.app.post('/', data={'q': 'test', 'format': 'json'}) + + result_dict = json.loads(result.data) + + self.assertEqual('test', result_dict['query']) + self.assertEqual( + result_dict['results'][0]['content'], 'first test content') + self.assertEqual( + result_dict['results'][0]['url'], 'http://first.test.xyz') + + @patch('searx.webapp.search') + def test_index_csv(self, search): + search.return_value = ( + self.test_results, + set() + ) + result = self.app.post('/', data={'q': 'test', 'format': 'csv'}) + + self.assertEqual( + 'title,url,content,host,engine,score\r\n' + 'First Test,http://first.test.xyz,first test content,first.test.xyz,startpage,\r\n' + 'Second Test,http://second.test.xyz,second test content,second.test.xyz,youtube,\r\n', + result.data + ) + + @patch('searx.webapp.search') + def test_index_rss(self, search): + search.return_value = ( + self.test_results, + set() + ) + result = self.app.post('/', data={'q': 'test', 'format': 'rss'}) + + self.assertIn( + 'Search results for "test" - searx', + result.data + ) + + self.assertIn( + '2', + result.data + ) + + self.assertIn( + 'First Test', + result.data + ) + + self.assertIn( + 'http://first.test.xyz', + result.data + ) + + self.assertIn( + 'first test content', + result.data + ) + + def test_about(self): + result = self.app.get('/about') + self.assertEqual(result.status_code, 200) + self.assertIn('

About searx

', result.data) + + def test_engines(self): + result = self.app.get('/engines') + self.assertEqual(result.status_code, 200) + self.assertIn('

Currently used search engines

', result.data) + + def test_preferences(self): + result = self.app.get('/preferences') + self.assertEqual(result.status_code, 200) + self.assertIn( + '
', + result.data + ) + self.assertIn( + 'Default categories', + result.data + ) + self.assertIn( + 'Interface language', + result.data + ) + + def test_stats(self): + result = self.app.get('/stats') + self.assertEqual(result.status_code, 200) + self.assertIn('

Engine stats

', result.data) + + def test_robots_txt(self): + result = self.app.get('/robots.txt') + self.assertEqual(result.status_code, 200) + self.assertIn('Allow: /', result.data) + + def test_opensearch_xml(self): + result = self.app.get('/opensearch.xml') + self.assertEqual(result.status_code, 200) + self.assertIn('Search searx', result.data) + + def test_favicon(self): + result = self.app.get('/favicon.ico') + self.assertEqual(result.status_code, 200) diff --git a/searx/webapp.py b/searx/webapp.py index f8ef27322..dc34567cb 100644 --- a/searx/webapp.py +++ b/searx/webapp.py @@ -117,6 +117,10 @@ def parse_query(query): @app.route('/', methods=['GET', 'POST']) def index(): + """Render index page. + + Supported outputs: html, json, csv, rss. + """ paging = False lang = 'all' @@ -231,17 +235,25 @@ def index(): @app.route('/about', methods=['GET']) def about(): + """Render about page""" return render('about.html') @app.route('/engines', methods=['GET']) def list_engines(): + """Render engines page. + + List of all supported engines. + """ global categories return render('engines.html', categs=categories.items()) @app.route('/preferences', methods=['GET', 'POST']) def preferences(): + """Render preferences page. + + Settings that are going to be saved as cookies.""" lang = None if request.cookies.get('language')\ @@ -296,6 +308,7 @@ def preferences(): @app.route('/stats', methods=['GET']) def stats(): + """Render engine statistics page.""" global categories stats = get_engines_stats() return render('stats.html', stats=stats) diff --git a/setup.py b/setup.py index ab7e16f0a..ddee4ed4e 100644 --- a/setup.py +++ b/setup.py @@ -40,6 +40,7 @@ setup( 'test': [ 'coverage', 'flake8', + 'mock', 'plone.testing', 'robotframework', 'robotframework-debuglibrary',