# Lint as: python2, python3
# Copyright 2015 The Bazel Authors. 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 stubify_application_manifest."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import unittest
from xml.etree import ElementTree

# Do not edit this line. Copybara replaces it with PY2 migration helper.
import six

from tools.android.stubify_manifest import ANDROID
from tools.android.stubify_manifest import BadManifestException
from tools.android.stubify_manifest import INSTANT_RUN_BOOTSTRAP_APPLICATION
from tools.android.stubify_manifest import MOBILE_INSTALL_STUB_APPLICATION
from tools.android.stubify_manifest import READ_EXTERNAL_STORAGE
from tools.android.stubify_manifest import StubifyInstantRun
from tools.android.stubify_manifest import StubifyMobileInstall


MANIFEST_WITH_APPLICATION = """
<manifest
  xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.google.package">
  <application android:name="old.application">
  </application>
</manifest>
"""

MANIFEST_WITH_HASCODE = """
<manifest
  xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.google.package">
  <application android:name="old.application" android:hasCode="false">
  </application>
</manifest>
"""

MANIFEST_WITHOUT_APPLICATION = """
<manifest
  xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.google.package">
</manifest>
"""

MANIFEST_WITH_PERMISSION = """
<manifest
  xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.google.package">
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
</manifest>
"""

BAD_MANIFEST = """
<b>Hello World!</b>
"""

MULTIPLE_APPLICATIONS = """
<manifest
  xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.google.package">
  <application android:name="old.application">
  </application>
  <application android:name="old.application">
  </application>
</manifest>
"""


NO_PACKAGE_MANIFEST = """
<manifest
  xmlns:android="http://schemas.android.com/apk/res/android">
  <application android:name="old.application">
  </application>
</manifest>
"""


class StubifyMobileInstallTest(unittest.TestCase):

  def GetApplication(self, manifest_string):
    manifest = ElementTree.fromstring(manifest_string)
    application = manifest.find("application")
    return application.get("{%s}name" % ANDROID)

  def testReplacesOldApplication(self):
    new_manifest, old_application, app_pkg = StubifyMobileInstall(
        MANIFEST_WITH_APPLICATION)
    self.assertEqual("com.google.package", app_pkg)
    self.assertEqual("old.application", old_application)
    self.assertEqual(
        MOBILE_INSTALL_STUB_APPLICATION, self.GetApplication(new_manifest))

  def testAddsNewAplication(self):
    new_manifest, old_application, app_pkg = (
        StubifyMobileInstall(MANIFEST_WITHOUT_APPLICATION))
    self.assertEqual("com.google.package", app_pkg)
    self.assertEqual("android.app.Application", old_application)
    self.assertEqual(
        MOBILE_INSTALL_STUB_APPLICATION, self.GetApplication(new_manifest))

  def testRemovesHasCode(self):
    new_manifest, _, _ = StubifyMobileInstall(MANIFEST_WITH_HASCODE)
    application = ElementTree.fromstring(
        six.ensure_str(new_manifest)).find("application")
    self.assertFalse(("{%s}hasCode" % ANDROID) in application.attrib)

  def assertHasPermission(self, manifest_string, permission):
    manifest = ElementTree.fromstring(manifest_string)
    nodes = manifest.findall(
        'uses-permission[@android:name="%s"]' % permission,
        namespaces={"android": ANDROID})
    self.assertEqual(1, len(nodes))

  def testAddsPermission(self):
    self.assertHasPermission(
        StubifyMobileInstall(
            MANIFEST_WITH_APPLICATION)[0], READ_EXTERNAL_STORAGE)

  def testDoesNotDuplicatePermission(self):
    self.assertHasPermission(
        StubifyMobileInstall(
            MANIFEST_WITH_PERMISSION)[0], READ_EXTERNAL_STORAGE)

  def testBadManifest(self):
    with self.assertRaises(BadManifestException):
      StubifyMobileInstall(BAD_MANIFEST)

  def testTooManyApplications(self):
    with self.assertRaises(BadManifestException):
      StubifyMobileInstall(MULTIPLE_APPLICATIONS)

  def testNoPackageInManifest(self):
    with self.assertRaises(BadManifestException):
      StubifyMobileInstall(NO_PACKAGE_MANIFEST)


class StubifyInstantRunTest(unittest.TestCase):

  def testReplacesOldApplication(self):
    new_manifest = StubifyInstantRun(MANIFEST_WITH_APPLICATION)
    manifest = ElementTree.fromstring(new_manifest)
    application = manifest.find("application")
    self.assertEqual(INSTANT_RUN_BOOTSTRAP_APPLICATION,
                     application.get("{%s}name" % ANDROID))
    self.assertEqual("old.application", application.get("name"))

  def testReplacesAndSavesOldApplication(self):
    new_manifest = StubifyInstantRun(MANIFEST_WITHOUT_APPLICATION)
    manifest = ElementTree.fromstring(new_manifest)
    application = manifest.find("application")
    self.assertEqual(INSTANT_RUN_BOOTSTRAP_APPLICATION,
                     application.get("{%s}name" % ANDROID))
    self.assertEqual(None, application.get("name"))


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