1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/features/base_feature_provider.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <set>
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <string>
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/extension_builder.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/features/feature.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/features/simple_feature.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/manifest.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/value_builder.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace extensions {
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Tests that a real manifest feature is available for the correct types of
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// extensions and apps.
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(BaseFeatureProviderTest, ManifestFeatureTypes) {
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const FeatureProvider* provider = BaseFeatureProvider::GetByName("manifest");
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // NOTE: This feature cannot have multiple rules, otherwise it is not a
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // SimpleFeature.
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SimpleFeature* feature =
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      static_cast<SimpleFeature*>(provider->GetFeature("description"));
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(feature);
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::set<Manifest::Type>* extension_types = feature->extension_types();
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(6u, extension_types->size());
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_EXTENSION));
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_LEGACY_PACKAGED_APP));
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_PLATFORM_APP));
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_HOSTED_APP));
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_THEME));
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_SHARED_MODULE));
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Tests that real manifest features have the correct availability for an
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// extension.
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(BaseFeatureProviderTest, ManifestFeatureAvailability) {
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const FeatureProvider* provider = BaseFeatureProvider::GetByName("manifest");
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<const Extension> extension =
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ExtensionBuilder()
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          .SetManifest(DictionaryBuilder()
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           .Set("name", "test extension")
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           .Set("version", "1")
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           .Set("description", "hello there"))
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          .Build();
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(extension.get());
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Feature* feature = provider->GetFeature("description");
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(Feature::IS_AVAILABLE,
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            feature->IsAvailableToContext(extension.get(),
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                          Feature::UNSPECIFIED_CONTEXT,
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                          GURL()).result());
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // This is a generic extension, so an app-only feature isn't allowed.
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  feature = provider->GetFeature("app.background");
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(feature);
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(Feature::INVALID_TYPE,
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            feature->IsAvailableToContext(extension.get(),
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                          Feature::UNSPECIFIED_CONTEXT,
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                          GURL()).result());
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // A feature not listed in the manifest isn't allowed.
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  feature = provider->GetFeature("background");
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(feature);
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(Feature::NOT_PRESENT,
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            feature->IsAvailableToContext(extension.get(),
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                          Feature::UNSPECIFIED_CONTEXT,
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                          GURL()).result());
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Tests that a real permission feature is available for the correct types of
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// extensions and apps.
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(BaseFeatureProviderTest, PermissionFeatureTypes) {
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const FeatureProvider* provider =
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      BaseFeatureProvider::GetByName("permission");
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // NOTE: This feature cannot have multiple rules, otherwise it is not a
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // SimpleFeature.
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SimpleFeature* feature =
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      static_cast<SimpleFeature*>(provider->GetFeature("power"));
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(feature);
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::set<Manifest::Type>* extension_types = feature->extension_types();
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(3u, extension_types->size());
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_EXTENSION));
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_LEGACY_PACKAGED_APP));
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(1u, extension_types->count(Manifest::TYPE_PLATFORM_APP));
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Tests that real permission features have the correct availability for an app.
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(BaseFeatureProviderTest, PermissionFeatureAvailability) {
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const FeatureProvider* provider =
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      BaseFeatureProvider::GetByName("permission");
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<const Extension> app =
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ExtensionBuilder()
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          .SetManifest(DictionaryBuilder()
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           .Set("name", "test app")
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           .Set("version", "1")
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           .Set("app",
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                DictionaryBuilder().Set(
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                    "background",
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                    DictionaryBuilder().Set(
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                        "scripts",
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                        ListBuilder().Append("background.js"))))
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           .Set("permissions", ListBuilder().Append("power")))
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          .Build();
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(app.get());
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(app->is_platform_app());
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // A permission requested in the manifest is available.
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Feature* feature = provider->GetFeature("power");
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      Feature::IS_AVAILABLE,
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      feature->IsAvailableToContext(
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   app.get(), Feature::UNSPECIFIED_CONTEXT, GURL()).result());
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // A permission only available to whitelisted extensions returns availability
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // NOT_FOUND_IN_WHITELIST.
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  feature = provider->GetFeature("bluetoothPrivate");
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(feature);
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      Feature::NOT_FOUND_IN_WHITELIST,
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      feature->IsAvailableToContext(
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   app.get(), Feature::UNSPECIFIED_CONTEXT, GURL()).result());
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // A permission that isn't part of the manifest returns NOT_PRESENT.
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  feature = provider->GetFeature("serial");
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(feature);
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      Feature::NOT_PRESENT,
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      feature->IsAvailableToContext(
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   app.get(), Feature::UNSPECIFIED_CONTEXT, GURL()).result());
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace extensions
139