# Copyright 2014 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Copy of googleapiclient.http's mock functionality.""" import json import httplib2 # TODO(craigcitro): Find a cleaner way to share this code with googleapiclient. class HttpMock(object): """Mock of httplib2.Http""" def __init__(self, filename=None, headers=None): """HttpMock constructor. Args: filename: string, absolute filename to read response from headers: dict, header to return with response """ if headers is None: headers = {'status': '200 OK'} if filename: f = file(filename, 'r') self.data = f.read() f.close() else: self.data = None self.response_headers = headers self.headers = None self.uri = None self.method = None self.body = None self.headers = None def request(self, uri, method='GET', body=None, headers=None, redirections=1, connection_type=None): self.uri = uri self.method = method self.body = body self.headers = headers return httplib2.Response(self.response_headers), self.data class HttpMockSequence(object): """Mock of httplib2.Http Mocks a sequence of calls to request returning different responses for each call. Create an instance initialized with the desired response headers and content and then use as if an httplib2.Http instance:: http = HttpMockSequence([ ({'status': '401'}, b''), ({'status': '200'}, b'{"access_token":"1/3w","expires_in":3600}'), ({'status': '200'}, 'echo_request_headers'), ]) resp, content = http.request("http://examples.com") There are special values you can pass in for content to trigger behavours that are helpful in testing. * 'echo_request_headers' means return the request headers in the response body * 'echo_request_headers_as_json' means return the request headers in the response body * 'echo_request_body' means return the request body in the response body * 'echo_request_uri' means return the request uri in the response body """ def __init__(self, iterable): """HttpMockSequence constructor. Args: iterable: iterable, a sequence of pairs of (headers, body) """ self._iterable = iterable self.follow_redirects = True self.requests = [] def request(self, uri, method='GET', body=None, headers=None, redirections=1, connection_type=None): resp, content = self._iterable.pop(0) self.requests.append({'uri': uri, 'body': body, 'headers': headers}) # Read any underlying stream before sending the request. body_stream_content = (body.read() if getattr(body, 'read', None) else None) if content == 'echo_request_headers': content = headers elif content == 'echo_request_headers_as_json': content = json.dumps(headers) elif content == 'echo_request_body': content = (body if body_stream_content is None else body_stream_content) elif content == 'echo_request_uri': content = uri elif not isinstance(content, bytes): raise TypeError('http content should be bytes: %r' % (content,)) return httplib2.Response(resp), content