"""Utility functions to support mocking in projects that use owsrequest.""" import json as json_tools import re class MockOwsResponse: """Fake response class that imitates response objects from requests.""" def __init__(self, status_code, json): """Construct a mock response.""" self.status_code = status_code self._json = json self.text = json_tools.dumps(json) def json(self): """Return a json payload.""" return self._json def mock_ows_requests(call_specs): r"""Mock HTTP calls that are made via owsrequest. Example: fake_json = {'foo': 'bar', 'baz': 123} call_specs = [ { 'service': 'ows-awesome', 'path': '/awesome-thing/123', 'status': 200, 'json': fake_json}, { 'service': 'ows-other', 'path_regex': r'/another/[0-9]+\Z', 'status': 200, 'json': fake_json }] monkeypatch.setattr( request, 'get', mock_ows_requests(call_specs)) Args: call_specs (list): list of dicts defining ows calls to mock. Returns: func: function that replaces a method-specific request function. """ def _path_matches(service_name, path, call_spec): spec_service = call_spec.get('service') if service_name != spec_service: return False if 'path' in call_spec: spec_path = call_spec.get('path') return path == spec_path if 'path_regex' in call_spec: spec_path_regex = call_spec.get('path_regex') pattern = re.compile(spec_path_regex) return pattern.match(path) def _mock_method(service_name, path, **options): for call_spec in call_specs: if _path_matches(service_name, path, call_spec): return MockOwsResponse( status_code=call_spec.get('status'), json=call_spec.get('json')) print(f'No test ows spec for service {service_name} and path {path}') raise Exception( 'No test ows spec for service {} and path {}'.format( service_name, path)) return _mock_method