# Copyright 2019 Google Inc.
#
# 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.

import os

import mock
from future.tests.base import unittest

from mobly.controllers import android_device
from mobly.controllers.android_device_lib import jsonrpc_shell_base


class JsonRpcClientBaseTest(unittest.TestCase):
  """Unit tests for mobly.controllers.android_device_lib.jsonrpc_shell_base.
  """

  @mock.patch.object(android_device, 'list_adb_devices')
  @mock.patch.object(android_device, 'get_instances')
  @mock.patch.object(os, 'environ', new={})
  def test_load_device(self, mock_get_instances, mock_list_adb_devices):
    mock_list_adb_devices.return_value = ['1234', '4312']
    mock_device = mock.MagicMock(spec=android_device.AndroidDevice)
    mock_get_instances.return_value = [mock_device]
    json_shell = jsonrpc_shell_base.JsonRpcShellBase()
    json_shell.load_device(serial='1234')
    self.assertEqual(json_shell._ad, mock_device)

  @mock.patch.object(android_device, 'list_adb_devices')
  @mock.patch.object(android_device, 'get_instances')
  @mock.patch.object(os, 'environ', new={})
  def test_load_device_when_one_device(self, mock_get_instances,
                                       mock_list_adb_devices):
    mock_list_adb_devices.return_value = ['1234']
    mock_device = mock.MagicMock(spec=android_device.AndroidDevice)
    mock_get_instances.return_value = [mock_device]
    json_shell = jsonrpc_shell_base.JsonRpcShellBase()
    json_shell.load_device()
    self.assertEqual(json_shell._ad, mock_device)

  @mock.patch.object(android_device, 'list_adb_devices')
  @mock.patch.object(android_device, 'get_instances')
  @mock.patch.object(os, 'environ', new={'ANDROID_SERIAL': '1234'})
  def test_load_device_when_android_serial(self, mock_get_instances,
                                           mock_list_adb_devices):
    mock_list_adb_devices.return_value = ['1234', '4321']
    mock_device = mock.MagicMock(spec=android_device.AndroidDevice)
    mock_get_instances.return_value = [mock_device]
    json_shell = jsonrpc_shell_base.JsonRpcShellBase()
    json_shell.load_device()
    self.assertEqual(json_shell._ad, mock_device)

  @mock.patch.object(android_device, 'list_adb_devices')
  def test_load_device_when_no_devices(self, mock_list_adb_devices):
    mock_list_adb_devices.return_value = []
    json_shell = jsonrpc_shell_base.JsonRpcShellBase()
    with self.assertRaisesRegex(jsonrpc_shell_base.Error,
                                'No adb device found!'):
      json_shell.load_device()

  @mock.patch.object(android_device, 'list_adb_devices')
  @mock.patch.object(os, 'environ', new={})
  def test_load_device_when_unspecified_device(self, mock_list_adb_devices):
    mock_list_adb_devices.return_value = ['1234', '4321']
    json_shell = jsonrpc_shell_base.JsonRpcShellBase()
    with self.assertRaisesRegex(jsonrpc_shell_base.Error,
                                'Expected one phone.*'):
      json_shell.load_device()

  @mock.patch.object(android_device, 'list_adb_devices')
  @mock.patch.object(os, 'environ', new={})
  def test_load_device_when_device_not_found(self, mock_list_adb_devices):
    mock_list_adb_devices.return_value = ['4321']
    json_shell = jsonrpc_shell_base.JsonRpcShellBase()
    with self.assertRaisesRegex(jsonrpc_shell_base.Error,
                                'Device "1234" is not found by adb.'):
      json_shell.load_device(serial='1234')


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