#!/usr/bin/python
# Copyright 2014 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Unittests for gob_util.py"""

from __future__ import print_function

import httplib
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(
    os.path.abspath(__file__)))))

from chromite.cbuildbot import constants
from chromite.lib import cros_test_lib
from chromite.lib import gob_util

import mock


class FakeHTTPResponse(object):
  """Enough of a HTTPResponse for FetchUrl.

  See https://docs.python.org/2/library/httplib.html#httpresponse-objects
  for more details.
  """

  def __init__(self, body='', headers=(), reason=None, status=200, version=11):
    if reason is None:
      reason = httplib.responses[status]

    self.body = body
    self.headers = dict(headers)
    self.msg = None
    self.reason = reason
    self.status = status
    self.version = version

  def read(self):
    return self.body

  def getheader(self, name, default=None):
    return self.headers.get(name, default)

  def getheaders(self):
    return tuple(self.headers.items())


class FakeHTTPConnection(object):
  """Enough of a HTTPConnection result for FetchUrl."""

  def __init__(self, req_url='/', req_method='GET', req_headers=None,
               req_body=None, **kwargs):
    self.kwargs = kwargs.copy()
    self.req_params = {
        'url': req_url,
        'method': req_method,
        'headers': req_headers,
        'body': req_body,
    }

  def getresponse(self):
    return FakeHTTPResponse(**self.kwargs)


class GobTest(cros_test_lib.MockTestCase):
  """Unittests that use mocks."""

  def testUtf8Response(self):
    """Handle gerrit responses w/UTF8 in them."""
    utf8_data = 'That\xe2\x80\x99s an error. That\xe2\x80\x99s all we know.'
    with mock.patch.object(gob_util, 'CreateHttpConn', autospec=False) as m:
      m.return_value = FakeHTTPConnection(body=utf8_data)
      gob_util.FetchUrl('', '')

      m.return_value = FakeHTTPConnection(body=utf8_data, status=502)
      self.assertRaises(gob_util.InternalGOBError, gob_util.FetchUrl, '', '')


@cros_test_lib.NetworkTest()
class NetworkGobTest(cros_test_lib.TestCase):
  """Unittests that talk to real Gerrit."""

  def test200(self):
    """Test successful loading of change."""
    gob_util.FetchUrlJson(constants.EXTERNAL_GOB_HOST, 'changes/227254/detail')

  def test404(self):
    gob_util.FetchUrlJson(constants.EXTERNAL_GOB_HOST, 'foo/bar/baz')

  def test404Exception(self):
    with self.assertRaises(gob_util.GOBError) as ex:
      gob_util.FetchUrlJson(constants.EXTERNAL_GOB_HOST, 'foo/bar/baz',
                            ignore_404=False)
    self.assertEqual(ex.exception.http_status, 404)


if __name__ == '__main__':
  gob_util.TRY_LIMIT = 1
  cros_test_lib.main()
