#!/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 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()
