Refactor WebsiteSettings to operate on a SecurityInfo
[chromium-blink-merge.git] / chrome / browser / safe_browsing / incident_reporting / preference_validation_delegate_unittest.cc
blob0cf05ddd661a9fa47345259da0cbaafeeb3d88ae
1 // Copyright 2014 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.
5 #include "chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate.h"
7 #include <string>
8 #include <vector>
10 #include "base/bind.h"
11 #include "base/compiler_specific.h"
12 #include "base/memory/scoped_vector.h"
13 #include "base/values.h"
14 #include "chrome/browser/safe_browsing/incident_reporting/incident.h"
15 #include "chrome/browser/safe_browsing/incident_reporting/mock_incident_receiver.h"
16 #include "chrome/common/safe_browsing/csd.pb.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 using ::testing::_;
21 using ::testing::IsNull;
22 using ::testing::NiceMock;
23 using ::testing::WithArg;
25 // A basic test harness that creates a delegate instance for which it stores all
26 // incidents. Tests can push data to the delegate and verify that the test
27 // instance was provided with the expected data.
28 class PreferenceValidationDelegateTest : public testing::Test {
29 protected:
30 typedef ScopedVector<safe_browsing::Incident> IncidentVector;
32 PreferenceValidationDelegateTest()
33 : kPrefPath_("atomic.pref"),
34 null_value_(base::Value::CreateNullValue()) {}
36 void SetUp() override {
37 testing::Test::SetUp();
38 invalid_keys_.push_back(std::string("one"));
39 invalid_keys_.push_back(std::string("two"));
40 scoped_ptr<safe_browsing::MockIncidentReceiver> receiver(
41 new NiceMock<safe_browsing::MockIncidentReceiver>());
42 ON_CALL(*receiver, DoAddIncidentForProfile(IsNull(), _))
43 .WillByDefault(WithArg<1>(TakeIncidentToVector(&incidents_)));
44 instance_.reset(new safe_browsing::PreferenceValidationDelegate(
45 nullptr, receiver.Pass()));
48 static void ExpectValueStatesEquate(
49 PrefHashStoreTransaction::ValueState store_state,
50 safe_browsing::
51 ClientIncidentReport_IncidentData_TrackedPreferenceIncident_ValueState
52 incident_state) {
53 typedef safe_browsing::
54 ClientIncidentReport_IncidentData_TrackedPreferenceIncident TPIncident;
55 switch (store_state) {
56 case PrefHashStoreTransaction::CLEARED:
57 EXPECT_EQ(TPIncident::CLEARED, incident_state);
58 break;
59 case PrefHashStoreTransaction::CHANGED:
60 EXPECT_EQ(TPIncident::CHANGED, incident_state);
61 break;
62 case PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE:
63 EXPECT_EQ(TPIncident::UNTRUSTED_UNKNOWN_VALUE, incident_state);
64 break;
65 default:
66 FAIL() << "unexpected store state";
67 break;
71 static void ExpectKeysEquate(
72 const std::vector<std::string>& store_keys,
73 const google::protobuf::RepeatedPtrField<std::string>& incident_keys) {
74 ASSERT_EQ(store_keys.size(), static_cast<size_t>(incident_keys.size()));
75 for (int i = 0; i < incident_keys.size(); ++i) {
76 EXPECT_EQ(store_keys[i], incident_keys.Get(i));
80 const std::string kPrefPath_;
81 IncidentVector incidents_;
82 scoped_ptr<base::Value> null_value_;
83 base::DictionaryValue dict_value_;
84 std::vector<std::string> invalid_keys_;
85 scoped_ptr<TrackedPreferenceValidationDelegate> instance_;
88 // Tests that a NULL value results in an incident with no value.
89 TEST_F(PreferenceValidationDelegateTest, NullValue) {
90 instance_->OnAtomicPreferenceValidation(kPrefPath_,
91 NULL,
92 PrefHashStoreTransaction::CLEARED,
93 false /* is_personal */);
94 scoped_ptr<safe_browsing::ClientIncidentReport_IncidentData> incident(
95 incidents_.back()->TakePayload());
96 EXPECT_FALSE(incident->tracked_preference().has_atomic_value());
97 EXPECT_EQ(
98 safe_browsing::
99 ClientIncidentReport_IncidentData_TrackedPreferenceIncident::CLEARED,
100 incident->tracked_preference().value_state());
103 // Tests that all supported value types can be stringified into an incident. The
104 // parameters for the test are the type of value to test and the expected value
105 // string.
106 class PreferenceValidationDelegateValues
107 : public PreferenceValidationDelegateTest,
108 public testing::WithParamInterface<
109 std::tr1::tuple<base::Value::Type, const char*> > {
110 protected:
111 void SetUp() override {
112 PreferenceValidationDelegateTest::SetUp();
113 value_type_ = std::tr1::get<0>(GetParam());
114 expected_value_ = std::tr1::get<1>(GetParam());
117 static scoped_ptr<base::Value> MakeValue(base::Value::Type value_type) {
118 using base::Value;
119 switch (value_type) {
120 case Value::TYPE_NULL:
121 return Value::CreateNullValue();
122 case Value::TYPE_BOOLEAN:
123 return scoped_ptr<Value>(new base::FundamentalValue(false));
124 case Value::TYPE_INTEGER:
125 return scoped_ptr<Value>(new base::FundamentalValue(47));
126 case Value::TYPE_DOUBLE:
127 return scoped_ptr<Value>(new base::FundamentalValue(0.47));
128 case Value::TYPE_STRING:
129 return scoped_ptr<Value>(new base::StringValue("i have a spleen"));
130 case Value::TYPE_DICTIONARY: {
131 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
132 value->SetInteger("twenty-two", 22);
133 value->SetInteger("forty-seven", 47);
134 return value.Pass();
136 case Value::TYPE_LIST: {
137 scoped_ptr<base::ListValue> value(new base::ListValue());
138 value->AppendInteger(22);
139 value->AppendInteger(47);
140 return value.Pass();
142 default:
143 ADD_FAILURE() << "unsupported value type " << value_type;
145 return scoped_ptr<Value>();
148 base::Value::Type value_type_;
149 const char* expected_value_;
152 TEST_P(PreferenceValidationDelegateValues, Value) {
153 instance_->OnAtomicPreferenceValidation(kPrefPath_,
154 MakeValue(value_type_).get(),
155 PrefHashStoreTransaction::CLEARED,
156 false /* is_personal */);
157 ASSERT_EQ(1U, incidents_.size());
158 scoped_ptr<safe_browsing::ClientIncidentReport_IncidentData> incident(
159 incidents_.back()->TakePayload());
160 EXPECT_EQ(std::string(expected_value_),
161 incident->tracked_preference().atomic_value());
164 INSTANTIATE_TEST_CASE_P(
165 Values,
166 PreferenceValidationDelegateValues,
167 // On Android, make_tuple(..., "null") doesn't compile due to the error:
168 // testing/gtest/include/gtest/internal/gtest-tuple.h:246:48:
169 // error: array used as initializer
170 testing::Values(
171 std::tr1::make_tuple(base::Value::TYPE_NULL,
172 const_cast<char*>("null")),
173 std::tr1::make_tuple(base::Value::TYPE_BOOLEAN,
174 const_cast<char*>("false")),
175 std::tr1::make_tuple(base::Value::TYPE_INTEGER,
176 const_cast<char*>("47")),
177 std::tr1::make_tuple(base::Value::TYPE_DOUBLE,
178 const_cast<char*>("0.47")),
179 std::tr1::make_tuple(base::Value::TYPE_STRING,
180 const_cast<char*>("i have a spleen")),
181 std::tr1::make_tuple(base::Value::TYPE_DICTIONARY,
182 const_cast<char*>("{\"forty-seven\":47,\"twenty-two\":22}")),
183 std::tr1::make_tuple(base::Value::TYPE_LIST,
184 const_cast<char*>("[22,47]"))));
186 // Tests that no incidents are reported for relevant combinations of ValueState.
187 class PreferenceValidationDelegateNoIncident
188 : public PreferenceValidationDelegateTest,
189 public testing::WithParamInterface<PrefHashStoreTransaction::ValueState> {
190 protected:
191 void SetUp() override {
192 PreferenceValidationDelegateTest::SetUp();
193 value_state_ = GetParam();
196 PrefHashStoreTransaction::ValueState value_state_;
199 TEST_P(PreferenceValidationDelegateNoIncident, Atomic) {
200 instance_->OnAtomicPreferenceValidation(kPrefPath_,
201 null_value_.get(),
202 value_state_,
203 false /* is_personal */);
204 EXPECT_EQ(0U, incidents_.size());
207 TEST_P(PreferenceValidationDelegateNoIncident, Split) {
208 instance_->OnSplitPreferenceValidation(kPrefPath_,
209 &dict_value_,
210 invalid_keys_,
211 value_state_,
212 false /* is_personal */);
213 EXPECT_EQ(0U, incidents_.size());
216 INSTANTIATE_TEST_CASE_P(
217 NoIncident,
218 PreferenceValidationDelegateNoIncident,
219 testing::Values(PrefHashStoreTransaction::UNCHANGED,
220 PrefHashStoreTransaction::SECURE_LEGACY,
221 PrefHashStoreTransaction::TRUSTED_UNKNOWN_VALUE));
223 // Tests that incidents are reported for relevant combinations of ValueState and
224 // impersonal/personal.
225 class PreferenceValidationDelegateWithIncident
226 : public PreferenceValidationDelegateTest,
227 public testing::WithParamInterface<
228 std::tr1::tuple<PrefHashStoreTransaction::ValueState, bool>> {
229 protected:
230 void SetUp() override {
231 PreferenceValidationDelegateTest::SetUp();
232 value_state_ = std::tr1::get<0>(GetParam());
233 is_personal_ = std::tr1::get<1>(GetParam());
236 PrefHashStoreTransaction::ValueState value_state_;
237 bool is_personal_;
240 TEST_P(PreferenceValidationDelegateWithIncident, Atomic) {
241 instance_->OnAtomicPreferenceValidation(
242 kPrefPath_, null_value_.get(), value_state_, is_personal_);
243 ASSERT_EQ(1U, incidents_.size());
244 scoped_ptr<safe_browsing::ClientIncidentReport_IncidentData> incident(
245 incidents_.back()->TakePayload());
246 EXPECT_TRUE(incident->has_tracked_preference());
247 const safe_browsing::
248 ClientIncidentReport_IncidentData_TrackedPreferenceIncident& tp_incident =
249 incident->tracked_preference();
250 EXPECT_EQ(kPrefPath_, tp_incident.path());
251 EXPECT_EQ(0, tp_incident.split_key_size());
252 if (!is_personal_) {
253 EXPECT_TRUE(tp_incident.has_atomic_value());
254 EXPECT_EQ(std::string("null"), tp_incident.atomic_value());
255 } else {
256 EXPECT_FALSE(tp_incident.has_atomic_value());
258 EXPECT_TRUE(tp_incident.has_value_state());
259 ExpectValueStatesEquate(value_state_, tp_incident.value_state());
262 TEST_P(PreferenceValidationDelegateWithIncident, Split) {
263 instance_->OnSplitPreferenceValidation(
264 kPrefPath_, &dict_value_, invalid_keys_, value_state_, is_personal_);
265 ASSERT_EQ(1U, incidents_.size());
266 scoped_ptr<safe_browsing::ClientIncidentReport_IncidentData> incident(
267 incidents_.back()->TakePayload());
268 EXPECT_TRUE(incident->has_tracked_preference());
269 const safe_browsing::
270 ClientIncidentReport_IncidentData_TrackedPreferenceIncident& tp_incident =
271 incident->tracked_preference();
272 EXPECT_EQ(kPrefPath_, tp_incident.path());
273 EXPECT_FALSE(tp_incident.has_atomic_value());
274 if (!is_personal_)
275 ExpectKeysEquate(invalid_keys_, tp_incident.split_key());
276 else
277 EXPECT_EQ(0, tp_incident.split_key_size());
278 EXPECT_TRUE(tp_incident.has_value_state());
279 ExpectValueStatesEquate(value_state_, tp_incident.value_state());
282 INSTANTIATE_TEST_CASE_P(
283 WithIncident,
284 PreferenceValidationDelegateWithIncident,
285 testing::Combine(
286 testing::Values(PrefHashStoreTransaction::CLEARED,
287 PrefHashStoreTransaction::CHANGED,
288 PrefHashStoreTransaction::UNTRUSTED_UNKNOWN_VALUE),
289 testing::Bool()));