test_play_queue_playlist_drop.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-2011 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 
25 var XUL_NS = XUL_NS ||
26  "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
27 
28 Components.utils.import("resource://app/jsmodules/ArrayConverter.jsm");
29 Components.utils.import("resource://app/jsmodules/DropHelper.jsm");
30 Components.utils.import("resource://app/jsmodules/sbProperties.jsm");
31 
32 function runTest () {
33  var url = "data:application/vnd.mozilla.xul+xml," +
34  "<?xml-stylesheet href='chrome://global/skin' type='text/css'?>" +
35  "<?xml-stylesheet href='chrome://songbird/content/bindings/bindings.css' type='text/css'?>" +
36  "<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'/>";
37 
39 }
40 
42 
43  setup: function TestPlayQueuPlaylistDrop_setup() {
44 
45 
46  testWindow.resizeTo(200,200);
47 
48  var document = testWindow.document,
49  library = createLibrary("test_play_queue_playlist_drop", null, false),
50  pqSvc = Cc["@songbirdnest.com/Songbird/playqueue/service;1"]
51  .getService(Ci.sbIPlayQueueService),
52  pqList = pqSvc.mediaList;
53 
54  pqSvc.clearAll();
55 
56  function createElement(aList, aType) {
57  var playlist = document.createElementNS(XUL_NS, aType);
58  playlist.setAttribute("flex", "1");
59  document.documentElement.appendChild(playlist);
60  playlist.bind(aList.createView(), null);
61 
62  return playlist;
63  }
64 
65  continueWindowTest(TestPlayQueueDrop.run,
66  [ createElement(library, "sb-playlist"),
67  createElement(pqList, "sb-playqueue-playlist") ]);
68  },
69 
70  run: function TestPlayQueueDrop_run(aLibraryPlaylist,
71  aPlayQueuePlaylist)
72  {
74  for (let i = 0, len = tests.length; i < len; i++) {
75  let testCase = new TestCase(tests[i]);
76  dump('DESC: ' + testCase.desc + '\n');
77  testCase.run([aLibraryPlaylist, aPlayQueuePlaylist]);
78  }
79  endWindowTest();
80  },
81 
82  // Helper to create dummy media items with unique uris within a given test run
83  createItemsInLibrary:
84  function TestPlayQueueDrop_createItemsInLibrary(aLibrary, aCount)
85  {
86  this._itemCounter = this._itemCounter || 0;
87 
88  function testURIFor(index) {
89  return newURI('http://test.com/playqueuedrop/' + index);
90  }
91 
92  var start = this._itemCounter,
93  finish,
94  indexes = [];
95 
96  this._itemCounter += aCount;
97  finish = this._itemCounter - 1;
98 
99  for (let i = start; i <= finish; i++) {
100  indexes.push(i);
101  }
102 
103  return [ aLibrary.createMediaItem(testURIFor(i)) for each (i in indexes) ];
104  }
105 };
106 
108 {
109  desc: "dropping an enumerator of mediaitems on an empty play queue " +
110  "should add items to the queue with async queueSomeNext",
111  pre: function (libraryPlaylist, playQueuePlaylist) {
112  var self = this;
113 
114  // Set up the async listener.
115  this.pqSvc = Cc["@songbirdnest.com/Songbird/playqueue/service;1"]
116  .getService(Ci.sbIPlayQueueService);
117  this.pqListener = {
118  onIndexUpdated: function (aToIndex) {
119  },
120  onQueueOperationStarted: function () {
121  self.asyncOpStarted = true;
122  },
123  onQueueOperationCompleted: function () {
124  assertEqual(3,
125  self.pqSvc.mediaList.length,
126  self.desc + ': incorrect queue length');
127  testFinished();
128  }
129  };
130  this.pqSvc.addListener(this.pqListener);
131 
132  // Create a fake drop from the test library
133  var items =
134  TestPlayQueueDrop.createItemsInLibrary(libraryPlaylist.library, 3);
135 
136  var view = libraryPlaylist.mediaListView;
137  view.selection.selectAll();
138  var context = new DNDUtils.MediaListViewSelectionTransferContext(view);
139  var handle = Cc["@songbirdnest.com/Songbird/DndSourceTracker;1"]
140  .getService(Ci.sbIDndSourceTracker)
141  .registerSource(context);
142 
143  this.stub(DNDUtils, 'getTransferDataForFlavour', function (type) {
144  var sourceData = null;
145  if (type == "application/x-sb-transfer-media-items") {
146  sourceData = { data: handle};
147  }
148  return sourceData;
149  });
150  this.asyncOpStarted = false;
151  this.fakeSession = {
152  getData: function (aTransferable, aItemIndex) {
153  return { data: null };
154  },
155  isDataFlavorSupported: function (aDataFlavor) {
156  return true;
157  },
158  dragAction: 1
159  };
160  },
161  exec: function (libraryPlaylist, playQueuePlaylist) {
162  playQueuePlaylist._dropOnTree(0,
163  Ci.sbIMediaListViewTreeViewObserver.DROP_AFTER,
164  this.fakeSession);
165  // If we didn't start an async operation, fail the test so we explicitly
166  // know that there is a problem instead of just hanging the test.
167  assertTrue(this.asyncOpStarted,
168  'async play queue drop did not call async listener');
169  testPending();
170  },
171  post: function(libraryPlaylist) {
172  this.pqSvc.removeListener(this.pqListener);
173  this.pqSvc.clearAll();
174  libraryPlaylist.library.clear();
175  }
176 },
177 {
178  desc: "inserting an enumerator of mediaitems between play queue rows " +
179  "should add items to the queue with async queueSomeBefore",
180  pre: function (libraryPlaylist, playQueuePlaylist) {
181  var self = this;
182 
183  // Set up the async listener
184  this.pqSvc = Cc["@songbirdnest.com/Songbird/playqueue/service;1"]
185  .getService(Ci.sbIPlayQueueService);
186  this.pqListener = {
187  onIndexUpdated: function (aToIndex) {
188  },
189  onQueueOperationStarted: function () {
190  self.asyncOpStarted = true;
191  },
192  onQueueOperationCompleted: function () {
193  assertEqual(7,
194  self.pqSvc.mediaList.length,
195  self.desc + ': incorrect queue length');
196  testFinished();
197  }
198  };
199  this.pqSvc.addListener(this.pqListener);
200 
201  // Create some items in the play queue.
202  var queueLib = this.pqSvc.mediaList.library;
203  var queueItems =
204  TestPlayQueueDrop.createItemsInLibrary(queueLib, 4);
205  queueItems.forEach(function (item) {
206  // We need to actually get the items into the queue list
207  self.pqSvc.queueNext(item);
208  });
209 
210  // Create a fake drop from the test library
211  var items =
212  TestPlayQueueDrop.createItemsInLibrary(libraryPlaylist.library, 3);
213  var view = libraryPlaylist.mediaListView;
214  view.selection.selectAll();
215  var context = new DNDUtils.MediaListViewSelectionTransferContext(view);
216  var handle = Cc["@songbirdnest.com/Songbird/DndSourceTracker;1"]
217  .getService(Ci.sbIDndSourceTracker)
218  .registerSource(context);
219 
220  this.stub(DNDUtils, 'getTransferDataForFlavour', function (type) {
221  var sourceData = null;
222  if (type == "application/x-sb-transfer-media-items") {
223  sourceData = { data: handle };
224  }
225  return sourceData;
226  });
227  this.asyncOpStarted = false;
228  this.fakeSession = {
229  getData: function (aTransferable, aItemIndex) {
230  return { data: handle };
231  },
232  isDataFlavorSupported: function (aDataFlavor) {
233  return true;
234  },
235  dragAction: 1
236  };
237  },
238  exec: function (libraryPlaylist, playQueuePlaylist) {
239  playQueuePlaylist._dropOnTree(2,
240  Ci.sbIMediaListViewTreeViewObserver.DROP_BEFORE, this.fakeSession);
241  // If we didn't start an async operation, fail the test so we explicitly
242  // know that there is a problem instead of just hanging the test.
243  assertTrue(this.asyncOpStarted,
244  'async play queue drop did not call async listener');
245  testPending();
246  },
247  post: function(libraryPlaylist) {
248  this.pqSvc.removeListener(this.pqListener);
249  this.pqSvc.clearAll();
250  libraryPlaylist.library.clear();
251  }
252 },
253 {
254  desc: "dropping a mediaList on an empty queue should call up to the parent " +
255  "playlist binding for synchronous insertion",
256  pre: function (libraryPlaylist, playQueuePlaylist) {
257  var self = this;
258 
259  // Set up the async listener.
260  this.pqSvc = Cc["@songbirdnest.com/Songbird/playqueue/service;1"]
261  .getService(Ci.sbIPlayQueueService);
262  this.pqListener = {
263  onIndexUpdated: function (aToIndex) {
264  },
265  onQueueOperationStarted: function () {
266  doFail("Synchronous play queue operations should not call the async " +
267  "operations listener");
268  },
269  onQueueOperationCompleted: function () {
270  doFail("Synchronous play queue operations should not call the async " +
271  "operations listener");
272  }
273  };
274  this.pqSvc.addListener(this.pqListener);
275 
276 
277  var library = libraryPlaylist.library;
278  var list = library.createMediaList("simple");
279  var items = TestPlayQueueDrop.createItemsInLibrary(library, 3);
280  items.forEach(function (item) {
281  list.add(item);
282  });
283  var context = new DNDUtils.MediaListTransferContext(list, list);
284  var handle = Cc["@songbirdnest.com/Songbird/DndSourceTracker;1"]
285  .getService(Ci.sbIDndSourceTracker)
286  .registerSource(context);
287 
288  this.stub(DNDUtils, 'getTransferDataForFlavour', function (type) {
289  var sourceData = null;
290  if (type === "application/x-sb-transfer-media-list") {
291  sourceData = { data: handle };
292  }
293  return sourceData;
294  });
295  this.stub(DNDUtils, 'getTransferData', function () {
296  return { data: handle };
297  });
298  this.stub(InternalDropHandler, 'isSupported', function () {
299  return true;
300  });
301  this.stub(ExternalDropHandler, 'isSupported', function () {
302  return false;
303  });
304  this.fakeSession = {
305  getData: function (aTransferable, aItemIndex) {
306  return { data: handle };
307  },
308  isDataFlavorSupported: function (aDataFlavor) {
309  return true;
310  },
311  dragAction: 1
312  };
313  },
314  exec: function (libraryPlaylist, playQueuePlaylist) {
315  playQueuePlaylist._dropOnTree(0,
316  Ci.sbIMediaListViewTreeViewObserver.DROP_BEFORE,
317  this.fakeSession);
318  assertEqual(this.pqSvc.mediaList.length,
319  3,
320  this.desc + ': incorrect queue length');
321  },
322  post: function (libraryPlaylist, playQueuePlaylist) {
323  this.pqSvc.removeListener(this.pqListener);
324  this.pqSvc.clearAll();
325  libraryPlaylist.library.clear();
326  }
327 },
328 {
329  desc: "dropping a mediaList at a specific insertion point in the queue " +
330  "should call the parent playlist binding for synchronous insertion",
331  pre: function (libraryPlaylist, playQueuePlaylist) {
332  var self = this;
333 
334  // Set up the async listener.
335  this.pqSvc = Cc["@songbirdnest.com/Songbird/playqueue/service;1"]
336  .getService(Ci.sbIPlayQueueService);
337  this.pqListener = {
338  onIndexUpdated: function (aToIndex) {
339  },
340  onQueueOperationStarted: function () {
341  doFail("Synchronous play queue operations should not call the async " +
342  "operations listener");
343  },
344  onQueueOperationCompleted: function () {
345  doFail("Synchronous play queue operations should not call the async " +
346  "operations listener");
347  }
348  };
349  this.pqSvc.addListener(this.pqListener);
350 
351  // Add some items to the queue.
352  var queueLib = this.pqSvc.mediaList.library;
353  var queueItems =
354  TestPlayQueueDrop.createItemsInLibrary(queueLib, 4);
355  queueItems.forEach(function (item) {
356  // We need to actually get the items into the queue list
357  self.pqSvc.queueNext(item);
358  });
359 
360  // Create a fake drop of a medialist from the test library
361  var library = libraryPlaylist.library;
362  var list = library.createMediaList("simple");
363  var items = TestPlayQueueDrop.createItemsInLibrary(library, 3);
364  items.forEach(function (item) {
365  list.add(item);
366  });
367  var context = new DNDUtils.MediaListTransferContext(list, list);
368  var handle = Cc["@songbirdnest.com/Songbird/DndSourceTracker;1"]
369  .getService(Ci.sbIDndSourceTracker)
370  .registerSource(context);
371 
372  this.stub(DNDUtils, 'getTransferDataForFlavour', function (type) {
373  var sourceData = null;
374  if (type === "application/x-sb-transfer-media-list") {
375  sourceData = { data: handle };
376  }
377  return sourceData;
378  });
379  this.stub(DNDUtils, 'getTransferData', function () {
380  return { data: handle };
381  });
382  this.stub(InternalDropHandler, 'isSupported', function () {
383  return true;
384  });
385  this.stub(ExternalDropHandler, 'isSupported', function () {
386  return false;
387  });
388 
389  // This test needs a session that implements nsIDragSession
390  this.fakeSession = {
391  getData: function (aTransferable, aItemIndex) {
392  return { data: handle };
393  },
394  isDataFlavorSupported: function (aDataFlavor) {
395  return true;
396  },
397  dragAction: 1
398  };
399  },
400  exec: function (libraryPlaylist, playQueuePlaylist) {
401  playQueuePlaylist._dropOnTree(2,
402  Ci.sbIMediaListViewTreeViewObserver.DROP_BEFORE,
403  this.fakeSession);
404  assertEqual(this.pqSvc.mediaList.length,
405  7,
406  this.desc + ': incorrect queue length');
407  },
408  post: function (libraryPlaylist, playQueuePlaylist) {
409  this.pqSvc.removeListener(this.pqListener);
410  this.pqSvc.clearAll();
411  libraryPlaylist.library.clear();
412  }
413 }];
414 
function start(ch)
const Cc
function endWindowTest(e)
function TestCase(config)
function setup()
function testFinished()
var DNDUtils
Definition: DropHelper.jsm:80
const K_PLAYQUEUEDROP_TESTCASES
function beginWindowTest(url, continueFunction)
function assertTrue(aTest, aMessage)
function assertEqual(aExpected, aActual, aMessage)
function handle(request, response)
function runTest()
Advanced DataRemote unit tests.
return null
Definition: FeedWriter.js:1143
function createLibrary(databaseGuid, databaseLocation)
Definition: test_load.js:151
function newURI(aURLString)
var testWindow
Test file.
function url(spec)
const Ci
function doFail(text)
restoreHistoryPrecursor aCount
observe data
Definition: FeedWriter.js:1329
_getSelectedPageStyle s i
function continueWindowTest(fn, parameters)
function testPending()