// Copyright (c) 2012 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.

#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "chrome/browser/extensions/api/permissions/permissions_api_helpers.h"
#include "chrome/common/extensions/api/permissions.h"
#include "chrome/common/extensions/permissions/permission_set.h"
#include "extensions/common/url_pattern_set.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

using extensions::api::permissions::Permissions;
using extensions::permissions_api_helpers::PackPermissionSet;
using extensions::permissions_api_helpers::UnpackPermissionSet;

namespace extensions {

namespace {

static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
  int schemes = URLPattern::SCHEME_ALL;
  extent->AddPattern(URLPattern(schemes, pattern));
}

}  // namespace

// Tests that we can convert PermissionSets to and from values.
TEST(ExtensionPermissionsAPIHelpers, Pack) {
  APIPermissionSet apis;
  apis.insert(APIPermission::kTab);
  apis.insert(APIPermission::kWebRequest);
  // Note: kWebRequest implies also kWebRequestInternal.
  URLPatternSet hosts;
  AddPattern(&hosts, "http://a.com/*");
  AddPattern(&hosts, "http://b.com/*");

  scoped_refptr<PermissionSet> permission_set =
      new PermissionSet(apis, hosts, URLPatternSet());

  // Pack the permission set to value and verify its contents.
  scoped_ptr<Permissions> permissions(PackPermissionSet(permission_set.get()));
  scoped_ptr<base::DictionaryValue> value(permissions->ToValue());
  base::ListValue* api_list = NULL;
  base::ListValue* origin_list = NULL;
  EXPECT_TRUE(value->GetList("permissions", &api_list));
  EXPECT_TRUE(value->GetList("origins", &origin_list));

  EXPECT_EQ(3u, api_list->GetSize());
  EXPECT_EQ(2u, origin_list->GetSize());

  std::string expected_apis[] = { "tabs", "webRequest" };
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(expected_apis); ++i) {
    scoped_ptr<Value> value(new base::StringValue(expected_apis[i]));
    EXPECT_NE(api_list->end(), api_list->Find(*value));
  }

  std::string expected_origins[] = { "http://a.com/*", "http://b.com/*" };
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(expected_origins); ++i) {
    scoped_ptr<Value> value(new base::StringValue(expected_origins[i]));
    EXPECT_NE(origin_list->end(), origin_list->Find(*value));
  }

  // Unpack the value back to a permission set and make sure its equal to the
  // original one.
  scoped_refptr<PermissionSet> from_value;
  std::string error;
  Permissions permissions_object;
  EXPECT_TRUE(Permissions::Populate(*value, &permissions_object));
  from_value = UnpackPermissionSet(permissions_object, true, &error);
  EXPECT_TRUE(error.empty());

  EXPECT_EQ(*permission_set.get(), *from_value.get());
}

// Tests various error conditions and edge cases when unpacking values
// into PermissionSets.
TEST(ExtensionPermissionsAPIHelpers, Unpack) {
  scoped_ptr<base::ListValue> apis(new base::ListValue());
  apis->Append(new base::StringValue("tabs"));
  scoped_ptr<base::ListValue> origins(new base::ListValue());
  origins->Append(new base::StringValue("http://a.com/*"));

  scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
  scoped_refptr<PermissionSet> permissions;
  std::string error;

  // Origins shouldn't have to be present.
  {
    Permissions permissions_object;
    value->Set("permissions", apis->DeepCopy());
    EXPECT_TRUE(Permissions::Populate(*value, &permissions_object));
    permissions = UnpackPermissionSet(permissions_object, true, &error);
    EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kTab));
    EXPECT_TRUE(permissions.get());
    EXPECT_TRUE(error.empty());
  }

  // The api permissions don't need to be present either.
  {
    Permissions permissions_object;
    value->Clear();
    value->Set("origins", origins->DeepCopy());
    EXPECT_TRUE(Permissions::Populate(*value, &permissions_object));
    permissions = UnpackPermissionSet(permissions_object, true, &error);
    EXPECT_TRUE(permissions.get());
    EXPECT_TRUE(error.empty());
    EXPECT_TRUE(permissions->HasExplicitAccessToOrigin(GURL("http://a.com/")));
  }

  // Throw errors for non-string API permissions.
  {
    Permissions permissions_object;
    value->Clear();
    scoped_ptr<base::ListValue> invalid_apis(apis->DeepCopy());
    invalid_apis->Append(new base::FundamentalValue(3));
    value->Set("permissions", invalid_apis->DeepCopy());
    EXPECT_FALSE(Permissions::Populate(*value, &permissions_object));
  }

  // Throw errors for non-string origins.
  {
    Permissions permissions_object;
    value->Clear();
    scoped_ptr<base::ListValue> invalid_origins(origins->DeepCopy());
    invalid_origins->Append(new base::FundamentalValue(3));
    value->Set("origins", invalid_origins->DeepCopy());
    EXPECT_FALSE(Permissions::Populate(*value, &permissions_object));
  }

  // Throw errors when "origins" or "permissions" are not list values.
  {
    Permissions permissions_object;
    value->Clear();
    value->Set("origins", new base::FundamentalValue(2));
    EXPECT_FALSE(Permissions::Populate(*value, &permissions_object));
  }

  {
    Permissions permissions_object;
    value->Clear();
    value->Set("permissions", new base::FundamentalValue(2));
    EXPECT_FALSE(Permissions::Populate(*value, &permissions_object));
  }

  // Additional fields should be allowed.
  {
    Permissions permissions_object;
    value->Clear();
    value->Set("origins", origins->DeepCopy());
    value->Set("random", new base::FundamentalValue(3));
    EXPECT_TRUE(Permissions::Populate(*value, &permissions_object));
    permissions = UnpackPermissionSet(permissions_object, true, &error);
    EXPECT_TRUE(permissions.get());
    EXPECT_TRUE(error.empty());
    EXPECT_TRUE(permissions->HasExplicitAccessToOrigin(GURL("http://a.com/")));
  }

  // Unknown permissions should throw an error.
  {
    Permissions permissions_object;
    value->Clear();
    scoped_ptr<base::ListValue> invalid_apis(apis->DeepCopy());
    invalid_apis->Append(new base::StringValue("unknown_permission"));
    value->Set("permissions", invalid_apis->DeepCopy());
    EXPECT_TRUE(Permissions::Populate(*value, &permissions_object));
    permissions = UnpackPermissionSet(permissions_object, true, &error);
    EXPECT_FALSE(permissions.get());
    EXPECT_FALSE(error.empty());
    EXPECT_EQ(error, "'unknown_permission' is not a recognized permission.");
  }
}

}  // namespace extensions
