toolkit/modules/tests/xpcshell/test_NewTabUtils.js

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:1d64a77daf55
1 /* Any copyright is dedicated to the Public Domain.
2 http://creativecommons.org/publicdomain/zero/1.0/ */
3
4 // See also browser/base/content/test/newtab/.
5
6 const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
7 Cu.import("resource://gre/modules/NewTabUtils.jsm");
8 Cu.import("resource://gre/modules/Promise.jsm");
9
10 function run_test() {
11 run_next_test();
12 }
13
14 add_test(function multipleProviders() {
15 // Make each provider generate NewTabUtils.links.maxNumLinks links to check
16 // that no more than maxNumLinks are actually returned in the merged list.
17 let evenLinks = makeLinks(0, 2 * NewTabUtils.links.maxNumLinks, 2);
18 let evenProvider = new TestProvider(done => done(evenLinks));
19 let oddLinks = makeLinks(0, 2 * NewTabUtils.links.maxNumLinks - 1, 2);
20 let oddProvider = new TestProvider(done => done(oddLinks));
21
22 NewTabUtils.initWithoutProviders();
23 NewTabUtils.links.addProvider(evenProvider);
24 NewTabUtils.links.addProvider(oddProvider);
25
26 // This is sync since the providers' getLinks are sync.
27 NewTabUtils.links.populateCache(function () {}, false);
28
29 let links = NewTabUtils.links.getLinks();
30 let expectedLinks = makeLinks(NewTabUtils.links.maxNumLinks,
31 2 * NewTabUtils.links.maxNumLinks,
32 1);
33 do_check_eq(links.length, NewTabUtils.links.maxNumLinks);
34 do_check_links(links, expectedLinks);
35
36 NewTabUtils.links.removeProvider(evenProvider);
37 NewTabUtils.links.removeProvider(oddProvider);
38 run_next_test();
39 });
40
41 add_test(function changeLinks() {
42 let expectedLinks = makeLinks(0, 20, 2);
43 let provider = new TestProvider(done => done(expectedLinks));
44
45 NewTabUtils.initWithoutProviders();
46 NewTabUtils.links.addProvider(provider);
47
48 // This is sync since the provider's getLinks is sync.
49 NewTabUtils.links.populateCache(function () {}, false);
50
51 do_check_links(NewTabUtils.links.getLinks(), expectedLinks);
52
53 // Notify of a new link.
54 let newLink = makeLink(19);
55 expectedLinks.splice(1, 0, newLink);
56 provider.notifyLinkChanged(newLink);
57 do_check_links(NewTabUtils.links.getLinks(), expectedLinks);
58
59 // Notify of a link that's changed sort criteria.
60 newLink.frecency = 17;
61 expectedLinks.splice(1, 1);
62 expectedLinks.splice(2, 0, newLink);
63 provider.notifyLinkChanged({
64 url: newLink.url,
65 frecency: 17,
66 });
67 do_check_links(NewTabUtils.links.getLinks(), expectedLinks);
68
69 // Notify of a link that's changed title.
70 newLink.title = "My frecency is now 17";
71 provider.notifyLinkChanged({
72 url: newLink.url,
73 title: newLink.title,
74 });
75 do_check_links(NewTabUtils.links.getLinks(), expectedLinks);
76
77 // Notify of a new link again, but this time make it overflow maxNumLinks.
78 provider.maxNumLinks = expectedLinks.length;
79 newLink = makeLink(21);
80 expectedLinks.unshift(newLink);
81 expectedLinks.pop();
82 do_check_eq(expectedLinks.length, provider.maxNumLinks); // Sanity check.
83 provider.notifyLinkChanged(newLink);
84 do_check_links(NewTabUtils.links.getLinks(), expectedLinks);
85
86 // Notify of many links changed.
87 expectedLinks = makeLinks(0, 3, 1);
88 provider.notifyManyLinksChanged();
89 // NewTabUtils.links will now repopulate its cache, which is sync since
90 // the provider's getLinks is sync.
91 do_check_links(NewTabUtils.links.getLinks(), expectedLinks);
92
93 NewTabUtils.links.removeProvider(provider);
94 run_next_test();
95 });
96
97 add_task(function oneProviderAlreadyCached() {
98 let links1 = makeLinks(0, 10, 1);
99 let provider1 = new TestProvider(done => done(links1));
100
101 NewTabUtils.initWithoutProviders();
102 NewTabUtils.links.addProvider(provider1);
103
104 // This is sync since the provider's getLinks is sync.
105 NewTabUtils.links.populateCache(function () {}, false);
106 do_check_links(NewTabUtils.links.getLinks(), links1);
107
108 let links2 = makeLinks(10, 20, 1);
109 let provider2 = new TestProvider(done => done(links2));
110 NewTabUtils.links.addProvider(provider2);
111
112 NewTabUtils.links.populateCache(function () {}, false);
113 do_check_links(NewTabUtils.links.getLinks(), links2.concat(links1));
114
115 NewTabUtils.links.removeProvider(provider1);
116 NewTabUtils.links.removeProvider(provider2);
117 });
118
119 add_task(function newLowRankedLink() {
120 // Init a provider with 10 links and make its maximum number also 10.
121 let links = makeLinks(0, 10, 1);
122 let provider = new TestProvider(done => done(links));
123 provider.maxNumLinks = links.length;
124
125 NewTabUtils.initWithoutProviders();
126 NewTabUtils.links.addProvider(provider);
127
128 // This is sync since the provider's getLinks is sync.
129 NewTabUtils.links.populateCache(function () {}, false);
130 do_check_links(NewTabUtils.links.getLinks(), links);
131
132 // Notify of a new link that's low-ranked enough not to make the list.
133 let newLink = makeLink(0);
134 provider.notifyLinkChanged(newLink);
135 do_check_links(NewTabUtils.links.getLinks(), links);
136
137 // Notify about the new link's title change.
138 provider.notifyLinkChanged({
139 url: newLink.url,
140 title: "a new title",
141 });
142 do_check_links(NewTabUtils.links.getLinks(), links);
143
144 NewTabUtils.links.removeProvider(provider);
145 });
146
147 function TestProvider(getLinksFn) {
148 this.getLinks = getLinksFn;
149 this._observers = new Set();
150 }
151
152 TestProvider.prototype = {
153 addObserver: function (observer) {
154 this._observers.add(observer);
155 },
156 notifyLinkChanged: function (link) {
157 this._notifyObservers("onLinkChanged", link);
158 },
159 notifyManyLinksChanged: function () {
160 this._notifyObservers("onManyLinksChanged");
161 },
162 _notifyObservers: function (observerMethodName, arg) {
163 for (let obs of this._observers) {
164 if (obs[observerMethodName])
165 obs[observerMethodName](this, arg);
166 }
167 },
168 };
169
170 function do_check_links(actualLinks, expectedLinks) {
171 do_check_true(Array.isArray(actualLinks));
172 do_check_eq(actualLinks.length, expectedLinks.length);
173 for (let i = 0; i < expectedLinks.length; i++) {
174 let expected = expectedLinks[i];
175 let actual = actualLinks[i];
176 do_check_eq(actual.url, expected.url);
177 do_check_eq(actual.title, expected.title);
178 do_check_eq(actual.frecency, expected.frecency);
179 do_check_eq(actual.lastVisitDate, expected.lastVisitDate);
180 }
181 }
182
183 function makeLinks(frecRangeStart, frecRangeEnd, step) {
184 let links = [];
185 // Remember, links are ordered by frecency descending.
186 for (let i = frecRangeEnd; i > frecRangeStart; i -= step) {
187 links.push(makeLink(i));
188 }
189 return links;
190 }
191
192 function makeLink(frecency) {
193 return {
194 url: "http://example.com/" + frecency,
195 title: "My frecency is " + frecency,
196 frecency: frecency,
197 lastVisitDate: 0,
198 };
199 }

mercurial