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