#!/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=None)
    # 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=None,
                  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_key_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.
    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?key=foo')

  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()
