Upstream version 5.34.104.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/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   virtual ~FullStreamUIPolicyTest() {
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, "odlameecjipmbmbejkplpemijjgpljce",
158                 Action::ACTION_API_CALL, "extension.connect",
159                 "[\"hello\",\"world\"]", "", "", "");
160   }
161
162   static void Arguments_GetTodaysActions(
163       scoped_ptr<Action::ActionVector> actions) {
164     ASSERT_EQ(2, static_cast<int>(actions->size()));
165     CheckAction(*actions->at(0), "punky", Action::ACTION_DOM_ACCESS, "lets",
166                 "[\"vamoose\"]", "http://www.google.com/", "Page Title",
167                 "http://www.arg-url.com/");
168     CheckAction(*actions->at(1), "punky", Action::ACTION_API_CALL, "brewster",
169                 "[\"woof\"]", "", "Page Title", "http://www.arg-url.com/");
170   }
171
172   static void Arguments_GetOlderActions(
173       scoped_ptr<Action::ActionVector> actions) {
174     ASSERT_EQ(2, static_cast<int>(actions->size()));
175     CheckAction(*actions->at(0), "punky", Action::ACTION_DOM_ACCESS, "lets",
176                 "[\"vamoose\"]", "http://www.google.com/", "", "");
177     CheckAction(*actions->at(1), "punky", Action::ACTION_API_CALL, "brewster",
178                 "[\"woof\"]", "", "", "");
179   }
180
181   static void AllURLsRemoved(scoped_ptr<Action::ActionVector> actions) {
182     ASSERT_EQ(2, static_cast<int>(actions->size()));
183     CheckAction(*actions->at(0), "punky", Action::ACTION_API_CALL, "lets",
184                 "[\"vamoose\"]", "", "", "");
185     CheckAction(*actions->at(1), "punky", Action::ACTION_DOM_ACCESS, "lets",
186                 "[\"vamoose\"]", "", "", "");
187   }
188
189   static void SomeURLsRemoved(scoped_ptr<Action::ActionVector> actions) {
190     // These will be in the vector in reverse time order.
191     ASSERT_EQ(5, static_cast<int>(actions->size()));
192     CheckAction(*actions->at(0), "punky", Action::ACTION_DOM_ACCESS, "lets",
193                 "[\"vamoose\"]", "http://www.google.com/", "Google",
194                 "http://www.args-url.com/");
195     CheckAction(*actions->at(1), "punky", Action::ACTION_DOM_ACCESS, "lets",
196                 "[\"vamoose\"]", "http://www.google.com/", "Google", "");
197     CheckAction(*actions->at(2), "punky", Action::ACTION_DOM_ACCESS, "lets",
198                 "[\"vamoose\"]", "", "", "");
199     CheckAction(*actions->at(3), "punky", Action::ACTION_DOM_ACCESS, "lets",
200                 "[\"vamoose\"]", "", "", "http://www.google.com/");
201     CheckAction(*actions->at(4), "punky", Action::ACTION_DOM_ACCESS, "lets",
202                 "[\"vamoose\"]", "", "", "");
203   }
204
205   static void CheckAction(const Action& action,
206                           const std::string& expected_id,
207                           const Action::ActionType& expected_type,
208                           const std::string& expected_api_name,
209                           const std::string& expected_args_str,
210                           const std::string& expected_page_url,
211                           const std::string& expected_page_title,
212                           const std::string& expected_arg_url) {
213     ASSERT_EQ(expected_id, action.extension_id());
214     ASSERT_EQ(expected_type, action.action_type());
215     ASSERT_EQ(expected_api_name, action.api_name());
216     ASSERT_EQ(expected_args_str,
217               ActivityLogPolicy::Util::Serialize(action.args()));
218     ASSERT_EQ(expected_page_url, action.SerializePageUrl());
219     ASSERT_EQ(expected_page_title, action.page_title());
220     ASSERT_EQ(expected_arg_url, action.SerializeArgUrl());
221     ASSERT_NE(-1, action.action_id());
222   }
223
224   // A helper function initializes the policy with a number of actions, calls
225   // RemoveActions on a policy object and then checks the result of the
226   // deletion.
227   void CheckRemoveActions(
228       ActivityLogDatabasePolicy* policy,
229       const std::vector<int64>& action_ids,
230       const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker) {
231
232     // Use a mock clock to ensure that events are not recorded on the wrong day
233     // when the test is run close to local midnight.
234     base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
235     mock_clock->SetNow(base::Time::Now().LocalMidnight() +
236                        base::TimeDelta::FromHours(12));
237     policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
238
239     // Record some actions
240     scoped_refptr<Action> action =
241         new Action("punky1",
242                    mock_clock->Now() - base::TimeDelta::FromMinutes(40),
243                    Action::ACTION_DOM_ACCESS,
244                    "lets1");
245     action->mutable_args()->AppendString("vamoose1");
246     action->set_page_url(GURL("http://www.google1.com"));
247     action->set_page_title("Google1");
248     action->set_arg_url(GURL("http://www.args-url1.com"));
249     policy->ProcessAction(action);
250     // Record the same action twice, so there are multiple entries in the
251     // database.
252     policy->ProcessAction(action);
253
254     action = new Action("punky2",
255                         mock_clock->Now() - base::TimeDelta::FromMinutes(30),
256                         Action::ACTION_API_CALL,
257                         "lets2");
258     action->mutable_args()->AppendString("vamoose2");
259     action->set_page_url(GURL("http://www.google2.com"));
260     action->set_page_title("Google2");
261     action->set_arg_url(GURL("http://www.args-url2.com"));
262     policy->ProcessAction(action);
263     // Record the same action twice, so there are multiple entries in the
264     // database.
265     policy->ProcessAction(action);
266
267     // Submit a request to delete actions.
268     policy->RemoveActions(action_ids);
269
270     // Check the result of the deletion. The checker function gets all
271     // activities in the database.
272     CheckReadData(policy, "", -1, checker);
273
274     // Clean database.
275     policy->DeleteDatabase();
276   }
277
278   static void AllActionsDeleted(scoped_ptr<Action::ActionVector> actions) {
279     ASSERT_EQ(0, static_cast<int>(actions->size()));
280   }
281
282   static void NoActionsDeleted(scoped_ptr<Action::ActionVector> actions) {
283     // These will be in the vector in reverse time order.
284     ASSERT_EQ(4, static_cast<int>(actions->size()));
285     CheckAction(*actions->at(0),
286                 "punky2",
287                 Action::ACTION_API_CALL,
288                 "lets2",
289                 "[\"vamoose2\"]",
290                 "http://www.google2.com/",
291                 "Google2",
292                 "http://www.args-url2.com/");
293     ASSERT_EQ(3, actions->at(0)->action_id());
294     CheckAction(*actions->at(1),
295                 "punky2",
296                 Action::ACTION_API_CALL,
297                 "lets2",
298                 "[\"vamoose2\"]",
299                 "http://www.google2.com/",
300                 "Google2",
301                 "http://www.args-url2.com/");
302     ASSERT_EQ(4, actions->at(1)->action_id());
303     CheckAction(*actions->at(2),
304                 "punky1",
305                 Action::ACTION_DOM_ACCESS,
306                 "lets1",
307                 "[\"vamoose1\"]",
308                 "http://www.google1.com/",
309                 "Google1",
310                 "http://www.args-url1.com/");
311     ASSERT_EQ(1, actions->at(2)->action_id());
312     CheckAction(*actions->at(3),
313                 "punky1",
314                 Action::ACTION_DOM_ACCESS,
315                 "lets1",
316                 "[\"vamoose1\"]",
317                 "http://www.google1.com/",
318                 "Google1",
319                 "http://www.args-url1.com/");
320     ASSERT_EQ(2, actions->at(3)->action_id());
321   }
322
323   static void Action1Deleted(scoped_ptr<Action::ActionVector> actions) {
324     // These will be in the vector in reverse time order.
325     ASSERT_EQ(2, static_cast<int>(actions->size()));
326     CheckAction(*actions->at(0),
327                 "punky2",
328                 Action::ACTION_API_CALL,
329                 "lets2",
330                 "[\"vamoose2\"]",
331                 "http://www.google2.com/",
332                 "Google2",
333                 "http://www.args-url2.com/");
334     ASSERT_EQ(3, actions->at(0)->action_id());
335     CheckAction(*actions->at(1),
336                 "punky2",
337                 Action::ACTION_API_CALL,
338                 "lets2",
339                 "[\"vamoose2\"]",
340                 "http://www.google2.com/",
341                 "Google2",
342                 "http://www.args-url2.com/");
343     ASSERT_EQ(4, actions->at(1)->action_id());
344   }
345
346   static void Action2Deleted(scoped_ptr<Action::ActionVector> actions) {
347     // These will be in the vector in reverse time order.
348     ASSERT_EQ(2, static_cast<int>(actions->size()));
349     CheckAction(*actions->at(0),
350                 "punky1",
351                 Action::ACTION_DOM_ACCESS,
352                 "lets1",
353                 "[\"vamoose1\"]",
354                 "http://www.google1.com/",
355                 "Google1",
356                 "http://www.args-url1.com/");
357     ASSERT_EQ(1, actions->at(0)->action_id());
358     CheckAction(*actions->at(1),
359                 "punky1",
360                 Action::ACTION_DOM_ACCESS,
361                 "lets1",
362                 "[\"vamoose1\"]",
363                 "http://www.google1.com/",
364                 "Google1",
365                 "http://www.args-url1.com/");
366     ASSERT_EQ(2, actions->at(1)->action_id());
367   }
368
369  protected:
370   ExtensionService* extension_service_;
371   scoped_ptr<TestingProfile> profile_;
372   content::TestBrowserThreadBundle thread_bundle_;
373   // Used to preserve a copy of the original command line.
374   // The test framework will do this itself as well. However, by then,
375   // it is too late to call ActivityLog::RecomputeLoggingIsEnabled() in
376   // TearDown().
377   CommandLine saved_cmdline_;
378
379 #if defined OS_CHROMEOS
380   chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
381   chromeos::ScopedTestCrosSettings test_cros_settings_;
382   scoped_ptr<chromeos::ScopedTestUserManager> test_user_manager_;
383 #endif
384 };
385
386 TEST_F(FullStreamUIPolicyTest, Construct) {
387   ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get());
388   policy->Init();
389   scoped_refptr<const Extension> extension =
390       ExtensionBuilder()
391           .SetManifest(DictionaryBuilder()
392                        .Set("name", "Test extension")
393                        .Set("version", "1.0.0")
394                        .Set("manifest_version", 2))
395           .Build();
396   extension_service_->AddExtension(extension.get());
397   scoped_ptr<base::ListValue> args(new base::ListValue());
398   scoped_refptr<Action> action = new Action(extension->id(),
399                                             base::Time::Now(),
400                                             Action::ACTION_API_CALL,
401                                             "tabs.testMethod");
402   action->set_args(args.Pass());
403   policy->ProcessAction(action);
404   policy->Close();
405 }
406
407 TEST_F(FullStreamUIPolicyTest, LogAndFetchActions) {
408   ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get());
409   policy->Init();
410   scoped_refptr<const Extension> extension =
411       ExtensionBuilder()
412           .SetManifest(DictionaryBuilder()
413                        .Set("name", "Test extension")
414                        .Set("version", "1.0.0")
415                        .Set("manifest_version", 2))
416           .Build();
417   extension_service_->AddExtension(extension.get());
418   GURL gurl("http://www.google.com");
419
420   // Write some API calls
421   scoped_refptr<Action> action_api = new Action(extension->id(),
422                                                 base::Time::Now(),
423                                                 Action::ACTION_API_CALL,
424                                                 "tabs.testMethod");
425   action_api->set_args(make_scoped_ptr(new base::ListValue()));
426   policy->ProcessAction(action_api);
427
428   scoped_refptr<Action> action_dom = new Action(extension->id(),
429                                                 base::Time::Now(),
430                                                 Action::ACTION_DOM_ACCESS,
431                                                 "document.write");
432   action_dom->set_args(make_scoped_ptr(new base::ListValue()));
433   action_dom->set_page_url(gurl);
434   policy->ProcessAction(action_dom);
435
436   CheckReadData(
437       policy,
438       extension->id(),
439       0,
440       base::Bind(&FullStreamUIPolicyTest::RetrieveActions_LogAndFetchActions));
441
442   policy->Close();
443 }
444
445 TEST_F(FullStreamUIPolicyTest, LogAndFetchFilteredActions) {
446   ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get());
447   policy->Init();
448   scoped_refptr<const Extension> extension =
449       ExtensionBuilder()
450           .SetManifest(DictionaryBuilder()
451                        .Set("name", "Test extension")
452                        .Set("version", "1.0.0")
453                        .Set("manifest_version", 2))
454           .Build();
455   extension_service_->AddExtension(extension.get());
456   GURL gurl("http://www.google.com");
457
458   // Write some API calls
459   scoped_refptr<Action> action_api = new Action(extension->id(),
460                                                 base::Time::Now(),
461                                                 Action::ACTION_API_CALL,
462                                                 "tabs.testMethod");
463   action_api->set_args(make_scoped_ptr(new base::ListValue()));
464   policy->ProcessAction(action_api);
465
466   scoped_refptr<Action> action_dom = new Action(extension->id(),
467                                                 base::Time::Now(),
468                                                 Action::ACTION_DOM_ACCESS,
469                                                 "document.write");
470   action_dom->set_args(make_scoped_ptr(new base::ListValue()));
471   action_dom->set_page_url(gurl);
472   policy->ProcessAction(action_dom);
473
474   CheckReadFilteredData(
475       policy,
476       extension->id(),
477       Action::ACTION_API_CALL,
478       "tabs.testMethod",
479       "",
480       "",
481       -1,
482       base::Bind(
483           &FullStreamUIPolicyTest::RetrieveActions_FetchFilteredActions1));
484
485   CheckReadFilteredData(
486       policy,
487       "",
488       Action::ACTION_DOM_ACCESS,
489       "",
490       "",
491       "",
492       -1,
493       base::Bind(
494           &FullStreamUIPolicyTest::RetrieveActions_FetchFilteredActions1));
495
496   CheckReadFilteredData(
497       policy,
498       "",
499       Action::ACTION_DOM_ACCESS,
500       "",
501       "http://www.google.com/",
502       "",
503       -1,
504       base::Bind(
505           &FullStreamUIPolicyTest::RetrieveActions_FetchFilteredActions1));
506
507   CheckReadFilteredData(
508       policy,
509       "",
510       Action::ACTION_DOM_ACCESS,
511       "",
512       "http://www.google.com",
513       "",
514       -1,
515       base::Bind(
516           &FullStreamUIPolicyTest::RetrieveActions_FetchFilteredActions1));
517
518   CheckReadFilteredData(
519       policy,
520       "",
521       Action::ACTION_DOM_ACCESS,
522       "",
523       "http://www.goo",
524       "",
525       -1,
526       base::Bind(
527           &FullStreamUIPolicyTest::RetrieveActions_FetchFilteredActions1));
528
529   CheckReadFilteredData(
530       policy,
531       extension->id(),
532       Action::ACTION_ANY,
533       "",
534       "",
535       "",
536       -1,
537       base::Bind(
538           &FullStreamUIPolicyTest::RetrieveActions_FetchFilteredActions2));
539
540   policy->Close();
541 }
542
543 TEST_F(FullStreamUIPolicyTest, LogWithArguments) {
544   ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get());
545   policy->Init();
546   scoped_refptr<const Extension> extension =
547       ExtensionBuilder()
548           .SetManifest(DictionaryBuilder()
549                        .Set("name", "Test extension")
550                        .Set("version", "1.0.0")
551                        .Set("manifest_version", 2))
552           .Build();
553   extension_service_->AddExtension(extension.get());
554
555   scoped_ptr<base::ListValue> args(new base::ListValue());
556   args->Set(0, new base::StringValue("hello"));
557   args->Set(1, new base::StringValue("world"));
558   scoped_refptr<Action> action = new Action(extension->id(),
559                                             base::Time::Now(),
560                                             Action::ACTION_API_CALL,
561                                             "extension.connect");
562   action->set_args(args.Pass());
563
564   policy->ProcessAction(action);
565   CheckReadData(policy,
566                 extension->id(),
567                 0,
568                 base::Bind(&FullStreamUIPolicyTest::Arguments_Present));
569   policy->Close();
570 }
571
572 TEST_F(FullStreamUIPolicyTest, GetTodaysActions) {
573   ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get());
574   policy->Init();
575
576   // Use a mock clock to ensure that events are not recorded on the wrong day
577   // when the test is run close to local midnight.  Note: Ownership is passed
578   // to the policy, but we still keep a pointer locally.  The policy will take
579   // care of destruction; this is safe since the policy outlives all our
580   // accesses to the mock clock.
581   base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
582   mock_clock->SetNow(base::Time::Now().LocalMidnight() +
583                      base::TimeDelta::FromHours(12));
584   policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
585
586   // Record some actions
587   scoped_refptr<Action> action =
588       new Action("punky",
589                  mock_clock->Now() - base::TimeDelta::FromMinutes(40),
590                  Action::ACTION_API_CALL,
591                  "brewster");
592   action->mutable_args()->AppendString("woof");
593   action->set_arg_url(GURL("http://www.arg-url.com"));
594   action->set_page_title("Page Title");
595   policy->ProcessAction(action);
596
597   action =
598       new Action("punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
599   action->mutable_args()->AppendString("vamoose");
600   action->set_page_url(GURL("http://www.google.com"));
601   action->set_arg_url(GURL("http://www.arg-url.com"));
602   action->set_page_title("Page Title");
603   policy->ProcessAction(action);
604
605   action = new Action(
606       "scoobydoo", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
607   action->mutable_args()->AppendString("vamoose");
608   action->set_page_url(GURL("http://www.google.com"));
609   action->set_arg_url(GURL("http://www.arg-url.com"));
610   policy->ProcessAction(action);
611
612   CheckReadData(
613       policy,
614       "punky",
615       0,
616       base::Bind(&FullStreamUIPolicyTest::Arguments_GetTodaysActions));
617   policy->Close();
618 }
619
620 // Check that we can read back less recent actions in the db.
621 TEST_F(FullStreamUIPolicyTest, GetOlderActions) {
622   ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get());
623   policy->Init();
624
625   // Use a mock clock to ensure that events are not recorded on the wrong day
626   // when the test is run close to local midnight.
627   base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
628   mock_clock->SetNow(base::Time::Now().LocalMidnight() +
629                      base::TimeDelta::FromHours(12));
630   policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
631
632   // Record some actions
633   scoped_refptr<Action> action =
634       new Action("punky",
635                  mock_clock->Now() - base::TimeDelta::FromDays(3) -
636                      base::TimeDelta::FromMinutes(40),
637                  Action::ACTION_API_CALL,
638                  "brewster");
639   action->mutable_args()->AppendString("woof");
640   policy->ProcessAction(action);
641
642   action = new Action("punky",
643                       mock_clock->Now() - base::TimeDelta::FromDays(3),
644                       Action::ACTION_DOM_ACCESS,
645                       "lets");
646   action->mutable_args()->AppendString("vamoose");
647   action->set_page_url(GURL("http://www.google.com"));
648   policy->ProcessAction(action);
649
650   action = new Action("punky",
651                       mock_clock->Now(),
652                       Action::ACTION_DOM_ACCESS,
653                       "lets");
654   action->mutable_args()->AppendString("too new");
655   action->set_page_url(GURL("http://www.google.com"));
656   policy->ProcessAction(action);
657
658   action = new Action("punky",
659                       mock_clock->Now() - base::TimeDelta::FromDays(7),
660                       Action::ACTION_DOM_ACCESS,
661                       "lets");
662   action->mutable_args()->AppendString("too old");
663   action->set_page_url(GURL("http://www.google.com"));
664   policy->ProcessAction(action);
665
666   CheckReadData(
667       policy,
668       "punky",
669       3,
670       base::Bind(&FullStreamUIPolicyTest::Arguments_GetOlderActions));
671   policy->Close();
672 }
673
674 TEST_F(FullStreamUIPolicyTest, RemoveAllURLs) {
675   ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get());
676   policy->Init();
677
678   // Use a mock clock to ensure that events are not recorded on the wrong day
679   // when the test is run close to local midnight.
680   base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
681   mock_clock->SetNow(base::Time::Now().LocalMidnight() +
682                      base::TimeDelta::FromHours(12));
683   policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
684
685   // Record some actions
686   scoped_refptr<Action> action =
687       new Action("punky", mock_clock->Now(),
688                  Action::ACTION_DOM_ACCESS, "lets");
689   action->mutable_args()->AppendString("vamoose");
690   action->set_page_url(GURL("http://www.google.com"));
691   action->set_page_title("Google");
692   action->set_arg_url(GURL("http://www.google.com"));
693   policy->ProcessAction(action);
694
695   mock_clock->Advance(base::TimeDelta::FromSeconds(1));
696   action = new Action(
697       "punky", mock_clock->Now(), Action::ACTION_API_CALL, "lets");
698   action->mutable_args()->AppendString("vamoose");
699   action->set_page_url(GURL("http://www.google2.com"));
700   action->set_page_title("Google");
701   // Deliberately no arg url set to make sure it still works when there is no
702   // arg url.
703   policy->ProcessAction(action);
704
705   // Clean all the URLs.
706   std::vector<GURL> no_url_restrictions;
707   policy->RemoveURLs(no_url_restrictions);
708
709   CheckReadData(
710       policy,
711       "punky",
712       0,
713       base::Bind(&FullStreamUIPolicyTest::AllURLsRemoved));
714   policy->Close();
715 }
716
717 TEST_F(FullStreamUIPolicyTest, RemoveSpecificURLs) {
718   ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get());
719   policy->Init();
720
721   // Use a mock clock to ensure that events are not recorded on the wrong day
722   // when the test is run close to local midnight.
723   base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
724   mock_clock->SetNow(base::Time::Now().LocalMidnight() +
725                      base::TimeDelta::FromHours(12));
726   policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
727
728   // Record some actions
729   // This should have the page url and args url cleared.
730   scoped_refptr<Action> action = new Action("punky", mock_clock->Now(),
731                                             Action::ACTION_DOM_ACCESS, "lets");
732   action->mutable_args()->AppendString("vamoose");
733   action->set_page_url(GURL("http://www.google1.com"));
734   action->set_page_title("Google");
735   action->set_arg_url(GURL("http://www.google1.com"));
736   policy->ProcessAction(action);
737
738   // This should have the page url cleared but not args url.
739   mock_clock->Advance(base::TimeDelta::FromSeconds(1));
740   action = new Action(
741       "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
742   action->mutable_args()->AppendString("vamoose");
743   action->set_page_url(GURL("http://www.google1.com"));
744   action->set_page_title("Google");
745   action->set_arg_url(GURL("http://www.google.com"));
746   policy->ProcessAction(action);
747
748   // This should have the page url cleared. The args url is deliberately not set
749   // to make sure this doesn't cause any issues.
750   mock_clock->Advance(base::TimeDelta::FromSeconds(1));
751   action = new Action(
752       "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
753   action->mutable_args()->AppendString("vamoose");
754   action->set_page_url(GURL("http://www.google2.com"));
755   action->set_page_title("Google");
756   policy->ProcessAction(action);
757
758   // This should have the args url cleared but not the page url or page title.
759   mock_clock->Advance(base::TimeDelta::FromSeconds(1));
760   action = new Action(
761       "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
762   action->mutable_args()->AppendString("vamoose");
763   action->set_page_url(GURL("http://www.google.com"));
764   action->set_page_title("Google");
765   action->set_arg_url(GURL("http://www.google1.com"));
766   policy->ProcessAction(action);
767
768   // This should have neither cleared.
769   mock_clock->Advance(base::TimeDelta::FromSeconds(1));
770   action = new Action(
771       "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
772   action->mutable_args()->AppendString("vamoose");
773   action->set_page_url(GURL("http://www.google.com"));
774   action->set_page_title("Google");
775   action->set_arg_url(GURL("http://www.args-url.com"));
776   policy->ProcessAction(action);
777
778   // Clean some URLs.
779   std::vector<GURL> urls;
780   urls.push_back(GURL("http://www.google1.com"));
781   urls.push_back(GURL("http://www.google2.com"));
782   urls.push_back(GURL("http://www.url_not_in_db.com"));
783   policy->RemoveURLs(urls);
784
785   CheckReadData(
786       policy,
787       "punky",
788       0,
789       base::Bind(&FullStreamUIPolicyTest::SomeURLsRemoved));
790   policy->Close();
791 }
792
793 TEST_F(FullStreamUIPolicyTest, RemoveExtensionData) {
794   FullStreamUIPolicy* policy = new FullStreamUIPolicy(profile_.get());
795   policy->Init();
796
797   // Use a mock clock to ensure that events are not recorded on the wrong day
798   // when the test is run close to local midnight.
799   base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
800   mock_clock->SetNow(base::Time::Now().LocalMidnight() +
801                      base::TimeDelta::FromHours(12));
802   policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
803
804   // Record some actions
805   scoped_refptr<Action> action = new Action("deleteextensiondata",
806                                             mock_clock->Now(),
807                                             Action::ACTION_DOM_ACCESS,
808                                             "lets");
809   action->mutable_args()->AppendString("vamoose");
810   action->set_page_title("Google");
811   action->set_arg_url(GURL("http://www.google.com"));
812   policy->ProcessAction(action);
813   policy->ProcessAction(action);
814   policy->ProcessAction(action);
815
816   scoped_refptr<Action> action2 = new Action("dontdelete",
817                                              mock_clock->Now(),
818                                              Action::ACTION_DOM_ACCESS,
819                                              "lets");
820   action->mutable_args()->AppendString("vamoose");
821   action->set_page_title("Google");
822   action->set_arg_url(GURL("http://www.google.com"));
823   policy->ProcessAction(action2);
824
825   policy->Flush();
826   policy->RemoveExtensionData("deleteextensiondata");
827
828   CheckReadFilteredData(
829       policy,
830       "deleteextensiondata",
831       Action::ACTION_ANY,
832       "",
833       "",
834       "",
835       -1,
836       base::Bind(
837           &FullStreamUIPolicyTest::RetrieveActions_FetchFilteredActions0));
838
839   CheckReadFilteredData(
840       policy,
841       "dontdelete",
842       Action::ACTION_ANY,
843       "",
844       "",
845       "",
846       -1,
847       base::Bind(
848           &FullStreamUIPolicyTest::RetrieveActions_FetchFilteredActions1));
849   policy->Close();
850 }
851
852 TEST_F(FullStreamUIPolicyTest, CapReturns) {
853   FullStreamUIPolicy* policy = new FullStreamUIPolicy(profile_.get());
854   policy->Init();
855
856   for (int i = 0; i < 305; i++) {
857     scoped_refptr<Action> action =
858         new Action("punky",
859                    base::Time::Now(),
860                    Action::ACTION_API_CALL,
861                    base::StringPrintf("apicall_%d", i));
862     policy->ProcessAction(action);
863   }
864
865   policy->Flush();
866   BrowserThread::PostTaskAndReply(
867       BrowserThread::DB,
868       FROM_HERE,
869       base::Bind(&base::DoNothing),
870       base::MessageLoop::current()->QuitClosure());
871   base::MessageLoop::current()->Run();
872
873   CheckReadFilteredData(
874       policy,
875       "punky",
876       Action::ACTION_ANY,
877       "",
878       "",
879       "",
880       -1,
881       base::Bind(
882           &FullStreamUIPolicyTest::RetrieveActions_FetchFilteredActions300));
883   policy->Close();
884 }
885
886 TEST_F(FullStreamUIPolicyTest, DeleteDatabase) {
887   ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get());
888   policy->Init();
889   scoped_refptr<const Extension> extension =
890       ExtensionBuilder()
891           .SetManifest(DictionaryBuilder()
892                        .Set("name", "Test extension")
893                        .Set("version", "1.0.0")
894                        .Set("manifest_version", 2))
895           .Build();
896   extension_service_->AddExtension(extension.get());
897   GURL gurl("http://www.google.com");
898
899   // Write some API calls.
900   scoped_refptr<Action> action_api = new Action(extension->id(),
901                                                 base::Time::Now(),
902                                                 Action::ACTION_API_CALL,
903                                                 "tabs.testMethod");
904   action_api->set_args(make_scoped_ptr(new base::ListValue()));
905   policy->ProcessAction(action_api);
906
907   scoped_refptr<Action> action_dom = new Action(extension->id(),
908                                                 base::Time::Now(),
909                                                 Action::ACTION_DOM_ACCESS,
910                                                 "document.write");
911   action_dom->set_args(make_scoped_ptr(new base::ListValue()));
912   action_dom->set_page_url(gurl);
913   policy->ProcessAction(action_dom);
914
915   CheckReadData(
916       policy,
917       extension->id(),
918       0,
919       base::Bind(&FullStreamUIPolicyTest::RetrieveActions_LogAndFetchActions));
920
921   // Now delete them.
922   policy->DeleteDatabase();
923
924   CheckReadFilteredData(
925       policy,
926       "",
927       Action::ACTION_ANY,
928       "",
929       "",
930       "",
931       -1,
932       base::Bind(
933           &FullStreamUIPolicyTest::RetrieveActions_FetchFilteredActions0));
934
935   policy->Close();
936 }
937
938 TEST_F(FullStreamUIPolicyTest, RemoveActions) {
939   ActivityLogDatabasePolicy* policy = new FullStreamUIPolicy(profile_.get());
940   policy->Init();
941
942   std::vector<int64> action_ids;
943
944   CheckRemoveActions(policy,
945                      action_ids,
946                      base::Bind(&FullStreamUIPolicyTest::NoActionsDeleted));
947
948   action_ids.push_back(-1);
949   action_ids.push_back(-10);
950   action_ids.push_back(0);
951   action_ids.push_back(5);
952   action_ids.push_back(10);
953   CheckRemoveActions(policy,
954                      action_ids,
955                      base::Bind(&FullStreamUIPolicyTest::NoActionsDeleted));
956   action_ids.clear();
957
958   for (int i = 0; i < 50; i++) {
959     action_ids.push_back(i + 5);
960   }
961   CheckRemoveActions(policy,
962                      action_ids,
963                      base::Bind(&FullStreamUIPolicyTest::NoActionsDeleted));
964   action_ids.clear();
965
966   // CheckRemoveActions pushes four actions to the Activity Log database with
967   // IDs 1, 2, 3, and 4.
968   action_ids.push_back(1);
969   action_ids.push_back(2);
970   action_ids.push_back(3);
971   action_ids.push_back(4);
972   CheckRemoveActions(policy,
973                      action_ids,
974                      base::Bind(&FullStreamUIPolicyTest::AllActionsDeleted));
975   action_ids.clear();
976
977   action_ids.push_back(1);
978   action_ids.push_back(2);
979   CheckRemoveActions(
980       policy, action_ids, base::Bind(&FullStreamUIPolicyTest::Action1Deleted));
981   action_ids.clear();
982
983   action_ids.push_back(3);
984   action_ids.push_back(4);
985   CheckRemoveActions(
986       policy, action_ids, base::Bind(&FullStreamUIPolicyTest::Action2Deleted));
987   action_ids.clear();
988
989   policy->Close();
990 }
991
992 }  // namespace extensions