test_playlist_candrop.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 
33 const Cu = Components.utils;
34 
35 var XUL_NS = XUL_NS ||
36  "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
37 
38 Cu.import("resource://app/jsmodules/DropHelper.jsm");
39 Cu.import("resource://app/jsmodules/sbProperties.jsm");
40 
41 function runTest () {
42  var url = "data:application/vnd.mozilla.xul+xml," +
43  "<?xml-stylesheet href='chrome://global/skin' type='text/css'?>" +
44  "<?xml-stylesheet href='chrome://songbird/content/bindings/bindings.css' type='text/css'?>" +
45  "<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'/>";
46 
47  beginWindowTest(url, setup);
48 }
49 
50 function setup () {
51 
52  testWindow.resizeTo(200,200);
53 
54  var document = testWindow.document,
55  library = createLibrary("test_playlist_candrop", null, false),
56  list = library.createMediaList("simple"),
57  pqList = Cc["@songbirdnest.com/Songbird/playqueue/service;1"]
58  .getService(Ci.sbIPlayQueueService)
59  .mediaList;
60 
61  function createElement(aList, aType) {
62  var playlist = document.createElementNS(XUL_NS, aType);
63  playlist.setAttribute("flex", "1");
64  document.documentElement.appendChild(playlist);
65  playlist.bind(aList.createView(), null);
66 
67  return playlist;
68  }
69 
71  [ createElement(library, "sb-playlist"),
72  createElement(list, "sb-playlist"),
73  createElement(pqList, "sb-playqueue-playlist") ]);
74 }
75 
76 function test_canDrop(aLibraryPlaylist, aListPlaylist, aPlayQueuePlaylist) {
77 
78  function runTests(aPlaylist, aTestCases) {
79  for (let i = 0, len = aTestCases.length; i < len; i++) {
80  let testCase = new TestCase(aTestCases[i]);
81  testCase.run([aPlaylist, aPlayQueuePlaylist]);
82  }
83  }
84 
85  runTests(aLibraryPlaylist, K_DROPONLIBRARY_TESTS);
86  runTests(aListPlaylist, K_DROPONLIST_TESTS);
87  runTests(aListPlaylist, K_DROPINDICATOR_TESTS);
88  runTests(aListPlaylist, K_DROPONPLAYQUEUE_TESTS);
89 
90  endWindowTest();
91 }
92 
93 // The order of test cases is important, as it represents the order that various
94 // conditions are checked in the _canDrop method. Many conditions cause early
95 // returns. For each test case in this array, it should be assumed that previous
96 // conditions do not cause early returns (i.e. any given test case should
97 // ensure that the specific condition for the test is actually arrived at)
98 
100 {
101  desc: "should always return false when the _disableDrop flag is true",
102  pre: function (playlist) {
103  this.stub(playlist, '_disableDrop', true);
104  },
105  exec: function (playlist) {
106  assertEqual(this.expected, playlist._canDrop(), this.desc);
107  },
108  expected: false
109 },
110 {
111  desc: "should always return false when the target is read only",
112  pre: function (playlist) {
113  this.stash = playlist.mediaList.getProperty(SBProperties.isReadOnly);
114  playlist.mediaList.setProperty(SBProperties.isReadOnly, "1");
115  },
116  exec: function(playlist) {
117  assertEqual(this.expected, playlist._canDrop(), this.desc);
118  },
119  post: function (playlist) {
120  playlist.mediaList.setProperty(SBProperties.isReadOnly, this.stash);
121  },
122  expected: false
123 },
124 {
125  desc: "should always return false when the target has read only content",
126  pre: function (playlist) {
127  this.stash = playlist.mediaList.getProperty(SBProperties.isContentReadOnly);
128  playlist.mediaList.setProperty(SBProperties.isContentReadOnly, "1");
129  },
130  exec: function (playlist) {
131  assertEqual(this.expected, playlist._canDrop(), this.desc);
132  },
133  post: function (playlist) {
134  playlist.mediaList.setProperty(SBProperties.isContentReadOnly, this.stash);
135  },
136  expected: false
137 },
138 {
139  desc: "should return true is the drop is a supported external flavor",
140  pre: function (playlist) {
141  this.stub(ExternalDropHandler, 'isSupported', function () {
142  return true;
143  });
144  },
145  exec: function (playlist) {
146  assertEqual(this.expected, playlist._canDrop(), this.desc);
147  },
148  expected: true
149 },
150 {
151  desc: "should return false if the drop is not supported by any handler",
152  pre: function (playlist) {
153  this.stub(ExternalDropHandler, 'isSupported', function () {
154  return false;
155  });
156  this.stub(InternalDropHandler, 'isSupported', function () {
157  return false;
158  });
159  },
160  exec: function (playlist) {
161  assertEqual(this.expected, playlist._canDrop(), this.desc);
162  },
163  expected: false
164 },
165 {
166  desc: "should return false for lists of customType 'download' when " +
167  "_canDownloadDrop returns false",
168  pre: function (playlist) {
169  this.stub(ExternalDropHandler, 'isSupported', function () {
170  return false;
171  });
172  this.stub(InternalDropHandler, 'isSupported', function () {
173  return true;
174  });
175  this.stub(playlist, '_canDownloadDrop', function() {
176  return false;
177  });
178  var list = playlist.mediaList;
179  this.stash = list.getProperty(SBProperties.customType);
180  list.setProperty(SBProperties.customType, "download");
181  },
182  exec: function (playlist) {
183  assertEqual(this.expected, playlist._canDrop(), this.desc);
184  },
185  post: function (playlist) {
186  playlist.mediaList.setProperty(SBProperties.customType, this.stash);
187  },
188  expected: false
189 },
190 {
191  desc: "should return true for lists of customType 'download' when " +
192  "_canDownloadDrop returns true",
193  pre: function (playlist) {
194  this.stub(ExternalDropHandler, 'isSupported', function () {
195  return false;
196  });
197  this.stub(InternalDropHandler, 'isSupported', function () {
198  return true;
199  });
200  this.stub(playlist, '_canDownloadDrop', function() {
201  return true;
202  });
203  var list = playlist.mediaList;
204  this.stash = list.getProperty(SBProperties.customType);
205  list.setProperty(SBProperties.customType, "download");
206  },
207  exec: function (playlist) {
208  assertEqual(this.expected, playlist._canDrop(), this.desc);
209  },
210  post: function (playlist) {
211  playlist.mediaList.setProperty(SBProperties.customType, this.stash);
212  },
213  expected: true
214 },
215 {
216  desc: "should return false if an internal drop does not contain data",
217  pre: function (playlist) {
218  this.stub(ExternalDropHandler, 'isSupported', function () {
219  return false;
220  });
221  this.stub(InternalDropHandler, 'isSupported', function () {
222  return true;
223  });
224  this.stub(DNDUtils, 'getTransferDataForFlavour', function () {
225  return null;
226  });
227  },
228  exec: function (playlist) {
229  assertEqual(this.expected, playlist._canDrop(), this.desc);
230  },
231  expected: false
232 },
233 {
234  desc: "should return true if the internal drop is a supported flavor, " +
235  "the drop source is different from the drop target, " +
236  "and the drop target accepts drops from the source",
237  pre: function (playlist) {
238 
239  var dnd = Cc["@songbirdnest.com/Songbird/DndSourceTracker;1"]
240  .getService(Ci.sbIDndSourceTracker),
241  sourceList = playlist.library.createMediaList("simple"),
242  context = new DNDUtils.MediaListTransferContext(sourceList, sourceList),
243  handle = dnd.registerSource(context);
244 
245  this.stub(ExternalDropHandler, 'isSupported', function () {
246  return false;
247  });
248  this.stub(InternalDropHandler, 'isSupported', function () {
249  return true;
250  });
251  this.stub(DNDUtils, 'getTransferDataForFlavour', function (type) {
252  var sourceData = null;
253  if (type == "application/x-sb-transfer-media-list") {
254  sourceData = { data: handle };
255  }
256  return sourceData;
257  });
258  this.stub(playlist, 'acceptDropSource', function () {
259  return true;
260  });
261  },
262  exec: function (playlist) {
263  assertEqual(this.expected, playlist._canDrop(), this.desc);
264  },
265  expected: true
266 },
267 {
268  desc: "should return false if the internal drop is a supported flavor, " +
269  "the drop source is different from the drop target, " +
270  "and the drop target does not accept drops from the source",
271  pre: function (playlist) {
272 
273  var dnd = Cc["@songbirdnest.com/Songbird/DndSourceTracker;1"]
274  .getService(Ci.sbIDndSourceTracker),
275  sourceList = playlist.library.createMediaList("simple"),
276  context = new DNDUtils.MediaListTransferContext(sourceList, sourceList),
277  handle = dnd.registerSource(context);
278 
279  this.stub(ExternalDropHandler, 'isSupported', function () {
280  return false;
281  });
282  this.stub(InternalDropHandler, 'isSupported', function () {
283  return true;
284  });
285  this.stub(DNDUtils, 'getTransferDataForFlavour', function (type) {
286  var sourceData = null;
287  if (type == "application/x-sb-transfer-media-list") {
288  sourceData = { data: handle };
289  }
290  return sourceData;
291  });
292  this.stub(playlist, 'acceptDropSource', function () {
293  return false;
294  });
295  },
296  exec: function (playlist) {
297  assertEqual(this.expected, playlist._canDrop(), this.desc);
298  },
299  expected: false
300 },
301 {
302  desc: "should return false if the internal drop is a supported flavor, " +
303  "the drop source is the same as the drop target, " +
304  "and the drop target is a library",
305  pre: function (playlist) {
306 
307  var dnd = Cc["@songbirdnest.com/Songbird/DndSourceTracker;1"]
308  .getService(Ci.sbIDndSourceTracker),
309  sourceList = playlist.mediaList,
310  context = new DNDUtils.MediaListTransferContext(sourceList, sourceList),
311  handle = dnd.registerSource(context);
312 
313  this.stub(ExternalDropHandler, 'isSupported', function () {
314  return false;
315  });
316  this.stub(InternalDropHandler, 'isSupported', function () {
317  return true;
318  });
319  this.stub(DNDUtils, 'getTransferDataForFlavour', function (type) {
320  var sourceData = null;
321  if (type == "application/x-sb-transfer-media-list") {
322  sourceData = { data: handle };
323  }
324  return sourceData;
325  });
326  },
327  exec: function (playlist) {
328  assertEqual(this.expected, playlist._canDrop(), this.desc);
329  },
330  expected: false
331 }];
332 
334 {
335  desc: "should return true if the internal drop is a supported flavor, " +
336  "the drop source is the same as the drop target, " +
337  "and the drop target is not a library",
338  pre: function (playlist) {
339 
340  var dnd = Cc["@songbirdnest.com/Songbird/DndSourceTracker;1"]
341  .getService(Ci.sbIDndSourceTracker),
342  sourceList = playlist.mediaList,
343  context = new DNDUtils.MediaListTransferContext(sourceList, sourceList),
344  handle = dnd.registerSource(context);
345 
346  this.stub(ExternalDropHandler, 'isSupported', function () {
347  return false;
348  });
349  this.stub(InternalDropHandler, 'isSupported', function () {
350  return true;
351  });
352  this.stub(DNDUtils, 'getTransferDataForFlavour', function (type) {
353  var sourceData = null;
354  if (type == "application/x-sb-transfer-media-list") {
355  sourceData = { data: handle };
356  }
357  return sourceData;
358  });
359  },
360  exec: function (playlist) {
361  assertEqual(this.expected, playlist._canDrop(), this.desc);
362  },
363  expected: true
364 },
365 {
366  desc: "should return false if the internal drop is a supported flavor, " +
367  "the drop source is the same as the drop target, " +
368  "the drop target is not a library, and the drop target is not " +
369  "sorted ordinally",
370  pre: function (playlist) {
371 
372  var dnd = Cc["@songbirdnest.com/Songbird/DndSourceTracker;1"]
373  .getService(Ci.sbIDndSourceTracker),
374  sourceList = playlist.mediaList,
375  context = new DNDUtils.MediaListTransferContext(sourceList, sourceList),
376  handle = dnd.registerSource(context);
377 
378  this.stub(ExternalDropHandler, 'isSupported', function () {
379  return false;
380  });
381  this.stub(InternalDropHandler, 'isSupported', function () {
382  return true;
383  });
384  this.stub(DNDUtils, 'getTransferDataForFlavour', function (type) {
385  var sourceData = null;
386  if (type == "application/x-sb-transfer-media-list") {
387  sourceData = { data: handle };
388  }
389  return sourceData;
390  });
391  this.stub(playlist, 'isOrdinalSort', function() {
392  return false;
393  });
394  },
395  exec: function (playlist) {
396  assertEqual(this.expected, playlist._canDrop(), this.desc);
397  },
398  expected: false
399 }];
400 
402 {
403  desc: "canDrop should return false when _canDrop returns false",
404  pre: function (playlist) {
405  this.stub(playlist, '_canDrop', function () {
406  return false;
407  });
408  this.stub(playlist, 'isOrdinalSort', function () {
409  return true;
410  });
411  },
412  exec: function (playlist) {
413  assertEqual(this.expected, playlist.canDrop(), this.desc);
414  },
415  expected: false
416 },
417 {
418  desc: "canDrop should return false when the sort is not ordinal",
419  pre: function (playlist) {
420  this.stub(playlist, '_canDrop', function () {
421  return true;
422  });
423  this.stub(playlist, 'isOrdinalSort', function () {
424  return false;
425  });
426  },
427  exec: function (playlist) {
428  assertEqual(this.expected, playlist.canDrop(), this.desc);
429  },
430  expected: false
431 },
432 {
433  desc: "canDrop should return true when canDrop returns true and the sort " +
434  "is ordinal",
435  pre: function (playlist) {
436  this.stub(playlist, '_canDrop', function () {
437  return true;
438  });
439  this.stub(playlist, 'isOrdinalSort', function () {
440  return true;
441  });
442  },
443  exec: function (playlist) {
444  assertEqual(this.expected, playlist.canDrop(), this.desc);
445  },
446  expected: true
447 }];
448 
450 {
451  desc: "_canDrop should return false when the target is the play queue and " +
452  "the source belongs to a device",
453  pre: function (playlist, playQueuePlaylist) {
454  var dnd = Cc["@songbirdnest.com/Songbird/DndSourceTracker;1"]
455  .getService(Ci.sbIDndSourceTracker),
456  sourceList,
457  context,
458  handle;
459 
460  this.dev = Cc["@songbirdnest.com/Songbird/Device/DeviceTester/MockDevice;1"]
461  .createInstance(Ci.sbIDevice),
462  this.devMgr = Cc["@songbirdnest.com/Songbird/DeviceManager;2"]
463  .getService(Ci.sbIDeviceManager2),
464  this.devMgr.registerDevice(this.dev);
465  sourceList = this.dev.defaultLibrary
466  .QueryInterface(Ci.sbILibrary)
467  .createMediaList("simple");
468  context = new DNDUtils.MediaListTransferContext(sourceList, sourceList),
469  handle = dnd.registerSource(context);
470 
471  this.stub(ExternalDropHandler, 'isSupported', function () {
472  return false;
473  });
474  this.stub(InternalDropHandler, 'isSupported', function() {
475  return true;
476  });
477  this.stub(DNDUtils, 'getTransferDataForFlavour', function (type) {
478  var sourceData = null;
479  if (type == "application/x-sb-transfer-media-list") {
480  sourceData = { data: handle };
481  }
482  return sourceData;
483  });
484  },
485  exec: function (playlist, playQueuePlaylist) {
486  assertEqual(this.expected, playQueuePlaylist._canDrop(), this.desc);
487  },
488  post: function() {
489  this.devMgr.unregisterDevice(this.dev);
490  this.dev.disconnect();
491  this.dev = null;
492  this.devMgr = null;
493  },
494  expected: false
495 },
496 {
497  desc: "_canDrop should return true when the target is the play queue and " +
498  "the source does not belong to a device, provided other normal " +
499  "drop constraints are satisfied",
500  pre: function (playlist, playQueuePlaylist) {
501  var dnd = Cc["@songbirdnest.com/Songbird/DndSourceTracker;1"]
502  .getService(Ci.sbIDndSourceTracker),
503  sourceList = playlist.library.createMediaList("simple"),
504  context = new DNDUtils.MediaListTransferContext(sourceList, sourceList),
505  handle = dnd.registerSource(context);
506 
507  this.stub(ExternalDropHandler, 'isSupported', function () {
508  return false;
509  });
510  this.stub(InternalDropHandler, 'isSupported', function() {
511  return true;
512  });
513  this.stub(DNDUtils, 'getTransferDataForFlavour', function (type) {
514  var sourceData = null;
515  if (type == "application/x-sb-transfer-media-list") {
516  sourceData = { data: handle };
517  }
518  return sourceData;
519  });
520  },
521  exec: function (playlist, playQueuePlaylist) {
522  assertEqual(this.expected, playQueuePlaylist._canDrop(), this.desc);
523  },
524  expected: true
525 
526 }];
527 
const Cc
function endWindowTest(e)
function TestCase(config)
const K_DROPONLIBRARY_TESTS
var DNDUtils
Definition: DropHelper.jsm:80
function beginWindowTest(url, continueFunction)
function assertEqual(aExpected, aActual, aMessage)
function handle(request, response)
function test_canDrop(aLibraryPlaylist, aListPlaylist, aPlayQueuePlaylist)
var XUL_NS
function runTest()
Advanced DataRemote unit tests.
function setup()
const K_DROPINDICATOR_TESTS
const K_DROPONPLAYQUEUE_TESTS
return null
Definition: FeedWriter.js:1143
function createLibrary(databaseGuid, databaseLocation)
Definition: test_load.js:151
var expected
var testWindow
Test file.
function url(spec)
const Cu
const Ci
const K_DROPONLIST_TESTS
observe data
Definition: FeedWriter.js:1329
_getSelectedPageStyle s i
function continueWindowTest(fn, parameters)