text:
// 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 "chrome/common/extensions/extension.h"

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/format_macros.h"
#include "base/json/json_file_value_serializer.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/command.h"
#include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/extensions/extension_manifest_constants.h"
#include "chrome/common/extensions/extension_resource.h"
#include "chrome/common/extensions/features/feature.h"
#include "chrome/common/extensions/permissions/api_permission.h"
#include "chrome/common/extensions/permissions/permission_set.h"
#include "chrome/common/extensions/permissions/socket_permission.h"
#include "chrome/common/extensions/permissions/usb_device_permission.h"
#include "chrome/common/url_constants.h"
#include "extensions/common/error_utils.h"
#include "googleurl/src/gurl.h"
#include "net/base/mime_sniffer.h"
#include "net/base/mock_host_resolver.h"
#include "skia/ext/image_operations.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/codec/png_codec.h"

using content::SocketPermissionRequest;
using extensions::APIPermission;
using extensions::APIPermissionSet;
using extensions::ErrorUtils;
using extensions::Extension;
using extensions::Feature;
using extensions::PermissionSet;
using extensions::SocketPermission;
using extensions::URLPatternSet;
using extensions::UsbDevicePermission;

namespace keys = extension_manifest_keys;
namespace values = extension_manifest_values;
namespace errors = extension_manifest_errors;

namespace {

scoped_refptr<Extension> LoadManifestUnchecked(
    const std::string& dir,
    const std::string& test_file,
    Extension::Location location,
    int extra_flags,
    std::string* error) {
  FilePath path;
  PathService::Get(chrome::DIR_TEST_DATA, &path);
  path = path.AppendASCII("extensions")
             .AppendASCII(dir)
             .AppendASCII(test_file);

  JSONFileValueSerializer serializer(path);
  scoped_ptr<Value> result(serializer.Deserialize(NULL, error));
  if (!result.get())
    return NULL;

  scoped_refptr<Extension> extension = Extension::Create(
      path.DirName(), location, *static_cast<DictionaryValue*>(result.get()),
      extra_flags, error);
  return extension;
}

static scoped_refptr<Extension> LoadManifest(const std::string& dir,
                                             const std::string& test_file,
                                             Extension::Location location,
                                             int extra_flags) {
  std::string error;
  scoped_refptr<Extension> extension = LoadManifestUnchecked(dir, test_file,
    location, extra_flags, &error);

  EXPECT_TRUE(extension) << test_file << ":" << error;
  return extension;
}

static scoped_refptr<Extension> LoadManifest(const std::string& dir,
                                             const std::string& test_file,
                                             int extra_flags) {
  return LoadManifest(dir, test_file, Extension::INVALID, extra_flags);
}

static scoped_refptr<Extension> LoadManifest(const std::string& dir,
                                             const std::string& test_file) {
  return LoadManifest(dir, test_file, Extension::NO_FLAGS);
}

static scoped_refptr<Extension> LoadManifestStrict(
    const std::string& dir,
    const std::string& test_file) {
  return LoadManifest(dir, test_file, Extension::NO_FLAGS);
}

static scoped_ptr<Extension::ActionInfo> LoadAction(
    const std::string& manifest) {
  scoped_refptr<Extension> extension = LoadManifest("page_action",
      manifest);
  EXPECT_TRUE(extension->page_action_info());
  if (extension->page_action_info()) {
    return make_scoped_ptr(new Extension::ActionInfo(
        *extension->page_action_info()));
  }
  ADD_FAILURE() << "Expected manifest in " << manifest
                << " to include a page_action section.";
  return scoped_ptr<Extension::ActionInfo>();
}

static void LoadActionAndExpectError(const std::string& manifest,
                                     const std::string& expected_error) {
  std::string error;
  scoped_refptr<Extension> extension = LoadManifestUnchecked("page_action",
      manifest, Extension::INTERNAL, Extension::NO_FLAGS, &error);
  EXPECT_FALSE(extension);
  EXPECT_EQ(expected_error, error);
}

}

class ExtensionTest : public testing::Test {
};

// We persist location values in the preferences, so this is a sanity test that
// someone doesn't accidentally change them.
TEST(ExtensionTest, LocationValuesTest) {
  ASSERT_EQ(0, Extension::INVALID);
  ASSERT_EQ(1, Extension::INTERNAL);
  ASSERT_EQ(2, Extension::EXTERNAL_PREF);
  ASSERT_EQ(3, Extension::EXTERNAL_REGISTRY);
  ASSERT_EQ(4, Extension::LOAD);
  ASSERT_EQ(5, Extension::COMPONENT);
  ASSERT_EQ(6, Extension::EXTERNAL_PREF_DOWNLOAD);
  ASSERT_EQ(7, Extension::EXTERNAL_POLICY_DOWNLOAD);
}

TEST(ExtensionTest, LocationPriorityTest) {
  for (int i = 0; i < Extension::NUM_LOCATIONS; i++) {
    Extension::Location loc = static_cast<Extension::Location>(i);

    // INVALID is not a valid location.
    if (loc == Extension::INVALID)
      continue;

    // Comparing a location that has no rank will hit a CHECK. Do a
    // compare with every valid location, to be sure each one is covered.

    // Check that no install source can override a componenet extension.
    ASSERT_EQ(Extension::COMPONENT,
              Extension::GetHigherPriorityLocation(Extension::COMPONENT, loc));
    ASSERT_EQ(Extension::COMPONENT,
              Extension::GetHigherPriorityLocation(loc, Extension::COMPONENT));

    // Check that any source can override a user install. This might change
    // in the future, in which case this test should be updated.
    ASSERT_EQ(loc,
              Extension::GetHigherPriorityLocation(Extension::INTERNAL, loc));
    ASSERT_EQ(loc,
              Extension::GetHigherPriorityLocation(loc, Extension::INTERNAL));
  }

  // Check a few interesting cases that we know can happen:
  ASSERT_EQ(Extension::EXTERNAL_POLICY_DOWNLOAD,
            Extension::GetHigherPriorityLocation(
                Extension::EXTERNAL_POLICY_DOWNLOAD,
                Extension::EXTERNAL_PREF));

  ASSERT_EQ(Extension::EXTERNAL_PREF,
            Extension::GetHigherPriorityLocation(
                Extension::INTERNAL,
                Extension::EXTERNAL_PREF));
}

TEST(ExtensionTest, GetResourceURLAndPath) {
  scoped_refptr<Extension> extension = LoadManifestStrict("empty_manifest",
      "empty.json");
  EXPECT_TRUE(extension.get());

  EXPECT_EQ(extension->url().spec() + "bar/baz.js",
            Extension::GetResourceURL(extension->url(), "bar/baz.js").spec());
  EXPECT_EQ(extension->url().spec() + "baz.js",
            Extension::GetResourceURL(extension->url(),
                                      "bar/../baz.js").spec());
  EXPECT_EQ(extension->url().spec() + "baz.js",
            Extension::GetResourceURL(extension->url(), "../baz.js").spec());

  // Test that absolute-looking paths ("/"-prefixed) are pasted correctly.
  EXPECT_EQ(extension->url().spec() + "test.html",
            extension->GetResourceURL("/test.html").spec());
}

TEST(ExtensionTest, GetAbsolutePathNoError) {
  scoped_refptr<Extension> extension = LoadManifestStrict("absolute_path",
      "absolute.json");
  EXPECT_TRUE(extension.get());
  std::string err;
  Extension::InstallWarningVector warnings;
  EXPECT_TRUE(extension_file_util::ValidateExtension(extension.get(),
                                                     &err, &warnings));
  EXPECT_EQ(0U, warnings.size());

  EXPECT_EQ(extension->path().AppendASCII("test.html").value(),
            extension->GetResource("test.html").GetFilePath().value());
  EXPECT_EQ(extension->path().AppendASCII("test.js").value(),
            extension->GetResource("test.js").GetFilePath().value());
}

TEST(ExtensionTest, LoadPageActionHelper) {
  scoped_ptr<Extension::ActionInfo> action;

  // First try with an empty dictionary.
  action = LoadAction("page_action_empty.json");
  ASSERT_TRUE(action != NULL);

  // Now setup some values to use in the action.
  const std::string id("MyExtensionActionId");
  const std::string name("MyExtensionActionName");
  std::string img1("image1.png");

  action = LoadAction("page_action.json");
  ASSERT_TRUE(NULL != action.get());
  ASSERT_EQ(id, action->id);

  // No title, so fall back to name.
  ASSERT_EQ(name, action->default_title);
  ASSERT_EQ(img1,
            action->default_icon.Get(extension_misc::EXTENSION_ICON_ACTION,
                                     ExtensionIconSet::MATCH_EXACTLY));

  // Same test with explicitly set type.
  action = LoadAction("page_action_type.json");
  ASSERT_TRUE(NULL != action.get());

  // Try an action without id key.
  action = LoadAction("page_action_no_id.json");
  ASSERT_TRUE(NULL != action.get());

  // Then try without the name key. It's optional, so no error.
  action = LoadAction("page_action_no_name.json");
  ASSERT_TRUE(NULL != action.get());
  ASSERT_TRUE(action->default_title.empty());

  // Then try without the icon paths key.
  action = LoadAction("page_action_no_icon.json");
  ASSERT_TRUE(NULL != action.get());

  // Now test that we can parse the new format for page actions.
  const std::string kTitle("MyExtensionActionTitle");
  const std::string kIcon("image1.png");
  const std::string kPopupHtmlFile("a_popup.html");

  action = LoadAction("page_action_new_format.json");
  ASSERT_TRUE(action.get());
  ASSERT_EQ(kTitle, action->default_title);
  ASSERT_FALSE(action->default_icon.empty());

  // Invalid title should give an error even with a valid name.
  LoadActionAndExpectError("page_action_invalid_title.json",
      errors::kInvalidPageActionDefaultTitle);

  // Invalid name should give an error only with no title.
  action = LoadAction("page_action_invalid_name.json");
  ASSERT_TRUE(NULL != action.get());
  ASSERT_EQ(kTitle, action->default_title);

  LoadActionAndExpectError("page_action_invalid_name_no_title.json",
      errors::kInvalidPageActionName);

  // Test that keys "popup" and "default_popup" both work, but can not
  // be used at the same time.
  // These tests require an extension_url, so we also load the manifest.

  // Only use "popup", expect success.
  scoped_refptr<Extension> extension = LoadManifest("page_action",
             "page_action_popup.json");
  action = LoadAction("page_action_popup.json");
  ASSERT_TRUE(NULL != action.get());
  ASSERT_STREQ(
      extension->url().Resolve(kPopupHtmlFile).spec().c_str(),
      action->default_popup_url.spec().c_str());

  // Use both "popup" and "default_popup", expect failure.
  LoadActionAndExpectError("page_action_popup_and_default_popup.json",
      ErrorUtils::FormatErrorMessage(
          errors::kInvalidPageActionOldAndNewKeys,
          keys::kPageActionDefaultPopup,
          keys::kPageActionPopup));

  // Use only "default_popup", expect success.
  extension = LoadManifest("page_action", "page_action_popup.json");
  action = LoadAction("page_action_default_popup.json");
  ASSERT_TRUE(NULL != action.get());
  ASSERT_STREQ(
      extension->url().Resolve(kPopupHtmlFile).spec().c_str(),
      action->default_popup_url.spec().c_str());

  // Setting default_popup to "" is the same as having no popup.
  action = LoadAction("page_action_empty_default_popup.json");
  ASSERT_TRUE(NULL != action.get());
  EXPECT_TRUE(action->default_popup_url.is_empty());
  ASSERT_STREQ(
      "",
      action->default_popup_url.spec().c_str());

  // Setting popup to "" is the same as having no popup.
  action = LoadAction("page_action_empty_popup.json");

  ASSERT_TRUE(NULL != action.get());
  EXPECT_TRUE(action->default_popup_url.is_empty());
  ASSERT_STREQ(
      "",
      action->default_popup_url.spec().c_str());
}

TEST(ExtensionTest, IdIsValid) {
  EXPECT_TRUE(Extension::IdIsValid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
  EXPECT_TRUE(Extension::IdIsValid("pppppppppppppppppppppppppppppppp"));
  EXPECT_TRUE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmnop"));
  EXPECT_TRUE(Extension::IdIsValid("ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"));
  EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmno"));
  EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmnopa"));
  EXPECT_FALSE(Extension::IdIsValid("0123456789abcdef0123456789abcdef"));
  EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmnoq"));
  EXPECT_FALSE(Extension::IdIsValid("abcdefghijklmnopabcdefghijklmno0"));
}

TEST(ExtensionTest, GenerateID) {
  const uint8 public_key_info[] = {
    0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
    0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81,
    0x89, 0x02, 0x81, 0x81, 0x00, 0xb8, 0x7f, 0x2b, 0x20, 0xdc, 0x7c, 0x9b,
    0x0c, 0xdc, 0x51, 0x61, 0x99, 0x0d, 0x36, 0x0f, 0xd4, 0x66, 0x88, 0x08,
    0x55, 0x84, 0xd5, 0x3a, 0xbf, 0x2b, 0xa4, 0x64, 0x85, 0x7b, 0x0c, 0x04,
    0x13, 0x3f, 0x8d, 0xf4, 0xbc, 0x38, 0x0d, 0x49, 0xfe, 0x6b, 0xc4, 0x5a,
    0xb0, 0x40, 0x53, 0x3a, 0xd7, 0x66, 0x09, 0x0f, 0x9e, 0x36, 0x74, 0x30,
    0xda, 0x8a, 0x31, 0x4f, 0x1f, 0x14, 0x50, 0xd7, 0xc7, 0x20, 0x94, 0x17,
    0xde, 0x4e, 0xb9, 0x57, 0x5e, 0x7e, 0x0a, 0xe5, 0xb2, 0x65, 0x7a, 0x89,
    0x4e, 0xb6, 0x47, 0xff, 0x1c, 0xbd, 0xb7, 0x38, 0x13, 0xaf, 0x47, 0x85,
    0x84, 0x32, 0x33, 0xf3, 0x17, 0x49, 0xbf, 0xe9, 0x96, 0xd0, 0xd6, 0x14,
    0x6f, 0x13, 0x8d, 0xc5, 0xfc, 0x2c, 0x72, 0xba, 0xac, 0xea, 0x7e, 0x18,
    0x53, 0x56, 0xa6, 0x83, 0xa2, 0xce, 0x93, 0x93, 0xe7, 0x1f, 0x0f, 0xe6,
    0x0f, 0x02, 0x03, 0x01, 0x00, 0x01
  };

  std::string extension_id;
  EXPECT_TRUE(
      Extension::GenerateId(
          std::string(reinterpret_cast<const char*>(&public_key_info[0]),
                      arraysize(public_key_info)),
          &extension_id));
  EXPECT_EQ("melddjfinppjdikinhbgehiennejpfhp", extension_id);
}

// This test ensures that the mimetype sniffing code stays in sync with the
// actual crx files that we test other parts of the system with.
TEST(ExtensionTest, MimeTypeSniffing) {
  FilePath path;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
  path = path.AppendASCII("extensions").AppendASCII("good.crx");

  std::string data;
  ASSERT_TRUE(file_util::ReadFileToString(path, &data));

  std::string result;
  EXPECT_TRUE(net::SniffMimeType(data.c_str(), data.size(),
              GURL("http://www.example.com/foo.crx"), "", &result));
  EXPECT_EQ(std::string(Extension::kMimeType), result);

  data.clear();
  result.clear();
  path = path.DirName().AppendASCII("bad_magic.crx");
  ASSERT_TRUE(file_util::ReadFileToString(path, &data));
  EXPECT_TRUE(net::SniffMimeType(data.c_str(), data.size(),
              GURL("http://www.example.com/foo.crx"), "", &result));
  EXPECT_EQ("application/octet-stream", result);
}

TEST(ExtensionTest, EffectiveHostPermissions) {
  scoped_refptr<Extension> extension;
  URLPatternSet hosts;

  extension = LoadManifest("effective_host_permissions", "empty.json");
  EXPECT_EQ(0u, extension->GetEffectiveHostPermissions().patterns().size());
  EXPECT_FALSE(hosts.MatchesURL(GURL("http://www.google.com")));
  EXPECT_FALSE(extension->HasEffectiveAccessToAllHosts());

  extension = LoadManifest("effective_host_permissions", "one_host.json");
  hosts = extension->GetEffectiveHostPermissions();
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
  EXPECT_FALSE(hosts.MatchesURL(GURL("https://www.google.com")));
  EXPECT_FALSE(extension->HasEffectiveAccessToAllHosts());

  extension = LoadManifest("effective_host_permissions",
                           "one_host_wildcard.json");
  hosts = extension->GetEffectiveHostPermissions();
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://google.com")));
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://foo.google.com")));
  EXPECT_FALSE(extension->HasEffectiveAccessToAllHosts());

  extension = LoadManifest("effective_host_permissions", "two_hosts.json");
  hosts = extension->GetEffectiveHostPermissions();
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.reddit.com")));
  EXPECT_FALSE(extension->HasEffectiveAccessToAllHosts());

  extension = LoadManifest("effective_host_permissions",
                           "https_not_considered.json");
  hosts = extension->GetEffectiveHostPermissions();
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://google.com")));
  EXPECT_TRUE(hosts.MatchesURL(GURL("https://google.com")));
  EXPECT_FALSE(extension->HasEffectiveAccessToAllHosts());

  extension = LoadManifest("effective_host_permissions",
                           "two_content_scripts.json");
  hosts = extension->GetEffectiveHostPermissions();
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://google.com")));
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.reddit.com")));
  EXPECT_TRUE(extension->GetActivePermissions()->HasEffectiveAccessToURL(
      GURL("http://www.reddit.com")));
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://news.ycombinator.com")));
  EXPECT_TRUE(extension->GetActivePermissions()->HasEffectiveAccessToURL(
      GURL("http://news.ycombinator.com")));
  EXPECT_FALSE(extension->HasEffectiveAccessToAllHosts());

  extension = LoadManifest("effective_host_permissions", "all_hosts.json");
  hosts = extension->GetEffectiveHostPermissions();
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://test/")));
  EXPECT_FALSE(hosts.MatchesURL(GURL("https://test/")));
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
  EXPECT_TRUE(extension->HasEffectiveAccessToAllHosts());

  extension = LoadManifest("effective_host_permissions", "all_hosts2.json");
  hosts = extension->GetEffectiveHostPermissions();
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://test/")));
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
  EXPECT_TRUE(extension->HasEffectiveAccessToAllHosts());

  extension = LoadManifest("effective_host_permissions", "all_hosts3.json");
  hosts = extension->GetEffectiveHostPermissions();
  EXPECT_FALSE(hosts.MatchesURL(GURL("http://test/")));
  EXPECT_TRUE(hosts.MatchesURL(GURL("https://test/")));
  EXPECT_TRUE(hosts.MatchesURL(GURL("http://www.google.com")));
  EXPECT_TRUE(extension->HasEffectiveAccessToAllHosts());
}

static bool CheckSocketPermission(scoped_refptr<Extension> extension,
    SocketPermissionRequest::OperationType type,
    const char* host,
    int port) {
  SocketPermission::CheckParam param(type, host, port);
  return extension->CheckAPIPermissionWithParam(
      APIPermission::kSocket, &param);
}

TEST(ExtensionTest, SocketPermissions) {
  // Set feature current channel to appropriate value.
  Feature::ScopedCurrentChannel scoped_channel(
      chrome::VersionInfo::CHANNEL_DEV);
  scoped_refptr<Extension> extension;
  std::string error;

  extension = LoadManifest("socket_permissions", "empty.json");
  EXPECT_FALSE(CheckSocketPermission(extension,
      SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80));

  extension = LoadManifestUnchecked("socket_permissions",
                                    "socket1.json",
                                    Extension::INTERNAL, Extension::NO_FLAGS,
                                    &error);
  EXPECT_TRUE(extension == NULL);
  ASSERT_EQ(ErrorUtils::FormatErrorMessage(
        errors::kInvalidPermission, "socket"), error);

  extension = LoadManifest("socket_permissions", "socket2.json");
  EXPECT_TRUE(CheckSocketPermission(extension,
      SocketPermissionRequest::TCP_CONNECT, "www.example.com", 80));
  EXPECT_FALSE(CheckSocketPermission(
        extension, SocketPermissionRequest::UDP_BIND, "", 80));
  EXPECT_TRUE(CheckSocketPermission(
        extension, SocketPermissionRequest::UDP_BIND, "", 8888));

  EXPECT_FALSE(CheckSocketPermission(
        extension, SocketPermissionRequest::UDP_SEND_TO, "example.com", 1900));
  EXPECT_TRUE(CheckSocketPermission(
        extension,
        SocketPermissionRequest::UDP_SEND_TO,
        "239.255.255.250", 1900));
}

// Returns a copy of |source| resized to |size| x |size|.
static SkBitmap ResizedCopy(const SkBitmap& source, int size) {
  return skia::ImageOperations::Resize(source,
                                       skia::ImageOperations::RESIZE_LANCZOS3,
                                       size,
                                       size);
}

static bool SizeEquals(const SkBitmap& bitmap, const gfx::Size& size) {
  return bitmap.width() == size.width() && bitmap.height() == size.height();
}

TEST(ExtensionTest, ImageCaching) {
  FilePath path;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
  path = path.AppendASCII("extensions");

  // Initialize the Extension.
  std::string errors;
  DictionaryValue values;
  values.SetString(keys::kName, "test");
  values.SetString(keys::kVersion, "0.1");
  scoped_refptr<Extension> extension(Extension::Create(
      path, Extension::INVALID, values, Extension::NO_FLAGS, &errors));
  ASSERT_TRUE(extension.get());

  // Create an ExtensionResource pointing at an icon.
  FilePath icon_relative_path(FILE_PATH_LITERAL("icon3.png"));
  ExtensionResource resource(extension->id(),
                             extension->path(),
                             icon_relative_path);

  // Read in the icon file.
  FilePath icon_absolute_path = extension->path().Append(icon_relative_path);
  std::string raw_png;
  ASSERT_TRUE(file_util::ReadFileToString(icon_absolute_path, &raw_png));
  SkBitmap image;
  ASSERT_TRUE(gfx::PNGCodec::Decode(
      reinterpret_cast<const unsigned char*>(raw_png.data()),
      raw_png.length(),
      &image));

  // Make sure the icon file is the size we expect.
  gfx::Size original_size(66, 66);
  ASSERT_EQ(image.width(), original_size.width());
  ASSERT_EQ(image.height(), original_size.height());

  // Create two resized versions at size 16x16 and 24x24.
  SkBitmap image16 = ResizedCopy(image, 16);
  SkBitmap image24 = ResizedCopy(image, 24);

  gfx::Size size16(16, 16);
  gfx::Size size24(24, 24);

  // Cache the 16x16 copy.
  EXPECT_FALSE(extension->HasCachedImage(resource, size16));
  extension->SetCachedImage(resource, image16, original_size);
  EXPECT_TRUE(extension->HasCachedImage(resource, size16));
  EXPECT_TRUE(SizeEquals(extension->GetCachedImage(resource, size16), size16));
  EXPECT_FALSE(extension->HasCachedImage(resource, size24));
  EXPECT_FALSE(extension->HasCachedImage(resource, original_size));

  // Cache the 24x24 copy.
  extension->SetCachedImage(resource, image24, original_size);
  EXPECT_TRUE(extension->HasCachedImage(resource, size24));
  EXPECT_TRUE(SizeEquals(extension->GetCachedImage(resource, size24), size24));
  EXPECT_FALSE(extension->HasCachedImage(resource, original_size));

  // Cache the original, and verify that it gets returned when we ask for a
  // max_size that is larger than the original.
  gfx::Size size128(128, 128);
  EXPECT_TRUE(image.width() < size128.width() &&
              image.height() < size128.height());
  extension->SetCachedImage(resource, image, original_size);
  EXPECT_TRUE(extension->HasCachedImage(resource, original_size));
  EXPECT_TRUE(extension->HasCachedImage(resource, size128));
  EXPECT_TRUE(SizeEquals(extension->GetCachedImage(resource, original_size),
                         original_size));
  EXPECT_TRUE(SizeEquals(extension->GetCachedImage(resource, size128),
                         original_size));
  EXPECT_EQ(extension->GetCachedImage(resource, original_size).getPixels(),
            extension->GetCachedImage(resource, size128).getPixels());
}

// This tests the API permissions with an empty manifest (one that just
// specifies a name and a version and nothing else).
TEST(ExtensionTest, ApiPermissions) {
  const struct {
    const char* permission_name;
    bool expect_success;
  } kTests[] = {
    // Negative test.
    { "non_existing_permission", false },
    // Test default module/package permission.
    { "browserAction",  true },
    { "devtools",       true },
    { "extension",      true },
    { "i18n",           true },
    { "pageAction",     true },
    { "pageActions",    true },
    { "test",           true },
    // Some negative tests.
    { "bookmarks",      false },
    { "cookies",        false },
    { "history",        false },
    // Make sure we find the module name after stripping '.' and '/'.
    { "browserAction/abcd/onClick",  true },
    { "browserAction.abcd.onClick",  true },
    // Test Tabs functions.
    { "tabs.create",      true},
    { "tabs.duplicate",   true},
    { "tabs.onRemoved",   true},
    { "tabs.remove",      true},
    { "tabs.update",      true},
    { "tabs.getSelected", true},
    { "tabs.onUpdated",   true },
    // Test getPermissionWarnings functions. Only one requires permissions.
    { "management.getPermissionWarningsById", false },
    { "management.getPermissionWarningsByManifest", true },
  };

  scoped_refptr<Extension> extension;
  extension = LoadManifest("empty_manifest", "empty.json");

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTests); ++i) {
    EXPECT_EQ(kTests[i].expect_success,
              extension->HasAPIPermission(kTests[i].permission_name))
                  << "Permission being tested: " << kTests[i].permission_name;
  }
}

TEST(ExtensionTest, GetPermissionMessages_ManyApiPermissions) {
  scoped_refptr<Extension> extension;
  extension = LoadManifest("permissions", "many-apis.json");
  std::vector<string16> warnings = extension->GetPermissionMessageStrings();
  ASSERT_EQ(6u, warnings.size());
  EXPECT_EQ("Access your data on api.flickr.com",
            UTF16ToUTF8(warnings[0]));
  EXPECT_EQ("Read and modify your bookmarks", UTF16ToUTF8(warnings[1]));
  EXPECT_EQ("Detect your physical location", UTF16ToUTF8(warnings[2]));
  EXPECT_EQ("Read and modify your browsing history", UTF16ToUTF8(warnings[3]));
  EXPECT_EQ("Access your tabs and browsing activity", UTF16ToUTF8(warnings[4]));
  EXPECT_EQ("Manage your apps, extensions, and themes",
            UTF16ToUTF8(warnings[5]));
}

TEST(ExtensionTest, GetPermissionMessages_ManyHosts) {
  scoped_refptr<Extension> extension;
  extension = LoadManifest("permissions", "many-hosts.json");
  std::vector<string16> warnings = extension->GetPermissionMessageStrings();
  ASSERT_EQ(1u, warnings.size());
  EXPECT_EQ("Access your data on encrypted.google.com and www.google.com",
            UTF16ToUTF8(warnings[0]));
}

TEST(ExtensionTest, GetPermissionMessages_Plugins) {
  scoped_refptr<Extension> extension;
  extension = LoadManifest("permissions", "plugins.json");
  std::vector<string16> warnings = extension->GetPermissionMessageStrings();
  // We don't parse the plugins key on Chrome OS, so it should not ask for any
  // permissions.
#if defined(OS_CHROMEOS)
  ASSERT_EQ(0u, warnings.size());
#else
  ASSERT_EQ(1u, warnings.size());
  EXPECT_EQ("Access all data on your computer and the websites you visit",
            UTF16ToUTF8(warnings[0]));
#endif
}

TEST(ExtensionTest, WantsFileAccess) {
  scoped_refptr<Extension> extension;
  GURL file_url("file:///etc/passwd");

  // <all_urls> permission
  extension = LoadManifest("permissions", "permissions_all_urls.json");
  EXPECT_TRUE(extension->wants_file_access());
  EXPECT_FALSE(extension->CanExecuteScriptOnPage(
      file_url, file_url, -1, NULL, NULL));
  extension = LoadManifest(
      "permissions", "permissions_all_urls.json", Extension::ALLOW_FILE_ACCESS);
  EXPECT_TRUE(extension->wants_file_access());
  EXPECT_TRUE(extension->CanExecuteScriptOnPage(
      file_url, file_url, -1, NULL, NULL));

  // file:///* permission
  extension = LoadManifest("permissions", "permissions_file_scheme.json");
  EXPECT_TRUE(extension->wants_file_access());
  EXPECT_FALSE(extension->CanExecuteScriptOnPage(
      file_url, file_url, -1, NULL, NULL));
  extension = LoadManifest("permissions", "permissions_file_scheme.json",
      Extension::ALLOW_FILE_ACCESS);
  EXPECT_TRUE(extension->wants_file_access());
  EXPECT_TRUE(extension->CanExecuteScriptOnPage(
      file_url, file_url, -1, NULL, NULL));

  // http://* permission
  extension = LoadManifest("permissions", "permissions_http_scheme.json");
  EXPECT_FALSE(extension->wants_file_access());
  EXPECT_FALSE(extension->CanExecuteScriptOnPage(
      file_url, file_url, -1, NULL, NULL));
  extension = LoadManifest("permissions", "permissions_http_scheme.json",
      Extension::ALLOW_FILE_ACCESS);
  EXPECT_FALSE(extension->wants_file_access());
  EXPECT_FALSE(extension->CanExecuteScriptOnPage(
      file_url, file_url, -1, NULL, NULL));

  // <all_urls> content script match
  extension = LoadManifest("permissions", "content_script_all_urls.json");
  EXPECT_TRUE(extension->wants_file_access());
  EXPECT_FALSE(extension->CanExecuteScriptOnPage(
      file_url, file_url, -1, &extension->content_scripts()[0], NULL));
  extension = LoadManifest("permissions", "content_script_all_urls.json",
      Extension::ALLOW_FILE_ACCESS);
  EXPECT_TRUE(extension->wants_file_access());
  EXPECT_TRUE(extension->CanExecuteScriptOnPage(
      file_url, file_url, -1, &extension->content_scripts()[0], NULL));

  // file:///* content script match
  extension = LoadManifest("permissions", "content_script_file_scheme.json");
  EXPECT_TRUE(extension->wants_file_access());
  EXPECT_FALSE(extension->CanExecuteScriptOnPage(
      file_url, file_url, -1, &extension->content_scripts()[0], NULL));
  extension = LoadManifest("permissions", "content_script_file_scheme.json",
      Extension::ALLOW_FILE_ACCESS);
  EXPECT_TRUE(extension->wants_file_access());
  EXPECT_TRUE(extension->CanExecuteScriptOnPage(
      file_url, file_url, -1, &extension->content_scripts()[0], NULL));

  // http://* content script match
  extension = LoadManifest("permissions", "content_script_http_scheme.json");
  EXPECT_FALSE(extension->wants_file_access());
  EXPECT_FALSE(extension->CanExecuteScriptOnPage(
      file_url, file_url, -1, &extension->content_scripts()[0], NULL));
  extension = LoadManifest("permissions", "content_script_http_scheme.json",
      Extension::ALLOW_FILE_ACCESS);
  EXPECT_FALSE(extension->wants_file_access());
  EXPECT_FALSE(extension->CanExecuteScriptOnPage(
      file_url, file_url, -1, &extension->content_scripts()[0], NULL));
}

TEST(ExtensionTest, ExtraFlags) {
  scoped_refptr<Extension> extension;
  extension = LoadManifest("app", "manifest.json", Extension::FROM_WEBSTORE);
  EXPECT_TRUE(extension->from_webstore());

  extension = LoadManifest("app", "manifest.json", Extension::FROM_BOOKMARK);
  EXPECT_TRUE(extension->from_bookmark());

  extension = LoadManifest("app", "manifest.json", Extension::NO_FLAGS);
  EXPECT_FALSE(extension->from_bookmark());
  EXPECT_FALSE(extension->from_webstore());
}

TEST(ExtensionTest, BrowserActionSynthesizesCommand) {
  scoped_refptr<Extension> extension;

  extension = LoadManifest("api_test/browser_action/synthesized",
                           "manifest.json");
  // An extension with a browser action but no extension command specified
  // should get a command assigned to it.
  const extensions::Command* command = extension->browser_action_command();
  ASSERT_TRUE(command != NULL);
  ASSERT_EQ(ui::VKEY_UNKNOWN, command->accelerator().key_code());
}

// Base class for testing the CanExecuteScriptOnPage and CanCaptureVisiblePage
// methods of Extension for extensions with various permissions.
class ExtensionScriptAndCaptureVisibleTest : public testing::Test {
 protected:
  ExtensionScriptAndCaptureVisibleTest()
      : http_url("http://www.google.com"),
        http_url_with_path("http://www.google.com/index.html"),
        https_url("https://www.google.com"),
        file_url("file:///foo/bar"),
        favicon_url("chrome://favicon/http://www.google.com"),
        extension_url("chrome-extension://" +
            Extension::GenerateIdForPath(FilePath(FILE_PATH_LITERAL("foo")))),
        settings_url("chrome://settings"),
        about_url("about:flags") {
    urls_.insert(http_url);
    urls_.insert(http_url_with_path);
    urls_.insert(https_url);
    urls_.insert(file_url);
    urls_.insert(favicon_url);
    urls_.insert(extension_url);
    urls_.insert(settings_url);
    urls_.insert(about_url);
  }

  bool AllowedScript(const Extension* extension, const GURL& url,
                     const GURL& top_url) {
    return extension->CanExecuteScriptOnPage(url, top_url, -1, NULL, NULL);
  }

  bool BlockedScript(const Extension* extension, const GURL& url,
                     const GURL& top_url) {
    return !extension->CanExecuteScriptOnPage(url, top_url, -1, NULL, NULL);
  }

  bool Allowed(const Extension* extension, const GURL& url) {
    return Allowed(extension, url, -1);
  }

  bool Allowed(const Extension* extension, const GURL& url, int tab_id) {
    return (extension->CanExecuteScriptOnPage(url, url, tab_id, NULL, NULL) &&
            extension->CanCaptureVisiblePage(url, tab_id, NULL));
  }

  bool CaptureOnly(const Extension* extension, const GURL& url) {
    return CaptureOnly(extension, url, -1);
  }

  bool CaptureOnly(const Extension* extension, const GURL& url, int tab_id) {
    return !extension->CanExecuteScriptOnPage(url, url, tab_id, NULL, NULL) &&
            extension->CanCaptureVisiblePage(url, tab_id, NULL);
  }

  bool Blocked(const Extension* extension, const GURL& url) {
    return Blocked(extension, url, -1);
  }

  bool Blocked(const Extension* extension, const GURL& url, int tab_id) {
    return !(extension->CanExecuteScriptOnPage(url, url, tab_id, NULL, NULL) ||
             extension->CanCaptureVisiblePage(url, tab_id, NULL));
  }

  bool AllowedExclusivelyOnTab(
      const Extension* extension,
      const std::set<GURL>& allowed_urls,
      int tab_id) {
    bool result = true;
    for (std::set<GURL>::iterator it = urls_.begin(); it != urls_.end(); ++it) {
      const GURL& url = *it;
      if (allowed_urls.count(url))
        result &= Allowed(extension, url, tab_id);
      else
        result &= Blocked(extension, url, tab_id);
    }
    return result;
  }

  // URLs that are "safe" to provide scripting and capture visible tab access
  // to if the permissions allow it.
  const GURL http_url;
  const GURL http_url_with_path;
  const GURL https_url;
  const GURL file_url;

  // We should allow host permission but not scripting permission for favicon
  // urls.
  const GURL favicon_url;

  // URLs that regular extensions should never get access to.
  const GURL extension_url;
  const GURL settings_url;
  const GURL about_url;

 private:
  // The set of all URLs above.
  std::set<GURL> urls_;
};

TEST_F(ExtensionScriptAndCaptureVisibleTest, Permissions) {
  scoped_refptr<Extension> extension;

  // Test <all_urls> for regular extensions.
  extension = LoadManifestStrict("script_and_capture",
      "extension_regular_all.json");
  EXPECT_TRUE(Allowed(extension, http_url));
  EXPECT_TRUE(Allowed(extension, https_url));
  EXPECT_TRUE(Blocked(extension, file_url));
  EXPECT_TRUE(Blocked(extension, settings_url));
  EXPECT_TRUE(CaptureOnly(extension, favicon_url));
  EXPECT_TRUE(Blocked(extension, about_url));
  EXPECT_TRUE(Blocked(extension, extension_url));

  // Test access to iframed content.
  GURL within_extension_url = extension->GetResourceURL("page.html");
  EXPECT_TRUE(AllowedScript(extension, http_url, http_url_with_path));
  EXPECT_TRUE(AllowedScript(extension, https_url, http_url_with_path));
  EXPECT_TRUE(AllowedScript(extension, http_url, within_extension_url));
  EXPECT_TRUE(AllowedScript(extension, https_url, within_extension_url));
  EXPECT_TRUE(BlockedScript(extension, http_url, extension_url));
  EXPECT_TRUE(BlockedScript(extension, https_url, extension_url));

  EXPECT_FALSE(extension->HasHostPermission(settings_url));
  EXPECT_FALSE(extension->HasHostPermission(about_url));
  EXPECT_TRUE(extension->HasHostPermission(favicon_url));

  // Test * for scheme, which implies just the http/https schemes.
  extension = LoadManifestStrict("script_and_capture",
      "extension_wildcard.json");
  EXPECT_TRUE(Allowed(extension, http_url));
  EXPECT_TRUE(Allowed(extension, https_url));
  EXPECT_TRUE(Blocked(extension, settings_url));
  EXPECT_TRUE(Blocked(extension, about_url));
  EXPECT_TRUE(Blocked(extension, file_url));
  EXPECT_TRUE(Blocked(extension, favicon_url));
  extension = LoadManifest("script_and_capture",
      "extension_wildcard_settings.json");
  EXPECT_TRUE(Blocked(extension, settings_url));

  // Having chrome://*/ should not work for regular extensions. Note that
  // for favicon access, we require the explicit pattern chrome://favicon/*.
  std::string error;
  extension = LoadManifestUnchecked("script_and_capture",
                                    "extension_wildcard_chrome.json",
                                    Extension::INTERNAL, Extension::NO_FLAGS,
                                    &error);
  EXPECT_TRUE(extension == NULL);
  EXPECT_EQ(ErrorUtils::FormatErrorMessage(
      errors::kInvalidPermissionScheme, "chrome://*/"), error);

  // Having chrome://favicon/* should not give you chrome://*
  extension = LoadManifestStrict("script_and_capture",
      "extension_chrome_favicon_wildcard.json");
  EXPECT_TRUE(Blocked(extension, settings_url));
  EXPECT_TRUE(CaptureOnly(extension, favicon_url));
  EXPECT_TRUE(Blocked(extension, about_url));
  EXPECT_TRUE(extension->HasHostPermission(favicon_url));

  // Having http://favicon should not give you chrome://favicon
  extension = LoadManifestStrict("script_and_capture",
      "extension_http_favicon.json");
  EXPECT_TRUE(Blocked(extension, settings_url));
  EXPECT_TRUE(Blocked(extension, favicon_url));

  // Component extensions with <all_urls> should get everything.
  extension = LoadManifest("script_and_capture", "extension_component_all.json",
      Extension::COMPONENT, Extension::NO_FLAGS);
  EXPECT_TRUE(Allowed(extension, http_url));
  EXPECT_TRUE(Allowed(extension, https_url));
  EXPECT_TRUE(Allowed(extension, settings_url));
  EXPECT_TRUE(Allowed(extension, about_url));
  EXPECT_TRUE(Allowed(extension, favicon_url));
  EXPECT_TRUE(extension->HasHostPermission(favicon_url));

  // Component extensions should only get access to what they ask for.
  extension = LoadManifest("script_and_capture",
      "extension_component_google.json", Extension::COMPONENT,
      Extension::NO_FLAGS);
  EXPECT_TRUE(Allowed(extension, http_url));
  EXPECT_TRUE(Blocked(extension, https_url));
  EXPECT_TRUE(Blocked(extension, file_url));
  EXPECT_TRUE(Blocked(extension, settings_url));
  EXPECT_TRUE(Blocked(extension, favicon_url));
  EXPECT_TRUE(Blocked(extension, about_url));
  EXPECT_TRUE(Blocked(extension, extension_url));
  EXPECT_FALSE(extension->HasHostPermission(settings_url));
}

TEST_F(ExtensionScriptAndCaptureVisibleTest, TabSpecific) {
  scoped_refptr<Extension> extension =
      LoadManifestStrict("script_and_capture", "tab_specific.json");

  EXPECT_FALSE(extension->GetTabSpecificPermissions(0).get());
  EXPECT_FALSE(extension->GetTabSpecificPermissions(1).get());
  EXPECT_FALSE(extension->GetTabSpecificPermissions(2).get());

  std::set<GURL> no_urls;

  EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 0));
  EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 1));
  EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 2));

  URLPatternSet allowed_hosts;
  allowed_hosts.AddPattern(URLPattern(URLPattern::SCHEME_ALL,
                                      http_url.spec()));
  std::set<GURL> allowed_urls;
  allowed_urls.insert(http_url);
  // http_url_with_path() will also be allowed, because Extension should be
  // considering the security origin of the URL not the URL itself, and
  // http_url is in allowed_hosts.
  allowed_urls.insert(http_url_with_path);

  {
    scoped_refptr<PermissionSet> permissions(
        new PermissionSet(APIPermissionSet(), allowed_hosts, URLPatternSet()));
    extension->UpdateTabSpecificPermissions(0, permissions);
    EXPECT_EQ(permissions->explicit_hosts(),
              extension->GetTabSpecificPermissions(0)->explicit_hosts());
  }

  EXPECT_TRUE(AllowedExclusivelyOnTab(extension, allowed_urls, 0));
  EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 1));
  EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 2));

  extension->ClearTabSpecificPermissions(0);
  EXPECT_FALSE(extension->GetTabSpecificPermissions(0).get());

  EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 0));
  EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 1));
  EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 2));

  std::set<GURL> more_allowed_urls = allowed_urls;
  more_allowed_urls.insert(https_url);
  URLPatternSet more_allowed_hosts = allowed_hosts;
  more_allowed_hosts.AddPattern(URLPattern(URLPattern::SCHEME_ALL,
                                           https_url.spec()));

  {
    scoped_refptr<PermissionSet> permissions(
        new PermissionSet(APIPermissionSet(), allowed_hosts, URLPatternSet()));
    extension->UpdateTabSpecificPermissions(0, permissions);
    EXPECT_EQ(permissions->explicit_hosts(),
              extension->GetTabSpecificPermissions(0)->explicit_hosts());

    permissions = new PermissionSet(APIPermissionSet(),
                                    more_allowed_hosts,
                                    URLPatternSet());
    extension->UpdateTabSpecificPermissions(1, permissions);
    EXPECT_EQ(permissions->explicit_hosts(),
              extension->GetTabSpecificPermissions(1)->explicit_hosts());
  }

  EXPECT_TRUE(AllowedExclusivelyOnTab(extension, allowed_urls, 0));
  EXPECT_TRUE(AllowedExclusivelyOnTab(extension, more_allowed_urls, 1));
  EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 2));

  extension->ClearTabSpecificPermissions(0);
  EXPECT_FALSE(extension->GetTabSpecificPermissions(0).get());

  EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 0));
  EXPECT_TRUE(AllowedExclusivelyOnTab(extension, more_allowed_urls, 1));
  EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 2));

  extension->ClearTabSpecificPermissions(1);
  EXPECT_FALSE(extension->GetTabSpecificPermissions(1).get());

  EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 0));
  EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 1));
  EXPECT_TRUE(AllowedExclusivelyOnTab(extension, no_urls, 2));
}

TEST(ExtensionTest, GenerateId) {
  std::string result;
  EXPECT_TRUE(Extension::GenerateId("", &result));

  EXPECT_TRUE(Extension::GenerateId("test", &result));
  EXPECT_EQ(result, "jpignaibiiemhngfjkcpokkamffknabf");

  EXPECT_TRUE(Extension::GenerateId("_", &result));
  EXPECT_EQ(result, "ncocknphbhhlhkikpnnlmbcnbgdempcd");

  EXPECT_TRUE(Extension::GenerateId(
      "this_string_is_longer_than_a_single_sha256_hash_digest", &result));
  EXPECT_EQ(result, "jimneklojkjdibfkgiiophfhjhbdgcfi");
}

namespace {
enum SyncTestExtensionType {
  EXTENSION,
  APP,
  USER_SCRIPT,
  THEME
};

static scoped_refptr<Extension> MakeSyncTestExtension(
    SyncTestExtensionType type,
    const GURL& update_url,
    const GURL& launch_url,
    Extension::Location location,
    int num_plugins,
    const FilePath& extension_path,
    int creation_flags) {
  DictionaryValue source;
  source.SetString(extension_manifest_keys::kName,
                   "PossiblySyncableExtension");
  source.SetString(extension_manifest_keys::kVersion, "0.0.0.0");
  if (type == APP)
    source.SetString(extension_manifest_keys::kApp, "true");
  if (type == THEME)
    source.Set(extension_manifest_keys::kTheme, new DictionaryValue());
  if (!update_url.is_empty()) {
    source.SetString(extension_manifest_keys::kUpdateURL,
                     update_url.spec());
  }
  if (!launch_url.is_empty()) {
    source.SetString(extension_manifest_keys::kLaunchWebURL,
                     launch_url.spec());
  }
  if (type != THEME) {
    source.SetBoolean(extension_manifest_keys::kConvertedFromUserScript,
                      type == USER_SCRIPT);
    ListValue* plugins = new ListValue();
    for (int i = 0; i < num_plugins; ++i) {
      DictionaryValue* plugin = new DictionaryValue();
      plugin->SetString(extension_manifest_keys::kPluginsPath, "");
      plugins->Set(i, plugin);
    }
    source.Set(extension_manifest_keys::kPlugins, plugins);
  }

  std::string error;
  scoped_refptr<Extension> extension = Extension::Create(
      extension_path, location, source, creation_flags, &error);
  EXPECT_TRUE(extension);
  EXPECT_EQ("", error);
  return extension;
}

static const char kValidUpdateUrl1[] =
    "http://clients2.google.com/service/update2/crx";
static const char kValidUpdateUrl2[] =
    "https://clients2.google.com/service/update2/crx";
}

TEST(ExtensionTest, GetSyncTypeNormalExtensionNoUpdateUrl) {
  scoped_refptr<Extension> extension(
      MakeSyncTestExtension(EXTENSION, GURL(), GURL(),
                            Extension::INTERNAL, 0, FilePath(),
                            Extension::NO_FLAGS));
  EXPECT_NE(extension->GetSyncType(), Extension::SYNC_TYPE_NONE);
}

TEST(ExtensionTest, GetSyncTypeUserScriptValidUpdateUrl) {
  scoped_refptr<Extension> extension(
      MakeSyncTestExtension(USER_SCRIPT, GURL(kValidUpdateUrl1), GURL(),
                            Extension::INTERNAL, 0, FilePath(),
                            Extension::NO_FLAGS));
  EXPECT_NE(extension->GetSyncType(), Extension::SYNC_TYPE_NONE);
}

TEST(ExtensionTest, GetSyncTypeUserScriptNoUpdateUrl) {
  scoped_refptr<Extension> extension(
      MakeSyncTestExtension(USER_SCRIPT, GURL(), GURL(),
                            Extension::INTERNAL, 0, FilePath(),
                            Extension::NO_FLAGS));
  EXPECT_EQ(extension->GetSyncType(), Extension::SYNC_TYPE_NONE);
}

TEST(ExtensionTest, GetSyncTypeThemeNoUpdateUrl) {
  scoped_refptr<Extension> extension(
      MakeSyncTestExtension(THEME, GURL(), GURL(),
                            Extension::INTERNAL, 0, FilePath(),
                            Extension::NO_FLAGS));
  EXPECT_EQ(extension->GetSyncType(), Extension::SYNC_TYPE_NONE);
}

TEST(ExtensionTest, GetSyncTypeExtensionWithLaunchUrl) {
  scoped_refptr<Extension> extension(
      MakeSyncTestExtension(EXTENSION, GURL(), GURL("http://www.google.com"),
                            Extension::INTERNAL, 0, FilePath(),
                            Extension::NO_FLAGS));
  EXPECT_NE(extension->GetSyncType(), Extension::SYNC_TYPE_NONE);
}

TEST(ExtensionTest, GetSyncTypeExtensionExternal) {
  scoped_refptr<Extension> extension(
      MakeSyncTestExtension(EXTENSION, GURL(), GURL(),
                            Extension::EXTERNAL_PREF, 0, FilePath(),
                            Extension::NO_FLAGS));

  EXPECT_EQ(extension->GetSyncType(), Extension::SYNC_TYPE_NONE);
}

TEST(ExtensionTest, GetSyncTypeUserScriptThirdPartyUpdateUrl) {
  scoped_refptr<Extension> extension(
      MakeSyncTestExtension(
          USER_SCRIPT, GURL("http://third-party.update_url.com"), GURL(),
          Extension::INTERNAL, 0, FilePath(), Extension::NO_FLAGS));
  EXPECT_EQ(extension->GetSyncType(), Extension::SYNC_TYPE_NONE);
}

TEST(ExtensionTest, OnlyDisplayAppsInLauncher) {
  scoped_refptr<Extension> extension(
      MakeSyncTestExtension(EXTENSION, GURL(), GURL(),
                            Extension::INTERNAL, 0, FilePath(),
                            Extension::NO_FLAGS));

  EXPECT_FALSE(extension->ShouldDisplayInAppLauncher());
  EXPECT_FALSE(extension->ShouldDisplayInNewTabPage());

  scoped_refptr<Extension> app(
      MakeSyncTestExtension(APP, GURL(), GURL("http://www.google.com"),
                            Extension::INTERNAL, 0, FilePath(),
                            Extension::NO_FLAGS));
  EXPECT_TRUE(app->ShouldDisplayInAppLauncher());
  EXPECT_TRUE(app->ShouldDisplayInNewTabPage());
}

TEST(ExtensionTest, DisplayInXManifestProperties) {
  DictionaryValue manifest;
  manifest.SetString(keys::kName, "TestComponentApp");
  manifest.SetString(keys::kVersion, "0.0.0.0");
  manifest.SetString(keys::kApp, "true");
  manifest.SetString(keys::kPlatformAppBackgroundPage, "");

  std::string error;
  scoped_refptr<Extension> app;

  // Default to true.
  app = Extension::Create(
      FilePath(), Extension::COMPONENT, manifest, 0, &error);
  EXPECT_EQ(error, std::string());
  EXPECT_TRUE(app->ShouldDisplayInAppLauncher());
  EXPECT_TRUE(app->ShouldDisplayInNewTabPage());

  // Value display_in_NTP defaults to display_in_launcher.
  manifest.SetBoolean(keys::kDisplayInLauncher, false);
  app = Extension::Create(
      FilePath(), Extension::COMPONENT, manifest, 0, &error);
  EXPECT_EQ(error, std::string());
  EXPECT_FALSE(app->ShouldDisplayInAppLauncher());
  EXPECT_FALSE(app->ShouldDisplayInNewTabPage());

  // Value display_in_NTP = true overriding display_in_launcher = false.
  manifest.SetBoolean(keys::kDisplayInNewTabPage, true);
  app = Extension::Create(
      FilePath(), Extension::COMPONENT, manifest, 0, &error);
  EXPECT_EQ(error, std::string());
  EXPECT_FALSE(app->ShouldDisplayInAppLauncher());
  EXPECT_TRUE(app->ShouldDisplayInNewTabPage());

  // Value display_in_NTP = false only, overrides default = true.
  manifest.Remove(keys::kDisplayInLauncher, NULL);
  manifest.SetBoolean(keys::kDisplayInNewTabPage, false);
  app = Extension::Create(
      FilePath(), Extension::COMPONENT, manifest, 0, &error);
  EXPECT_EQ(error, std::string());
  EXPECT_TRUE(app->ShouldDisplayInAppLauncher());
  EXPECT_FALSE(app->ShouldDisplayInNewTabPage());

  // Error checking.
  manifest.SetString(keys::kDisplayInNewTabPage, "invalid");
  app = Extension::Create(
      FilePath(), Extension::COMPONENT, manifest, 0, &error);
  EXPECT_EQ(error, std::string(errors::kInvalidDisplayInNewTabPage));
}

TEST(ExtensionTest, OnlySyncInternal) {
  scoped_refptr<Extension> extension_internal(
      MakeSyncTestExtension(EXTENSION, GURL(), GURL(),
                            Extension::INTERNAL, 0, FilePath(),
                            Extension::NO_FLAGS));
  EXPECT_TRUE(extension_internal->IsSyncable());

  scoped_refptr<Extension> extension_noninternal(
      MakeSyncTestExtension(EXTENSION, GURL(), GURL(),
                            Extension::COMPONENT, 0, FilePath(),
                            Extension::NO_FLAGS));
  EXPECT_FALSE(extension_noninternal->IsSyncable());
}

TEST(ExtensionTest, DontSyncDefault) {
  scoped_refptr<Extension> extension_default(
      MakeSyncTestExtension(EXTENSION, GURL(), GURL(),
                            Extension::INTERNAL, 0, FilePath(),
                            Extension::WAS_INSTALLED_BY_DEFAULT));
  EXPECT_FALSE(extension_default->IsSyncable());
}

TEST(ExtensionTest, OptionalOnlyPermission) {
  // Set feature current channel to dev because the only permission that must
  // be optional (usbDevices) is only available on dev channel.
  Feature::ScopedCurrentChannel scoped_channel(
      chrome::VersionInfo::CHANNEL_DEV);

  scoped_refptr<Extension> extension;
  std::string error;
  extension = LoadManifestUnchecked("optional_only_permission",
                                    "manifest1.json",
                                    Extension::INTERNAL, Extension::NO_FLAGS,
                                    &error);
  EXPECT_TRUE(extension == NULL);
  ASSERT_EQ(ErrorUtils::FormatErrorMessage(
        errors::kPermissionMustBeOptional, "usbDevices"), error);

  error.clear();
  extension = LoadManifestUnchecked("optional_only_permission",
                                    "manifest2.json",
                                    Extension::INTERNAL, Extension::NO_FLAGS,
                                    &error);
  EXPECT_TRUE(extension != NULL);
  EXPECT_TRUE(error.empty());
}

// These last 2 tests don't make sense on Chrome OS, where extension plugins
// are not allowed.
#if !defined(OS_CHROMEOS)
TEST(ExtensionTest, GetSyncTypeExtensionWithPlugin) {
  scoped_refptr<Extension> extension(
      MakeSyncTestExtension(EXTENSION, GURL(), GURL(),
                            Extension::INTERNAL, 1, FilePath(),
                            Extension::NO_FLAGS));
  if (extension)
    EXPECT_EQ(extension->GetSyncType(), Extension::SYNC_TYPE_NONE);
}

TEST(ExtensionTest, GetSyncTypeExtensionWithTwoPlugins) {
  scoped_refptr<Extension> extension(
      MakeSyncTestExtension(EXTENSION, GURL(), GURL(),
                            Extension::INTERNAL, 2, FilePath(),
                            Extension::NO_FLAGS));
  if (extension)
    EXPECT_EQ(extension->GetSyncType(), Extension::SYNC_TYPE_NONE);
}
#endif // !defined(OS_CHROMEOS)


text:
@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.github.com/sawied/bean/base", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.github.sawied.bean.base;

redpajama_set_name: RedPajamaGithub


text:
package edu.mit.cci.wikilanguage.model.active

import org.apache.commons.httpclient.methods.GetMethod
import org.jsoup.Jsoup
import org.jsoup.nodes.Element
import edu.mit.cci.util.U
import scala.xml.XML

/**
 * User: pdeboer
 * Date: 8/6/13
 * Time: 7:39 PM
 *
 * rich class that fetches data from wikipedia if needed. starts off sparse
 */
class WikiArticle(val name: String, val lang: String = "en", var text: String = "") {
	private var _parsed: Element = null
	private var _categories: Array[WikiCategory] = null

	private var contentFetchTries = 0
	private val MAX_CONTENT_FETCH_TRIES: Int = 3

	private var categoryFetchTries = 0

	def textFetched: String = {
		if (text == "" && contentFetchTries < MAX_CONTENT_FETCH_TRIES) {
			contentFetchTries += 1
			try {
				val client = U.httpClient()
				//val method = new GetMethod("http://en.wikipedia.org/w/index.php?title=" + URLEncoder.encode(name) + "&action=raw")
				val nameToUse = if(contentFetchTries%2==1) nameCleaned else name
				val method = new GetMethod("http://" + lang + ".wikipedia.org/wiki/" + nameToUse)
				method.addRequestHeader("Accept-Charset", "utf-8")
				client.executeMethod(method)

				text = method.getResponseBodyAsString

				method.releaseConnection()
			}
			catch {
				case e: Throwable => println("couldn't fetch content of article " + lang + "." + name)
			}
		}
		text
	}

	def parsed: Element = {
		if (_parsed == null && textFetched != null) {
			val pcontent = Jsoup.parse(textFetched).select("div#mw-content-text")
			if (pcontent != null) {
				_parsed = pcontent.first()
			}
		}
		_parsed
	}

	def categories = {
		if (_categories == null && categoryFetchTries < 4) {
			categoryFetchTries += 1
			try {
				val client = U.httpClient()
				val nameToUse = if(categoryFetchTries%2==1) nameCleaned else name
				val method = new GetMethod("http://" + lang + ".wikipedia.org/w/api.php?" +
				  "format=xml&action=query&prop=categories&titles=" + nameToUse + "&cllimit=500")
				method.addRequestHeader("Accept-Charset", "utf-8")
				client.executeMethod(method)
				val data = method.getResponseBodyAsString
				method.releaseConnection()

				val xml = XML.loadString(data)
				val cat = (xml \\ "cl" \\ "@title").map(c => new WikiCategory(c.text, lang = lang))
				_categories = Array() ++ cat
			}
			catch {
				case e: Throwable => {
					println("Couldn't get contents of category " + name)
					e.printStackTrace(System.err)
				}
			}
		}
		_categories
	}

	/**
	 * find names of all articles this article is referencing
	 * @return
	 */
	def outlinks(): List[String] = {
		//try as many times to get text as possible
		for (i <- 1 until MAX_CONTENT_FETCH_TRIES) textFetched

		try {
			//fetch all outgoing links of article and return their names
			val linkElements = U.convertJSoupToList(parsed.select("a"))
			val cleanedList = linkElements.filter(a => loc(a) != null && loc(a).length > 0).map(loc(_))
			val links = cleanedList.map(l => {
				val u = urlStart.find(l.startsWith(_))

				if (!u.isEmpty) l.substring(u.get.length)
				else null
			})

			links.filterNot(_ == null)
		}
		catch {
			case e: Exception => {
				println("couldnt parse " + name)
				List.empty[String]
			}
		}

	}

	private def fetchRedirects(numTries: Int = 3): Array[String] = {
		if (numTries <= 0) return Array.empty[String]

		try {
			val client = U.httpClient()
			val nameToUse = if(numTries % 2 == 1) nameCleaned else name

			val method = new GetMethod("http://" + lang + ".wikipedia.org/w/api.php?" +
			  "format=xml&action=query&list=backlinks&prop=info&bllimit=250&blredirect=1" +
			  "&blfilterredir=redirects&bltitle=" + nameToUse)
			method.addRequestHeader("Accept-Charset", "utf-8")
			client.executeMethod(method)
			val data = method.getResponseBodyAsString
			method.releaseConnection()

			val xml = XML.loadString(data)
			val cat = (xml \\ "bl" \\ "@title").map(c => c.toString())

			Array() ++ cat
		}
		catch {
			case e: Throwable => {
				println("Couldn't get contents of category " + name)
				e.printStackTrace(System.err)
				return fetchRedirects(numTries - 1)
			}
		}
	}

	lazy val redirects: Array[String] = fetchRedirects()

	private def urlStart = Array("http://" + lang + ".wikipedia.org/wiki/", "/wiki/", "/w/")

	def likelyPersonOutlinks(): List[String] = {
		outlinks.filter(u => !u.contains(":") && !u.startsWith("index.php"))
	}

	private def loc(e: Element): String = e.attr("href")

	def nameCleaned: String = U.entityEscape(name)

	def titleInOtherLanguages: List[String] = {
		//TODO: code me
		Nil
	}
}


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.IE;
using OpenQA.Selenium.Support.UI;
using CSharp_Blusource_Selenium.Toolkit;

namespace CSharp_Blusource_Selenium.Pages
{
    class BlueSource_Employee : Bluesource
    {
        public BlueSource_Employee()
        {

        }

        // Open time off details for the selected employee.
        public void openTimeOffDetails()
        {
            try
            {
                // Select the "Time Off" view.
                OSI.Web.Link.ClickByText("View");
            }
            catch (Exception e)
            {
                System.Console.WriteLine("Unspecified exception in BlueSource_EmployeeSearch.getTimeOffDetailTotalsForEmployee().");
                System.Console.WriteLine(e.ToString());
            }
        }

        // Open management details for the selected employee.
        public void openManagementDetails()
        {
            try
            {
                // Select the "Manage" view.
                OSI.Web.Link.ClickByText("Manage");
            }
            catch (Exception e)
            {
                System.Console.WriteLine("Unspecified exception in BlueSource_EmployeeSearch.openManagementDetails().");
                System.Console.WriteLine(e.ToString());
            }
        }

        // Tells if you're on the correct page or not.
        public Boolean isOnEmployeePage()
        {
            Boolean onPage = false;

            try
            {
                // Using two identifiers to avoid false positives from other pages.  The IDs in the CSS don't seem unique and may be on other pages.
                onPage = OSI.Web.Sync.SyncByLinkText("username", 7);
                onPage = OSI.Web.Sync.SyncByLinkText("role", 7);
            }
            catch(Exception e)
            {
                System.Console.WriteLine("Unspecified exception in BlueSource_EmployeeSearch.isOnEmployeePage().");
                System.Console.WriteLine(e.ToString());
            }

            return onPage;
        }
    }
}


text:
import httplib2
import json
import logging

okStates = [200, 201, 202]
states = [
    'Queued',
    'In Progress',
    'Manual Step Required',
    'Error',
    'Finished',
    'Aborted',
    'Retried',
    'IRebooting',
    'Force Continue',
    'Pending',
    ]
notStartedState = 'Not_Started'
errorStates = ['Error', 'Aborted', 'Force Continue']
finishedStates = ['Manual Step Required', 'Finished']

logger = logging.getLogger(__name__)

class TestFailedError(Exception):
    pass

class ChassisRestAPI:
    @staticmethod
    def postWithPayload(loginUrl, payload=None):
        urlHeadersJson = {'content-type': 'application/json'}
        try:
            h = httplib2.Http('.cache',
                              disable_ssl_certificate_validation=True)
            if payload is None:
                logger.debug('POST: ' + loginUrl)
                (response, content) = h.request(loginUrl, 'POST', '',
                                                urlHeadersJson)
                logger.debug(content)
            else:
                logger.debug('POST: ' + loginUrl + ' <- Data: ' + str(payload))
                (response, content) = h.request(loginUrl, 'POST',
                                                body=payload,
                                                headers=urlHeadersJson)
                logger.debug(response)
                logger.debug(content)
        except Exception, e:
            raise Exception('Got an error code: ', e)
        return content

    @staticmethod
    def postWithPayloadAndHeaders(loginUrl, urlHeadersJson,
                                  payload=None):
        try:
            h = httplib2.Http('.cache',
                              disable_ssl_certificate_validation=True)
            if payload is None:
                logger.debug('POST: ' + loginUrl)
                (response, content) = h.request(loginUrl, 'POST', '',
                                                urlHeadersJson)
            else:
                logger.debug('POST: ' + loginUrl + ' <- Data: ' + str(payload))
                (response, content) = h.request(loginUrl, 'POST',
                                                body=payload,
                                                headers=urlHeadersJson)
        except Exception, e:
            raise Exception('Got an error code: ', e)
        return content

    @staticmethod
    def postOperation(url, apiKey, payload=''):
        urlHeadersJson = {'content-type': 'application/json',
                          'X-Api-Key': '%s' % str(apiKey)}
        try:
            h = httplib2.Http('.cache',
                              disable_ssl_certificate_validation=True)
            if payload is None:
                logger.debug('POST: ' + url)
                (response, content) = h.request(url, 'POST',
                                                json.dumps(payload),
                                                urlHeadersJson)
            else:
                logger.debug('POST: ' + url + ' <- Data: ' + str(payload))
                (response, content) = h.request(url, 'POST',
                                                json.dumps(payload),
                                                headers=urlHeadersJson)
        except Exception, e:
            raise Exception('Got an error code: ', e)
        return content

    @staticmethod
    def patch(url, payload, apiKey):
        urlHeadersJson = {'content-type': 'application/json',
                          'X-Api-Key': '%s' % str(apiKey)}
        try:
            h = httplib2.Http('.cache',
                              disable_ssl_certificate_validation=True)
            logger.debug('PATCH: ' + url + ' <-- Attribute: ' +
                         str(payload))
            (response, content) = h.request(url, 'PATCH',
                                            json.dumps(payload),
                                            urlHeadersJson)
        except Exception, e:

            # print (response, content)

            raise Exception('Got an error code: ', e)
        return content

    @staticmethod
    def delete(url, apiKey):
        urlHeadersJson = {'content-type': 'application/json',
                          'X-Api-Key': '%s' % str(apiKey)}
        try:
            h = httplib2.Http('.cache',
                              disable_ssl_certificate_validation=True)
            (response, content) = h.request(url, 'DELETE', '', urlHeadersJson)
            logger.debug('DELETE: ' + url)
        except Exception, e:
            raise Exception('Got an error code: ', e)
        if response.status not in okStates:
            raise TestFailedError(json.loads(content)['error'])
        return json.loads(content)

    @staticmethod
    def getWithHeaders(url, apiKey):
        urlHeadersJson = {'content-type': 'application/json',
                          'X-Api-Key': '%s' % str(apiKey)}
        try:
            h = httplib2.Http('.cache',
                              disable_ssl_certificate_validation=True)
            logger.debug('GET: ' + url)
            (response, content) = h.request(url, 'GET', '', urlHeadersJson)
        except Exception, e:
            raise Exception('Got an error code: ', e)
        if response.status not in okStates:
            raise TestFailedError(json.loads(content)['error'])
        output = json.loads(content)
        return output


text:
using System.Data.Common;
using Ycql.DbHelpers;
using Ycql.Interfaces;

namespace Ycql
{
	/// <summary>
	/// Represents a Sql string which will not be escaped or treat as a parameter during Sql Translation
	/// </summary>
	/// <seealso cref="Ycql.Interfaces.ITranslateSql"/>
	public class SqlRawText : ITranslateSql
	{
		/// <summary>
		/// Initializes a new instance of the SQLRawText class using specified Sql string
		/// </summary>
		/// <param name="text">The Sql string which will not be escaped</param>
		public SqlRawText(string text)
		{
			Text = text;
		}

		/// <summary>
		/// Gets or sets the Sql string which will not be escaped
		/// </summary>
		public string Text { get; set; }

		/// <summary>
		/// Returns an unescaped Sql String
		/// </summary>
		/// <param name="dbVersion">Not used</param>
		/// <param name="parameterCollection">Not used</param>
		/// <returns>Not parameterized Sql string</returns>
		public string ToSql(DbVersion dbVersion, DbParameterCollection parameterCollection)
		{
			return Text;
		}
	}
}


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<TITLE>
atg.commerce.payment (ATG Java API)
</TITLE>

<META NAME="keywords" CONTENT="atg.commerce.payment package">

<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">

      Overview
    Package
      Class
      Tree
      Deprecated
      Index
      Help

 PREV PACKAGE
 NEXT PACKAGE

  FRAMES
 NO FRAMES

  All Classes

Package atg.commerce.payment

Class Summary

DummyAddressVerificationProcessor
This class is a dummy address verification processor.

DummyCreditCardProcessor
This class is a dummy credit card processor.

DummyGiftCertificateProcessor
This class is a dummy gift certificate processor.

DummyTaxProcessor
Placeholder tax processor for testing tax processing APIs.

DummyTaxStatus
Dummy tax status for use only with a DummyTaxProcessor.

GiftCertificateProcessorImpl
This class performs the actual functions of authorizing, debiting and crediting a
 giftcertificate.

PaymentManager
This class provides a set of methods for dealing with operations on PaymentGroups.

PaymentManagerAction
Enumerated type representing the actions that can be taken by the
 PaymentManager with respect to a PaymentGroup.

PaymentManagerPipelineArgs
Argument dictionary for pipeline chains and processors invoked by the
 PaymentManager.

StoreCreditProcessorImpl
This class performs the actual functions of authorizing, debiting and crediting a
 store credit.

Exception Summary

PaymentException
This exception indicates that an error occured while performing a
 PaymentManagewr operation.

      Overview
    Package
      Class
      Tree
      Deprecated
      Index
      Help

 PREV PACKAGE
 NEXT PACKAGE

  FRAMES
 NO FRAMES

  All Classes


text:
injectPlayerScript();

var player=null,
		scope=null;

var app = angular.module("YouTube",[]);
app.controller("YouTubeCtrl",function($scope,$http){
	scope=$scope;
	$scope.term="mc hammer";
	$scope.nowPlaying = [];
	$scope.people = [];
	$scope.currentSong=0;
	var isPlaying=false;

	$scope.search = function(term){
		$http.get("/search?q=" + term)
			 .success(function(data){
			  $scope.results = data.items;
			 });
	}

	$scope.play = function(item){
		var videoId = item.id.videoId;
		socket.emit("play",videoId);
		isPlaying=true;
		if(player==null){
				player = new YT.Player('player', {
      	height: '190',
      	width: '340',
      	videoId: videoId,
      	autoplay : 1,
      	playerVars: { 'autoplay': 1, 'controls': 1 },
      	events: {
        	'onReady': onPlayerReady,
        	'onStateChange': onPlayerStateChange
      	}
    	});
		}
		else{
			player.loadVideoById(videoId, 0);
		}
	}

	$scope.add = function(item){
		var video = {
			videoId : item.id.videoId,
			description : item.snippet.description
		};
		$scope.nowPlaying.push(video);
		if(!isPlaying){
			$scope.play(item);
		}
		$http.post("/video",video);
	};

	$scope.remove = function(video){
		var index=$scope.nowPlaying.indexOf(video);
		scope.nowPlaying.splice(index,1);
		$http.delete("/video/" + video.videoId);
	};

  $scope.selectNowPlaying = function(video,index){
  		player.loadVideoById(video.videoId, 0);
  		socket.emit("play",videoId);
  		$scope.currentSong=index;
  };

  $scope.join = function(person){
  	if(person.DisplayName != myName){
  		$scope.people.push(person);
  		$scope.$apply();
  	}
  };

  $scope.socketPlay = function(videoId){
  	if(player==null){
				player = new YT.Player('player', {
      	height: '190',
      	width: '340',
      	videoId: videoId,
      	autoplay : 1,
      	playerVars: { 'autoplay': 1, 'controls': 1 },
      	events: {
        	'onReady': onPlayerReady,
        	'onStateChange': onPlayerStateChange
      	}
    	});
		}
		else{
			player.loadVideoById(videoId, 0);
		}
  };

	$scope.$on('end',function(e,value){
		$scope.currentSong++;
		if($scope.currentSong < $scope.nowPlaying.length){
			isPlaying=true;
			player.loadVideoById($scope.nowPlaying[$scope.currentSong], 0);
		}
		else{
			isPlaying=false;
			return;
		}

	});

		$http.get("/video").success(function(data){
		$scope.nowPlaying=data;

		if(data.length > 0){
			var video = data[0];
			isPlaying=true;

			window.setTimeout(function(){
				player = new YT.Player('player', {
      	height: '190',
      	width: '340',
      	videoId: video.videoId,
      	autoplay : 1,
      	playerVars: { 'autoplay': 1, 'controls': 1 },
      	events: {
        	'onReady': onPlayerReady,
        	'onStateChange': onPlayerStateChange
      	}
    	});
				},100);
		}
	});
});

function onPlayerReady(event) {
  player.playVideo();
}

function onPlayerStateChange(event) {

  if (event.data == YT.PlayerState.ENDED) {
    setTimeout(function(){
    	scope.$broadcast("end");
    }, 1);
  }
}

function injectPlayerScript(){
	var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}


text:
<?php

require_once(__DIR__.'/../../bootstrap/unit.php');

$t = new lime_test(47);

class MySessionStorage extends sfSessionTestStorage
{
  public function regenerate($destroy = false)
  {
    $this->sessionId = rand(1, 9999);

    return true;
  }
}

$dispatcher = new sfEventDispatcher();
$sessionPath = sys_get_temp_dir().'/sessions_'.rand(11111, 99999);
$storage = new MySessionStorage(array('session_path' => $sessionPath));

$user = new sfBasicSecurityUser($dispatcher, $storage);

// ->initialize()
$t->diag('->initialize()');
$t->todo('->initialize() times out the user if no request made for a long time');

// ->getCredentials()
$t->diag('->getCredentials()');
$user->clearCredentials();
$user->addCredential('user');
$t->is($user->getCredentials(), array('user'), '->getCredentials() returns user credentials as an array');

// ->setAuthenticated() ->isAuthenticated()
$t->diag('->setAuthenticated() ->isAuthenticated()');
$t->is($user->isAuthenticated(), false, '->isAuthenticated() returns false by default');
$user->setAuthenticated(true);
$t->is($user->isAuthenticated(), true, '->isAuthenticated() returns true if the user is authenticated');
$user->setAuthenticated(false);
$t->is($user->isAuthenticated(), false, '->setAuthenticated() accepts a boolean as its first parameter');

// session id regeneration
$user->setAuthenticated(false);
$id = $storage->getSessionId();
$user->setAuthenticated(true);
$t->isnt($id, $id = $storage->getSessionId(), '->setAuthenticated() regenerates the session id if the authentication changes');
$user->setAuthenticated(true);
$t->is($storage->getSessionId(), $id, '->setAuthenticated() does not regenerate the session id if the authentication does not change');
$user->addCredential('foo');
$t->isnt($id, $id = $storage->getSessionId(), '->addCredential() regenerates the session id if a new credential is added');
$t->is($id, $storage->getSessionId(), '->addCredential() does not regenerate the session id if the credential already exists');
$user->removeCredential('foo');
$t->isnt($id, $id = $storage->getSessionId(), '->removeCredential() regenerates the session id if a credential is removed');
$t->is($id, $storage->getSessionId(), '->removeCredential() does not regenerate the session id if the credential does not exist');

// ->setTimedOut() ->getTimedOut()
$user = new sfBasicSecurityUser($dispatcher, $storage);
$t->diag('->setTimedOut() ->isTimedOut()');
$t->is($user->isTimedOut(), false, '->isTimedOut() returns false if the session is not timed out');
$user->setTimedOut();
$t->is($user->isTimedOut(), true, '->isTimedOut() returns true if the session is timed out');

// ->hasCredential()
$t->diag('->hasCredential()');
$user->clearCredentials();
$t->is($user->hasCredential('admin'), false, '->hasCredential() returns false if user has not the credential');

$user->addCredential('admin');
$t->is($user->hasCredential('admin'), true, '->addCredential() takes a credential as its first argument');

// admin AND user
$t->is($user->hasCredential(array('admin', 'user')), false, '->hasCredential() can takes an array of credential as a parameter');

// admin OR user
$t->is($user->hasCredential(array(array('admin', 'user'))), true, '->hasCredential() can takes an array of credential as a parameter');

// (admin OR user) AND owner
$t->is($user->hasCredential(array(array('admin', 'user'), 'owner')), false, '->hasCredential() can takes an array of credential as a parameter');
$user->addCredential('owner');
$t->is($user->hasCredential(array(array('admin', 'user'), 'owner')), true, '->hasCredential() can takes an array of credential as a parameter');

// [[root, admin, editor, [supplier, owner], [supplier, group], accounts]]
// root OR admin OR editor OR (supplier AND owner) OR (supplier AND group) OR accounts
$user->clearCredentials();
$credential = array(array('root', 'admin', 'editor', array('supplier', 'owner'), array('supplier', 'group'), 'accounts'));
$t->is($user->hasCredential($credential), false, '->hasCredential() can takes an array of credential as a parameter');
$user->addCredential('admin');
$t->is($user->hasCredential($credential), true, '->hasCredential() can takes an array of credential as a parameter');
$user->clearCredentials();
$user->addCredential('supplier');
$t->is($user->hasCredential($credential), false, '->hasCredential() can takes an array of credential as a parameter');
$user->addCredential('owner');
$t->is($user->hasCredential($credential), true, '->hasCredential() can takes an array of credential as a parameter');

// [[root, [supplier, [owner, quasiowner]], accounts]]
// root OR (supplier AND (owner OR quasiowner)) OR accounts
$user->clearCredentials();
$credential = array(array('root', array('supplier', array('owner', 'quasiowner')), 'accounts'));
$t->is($user->hasCredential($credential), false, '->hasCredential() can takes an array of credential as a parameter');
$user->addCredential('root');
$t->is($user->hasCredential($credential), true, '->hasCredential() can takes an array of credential as a parameter');
$user->clearCredentials();
$user->addCredential('supplier');
$t->is($user->hasCredential($credential), false, '->hasCredential() can takes an array of credential as a parameter');
$user->addCredential('owner');
$t->is($user->hasCredential($credential), true, '->hasCredential() can takes an array of credential as a parameter');
$user->addCredential('quasiowner');
$t->is($user->hasCredential($credential), true, '->hasCredential() can takes an array of credential as a parameter');
$user->removeCredential('owner');
$t->is($user->hasCredential($credential), true, '->hasCredential() can takes an array of credential as a parameter');
$user->removeCredential('supplier');
$t->is($user->hasCredential($credential), false, '->hasCredential() can takes an array of credential as a parameter');

$user->clearCredentials();
$user->addCredential('admin');
$user->addCredential('user');
$t->is($user->hasCredential('admin'), true);
$t->is($user->hasCredential('user'), true);

$user->addCredentials('superadmin', 'subscriber');
$t->is($user->hasCredential('subscriber'), true);
$t->is($user->hasCredential('superadmin'), true);

// admin and (user or subscriber)
$t->is($user->hasCredential(array(array('admin', array('user', 'subscriber')))), true);

$user->addCredentials(array('superadmin1', 'subscriber1'));
$t->is($user->hasCredential('subscriber1'), true);
$t->is($user->hasCredential('superadmin1'), true);

// admin and (user or subscriber) and (superadmin1 or subscriber1)
$t->is($user->hasCredential(array(array('admin', array('user', 'subscriber'), array('superadmin1', 'subscriber1')))), true);

// numerical credentials
$user->clearCredentials();
$user->addCredentials(array('1', 2));
$t->is($user->hasCredential(1), true, '->hasCrendential() supports numerical credentials');
$t->is($user->hasCredential('2'), true, '->hasCrendential() supports numerical credentials');
$t->is($user->hasCredential(array('1', 2)), true, '->hasCrendential() supports numerical credentials');
$t->is($user->hasCredential(array(1, '2')), true, '->hasCrendential() supports numerical credentials');

// ->removeCredential()
$t->diag('->removeCredential()');
$user->removeCredential('user');
$t->is($user->hasCredential('user'), false);

// ->clearCredentials()
$t->diag('->clearCredentials()');
$user->clearCredentials();
$t->is($user->hasCredential('subscriber'), false);
$t->is($user->hasCredential('superadmin'), false);

// timeout
$user->setAuthenticated(true);
$user->shutdown();
$user = new sfBasicSecurityUser($dispatcher, $storage, array('timeout' => 0));
$t->is($user->isTimedOut(), true, '->initialize() times out the user if no request made for a long time');

$user = new sfBasicSecurityUser($dispatcher, $storage, array('timeout' => false));
$t->is($user->isTimedOut(), false, '->initialize() takes a timeout parameter which can be false to disable session timeout');

sfToolkit::clearDirectory($sessionPath);


text:
module Azure::CognitiveServices::ContentModerator::V1_0
  module Models
    #
    # Refresh Index Response.
    #
    class RefreshIndex

      include MsRestAzure

      # @return [String] Content source Id.
      attr_accessor :content_source_id

      # @return [Boolean] Update success status.
      attr_accessor :is_update_success

      # @return [Array<Hash{String => String}>] Advanced info list.
      attr_accessor :advanced_info

      # @return [Status] Refresh index status.
      attr_accessor :status

      # @return [String] Tracking Id.
      attr_accessor :tracking_id

      #
      # Mapper for RefreshIndex class as Ruby Hash.
      # This will be used for serialization/deserialization.
      #
      def self.mapper()
        {
          client_side_validation: true,
          required: false,
          serialized_name: 'RefreshIndex',
          type: {
            name: 'Composite',
            class_name: 'RefreshIndex',
            model_properties: {
              content_source_id: {
                client_side_validation: true,
                required: false,
                serialized_name: 'ContentSourceId',
                type: {
                  name: 'String'
                }
              },
              is_update_success: {
                client_side_validation: true,
                required: false,
                serialized_name: 'IsUpdateSuccess',
                type: {
                  name: 'Boolean'
                }
              },
              advanced_info: {
                client_side_validation: true,
                required: false,
                serialized_name: 'AdvancedInfo',
                type: {
                  name: 'Sequence',
                  element: {
                      client_side_validation: true,
                      required: false,
                      serialized_name: 'HashElementType',
                      type: {
                        name: 'Dictionary',
                        value: {
                            client_side_validation: true,
                            required: false,
                            serialized_name: 'StringElementType',
                            type: {
                              name: 'String'
                            }
                        }
                      }
                  }
                }
              },
              status: {
                client_side_validation: true,
                required: false,
                serialized_name: 'Status',
                type: {
                  name: 'Composite',
                  class_name: 'Status'
                }
              },
              tracking_id: {
                client_side_validation: true,
                required: false,
                serialized_name: 'TrackingId',
                type: {
                  name: 'String'
                }
              }
            }
          }
        }
      end
    end
  end
end


text:
    <link rel="Stylesheet" media="screen" href="data/styles.css" />

ui.awesomebar.js

Copyright (c) 2007-2008 Maxime Haineault (haineault.com)

MIT License ~ http://www.opensource.org/licenses/mit-license.php

    Experimental code !

Demo

        <input type="text" id="test-1" />

Usage

$('#test-1').awesomebar({
    dataSource: 'data/awesomebar-data.php?str=%s'
});


text:
require('proof')(1, require('cadence')(prove))

function prove (async, assert) {
    async(function () {
    }, function () {
    })
}


text: External Sources Folder


text:
[Express.js](http://github.com/visionmedia/express) view engine for
[handlebars.js](http://github.com/wycats/handlebars.js)

## Install ##

```
npm install hbs
```

## Use ##

Using *hbs* as the default view engine requires just one line of code in your app setup. This will render `.hbs` files when `res.render` is called.

```javascript
app.set('view engine', 'hbs');
```

To use a different extension (i.e. html) for your template files:

```javascript
app.set('view engine', 'html');
app.engine('html', require('hbs').__express);
```

## Helpers and Partials ##

hbs exposes the `registerHelper` and `registerPartial` method from handlebars.

```javascript
var hbs = require('hbs');

hbs.registerHelper('helper_name', function(...) { ... });
hbs.registerPartial('partial_name', 'partial value');
```

For convenience, `registerPartials` provides a quick way to load all partials from a specific directory:

```javascript
var hbs = require('hbs');

hbs.registerPartials(__dirname + '/views/partials' [, callback]);
```

Partials that are loaded from a directory are named based on their filename, where spaces and hyphens are replaced with an underscore character:

```
template.html      -> {{> template}}
template 2.html    -> {{> template_2}}
login view.hbs     -> {{> login_view}}
template-file.html -> {{> template_file}}
```

See the [handlebars.js](http://github.com/wycats/handlebars.js) README and docs for more information.

**Note:** This method is async; meaning that the directory is walked in a non-blocking manner to app startup.

## Exposing locals as template data ##

hbs has the ability to expose the application and request locals within any context inside a view. To enable this functionality, simply call the `localsAsTemplateData` method and pass in your Express application instance.

```javascript
var hbs = require('hbs');
var express = require('express');

var app = express();
hbs.localsAsTemplateData(app);

app.locals.foo = "bar";
```

The local data can then be accessed using the `@property` syntax:

```
top level: {{@foo}}
{{#each items}}
  {{label}}: {{@foo}}
{{/each}}
```
Note: In partials and templates, local data can be accessed without using `@` prefix.

## handlebars ##

The handlebars require used by hbs can be accessed via the `handlebars` property on the `hbs` module.

If you wish to use handlebars methods like `SafeString` please do so on this property. Do not register helpers or partials in this way.

```
// hbs.handlebars is the handlebars module
hbs.handlebars === require('handlebars');
```

## Recipes ##

### more than one instance ###
You can create isolated instances of hbs using the `create()` function on the module object.

```
var hbs = require('hbs');

var instance1 = hbs.create();
var instance2 = hbs.create();

app.engine('html', instance1.__express);
app.engine('hbs', instance2.__express);
```

Each instance has the same methods/properties as the `hbs` module object. The module object is actually just an instance created for you automatically.

### extra scripts or styles ##
Sometimes it is useful to have custom scripts or stylesheets on your pages. Handlebars does not provide a way to import or extend a template, but through the use of helpers you can create a similar result.

We can take advantage of the fact that our body template is processed before the layout template. Knowing this, we can create two helpers `block` and `extend` which can be used to 'inject' custom stylesheets or scripts into the layout template. The `block` helper will act as a placeholder for values specified in earlier `extend` helpers.

See examples/extend for a working example. Note how the index.hbs file defines extra stylesheets and scripts to be injected into the layout. They are put into the head section and at the end of the body respectively. If this was not done, the stylesheet would be in the body and the script would print `foo bar` too soon.

## Helpful Modules ##

- **[hbs-utils](https://github.com/dpolivy/hbs-utils)**: A small utility library that provides helpers for registering and compiling partials, including automatic updates when partials are changed.


text:
using System.Collections.Generic;
using CyDesigner.Extensions.Gde;
using CyDesigner.Extensions.Common;
using System.Windows.Forms;

namespace CharLCDmp_v1_2
{
    [CyCompDevCustomizer]
    public partial class CyCustomizer : ICyParamEditHook_v1
    {
        #region ICyParamEditHook_v1 Members

        // Type of dialog box.  Advanced opens with a button on the generic form.  Complete opens immediately
        private const CyCompDevParamEditorMode MODE = CyCompDevParamEditorMode.COMPLETE;
        // Run Instance Customizer on Instance Selection
        private const bool EDIT_ON_DROP = false;
        private CyCharacterLCDEditingControl m_editControl;

        /// <summary>
        /// Edit Params initializes the data in the customizer as well as
        /// instantiating the dialog.
        /// </summary>
        /// <param name="obj"> Is a component object containing the parameter information for the object. </param>
        /// <returns>A DialogResult object associated with the form.
        /// OK means accept changes.  Cancel means reject changes.</returns>
        DialogResult ICyParamEditHook_v1.EditParams(ICyInstEdit_v1 obj, ICyTerminalQuery_v1 termQuery,
            ICyExpressMgr_v1 mgr)
        {
            ICyTabbedParamEditor editor = obj.CreateTabbedParamEditor();
            m_editControl = new CyCharacterLCDEditingControl(obj);
            editor.AddCustomPage("General", m_editControl, ExpView_ParamChanged, "General");
            editor.AddDefaultPage("Built-in", "Built-in");
            System.Windows.Forms.DialogResult result = editor.ShowDialog();
            return result;
        }

        CyCompDevParamEditorMode ICyParamEditHook_v1.GetEditorMode()
        {
            return MODE;
        }

        bool ICyParamEditHook_v1.EditParamsOnDrop
        {
            get { return EDIT_ON_DROP; }
        }
        #endregion

        private void ExpView_ParamChanged(ICyParamEditor custEditor, CyCompDevParam param)
        {
            if (param.ErrorCount == 0)
            {
                ((CyCharLCDControl)(m_editControl.DisplayControl)).InitializeParameters();
            }
        }
    }

    public class CyCharacterLCDEditingControl : ICyParamEditingControl
    {
        private CyCharLCDControl m_control;

        public CyCharacterLCDEditingControl(ICyInstEdit_v1 obj)
        {
            this.m_control = new CyCharLCDControl(obj);
            this.m_control.Dock = DockStyle.Fill;
        }

        #region ICyParamEditingControl Members

        public Control DisplayControl
        {
            get { return m_control; }
        }

        public IEnumerable<CyCustErr> GetErrors()
        {
            return new CyCustErr[] { };
        }

        #endregion
    }
}