1 // Copyright 2015 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/state_store.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/json/json_file_value_serializer.h"
9 #include "base/macros.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/test/test_simple_task_runner.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "base/values.h"
15 #include "chrome/browser/prefs/browser_prefs.h"
16 #include "chrome/browser/prefs/pref_service_syncable.h"
17 #include "chrome/browser/prefs/pref_service_syncable_factory.h"
18 #include "chrome/browser/safe_browsing/incident_reporting/incident.h"
19 #include "chrome/common/pref_names.h"
20 #include "chrome/test/base/testing_browser_process.h"
21 #include "chrome/test/base/testing_profile.h"
22 #include "chrome/test/base/testing_profile_manager.h"
23 #include "components/pref_registry/pref_registry_syncable.h"
24 #include "testing/gtest/include/gtest/gtest.h"
26 namespace safe_browsing
{
28 // A test fixture with a testing profile that writes its user prefs to a json
30 class StateStoreTest
: public ::testing::Test
{
40 task_runner_(new base::TestSimpleTaskRunner()),
41 thread_task_runner_handle_(task_runner_
),
42 profile_manager_(TestingBrowserProcess::GetGlobal()) {}
44 void SetUp() override
{
45 testing::Test::SetUp();
46 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
47 ASSERT_TRUE(profile_manager_
.SetUp());
51 void DeleteProfile() {
54 profile_manager_
.DeleteTestingProfile(kProfileName_
);
58 // Removes the safebrowsing.incidents_sent preference from the profile's pref
61 ASSERT_EQ(nullptr, profile_
);
62 scoped_ptr
<base::Value
> prefs(JSONFileValueDeserializer(GetPrefsPath())
63 .Deserialize(nullptr, nullptr));
64 ASSERT_NE(nullptr, prefs
.get());
65 base::DictionaryValue
* dict
= nullptr;
66 ASSERT_TRUE(prefs
->GetAsDictionary(&dict
));
67 ASSERT_TRUE(dict
->Remove(prefs::kSafeBrowsingIncidentsSent
, nullptr));
68 ASSERT_TRUE(JSONFileValueSerializer(GetPrefsPath()).Serialize(*dict
));
71 void CreateProfile() {
72 ASSERT_EQ(nullptr, profile_
);
73 // Create the testing profile with a file-backed user pref store.
74 PrefServiceSyncableFactory factory
;
75 factory
.SetUserPrefsFile(GetPrefsPath(), task_runner_
.get());
76 user_prefs::PrefRegistrySyncable
* pref_registry
=
77 new user_prefs::PrefRegistrySyncable();
78 chrome::RegisterUserProfilePrefs(pref_registry
);
79 profile_
= profile_manager_
.CreateTestingProfile(
80 kProfileName_
, factory
.CreateSyncable(pref_registry
).Pass(),
81 base::UTF8ToUTF16(kProfileName_
), 0, std::string(),
82 TestingProfile::TestingFactories());
85 static const char kProfileName_
[];
86 static const TestData kTestData_
[];
87 TestingProfile
* profile_
;
88 scoped_refptr
<base::TestSimpleTaskRunner
> task_runner_
;
91 base::FilePath
GetPrefsPath() {
92 return temp_dir_
.path().AppendASCII("prefs");
95 base::ScopedTempDir temp_dir_
;
96 base::ThreadTaskRunnerHandle thread_task_runner_handle_
;
97 TestingProfileManager profile_manager_
;
99 DISALLOW_COPY_AND_ASSIGN(StateStoreTest
);
103 const char StateStoreTest::kProfileName_
[] = "test_profile";
104 const StateStoreTest::TestData
StateStoreTest::kTestData_
[] = {
105 {IncidentType::TRACKED_PREFERENCE
, "tp_one", 1},
106 {IncidentType::TRACKED_PREFERENCE
, "tp_two", 2},
107 {IncidentType::TRACKED_PREFERENCE
, "tp_three", 3},
108 {IncidentType::BINARY_INTEGRITY
, "bi", 0},
109 {IncidentType::BLACKLIST_LOAD
, "bl", 0x47},
112 TEST_F(StateStoreTest
, MarkAsAndHasBeenReported
) {
113 StateStore
state_store(profile_
);
115 for (const auto& data
: kTestData_
)
116 ASSERT_FALSE(state_store
.HasBeenReported(data
.type
, data
.key
, data
.digest
));
119 StateStore::Transaction
transaction(&state_store
);
120 for (const auto& data
: kTestData_
) {
121 transaction
.MarkAsReported(data
.type
, data
.key
, data
.digest
);
123 state_store
.HasBeenReported(data
.type
, data
.key
, data
.digest
));
127 for (const auto& data
: kTestData_
)
128 ASSERT_TRUE(state_store
.HasBeenReported(data
.type
, data
.key
, data
.digest
));
131 TEST_F(StateStoreTest
, ClearForType
) {
132 StateStore
state_store(profile_
);
135 StateStore::Transaction
transaction(&state_store
);
136 for (const auto& data
: kTestData_
)
137 transaction
.MarkAsReported(data
.type
, data
.key
, data
.digest
);
140 for (const auto& data
: kTestData_
)
141 ASSERT_TRUE(state_store
.HasBeenReported(data
.type
, data
.key
, data
.digest
));
143 const IncidentType removed_type
= IncidentType::TRACKED_PREFERENCE
;
144 StateStore::Transaction(&state_store
).ClearForType(removed_type
);
146 for (const auto& data
: kTestData_
) {
147 if (data
.type
== removed_type
) {
149 state_store
.HasBeenReported(data
.type
, data
.key
, data
.digest
));
152 state_store
.HasBeenReported(data
.type
, data
.key
, data
.digest
));
157 TEST_F(StateStoreTest
, Persistence
) {
158 // Write some state to the store.
160 StateStore
state_store(profile_
);
161 StateStore::Transaction
transaction(&state_store
);
162 for (const auto& data
: kTestData_
)
163 transaction
.MarkAsReported(data
.type
, data
.key
, data
.digest
);
166 // Run tasks to write prefs out to the JsonPrefStore.
167 task_runner_
->RunUntilIdle();
169 // Delete the profile.
172 // Recreate the profile.
175 // Verify that the state survived.
176 StateStore
state_store(profile_
);
177 for (const auto& data
: kTestData_
)
178 ASSERT_TRUE(state_store
.HasBeenReported(data
.type
, data
.key
, data
.digest
));
181 TEST_F(StateStoreTest
, PersistenceWithStoreDelete
) {
182 // Write some state to the store.
184 StateStore
state_store(profile_
);
185 StateStore::Transaction
transaction(&state_store
);
186 for (const auto& data
: kTestData_
)
187 transaction
.MarkAsReported(data
.type
, data
.key
, data
.digest
);
190 // Run tasks to write prefs out to the JsonPrefStore.
191 task_runner_
->RunUntilIdle();
193 // Delete the profile.
196 // Delete the state pref.
199 // Recreate the profile.
202 // Verify that the state did not survive.
203 StateStore
state_store(profile_
);
204 for (const auto& data
: kTestData_
)
205 ASSERT_FALSE(state_store
.HasBeenReported(data
.type
, data
.key
, data
.digest
));
208 } // namespace safe_browsing