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

import copy
import feature_compiler
import unittest

class FeatureCompilerTest(unittest.TestCase):
  """Test the FeatureCompiler. Note that we test that the expected features are
  generated more thoroughly in features_generation_unittest.cc. And, of course,
  this is most exhaustively tested through Chrome's compilation process (if a
  feature fails to parse, the compile fails).
  These tests primarily focus on catching errors during parsing.
  """
  def _parseFeature(self, value):
    """Parses a feature from the given value and returns the result."""
    f = feature_compiler.Feature('alpha')
    f.Parse(value, {})
    return f

  def _createTestFeatureCompiler(self, feature_class):
    return feature_compiler.FeatureCompiler('chrome_root', [], feature_class,
        'provider_class', 'out_root', 'gen', 'out_base_filename')

  def _hasError(self, f, error):
    """Asserts that |error| is present somewhere in the given feature's
    errors."""
    errors = f.GetErrors()
    self.assertTrue(errors)
    self.assertNotEqual(-1, str(errors).find(error), str(errors))

  def setUp(self):
    feature_compiler.ENABLE_ASSERTIONS = False

  def testFeature(self):
    # Test some basic feature parsing for a sanity check.
    f = self._parseFeature({
      'blocklist': [
        'ABCDEF0123456789ABCDEF0123456789ABCDEF01',
        '10FEDCBA9876543210FEDCBA9876543210FEDCBA'
      ],
      'channel': 'stable',
      'command_line_switch': 'switch',
      'component_extensions_auto_granted': False,
      'contexts': [
        'blessed_extension',
        'blessed_web_page',
        'lock_screen_extension'
      ],
      'default_parent': True,
      'dependencies': ['dependency1', 'dependency2'],
      'developer_mode_only': True,
      'disallow_for_service_workers': True,
      'extension_types': ['extension'],
      'location': 'component',
      'internal': True,
      'matches': ['*://*/*'],
      'max_manifest_version': 1,
      'noparent': True,
      'platforms': ['mac', 'win'],
      'session_types': ['kiosk', 'regular'],
      'allowlist': [
        '0123456789ABCDEF0123456789ABCDEF01234567',
        '76543210FEDCBA9876543210FEDCBA9876543210'
      ]
    })
    self.assertFalse(f.GetErrors())

  def testInvalidAll(self):
    f = self._parseFeature({
      'channel': 'stable',
      'dependencies': 'all',
    })
    self._hasError(f, 'Illegal value: "all"')

  def testUnknownKeyError(self):
    f = self._parseFeature({
      'contexts': ['blessed_extension'],
      'channel': 'stable',
      'unknownkey': 'unknownvalue'
    })
    self._hasError(f, 'Unrecognized key')

  def testUnknownEnumValue(self):
    f = self._parseFeature({
      'contexts': ['blessed_extension', 'unknown_context'],
      'channel': 'stable'
    })
    self._hasError(f, 'Illegal value: "unknown_context"')

  def testImproperType(self):
    f = self._parseFeature({'min_manifest_version': '1'})
    self._hasError(f, 'Illegal value: "1"')

  def testImproperSubType(self):
    f = self._parseFeature({'dependencies': [1, 2, 3]})
    self._hasError(f, 'Illegal value: "1"')

  def testImproperValue(self):
    f = self._parseFeature({'noparent': False})
    self._hasError(f, 'Illegal value: "False"')

  def testEmptyList(self):
    f = self._parseFeature({'extension_types': []})
    self._hasError(f, 'List must specify at least one element.')

  def testEmptyListWithAllowEmpty(self):
    # `dependencies` is the only key that allows an empty list.
    f = self._parseFeature({'dependencies': []})
    self.assertFalse(f.GetErrors())

  def testApiFeaturesNeedContexts(self):
    f = self._parseFeature({'extension_types': ['extension'],
                            'channel': 'trunk'})
    f.Validate('APIFeature', {})
    self._hasError(f, 'APIFeatures must specify the contexts property')

  def testAPIFeaturesCanSpecifyEmptyContexts(self):
    f = self._parseFeature({'extension_types': ['extension'],
                            'channel': 'trunk',
                            'contexts': []})
    f.Validate('APIFeature', {})
    self.assertFalse(f.GetErrors())

  def testManifestFeaturesNeedExtensionTypes(self):
    f = self._parseFeature({'dependencies': 'alpha', 'channel': 'beta'})
    f.Validate('ManifestFeature', {})
    self._hasError(f,
                   'ManifestFeatures must specify at least one extension type')

  def testManifestFeaturesCantHaveContexts(self):
    f = self._parseFeature({'dependencies': 'alpha',
                            'channel': 'beta',
                            'extension_types': ['extension'],
                            'contexts': ['blessed_extension']})
    f.Validate('ManifestFeature', {})
    self._hasError(f, 'ManifestFeatures do not support contexts')

  def testPermissionFeaturesNeedExtensionTypes(self):
    f = self._parseFeature({'dependencies': 'alpha', 'channel': 'beta'})
    f.Validate('PermissionFeature', {})
    self._hasError(
        f, 'PermissionFeatures must specify at least one extension type')

  def testPermissionFeaturesCantHaveContexts(self):
    f = self._parseFeature({'dependencies': 'alpha',
                            'channel': 'beta',
                            'extension_types': ['extension'],
                            'contexts': ['blessed_extension']})
    f.Validate('PermissionFeature', {})
    self._hasError(f, 'PermissionFeatures do not support contexts')

  def testAllPermissionsNeedChannelOrDependencies(self):
    api_feature = self._parseFeature({'contexts': ['blessed_extension']})
    api_feature.Validate('APIFeature', {})
    self._hasError(
        api_feature, 'Features must specify either a channel or dependencies')
    permission_feature = self._parseFeature({'extension_types': ['extension']})
    permission_feature.Validate('PermissionFeature', {})
    self._hasError(permission_feature,
                   'Features must specify either a channel or dependencies')
    manifest_feature = self._parseFeature({'extension_types': ['extension']})
    manifest_feature.Validate('ManifestFeature', {})
    self._hasError(manifest_feature,
                   'Features must specify either a channel or dependencies')
    channel_feature = self._parseFeature({'contexts': ['blessed_extension'],
                                          'channel': 'trunk'})
    channel_feature.Validate('APIFeature', {})
    self.assertFalse(channel_feature.GetErrors())
    dependency_feature = self._parseFeature(
                             {'contexts': ['blessed_extension'],
                              'dependencies': ['alpha']})
    dependency_feature.Validate('APIFeature', {})
    self.assertFalse(dependency_feature.GetErrors())

  def testBothAliasAndSource(self):
    compiler = self._createTestFeatureCompiler('APIFeature')
    compiler._json = {
      'feature_alpha': {
        'channel': 'beta',
        'contexts': ['blessed_extension'],
        'alias': 'feature_alpha',
        'source': 'feature_alpha'
      }
    }
    compiler.Compile()

    feature = compiler._features.get('feature_alpha')
    self.assertTrue(feature)
    self._hasError(feature, 'Features cannot specify both alias and source.')

  def testAliasOnNonApiFeature(self):
    compiler = self._createTestFeatureCompiler('PermissionFeature')
    compiler._json = {
      'feature_alpha': {
        'channel': 'beta',
        'contexts': ['blessed_extension'],
        'alias': 'feature_beta'
      },
      'feature_beta': [{
        'channel': 'beta',
        'contexts': ['blessed_extension'],
        'source': 'feature_alpha'
      },{
        'channel': 'dev',
        'context': ['blessed_extension']
      }]
    };
    compiler.Compile()

    feature = compiler._features.get('feature_alpha')
    self.assertTrue(feature)
    self._hasError(feature, 'PermissionFeatures do not support alias.')

    feature = compiler._features.get('feature_beta')
    self.assertTrue(feature)
    self._hasError(feature, 'PermissionFeatures do not support source.')

  def testAliasFeature(self):
    compiler = self._createTestFeatureCompiler('APIFeature')
    compiler._json = {
      'feature_alpha': {
        'channel': 'beta',
        'contexts': ['blessed_extension'],
        'alias': 'feature_beta'
      },
      'feature_beta': {
        'channel': 'beta',
        'contexts': ['blessed_extension'],
        'source': 'feature_alpha'
      }
    };
    compiler.Compile()

    feature = compiler._features.get('feature_alpha')
    self.assertTrue(feature)
    self.assertFalse(feature.GetErrors())

    feature = compiler._features.get('feature_beta')
    self.assertTrue(feature)
    self.assertFalse(feature.GetErrors())

  def testMultipleAliasesInComplexFeature(self):
    compiler = self._createTestFeatureCompiler('APIFeature')
    compiler._json = {
      'feature_alpha': [{
        'channel': 'beta',
        'contexts': ['blessed_extension'],
        'alias': 'feature_beta'
      }, {
        'contexts': ['blessed_extension'],
        'channel': 'beta',
        'alias': 'feature_beta'
      }]
    };
    compiler.Compile()

    feature = compiler._features.get('feature_alpha')
    self.assertTrue(feature)
    self._hasError(feature, 'Error parsing feature "feature_alpha" at key ' +
                            '"alias": Key can be set at most once per feature.')

  def testAliasReferenceInComplexFeature(self):
    compiler = self._createTestFeatureCompiler('APIFeature')
    compiler._json = {
      'feature_alpha': [{
        'channel': 'beta',
        'contexts': ['blessed_extension'],
        'alias': 'feature_beta'
      }, {
        'contexts': ['blessed_extension'],
        'channel': 'beta',
      }],
      'feature_beta': {
        'channel': 'beta',
        'contexts': ['blessed_extension'],
        'source': 'feature_alpha'
      }
    };
    compiler.Compile()

    feature = compiler._features.get('feature_alpha')
    self.assertTrue(feature)
    self.assertFalse(feature.GetErrors())

    feature = compiler._features.get('feature_beta')
    self.assertTrue(feature)
    self.assertFalse(feature.GetErrors())

  def testSourceMissingReference(self):
    compiler = self._createTestFeatureCompiler('APIFeature')
    compiler._json = {
      'feature_alpha': {
        'channel': 'beta',
        'contexts': ['blessed_extension'],
        'alias': 'feature_beta'
      },
      'feature_beta': {
        'contexts': ['blessed_extension'],
        'channel': 'beta',
        'source': 'does_not_exist'
      }
    };
    compiler.Compile()

    feature = compiler._features.get('feature_beta')
    self.assertTrue(feature)
    self._hasError(feature, 'A feature source property should reference a ' +
                            'feature whose alias property references it back.')


  def testAliasMissingReferenceInComplexFeature(self):
    compiler = self._createTestFeatureCompiler('APIFeature')
    compiler._json = {
      'feature_alpha': [{
        'channel': 'beta',
        'contexts': ['blessed_extension'],
        'alias': 'feature_beta'
      }, {
        'contexts': ['blessed_extension'],
        'channel': 'beta'
      }]
    };
    compiler.Compile()

    feature = compiler._features.get('feature_alpha')
    self.assertTrue(feature)
    self._hasError(feature, 'A feature alias property should reference a ' +
                            'feature whose source property references it back.')

  def testAliasReferenceMissingSourceInComplexFeature(self):
    compiler = self._createTestFeatureCompiler('APIFeature')
    compiler._json = {
      'feature_alpha': {
        'contexts': ['blessed_extension'],
        'channel': 'beta',
      },
      'feature_beta': {
        'channel': 'beta',
        'contexts': ['blessed_extension'],
        'alias': 'feature_alpha'
      }
    };
    compiler.Compile()

    feature = compiler._features.get('feature_alpha')
    self.assertTrue(feature)
    self.assertFalse(feature.GetErrors())

    feature = compiler._features.get('feature_beta')
    self.assertTrue(feature)
    self._hasError(feature, 'A feature alias property should reference a ' +
                            'feature whose source property references it back.')

  def testComplexParentWithoutDefaultParent(self):
    c = feature_compiler.FeatureCompiler(
        None, None, 'APIFeature', None, None, None, None)
    c._CompileFeature('bookmarks',
        [{
          'contexts': ['blessed_extension'],
        }, {
          'channel': 'stable',
          'contexts': ['webui'],
        }])

    with self.assertRaisesRegex(AssertionError,
                                'No default parent found for bookmarks'):
      c._CompileFeature('bookmarks.export', { "allowlist": ["asdf"] })

  def testRealIdsDisallowedInAllowlist(self):
    fake_id = 'a' * 32;
    f = self._parseFeature({'allowlist': [fake_id],
                            'extension_types': ['extension'],
                            'channel': 'beta'})
    f.Validate('PermissionFeature', {})
    self._hasError(
        f, 'list should only have hex-encoded SHA1 hashes of extension ids')

  def testHostedAppsCantUseAllowlistedFeatures_SimpleFeature(self):
    f = self._parseFeature({
        'extension_types': ['extension', 'hosted_app'],
        'allowlist': ['0123456789ABCDEF0123456789ABCDEF01234567'],
        'channel': 'beta',
    })
    f.Validate('PermissionFeature', {})
    self._hasError(f, 'Hosted apps are not allowed to use restricted features')

  def testHostedAppsCantUseAllowlistedFeatures_ComplexFeature(self):
    c = feature_compiler.FeatureCompiler(
        None, None, 'PermissionFeature', None, None, None, None)
    c._CompileFeature('invalid_feature',
        [{
          'extension_types': ['extension'],
          'channel': 'beta',
        }, {
          'channel': 'beta',
          'extension_types': ['hosted_app'],
          'allowlist': ['0123456789ABCDEF0123456789ABCDEF01234567'],
        }])
    c._CompileFeature('valid_feature',
        [{
          'extension_types': ['extension'],
          'channel': 'beta',
          'allowlist': ['0123456789ABCDEF0123456789ABCDEF01234567'],
        }, {
          'channel': 'beta',
          'extension_types': ['hosted_app'],
        }])

    valid_feature = c._features.get('valid_feature')
    self.assertTrue(valid_feature)
    self.assertFalse(valid_feature.GetErrors())

    invalid_feature = c._features.get('invalid_feature')
    self.assertTrue(invalid_feature)
    self._hasError(invalid_feature,
                   'Hosted apps are not allowed to use restricted features')


  def testHostedAppsCantUseAllowlistedFeatures_ChildFeature(self):
    c = feature_compiler.FeatureCompiler(
        None, None, 'PermissionFeature', None, None, None, None)
    c._CompileFeature('parent',
        {
          'extension_types': ['hosted_app'],
          'channel': 'beta',
        })

    c._CompileFeature('parent.child',
        {
          'allowlist': ['0123456789ABCDEF0123456789ABCDEF01234567']
        })
    feature = c._features.get('parent.child')
    self.assertTrue(feature)
    self._hasError(feature,
                   'Hosted apps are not allowed to use restricted features')

  def testEmptyContextsDisallowed(self):
    compiler = self._createTestFeatureCompiler('APIFeature')
    compiler._json = {
      'feature_alpha': {
        'channel': 'beta',
        'contexts': [],
        'extension_types': ['extension']
      }
    }
    compiler.Compile()

    feature = compiler._features.get('feature_alpha')
    self.assertTrue(feature)
    self._hasError(feature,
        'An empty contexts list is not allowed for this feature.')

  def testEmptyContextsAllowed(self):
    compiler = self._createTestFeatureCompiler('APIFeature')
    compiler._json = {
      'empty_contexts': {
        'channel': 'beta',
        'contexts': [],
        'extension_types': ['extension']
      }
    }
    compiler.Compile()

    feature = compiler._features.get('empty_contexts')
    self.assertTrue(feature)
    self.assertFalse(feature.GetErrors())

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