# 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
from unittest import mock
import urllib

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)
