summaryrefslogtreecommitdiffstats
path: root/toolkit/components/places/tests/unit/test_history_observer.js
blob: 1a9323f89004330122b397f1e1b5f887631f852f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

/**
 * Registers a one-time places observer for 'page-visited',
 * which resolves a promise on being called.
 */
function promiseVisitAdded(callback) {
  return new Promise(resolve => {
    async function listener(events) {
      PlacesObservers.removeListener(["page-visited"], listener);
      Assert.equal(events.length, 1, "Right number of visits notified");
      Assert.equal(events[0].type, "page-visited");
      await callback(events[0]);
      resolve();
    }
    PlacesObservers.addListener(["page-visited"], listener);
  });
}

/**
 * Asynchronous task that adds a visit to the history database.
 */
async function task_add_visit(uri, timestamp, transition) {
  uri = uri || NetUtil.newURI("http://firefox.com/");
  timestamp = timestamp || Date.now() * 1000;
  await PlacesTestUtils.addVisits({
    uri,
    transition: transition || TRANSITION_TYPED,
    visitDate: timestamp,
  });
  return [uri, timestamp];
}

add_task(async function test_visitAdded() {
  let promiseNotify = promiseVisitAdded(async function (visit) {
    Assert.ok(visit.visitId > 0);
    Assert.equal(visit.url, testuri.spec);
    Assert.equal(visit.visitTime, testtime / 1000);
    Assert.equal(visit.referringVisitId, 0);
    Assert.equal(visit.transitionType, TRANSITION_TYPED);
    let uri = NetUtil.newURI(visit.url);
    await check_guid_for_uri(uri, visit.pageGuid);
    Assert.ok(!visit.hidden);
    Assert.equal(visit.visitCount, 1);
    Assert.equal(visit.typedCount, 1);
  });
  let testuri = NetUtil.newURI("http://firefox.com/");
  let testtime = Date.now() * 1000;
  await task_add_visit(testuri, testtime);
  await promiseNotify;
});

add_task(async function test_visitAdded() {
  let promiseNotify = promiseVisitAdded(async function (visit) {
    Assert.ok(visit.visitId > 0);
    Assert.equal(visit.url, testuri.spec);
    Assert.equal(visit.visitTime, testtime / 1000);
    Assert.equal(visit.referringVisitId, 0);
    Assert.equal(visit.transitionType, TRANSITION_FRAMED_LINK);
    let uri = NetUtil.newURI(visit.url);
    await check_guid_for_uri(uri, visit.pageGuid);
    Assert.ok(visit.hidden);
    Assert.equal(visit.visitCount, 1);
    Assert.equal(visit.typedCount, 0);
  });
  let testuri = NetUtil.newURI("http://hidden.firefox.com/");
  let testtime = Date.now() * 1000;
  await task_add_visit(testuri, testtime, TRANSITION_FRAMED_LINK);
  await promiseNotify;
});

add_task(async function test_multiple_onVisit() {
  let testuri = NetUtil.newURI("http://self.firefox.com/");
  let promiseNotifications = new Promise(resolve => {
    async function listener(aEvents) {
      Assert.equal(aEvents.length, 3, "Right number of visits notified");
      for (let i = 0; i < aEvents.length; i++) {
        Assert.equal(aEvents[i].type, "page-visited");
        let visit = aEvents[i];
        Assert.equal(testuri.spec, visit.url);
        Assert.ok(visit.visitId > 0);
        Assert.ok(visit.visitTime > 0);
        Assert.ok(!visit.hidden);
        let uri = NetUtil.newURI(visit.url);
        await check_guid_for_uri(uri, visit.pageGuid);
        switch (i) {
          case 0:
            Assert.equal(visit.referringVisitId, 0);
            Assert.equal(visit.transitionType, TRANSITION_LINK);
            Assert.equal(visit.visitCount, 1);
            Assert.equal(visit.typedCount, 0);
            break;
          case 1:
            Assert.ok(visit.referringVisitId > 0);
            Assert.equal(visit.transitionType, TRANSITION_LINK);
            Assert.equal(visit.visitCount, 2);
            Assert.equal(visit.typedCount, 0);
            break;
          case 2:
            Assert.equal(visit.referringVisitId, 0);
            Assert.equal(visit.transitionType, TRANSITION_TYPED);
            Assert.equal(visit.visitCount, 3);
            Assert.equal(visit.typedCount, 1);

            PlacesObservers.removeListener(["page-visited"], listener);
            resolve();
            break;
        }
      }
    }
    PlacesObservers.addListener(["page-visited"], listener);
  });
  await PlacesTestUtils.addVisits([
    { uri: testuri, transition: TRANSITION_LINK },
    { uri: testuri, referrer: testuri, transition: TRANSITION_LINK },
    { uri: testuri, transition: TRANSITION_TYPED },
  ]);
  await promiseNotifications;
});

add_task(async function test_pageRemovedFromStore() {
  let [testuri] = await task_add_visit();
  let testguid = await PlacesTestUtils.getDatabaseValue("moz_places", "guid", {
    url: testuri,
  });

  const promiseNotify = PlacesTestUtils.waitForNotification("page-removed");

  await PlacesUtils.history.remove(testuri);

  const events = await promiseNotify;
  Assert.equal(events.length, 1, "Right number of page-removed notified");
  Assert.equal(events[0].type, "page-removed");
  Assert.ok(events[0].isRemovedFromStore);
  Assert.equal(events[0].url, testuri.spec);
  Assert.equal(events[0].pageGuid, testguid);
  Assert.equal(events[0].reason, PlacesVisitRemoved.REASON_DELETED);
});

add_task(async function test_pageRemovedAllVisits() {
  const promiseNotify = PlacesTestUtils.waitForNotification("page-removed");

  let msecs24hrsAgo = Date.now() - 86400 * 1000;
  let [testuri] = await task_add_visit(undefined, msecs24hrsAgo * 1000);
  // Add a bookmark so the page is not removed.
  await PlacesUtils.bookmarks.insert({
    parentGuid: PlacesUtils.bookmarks.unfiledGuid,
    title: "test",
    url: testuri,
  });
  let testguid = await PlacesTestUtils.getDatabaseValue("moz_places", "guid", {
    url: testuri,
  });
  await PlacesUtils.history.remove(testuri);

  const events = await promiseNotify;
  Assert.equal(events.length, 1, "Right number of page-removed notified");
  Assert.equal(events[0].type, "page-removed");
  Assert.ok(!events[0].isRemovedFromStore);
  Assert.equal(events[0].url, testuri.spec);
  // Can't use do_check_guid_for_uri() here because the visit is already gone.
  Assert.equal(events[0].pageGuid, testguid);
  Assert.equal(events[0].reason, PlacesVisitRemoved.REASON_DELETED);
  Assert.ok(!events[0].isPartialVisistsRemoval); // All visits have been removed.
});

add_task(async function test_pageTitleChanged() {
  const [testuri] = await task_add_visit();
  const title = "test-title";

  const promiseNotify =
    PlacesTestUtils.waitForNotification("page-title-changed");

  await PlacesTestUtils.addVisits({
    uri: testuri,
    title,
  });

  const events = await promiseNotify;
  Assert.equal(events.length, 1, "Right number of title changed notified");
  Assert.equal(events[0].type, "page-title-changed");
  Assert.equal(events[0].url, testuri.spec);
  Assert.equal(events[0].title, title);
  await check_guid_for_uri(testuri, events[0].pageGuid);
});