import unittest import responses import requests from urllib.parse import urlencode from unittest.mock import * from jike import utils, constants class TestJikeUtils(unittest.TestCase): def setUp(self): self.session = requests.Session() def tearDown(self): self.session.close() def test_read_token(self): mocked_metro_json = '{"auth_token": "token"}' with patch('os.path.exists', return_value=True), \ patch('builtins.open', mock_open(read_data=mocked_metro_json)): mock_token = utils.read_token() self.assertEqual(mock_token, 'token') def test_write_token(self): m = mock_open() with patch('builtins.open', m): utils.write_token('token') m.assert_called_once_with(constants.AUTH_TOKEN_STORE_PATH, 'wt', encoding='utf-8') handle = m() handle.write.assert_called() @responses.activate def test_extract_link(self): success_response = {'success': True, 'data': 'link'} responses.add(responses.POST, constants.ENDPOINTS['extract_link'], json=success_response, status=200) responses.add(responses.POST, constants.ENDPOINTS['extract_link'], status=401) # success call result = utils.extract_link(self.session, 'https://www.ojbk.com') self.assertEqual(result, 'link') self.assertEqual(len(responses.calls), 1) self.assertEqual(responses.calls[0].request.url, constants.ENDPOINTS['extract_link']) self.assertEqual(responses.calls[0].response.json(), success_response) # failed call with self.assertRaises(requests.HTTPError) as cm: utils.extract_link(self.session, 'https://www.ojbk.com') self.assertEqual(len(responses.calls), 2) self.assertEqual(cm.exception.response.status_code, 401) def test_extract_url(self): content = 'no url inside' self.assertEqual(utils.extract_url(content), []) content = 'one url inside: https://www.jike.ojbk.com/metro end this url' self.assertEqual(utils.extract_url(content), ['https://www.jike.ojbk.com/metro']) content = 'more urls ' + content + ' http://www.test.xyz/a/132-z/ end ' self.assertEqual(utils.extract_url(content), ['https://www.jike.ojbk.com/metro', 'http://www.test.xyz/a/132-z/']) @responses.activate def test_wait_login(self): success_response = {'logged_in': True} responses.add(responses.GET, constants.ENDPOINTS['wait_login'], json=success_response, status=200) failed_response = {'logged_in': False} responses.add(responses.GET, constants.ENDPOINTS['wait_login'], json=failed_response, status=200) responses.add(responses.GET, constants.ENDPOINTS['wait_login'], status=500) uuid = {'uuid': '123'} # success call result = utils.wait_login(uuid) self.assertTrue(result) self.assertEqual(len(responses.calls), 1) self.assertEqual(responses.calls[0].request.url, constants.ENDPOINTS['wait_login'] + '?' + urlencode(uuid)) self.assertEqual(responses.calls[0].response.json(), success_response) # failed call result = utils.wait_login(uuid) self.assertFalse(result) self.assertEqual(len(responses.calls), 2) self.assertEqual(responses.calls[1].request.url, constants.ENDPOINTS['wait_login'] + '?' + urlencode(uuid)) self.assertEqual(responses.calls[1].response.json(), failed_response) # failed again call with self.assertRaises(requests.HTTPError) as cm: utils.wait_login(uuid) self.assertEqual(len(responses.calls), 3) self.assertEqual(cm.exception.response.status_code, 500) @responses.activate def test_confirm_login(self): success_response = {'confirmed': True, 'token': 'token'} responses.add(responses.GET, constants.ENDPOINTS['confirm_login'], json=success_response, status=200) failed_response = {'confirmed': False, 'token': 'token'} responses.add(responses.GET, constants.ENDPOINTS['confirm_login'], json=failed_response, status=200) responses.add(responses.GET, constants.ENDPOINTS['confirm_login'], status=502) uuid = {'uuid': '123'} # success call result = utils.confirm_login(uuid) self.assertEqual(result, 'token') self.assertEqual(len(responses.calls), 1) self.assertEqual(responses.calls[0].request.url, constants.ENDPOINTS['confirm_login'] + '?' + urlencode(uuid)) self.assertEqual(responses.calls[0].response.json(), success_response) # failed call with self.assertRaises(SystemExit): utils.confirm_login(uuid) self.assertEqual(len(responses.calls), 2) self.assertEqual(responses.calls[1].request.url, constants.ENDPOINTS['confirm_login'] + '?' + urlencode(uuid)) self.assertEqual(responses.calls[1].response.json(), failed_response) # failed again call with self.assertRaises(requests.HTTPError) as cm: utils.confirm_login(uuid) self.assertEqual(len(responses.calls), 3) self.assertEqual(cm.exception.response.status_code, 502) @responses.activate def test_login(self): uuid = {'uuid': '123'} responses.add(responses.GET, constants.ENDPOINTS['create_session'], json=uuid, status=200) responses.add(responses.GET, constants.ENDPOINTS['create_session'], status=400) responses.add(responses.GET, constants.ENDPOINTS['create_session'], json=uuid, status=200) responses.add(responses.GET, constants.ENDPOINTS['create_session'], json=uuid, status=200) # success call with patch('jike.utils.wait_login', return_value=True), \ patch('jike.utils.confirm_login', return_value='token'), \ patch('jike.utils.make_qrcode'): result = utils.login() self.assertEqual(result, 'token') self.assertEqual(len(responses.calls), 1) self.assertEqual(responses.calls[0].request.url, constants.ENDPOINTS['create_session']) self.assertEqual(responses.calls[0].response.json(), uuid) # failed call with patch('jike.utils.wait_login', return_value=True), \ patch('jike.utils.confirm_login', return_value='token'), \ patch('jike.utils.make_qrcode'), \ self.assertRaises(requests.HTTPError) as cm: utils.login() self.assertEqual(len(responses.calls), 2) self.assertEqual(cm.exception.response.status_code, 400) # failed call by `wait_login` with patch('jike.utils.wait_login', return_value=False), \ patch('jike.utils.confirm_login', return_value='token'), \ patch('jike.utils.make_qrcode'), \ self.assertRaises(SystemExit): utils.login() self.assertEqual(len(responses.calls), 3) # failed call by `confirm_login` with patch('jike.utils.wait_login', return_value=True), \ patch('jike.utils.confirm_login', return_value=None), \ patch('jike.utils.make_qrcode'), \ self.assertRaises(SystemExit): utils.login() self.assertEqual(len(responses.calls), 4) @responses.activate def test_get_uptoken(self): params = {'bucket': 'jike'} success_reponse = {'uptoken': 'token'} responses.add(responses.GET, constants.ENDPOINTS['picture_uptoken'], json=success_reponse, status=200) responses.add(responses.GET, constants.ENDPOINTS['picture_uptoken'], status=404) # success call result = utils.get_uptoken() self.assertEqual(result, 'token') self.assertEqual(len(responses.calls), 1) self.assertEqual(responses.calls[0].request.url, constants.ENDPOINTS['picture_uptoken'] + '?' + urlencode(params)) self.assertEqual(responses.calls[0].response.json(), success_reponse) # failed call with self.assertRaises(requests.HTTPError) as cm: utils.get_uptoken() self.assertEqual(len(responses.calls), 2) self.assertEqual(cm.exception.response.status_code, 404) @responses.activate def test_upload_a_picture(self): # picture not exists with patch('os.path.exists', return_value=False), \ self.assertRaises(AssertionError): utils.upload_a_picture('jike.png') # cannot figure out mimetype with patch('os.path.exists', return_value=True), \ patch('os.path.split', return_value=('a', 'b')), \ patch('mimetypes.guess_type', return_value=(None, None)), \ self.assertRaises(AssertionError): utils.upload_a_picture('jike.png') # not upload picture with patch('os.path.exists', return_value=True), \ self.assertRaises(ValueError): utils.upload_a_picture('a.txt') success_reponse = {'success': True, 'key': 'key'} responses.add(responses.POST, constants.ENDPOINTS['picture_upload'], json=success_reponse, status=200) failed_response = {'success': False} responses.add(responses.POST, constants.ENDPOINTS['picture_upload'], json=failed_response, status=200) responses.add(responses.POST, constants.ENDPOINTS['picture_upload'], status=401) # success call with patch('os.path.exists', return_value=True), \ patch('jike.utils.get_uptoken', return_value='token'), \ patch('builtins.open', mock_open(read_data='picture_content')): result = utils.upload_a_picture('jike.png') self.assertEqual(result, 'key') self.assertEqual(len(responses.calls), 1) self.assertEqual(responses.calls[0].request.url, constants.ENDPOINTS['picture_upload']) self.assertEqual(responses.calls[0].response.json(), success_reponse) self.assertTrue(responses.calls[0].request.headers['Content-Type'].startswith('multipart/form-data;')) self.assertTrue(b'jike.png' in responses.calls[0].request.body) # failed call with patch('os.path.exists', return_value=True), \ patch('jike.utils.get_uptoken', return_value='token'), \ patch('builtins.open', mock_open(read_data='picture_content')), \ self.assertRaises(RuntimeError): utils.upload_a_picture('jike.png') self.assertEqual(len(responses.calls), 2) self.assertEqual(responses.calls[1].response.json(), failed_response) # failed again call with patch('os.path.exists', return_value=True), \ patch('jike.utils.get_uptoken', return_value='token'), \ patch('builtins.open', mock_open(read_data='picture_content')), \ self.assertRaises(requests.HTTPError) as cm: utils.upload_a_picture('jike.png') self.assertEqual(len(responses.calls), 3) self.assertEqual(cm.exception.response.status_code, 401) def test_upload_pictures(self): with patch('jike.utils.upload_a_picture', return_value='a_url'): pic_urls = utils.upload_pictures('p.png') self.assertEqual(len(pic_urls), 1) with patch('jike.utils.upload_a_picture', return_value='a_url'): pic_urls = utils.upload_pictures(['p.png', 'q.png']) self.assertEqual(len(pic_urls), 2) if __name__ == '__main__': unittest.main()