#!/usr/bin/env python
#
# 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.

"""Mock tests

Unit tests for the Mocks.
"""
from __future__ import absolute_import

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

import httplib2
import os
import unittest2 as unittest

from googleapiclient.errors import HttpError
from googleapiclient.errors import UnexpectedBodyError
from googleapiclient.errors import UnexpectedMethodError
from googleapiclient.discovery import build
from googleapiclient.http import RequestMockBuilder
from googleapiclient.http import HttpMock


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


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


class Mocks(unittest.TestCase):
    def setUp(self):
        self.http = HttpMock(datafile("plus.json"), {"status": "200"})
        self.zoo_http = HttpMock(datafile("zoo.json"), {"status": "200"})

    def test_default_response(self):
        requestBuilder = RequestMockBuilder({})
        plus = build("plus", "v1", http=self.http, requestBuilder=requestBuilder, static_discovery=False)
        activity = plus.activities().get(activityId="tag:blah").execute()
        self.assertEqual({}, activity)

    def test_simple_response(self):
        requestBuilder = RequestMockBuilder(
            {"plus.activities.get": (None, '{"foo": "bar"}')}
        )
        plus = build("plus", "v1", http=self.http, requestBuilder=requestBuilder, static_discovery=False)

        activity = plus.activities().get(activityId="tag:blah").execute()
        self.assertEqual({"foo": "bar"}, activity)

    def test_unexpected_call(self):
        requestBuilder = RequestMockBuilder({}, check_unexpected=True)

        plus = build("plus", "v1", http=self.http, requestBuilder=requestBuilder, static_discovery=False)

        try:
            plus.activities().get(activityId="tag:blah").execute()
            self.fail("UnexpectedMethodError should have been raised")
        except UnexpectedMethodError:
            pass

    def test_simple_unexpected_body(self):
        requestBuilder = RequestMockBuilder(
            {"zoo.animals.insert": (None, '{"data": {"foo": "bar"}}', None)}
        )
        zoo = build("zoo", "v1", http=self.zoo_http, requestBuilder=requestBuilder, static_discovery=False)

        try:
            zoo.animals().insert(body="{}").execute()
            self.fail("UnexpectedBodyError should have been raised")
        except UnexpectedBodyError:
            pass

    def test_simple_expected_body(self):
        requestBuilder = RequestMockBuilder(
            {"zoo.animals.insert": (None, '{"data": {"foo": "bar"}}', "{}")}
        )
        zoo = build("zoo", "v1", http=self.zoo_http, requestBuilder=requestBuilder, static_discovery=False)

        try:
            zoo.animals().insert(body="").execute()
            self.fail("UnexpectedBodyError should have been raised")
        except UnexpectedBodyError:
            pass

    def test_simple_wrong_body(self):
        requestBuilder = RequestMockBuilder(
            {
                "zoo.animals.insert": (
                    None,
                    '{"data": {"foo": "bar"}}',
                    '{"data": {"foo": "bar"}}',
                )
            }
        )
        zoo = build("zoo", "v1", http=self.zoo_http, requestBuilder=requestBuilder, static_discovery=False)

        try:
            zoo.animals().insert(body='{"data": {"foo": "blah"}}').execute()
            self.fail("UnexpectedBodyError should have been raised")
        except UnexpectedBodyError:
            pass

    def test_simple_matching_str_body(self):
        requestBuilder = RequestMockBuilder(
            {
                "zoo.animals.insert": (
                    None,
                    '{"data": {"foo": "bar"}}',
                    '{"data": {"foo": "bar"}}',
                )
            }
        )
        zoo = build("zoo", "v1", http=self.zoo_http, requestBuilder=requestBuilder, static_discovery=False)

        activity = zoo.animals().insert(body={"data": {"foo": "bar"}}).execute()
        self.assertEqual({"foo": "bar"}, activity)

    def test_simple_matching_dict_body(self):
        requestBuilder = RequestMockBuilder(
            {
                "zoo.animals.insert": (
                    None,
                    '{"data": {"foo": "bar"}}',
                    {"data": {"foo": "bar"}},
                )
            }
        )
        zoo = build("zoo", "v1", http=self.zoo_http, requestBuilder=requestBuilder, static_discovery=False)

        activity = zoo.animals().insert(body={"data": {"foo": "bar"}}).execute()
        self.assertEqual({"foo": "bar"}, activity)

    def test_errors(self):
        errorResponse = httplib2.Response({"status": 500, "reason": "Server Error"})
        requestBuilder = RequestMockBuilder(
            {"plus.activities.list": (errorResponse, b"{}")}
        )
        plus = build("plus", "v1", http=self.http, requestBuilder=requestBuilder, static_discovery=False)

        try:
            activity = (
                plus.activities().list(collection="public", userId="me").execute()
            )
            self.fail("An exception should have been thrown")
        except HttpError as e:
            self.assertEqual(b"{}", e.content)
            self.assertEqual(500, e.resp.status)
            self.assertEqual("Server Error", e.resp.reason)


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