#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# Copyright 2018 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 Nebraska server."""

from __future__ import print_function

import mock
import unittest

import nebraska

_NEBRASKA_PORT = 11235
_INSTALL_DIR = "test_install_dir"
_UPDATE_DIR = "test_update_dir"
_PAYLOAD_ADDRESS = "111.222.212:2357"

class MockNebraskaHandler(nebraska.NebraskaServer.NebraskaHandler):
  """Subclass NebraskaHandler to facilitate testing.

  Because of the complexity of the socket handling super class init functions,
  the easiest way to test NebraskaHandler is to just subclass it and mock
  whatever we need from its super classes.
  """
  # pylint: disable=super-init-not-called
  def __init__(self):
    self.headers = mock.MagicMock()
    self.send_response = mock.MagicMock()
    self.send_error = mock.MagicMock()
    self.send_header = mock.MagicMock()
    self.end_headers = mock.MagicMock()
    self.rfile = mock.MagicMock()
    self.wfile = mock.MagicMock()
    self.server = mock.MagicMock()
    self.server.owner = nebraska.NebraskaServer(nebraska.Nebraska(
        _PAYLOAD_ADDRESS, _PAYLOAD_ADDRESS))


class NebraskaTest(unittest.TestCase):
  """Test Nebraska."""

  def testDefaultInstallPayloadsAddress(self):
    """Tests the default install_payloads_address is correctly set."""
    update_addr = 'foo/update/'
    install_addr = 'foo/install/'
    # pylint: disable=protected-access
    n = nebraska.Nebraska(update_addr, install_addr)
    self.assertEqual(n._install_payloads_address, install_addr)

    n = nebraska.Nebraska(update_addr)
    self.assertEqual(n._install_payloads_address, update_addr)

class NebraskaHandlerTest(unittest.TestCase):
  """Test NebraskaHandler."""

  def testDoPostSuccess(self):
    """Tests do_POST success."""
    nebraska_handler = MockNebraskaHandler()
    test_response = "foobar"

    with mock.patch('nebraska.Response') as response_mock:
      response_instance = response_mock.return_value
      response_instance.GetXMLString.return_value = test_response
      nebraska_handler.do_POST()

    nebraska_handler.send_response.assert_called_once_with(200)
    nebraska_handler.send_header.assert_called_once()
    nebraska_handler.end_headers.assert_called_once()
    nebraska_handler.wfile.write.assert_called_once_with(test_response)

  def testDoPostInvalidRequest(self):
    """Test do_POST invalid request."""

    nebraska_handler = MockNebraskaHandler()

    with mock.patch('nebraska.Response') as response_mock:
      response_mock.side_effect = ValueError

      nebraska_handler.do_POST()

      nebraska_handler.send_error.assert_called_once_with(
          500, "Failed to handle incoming request")

  def testDoPostInvalidResponse(self):
    """Tests do_POST invalid response handling."""

    nebraska_handler = MockNebraskaHandler()

    with mock.patch('nebraska.traceback') as traceback_mock:
      with mock.patch('nebraska.Response') as response_mock:
        response_instance = response_mock.return_value
        response_instance.GetXMLString.side_effect = Exception
        nebraska_handler.do_POST()
        traceback_mock.print_exc.assert_called_once()
        nebraska_handler.send_error.assert_called_once_with(
            500, "Failed to handle incoming request")

class NebraskaServerTest(unittest.TestCase):
  """Test NebraskaServer."""

  def testStart(self):
    """Tests Start."""
    nebraska_instance = nebraska.Nebraska(_PAYLOAD_ADDRESS, _PAYLOAD_ADDRESS)
    server = nebraska.NebraskaServer(nebraska_instance, _NEBRASKA_PORT)

    with mock.patch('nebraska.HTTPServer') as server_mock:
      with mock.patch('nebraska.threading.Thread') as thread_mock:
        server.Start()

        server_mock.assert_called_once_with(
            ('', _NEBRASKA_PORT), nebraska.NebraskaServer.NebraskaHandler)

        # pylint: disable=protected-access
        thread_mock.assert_has_calls((
            mock.call(target=server._httpd.serve_forever),
            mock.call().start()))

  def testStop(self):
    """Tests Stop."""
    nebraska_instance = nebraska.Nebraska(
        _PAYLOAD_ADDRESS, _PAYLOAD_ADDRESS)
    server = nebraska.NebraskaServer(nebraska_instance, _NEBRASKA_PORT)

    # pylint: disable=protected-access
    server._httpd = mock.MagicMock(name="_httpd")
    server._server_thread = mock.MagicMock(name="_server_thread")
    server.Stop()
    # pylint: disable=protected-access
    server._httpd.shutdown.assert_called_once_with()
    server._server_thread.join.assert_called_once_with()


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