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

"""
Unit tests for the contents of shared_prefs.py (mostly SharedPrefs).
"""

import logging
import unittest

from devil import devil_env
from devil.android import device_utils
from devil.android.sdk import shared_prefs
from devil.android.sdk import version_codes

with devil_env.SysPath(devil_env.PYMOCK_PATH):
  import mock  # pylint: disable=import-error


def MockDeviceWithFiles(files=None):
  if files is None:
    files = {}

  def file_exists(path):
    return path in files

  def write_file(path, contents, **_kwargs):
    files[path] = contents

  def read_file(path, **_kwargs):
    return files[path]

  device = mock.MagicMock(spec=device_utils.DeviceUtils)
  device.FileExists = mock.Mock(side_effect=file_exists)
  device.WriteFile = mock.Mock(side_effect=write_file)
  device.ReadFile = mock.Mock(side_effect=read_file)
  return device


class SharedPrefsTest(unittest.TestCase):

  def setUp(self):
    self.device = MockDeviceWithFiles({
      '/data/data/com.some.package/shared_prefs/prefs.xml':
          "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
          '<map>\n'
          '  <int name="databaseVersion" value="107" />\n'
          '  <boolean name="featureEnabled" value="false" />\n'
          '  <string name="someHashValue">249b3e5af13d4db2</string>\n'
          '</map>'})
    self.expected_data = {'databaseVersion': 107,
                          'featureEnabled': False,
                          'someHashValue': '249b3e5af13d4db2'}

  def testPropertyLifetime(self):
    prefs = shared_prefs.SharedPrefs(
        self.device, 'com.some.package', 'prefs.xml')
    self.assertEquals(len(prefs), 0)  # collection is empty before loading
    prefs.SetInt('myValue', 444)
    self.assertEquals(len(prefs), 1)
    self.assertEquals(prefs.GetInt('myValue'), 444)
    self.assertTrue(prefs.HasProperty('myValue'))
    prefs.Remove('myValue')
    self.assertEquals(len(prefs), 0)
    self.assertFalse(prefs.HasProperty('myValue'))
    with self.assertRaises(KeyError):
      prefs.GetInt('myValue')

  def testPropertyType(self):
    prefs = shared_prefs.SharedPrefs(
        self.device, 'com.some.package', 'prefs.xml')
    prefs.SetInt('myValue', 444)
    self.assertEquals(prefs.PropertyType('myValue'), 'int')
    with self.assertRaises(TypeError):
      prefs.GetString('myValue')
    with self.assertRaises(TypeError):
      prefs.SetString('myValue', 'hello')

  def testLoad(self):
    prefs = shared_prefs.SharedPrefs(
        self.device, 'com.some.package', 'prefs.xml')
    self.assertEquals(len(prefs), 0)  # collection is empty before loading
    prefs.Load()
    self.assertEquals(len(prefs), len(self.expected_data))
    self.assertEquals(prefs.AsDict(), self.expected_data)
    self.assertFalse(prefs.changed)

  def testClear(self):
    prefs = shared_prefs.SharedPrefs(
        self.device, 'com.some.package', 'prefs.xml')
    prefs.Load()
    self.assertEquals(prefs.AsDict(), self.expected_data)
    self.assertFalse(prefs.changed)
    prefs.Clear()
    self.assertEquals(len(prefs), 0)  # collection is empty now
    self.assertTrue(prefs.changed)

  def testCommit(self):
    type(self.device).build_version_sdk = mock.PropertyMock(
        return_value=version_codes.LOLLIPOP_MR1)
    prefs = shared_prefs.SharedPrefs(
        self.device, 'com.some.package', 'other_prefs.xml')
    self.assertFalse(self.device.FileExists(prefs.path))  # file does not exist
    prefs.Load()
    self.assertEquals(len(prefs), 0)  # file did not exist, collection is empty
    prefs.SetInt('magicNumber', 42)
    prefs.SetFloat('myMetric', 3.14)
    prefs.SetLong('bigNumner', 6000000000)
    prefs.SetStringSet('apps', ['gmail', 'chrome', 'music'])
    self.assertFalse(self.device.FileExists(prefs.path))  # still does not exist
    self.assertTrue(prefs.changed)
    prefs.Commit()
    self.assertTrue(self.device.FileExists(prefs.path))  # should exist now
    self.device.KillAll.assert_called_once_with(prefs.package, exact=True,
                                                as_root=True, quiet=True)
    self.assertFalse(prefs.changed)

    prefs = shared_prefs.SharedPrefs(
        self.device, 'com.some.package', 'other_prefs.xml')
    self.assertEquals(len(prefs), 0)  # collection is empty before loading
    prefs.Load()
    self.assertEquals(prefs.AsDict(), {
        'magicNumber': 42,
        'myMetric': 3.14,
        'bigNumner': 6000000000,
        'apps': ['gmail', 'chrome', 'music']})  # data survived roundtrip

  def testAsContextManager_onlyReads(self):
    with shared_prefs.SharedPrefs(
        self.device, 'com.some.package', 'prefs.xml') as prefs:
      self.assertEquals(prefs.AsDict(), self.expected_data)  # loaded and ready
    self.assertEquals(self.device.WriteFile.call_args_list, [])  # did not write

  def testAsContextManager_readAndWrite(self):
    type(self.device).build_version_sdk = mock.PropertyMock(
        return_value=version_codes.LOLLIPOP_MR1)
    with shared_prefs.SharedPrefs(
        self.device, 'com.some.package', 'prefs.xml') as prefs:
      prefs.SetBoolean('featureEnabled', True)
      prefs.Remove('someHashValue')
      prefs.SetString('newString', 'hello')

    self.assertTrue(self.device.WriteFile.called)  # did write
    with shared_prefs.SharedPrefs(
        self.device, 'com.some.package', 'prefs.xml') as prefs:
      # changes persisted
      self.assertTrue(prefs.GetBoolean('featureEnabled'))
      self.assertFalse(prefs.HasProperty('someHashValue'))
      self.assertEquals(prefs.GetString('newString'), 'hello')
      self.assertTrue(prefs.HasProperty('databaseVersion'))  # still there

  def testAsContextManager_commitAborted(self):
    with self.assertRaises(TypeError):
      with shared_prefs.SharedPrefs(
          self.device, 'com.some.package', 'prefs.xml') as prefs:
        prefs.SetBoolean('featureEnabled', True)
        prefs.Remove('someHashValue')
        prefs.SetString('newString', 'hello')
        prefs.SetInt('newString', 123)  # oops!

    self.assertEquals(self.device.WriteFile.call_args_list, [])  # did not write
    with shared_prefs.SharedPrefs(
        self.device, 'com.some.package', 'prefs.xml') as prefs:
      # contents were not modified
      self.assertEquals(prefs.AsDict(), self.expected_data)

if __name__ == '__main__':
  logging.getLogger().setLevel(logging.DEBUG)
  unittest.main(verbosity=2)
