Merge branch 'master' into epel8

This commit is contained in:
Steve Traylen 2019-11-15 10:26:38 +01:00
commit c4796a6927
5 changed files with 460 additions and 3 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
/httmock-1.2.6.tar.gz
/httmock-1.3.0.tar.gz
/tests.py

View file

@ -1,3 +0,0 @@
# python-httmock
mocking library for requests

85
python-httmock.spec Normal file
View file

@ -0,0 +1,85 @@
%{?python_enable_dependency_generator}
# Created by pyp2rpm-3.3.0
%global pypi_name httmock
Name: python-%{pypi_name}
Version: 1.3.0
Release: 1%{?dist}
Summary: A mocking library for requests
License: ASL 2.0
URL: https://github.com/patrys/httmock
Source0: https://files.pythonhosted.org/packages/source/h/httmock/httmock-%{version}.tar.gz
Source1: https://raw.githubusercontent.com/patrys/httmock/%{version}/tests.py
BuildArch: noarch
%description
A mocking library for requests for Python.
You can use it to mock third-party APIs and test libraries
that use requests internally.
%package -n python3-%{pypi_name}
Summary: %{summary}
%{?python_provide:%python_provide python3-%{pypi_name}}
BuildRequires: python3-devel
BuildRequires: python3-setuptools
BuildRequires: python3dist(requests) >= 1
%description -n python3-%{pypi_name}
A mocking library for requests for Python.
You can use it to mock third-party APIs and test libraries
that use requests internally.
%prep
%autosetup -n %{pypi_name}-%{version}
# Remove bundled egg-info
rm -rf %{pypi_name}.egg-info
cp %{SOURCE1} .
%build
%py3_build
%install
%py3_install
%check
%{__python3} setup.py test
%files -n python3-%{pypi_name}
%license LICENSE
%doc README.md
%{python3_sitelib}/__pycache__/*
%{python3_sitelib}/%{pypi_name}.py
%{python3_sitelib}/%{pypi_name}-%{version}-py?.?.egg-info
%changelog
* Wed Nov 13 2019 Steve Traylen <steve.traylen@cern.ch> - 1.3.0-1
- Update to 1.3.0
* Thu Oct 03 2019 Miro Hrončok <mhroncok@redhat.com> - 1.2.6-9
- Rebuilt for Python 3.8.0rc1 (#1748018)
* Mon Aug 19 2019 Miro Hrončok <mhroncok@redhat.com> - 1.2.6-8
- Rebuilt for Python 3.8
* Fri Jul 26 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.2.6-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Sat Feb 02 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.2.6-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Fri Jan 04 2019 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 1.2.6-5
- Enable python dependency generator
* Fri Jan 04 2019 Miro Hrončok <mhroncok@redhat.com> - 1.2.6-4
- Subpackage python2-httmock has been removed
See https://fedoraproject.org/wiki/Changes/Mass_Python_2_Package_Removal
* Sat Jul 14 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.2.6-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Tue Jun 19 2018 Miro Hrončok <mhroncok@redhat.com> - 1.2.6-2
- Rebuilt for Python 3.7
* Fri May 11 2018 Steve Traylen <steve.traylen@cern.ch> - 1.2.6-1
- Initial package.

2
sources Normal file
View file

@ -0,0 +1,2 @@
SHA512 (tests.py) = f869c9923bdd68c8758c1937eb61a7b8e2aae1ef32dce9ca850460dfdfd8daae7c20e1e5b9c298c1ce600900cbe2c34ba9660bd0ded0dbd34e817e39a18eee72
SHA512 (httmock-1.3.0.tar.gz) = f713ddf45675738582a3611e01a55babce2951231b34fb9ca6b1b64fcf60a3862994ff7ad4cd7a224a116c6acb1caa267978a7cb6fedd02676fa2a01f90e93aa

370
tests.py Normal file
View file

@ -0,0 +1,370 @@
# -*- coding: utf-8 -*-
import requests
import unittest
from httmock import (all_requests, response, urlmatch, with_httmock, HTTMock,
remember_called, text_type, binary_type)
@urlmatch(scheme='swallow')
def unmatched_scheme(url, request):
raise AssertionError('This is outrageous')
@urlmatch(path=r'^never$')
def unmatched_path(url, request):
raise AssertionError('This is outrageous')
@urlmatch(method='post')
def unmatched_method(url, request):
raise AssertionError('This is outrageous')
@urlmatch(netloc=r'(.*\.)?google\.com$', path=r'^/$')
def google_mock(url, request):
return 'Hello from Google'
@urlmatch(netloc=r'(.*\.)?google\.com$', path=r'^/$')
@remember_called
def google_mock_count(url, request):
return 'Hello from Google'
@urlmatch(scheme='http', netloc=r'(.*\.)?facebook\.com$')
def facebook_mock(url, request):
return 'Hello from Facebook'
@urlmatch(scheme='http', netloc=r'(.*\.)?facebook\.com$')
@remember_called
def facebook_mock_count(url, request):
return 'Hello from Facebook'
@urlmatch(netloc=r'(.*\.)?google\.com$', path=r'^/$', method='POST')
@remember_called
def google_mock_store_requests(url, request):
return 'Posting at Google'
@all_requests
def charset_utf8(url, request):
return {
'content': u'Motörhead'.encode('utf-8'),
'status_code': 200,
'headers': {
'Content-Type': 'text/plain; charset=utf-8'
}
}
def any_mock(url, request):
return 'Hello from %s' % (url.netloc,)
def dict_any_mock(url, request):
return {
'content': 'Hello from %s' % (url.netloc,),
'status_code': 200
}
def example_400_response(url, response):
r = requests.Response()
r.status_code = 400
r._content = b'Bad request.'
return r
class MockTest(unittest.TestCase):
def test_return_type(self):
with HTTMock(any_mock):
r = requests.get('http://domain.com/')
self.assertTrue(isinstance(r, requests.Response))
self.assertTrue(isinstance(r.content, binary_type))
self.assertTrue(isinstance(r.text, text_type))
def test_scheme_fallback(self):
with HTTMock(unmatched_scheme, any_mock):
r = requests.get('http://example.com/')
self.assertEqual(r.content, b'Hello from example.com')
def test_path_fallback(self):
with HTTMock(unmatched_path, any_mock):
r = requests.get('http://example.com/')
self.assertEqual(r.content, b'Hello from example.com')
def test_method_fallback(self):
with HTTMock(unmatched_method, any_mock):
r = requests.get('http://example.com/')
self.assertEqual(r.content, b'Hello from example.com')
def test_netloc_fallback(self):
with HTTMock(google_mock, facebook_mock):
r = requests.get('http://google.com/')
self.assertEqual(r.content, b'Hello from Google')
with HTTMock(google_mock, facebook_mock):
r = requests.get('http://facebook.com/')
self.assertEqual(r.content, b'Hello from Facebook')
def test_400_response(self):
with HTTMock(example_400_response):
r = requests.get('http://example.com/')
self.assertEqual(r.status_code, 400)
self.assertEqual(r.content, b'Bad request.')
def test_real_request_fallback(self):
with HTTMock(any_mock):
with HTTMock(google_mock, facebook_mock):
r = requests.get('http://example.com/')
self.assertEqual(r.status_code, 200)
self.assertEqual(r.content, b'Hello from example.com')
def test_invalid_intercept_response_raises_value_error(self):
@all_requests
def response_content(url, request):
return -1
with HTTMock(response_content):
self.assertRaises(TypeError, requests.get, 'http://example.com/')
def test_encoding_from_contenttype(self):
with HTTMock(charset_utf8):
r = requests.get('http://example.com/')
self.assertEqual(r.encoding, 'utf-8')
self.assertEqual(r.text, u'Motörhead')
self.assertEqual(r.content, r.text.encode('utf-8'))
class DecoratorTest(unittest.TestCase):
@with_httmock(any_mock)
def test_decorator(self):
r = requests.get('http://example.com/')
self.assertEqual(r.content, b'Hello from example.com')
@with_httmock(any_mock)
def test_iter_lines(self):
r = requests.get('http://example.com/')
self.assertEqual(list(r.iter_lines()),
[b'Hello from example.com'])
class AllRequestsDecoratorTest(unittest.TestCase):
def test_all_requests_response(self):
@all_requests
def response_content(url, request):
return {'status_code': 200, 'content': 'Oh hai'}
with HTTMock(response_content):
r = requests.get('https://example.com/')
self.assertEqual(r.status_code, 200)
self.assertEqual(r.content, b'Oh hai')
def test_all_str_response(self):
@all_requests
def response_content(url, request):
return 'Hello'
with HTTMock(response_content):
r = requests.get('https://example.com/')
self.assertEqual(r.content, b'Hello')
class AllRequestsMethodDecoratorTest(unittest.TestCase):
@all_requests
def response_content(self, url, request):
return {'status_code': 200, 'content': 'Oh hai'}
def test_all_requests_response(self):
with HTTMock(self.response_content):
r = requests.get('https://example.com/')
self.assertEqual(r.status_code, 200)
self.assertEqual(r.content, b'Oh hai')
@all_requests
def string_response_content(self, url, request):
return 'Hello'
def test_all_str_response(self):
with HTTMock(self.string_response_content):
r = requests.get('https://example.com/')
self.assertEqual(r.content, b'Hello')
class UrlMatchMethodDecoratorTest(unittest.TestCase):
@urlmatch(netloc=r'(.*\.)?google\.com$', path=r'^/$')
def google_mock(self, url, request):
return 'Hello from Google'
@urlmatch(scheme='http', netloc=r'(.*\.)?facebook\.com$')
def facebook_mock(self, url, request):
return 'Hello from Facebook'
@urlmatch(query=r'.*page=test')
def query_page_mock(self, url, request):
return 'Hello from test page'
def test_netloc_fallback(self):
with HTTMock(self.google_mock, facebook_mock):
r = requests.get('http://google.com/')
self.assertEqual(r.content, b'Hello from Google')
with HTTMock(self.google_mock, facebook_mock):
r = requests.get('http://facebook.com/')
self.assertEqual(r.content, b'Hello from Facebook')
def test_query(self):
with HTTMock(self.query_page_mock, self.google_mock):
r = requests.get('http://google.com/?page=test')
r2 = requests.get('http://google.com/')
self.assertEqual(r.content, b'Hello from test page')
self.assertEqual(r2.content, b'Hello from Google')
class ResponseTest(unittest.TestCase):
content = {'name': 'foo', 'ipv4addr': '127.0.0.1'}
content_list = list(content.keys())
def test_response_auto_json(self):
r = response(0, self.content)
self.assertTrue(isinstance(r.content, binary_type))
self.assertTrue(isinstance(r.text, text_type))
self.assertEqual(r.json(), self.content)
r = response(0, self.content_list)
self.assertEqual(r.json(), self.content_list)
def test_response_status_code(self):
r = response(200)
self.assertEqual(r.status_code, 200)
def test_response_headers(self):
r = response(200, None, {'Content-Type': 'application/json'})
self.assertEqual(r.headers['content-type'], 'application/json')
def test_response_cookies(self):
@all_requests
def response_content(url, request):
return response(200, 'Foo', {'Set-Cookie': 'foo=bar;'},
request=request)
with HTTMock(response_content):
r = requests.get('https://example.com/')
self.assertEqual(len(r.cookies), 1)
self.assertTrue('foo' in r.cookies)
self.assertEqual(r.cookies['foo'], 'bar')
def test_response_session_cookies(self):
@all_requests
def response_content(url, request):
return response(200, 'Foo', {'Set-Cookie': 'foo=bar;'},
request=request)
session = requests.Session()
with HTTMock(response_content):
r = session.get('https://foo_bar')
self.assertEqual(len(r.cookies), 1)
self.assertTrue('foo' in r.cookies)
self.assertEqual(r.cookies['foo'], 'bar')
self.assertEqual(len(session.cookies), 1)
self.assertTrue('foo' in session.cookies)
self.assertEqual(session.cookies['foo'], 'bar')
def test_python_version_encoding_differences(self):
# Previous behavior would result in this test failing in Python3 due
# to how requests checks for utf-8 JSON content in requests.utils with:
#
# TypeError: Can't convert 'bytes' object to str implicitly
@all_requests
def get_mock(url, request):
return {'content': self.content,
'headers': {'content-type': 'application/json'},
'status_code': 200,
'elapsed': 5}
with HTTMock(get_mock):
response = requests.get('http://example.com/')
self.assertEqual(self.content, response.json())
def test_mock_redirect(self):
@urlmatch(netloc='example.com')
def get_mock(url, request):
return {'status_code': 302,
'headers': {'Location': 'http://google.com/'}}
with HTTMock(get_mock, google_mock):
response = requests.get('http://example.com/')
self.assertEqual(len(response.history), 1)
self.assertEqual(response.content, b'Hello from Google')
class StreamTest(unittest.TestCase):
@with_httmock(any_mock)
def test_stream_request(self):
r = requests.get('http://domain.com/', stream=True)
self.assertEqual(r.raw.read(), b'Hello from domain.com')
@with_httmock(dict_any_mock)
def test_stream_request_with_dict_mock(self):
r = requests.get('http://domain.com/', stream=True)
self.assertEqual(r.raw.read(), b'Hello from domain.com')
@with_httmock(any_mock)
def test_non_stream_request(self):
r = requests.get('http://domain.com/')
self.assertEqual(r.raw.read(), b'')
class RememberCalledTest(unittest.TestCase):
@staticmethod
def several_calls(count, method, *args, **kwargs):
results = []
for _ in range(count):
results.append(method(*args, **kwargs))
return results
def test_several_calls(self):
with HTTMock(google_mock_count, facebook_mock_count):
results = self.several_calls(
3, requests.get, 'http://facebook.com/')
self.assertTrue(facebook_mock_count.call['called'])
self.assertEqual(facebook_mock_count.call['count'], 3)
self.assertFalse(google_mock_count.call['called'])
self.assertEqual(google_mock_count.call['count'], 0)
for r in results:
self.assertEqual(r.content, b'Hello from Facebook')
# Negative case: cleanup call data
with HTTMock(facebook_mock_count):
results = self.several_calls(
1, requests.get, 'http://facebook.com/')
self.assertEquals(facebook_mock_count.call['count'], 1)
@with_httmock(google_mock_count, facebook_mock_count)
def test_several_call_decorated(self):
results = self.several_calls(3, requests.get, 'http://facebook.com/')
self.assertTrue(facebook_mock_count.call['called'])
self.assertEqual(facebook_mock_count.call['count'], 3)
self.assertFalse(google_mock_count.call['called'])
self.assertEqual(google_mock_count.call['count'], 0)
for r in results:
self.assertEqual(r.content, b'Hello from Facebook')
self.several_calls(1, requests.get, 'http://facebook.com/')
self.assertEquals(facebook_mock_count.call['count'], 4)
def test_store_several_requests(self):
with HTTMock(google_mock_store_requests):
payload = {"query": "foo"}
requests.post('http://google.com', data=payload)
self.assertTrue(google_mock_store_requests.call['called'])
self.assertEqual(google_mock_store_requests.call['count'], 1)
request = google_mock_store_requests.call['requests'][0]
self.assertEqual(request.body, 'query=foo')