Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / extensions / activity_log / fullstream_ui_policy_unittest.cc
bloba96d0d368fda62539974f86260ead860b0ad61a7
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.
5 #include "base/cancelable_callback.h"
6 #include "base/command_line.h"
7 #include "base/location.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/run_loop.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/synchronization/waitable_event.h"
13 #include "base/test/simple_test_clock.h"
14 #include "base/test/test_timeouts.h"
15 #include "base/thread_task_runner_handle.h"
16 #include "chrome/browser/extensions/activity_log/activity_log.h"
17 #include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h"
18 #include "chrome/browser/extensions/extension_service.h"
19 #include "chrome/browser/extensions/test_extension_system.h"
20 #include "chrome/common/chrome_constants.h"
21 #include "chrome/common/chrome_switches.h"
22 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
23 #include "chrome/test/base/testing_profile.h"
24 #include "content/public/test/test_browser_thread_bundle.h"
25 #include "extensions/common/extension_builder.h"
26 #include "testing/gtest/include/gtest/gtest.h"
28 #if defined(OS_CHROMEOS)
29 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
30 #include "chrome/browser/chromeos/settings/cros_settings.h"
31 #include "chrome/browser/chromeos/settings/device_settings_service.h"
32 #endif
34 using content::BrowserThread;
36 namespace extensions {
38 class FullStreamUIPolicyTest : public testing::Test {
39 public:
40 FullStreamUIPolicyTest()
41 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
42 saved_cmdline_(base::CommandLine::NO_PROGRAM) {
43 #if defined OS_CHROMEOS
44 test_user_manager_.reset(new chromeos::ScopedTestUserManager());
45 #endif
46 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
47 saved_cmdline_ = *base::CommandLine::ForCurrentProcess();
48 profile_.reset(new TestingProfile());
49 base::CommandLine::ForCurrentProcess()->AppendSwitch(
50 switches::kEnableExtensionActivityLogging);
51 base::CommandLine::ForCurrentProcess()->AppendSwitch(
52 switches::kEnableExtensionActivityLogTesting);
53 extension_service_ = static_cast<TestExtensionSystem*>(
54 ExtensionSystem::Get(profile_.get()))->CreateExtensionService
55 (&command_line, base::FilePath(), false);
58 ~FullStreamUIPolicyTest() override {
59 #if defined OS_CHROMEOS
60 test_user_manager_.reset();
61 #endif
62 base::RunLoop().RunUntilIdle();
63 profile_.reset(NULL);
64 base::RunLoop().RunUntilIdle();
65 // Restore the original command line and undo the affects of SetUp().
66 *base::CommandLine::ForCurrentProcess() = saved_cmdline_;
69 // A wrapper function for CheckReadFilteredData, so that we don't need to
70 // enter empty string values for parameters we don't care about.
71 void CheckReadData(
72 ActivityLogDatabasePolicy* policy,
73 const std::string& extension_id,
74 int day,
75 const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker) {
76 CheckReadFilteredData(
77 policy, extension_id, Action::ACTION_ANY, "", "", "", day, checker);
80 // A helper function to call ReadFilteredData on a policy object and wait for
81 // the results to be processed.
82 void CheckReadFilteredData(
83 ActivityLogDatabasePolicy* policy,
84 const std::string& extension_id,
85 const Action::ActionType type,
86 const std::string& api_name,
87 const std::string& page_url,
88 const std::string& arg_url,
89 const int days_ago,
90 const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker) {
91 // Submit a request to the policy to read back some data, and call the
92 // checker function when results are available. This will happen on the
93 // database thread.
94 policy->ReadFilteredData(
95 extension_id,
96 type,
97 api_name,
98 page_url,
99 arg_url,
100 days_ago,
101 base::Bind(&FullStreamUIPolicyTest::CheckWrapper,
102 checker,
103 base::MessageLoop::current()->QuitClosure()));
105 // Set up a timeout for receiving results; if we haven't received anything
106 // when the timeout triggers then assume that the test is broken.
107 base::CancelableClosure timeout(
108 base::Bind(&FullStreamUIPolicyTest::TimeoutCallback));
109 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
110 FROM_HERE, timeout.callback(), TestTimeouts::action_timeout());
112 // Wait for results; either the checker or the timeout callbacks should
113 // cause the main loop to exit.
114 base::MessageLoop::current()->Run();
116 timeout.Cancel();
119 static void CheckWrapper(
120 const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker,
121 const base::Closure& done,
122 scoped_ptr<Action::ActionVector> results) {
123 checker.Run(results.Pass());
124 done.Run();
127 static void TimeoutCallback() {
128 base::MessageLoop::current()->QuitWhenIdle();
129 FAIL() << "Policy test timed out waiting for results";
132 static void RetrieveActions_LogAndFetchActions(
133 scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
134 ASSERT_EQ(2, static_cast<int>(i->size()));
137 static void RetrieveActions_FetchFilteredActions0(
138 scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
139 ASSERT_EQ(0, static_cast<int>(i->size()));
142 static void RetrieveActions_FetchFilteredActions1(
143 scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
144 ASSERT_EQ(1, static_cast<int>(i->size()));
147 static void RetrieveActions_FetchFilteredActions2(
148 scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
149 ASSERT_EQ(2, static_cast<int>(i->size()));
152 static void RetrieveActions_FetchFilteredActions300(
153 scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
154 ASSERT_EQ(300, static_cast<int>(i->size()));
157 static void Arguments_Present(scoped_ptr<Action::ActionVector> i) {
158 scoped_refptr<Action> last = i->front();
159 CheckAction(*last.get(),
160 "odlameecjipmbmbejkplpemijjgpljce",
161 Action::ACTION_API_CALL,
162 "extension.connect",
163 "[\"hello\",\"world\"]",
166 "");
169 static void Arguments_GetTodaysActions(
170 scoped_ptr<Action::ActionVector> actions) {
171 ASSERT_EQ(2, static_cast<int>(actions->size()));
172 CheckAction(*actions->at(0).get(),
173 "punky",
174 Action::ACTION_DOM_ACCESS,
175 "lets",
176 "[\"vamoose\"]",
177 "http://www.google.com/",
178 "Page Title",
179 "http://www.arg-url.com/");
180 CheckAction(*actions->at(1).get(),
181 "punky",
182 Action::ACTION_API_CALL,
183 "brewster",
184 "[\"woof\"]",
186 "Page Title",
187 "http://www.arg-url.com/");
190 static void Arguments_GetOlderActions(
191 scoped_ptr<Action::ActionVector> actions) {
192 ASSERT_EQ(2, static_cast<int>(actions->size()));
193 CheckAction(*actions->at(0).get(),
194 "punky",
195 Action::ACTION_DOM_ACCESS,
196 "lets",
197 "[\"vamoose\"]",
198 "http://www.google.com/",
200 "");
201 CheckAction(*actions->at(1).get(),
202 "punky",
203 Action::ACTION_API_CALL,
204 "brewster",
205 "[\"woof\"]",
208 "");
211 static void AllURLsRemoved(scoped_ptr<Action::ActionVector> actions) {
212 ASSERT_EQ(2, static_cast<int>(actions->size()));
213 CheckAction(*actions->at(0).get(),
214 "punky",
215 Action::ACTION_API_CALL,
216 "lets",
217 "[\"vamoose\"]",
220 "");
221 CheckAction(*actions->at(1).get(),
222 "punky",
223 Action::ACTION_DOM_ACCESS,
224 "lets",
225 "[\"vamoose\"]",
228 "");
231 static void SomeURLsRemoved(scoped_ptr<Action::ActionVector> actions) {
232 // These will be in the vector in reverse time order.
233 ASSERT_EQ(5, static_cast<int>(actions->size()));
234 CheckAction(*actions->at(0).get(),
235 "punky",
236 Action::ACTION_DOM_ACCESS,
237 "lets",
238 "[\"vamoose\"]",
239 "http://www.google.com/",
240 "Google",
241 "http://www.args-url.com/");
242 CheckAction(*actions->at(1).get(),
243 "punky",
244 Action::ACTION_DOM_ACCESS,
245 "lets",
246 "[\"vamoose\"]",
247 "http://www.google.com/",
248 "Google",
249 "");
250 CheckAction(*actions->at(2).get(),
251 "punky",
252 Action::ACTION_DOM_ACCESS,
253 "lets",
254 "[\"vamoose\"]",
257 "");
258 CheckAction(*actions->at(3).get(),
259 "punky",
260 Action::ACTION_DOM_ACCESS,
261 "lets",
262 "[\"vamoose\"]",
265 "http://www.google.com/");
266 CheckAction(*actions->at(4).get(),
267 "punky",
268 Action::ACTION_DOM_ACCESS,
269 "lets",
270 "[\"vamoose\"]",
273 "");
276 static void CheckAction(const Action& action,
277 const std::string& expected_id,
278 const Action::ActionType& expected_type,
279 const std::string& expected_api_name,
280 const std::string& expected_args_str,
281 const std::string& expected_page_url,
282 const std::string& expected_page_title,
283 const std::string& expected_arg_url) {
284 ASSERT_EQ(expected_id, action.extension_id());
285 ASSERT_EQ(expected_type, action.action_type());
286 ASSERT_EQ(expected_api_name, action.api_name());
287 ASSERT_EQ(expected_args_str,
288 ActivityLogPolicy::Util::Serialize(action.args()));
289 ASSERT_EQ(expected_page_url, action.SerializePageUrl());
290 ASSERT_EQ(expected_page_title, action.page_title());
291 ASSERT_EQ(expected_arg_url, action.SerializeArgUrl());
292 ASSERT_NE(-1, action.action_id());
295 // A helper function initializes the policy with a number of actions, calls
296 // RemoveActions on a policy object and then checks the result of the
297 // deletion.
298 void CheckRemoveActions(
299 ActivityLogDatabasePolicy* policy,
300 const std::vector<int64>& action_ids,
301 const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker) {
303 // Use a mock clock to ensure that events are not recorded on the wrong day
304 // when the test is run close to local midnight.
305 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
306 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
307 base::TimeDelta::FromHours(12));
308 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
310 // Record some actions
311 scoped_refptr<Action> action =
312 new Action("punky1",
313 mock_clock->Now() - base::TimeDelta::FromMinutes(40),
314 Action::ACTION_DOM_ACCESS,
315 "lets1");
316 action->mutable_args()->AppendString("vamoose1");
317 action->set_page_url(GURL("http://www.google1.com"));
318 action->set_page_title("Google1");
319 action->set_arg_url(GURL("http://www.args-url1.com"));
320 policy->ProcessAction(action);
321 // Record the same action twice, so there are multiple entries in the
322 // database.
323 policy->ProcessAction(action);
325 action = new Action("punky2",
326 mock_clock->Now() - base::TimeDelta::FromMinutes(30),
327 Action::ACTION_API_CALL,
328 "lets2");
329 action->mutable_args()->AppendString("vamoose2");
330 action->set_page_url(GURL("http://www.google2.com"));
331 action->set_page_title("Google2");
332 action->set_arg_url(GURL("http://www.args-url2.com"));
333 policy->ProcessAction(action);
334 // Record the same action twice, so there are multiple entries in the
335 // database.
336 policy->ProcessAction(action);
338 // Submit a request to delete actions.
339 policy->RemoveActions(action_ids);
341 // Check the result of the deletion. The checker function gets all
342 // activities in the database.
343 CheckReadData(policy, "", -1, checker);
345 // Clean database.
346 policy->DeleteDatabase();
349 static void AllActionsDeleted(scoped_ptr<Action::ActionVector> actions) {
350 ASSERT_EQ(0, static_cast<int>(actions->size()));
353 static void NoActionsDeleted(scoped_ptr<Action::ActionVector> actions) {
354 // These will be in the vector in reverse time order.
355 ASSERT_EQ(4, static_cast<int>(actions->size()));
356 CheckAction(*actions->at(0).get(),
357 "punky2",
358 Action::ACTION_API_CALL,
359 "lets2",
360 "[\"vamoose2\"]",
361 "http://www.google2.com/",
362 "Google2",
363 "http://www.args-url2.com/");
364 ASSERT_EQ(3, actions->at(0)->action_id());
365 CheckAction(*actions->at(1).get(),
366 "punky2",
367 Action::ACTION_API_CALL,
368 "lets2",
369 "[\"vamoose2\"]",
370 "http://www.google2.com/",
371 "Google2",
372 "http://www.args-url2.com/");
373 ASSERT_EQ(4, actions->at(1)->action_id());
374 CheckAction(*actions->at(2).get(),
375 "punky1",
376 Action::ACTION_DOM_ACCESS,
377 "lets1",
378 "[\"vamoose1\"]",
379 "http://www.google1.com/",
380 "Google1",
381 "http://www.args-url1.com/");
382 ASSERT_EQ(1, actions->at(2)->action_id());
383 CheckAction(*actions->at(3).get(),
384 "punky1",
385 Action::ACTION_DOM_ACCESS,
386 "lets1",
387 "[\"vamoose1\"]",
388 "http://www.google1.com/",
389 "Google1",
390 "http://www.args-url1.com/");
391 ASSERT_EQ(2, actions->at(3)->action_id());
394 static void Action1Deleted(scoped_ptr<Action::ActionVector> actions) {
395 // These will be in the vector in reverse time order.
396 ASSERT_EQ(2, static_cast<int>(actions->size()));
397 CheckAction(*actions->at(0).get(),
398 "punky2",
399 Action::ACTION_API_CALL,
400 "lets2",
401 "[\"vamoose2\"]",
402 "http://www.google2.com/",
403 "Google2",
404 "http://www.args-url2.com/");
405 ASSERT_EQ(3, actions->at(0)->action_id());
406 CheckAction(*actions->at(1).get(),
407 "punky2",
408 Action::ACTION_API_CALL,
409 "lets2",
410 "[\"vamoose2\"]",
411 "http://www.google2.com/",
412 "Google2",
413 "http://www.args-url2.com/");
414 ASSERT_EQ(4, actions->at(1)->action_id());
417 static void Action2Deleted(scoped_ptr<Action::ActionVector> actions) {
418 // These will be in the vector in reverse time order.
419 ASSERT_EQ(2, static_cast<int>(actions->size()));
420 CheckAction(*actions->at(0).get(),
421 "punky1",
422 Action::ACTION_DOM_ACCESS,
423 "lets1",
424 "[\"vamoose1\"]",
425 "http://www.google1.com/",
426 "Google1",
427 "http://www.args-url1.com/");
428 ASSERT_EQ(1, actions->at(0)->action_id());
429 CheckAction(*actions->at(1).get(),
430 "punky1",
431 Action::ACTION_DOM_ACCESS,
432 "lets1",
433 "[\"vamoose1\"]",
434 "http://www.google1.com/",
435 "Google1",
436 "http://www.args-url1.com/");
437 ASSERT_EQ(2, actions->at(1)->action_id());
440 protected:
441 ExtensionService* extension_service_;
442 scoped_ptr<TestingProfile> profile_;
443 content::TestBrowserThreadBundle thread_bundle_;
444 // Used to preserve a copy of the original command line.
445 // The test framework will do this itself as well. However, by then,
446 // it is too late to call ActivityLog::RecomputeLoggingIsEnabled() in
447 // TearDown().
448 base::CommandLine saved_cmdline_;
450 #if defined OS_CHROMEOS
451 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
452 chromeos::ScopedTestCrosSettings test_cros_settings_;
453 scoped_ptr<chromeos::ScopedTestUserManager> test_user_manager_;
454 #endif
457 TEST_F(FullStreamUIPolicyTest, Construct) {
458 ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get());
459 policy->Init();
460 scoped_refptr<const Extension> extension =
461 ExtensionBuilder()
462 .SetManifest(DictionaryBuilder()
463 .Set("name", "Test extension")
464 .Set("version", "1.0.0")
465 .Set("manifest_version", 2))
466 .Build();
467 extension_service_->AddExtension(extension.get());
468 scoped_ptr<base::ListValue> args(new base::ListValue());
469 scoped_refptr<Action> action = new Action(extension->id(),
470 base::Time::Now(),
471 Action::ACTION_API_CALL,
472 "tabs.testMethod");
473 action->set_args(args.Pass());
474 policy->ProcessAction(action);
475 policy->Close();
478 TEST_F(FullStreamUIPolicyTest, LogAndFetchActions) {
479 ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get());
480 policy->Init();
481 scoped_refptr<const Extension> extension =
482 ExtensionBuilder()
483 .SetManifest(DictionaryBuilder()
484 .Set("name", "Test extension")
485 .Set("version", "1.0.0")
486 .Set("manifest_version", 2))
487 .Build();
488 extension_service_->AddExtension(extension.get());
489 GURL gurl("http://www.google.com");
491 // Write some API calls
492 scoped_refptr<Action> action_api = new Action(extension->id(),
493 base::Time::Now(),
494 Action::ACTION_API_CALL,
495 "tabs.testMethod");
496 action_api->set_args(make_scoped_ptr(new base::ListValue()));
497 policy->ProcessAction(action_api);
499 scoped_refptr<Action> action_dom = new Action(extension->id(),
500 base::Time::Now(),
501 Action::ACTION_DOM_ACCESS,
502 "document.write");
503 action_dom->set_args(make_scoped_ptr(new base::ListValue()));
504 action_dom->set_page_url(gurl);
505 policy->ProcessAction(action_dom);
507 CheckReadData(
508 policy,
509 extension->id(),
511 base::Bind(&FullStreamUIPolicyTest::RetrieveActions_LogAndFetchActions));
513 policy->Close();
516 TEST_F(FullStreamUIPolicyTest, LogAndFetchFilteredActions) {
517 ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get());
518 policy->Init();
519 scoped_refptr<const Extension> extension =
520 ExtensionBuilder()
521 .SetManifest(DictionaryBuilder()
522 .Set("name", "Test extension")
523 .Set("version", "1.0.0")
524 .Set("manifest_version", 2))
525 .Build();
526 extension_service_->AddExtension(extension.get());
527 GURL gurl("http://www.google.com");
529 // Write some API calls
530 scoped_refptr<Action> action_api = new Action(extension->id(),
531 base::Time::Now(),
532 Action::ACTION_API_CALL,
533 "tabs.testMethod");
534 action_api->set_args(make_scoped_ptr(new base::ListValue()));
535 policy->ProcessAction(action_api);
537 scoped_refptr<Action> action_dom = new Action(extension->id(),
538 base::Time::Now(),
539 Action::ACTION_DOM_ACCESS,
540 "document.write");
541 action_dom->set_args(make_scoped_ptr(new base::ListValue()));
542 action_dom->set_page_url(gurl);
543 policy->ProcessAction(action_dom);
545 CheckReadFilteredData(
546 policy,
547 extension->id(),
548 Action::ACTION_API_CALL,
549 "tabs.testMethod",
553 base::Bind(
554 &FullStreamUIPolicyTest::RetrieveActions_FetchFilteredActions1));
556 CheckReadFilteredData(
557 policy,
559 Action::ACTION_DOM_ACCESS,
564 base::Bind(
565 &FullStreamUIPolicyTest::RetrieveActions_FetchFilteredActions1));
567 CheckReadFilteredData(
568 policy,
570 Action::ACTION_DOM_ACCESS,
572 "http://www.google.com/",
575 base::Bind(
576 &FullStreamUIPolicyTest::RetrieveActions_FetchFilteredActions1));
578 CheckReadFilteredData(
579 policy,
581 Action::ACTION_DOM_ACCESS,
583 "http://www.google.com",
586 base::Bind(
587 &FullStreamUIPolicyTest::RetrieveActions_FetchFilteredActions1));
589 CheckReadFilteredData(
590 policy,
592 Action::ACTION_DOM_ACCESS,
594 "http://www.goo",
597 base::Bind(
598 &FullStreamUIPolicyTest::RetrieveActions_FetchFilteredActions1));
600 CheckReadFilteredData(
601 policy,
602 extension->id(),
603 Action::ACTION_ANY,
608 base::Bind(
609 &FullStreamUIPolicyTest::RetrieveActions_FetchFilteredActions2));
611 policy->Close();
614 TEST_F(FullStreamUIPolicyTest, LogWithArguments) {
615 ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get());
616 policy->Init();
617 scoped_refptr<const Extension> extension =
618 ExtensionBuilder()
619 .SetManifest(DictionaryBuilder()
620 .Set("name", "Test extension")
621 .Set("version", "1.0.0")
622 .Set("manifest_version", 2))
623 .Build();
624 extension_service_->AddExtension(extension.get());
626 scoped_ptr<base::ListValue> args(new base::ListValue());
627 args->Set(0, new base::StringValue("hello"));
628 args->Set(1, new base::StringValue("world"));
629 scoped_refptr<Action> action = new Action(extension->id(),
630 base::Time::Now(),
631 Action::ACTION_API_CALL,
632 "extension.connect");
633 action->set_args(args.Pass());
635 policy->ProcessAction(action);
636 CheckReadData(policy,
637 extension->id(),
639 base::Bind(&FullStreamUIPolicyTest::Arguments_Present));
640 policy->Close();
643 TEST_F(FullStreamUIPolicyTest, GetTodaysActions) {
644 ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get());
645 policy->Init();
647 // Use a mock clock to ensure that events are not recorded on the wrong day
648 // when the test is run close to local midnight. Note: Ownership is passed
649 // to the policy, but we still keep a pointer locally. The policy will take
650 // care of destruction; this is safe since the policy outlives all our
651 // accesses to the mock clock.
652 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
653 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
654 base::TimeDelta::FromHours(12));
655 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
657 // Record some actions
658 scoped_refptr<Action> action =
659 new Action("punky",
660 mock_clock->Now() - base::TimeDelta::FromMinutes(40),
661 Action::ACTION_API_CALL,
662 "brewster");
663 action->mutable_args()->AppendString("woof");
664 action->set_arg_url(GURL("http://www.arg-url.com"));
665 action->set_page_title("Page Title");
666 policy->ProcessAction(action);
668 action =
669 new Action("punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
670 action->mutable_args()->AppendString("vamoose");
671 action->set_page_url(GURL("http://www.google.com"));
672 action->set_arg_url(GURL("http://www.arg-url.com"));
673 action->set_page_title("Page Title");
674 policy->ProcessAction(action);
676 action = new Action(
677 "scoobydoo", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
678 action->mutable_args()->AppendString("vamoose");
679 action->set_page_url(GURL("http://www.google.com"));
680 action->set_arg_url(GURL("http://www.arg-url.com"));
681 policy->ProcessAction(action);
683 CheckReadData(
684 policy,
685 "punky",
687 base::Bind(&FullStreamUIPolicyTest::Arguments_GetTodaysActions));
688 policy->Close();
691 // Check that we can read back less recent actions in the db.
692 TEST_F(FullStreamUIPolicyTest, GetOlderActions) {
693 ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get());
694 policy->Init();
696 // Use a mock clock to ensure that events are not recorded on the wrong day
697 // when the test is run close to local midnight.
698 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
699 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
700 base::TimeDelta::FromHours(12));
701 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
703 // Record some actions
704 scoped_refptr<Action> action =
705 new Action("punky",
706 mock_clock->Now() - base::TimeDelta::FromDays(3) -
707 base::TimeDelta::FromMinutes(40),
708 Action::ACTION_API_CALL,
709 "brewster");
710 action->mutable_args()->AppendString("woof");
711 policy->ProcessAction(action);
713 action = new Action("punky",
714 mock_clock->Now() - base::TimeDelta::FromDays(3),
715 Action::ACTION_DOM_ACCESS,
716 "lets");
717 action->mutable_args()->AppendString("vamoose");
718 action->set_page_url(GURL("http://www.google.com"));
719 policy->ProcessAction(action);
721 action = new Action("punky",
722 mock_clock->Now(),
723 Action::ACTION_DOM_ACCESS,
724 "lets");
725 action->mutable_args()->AppendString("too new");
726 action->set_page_url(GURL("http://www.google.com"));
727 policy->ProcessAction(action);
729 action = new Action("punky",
730 mock_clock->Now() - base::TimeDelta::FromDays(7),
731 Action::ACTION_DOM_ACCESS,
732 "lets");
733 action->mutable_args()->AppendString("too old");
734 action->set_page_url(GURL("http://www.google.com"));
735 policy->ProcessAction(action);
737 CheckReadData(
738 policy,
739 "punky",
741 base::Bind(&FullStreamUIPolicyTest::Arguments_GetOlderActions));
742 policy->Close();
745 TEST_F(FullStreamUIPolicyTest, RemoveAllURLs) {
746 ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get());
747 policy->Init();
749 // Use a mock clock to ensure that events are not recorded on the wrong day
750 // when the test is run close to local midnight.
751 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
752 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
753 base::TimeDelta::FromHours(12));
754 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
756 // Record some actions
757 scoped_refptr<Action> action =
758 new Action("punky", mock_clock->Now(),
759 Action::ACTION_DOM_ACCESS, "lets");
760 action->mutable_args()->AppendString("vamoose");
761 action->set_page_url(GURL("http://www.google.com"));
762 action->set_page_title("Google");
763 action->set_arg_url(GURL("http://www.google.com"));
764 policy->ProcessAction(action);
766 mock_clock->Advance(base::TimeDelta::FromSeconds(1));
767 action = new Action(
768 "punky", mock_clock->Now(), Action::ACTION_API_CALL, "lets");
769 action->mutable_args()->AppendString("vamoose");
770 action->set_page_url(GURL("http://www.google2.com"));
771 action->set_page_title("Google");
772 // Deliberately no arg url set to make sure it still works when there is no
773 // arg url.
774 policy->ProcessAction(action);
776 // Clean all the URLs.
777 std::vector<GURL> no_url_restrictions;
778 policy->RemoveURLs(no_url_restrictions);
780 CheckReadData(
781 policy,
782 "punky",
784 base::Bind(&FullStreamUIPolicyTest::AllURLsRemoved));
785 policy->Close();
788 TEST_F(FullStreamUIPolicyTest, RemoveSpecificURLs) {
789 ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get());
790 policy->Init();
792 // Use a mock clock to ensure that events are not recorded on the wrong day
793 // when the test is run close to local midnight.
794 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
795 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
796 base::TimeDelta::FromHours(12));
797 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
799 // Record some actions
800 // This should have the page url and args url cleared.
801 scoped_refptr<Action> action = new Action("punky", mock_clock->Now(),
802 Action::ACTION_DOM_ACCESS, "lets");
803 action->mutable_args()->AppendString("vamoose");
804 action->set_page_url(GURL("http://www.google1.com"));
805 action->set_page_title("Google");
806 action->set_arg_url(GURL("http://www.google1.com"));
807 policy->ProcessAction(action);
809 // This should have the page url cleared but not args url.
810 mock_clock->Advance(base::TimeDelta::FromSeconds(1));
811 action = new Action(
812 "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
813 action->mutable_args()->AppendString("vamoose");
814 action->set_page_url(GURL("http://www.google1.com"));
815 action->set_page_title("Google");
816 action->set_arg_url(GURL("http://www.google.com"));
817 policy->ProcessAction(action);
819 // This should have the page url cleared. The args url is deliberately not set
820 // to make sure this doesn't cause any issues.
821 mock_clock->Advance(base::TimeDelta::FromSeconds(1));
822 action = new Action(
823 "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
824 action->mutable_args()->AppendString("vamoose");
825 action->set_page_url(GURL("http://www.google2.com"));
826 action->set_page_title("Google");
827 policy->ProcessAction(action);
829 // This should have the args url cleared but not the page url or page title.
830 mock_clock->Advance(base::TimeDelta::FromSeconds(1));
831 action = new Action(
832 "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
833 action->mutable_args()->AppendString("vamoose");
834 action->set_page_url(GURL("http://www.google.com"));
835 action->set_page_title("Google");
836 action->set_arg_url(GURL("http://www.google1.com"));
837 policy->ProcessAction(action);
839 // This should have neither cleared.
840 mock_clock->Advance(base::TimeDelta::FromSeconds(1));
841 action = new Action(
842 "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
843 action->mutable_args()->AppendString("vamoose");
844 action->set_page_url(GURL("http://www.google.com"));
845 action->set_page_title("Google");
846 action->set_arg_url(GURL("http://www.args-url.com"));
847 policy->ProcessAction(action);
849 // Clean some URLs.
850 std::vector<GURL> urls;
851 urls.push_back(GURL("http://www.google1.com"));
852 urls.push_back(GURL("http://www.google2.com"));
853 urls.push_back(GURL("http://www.url_not_in_db.com"));
854 policy->RemoveURLs(urls);
856 CheckReadData(
857 policy,
858 "punky",
860 base::Bind(&FullStreamUIPolicyTest::SomeURLsRemoved));
861 policy->Close();
864 TEST_F(FullStreamUIPolicyTest, RemoveExtensionData) {
865 FullStreamUIPolicy* policy = new FullStreamUIPolicy(profile_.get());
866 policy->Init();
868 // Use a mock clock to ensure that events are not recorded on the wrong day
869 // when the test is run close to local midnight.
870 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
871 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
872 base::TimeDelta::FromHours(12));
873 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
875 // Record some actions
876 scoped_refptr<Action> action = new Action("deleteextensiondata",
877 mock_clock->Now(),
878 Action::ACTION_DOM_ACCESS,
879 "lets");
880 action->mutable_args()->AppendString("vamoose");
881 action->set_page_title("Google");
882 action->set_arg_url(GURL("http://www.google.com"));
883 policy->ProcessAction(action);
884 policy->ProcessAction(action);
885 policy->ProcessAction(action);
887 scoped_refptr<Action> action2 = new Action("dontdelete",
888 mock_clock->Now(),
889 Action::ACTION_DOM_ACCESS,
890 "lets");
891 action->mutable_args()->AppendString("vamoose");
892 action->set_page_title("Google");
893 action->set_arg_url(GURL("http://www.google.com"));
894 policy->ProcessAction(action2);
896 policy->Flush();
897 policy->RemoveExtensionData("deleteextensiondata");
899 CheckReadFilteredData(
900 policy,
901 "deleteextensiondata",
902 Action::ACTION_ANY,
907 base::Bind(
908 &FullStreamUIPolicyTest::RetrieveActions_FetchFilteredActions0));
910 CheckReadFilteredData(
911 policy,
912 "dontdelete",
913 Action::ACTION_ANY,
918 base::Bind(
919 &FullStreamUIPolicyTest::RetrieveActions_FetchFilteredActions1));
920 policy->Close();
923 TEST_F(FullStreamUIPolicyTest, CapReturns) {
924 FullStreamUIPolicy* policy = new FullStreamUIPolicy(profile_.get());
925 policy->Init();
927 for (int i = 0; i < 305; i++) {
928 scoped_refptr<Action> action =
929 new Action("punky",
930 base::Time::Now(),
931 Action::ACTION_API_CALL,
932 base::StringPrintf("apicall_%d", i));
933 policy->ProcessAction(action);
936 policy->Flush();
937 BrowserThread::PostTaskAndReply(
938 BrowserThread::DB,
939 FROM_HERE,
940 base::Bind(&base::DoNothing),
941 base::MessageLoop::current()->QuitClosure());
942 base::MessageLoop::current()->Run();
944 CheckReadFilteredData(
945 policy,
946 "punky",
947 Action::ACTION_ANY,
952 base::Bind(
953 &FullStreamUIPolicyTest::RetrieveActions_FetchFilteredActions300));
954 policy->Close();
957 TEST_F(FullStreamUIPolicyTest, DeleteDatabase) {
958 ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get());
959 policy->Init();
960 scoped_refptr<const Extension> extension =
961 ExtensionBuilder()
962 .SetManifest(DictionaryBuilder()
963 .Set("name", "Test extension")
964 .Set("version", "1.0.0")
965 .Set("manifest_version", 2))
966 .Build();
967 extension_service_->AddExtension(extension.get());
968 GURL gurl("http://www.google.com");
970 // Write some API calls.
971 scoped_refptr<Action> action_api = new Action(extension->id(),
972 base::Time::Now(),
973 Action::ACTION_API_CALL,
974 "tabs.testMethod");
975 action_api->set_args(make_scoped_ptr(new base::ListValue()));
976 policy->ProcessAction(action_api);
978 scoped_refptr<Action> action_dom = new Action(extension->id(),
979 base::Time::Now(),
980 Action::ACTION_DOM_ACCESS,
981 "document.write");
982 action_dom->set_args(make_scoped_ptr(new base::ListValue()));
983 action_dom->set_page_url(gurl);
984 policy->ProcessAction(action_dom);
986 CheckReadData(
987 policy,
988 extension->id(),
990 base::Bind(&FullStreamUIPolicyTest::RetrieveActions_LogAndFetchActions));
992 // Now delete them.
993 policy->DeleteDatabase();
995 CheckReadFilteredData(
996 policy,
998 Action::ACTION_ANY,
1003 base::Bind(
1004 &FullStreamUIPolicyTest::RetrieveActions_FetchFilteredActions0));
1006 policy->Close();
1009 TEST_F(FullStreamUIPolicyTest, RemoveActions) {
1010 ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get());
1011 policy->Init();
1013 std::vector<int64> action_ids;
1015 CheckRemoveActions(policy,
1016 action_ids,
1017 base::Bind(&FullStreamUIPolicyTest::NoActionsDeleted));
1019 action_ids.push_back(-1);
1020 action_ids.push_back(-10);
1021 action_ids.push_back(0);
1022 action_ids.push_back(5);
1023 action_ids.push_back(10);
1024 CheckRemoveActions(policy,
1025 action_ids,
1026 base::Bind(&FullStreamUIPolicyTest::NoActionsDeleted));
1027 action_ids.clear();
1029 for (int i = 0; i < 50; i++) {
1030 action_ids.push_back(i + 5);
1032 CheckRemoveActions(policy,
1033 action_ids,
1034 base::Bind(&FullStreamUIPolicyTest::NoActionsDeleted));
1035 action_ids.clear();
1037 // CheckRemoveActions pushes four actions to the Activity Log database with
1038 // IDs 1, 2, 3, and 4.
1039 action_ids.push_back(1);
1040 action_ids.push_back(2);
1041 action_ids.push_back(3);
1042 action_ids.push_back(4);
1043 CheckRemoveActions(policy,
1044 action_ids,
1045 base::Bind(&FullStreamUIPolicyTest::AllActionsDeleted));
1046 action_ids.clear();
1048 action_ids.push_back(1);
1049 action_ids.push_back(2);
1050 CheckRemoveActions(
1051 policy, action_ids, base::Bind(&FullStreamUIPolicyTest::Action1Deleted));
1052 action_ids.clear();
1054 action_ids.push_back(3);
1055 action_ids.push_back(4);
1056 CheckRemoveActions(
1057 policy, action_ids, base::Bind(&FullStreamUIPolicyTest::Action2Deleted));
1058 action_ids.clear();
1060 policy->Close();
1063 } // namespace extensions