# Copyright 2015 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.

"""Unit tests for googleapiclient._helpers."""

import unittest
import urllib

import mock
from googleapiclient import _helpers


class PositionalTests(unittest.TestCase):
    def test_usage(self):
        _helpers.positional_parameters_enforcement = _helpers.POSITIONAL_EXCEPTION

        # 1 positional arg, 1 keyword-only arg.
        @_helpers.positional(1)
        def function(pos, kwonly=None):
            return True

        self.assertTrue(function(1))
        self.assertTrue(function(1, kwonly=2))
        with self.assertRaises(TypeError):
            function(1, 2)

        # No positional, but a required keyword arg.
        @_helpers.positional(0)
        def function2(required_kw):
            return True

        self.assertTrue(function2(required_kw=1))
        with self.assertRaises(TypeError):
            function2(1)

        # Unspecified positional, should automatically figure out 1 positional
        # 1 keyword-only (same as first case above).
        @_helpers.positional
        def function3(pos, kwonly=None):
            return True

        self.assertTrue(function3(1))
        self.assertTrue(function3(1, kwonly=2))
        with self.assertRaises(TypeError):
            function3(1, 2)

    @mock.patch("googleapiclient._helpers.logger")
    def test_enforcement_warning(self, mock_logger):
        _helpers.positional_parameters_enforcement = _helpers.POSITIONAL_WARNING

        @_helpers.positional(1)
        def function(pos, kwonly=None):
            return True

        self.assertTrue(function(1, 2))
        self.assertTrue(mock_logger.warning.called)

    @mock.patch("googleapiclient._helpers.logger")
    def test_enforcement_ignore(self, mock_logger):
        _helpers.positional_parameters_enforcement = _helpers.POSITIONAL_IGNORE

        @_helpers.positional(1)
        def function(pos, kwonly=None):
            return True

        self.assertTrue(function(1, 2))
        self.assertFalse(mock_logger.warning.called)


class AddQueryParameterTests(unittest.TestCase):
    def test__add_query_parameter(self):
        self.assertEqual(_helpers._add_query_parameter("/action", "a", None), "/action")
        self.assertEqual(
            _helpers._add_query_parameter("/action", "a", "b"), "/action?a=b"
        )
        self.assertEqual(
            _helpers._add_query_parameter("/action?a=b", "a", "c"), "/action?a=c"
        )
        # Order is non-deterministic.
        self.assertIn(
            _helpers._add_query_parameter("/action?a=b", "c", "d"),
            ["/action?a=b&c=d", "/action?c=d&a=b"],
        )
        self.assertEqual(
            _helpers._add_query_parameter("/action", "a", " ="), "/action?a=+%3D"
        )


def assertUrisEqual(testcase, expected, actual):
    """Test that URIs are the same, up to reordering of query parameters."""
    expected = urllib.parse.urlparse(expected)
    actual = urllib.parse.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 = urllib.parse.parse_qs(expected.query)
    actual_query = urllib.parse.parse_qs(actual.query)
    for name in expected_query.keys():
        testcase.assertEqual(expected_query[name], actual_query[name])
    for name in actual_query.keys():
        testcase.assertEqual(expected_query[name], actual_query[name])


class Test_update_query_params(unittest.TestCase):
    def test_update_query_params_no_params(self):
        uri = "http://www.google.com"
        updated = _helpers.update_query_params(uri, {"a": "b"})
        self.assertEqual(updated, uri + "?a=b")

    def test_update_query_params_existing_params(self):
        uri = "http://www.google.com?x=y"
        updated = _helpers.update_query_params(uri, {"a": "b", "c": "d&"})
        hardcoded_update = uri + "&a=b&c=d%26"
        assertUrisEqual(self, updated, hardcoded_update)

    def test_update_query_params_replace_param(self):
        base_uri = "http://www.google.com"
        uri = base_uri + "?x=a"
        updated = _helpers.update_query_params(uri, {"x": "b", "y": "c"})
        hardcoded_update = base_uri + "?x=b&y=c"
        assertUrisEqual(self, updated, hardcoded_update)

    def test_update_query_params_repeated_params(self):
        uri = "http://www.google.com?x=a&x=b"
        with self.assertRaises(ValueError):
            _helpers.update_query_params(uri, {"a": "c"})


class Test_parse_unique_urlencoded(unittest.TestCase):
    def test_without_repeats(self):
        content = "a=b&c=d"
        result = _helpers.parse_unique_urlencoded(content)
        self.assertEqual(result, {"a": "b", "c": "d"})

    def test_with_repeats(self):
        content = "a=b&a=d"
        with self.assertRaises(ValueError):
            _helpers.parse_unique_urlencoded(content)
