From 614ad9721e62cd3c559cd79f95c58fbd96c8fd02 Mon Sep 17 00:00:00 2001 From: Beatriz Rizental Date: Wed, 2 Aug 2017 15:10:50 -0300 Subject: [PATCH] Fixes #1618 - Get all unittests to be network independent. --- tests/test_api_urls.py | 100 +++++++++++++++++++++++++++-------------- tests/test_urls.py | 5 +-- 2 files changed, 69 insertions(+), 36 deletions(-) diff --git a/tests/test_api_urls.py b/tests/test_api_urls.py index 062031af2..09aacf938 100644 --- a/tests/test_api_urls.py +++ b/tests/test_api_urls.py @@ -7,14 +7,14 @@ '''Tests for our API URL endpoints.''' import json -import os.path -import sys import unittest -# Add webcompat module to import path -sys.path.append(os.path.realpath(os.pardir)) -import webcompat +from mock import patch +from mock import MagicMock +from requests import Response +from requests.structures import CaseInsensitiveDict +import webcompat # Any request that depends on parsing HTTP Headers (basically anything # on the index route, will need to include the following: environ_base=headers @@ -23,10 +23,29 @@ 'HTTP_ACCEPT': 'application/json'} +def mock_api_response(response_config={}): + ''' Helper method to create a mock response from the Github API.''' + headers = { + 'ETag': 'W/"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"', + 'Cache-Control': 'public, max-age=60, s-maxage=60', + 'Content-Type': 'application/json; charset=utf-8' + } + api_response = MagicMock(spec=Response) + api_response.content_type = 'application/json' + for k, v in response_config.iteritems(): + if k == 'headers': + headers.update(v) + setattr(api_response, k, v) + # Request headers are case insensitive dicts, + # so we need to turn our mock headers into one. + api_response.headers = CaseInsensitiveDict(headers) + return api_response + + class TestAPIURLs(unittest.TestCase): def setUp(self): # Switch to False here because we don't want to send the mocked - # Fixture data. Which is OK because these don't touch GitHub API data. + # Fixture data. webcompat.app.config['TESTING'] = False self.app = webcompat.app.test_client() @@ -41,12 +60,16 @@ def test_api_issues_search(self): def test_api_issues_out_of_range(self): '''API issue for a non existent number returns JSON 404.''' - # If we reach 1,000,000 webcompat issues we can celebrate - rv = self.app.get('/api/issues/1000000', environ_base=headers) - json_body = json.loads(rv.data) - self.assertEqual(rv.status_code, 404) - self.assertEqual(rv.content_type, 'application/json') - self.assertEqual(json_body['status'], 404) + with patch('webcompat.helpers.proxy_request') as github_data: + github_data.return_value = mock_api_response({ + 'status_code': 404, + 'content': '[{"message":"Not Found","documentation_url":"https://developer.github.com/v3"}]' # nopep8 + }) + rv = self.app.get('/api/issues/1', environ_base=headers) + json_body = json.loads(rv.data) + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv.content_type, 'application/json') + self.assertEqual(json_body['status'], 404) def test_api_wrong_route(self): '''API with wrong route returns JSON 404.''' @@ -66,31 +89,42 @@ def test_api_wrong_category(self): def test_api_labels_without_auth(self): '''API access to labels without auth returns JSON 200.''' - rv = self.app.get('/api/issues/labels', environ_base=headers) - json_body = json.loads(rv.data) - self.assertEqual(rv.status_code, 200) - self.assertEqual(rv.content_type, 'application/json') + with patch('webcompat.helpers.proxy_request') as github_data: + github_data.return_value = mock_api_response( + {'status_code': 200, 'content': '[]'}) + rv = self.app.get('/api/issues/labels', environ_base=headers) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv.content_type, 'application/json') def test_api_comments_link_header_auth(self): '''API access to comments greater than 30 returns pagination in Link header of the response.''' - query_string = {'callback': 'foo'} - # Force a JSONP callback response with `query_string` because it gives - # us the header properties we want to test. - rv = self.app.get('/api/issues/398/comments', - query_string=query_string, environ_base=headers) - self.assertTrue = all(x in rv.data for x in ['Link', 'rel', 'next', - 'last', 'page']) - self.assertEqual(rv.status_code, 200) - self.assertEqual(rv.content_type, 'application/json') - # API access to comments for an issue with < 30 does not return link a - # header in the response (until GitHub changes it....?) - rv = self.app.get('/api/issues/4/comments', query_string=query_string, - environ_base=headers) - self.assertTrue = not all(x in rv.data for x in ['Link', 'rel', 'next', - 'last', 'page']) - self.assertEqual(rv.status_code, 200) - self.assertEqual(rv.content_type, 'application/json') + with patch('webcompat.helpers.proxy_request') as github_data: + # Create mock data. One api_response for each call. + github_data.side_effect = [ + mock_api_response({ + 'status_code': 200, + 'content': '[]', + 'headers': { + 'Link': '; rel="next", ; rel="last"', # nopep8 + }, + }), + mock_api_response({'status_code': 200, 'content': '[]'}) + ] + rv = self.app.get('/api/issues/398/comments', environ_base=headers) + self.assertTrue( + 'link' in rv.headers and all( + x in rv.headers.get('link') for x in [ + 'page', 'next', 'last'])) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv.content_type, 'application/json') + # API access to comments for an issue + # with < 30 does not return link a header in + # the response (until GitHub changes it....?) + rv = self.app.get('/api/issues/4/comments', environ_base=headers) + self.assertTrue('link' not in rv.headers) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv.content_type, 'application/json') def test_api_set_labels_without_auth(self): '''API setting labels without auth returns JSON 403 error code.''' diff --git a/tests/test_urls.py b/tests/test_urls.py index 3d787e8c8..3c11b7edd 100644 --- a/tests/test_urls.py +++ b/tests/test_urls.py @@ -118,16 +118,15 @@ def test_missing_parameters_for_new_issue(self): self.assertEqual(rv.status_code, 400) def test_new_issue_should_not_crash(self): - '''Checks 500 is not accepted for /issues/new POST.''' + '''/issues/new POST exit with 400 if missing parameters.''' data = {'problem_category': u'mobile_site_bug', - 'username': u'', 'description': u'foo', 'submit-type': u'github-proxy-report', 'url': u'http://example.com', 'os': u'Foobar', 'browser': u'BarFoo'} rv = self.app.post('/issues/new', data=data) - self.assertNotEqual(rv.status_code, 500) + self.assertEqual(rv.status_code, 400) if __name__ == '__main__':