15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/visit_tracker.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using history::ContextID;
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using history::VisitTracker;
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct VisitToTest {
15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Identifies the context.
16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  int context_id_int;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 page_id;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used when adding this to the tracker
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* url;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const history::VisitID visit_id;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used when finding the referrer
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* referrer;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the correct referring visit ID to compare to the computed one
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::VisitID referring_visit_id;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RunTest(VisitTracker* tracker, VisitToTest* test, int test_count) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < test_count; i++) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Our host pointer is actually just an int, convert it (it will not get
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // dereferenced).
34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ContextID context_id = reinterpret_cast<ContextID>(test[i].context_id_int);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check the referrer for this visit.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history::VisitID ref_visit = tracker->GetLastVisit(
38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        context_id, test[i].page_id, GURL(test[i].referrer));
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(test[i].referring_visit_id, ref_visit);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Now add this visit.
42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    tracker->AddVisit(
43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        context_id, test[i].page_id, GURL(test[i].url), test[i].visit_id);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A simple test that makes sure we transition between main pages in the
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// presence of back/forward.
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(VisitTracker, SimpleTransitions) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitToTest test_simple[] = {
53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // Started here:
54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      {1, 1, "http://www.google.com/", 1, "", 0},
55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // Clicked a link:
56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      {1, 2, "http://images.google.com/", 2, "http://www.google.com/", 1},
57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // Went back, then clicked a link:
58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      {1, 3, "http://video.google.com/", 3, "http://www.google.com/", 1},
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitTracker tracker;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTest(&tracker, test_simple, arraysize(test_simple));
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that referrer is properly computed when there are different frame
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// navigations happening.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(VisitTracker, Frames) {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitToTest test_frames[] = {
69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // Started here:
70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      {1, 1, "http://foo.com/", 1, "", 0},
71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // Which had an auto-loaded subframe:
72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      {1, 1, "http://foo.com/ad.html", 2, "http://foo.com/", 1},
73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // ...and another auto-loaded subframe:
74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      {1, 1, "http://foo.com/ad2.html", 3, "http://foo.com/", 1},
75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // ...and the user navigated the first subframe to somwhere else
76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      {1, 2, "http://bar.com/", 4, "http://foo.com/ad.html", 2},
77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // ...and then the second subframe somewhere else
78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      {1, 3, "http://fud.com/", 5, "http://foo.com/ad2.html", 3},
79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // ...and then the main frame somewhere else.
80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      {1, 4, "http://www.google.com/", 6, "http://foo.com/", 1},
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitTracker tracker;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTest(&tracker, test_frames, arraysize(test_frames));
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test frame navigation to make sure that the referrer is properly computed
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// when there are multiple processes navigating the same pages.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(VisitTracker, MultiProcess) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitToTest test_processes[] = {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Process 1 and 2 start here:
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {1, 1, "http://foo.com/",           1, "",                       0},
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {2, 1, "http://foo.com/",           2, "",                       0},
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // They have some subframes:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {1, 1, "http://foo.com/ad.html",    3, "http://foo.com/",        1},
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {2, 1, "http://foo.com/ad.html",    4, "http://foo.com/",        2},
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Subframes are navigated:
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {1, 2, "http://bar.com/",           5, "http://foo.com/ad.html", 3},
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {2, 2, "http://bar.com/",           6, "http://foo.com/ad.html", 4},
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Main frame is navigated:
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {1, 3, "http://www.google.com/",    7, "http://foo.com/",        1},
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {2, 3, "http://www.google.com/",    8, "http://foo.com/",        2},
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitTracker tracker;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTest(&tracker, test_processes, arraysize(test_processes));
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that processes get removed properly.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(VisitTracker, ProcessRemove) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simple navigation from one process.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitToTest part1[] = {
113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      {1, 1, "http://www.google.com/", 1, "", 0},
114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      {1, 2, "http://images.google.com/", 2, "http://www.google.com/", 1},
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitTracker tracker;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTest(&tracker, part1, arraysize(part1));
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Say that context has been invalidated.
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  tracker.ClearCachedDataForContextID(reinterpret_cast<ContextID>(1));
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simple navigation from a new process with the same ID, it should not find
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a referrer.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VisitToTest part2[] = {
126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      {1, 1, "http://images.google.com/", 2, "http://www.google.com/", 0},
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTest(&tracker, part2, arraysize(part2));
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
130