summaryrefslogtreecommitdiffstats
path: root/toolkit/components/places/tests/favicons/test_query_result_favicon_changed_on_child.js
blob: 4e5c55e50a4603277aaab6bebe870b199b2b4076 (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
/**
 * Test for bug 451499 <https://bugzilla.mozilla.org/show_bug.cgi?id=451499>:
 * Wrong folder icon appears on queries.
 */

"use strict";

add_task(async function test_query_result_favicon_changed_on_child() {
  // Bookmark our test page, so it will appear in the query resultset.
  const PAGE_URI = Services.io.newURI("http://example.com/test_query_result");
  await PlacesUtils.bookmarks.insert({
    parentGuid: PlacesUtils.bookmarks.menuGuid,
    title: "test_bookmark",
    url: PAGE_URI,
  });

  // Get the last 10 bookmarks added to the menu or the toolbar.
  let query = PlacesUtils.history.getNewQuery();
  query.setParents([
    PlacesUtils.bookmarks.menuGuid,
    PlacesUtils.bookmarks.toolbarGuid,
  ]);

  let options = PlacesUtils.history.getNewQueryOptions();
  options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS;
  options.maxResults = 10;
  options.excludeQueries = 1;
  options.sortingMode = options.SORT_BY_DATE_DESCENDING;

  let result = PlacesUtils.history.executeQuery(query, options);
  let resultObserver = {
    containerStateChanged(aContainerNode, aOldState, aNewState) {
      if (aNewState == Ci.nsINavHistoryContainerResultNode.STATE_OPENED) {
        // We set a favicon on PAGE_URI while the container is open.  The
        // favicon for the page must have data associated with it in order for
        // the icon changed notifications to be sent, so we use a valid image
        // data URI.
        PlacesUtils.favicons.setAndFetchFaviconForPage(
          PAGE_URI,
          SMALLPNG_DATA_URI,
          false,
          PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
          null,
          Services.scriptSecurityManager.getSystemPrincipal()
        );
      }
    },
    nodeIconChanged(aNode) {
      if (PlacesUtils.nodeIsContainer(aNode)) {
        do_throw(
          "The icon should be set only for the page," +
            " not for the containing query."
        );
      }
    },
  };
  Object.setPrototypeOf(resultObserver, NavHistoryResultObserver.prototype);
  result.addObserver(resultObserver);

  // Open the container and wait for containerStateChanged. We should start
  // observing before setting |containerOpen| as that's caused by the
  // setAndFetchFaviconForPage() call caused by the containerStateChanged
  // observer above.
  let promise = promiseFaviconChanged(PAGE_URI, SMALLPNG_DATA_URI);
  result.root.containerOpen = true;
  await promise;

  // We must wait for the asynchronous database thread to finish the
  // operation, and then for the main thread to process any pending
  // notifications that came from the asynchronous thread, before we can be
  // sure that nodeIconChanged was not invoked in the meantime.
  await PlacesTestUtils.promiseAsyncUpdates();
  result.removeObserver(resultObserver);

  // Free the resources immediately.
  result.root.containerOpen = false;

  await PlacesUtils.bookmarks.eraseEverything();
  await PlacesUtils.history.clear();
});

add_task(
  async function test_query_result_favicon_changed_not_affect_lastmodified() {
    // Bookmark our test page, so it will appear in the query resultset.
    const PAGE_URI2 = Services.io.newURI(
      "http://example.com/test_query_result"
    );
    let bm = await PlacesUtils.bookmarks.insert({
      parentGuid: PlacesUtils.bookmarks.menuGuid,
      title: "test_bookmark",
      url: PAGE_URI2,
    });

    let result = PlacesUtils.getFolderContents(PlacesUtils.bookmarks.menuGuid);

    Assert.equal(
      result.root.childCount,
      1,
      "Should have only one item in the query"
    );
    Assert.equal(
      result.root.getChild(0).uri,
      PAGE_URI2.spec,
      "Should have the correct child"
    );
    Assert.equal(
      result.root.getChild(0).lastModified,
      PlacesUtils.toPRTime(bm.lastModified),
      "Should have the expected last modified date."
    );

    let promise = promiseFaviconChanged(PAGE_URI2, SMALLPNG_DATA_URI);
    PlacesUtils.favicons.setAndFetchFaviconForPage(
      PAGE_URI2,
      SMALLPNG_DATA_URI,
      false,
      PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
      null,
      Services.scriptSecurityManager.getSystemPrincipal()
    );
    await promise;

    // Open the container and wait for containerStateChanged. We should start
    // observing before setting |containerOpen| as that's caused by the
    // setAndFetchFaviconForPage() call caused by the containerStateChanged
    // observer above.

    // We must wait for the asynchronous database thread to finish the
    // operation, and then for the main thread to process any pending
    // notifications that came from the asynchronous thread, before we can be
    // sure that nodeIconChanged was not invoked in the meantime.
    await PlacesTestUtils.promiseAsyncUpdates();

    Assert.equal(
      result.root.childCount,
      1,
      "Should have only one item in the query"
    );
    Assert.equal(
      result.root.getChild(0).uri,
      PAGE_URI2.spec,
      "Should have the correct child"
    );
    Assert.equal(
      result.root.getChild(0).lastModified,
      PlacesUtils.toPRTime(bm.lastModified),
      "Should not have changed the last modified date."
    );

    // Free the resources immediately.
    result.root.containerOpen = false;
  }
);