# 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."""

import unittest
from xml.etree import ElementTree

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

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(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()
