test_media_item_controller_cleanup.js
Go to the documentation of this file.
1 /*
2  *=BEGIN SONGBIRD GPL
3  *
4  * This file is part of the Songbird web player.
5  *
6  * Copyright(c) 2005-2010 POTI, Inc.
7  * http://www.songbirdnest.com
8  *
9  * This file may be licensed under the terms of of the
10  * GNU General Public License Version 2 (the ``GPL'').
11  *
12  * Software distributed under the License is distributed
13  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
14  * express or implied. See the GPL for the specific language
15  * governing rights and limitations.
16  *
17  * You should have received a copy of the GPL along with this
18  * program. If not, go to http://www.gnu.org/licenses/gpl.html
19  * or write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  *
22  *=END SONGBIRD GPL
23  */
24 
29 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
30 Components.utils.import("resource://app/jsmodules/sbProperties.jsm");
31 Components.utils.import("resource://app/jsmodules/sbLibraryUtils.jsm");
32 
33 const K_TRACKTYPE_REMOVED = "TEST_MEDIA_ITEM_CONTROLLER_REMOVED";
34 const K_TRACKTYPE_ADDED = "TEST_MEDIA_ITEM_CONTROLLER_ADDED";
35 const K_TRACKTYPE_SEPARATOR = '\x7F';
36 const K_COMPLETE_TOPIC = "songbird-media-item-controller-cleanup-complete";
37 const K_IDLE_TOPIC = "songbird-media-item-controller-cleanup-idle";
38 const K_TOTAL_ITEMS = 200;
39 const K_SEEN_PROP = SBProperties.base + "libraryItemControllerLastSeenTypes";
40 const K_HIDDEN_PROP = SBProperties.base + "libraryItemControllerTypeDisappeared";
41 
42 var gLibrary = null;
43 var gCount = {};
44 
45 function runTest () {
46  gLibrary = createLibrary("test_media_item_controller_cleanup",
47  null,
48  false);
49 
50 
51  // wait for things to clear out
52  log("Processing pre-existing libraries...");
53  var obs = Cc["@mozilla.org/observer-service;1"]
54  .getService(Ci.nsIObserverService);
55  var observer = {observe: function(aSubject, aTopic, aData) {
56  obs.removeObserver(this, K_COMPLETE_TOPIC);
57  obs.removeObserver(this, K_IDLE_TOPIC);
58  log("Initialized: " + aTopic + " [" + aData + "]");
59  // we need to sleep(0) to make sure we get out of the observer topic
60  // callback loop, so that registering the next observer will not be called
61  // immediately.
62  sleep(0);
63  testFinished();}
64  };
65 
66  obs.addObserver(observer, K_COMPLETE_TOPIC, false);
67  obs.addObserver(observer, K_IDLE_TOPIC, false);
68  var cleanupSvc =
69  Cc["@songbirdnest.com/Songbird/Library/MediaItemControllerCleanup;1"]
70  .getService(Ci.nsIObserver);
71  cleanupSvc.observe(null, "idle", null);
72  testPending();
73  log("Pre-existing libraries processed");
74 
76 }
77 
84 function EnumeratorCounter(aList, aFilter, aCheck) {
85  var count = 0;
86  var exception = null;
87 
88  var listener = {
89  onEnumerationBegin: function(aList) {},
90  onEnumerationEnd: function(aList, aResult) {},
91  onEnumeratedItem: function(aList, aItem) {
92  try {
93  for each (var prop in postFilter) {
94  if (aItem.getProperty(prop[0]) !== null) {
95  // this doesn't _actually_ match. yay?
96  return;
97  }
98  }
99  if (aCheck) {
100  for each (var set in aCheck) {
101  assertEqual(set[1],
102  aItem.getProperty(set[0]),
103  aItem.contentSrc.spec);
104  }
105  }
106  ++count;
107  } catch (e) {
108  throw (exception = e);
109  }
110  },
111  QueryInterface: XPCOMUtils.generateQI([Ci.sbIMediaListEnumerationListener])
112  };
113 
114  // XXX: Note that we can't actually call enumerateItemsByProperties to look
115  // for items that does _not_ have a given property (we can only look for items
116  // with a given property to empty string); so here we split the set of
117  // properties into two and do post-processing on the enumeration instead.
118 
119  var selector = aFilter.filter(function(f)f[1] !== null);
120  var postFilter = aFilter.filter(function(f)f[1] === null);
121  if (selector.length > 0) {
122  aList.enumerateItemsByProperties(SBProperties.createArray(selector),
123  listener);
124  }
125  else {
126  aList.enumerateAllItems(listener);
127  }
128 
129  if (exception) {
130  throw exception;
131  }
132  return count;
133 }
134 
135 function setupForItemHidden() {
136  var obs = Cc["@mozilla.org/observer-service;1"]
137  .getService(Ci.nsIObserverService);
138  obs.addObserver({observe: checkItemsHidden}, K_COMPLETE_TOPIC, false);
139 
140  gLibrary.clear();
141 
142  gCount = {true:0, false:0};
143 
144  gLibrary.runInBatchMode(function() {
145  for (var i = 0; i < K_TOTAL_ITEMS; ++i) {
146  var hide = (Math.random() >= 0.5);
147  ++gCount[hide];
148  var uri = newURI("data:application/octet-stream," + i);
149  var item = gLibrary.createMediaItem(uri);
150  if (hide) {
151  item.setProperty(SBProperties.trackType, K_TRACKTYPE_REMOVED);
152  }
153  }
154  });
155 
156  assertEqual(K_TOTAL_ITEMS, gLibrary.length,
157  "unexpected number of items added to library");
158  assertEqual(gCount[true],
159  gLibrary.getItemCountByProperty(SBProperties.trackType,
161  "unexpected number of items with testing track type");
162 
163  gLibrary.setProperty(K_SEEN_PROP,
165  LibraryUtils.manager.registerLibrary(gLibrary, false);
166 
167  // since we don't actually want to wait for idle, just fire the event
168  // at the cleanup component manually
169  var cleanupSvc =
170  Cc["@songbirdnest.com/Songbird/Library/MediaItemControllerCleanup;1"]
171  .getService(Ci.nsIObserver);
172  cleanupSvc.observe(null, "idle", null);
173  testPending();
174 }
175 
176 function checkItemsHidden() {
177  var obs = Cc["@mozilla.org/observer-service;1"]
178  .getService(Ci.nsIObserverService);
179  obs.removeObserver(this, K_COMPLETE_TOPIC);
180 
181  assertEqual(K_TOTAL_ITEMS, gLibrary.length,
182  "unexpected number of items added to library");
183  assertEqual(gCount[true],
184  gLibrary.getItemCountByProperty(SBProperties.hidden, "1"),
185  "unexpected number of hidden items");
186  assertEqual(gCount[true],
187  gLibrary.getItemCountByProperty(K_HIDDEN_PROP, "1"),
188  "unexpected number of marked items");
189  var seenItems = 0;
190  gLibrary.enumerateItemsByProperties(
191  SBProperties.createArray([[SBProperties.trackType, K_TRACKTYPE_REMOVED],
192  [SBProperties.hidden, 1]]),
193  {onEnumerationBegin: function(){},
194  onEnumerationEnd: function(){},
195  onEnumeratedItem: function(aList, aItem){
197  aItem.getProperty(SBProperties.trackType),
198  "item with testing track type was not hidden");
199  assertEqual("1",
200  aItem.getProperty(K_HIDDEN_PROP),
201  "item hidden incorrectly");
202  ++seenItems;
203  }
204  });
205  assertEqual(gCount[true],
206  seenItems,
207  "unexpected number of hidden items with testing track type");
208 
209  seenItems = 0;
210  gLibrary.enumerateItemsByProperty(
211  SBProperties.hidden,
212  0, // not hidden
213  {onEnumerationBegin: function(){},
214  onEnumerationEnd: function(){},
215  onEnumeratedItem: function(aList, aItem){
217  aItem.getProperty(SBProperties.trackType),
218  "item with testing track type was not hidden");
219  assertNotEqual("1",
220  aItem.getProperty(K_HIDDEN_PROP),
221  "item hidden incorrectly");
222  ++seenItems;
223  }
224  });
225  assertEqual(gCount[false],
226  seenItems,
227  "unexpected number of not hidden tracks");
228  LibraryUtils.manager.unregisterLibrary(gLibrary);
229  testFinished();
230 
232 }
233 
235  gLibrary.clear();
236 
237  gCount = {true: {
238  true: { true:0, false: 0},
239  false: { true:0, false: 0}},
240  false: {
241  true: { true:0, false: 0},
242  false: { true:0, false: 0}}
243  };
244 
245  gLibrary.runInBatchMode(function() {
246  for (var i = 0; i < K_TOTAL_ITEMS; ++i) {
247  var type = (Math.random() > 0.5); // true = type_added, false = no value
248  var hidden = (Math.random() > 0.5);
249  var flagged = (hidden && Math.random() > 0.5); // true = has K_HIDDEN_PROP
250  ++gCount[type][hidden][flagged];
251 
252  var uri = newURI("data:application/octet-stream," + i);
253  var item = gLibrary.createMediaItem(uri);
254  if (type)
255  item.setProperty(SBProperties.trackType, K_TRACKTYPE_ADDED);
256  if (hidden)
257  item.setProperty(SBProperties.hidden, 1);
258  if (flagged)
259  item.setProperty(K_HIDDEN_PROP, 1);
260  }
261  });
262 
263  assertEqual(K_TOTAL_ITEMS, gLibrary.length,
264  "unexpected number of items added to library");
265  for each (var type in [false, true]) {
266  for each (var hidden in [false, true]) {
267  for each (var flagged in [false, true]) {
268  var props = [
269  [SBProperties.trackType,
270  type ? K_TRACKTYPE_ADDED : null],
271  [SBProperties.hidden,
272  hidden ? 1 : 0],
273  [K_HIDDEN_PROP,
274  flagged ? 1 : null]];
275 
276  assertEqual(gCount[type][hidden][flagged],
277  EnumeratorCounter(gLibrary, props, props),
278  "unexpected number of initial " +
279  (type ? "custom controller" : "default controller") + "/" +
280  (hidden ? "hidden" : "visible") + "/" +
281  (flagged ? "flagged" : "unflagged") +
282  " items in library");
283  }
284  }
285  }
286 
287  gLibrary.setProperty(K_SEEN_PROP, "");
288 
289  // trigger a restore and check again
290  LibraryUtils.manager.registerLibrary(gLibrary, false);
291  var obs = Cc["@mozilla.org/observer-service;1"]
292  .getService(Ci.nsIObserverService);
293  obs.addObserver({observe: checkItemsRestored}, K_COMPLETE_TOPIC, false);
294  var cleanupSvc =
295  Cc["@songbirdnest.com/Songbird/Library/MediaItemControllerCleanup;1"]
296  .getService(Ci.nsIObserver);
297  cleanupSvc.observe(null, "idle", null);
298 
299  testPending();
300 }
301 
302 function checkItemsRestored() {
303  var obs = Cc["@mozilla.org/observer-service;1"]
304  .getService(Ci.nsIObserverService);
305  obs.removeObserver(this, K_COMPLETE_TOPIC);
306 
307  assertEqual(K_TOTAL_ITEMS, gLibrary.length,
308  "unexpected number of added items remaining library");
309 
310  // all items that 1) have custom controller, 2) are hidden, _AND_
311  // 3) are flagged as having been hidden due to this, should be flipped back
312  // to visible with the custom type still set (and unflagged)
313  gCount[true][false][false] += gCount[true][true][true];
314  gCount[true][true][true] = 0;
315 
316  for each (type in [false, true]) {
317  for each (hidden in [false, true]) {
318  for each (flagged in [false, true]) {
319  var props = [
320  [SBProperties.trackType,
321  type ? K_TRACKTYPE_ADDED : null],
322  [SBProperties.hidden,
323  hidden ? 1 : 0],
324  [K_HIDDEN_PROP,
325  flagged ? 1 : null]];
326 
327  var config = [
328  (type ? "custom controller" : "default controller"),
329  (hidden ? "hidden" : "visible"),
330  (flagged ? "flagged" : "unflagged")];
331  try {
332  assertEqual(gCount[type][hidden][flagged],
333  EnumeratorCounter(gLibrary, props, props),
334  "unexpected number of resulting " +
335  config.join("/") +
336  " items in library");
337  } catch (e) {
338  // eat the error so we can finish this test and see what other errors
339  // show up
340  }
341  }
342  }
343  }
344 
345  LibraryUtils.manager.unregisterLibrary(gLibrary);
346  testFinished();
347 }
function EnumeratorCounter(aList, aFilter, aCheck)
function sleep(ms, suppressOutput)
const Cc
function setupForItemRestored()
function runTest()
Advanced DataRemote unit tests.
function assertNotEqual(aExpected, aActual, aMessage)
function log(s)
function testFinished()
sbOSDControlService prototype QueryInterface
function assertEqual(aExpected, aActual, aMessage)
var count
Definition: test_bug7406.js:32
function setupForItemHidden()
return null
Definition: FeedWriter.js:1143
function createLibrary(databaseGuid, databaseLocation)
Definition: test_load.js:151
function newURI(aURLString)
var uri
Definition: FeedWriter.js:1135
function checkItemsHidden()
const Ci
Javascript wrappers for common library tasks.
var hidden
_getSelectedPageStyle s i
let observer
function checkItemsRestored()
_updateTextAndScrollDataForFrame aData
sbDeviceFirmwareAutoCheckForUpdate prototype observe
function testPending()