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/pickle.h"
6#include "base/values.h"
7#include "extensions/common/permissions/manifest_permission.h"
8#include "extensions/common/permissions/manifest_permission_set.h"
9#include "ipc/ipc_message.h"
10#include "testing/gtest/include/gtest/gtest.h"
11
12namespace extensions {
13
14class MockManifestPermission : public ManifestPermission {
15 public:
16  MockManifestPermission(const std::string& name)
17      : name_(name) {
18  }
19
20  virtual std::string name() const OVERRIDE {
21    return name_;
22  }
23
24  virtual std::string id() const OVERRIDE {
25    return name();
26  }
27
28  virtual bool HasMessages() const OVERRIDE {
29    return false;
30  }
31
32  virtual PermissionMessages GetMessages() const OVERRIDE {
33    return PermissionMessages();
34  }
35
36  virtual bool FromValue(const base::Value* value) OVERRIDE { return true; }
37
38  virtual scoped_ptr<base::Value> ToValue() const OVERRIDE {
39    return make_scoped_ptr(base::Value::CreateNullValue());
40  }
41
42  virtual ManifestPermission* Diff(const ManifestPermission* rhs)
43      const OVERRIDE {
44    const MockManifestPermission* other =
45        static_cast<const MockManifestPermission*>(rhs);
46    EXPECT_EQ(name_, other->name_);
47    return NULL;
48  }
49
50  virtual ManifestPermission* Union(const ManifestPermission* rhs)
51      const OVERRIDE {
52    const MockManifestPermission* other =
53        static_cast<const MockManifestPermission*>(rhs);
54    EXPECT_EQ(name_, other->name_);
55    return new MockManifestPermission(name_);
56  }
57
58  virtual ManifestPermission* Intersect(const ManifestPermission* rhs)
59      const OVERRIDE {
60    const MockManifestPermission* other =
61        static_cast<const MockManifestPermission*>(rhs);
62    EXPECT_EQ(name_, other->name_);
63    return new MockManifestPermission(name_);
64  }
65
66 private:
67  std::string name_;
68};
69
70TEST(ManifestPermissionSetTest, General) {
71  ManifestPermissionSet set;
72  set.insert(new MockManifestPermission("p1"));
73  set.insert(new MockManifestPermission("p2"));
74  set.insert(new MockManifestPermission("p3"));
75  set.insert(new MockManifestPermission("p4"));
76  set.insert(new MockManifestPermission("p5"));
77
78  EXPECT_EQ(set.find("p1")->id(), "p1");
79  EXPECT_TRUE(set.find("p10") == set.end());
80
81  EXPECT_EQ(set.size(), 5u);
82
83  EXPECT_EQ(set.erase("p1"), 1u);
84  EXPECT_EQ(set.size(), 4u);
85
86  EXPECT_EQ(set.erase("p1"), 0u);
87  EXPECT_EQ(set.size(), 4u);
88}
89
90TEST(ManifestPermissionSetTest, CreateUnion) {
91  ManifestPermissionSet permissions1;
92  ManifestPermissionSet permissions2;
93  ManifestPermissionSet expected_permissions;
94  ManifestPermissionSet result;
95
96  ManifestPermission* permission = new MockManifestPermission("p3");
97
98  // Union with an empty set.
99  permissions1.insert(new MockManifestPermission("p1"));
100  permissions1.insert(new MockManifestPermission("p2"));
101  permissions1.insert(permission->Clone());
102  expected_permissions.insert(new MockManifestPermission("p1"));
103  expected_permissions.insert(new MockManifestPermission("p2"));
104  expected_permissions.insert(permission);
105
106  ManifestPermissionSet::Union(permissions1, permissions2, &result);
107
108  EXPECT_TRUE(permissions1.Contains(permissions2));
109  EXPECT_TRUE(permissions1.Contains(result));
110  EXPECT_FALSE(permissions2.Contains(permissions1));
111  EXPECT_FALSE(permissions2.Contains(result));
112  EXPECT_TRUE(result.Contains(permissions1));
113  EXPECT_TRUE(result.Contains(permissions2));
114
115  EXPECT_EQ(expected_permissions, result);
116
117  // Now use a real second set.
118  permissions2.insert(new MockManifestPermission("p1"));
119  permissions2.insert(new MockManifestPermission("p2"));
120  permissions2.insert(new MockManifestPermission("p33"));
121  permissions2.insert(new MockManifestPermission("p4"));
122  permissions2.insert(new MockManifestPermission("p5"));
123
124  expected_permissions.insert(new MockManifestPermission("p1"));
125  expected_permissions.insert(new MockManifestPermission("p2"));
126  expected_permissions.insert(new MockManifestPermission("p3"));
127  expected_permissions.insert(new MockManifestPermission("p4"));
128  expected_permissions.insert(new MockManifestPermission("p5"));
129  expected_permissions.insert(new MockManifestPermission("p33"));
130
131  ManifestPermissionSet::Union(permissions1, permissions2, &result);
132
133  {
134    ManifestPermissionSet set1;
135    set1.insert(new MockManifestPermission("p1"));
136    set1.insert(new MockManifestPermission("p2"));
137    ManifestPermissionSet set2;
138    set2.insert(new MockManifestPermission("p3"));
139
140    EXPECT_FALSE(set1.Contains(set2));
141    EXPECT_FALSE(set2.Contains(set1));
142  }
143
144  EXPECT_FALSE(permissions1.Contains(permissions2));
145  EXPECT_FALSE(permissions1.Contains(result));
146  EXPECT_FALSE(permissions2.Contains(permissions1));
147  EXPECT_FALSE(permissions2.Contains(result));
148  EXPECT_TRUE(result.Contains(permissions1));
149  EXPECT_TRUE(result.Contains(permissions2));
150
151  EXPECT_EQ(expected_permissions, result);
152}
153
154TEST(ManifestPermissionSetTest, CreateIntersection) {
155  ManifestPermissionSet permissions1;
156  ManifestPermissionSet permissions2;
157  ManifestPermissionSet expected_permissions;
158  ManifestPermissionSet result;
159
160  // Intersection with an empty set.
161  permissions1.insert(new MockManifestPermission("p1"));
162  permissions1.insert(new MockManifestPermission("p2"));
163  permissions1.insert(new MockManifestPermission("p3"));
164
165  ManifestPermissionSet::Intersection(permissions1, permissions2, &result);
166  EXPECT_TRUE(permissions1.Contains(result));
167  EXPECT_TRUE(permissions2.Contains(result));
168  EXPECT_TRUE(permissions1.Contains(permissions2));
169  EXPECT_FALSE(permissions2.Contains(permissions1));
170  EXPECT_FALSE(result.Contains(permissions1));
171  EXPECT_TRUE(result.Contains(permissions2));
172
173  EXPECT_TRUE(result.empty());
174  EXPECT_EQ(expected_permissions, result);
175
176  // Now use a real second set.
177  permissions2.insert(new MockManifestPermission("p1"));
178  permissions2.insert(new MockManifestPermission("p3"));
179  permissions2.insert(new MockManifestPermission("p4"));
180  permissions2.insert(new MockManifestPermission("p5"));
181
182  expected_permissions.insert(new MockManifestPermission("p1"));
183  expected_permissions.insert(new MockManifestPermission("p3"));
184
185  ManifestPermissionSet::Intersection(permissions1, permissions2, &result);
186
187  EXPECT_TRUE(permissions1.Contains(result));
188  EXPECT_TRUE(permissions2.Contains(result));
189  EXPECT_FALSE(permissions1.Contains(permissions2));
190  EXPECT_FALSE(permissions2.Contains(permissions1));
191  EXPECT_FALSE(result.Contains(permissions1));
192  EXPECT_FALSE(result.Contains(permissions2));
193
194  EXPECT_EQ(expected_permissions, result);
195}
196
197TEST(ManifestPermissionSetTest, CreateDifference) {
198  ManifestPermissionSet permissions1;
199  ManifestPermissionSet permissions2;
200  ManifestPermissionSet expected_permissions;
201  ManifestPermissionSet result;
202
203  // Difference with an empty set.
204  permissions1.insert(new MockManifestPermission("p1"));
205  permissions1.insert(new MockManifestPermission("p2"));
206  permissions1.insert(new MockManifestPermission("p3"));
207
208  ManifestPermissionSet::Difference(permissions1, permissions2, &result);
209
210  EXPECT_EQ(permissions1, result);
211
212  // Now use a real second set.
213  permissions2.insert(new MockManifestPermission("p1"));
214  permissions2.insert(new MockManifestPermission("p2"));
215  permissions2.insert(new MockManifestPermission("p4"));
216  permissions2.insert(new MockManifestPermission("p5"));
217  permissions2.insert(new MockManifestPermission("p6"));
218
219  expected_permissions.insert(new MockManifestPermission("p3"));
220
221  ManifestPermissionSet::Difference(permissions1, permissions2, &result);
222
223  EXPECT_TRUE(permissions1.Contains(result));
224  EXPECT_FALSE(permissions2.Contains(result));
225
226  EXPECT_EQ(expected_permissions, result);
227
228  // |result| = |permissions1| - |permissions2| -->
229  //   |result| intersect |permissions2| == empty_set
230  ManifestPermissionSet result2;
231  ManifestPermissionSet::Intersection(result, permissions2, &result2);
232  EXPECT_TRUE(result2.empty());
233}
234
235}  // namespace extensions
236