1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/files/file_path.h"
6#include "base/logging.h"
7#include "base/memory/ref_counted.h"
8#include "base/memory/scoped_ptr.h"
9#include "base/values.h"
10#include "extensions/common/extension.h"
11#include "extensions/common/extension_set.h"
12#include "testing/gtest/include/gtest/gtest.h"
13
14namespace extensions {
15
16namespace {
17
18scoped_refptr<Extension> CreateTestExtension(const std::string& name,
19                                             const std::string& launch_url,
20                                             const std::string& extent) {
21#if defined(OS_WIN)
22  base::FilePath path(FILE_PATH_LITERAL("c:\\"));
23#else
24  base::FilePath path(FILE_PATH_LITERAL("/"));
25#endif
26  path = path.AppendASCII(name);
27
28  base::DictionaryValue manifest;
29  manifest.SetString("name", name);
30  manifest.SetString("version", "1");
31
32  if (!launch_url.empty())
33    manifest.SetString("app.launch.web_url", launch_url);
34
35  if (!extent.empty()) {
36    base::ListValue* urls = new base::ListValue();
37    manifest.Set("app.urls", urls);
38    urls->Append(new base::StringValue(extent));
39  }
40
41  std::string error;
42  scoped_refptr<Extension> extension(
43      Extension::Create(path, Manifest::INTERNAL, manifest,
44                        Extension::NO_FLAGS, &error));
45  EXPECT_TRUE(extension.get()) << error;
46  return extension;
47}
48
49}  // namespace
50
51TEST(ExtensionSetTest, ExtensionSet) {
52  scoped_refptr<Extension> ext1(CreateTestExtension(
53      "a", "https://chrome.google.com/launch", "https://chrome.google.com/"));
54
55  scoped_refptr<Extension> ext2(CreateTestExtension(
56      "a", "http://code.google.com/p/chromium",
57      "http://code.google.com/p/chromium/"));
58
59  scoped_refptr<Extension> ext3(CreateTestExtension(
60      "b", "http://dev.chromium.org/", "http://dev.chromium.org/"));
61
62  scoped_refptr<Extension> ext4(
63      CreateTestExtension("c", std::string(), std::string()));
64
65  ASSERT_TRUE(ext1.get() && ext2.get() && ext3.get() && ext4.get());
66
67  ExtensionSet extensions;
68
69  // Add an extension.
70  EXPECT_TRUE(extensions.Insert(ext1));
71  EXPECT_EQ(1u, extensions.size());
72  EXPECT_EQ(ext1.get(), extensions.GetByID(ext1->id()));
73
74  // Since extension2 has same ID, it should overwrite extension1.
75  EXPECT_FALSE(extensions.Insert(ext2));
76  EXPECT_EQ(1u, extensions.size());
77  EXPECT_EQ(ext2.get(), extensions.GetByID(ext1->id()));
78
79  // Add the other extensions.
80  EXPECT_TRUE(extensions.Insert(ext3));
81  EXPECT_TRUE(extensions.Insert(ext4));
82  EXPECT_EQ(3u, extensions.size());
83
84  // Get extension by its chrome-extension:// URL
85  EXPECT_EQ(
86      ext2.get(),
87      extensions.GetExtensionOrAppByURL(ext2->GetResourceURL("test.html")));
88  EXPECT_EQ(
89      ext3.get(),
90      extensions.GetExtensionOrAppByURL(ext3->GetResourceURL("test.html")));
91  EXPECT_EQ(
92      ext4.get(),
93      extensions.GetExtensionOrAppByURL(ext4->GetResourceURL("test.html")));
94
95  // Get extension by web extent.
96  EXPECT_EQ(ext2.get(),
97            extensions.GetExtensionOrAppByURL(
98                GURL("http://code.google.com/p/chromium/monkey")));
99  EXPECT_EQ(ext3.get(),
100            extensions.GetExtensionOrAppByURL(
101                GURL("http://dev.chromium.org/design-docs/")));
102  EXPECT_FALSE(extensions.GetExtensionOrAppByURL(
103      GURL("http://blog.chromium.org/")));
104
105  // Test InSameExtent().
106  EXPECT_TRUE(extensions.InSameExtent(
107      GURL("http://code.google.com/p/chromium/monkey/"),
108      GURL("http://code.google.com/p/chromium/")));
109  EXPECT_FALSE(extensions.InSameExtent(
110      GURL("http://code.google.com/p/chromium/"),
111      GURL("https://code.google.com/p/chromium/")));
112  EXPECT_FALSE(extensions.InSameExtent(
113      GURL("http://code.google.com/p/chromium/"),
114      GURL("http://dev.chromium.org/design-docs/")));
115
116  // Both of these should be NULL, which mean true for InSameExtent.
117  EXPECT_TRUE(extensions.InSameExtent(
118      GURL("http://www.google.com/"),
119      GURL("http://blog.chromium.org/")));
120
121  // Remove one of the extensions.
122  EXPECT_TRUE(extensions.Remove(ext2->id()));
123  EXPECT_EQ(2u, extensions.size());
124  EXPECT_FALSE(extensions.GetByID(ext2->id()));
125
126  // Make a union of a set with 3 more extensions (only 2 are new).
127  scoped_refptr<Extension> ext5(
128      CreateTestExtension("d", std::string(), std::string()));
129  scoped_refptr<Extension> ext6(
130      CreateTestExtension("e", std::string(), std::string()));
131  ASSERT_TRUE(ext5.get() && ext6.get());
132
133  scoped_ptr<ExtensionSet> to_add(new ExtensionSet());
134  // |ext3| is already in |extensions|, should not affect size.
135  EXPECT_TRUE(to_add->Insert(ext3));
136  EXPECT_TRUE(to_add->Insert(ext5));
137  EXPECT_TRUE(to_add->Insert(ext6));
138
139  ASSERT_TRUE(extensions.Contains(ext3->id()));
140  ASSERT_TRUE(extensions.InsertAll(*to_add));
141  EXPECT_EQ(4u, extensions.size());
142
143  ASSERT_FALSE(extensions.InsertAll(*to_add));  // Re-adding same set no-ops.
144  EXPECT_EQ(4u, extensions.size());
145}
146
147}  // namespace extensions
148