#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# 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.


"""Discovery document tests

Unit tests for objects created from discovery documents.
"""
from __future__ import absolute_import
import six

__author__ = 'jcgregorio@google.com (Joe Gregorio)'

from six import BytesIO, StringIO
from six.moves.urllib.parse import urlparse, parse_qs

import copy
import datetime
import httplib2
import itertools
import json
import os
import pickle
import re
import sys
import unittest2 as unittest

import mock

import google.auth.credentials
import google_auth_httplib2
from googleapiclient.discovery import _fix_up_media_upload
from googleapiclient.discovery import _fix_up_method_description
from googleapiclient.discovery import _fix_up_parameters
from googleapiclient.discovery import _urljoin
from googleapiclient.discovery import build
from googleapiclient.discovery import build_from_document
from googleapiclient.discovery import DISCOVERY_URI
from googleapiclient.discovery import key2param
from googleapiclient.discovery import MEDIA_BODY_PARAMETER_DEFAULT_VALUE
from googleapiclient.discovery import MEDIA_MIME_TYPE_PARAMETER_DEFAULT_VALUE
from googleapiclient.discovery import ResourceMethodParameters
from googleapiclient.discovery import STACK_QUERY_PARAMETERS
from googleapiclient.discovery import STACK_QUERY_PARAMETER_DEFAULT_VALUE
from googleapiclient.discovery_cache import DISCOVERY_DOC_MAX_AGE
from googleapiclient.discovery_cache.base import Cache
from googleapiclient.errors import HttpError
from googleapiclient.errors import InvalidJsonError
from googleapiclient.errors import MediaUploadSizeError
from googleapiclient.errors import ResumableUploadError
from googleapiclient.errors import UnacceptableMimeTypeError
from googleapiclient.errors import UnknownApiNameOrVersion
from googleapiclient.errors import UnknownFileType
from googleapiclient.http import build_http
from googleapiclient.http import BatchHttpRequest
from googleapiclient.http import HttpMock
from googleapiclient.http import HttpMockSequence
from googleapiclient.http import MediaFileUpload
from googleapiclient.http import MediaIoBaseUpload
from googleapiclient.http import MediaUpload
from googleapiclient.http import MediaUploadProgress
from googleapiclient.http import tunnel_patch
from googleapiclient.model import JsonModel
from googleapiclient.schema import Schemas
from oauth2client import GOOGLE_TOKEN_URI
from oauth2client.client import OAuth2Credentials, GoogleCredentials

from googleapiclient import _helpers as util

import uritemplate


DATA_DIR = os.path.join(os.path.dirname(__file__), 'data')


def assertUrisEqual(testcase, expected, actual):
  """Test that URIs are the same, up to reordering of query parameters."""
  expected = urlparse(expected)
  actual = urlparse(actual)
  testcase.assertEqual(expected.scheme, actual.scheme)
  testcase.assertEqual(expected.netloc, actual.netloc)
  testcase.assertEqual(expected.path, actual.path)
  testcase.assertEqual(expected.params, actual.params)
  testcase.assertEqual(expected.fragment, actual.fragment)
  expected_query = parse_qs(expected.query)
  actual_query = parse_qs(actual.query)
  for name in list(expected_query.keys()):
    testcase.assertEqual(expected_query[name], actual_query[name])
  for name in list(actual_query.keys()):
    testcase.assertEqual(expected_query[name], actual_query[name])


def datafile(filename):
  return os.path.join(DATA_DIR, filename)


class SetupHttplib2(unittest.TestCase):

  def test_retries(self):
    # Merely loading googleapiclient.discovery should set the RETRIES to 1.
    self.assertEqual(1, httplib2.RETRIES)


class Utilities(unittest.TestCase):

  def setUp(self):
    with open(datafile('zoo.json'), 'r') as fh:
      self.zoo_root_desc = json.loads(fh.read())
    self.zoo_get_method_desc = self.zoo_root_desc['methods']['query']
    self.zoo_animals_resource = self.zoo_root_desc['resources']['animals']
    self.zoo_insert_method_desc = self.zoo_animals_resource['methods']['insert']
    self.zoo_schema = Schemas(self.zoo_root_desc)

  def test_key2param(self):
    self.assertEqual('max_results', key2param('max-results'))
    self.assertEqual('x007_bond', key2param('007-bond'))

  def _base_fix_up_parameters_test(
          self, method_desc, http_method, root_desc, schema):
    self.assertEqual(method_desc['httpMethod'], http_method)

    method_desc_copy = copy.deepcopy(method_desc)
    self.assertEqual(method_desc, method_desc_copy)

    parameters = _fix_up_parameters(method_desc_copy, root_desc, http_method,
                                    schema)

    self.assertNotEqual(method_desc, method_desc_copy)

    for param_name in STACK_QUERY_PARAMETERS:
      self.assertEqual(STACK_QUERY_PARAMETER_DEFAULT_VALUE,
                       parameters[param_name])

    for param_name, value in six.iteritems(root_desc.get('parameters', {})):
      self.assertEqual(value, parameters[param_name])

    return parameters

  def test_fix_up_parameters_get(self):
    parameters = self._base_fix_up_parameters_test(
      self.zoo_get_method_desc, 'GET', self.zoo_root_desc, self.zoo_schema)
    # Since http_method is 'GET'
    self.assertFalse('body' in parameters)

  def test_fix_up_parameters_insert(self):
    parameters = self._base_fix_up_parameters_test(
      self.zoo_insert_method_desc, 'POST', self.zoo_root_desc, self.zoo_schema)
    body = {
        'description': 'The request body.',
        'type': 'object',
        'required': True,
        '$ref': 'Animal',
    }
    self.assertEqual(parameters['body'], body)

  def test_fix_up_parameters_check_body(self):
    dummy_root_desc = {}
    dummy_schema = {
      'Request': {
        'properties': {
          "description": "Required. Dummy parameter.",
          "type": "string"
        }
      }
    }
    no_payload_http_method = 'DELETE'
    with_payload_http_method = 'PUT'

    invalid_method_desc = {'response': 'Who cares'}
    valid_method_desc = {
      'request': {
        'key1': 'value1',
        'key2': 'value2',
        '$ref': 'Request'
      }
    }

    parameters = _fix_up_parameters(invalid_method_desc, dummy_root_desc,
                                    no_payload_http_method, dummy_schema)
    self.assertFalse('body' in parameters)

    parameters = _fix_up_parameters(valid_method_desc, dummy_root_desc,
                                    no_payload_http_method, dummy_schema)
    self.assertFalse('body' in parameters)

    parameters = _fix_up_parameters(invalid_method_desc, dummy_root_desc,
                                    with_payload_http_method, dummy_schema)
    self.assertFalse('body' in parameters)

    parameters = _fix_up_parameters(valid_method_desc, dummy_root_desc,
                                    with_payload_http_method, dummy_schema)
    body = {
        'description': 'The request body.',
        'type': 'object',
        'required': True,
        '$ref': 'Request',
        'key1': 'value1',
        'key2': 'value2',
    }
    self.assertEqual(parameters['body'], body)

  def test_fix_up_parameters_optional_body(self):
    # Request with no parameters
    dummy_schema = {'Request': {'properties': {}}}
    method_desc = {'request': {'$ref': 'Request'}}

    parameters = _fix_up_parameters(method_desc, {}, 'POST', dummy_schema)
    self.assertFalse(parameters['body']['required'])

  def _base_fix_up_method_description_test(
      self, method_desc, initial_parameters, final_parameters,
      final_accept, final_max_size, final_media_path_url):
    fake_root_desc = {'rootUrl': 'http://root/',
                      'servicePath': 'fake/'}
    fake_path_url = 'fake-path/'

    accept, max_size, media_path_url = _fix_up_media_upload(
        method_desc, fake_root_desc, fake_path_url, initial_parameters)
    self.assertEqual(accept, final_accept)
    self.assertEqual(max_size, final_max_size)
    self.assertEqual(media_path_url, final_media_path_url)
    self.assertEqual(initial_parameters, final_parameters)

  def test_fix_up_media_upload_no_initial_invalid(self):
    invalid_method_desc = {'response': 'Who cares'}
    self._base_fix_up_method_description_test(invalid_method_desc, {}, {},
                                              [], 0, None)

  def test_fix_up_media_upload_no_initial_valid_minimal(self):
    valid_method_desc = {'mediaUpload': {'accept': []}}
    final_parameters = {'media_body': MEDIA_BODY_PARAMETER_DEFAULT_VALUE,
                        'media_mime_type': MEDIA_MIME_TYPE_PARAMETER_DEFAULT_VALUE}
    self._base_fix_up_method_description_test(
        valid_method_desc, {}, final_parameters, [], 0,
        'http://root/upload/fake/fake-path/')

  def test_fix_up_media_upload_no_initial_valid_full(self):
    valid_method_desc = {'mediaUpload': {'accept': ['*/*'], 'maxSize': '10GB'}}
    final_parameters = {'media_body': MEDIA_BODY_PARAMETER_DEFAULT_VALUE,
                        'media_mime_type': MEDIA_MIME_TYPE_PARAMETER_DEFAULT_VALUE}
    ten_gb = 10 * 2**30
    self._base_fix_up_method_description_test(
        valid_method_desc, {}, final_parameters, ['*/*'],
        ten_gb, 'http://root/upload/fake/fake-path/')

  def test_fix_up_media_upload_with_initial_invalid(self):
    invalid_method_desc = {'response': 'Who cares'}
    initial_parameters = {'body': {}}
    self._base_fix_up_method_description_test(
        invalid_method_desc, initial_parameters,
        initial_parameters, [], 0, None)

  def test_fix_up_media_upload_with_initial_valid_minimal(self):
    valid_method_desc = {'mediaUpload': {'accept': []}}
    initial_parameters = {'body': {}}
    final_parameters = {'body': {'required': False},
                        'media_body': MEDIA_BODY_PARAMETER_DEFAULT_VALUE,
                        'media_mime_type': MEDIA_MIME_TYPE_PARAMETER_DEFAULT_VALUE}
    self._base_fix_up_method_description_test(
        valid_method_desc, initial_parameters, final_parameters, [], 0,
        'http://root/upload/fake/fake-path/')

  def test_fix_up_media_upload_with_initial_valid_full(self):
    valid_method_desc = {'mediaUpload': {'accept': ['*/*'], 'maxSize': '10GB'}}
    initial_parameters = {'body': {}}
    final_parameters = {'body': {'required': False},
                        'media_body': MEDIA_BODY_PARAMETER_DEFAULT_VALUE,
                        'media_mime_type': MEDIA_MIME_TYPE_PARAMETER_DEFAULT_VALUE}
    ten_gb = 10 * 2**30
    self._base_fix_up_method_description_test(
        valid_method_desc, initial_parameters, final_parameters, ['*/*'],
        ten_gb, 'http://root/upload/fake/fake-path/')

  def test_fix_up_method_description_get(self):
    result = _fix_up_method_description(self.zoo_get_method_desc,
                                        self.zoo_root_desc, self.zoo_schema)
    path_url = 'query'
    http_method = 'GET'
    method_id = 'bigquery.query'
    accept = []
    max_size = 0
    media_path_url = None
    self.assertEqual(result, (path_url, http_method, method_id, accept,
                              max_size, media_path_url))

  def test_fix_up_method_description_insert(self):
    result = _fix_up_method_description(self.zoo_insert_method_desc,
                                        self.zoo_root_desc, self.zoo_schema)
    path_url = 'animals'
    http_method = 'POST'
    method_id = 'zoo.animals.insert'
    accept = ['image/png']
    max_size = 1024
    media_path_url = 'https://www.googleapis.com/upload/zoo/v1/animals'
    self.assertEqual(result, (path_url, http_method, method_id, accept,
                              max_size, media_path_url))

  def test_urljoin(self):
    # We want to exhaustively test various URL combinations.
    simple_bases = ['https://www.googleapis.com', 'https://www.googleapis.com/']
    long_urls = ['foo/v1/bar:custom?alt=json', '/foo/v1/bar:custom?alt=json']

    long_bases = [
      'https://www.googleapis.com/foo/v1',
      'https://www.googleapis.com/foo/v1/',
    ]
    simple_urls = ['bar:custom?alt=json', '/bar:custom?alt=json']

    final_url = 'https://www.googleapis.com/foo/v1/bar:custom?alt=json'
    for base, url in itertools.product(simple_bases, long_urls):
      self.assertEqual(final_url, _urljoin(base, url))
    for base, url in itertools.product(long_bases, simple_urls):
      self.assertEqual(final_url, _urljoin(base, url))


  def test_ResourceMethodParameters_zoo_get(self):
    parameters = ResourceMethodParameters(self.zoo_get_method_desc)

    param_types = {'a': 'any',
                   'b': 'boolean',
                   'e': 'string',
                   'er': 'string',
                   'i': 'integer',
                   'n': 'number',
                   'o': 'object',
                   'q': 'string',
                   'rr': 'string'}
    keys = list(param_types.keys())
    self.assertEqual(parameters.argmap, dict((key, key) for key in keys))
    self.assertEqual(parameters.required_params, [])
    self.assertEqual(sorted(parameters.repeated_params), ['er', 'rr'])
    self.assertEqual(parameters.pattern_params, {'rr': '[a-z]+'})
    self.assertEqual(sorted(parameters.query_params),
                     ['a', 'b', 'e', 'er', 'i', 'n', 'o', 'q', 'rr'])
    self.assertEqual(parameters.path_params, set())
    self.assertEqual(parameters.param_types, param_types)
    enum_params = {'e': ['foo', 'bar'],
                   'er': ['one', 'two', 'three']}
    self.assertEqual(parameters.enum_params, enum_params)

  def test_ResourceMethodParameters_zoo_animals_patch(self):
    method_desc = self.zoo_animals_resource['methods']['patch']
    parameters = ResourceMethodParameters(method_desc)

    param_types = {'name': 'string'}
    keys = list(param_types.keys())
    self.assertEqual(parameters.argmap, dict((key, key) for key in keys))
    self.assertEqual(parameters.required_params, ['name'])
    self.assertEqual(parameters.repeated_params, [])
    self.assertEqual(parameters.pattern_params, {})
    self.assertEqual(parameters.query_params, [])
    self.assertEqual(parameters.path_params, set(['name']))
    self.assertEqual(parameters.param_types, param_types)
    self.assertEqual(parameters.enum_params, {})


class DiscoveryErrors(unittest.TestCase):

  def test_tests_should_be_run_with_strict_positional_enforcement(self):
    try:
      plus = build('plus', 'v1', None)
      self.fail("should have raised a TypeError exception over missing http=.")
    except TypeError:
      pass

  def test_failed_to_parse_discovery_json(self):
    self.http = HttpMock(datafile('malformed.json'), {'status': '200'})
    try:
      plus = build('plus', 'v1', http=self.http, cache_discovery=False)
      self.fail("should have raised an exception over malformed JSON.")
    except InvalidJsonError:
      pass

  def test_unknown_api_name_or_version(self):
      http = HttpMockSequence([
        ({'status': '404'}, open(datafile('zoo.json'), 'rb').read()),
        ({'status': '404'}, open(datafile('zoo.json'), 'rb').read()),
      ])
      with self.assertRaises(UnknownApiNameOrVersion):
        plus = build('plus', 'v1', http=http, cache_discovery=False)

  def test_credentials_and_http_mutually_exclusive(self):
    http = HttpMock(datafile('plus.json'), {'status': '200'})
    with self.assertRaises(ValueError):
      build(
        'plus', 'v1', http=http, credentials=mock.sentinel.credentials)


class DiscoveryFromDocument(unittest.TestCase):
  MOCK_CREDENTIALS = mock.Mock(spec=google.auth.credentials.Credentials)

  def test_can_build_from_local_document(self):
    discovery = open(datafile('plus.json')).read()
    plus = build_from_document(
      discovery, base="https://www.googleapis.com/",
      credentials=self.MOCK_CREDENTIALS)
    self.assertTrue(plus is not None)
    self.assertTrue(hasattr(plus, 'activities'))

  def test_can_build_from_local_deserialized_document(self):
    discovery = open(datafile('plus.json')).read()
    discovery = json.loads(discovery)
    plus = build_from_document(
      discovery, base="https://www.googleapis.com/",
      credentials=self.MOCK_CREDENTIALS)
    self.assertTrue(plus is not None)
    self.assertTrue(hasattr(plus, 'activities'))

  def test_building_with_base_remembers_base(self):
    discovery = open(datafile('plus.json')).read()

    base = "https://www.example.com/"
    plus = build_from_document(
      discovery, base=base, credentials=self.MOCK_CREDENTIALS)
    self.assertEquals("https://www.googleapis.com/plus/v1/", plus._baseUrl)

  def test_building_with_optional_http_with_authorization(self):
    discovery = open(datafile('plus.json')).read()
    plus = build_from_document(
      discovery, base="https://www.googleapis.com/",
      credentials=self.MOCK_CREDENTIALS)

    # plus service requires Authorization, hence we expect to see AuthorizedHttp object here
    self.assertIsInstance(plus._http, google_auth_httplib2.AuthorizedHttp)
    self.assertIsInstance(plus._http.http, httplib2.Http)
    self.assertIsInstance(plus._http.http.timeout, int)
    self.assertGreater(plus._http.http.timeout, 0)

  def test_building_with_optional_http_with_no_authorization(self):
    discovery = open(datafile('plus.json')).read()
    # Cleanup auth field, so we would use plain http client
    discovery = json.loads(discovery)
    discovery['auth'] = {}
    discovery = json.dumps(discovery)

    plus = build_from_document(
      discovery, base="https://www.googleapis.com/",
      credentials=self.MOCK_CREDENTIALS)
    # plus service requires Authorization
    self.assertIsInstance(plus._http, httplib2.Http)
    self.assertIsInstance(plus._http.timeout, int)
    self.assertGreater(plus._http.timeout, 0)

  def test_building_with_explicit_http(self):
    http = HttpMock()
    discovery = open(datafile('plus.json')).read()
    plus = build_from_document(
      discovery, base="https://www.googleapis.com/", http=http)
    self.assertEquals(plus._http, http)

  def test_building_with_developer_key_skips_adc(self):
    discovery = open(datafile('plus.json')).read()
    plus = build_from_document(
      discovery, base="https://www.googleapis.com/", developerKey='123')
    self.assertIsInstance(plus._http, httplib2.Http)
    # It should not be an AuthorizedHttp, because that would indicate that
    # application default credentials were used.
    self.assertNotIsInstance(plus._http, google_auth_httplib2.AuthorizedHttp)


class DiscoveryFromHttp(unittest.TestCase):
  def setUp(self):
    self.old_environ = os.environ.copy()

  def tearDown(self):
    os.environ = self.old_environ

  def test_userip_is_added_to_discovery_uri(self):
    # build() will raise an HttpError on a 400, use this to pick the request uri
    # out of the raised exception.
    os.environ['REMOTE_ADDR'] = '10.0.0.1'
    try:
      http = HttpMockSequence([
        ({'status': '400'}, open(datafile('zoo.json'), 'rb').read()),
        ])
      zoo = build('zoo', 'v1', http=http, developerKey='foo',
                  discoveryServiceUrl='http://example.com')
      self.fail('Should have raised an exception.')
    except HttpError as e:
      self.assertEqual(e.uri, 'http://example.com?userIp=10.0.0.1')

  def test_userip_missing_is_not_added_to_discovery_uri(self):
    # build() will raise an HttpError on a 400, use this to pick the request uri
    # out of the raised exception.
    try:
      http = HttpMockSequence([
        ({'status': '400'}, open(datafile('zoo.json'), 'rb').read()),
        ])
      zoo = build('zoo', 'v1', http=http, developerKey=None,
                  discoveryServiceUrl='http://example.com')
      self.fail('Should have raised an exception.')
    except HttpError as e:
      self.assertEqual(e.uri, 'http://example.com')

  def test_discovery_loading_from_v2_discovery_uri(self):
      http = HttpMockSequence([
        ({'status': '404'}, 'Not found'),
        ({'status': '200'}, open(datafile('zoo.json'), 'rb').read()),
      ])
      zoo = build('zoo', 'v1', http=http, cache_discovery=False)
      self.assertTrue(hasattr(zoo, 'animals'))

class DiscoveryFromAppEngineCache(unittest.TestCase):
  def test_appengine_memcache(self):
    # Hack module import
    self.orig_import = __import__
    self.mocked_api = mock.MagicMock()

    def import_mock(name, *args, **kwargs):
      if name == 'google.appengine.api':
        return self.mocked_api
      return self.orig_import(name, *args, **kwargs)

    import_fullname = '__builtin__.__import__'
    if sys.version_info[0] >= 3:
      import_fullname = 'builtins.__import__'

    with mock.patch(import_fullname, side_effect=import_mock):
      namespace = 'google-api-client'
      self.http = HttpMock(datafile('plus.json'), {'status': '200'})

      self.mocked_api.memcache.get.return_value = None

      plus = build('plus', 'v1', http=self.http)

      # memcache.get is called once
      url = 'https://www.googleapis.com/discovery/v1/apis/plus/v1/rest'
      self.mocked_api.memcache.get.assert_called_once_with(url,
                                                           namespace=namespace)

      # memcache.set is called once
      with open(datafile('plus.json')) as f:
        content = f.read()
      self.mocked_api.memcache.set.assert_called_once_with(
        url, content, time=DISCOVERY_DOC_MAX_AGE, namespace=namespace)

      # Returns the cached content this time.
      self.mocked_api.memcache.get.return_value = content

      # Make sure the contents are returned from the cache.
      # (Otherwise it should through an error)
      self.http = HttpMock(None, {'status': '200'})

      plus = build('plus', 'v1', http=self.http)

      # memcache.get is called twice
      self.mocked_api.memcache.get.assert_has_calls(
        [mock.call(url, namespace=namespace),
         mock.call(url, namespace=namespace)])

      # memcahce.set is called just once
      self.mocked_api.memcache.set.assert_called_once_with(
        url, content, time=DISCOVERY_DOC_MAX_AGE,namespace=namespace)


class DictCache(Cache):
  def __init__(self):
    self.d = {}
  def get(self, url):
    return self.d.get(url, None)
  def set(self, url, content):
    self.d[url] = content
  def contains(self, url):
    return url in self.d


class DiscoveryFromFileCache(unittest.TestCase):
  def test_file_based_cache(self):
    cache = mock.Mock(wraps=DictCache())
    with mock.patch('googleapiclient.discovery_cache.autodetect',
                    return_value=cache):
      self.http = HttpMock(datafile('plus.json'), {'status': '200'})

      plus = build('plus', 'v1', http=self.http)

      # cache.get is called once
      url = 'https://www.googleapis.com/discovery/v1/apis/plus/v1/rest'
      cache.get.assert_called_once_with(url)

      # cache.set is called once
      with open(datafile('plus.json')) as f:
        content = f.read()
      cache.set.assert_called_once_with(url, content)

      # Make sure there is a cache entry for the plus v1 discovery doc.
      self.assertTrue(cache.contains(url))

      # Make sure the contents are returned from the cache.
      # (Otherwise it should through an error)
      self.http = HttpMock(None, {'status': '200'})

      plus = build('plus', 'v1', http=self.http)

      # cache.get is called twice
      cache.get.assert_has_calls([mock.call(url), mock.call(url)])

      # cahce.set is called just once
      cache.set.assert_called_once_with(url, content)


class Discovery(unittest.TestCase):

  def test_method_error_checking(self):
    self.http = HttpMock(datafile('plus.json'), {'status': '200'})
    plus = build('plus', 'v1', http=self.http)

    # Missing required parameters
    try:
      plus.activities().list()
      self.fail()
    except TypeError as e:
      self.assertTrue('Missing' in str(e))

    # Missing required parameters even if supplied as None.
    try:
      plus.activities().list(collection=None, userId=None)
      self.fail()
    except TypeError as e:
      self.assertTrue('Missing' in str(e))

    # Parameter doesn't match regex
    try:
      plus.activities().list(collection='not_a_collection_name', userId='me')
      self.fail()
    except TypeError as e:
      self.assertTrue('not an allowed value' in str(e))

    # Unexpected parameter
    try:
      plus.activities().list(flubber=12)
      self.fail()
    except TypeError as e:
      self.assertTrue('unexpected' in str(e))

  def _check_query_types(self, request):
    parsed = urlparse(request.uri)
    q = parse_qs(parsed[4])
    self.assertEqual(q['q'], ['foo'])
    self.assertEqual(q['i'], ['1'])
    self.assertEqual(q['n'], ['1.0'])
    self.assertEqual(q['b'], ['false'])
    self.assertEqual(q['a'], ['[1, 2, 3]'])
    self.assertEqual(q['o'], ['{\'a\': 1}'])
    self.assertEqual(q['e'], ['bar'])

  def test_type_coercion(self):
    http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=http)

    request = zoo.query(
        q="foo", i=1.0, n=1.0, b=0, a=[1,2,3], o={'a':1}, e='bar')
    self._check_query_types(request)
    request = zoo.query(
        q="foo", i=1, n=1, b=False, a=[1,2,3], o={'a':1}, e='bar')
    self._check_query_types(request)

    request = zoo.query(
        q="foo", i="1", n="1", b="", a=[1,2,3], o={'a':1}, e='bar', er='two')

    request = zoo.query(
        q="foo", i="1", n="1", b="", a=[1,2,3], o={'a':1}, e='bar',
        er=['one', 'three'], rr=['foo', 'bar'])
    self._check_query_types(request)

    # Five is right out.
    self.assertRaises(TypeError, zoo.query, er=['one', 'five'])

  def test_optional_stack_query_parameters(self):
    http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=http)
    request = zoo.query(trace='html', fields='description')

    parsed = urlparse(request.uri)
    q = parse_qs(parsed[4])
    self.assertEqual(q['trace'], ['html'])
    self.assertEqual(q['fields'], ['description'])

  def test_string_params_value_of_none_get_dropped(self):
    http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=http)
    request = zoo.query(trace=None, fields='description')

    parsed = urlparse(request.uri)
    q = parse_qs(parsed[4])
    self.assertFalse('trace' in q)

  def test_model_added_query_parameters(self):
    http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=http)
    request = zoo.animals().get(name='Lion')

    parsed = urlparse(request.uri)
    q = parse_qs(parsed[4])
    self.assertEqual(q['alt'], ['json'])
    self.assertEqual(request.headers['accept'], 'application/json')

  def test_fallback_to_raw_model(self):
    http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=http)
    request = zoo.animals().getmedia(name='Lion')

    parsed = urlparse(request.uri)
    q = parse_qs(parsed[4])
    self.assertTrue('alt' not in q)
    self.assertEqual(request.headers['accept'], '*/*')

  def test_patch(self):
    http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=http)
    request = zoo.animals().patch(name='lion', body='{"description": "foo"}')

    self.assertEqual(request.method, 'PATCH')

  def test_batch_request_from_discovery(self):
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    # zoo defines a batchPath
    zoo = build('zoo', 'v1', http=self.http)
    batch_request = zoo.new_batch_http_request()
    self.assertEqual(batch_request._batch_uri,
                     "https://www.googleapis.com/batchZoo")

  def test_batch_request_from_default(self):
    self.http = HttpMock(datafile('plus.json'), {'status': '200'})
    # plus does not define a batchPath
    plus = build('plus', 'v1', http=self.http)
    batch_request = plus.new_batch_http_request()
    self.assertEqual(batch_request._batch_uri,
                     "https://www.googleapis.com/batch")

  def test_tunnel_patch(self):
    http = HttpMockSequence([
      ({'status': '200'}, open(datafile('zoo.json'), 'rb').read()),
      ({'status': '200'}, 'echo_request_headers_as_json'),
      ])
    http = tunnel_patch(http)
    zoo = build('zoo', 'v1', http=http, cache_discovery=False)
    resp = zoo.animals().patch(
        name='lion', body='{"description": "foo"}').execute()

    self.assertTrue('x-http-method-override' in resp)

  def test_plus_resources(self):
    self.http = HttpMock(datafile('plus.json'), {'status': '200'})
    plus = build('plus', 'v1', http=self.http)
    self.assertTrue(getattr(plus, 'activities'))
    self.assertTrue(getattr(plus, 'people'))

  def test_oauth2client_credentials(self):
    credentials = mock.Mock(spec=GoogleCredentials)
    credentials.create_scoped_required.return_value = False

    discovery = open(datafile('plus.json')).read()
    service = build_from_document(discovery, credentials=credentials)
    self.assertEqual(service._http, credentials.authorize.return_value)

  def test_google_auth_credentials(self):
    credentials = mock.Mock(spec=google.auth.credentials.Credentials)
    discovery = open(datafile('plus.json')).read()
    service = build_from_document(discovery, credentials=credentials)

    self.assertIsInstance(service._http, google_auth_httplib2.AuthorizedHttp)
    self.assertEqual(service._http.credentials, credentials)

  def test_no_scopes_no_credentials(self):
    # Zoo doesn't have scopes
    discovery = open(datafile('zoo.json')).read()
    service = build_from_document(discovery)
    # Should be an ordinary httplib2.Http instance and not AuthorizedHttp.
    self.assertIsInstance(service._http, httplib2.Http)

  def test_full_featured(self):
    # Zoo should exercise all discovery facets
    # and should also have no future.json file.
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)
    self.assertTrue(getattr(zoo, 'animals'))

    request = zoo.animals().list(name='bat', projection="full")
    parsed = urlparse(request.uri)
    q = parse_qs(parsed[4])
    self.assertEqual(q['name'], ['bat'])
    self.assertEqual(q['projection'], ['full'])

  def test_nested_resources(self):
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)
    self.assertTrue(getattr(zoo, 'animals'))
    request = zoo.my().favorites().list(max_results="5")
    parsed = urlparse(request.uri)
    q = parse_qs(parsed[4])
    self.assertEqual(q['max-results'], ['5'])

  @unittest.skipIf(six.PY3, 'print is not a reserved name in Python 3')
  def test_methods_with_reserved_names(self):
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)
    self.assertTrue(getattr(zoo, 'animals'))
    request = zoo.global_().print_().assert_(max_results="5")
    parsed = urlparse(request.uri)
    self.assertEqual(parsed[2], '/zoo/v1/global/print/assert')

  def test_top_level_functions(self):
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)
    self.assertTrue(getattr(zoo, 'query'))
    request = zoo.query(q="foo")
    parsed = urlparse(request.uri)
    q = parse_qs(parsed[4])
    self.assertEqual(q['q'], ['foo'])

  def test_simple_media_uploads(self):
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)
    doc = getattr(zoo.animals().insert, '__doc__')
    self.assertTrue('media_body' in doc)

  def test_simple_media_upload_no_max_size_provided(self):
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)
    request = zoo.animals().crossbreed(media_body=datafile('small.png'))
    self.assertEquals('image/png', request.headers['content-type'])
    self.assertEquals(b'PNG', request.body[1:4])

  def test_simple_media_raise_correct_exceptions(self):
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)

    try:
      zoo.animals().insert(media_body=datafile('smiley.png'))
      self.fail("should throw exception if media is too large.")
    except MediaUploadSizeError:
      pass

    try:
      zoo.animals().insert(media_body=datafile('small.jpg'))
      self.fail("should throw exception if mimetype is unacceptable.")
    except UnacceptableMimeTypeError:
      pass

  def test_simple_media_good_upload(self):
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)

    request = zoo.animals().insert(media_body=datafile('small.png'))
    self.assertEquals('image/png', request.headers['content-type'])
    self.assertEquals(b'PNG', request.body[1:4])
    assertUrisEqual(self,
        'https://www.googleapis.com/upload/zoo/v1/animals?uploadType=media&alt=json',
        request.uri)

  def test_simple_media_unknown_mimetype(self):
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)

    try:
      zoo.animals().insert(media_body=datafile('small-png'))
      self.fail("should throw exception if mimetype is unknown.")
    except UnknownFileType:
      pass

    request = zoo.animals().insert(media_body=datafile('small-png'),
                                   media_mime_type='image/png')
    self.assertEquals('image/png', request.headers['content-type'])
    self.assertEquals(b'PNG', request.body[1:4])
    assertUrisEqual(self,
        'https://www.googleapis.com/upload/zoo/v1/animals?uploadType=media&alt=json',
        request.uri)

  def test_multipart_media_raise_correct_exceptions(self):
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)

    try:
      zoo.animals().insert(media_body=datafile('smiley.png'), body={})
      self.fail("should throw exception if media is too large.")
    except MediaUploadSizeError:
      pass

    try:
      zoo.animals().insert(media_body=datafile('small.jpg'), body={})
      self.fail("should throw exception if mimetype is unacceptable.")
    except UnacceptableMimeTypeError:
      pass

  def test_multipart_media_good_upload(self):
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)

    request = zoo.animals().insert(media_body=datafile('small.png'), body={})
    self.assertTrue(request.headers['content-type'].startswith(
        'multipart/related'))
    with open(datafile('small.png'), 'rb') as f:
      contents = f.read()
    boundary = re.match(b'--=+([^=]+)', request.body).group(1)
    self.assertEqual(
      request.body.rstrip(b"\n"), # Python 2.6 does not add a trailing \n
      b'--===============' + boundary + b'==\n' +
      b'Content-Type: application/json\n' +
      b'MIME-Version: 1.0\n\n' +
      b'{"data": {}}\n' +
      b'--===============' + boundary + b'==\n' +
      b'Content-Type: image/png\n' +
      b'MIME-Version: 1.0\n' +
      b'Content-Transfer-Encoding: binary\n\n' +
      contents +
      b'\n--===============' + boundary + b'==--')
    assertUrisEqual(self,
        'https://www.googleapis.com/upload/zoo/v1/animals?uploadType=multipart&alt=json',
        request.uri)

  def test_media_capable_method_without_media(self):
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)

    request = zoo.animals().insert(body={})
    self.assertTrue(request.headers['content-type'], 'application/json')

  def test_resumable_multipart_media_good_upload(self):
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)

    media_upload = MediaFileUpload(datafile('small.png'), resumable=True)
    request = zoo.animals().insert(media_body=media_upload, body={})
    self.assertTrue(request.headers['content-type'].startswith(
        'application/json'))
    self.assertEquals('{"data": {}}', request.body)
    self.assertEquals(media_upload, request.resumable)

    self.assertEquals('image/png', request.resumable.mimetype())

    self.assertNotEquals(request.body, None)
    self.assertEquals(request.resumable_uri, None)

    http = HttpMockSequence([
      ({'status': '200',
        'location': 'http://upload.example.com'}, ''),
      ({'status': '308',
        'location': 'http://upload.example.com/2'}, ''),
      ({'status': '308',
        'location': 'http://upload.example.com/3',
        'range': '0-12'}, ''),
      ({'status': '308',
        'location': 'http://upload.example.com/4',
        'range': '0-%d' % (media_upload.size() - 2)}, ''),
      ({'status': '200'}, '{"foo": "bar"}'),
      ])

    status, body = request.next_chunk(http=http)
    self.assertEquals(None, body)
    self.assertTrue(isinstance(status, MediaUploadProgress))
    self.assertEquals(0, status.resumable_progress)

    # Two requests should have been made and the resumable_uri should have been
    # updated for each one.
    self.assertEquals(request.resumable_uri, 'http://upload.example.com/2')
    self.assertEquals(media_upload, request.resumable)
    self.assertEquals(0, request.resumable_progress)
    
    # This next chuck call should upload the first chunk
    status, body = request.next_chunk(http=http)
    self.assertEquals(request.resumable_uri, 'http://upload.example.com/3')
    self.assertEquals(media_upload, request.resumable)
    self.assertEquals(13, request.resumable_progress)

    # This call will upload the next chunk
    status, body = request.next_chunk(http=http)
    self.assertEquals(request.resumable_uri, 'http://upload.example.com/4')
    self.assertEquals(media_upload.size()-1, request.resumable_progress)
    self.assertEquals('{"data": {}}', request.body)

    # Final call to next_chunk should complete the upload.
    status, body = request.next_chunk(http=http)
    self.assertEquals(body, {"foo": "bar"})
    self.assertEquals(status, None)


  def test_resumable_media_good_upload(self):
    """Not a multipart upload."""
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)

    media_upload = MediaFileUpload(datafile('small.png'), resumable=True)
    request = zoo.animals().insert(media_body=media_upload, body=None)
    self.assertEquals(media_upload, request.resumable)

    self.assertEquals('image/png', request.resumable.mimetype())

    self.assertEquals(request.body, None)
    self.assertEquals(request.resumable_uri, None)

    http = HttpMockSequence([
      ({'status': '200',
        'location': 'http://upload.example.com'}, ''),
      ({'status': '308',
        'location': 'http://upload.example.com/2',
        'range': '0-12'}, ''),
      ({'status': '308',
        'location': 'http://upload.example.com/3',
        'range': '0-%d' % (media_upload.size() - 2)}, ''),
      ({'status': '200'}, '{"foo": "bar"}'),
      ])

    status, body = request.next_chunk(http=http)
    self.assertEquals(None, body)
    self.assertTrue(isinstance(status, MediaUploadProgress))
    self.assertEquals(13, status.resumable_progress)

    # Two requests should have been made and the resumable_uri should have been
    # updated for each one.
    self.assertEquals(request.resumable_uri, 'http://upload.example.com/2')

    self.assertEquals(media_upload, request.resumable)
    self.assertEquals(13, request.resumable_progress)

    status, body = request.next_chunk(http=http)
    self.assertEquals(request.resumable_uri, 'http://upload.example.com/3')
    self.assertEquals(media_upload.size()-1, request.resumable_progress)
    self.assertEquals(request.body, None)

    # Final call to next_chunk should complete the upload.
    status, body = request.next_chunk(http=http)
    self.assertEquals(body, {"foo": "bar"})
    self.assertEquals(status, None)

  def test_resumable_media_good_upload_from_execute(self):
    """Not a multipart upload."""
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)

    media_upload = MediaFileUpload(datafile('small.png'), resumable=True)
    request = zoo.animals().insert(media_body=media_upload, body=None)
    assertUrisEqual(self,
        'https://www.googleapis.com/upload/zoo/v1/animals?uploadType=resumable&alt=json',
        request.uri)

    http = HttpMockSequence([
      ({'status': '200',
        'location': 'http://upload.example.com'}, ''),
      ({'status': '308',
        'location': 'http://upload.example.com/2',
        'range': '0-12'}, ''),
      ({'status': '308',
        'location': 'http://upload.example.com/3',
        'range': '0-%d' % media_upload.size()}, ''),
      ({'status': '200'}, '{"foo": "bar"}'),
      ])

    body = request.execute(http=http)
    self.assertEquals(body, {"foo": "bar"})

  def test_resumable_media_fail_unknown_response_code_first_request(self):
    """Not a multipart upload."""
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)

    media_upload = MediaFileUpload(datafile('small.png'), resumable=True)
    request = zoo.animals().insert(media_body=media_upload, body=None)

    http = HttpMockSequence([
      ({'status': '400',
        'location': 'http://upload.example.com'}, ''),
      ])

    try:
      request.execute(http=http)
      self.fail('Should have raised ResumableUploadError.')
    except ResumableUploadError as e:
      self.assertEqual(400, e.resp.status)

  def test_resumable_media_fail_unknown_response_code_subsequent_request(self):
    """Not a multipart upload."""
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)

    media_upload = MediaFileUpload(datafile('small.png'), resumable=True)
    request = zoo.animals().insert(media_body=media_upload, body=None)

    http = HttpMockSequence([
      ({'status': '200',
        'location': 'http://upload.example.com'}, ''),
      ({'status': '400'}, ''),
      ])

    self.assertRaises(HttpError, request.execute, http=http)
    self.assertTrue(request._in_error_state)

    http = HttpMockSequence([
      ({'status': '308',
        'range': '0-5'}, ''),
      ({'status': '308',
        'range': '0-6'}, ''),
      ])

    status, body = request.next_chunk(http=http)
    self.assertEquals(status.resumable_progress, 7,
      'Should have first checked length and then tried to PUT more.')
    self.assertFalse(request._in_error_state)

    # Put it back in an error state.
    http = HttpMockSequence([
      ({'status': '400'}, ''),
      ])
    self.assertRaises(HttpError, request.execute, http=http)
    self.assertTrue(request._in_error_state)

    # Pretend the last request that 400'd actually succeeded.
    http = HttpMockSequence([
      ({'status': '200'}, '{"foo": "bar"}'),
      ])
    status, body = request.next_chunk(http=http)
    self.assertEqual(body, {'foo': 'bar'})

  def test_media_io_base_stream_unlimited_chunksize_resume(self):
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)

    # Set up a seekable stream and try to upload in single chunk.
    fd = BytesIO(b'01234"56789"')
    media_upload = MediaIoBaseUpload(
        fd=fd, mimetype='text/plain', chunksize=-1, resumable=True)

    request = zoo.animals().insert(media_body=media_upload, body=None)

    # The single chunk fails, restart at the right point.
    http = HttpMockSequence([
      ({'status': '200',
        'location': 'http://upload.example.com'}, ''),
      ({'status': '308',
        'location': 'http://upload.example.com/2',
        'range': '0-4'}, ''),
      ({'status': '200'}, 'echo_request_body'),
      ])

    body = request.execute(http=http)
    self.assertEqual('56789', body)

  def test_media_io_base_stream_chunksize_resume(self):
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)

    # Set up a seekable stream and try to upload in chunks.
    fd = BytesIO(b'0123456789')
    media_upload = MediaIoBaseUpload(
        fd=fd, mimetype='text/plain', chunksize=5, resumable=True)

    request = zoo.animals().insert(media_body=media_upload, body=None)

    # The single chunk fails, pull the content sent out of the exception.
    http = HttpMockSequence([
      ({'status': '200',
        'location': 'http://upload.example.com'}, ''),
      ({'status': '400'}, 'echo_request_body'),
      ])

    try:
      body = request.execute(http=http)
    except HttpError as e:
      self.assertEqual(b'01234', e.content)

  def test_resumable_media_handle_uploads_of_unknown_size(self):
    http = HttpMockSequence([
      ({'status': '200',
        'location': 'http://upload.example.com'}, ''),
      ({'status': '200'}, 'echo_request_headers_as_json'),
      ])

    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)

    # Create an upload that doesn't know the full size of the media.
    class IoBaseUnknownLength(MediaUpload):
      def chunksize(self):
        return 10

      def mimetype(self):
        return 'image/png'

      def size(self):
        return None

      def resumable(self):
        return True

      def getbytes(self, begin, length):
        return '0123456789'

    upload = IoBaseUnknownLength()

    request = zoo.animals().insert(media_body=upload, body=None)
    status, body = request.next_chunk(http=http)
    self.assertEqual(body, {
        'Content-Range': 'bytes 0-9/*',
        'Content-Length': '10',
        })

  def test_resumable_media_no_streaming_on_unsupported_platforms(self):
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)

    class IoBaseHasStream(MediaUpload):
      def chunksize(self):
        return 10

      def mimetype(self):
        return 'image/png'

      def size(self):
        return None

      def resumable(self):
        return True

      def getbytes(self, begin, length):
        return '0123456789'

      def has_stream(self):
        return True

      def stream(self):
        raise NotImplementedError()

    upload = IoBaseHasStream()

    orig_version = sys.version_info

    sys.version_info = (2, 6, 5, 'final', 0)

    request = zoo.animals().insert(media_body=upload, body=None)

    # This should raise an exception because stream() will be called.
    http = HttpMockSequence([
      ({'status': '200',
        'location': 'http://upload.example.com'}, ''),
      ({'status': '200'}, 'echo_request_headers_as_json'),
      ])

    self.assertRaises(NotImplementedError, request.next_chunk, http=http)

    sys.version_info = orig_version

  def test_resumable_media_handle_uploads_of_unknown_size_eof(self):
    http = HttpMockSequence([
      ({'status': '200',
        'location': 'http://upload.example.com'}, ''),
      ({'status': '200'}, 'echo_request_headers_as_json'),
      ])

    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)

    fd = BytesIO(b'data goes here')

    # Create an upload that doesn't know the full size of the media.
    upload = MediaIoBaseUpload(
        fd=fd, mimetype='image/png', chunksize=15, resumable=True)

    request = zoo.animals().insert(media_body=upload, body=None)
    status, body = request.next_chunk(http=http)
    self.assertEqual(body, {
        'Content-Range': 'bytes 0-13/14',
        'Content-Length': '14',
        })

  def test_resumable_media_handle_resume_of_upload_of_unknown_size(self):
    http = HttpMockSequence([
      ({'status': '200',
        'location': 'http://upload.example.com'}, ''),
      ({'status': '400'}, ''),
      ])

    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)

    # Create an upload that doesn't know the full size of the media.
    fd = BytesIO(b'data goes here')

    upload = MediaIoBaseUpload(
        fd=fd, mimetype='image/png', chunksize=500, resumable=True)

    request = zoo.animals().insert(media_body=upload, body=None)

    # Put it in an error state.
    self.assertRaises(HttpError, request.next_chunk, http=http)

    http = HttpMockSequence([
      ({'status': '400',
        'range': '0-5'}, 'echo_request_headers_as_json'),
      ])
    try:
      # Should resume the upload by first querying the status of the upload.
      request.next_chunk(http=http)
    except HttpError as e:
      expected = {
          'Content-Range': 'bytes */14',
          'content-length': '0'
          }
      self.assertEqual(expected, json.loads(e.content.decode('utf-8')),
        'Should send an empty body when requesting the current upload status.')

  def test_pickle(self):
    sorted_resource_keys = ['_baseUrl',
                            '_developerKey',
                            '_dynamic_attrs',
                            '_http',
                            '_model',
                            '_requestBuilder',
                            '_resourceDesc',
                            '_rootDesc',
                            '_schema',
                            'animals',
                            'global_',
                            'load',
                            'loadNoTemplate',
                            'my',
                            'new_batch_http_request',
                            'query',
                            'scopedAnimals']

    http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=http)
    self.assertEqual(sorted(zoo.__dict__.keys()), sorted_resource_keys)

    pickled_zoo = pickle.dumps(zoo)
    new_zoo = pickle.loads(pickled_zoo)
    self.assertEqual(sorted(new_zoo.__dict__.keys()), sorted_resource_keys)
    self.assertTrue(hasattr(new_zoo, 'animals'))
    self.assertTrue(callable(new_zoo.animals))
    self.assertTrue(hasattr(new_zoo, 'global_'))
    self.assertTrue(callable(new_zoo.global_))
    self.assertTrue(hasattr(new_zoo, 'load'))
    self.assertTrue(callable(new_zoo.load))
    self.assertTrue(hasattr(new_zoo, 'loadNoTemplate'))
    self.assertTrue(callable(new_zoo.loadNoTemplate))
    self.assertTrue(hasattr(new_zoo, 'my'))
    self.assertTrue(callable(new_zoo.my))
    self.assertTrue(hasattr(new_zoo, 'query'))
    self.assertTrue(callable(new_zoo.query))
    self.assertTrue(hasattr(new_zoo, 'scopedAnimals'))
    self.assertTrue(callable(new_zoo.scopedAnimals))

    self.assertEqual(sorted(zoo._dynamic_attrs), sorted(new_zoo._dynamic_attrs))
    self.assertEqual(zoo._baseUrl, new_zoo._baseUrl)
    self.assertEqual(zoo._developerKey, new_zoo._developerKey)
    self.assertEqual(zoo._requestBuilder, new_zoo._requestBuilder)
    self.assertEqual(zoo._resourceDesc, new_zoo._resourceDesc)
    self.assertEqual(zoo._rootDesc, new_zoo._rootDesc)
    # _http, _model and _schema won't be equal since we will get new
    # instances upon un-pickling

  def _dummy_zoo_request(self):
    with open(os.path.join(DATA_DIR, 'zoo.json'), 'rU') as fh:
      zoo_contents = fh.read()

    zoo_uri = uritemplate.expand(DISCOVERY_URI,
                                 {'api': 'zoo', 'apiVersion': 'v1'})
    if 'REMOTE_ADDR' in os.environ:
        zoo_uri = util._add_query_parameter(zoo_uri, 'userIp',
                                            os.environ['REMOTE_ADDR'])

    http = build_http()
    original_request = http.request
    def wrapped_request(uri, method='GET', *args, **kwargs):
        if uri == zoo_uri:
          return httplib2.Response({'status': '200'}), zoo_contents
        return original_request(uri, method=method, *args, **kwargs)
    http.request = wrapped_request
    return http

  def _dummy_token(self):
    access_token = 'foo'
    client_id = 'some_client_id'
    client_secret = 'cOuDdkfjxxnv+'
    refresh_token = '1/0/a.df219fjls0'
    token_expiry = datetime.datetime.utcnow()
    user_agent = 'refresh_checker/1.0'
    return OAuth2Credentials(
        access_token, client_id, client_secret,
        refresh_token, token_expiry, GOOGLE_TOKEN_URI,
        user_agent)

  def test_pickle_with_credentials(self):
    credentials = self._dummy_token()
    http = self._dummy_zoo_request()
    http = credentials.authorize(http)
    self.assertTrue(hasattr(http.request, 'credentials'))

    zoo = build('zoo', 'v1', http=http)
    pickled_zoo = pickle.dumps(zoo)
    new_zoo = pickle.loads(pickled_zoo)
    self.assertEqual(sorted(zoo.__dict__.keys()),
                     sorted(new_zoo.__dict__.keys()))
    new_http = new_zoo._http
    self.assertFalse(hasattr(new_http.request, 'credentials'))

  def test_resumable_media_upload_no_content(self):
    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)

    media_upload = MediaFileUpload(datafile('empty'), resumable=True)
    request = zoo.animals().insert(media_body=media_upload, body=None)

    self.assertEquals(media_upload, request.resumable)
    self.assertEquals(request.body, None)
    self.assertEquals(request.resumable_uri, None)

    http = HttpMockSequence([
      ({'status': '200',
        'location': 'http://upload.example.com'}, ''),
      ({'status': '308',
        'location': 'http://upload.example.com/2',
        'range': '0-0'}, ''),
    ])

    status, body = request.next_chunk(http=http)
    self.assertEquals(None, body)
    self.assertTrue(isinstance(status, MediaUploadProgress))
    self.assertEquals(0, status.progress())


class Next(unittest.TestCase):

  def test_next_successful_none_on_no_next_page_token(self):
    self.http = HttpMock(datafile('tasks.json'), {'status': '200'})
    tasks = build('tasks', 'v1', http=self.http)
    request = tasks.tasklists().list()
    self.assertEqual(None, tasks.tasklists().list_next(request, {}))

  def test_next_successful_none_on_empty_page_token(self):
    self.http = HttpMock(datafile('tasks.json'), {'status': '200'})
    tasks = build('tasks', 'v1', http=self.http)
    request = tasks.tasklists().list()
    next_request = tasks.tasklists().list_next(
        request, {'nextPageToken': ''})
    self.assertEqual(None, next_request)

  def test_next_successful_with_next_page_token(self):
    self.http = HttpMock(datafile('tasks.json'), {'status': '200'})
    tasks = build('tasks', 'v1', http=self.http)
    request = tasks.tasklists().list()
    next_request = tasks.tasklists().list_next(
        request, {'nextPageToken': '123abc'})
    parsed = list(urlparse(next_request.uri))
    q = parse_qs(parsed[4])
    self.assertEqual(q['pageToken'][0], '123abc')

  def test_next_successful_with_next_page_token_alternate_name(self):
    self.http = HttpMock(datafile('bigquery.json'), {'status': '200'})
    bigquery = build('bigquery', 'v2', http=self.http)
    request = bigquery.tabledata().list(datasetId='', projectId='', tableId='')
    next_request = bigquery.tabledata().list_next(
        request, {'pageToken': '123abc'})
    parsed = list(urlparse(next_request.uri))
    q = parse_qs(parsed[4])
    self.assertEqual(q['pageToken'][0], '123abc')

  def test_next_successful_with_next_page_token_in_body(self):
    self.http = HttpMock(datafile('logging.json'), {'status': '200'})
    logging = build('logging', 'v2', http=self.http)
    request = logging.entries().list(body={})
    next_request = logging.entries().list_next(
        request, {'nextPageToken': '123abc'})
    body = JsonModel().deserialize(next_request.body)
    self.assertEqual(body['pageToken'], '123abc')

  def test_next_with_method_with_no_properties(self):
    self.http = HttpMock(datafile('latitude.json'), {'status': '200'})
    service = build('latitude', 'v1', http=self.http)
    service.currentLocation().get()

  def test_next_nonexistent_with_no_next_page_token(self):
    self.http = HttpMock(datafile('drive.json'), {'status': '200'})
    drive = build('drive', 'v3', http=self.http)
    drive.changes().watch(body={})
    self.assertFalse(callable(getattr(drive.changes(), 'watch_next', None)))

  def test_next_successful_with_next_page_token_required(self):
    self.http = HttpMock(datafile('drive.json'), {'status': '200'})
    drive = build('drive', 'v3', http=self.http)
    request = drive.changes().list(pageToken='startPageToken')
    next_request = drive.changes().list_next(
        request, {'nextPageToken': '123abc'})
    parsed = list(urlparse(next_request.uri))
    q = parse_qs(parsed[4])
    self.assertEqual(q['pageToken'][0], '123abc')


class MediaGet(unittest.TestCase):

  def test_get_media(self):
    http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=http)
    request = zoo.animals().get_media(name='Lion')

    parsed = urlparse(request.uri)
    q = parse_qs(parsed[4])
    self.assertEqual(q['alt'], ['media'])
    self.assertEqual(request.headers['accept'], '*/*')

    http = HttpMockSequence([
      ({'status': '200'}, 'standing in for media'),
      ])
    response = request.execute(http=http)
    self.assertEqual(b'standing in for media', response)


if __name__ == '__main__':
  unittest.main()
