Enable removing genre auto-playlists from the list
- Added an svg "X" icon to enable removing auto-playlists - Notice that the background-color and color change are done too, and since it's SVG, it takes only one image and some CSS to do both. - Added a subsonic.css file. It is intended (long term) to have all subsonic view-related CSS styles. - persistence-service now manages the selected genre auto-playlists names instead of utils.getValue(). - Rewrote persistence-service.js to comply with https://github.com/johnpapa/angular-styleguide#style-y052 - Rewrote many test descriptions in persistence-service_test.js to follow these recommendations : http://gojko.net/2015/02/25/how-to-get-the-most-out-of-given-when-then/
This commit is contained in:
parent
d2bdb8eed9
commit
48da0ee7f0
9 changed files with 600 additions and 393 deletions
|
@ -6,8 +6,6 @@ angular.module('JamStash')
|
||||||
$rootScope.settings = globals.settings;
|
$rootScope.settings = globals.settings;
|
||||||
$rootScope.song = [];
|
$rootScope.song = [];
|
||||||
$rootScope.playingSong = null;
|
$rootScope.playingSong = null;
|
||||||
$rootScope.MusicFolders = [];
|
|
||||||
$rootScope.Genres = [];
|
|
||||||
$rootScope.Messages = [];
|
$rootScope.Messages = [];
|
||||||
|
|
||||||
$rootScope.unity = null;
|
$rootScope.unity = null;
|
||||||
|
@ -56,7 +54,6 @@ angular.module('JamStash')
|
||||||
}
|
}
|
||||||
if (utils.getValue("SavedCollections")) { globals.SavedCollections = utils.getValue("SavedCollections").split(","); }
|
if (utils.getValue("SavedCollections")) { globals.SavedCollections = utils.getValue("SavedCollections").split(","); }
|
||||||
if (utils.getValue("DefaultCollection")) { globals.DefaultCollection = utils.getValue("DefaultCollection"); }
|
if (utils.getValue("DefaultCollection")) { globals.DefaultCollection = utils.getValue("DefaultCollection"); }
|
||||||
if (utils.getValue("SavedGenres")) { globals.SavedGenres = utils.getValue("SavedGenres").split(","); }
|
|
||||||
if (globals.settings.Debug) { console.log('Loaded Settings: ' + JSON.stringify(globals.settings, null, 2)); }
|
if (globals.settings.Debug) { console.log('Loaded Settings: ' + JSON.stringify(globals.settings, null, 2)); }
|
||||||
};
|
};
|
||||||
$scope.toggleSetting = function (setting) {
|
$scope.toggleSetting = function (setting) {
|
||||||
|
|
|
@ -1,141 +1,24 @@
|
||||||
'use strict';
|
|
||||||
/**
|
/**
|
||||||
* jamstash.persistence Module
|
* jamstash.persistence Module
|
||||||
*
|
*
|
||||||
* Provides load, save and delete operations for the current song and queue.
|
* Provides load, save and delete operations for the current song and queue.
|
||||||
* Data storage provided by HTML5 localStorage.
|
* Data storage provided by HTML5 localStorage.
|
||||||
*/
|
*/
|
||||||
angular.module('jamstash.persistence', ['ngLodash', 'angular-locker',
|
angular.module('jamstash.persistence', [
|
||||||
'jamstash.settings.service', 'jamstash.player.service', 'jamstash.notifications', 'jamstash.utils'])
|
'ngLodash',
|
||||||
|
'angular-locker',
|
||||||
|
'jamstash.settings.service',
|
||||||
|
'jamstash.player.service',
|
||||||
|
'jamstash.notifications',
|
||||||
|
'jamstash.utils'
|
||||||
|
])
|
||||||
|
|
||||||
.config(['lockerProvider', function (lockerProvider) {
|
.config(['lockerProvider', lockerConfig])
|
||||||
lockerProvider.setDefaultDriver('local')
|
|
||||||
.setDefaultNamespace(false)
|
|
||||||
.setEventsEnabled(false);
|
|
||||||
}])
|
|
||||||
|
|
||||||
.service('persistence', ['lodash', 'globals', 'player', 'notifications', 'locker', 'json', 'jamstashVersionChangesets', 'utils',
|
.service('persistence', persistenceService)
|
||||||
function (_, globals, player, notifications, locker, json, jamstashVersionChangesets, utils) {
|
|
||||||
/* Manage current track */
|
|
||||||
this.loadTrackPosition = function () {
|
|
||||||
// Load Saved Song
|
|
||||||
var song = locker.get('CurrentSong');
|
|
||||||
if (song) {
|
|
||||||
player.load(song);
|
|
||||||
}
|
|
||||||
if (globals.settings.Debug) { console.log('Current Position Loaded from localStorage: ', song); }
|
|
||||||
};
|
|
||||||
|
|
||||||
this.saveTrackPosition = function (song) {
|
|
||||||
locker.put('CurrentSong', song);
|
|
||||||
if (globals.settings.Debug) { console.log('Saving Current Position: ', song); }
|
|
||||||
};
|
|
||||||
|
|
||||||
this.deleteTrackPosition = function () {
|
|
||||||
locker.forget('CurrentSong');
|
|
||||||
if (globals.settings.Debug) { console.log('Removing Current Position from localStorage'); }
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Manage playing queue */
|
|
||||||
this.loadQueue = function () {
|
|
||||||
// load Saved queue
|
|
||||||
var queue = locker.get('CurrentQueue');
|
|
||||||
if (queue) {
|
|
||||||
player.addSongs(queue);
|
|
||||||
if (player.queue.length > 0) {
|
|
||||||
notifications.updateMessage(player.queue.length + ' Saved Song(s)', true);
|
|
||||||
}
|
|
||||||
if (globals.settings.Debug) { console.log('Play Queue Loaded from localStorage: ' + player.queue.length + ' song(s)'); }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.saveQueue = function () {
|
|
||||||
locker.put('CurrentQueue', player.queue);
|
|
||||||
if (globals.settings.Debug) { console.log('Saving Queue: ' + player.queue.length + ' songs'); }
|
|
||||||
};
|
|
||||||
|
|
||||||
this.deleteQueue = function () {
|
|
||||||
locker.forget('CurrentQueue');
|
|
||||||
if (globals.settings.Debug) { console.log('Removing Play Queue from localStorage'); }
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Manage player volume */
|
|
||||||
this.getVolume = function () {
|
|
||||||
var volume = locker.get('Volume');
|
|
||||||
if (volume === undefined) {
|
|
||||||
locker.put('Volume', 1.0);
|
|
||||||
volume = 1.0;
|
|
||||||
}
|
|
||||||
return volume;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.saveVolume = function (volume) {
|
|
||||||
locker.put('Volume', volume);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.deleteVolume = function () {
|
|
||||||
locker.forget('Volume');
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Manage selected music folder */
|
|
||||||
this.getSelectedMusicFolder = function () {
|
|
||||||
return locker.get('MusicFolders');
|
|
||||||
};
|
|
||||||
|
|
||||||
this.saveSelectedMusicFolder = function (selectedMusicFolder) {
|
|
||||||
locker.put('MusicFolders', selectedMusicFolder);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.deleteSelectedMusicFolder = function () {
|
|
||||||
locker.forget('MusicFolders');
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Manage user settings */
|
|
||||||
this.getSettings = function () {
|
|
||||||
// If the latest version from changelog.json is newer than the version stored in local storage,
|
|
||||||
// we upgrade it
|
|
||||||
var storedVersion = this.getVersion();
|
|
||||||
var persistenceService = this;
|
|
||||||
json.getChangeLog(function (changelogs) {
|
|
||||||
var changelogVersion = changelogs[0].version;
|
|
||||||
if(utils.checkVersionNewer(changelogVersion, storedVersion)) {
|
|
||||||
persistenceService.upgradeVersion(storedVersion, changelogVersion);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return locker.get('Settings');
|
|
||||||
};
|
|
||||||
|
|
||||||
this.saveSettings = function (settings) {
|
|
||||||
locker.put('Settings', settings);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.deleteSettings = function () {
|
|
||||||
locker.forget('Settings');
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Manage Jamstash Version */
|
|
||||||
this.getVersion = function () {
|
|
||||||
return locker.get('JamstashVersion');
|
|
||||||
};
|
|
||||||
|
|
||||||
this.upgradeVersion = function (currentVersion, finalVersion) {
|
|
||||||
var settings = locker.get('Settings');
|
|
||||||
// Apply all upgrades older than the final version and newer than the current
|
|
||||||
var allUpgrades = _.filter(jamstashVersionChangesets.versions, function (toApply) {
|
|
||||||
var olderOrEqualToFinal = utils.checkVersion(finalVersion, toApply.version);
|
|
||||||
var newerThanCurrent = utils.checkVersionNewer(toApply.version, currentVersion);
|
|
||||||
return olderOrEqualToFinal && newerThanCurrent;
|
|
||||||
});
|
|
||||||
_.forEach(allUpgrades, function (versionUpg) {
|
|
||||||
versionUpg.changeset(settings);
|
|
||||||
});
|
|
||||||
this.saveSettings(settings);
|
|
||||||
locker.put('JamstashVersion', finalVersion);
|
|
||||||
notifications.updateMessage('Version ' + currentVersion + ' to ' + finalVersion, true);
|
|
||||||
};
|
|
||||||
}])
|
|
||||||
|
|
||||||
.value('jamstashVersionChangesets', {
|
.value('jamstashVersionChangesets', {
|
||||||
|
// jshint strict: false
|
||||||
versions: [
|
versions: [
|
||||||
{
|
{
|
||||||
version: '4.4.5',
|
version: '4.4.5',
|
||||||
|
@ -146,3 +29,187 @@ angular.module('jamstash.persistence', ['ngLodash', 'angular-locker',
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
lockerConfig.$inject = ['lockerProvider'];
|
||||||
|
|
||||||
|
function lockerConfig(lockerProvider) {
|
||||||
|
'use strict';
|
||||||
|
lockerProvider.setDefaultDriver('local')
|
||||||
|
.setDefaultNamespace(false)
|
||||||
|
.setEventsEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
persistenceService.$inject = [
|
||||||
|
'lodash',
|
||||||
|
'globals',
|
||||||
|
'player',
|
||||||
|
'notifications',
|
||||||
|
'locker',
|
||||||
|
'json',
|
||||||
|
'jamstashVersionChangesets',
|
||||||
|
'utils'
|
||||||
|
];
|
||||||
|
|
||||||
|
function persistenceService(_, globals, player, notifications, locker, json, jamstashVersionChangesets, utils) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const CURRENT_SONG = 'CurrentSong',
|
||||||
|
CURRENT_QUEUE = 'CurrentQueue',
|
||||||
|
VOLUME = 'Volume',
|
||||||
|
MUSIC_FOLDERS = 'MusicFolders',
|
||||||
|
GENRES = 'SavedGenres',
|
||||||
|
SETTINGS = 'Settings';
|
||||||
|
|
||||||
|
// jshint validthis: true
|
||||||
|
var self = this;
|
||||||
|
_.extend(self, {
|
||||||
|
loadTrackPosition : loadTrackPosition,
|
||||||
|
saveTrackPosition : saveTrackPosition,
|
||||||
|
deleteTrackPosition : deleteTrackPosition,
|
||||||
|
loadQueue : loadQueue,
|
||||||
|
saveQueue : saveQueue,
|
||||||
|
deleteQueue : deleteQueue,
|
||||||
|
getVolume : getVolume,
|
||||||
|
saveVolume : saveVolume,
|
||||||
|
deleteVolume : deleteVolume,
|
||||||
|
getSelectedMusicFolder : getSelectedMusicFolder,
|
||||||
|
saveSelectedMusicFolder : saveSelectedMusicFolder,
|
||||||
|
deleteSelectedMusicFolder: deleteSelectedMusicFolder,
|
||||||
|
saveSelectedGenreNames : saveSelectedGenreNames,
|
||||||
|
loadSelectedGenreNames : loadSelectedGenreNames,
|
||||||
|
deleteSelectedGenreNames : deleteSelectedGenreNames,
|
||||||
|
getSettings : getSettings,
|
||||||
|
saveSettings : saveSettings,
|
||||||
|
deleteSettings : deleteSettings,
|
||||||
|
getVersion : getVersion,
|
||||||
|
upgradeVersion : upgradeVersion
|
||||||
|
});
|
||||||
|
|
||||||
|
return self;
|
||||||
|
|
||||||
|
function loadTrackPosition() {
|
||||||
|
// Load Saved Song
|
||||||
|
var song = locker.get(CURRENT_SONG);
|
||||||
|
if (song) {
|
||||||
|
player.load(song);
|
||||||
|
}
|
||||||
|
if (globals.settings.Debug) { console.log('Current Position Loaded from localStorage: ', song); }
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveTrackPosition(song) {
|
||||||
|
locker.put(CURRENT_SONG, song);
|
||||||
|
if (globals.settings.Debug) { console.log('Saving Current Position: ', song); }
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteTrackPosition() {
|
||||||
|
locker.forget(CURRENT_SONG);
|
||||||
|
if (globals.settings.Debug) { console.log('Removing Current Position from localStorage'); }
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadQueue() {
|
||||||
|
// load Saved queue
|
||||||
|
var queue = locker.get(CURRENT_QUEUE);
|
||||||
|
if (queue) {
|
||||||
|
player.addSongs(queue);
|
||||||
|
if (player.queue.length > 0) {
|
||||||
|
notifications.updateMessage(player.queue.length + ' Saved Song(s)', true);
|
||||||
|
}
|
||||||
|
if (globals.settings.Debug) { console.log('Play Queue Loaded from localStorage: ' + player.queue.length + ' song(s)'); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveQueue() {
|
||||||
|
locker.put(CURRENT_QUEUE, player.queue);
|
||||||
|
if (globals.settings.Debug) { console.log('Saving Queue: ' + player.queue.length + ' songs'); }
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteQueue() {
|
||||||
|
locker.forget(CURRENT_QUEUE);
|
||||||
|
if (globals.settings.Debug) { console.log('Removing Play Queue from localStorage'); }
|
||||||
|
}
|
||||||
|
|
||||||
|
function getVolume() {
|
||||||
|
var volume = locker.get(VOLUME);
|
||||||
|
if (volume === undefined) {
|
||||||
|
locker.put(VOLUME, 1.0);
|
||||||
|
volume = 1.0;
|
||||||
|
}
|
||||||
|
return volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveVolume(volume) {
|
||||||
|
locker.put(VOLUME, volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteVolume() {
|
||||||
|
locker.forget(VOLUME);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSelectedMusicFolder() {
|
||||||
|
return locker.get(MUSIC_FOLDERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveSelectedMusicFolder(selectedMusicFolder) {
|
||||||
|
locker.put(MUSIC_FOLDERS, selectedMusicFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteSelectedMusicFolder() {
|
||||||
|
locker.forget(MUSIC_FOLDERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveSelectedGenreNames(selectedGenreNames) {
|
||||||
|
locker.put(GENRES, selectedGenreNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadSelectedGenreNames() {
|
||||||
|
var selectedGenreNames = locker.get(GENRES);
|
||||||
|
if (selectedGenreNames === undefined) {
|
||||||
|
selectedGenreNames = [];
|
||||||
|
}
|
||||||
|
return selectedGenreNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteSelectedGenreNames() {
|
||||||
|
locker.forget(GENRES);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSettings() {
|
||||||
|
// If the latest version from changelog.json is newer than the version stored in local storage,
|
||||||
|
// we upgrade it
|
||||||
|
var storedVersion = self.getVersion();
|
||||||
|
json.getChangeLog(function (changelogs) {
|
||||||
|
var changelogVersion = changelogs[0].version;
|
||||||
|
if (utils.checkVersionNewer(changelogVersion, storedVersion)) {
|
||||||
|
self.upgradeVersion(storedVersion, changelogVersion);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return locker.get(SETTINGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveSettings(settings) {
|
||||||
|
locker.put(SETTINGS, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteSettings() {
|
||||||
|
locker.forget(SETTINGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getVersion() {
|
||||||
|
return locker.get('JamstashVersion');
|
||||||
|
}
|
||||||
|
|
||||||
|
function upgradeVersion(currentVersion, finalVersion) {
|
||||||
|
var settings = locker.get(SETTINGS);
|
||||||
|
// Apply all upgrades older than the final version and newer than the current
|
||||||
|
var allUpgrades = _.filter(jamstashVersionChangesets.versions, function (toApply) {
|
||||||
|
var olderOrEqualToFinal = utils.checkVersion(finalVersion, toApply.version);
|
||||||
|
var newerThanCurrent = utils.checkVersionNewer(toApply.version, currentVersion);
|
||||||
|
return olderOrEqualToFinal && newerThanCurrent;
|
||||||
|
});
|
||||||
|
_.forEach(allUpgrades, function (versionUpg) {
|
||||||
|
versionUpg.changeset(settings);
|
||||||
|
});
|
||||||
|
self.saveSettings(settings);
|
||||||
|
locker.put('JamstashVersion', finalVersion);
|
||||||
|
notifications.updateMessage('Version ' + currentVersion + ' to ' + finalVersion, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
describe("Persistence service", function() {
|
// jscs:disable validateQuoteMarks
|
||||||
|
describe("Persistence service", function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var persistence, player, notifications, locker, json,
|
var persistence, player, notifications, locker, json,
|
||||||
song, fakeStorage, fakeVersionChangesets;
|
song, fakeStorage, fakeVersionChangesets;
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
fakeVersionChangesets = {versions: []};
|
fakeVersionChangesets = { versions: []};
|
||||||
module('jamstash.persistence', function ($provide) {
|
module('jamstash.persistence', function ($provide) {
|
||||||
// Mock locker
|
// Mock locker
|
||||||
$provide.decorator('locker', function () {
|
$provide.decorator('locker', function () {
|
||||||
|
@ -43,17 +44,17 @@ describe("Persistence service", function() {
|
||||||
};
|
};
|
||||||
fakeStorage = {};
|
fakeStorage = {};
|
||||||
|
|
||||||
locker.get.and.callFake(function(key) {
|
locker.get.and.callFake(function (key) {
|
||||||
return fakeStorage[key];
|
return fakeStorage[key];
|
||||||
});
|
});
|
||||||
locker.put.and.callFake(function(key, value) {
|
locker.put.and.callFake(function (key, value) {
|
||||||
fakeStorage[key] = value;
|
fakeStorage[key] = value;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("loadTrackPosition() -", function() {
|
describe("loadTrackPosition() -", function () {
|
||||||
it("Given a previously saved song in local storage, when I load the song, the player will load it", function() {
|
it("Given a previously saved song in local storage, when I load the song, the player will load it", function () {
|
||||||
fakeStorage = { 'CurrentSong': song };
|
fakeStorage = { CurrentSong: song };
|
||||||
|
|
||||||
persistence.loadTrackPosition();
|
persistence.loadTrackPosition();
|
||||||
|
|
||||||
|
@ -61,38 +62,38 @@ describe("Persistence service", function() {
|
||||||
expect(player.load).toHaveBeenCalledWith(song);
|
expect(player.load).toHaveBeenCalledWith(song);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that no song was previously saved in local storage, it doesn't do anything", function() {
|
it("Given that no song was previously saved in local storage, it doesn't do anything", function () {
|
||||||
persistence.loadTrackPosition();
|
persistence.loadTrackPosition();
|
||||||
expect(locker.get).toHaveBeenCalledWith('CurrentSong');
|
expect(locker.get).toHaveBeenCalledWith('CurrentSong');
|
||||||
expect(player.load).not.toHaveBeenCalled();
|
expect(player.load).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("saveTrackPosition() - saves the current track's position in local storage", function() {
|
it("saveTrackPosition() - Given a song object, when I save the current track's position, then it will be set in local storage", function () {
|
||||||
persistence.saveTrackPosition(song);
|
persistence.saveTrackPosition(song);
|
||||||
expect(locker.put).toHaveBeenCalledWith('CurrentSong', song);
|
expect(locker.put).toHaveBeenCalledWith('CurrentSong', song);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("deleteTrackPosition() - deletes the current track from local storage", function() {
|
it("deleteTrackPosition() - When I delete the current track, then it will be erased from local storage", function () {
|
||||||
persistence.deleteTrackPosition();
|
persistence.deleteTrackPosition();
|
||||||
expect(locker.forget).toHaveBeenCalledWith('CurrentSong');
|
expect(locker.forget).toHaveBeenCalledWith('CurrentSong');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("loadQueue() -", function() {
|
describe("loadQueue() -", function () {
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
player.addSongs.and.callFake(function (songs) {
|
player.addSongs.and.callFake(function (songs) {
|
||||||
// Update the queue length so that notifications work
|
// Update the queue length so that notifications work
|
||||||
player.queue.length += songs.length;
|
player.queue.length += songs.length;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given a previously saved queue in local storage, when I load the queue, the player's queue will be filled with the retrieved queue and the user will be notified", function() {
|
it("Given a previously saved queue in local storage, when I load the queue, the player's queue will be filled with the retrieved queue and the user will be notified", function () {
|
||||||
var queue = [
|
var queue = [
|
||||||
{ id: 8705 },
|
{ id: 8705 },
|
||||||
{ id: 1617 },
|
{ id: 1617 },
|
||||||
{ id: 9812 }
|
{ id: 9812 }
|
||||||
];
|
];
|
||||||
fakeStorage = { 'CurrentQueue': queue };
|
fakeStorage = { CurrentQueue: queue };
|
||||||
|
|
||||||
persistence.loadQueue();
|
persistence.loadQueue();
|
||||||
|
|
||||||
|
@ -101,7 +102,7 @@ describe("Persistence service", function() {
|
||||||
expect(notifications.updateMessage).toHaveBeenCalledWith('3 Saved Song(s)', true);
|
expect(notifications.updateMessage).toHaveBeenCalledWith('3 Saved Song(s)', true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that no queue was previously saved in local storage, when I load the queue, the player's queue will stay the same and no notification will be displayed", function() {
|
it("Given that no queue was previously saved in local storage, when I load the queue, the player's queue will stay the same and no notification will be displayed", function () {
|
||||||
persistence.loadQueue();
|
persistence.loadQueue();
|
||||||
|
|
||||||
expect(locker.get).toHaveBeenCalledWith('CurrentQueue');
|
expect(locker.get).toHaveBeenCalledWith('CurrentQueue');
|
||||||
|
@ -110,7 +111,7 @@ describe("Persistence service", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("saveQueue() - saves the playing queue in local storage", function() {
|
it("saveQueue() - Given an array of song objects, when I save the playing queue, then the array will be set in local storage", function () {
|
||||||
player.queue = [
|
player.queue = [
|
||||||
{ id: 1245 },
|
{ id: 1245 },
|
||||||
{ id: 7465 },
|
{ id: 7465 },
|
||||||
|
@ -120,14 +121,14 @@ describe("Persistence service", function() {
|
||||||
expect(locker.put).toHaveBeenCalledWith('CurrentQueue', player.queue);
|
expect(locker.put).toHaveBeenCalledWith('CurrentQueue', player.queue);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("deleteQueue() - deletes the saved playing queue from local storage", function() {
|
it("deleteQueue() - When I delete the playing queue, then it will be erased from local storage", function () {
|
||||||
persistence.deleteQueue();
|
persistence.deleteQueue();
|
||||||
expect(locker.forget).toHaveBeenCalledWith('CurrentQueue');
|
expect(locker.forget).toHaveBeenCalledWith('CurrentQueue');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getVolume() -", function() {
|
describe("getVolume() -", function () {
|
||||||
it("Given a previously saved volume value in local storage, it retrieves it", function() {
|
it("Given a previously saved volume value in local storage, it retrieves it", function () {
|
||||||
fakeStorage = { 'Volume': 0.46582 };
|
fakeStorage = { Volume: 0.46582 };
|
||||||
|
|
||||||
var volume = persistence.getVolume();
|
var volume = persistence.getVolume();
|
||||||
|
|
||||||
|
@ -135,7 +136,7 @@ describe("Persistence service", function() {
|
||||||
expect(volume).toBe(0.46582);
|
expect(volume).toBe(0.46582);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that no volume value was previously saved in local storage, it will return 1.0 and set it in local storage", function() {
|
it("Given that no volume value was previously saved in local storage, it will return 1.0 and set it in local storage", function () {
|
||||||
var volume = persistence.getVolume();
|
var volume = persistence.getVolume();
|
||||||
|
|
||||||
expect(locker.get).toHaveBeenCalledWith('Volume');
|
expect(locker.get).toHaveBeenCalledWith('Volume');
|
||||||
|
@ -144,22 +145,22 @@ describe("Persistence service", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("saveVolume() - given a volume, it will be saved in local storage", function() {
|
it("saveVolume() - Given a volume, when I save the volume, then it will be set in local storage", function () {
|
||||||
persistence.saveVolume(0.05167);
|
persistence.saveVolume(0.05167);
|
||||||
expect(locker.put).toHaveBeenCalledWith('Volume', 0.05167);
|
expect(locker.put).toHaveBeenCalledWith('Volume', 0.05167);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("deleteVolume() - deletes the saved volume from local storage", function() {
|
it("deleteVolume() - When I delete the volume, then it will be erased from local storage", function () {
|
||||||
persistence.deleteVolume();
|
persistence.deleteVolume();
|
||||||
expect(locker.forget).toHaveBeenCalledWith('Volume');
|
expect(locker.forget).toHaveBeenCalledWith('Volume');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getSelectedMusicFolder() -", function() {
|
describe("getSelectedMusicFolder() -", function () {
|
||||||
it("Given a previously saved selected music folder in local storage, when I get the saved music folder, then an object containing the id and name of the selected music folder will be returned", function() {
|
it("Given a previously saved selected music folder in local storage, when I get the saved music folder, then an object containing the id and name of the selected music folder will be returned", function () {
|
||||||
fakeStorage = {
|
fakeStorage = {
|
||||||
'MusicFolders': {
|
MusicFolders: {
|
||||||
'id': 74,
|
id: 74,
|
||||||
'name': 'kooliman unhurled'
|
name: 'kooliman unhurled'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -167,12 +168,12 @@ describe("Persistence service", function() {
|
||||||
|
|
||||||
expect(locker.get).toHaveBeenCalledWith('MusicFolders');
|
expect(locker.get).toHaveBeenCalledWith('MusicFolders');
|
||||||
expect(selectedMusicFolder).toEqual({
|
expect(selectedMusicFolder).toEqual({
|
||||||
'id': 74,
|
id: 74,
|
||||||
'name': 'kooliman unhurled'
|
name: 'kooliman unhurled'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that no selected music folder was previously saved in local storage, when I get the saved music folder, then undefined will be returned", function() {
|
it("Given that no selected music folder was previously saved in local storage, when I get the saved music folder, then undefined will be returned", function () {
|
||||||
var selectedMusicFolder = persistence.getSelectedMusicFolder();
|
var selectedMusicFolder = persistence.getSelectedMusicFolder();
|
||||||
|
|
||||||
expect(locker.get).toHaveBeenCalledWith('MusicFolders');
|
expect(locker.get).toHaveBeenCalledWith('MusicFolders');
|
||||||
|
@ -180,7 +181,7 @@ describe("Persistence service", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("saveSelectedMusicFolder() - given an object containing the id and name of the selected music folder, when I save the music folder, then it will be set in local storage", function() {
|
it("saveSelectedMusicFolder() - Given an object containing the id and name of the selected music folder, when I save the music folder, then it will be set in local storage", function () {
|
||||||
persistence.saveSelectedMusicFolder({
|
persistence.saveSelectedMusicFolder({
|
||||||
id: 41,
|
id: 41,
|
||||||
name: 'parlormaid carcinolytic'
|
name: 'parlormaid carcinolytic'
|
||||||
|
@ -191,27 +192,57 @@ describe("Persistence service", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("deleteSelectedMusicFolder() - when I delete the selected music folder, then it will be erased from local storage", function() {
|
it("deleteSelectedMusicFolder() - When I delete the selected music folder, then it will be erased from local storage", function () {
|
||||||
persistence.deleteSelectedMusicFolder();
|
persistence.deleteSelectedMusicFolder();
|
||||||
expect(locker.forget).toHaveBeenCalledWith('MusicFolders');
|
expect(locker.forget).toHaveBeenCalledWith('MusicFolders');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getSettings() -", function() {
|
describe("loadSelectedGenreNames() -", function () {
|
||||||
beforeEach(function() {
|
it("Given a previously saved array of genre names in local storage, when I get the saved genre names, then an array of genre names will be returned", function () {
|
||||||
|
fakeStorage = {
|
||||||
|
SavedGenres: ['thermetrograph', 'balandra transrhodanian', 'loverdom codeposit']
|
||||||
|
};
|
||||||
|
|
||||||
|
var selectedGenreNames = persistence.loadSelectedGenreNames();
|
||||||
|
|
||||||
|
expect(locker.get).toHaveBeenCalledWith('SavedGenres');
|
||||||
|
expect(selectedGenreNames).toEqual(['thermetrograph', 'balandra transrhodanian', 'loverdom codeposit']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Given that no selected genre name was previously saved in local storage, when I get the saved genre names, then an empty array will be returned", function () {
|
||||||
|
var selectedGenreNames = persistence.loadSelectedGenreNames();
|
||||||
|
|
||||||
|
expect(locker.get).toHaveBeenCalledWith('SavedGenres');
|
||||||
|
expect(selectedGenreNames).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("saveSelectedGenreNames() - Given an array of genre names, when I save the genre names, then the array will be set in local storage", function () {
|
||||||
|
persistence.saveSelectedGenreNames(['verascope', 'diode encephalotome', 'already squabbly']);
|
||||||
|
expect(locker.put).toHaveBeenCalledWith('SavedGenres', ['verascope', 'diode encephalotome', 'already squabbly']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("deleteSelectedGenreNames() - When I delete the genre names, then they will be erased from local storage", function () {
|
||||||
|
persistence.deleteSelectedGenreNames();
|
||||||
|
expect(locker.forget).toHaveBeenCalledWith('SavedGenres');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("getSettings() -", function () {
|
||||||
|
beforeEach(function () {
|
||||||
spyOn(persistence, 'upgradeVersion');
|
spyOn(persistence, 'upgradeVersion');
|
||||||
json.getChangeLog.and.callFake(function (callback) {
|
json.getChangeLog.and.callFake(function (callback) {
|
||||||
callback([
|
callback([
|
||||||
{version: '1.0.1'}
|
{ version: '1.0.1' }
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
fakeStorage.JamstashVersion = '1.0.1';
|
fakeStorage.JamstashVersion = '1.0.1';
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given previously saved user settings in local storage, a promise will be resovled with the user settings", function() {
|
it("Given previously saved user settings in local storage, a promise will be resovled with the user settings", function () {
|
||||||
fakeStorage = {
|
fakeStorage = {
|
||||||
"Settings": {
|
Settings: {
|
||||||
"url": "https://headed.com/aleurodidae/taistrel?a=roquet&b=trichophoric#cathole",
|
url: "https://headed.com/aleurodidae/taistrel?a=roquet&b=trichophoric#cathole",
|
||||||
"Username": "Haupert"
|
Username: "Haupert"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -219,12 +250,12 @@ describe("Persistence service", function() {
|
||||||
|
|
||||||
expect(locker.get).toHaveBeenCalledWith('Settings');
|
expect(locker.get).toHaveBeenCalledWith('Settings');
|
||||||
expect(settings).toEqual({
|
expect(settings).toEqual({
|
||||||
"url": "https://headed.com/aleurodidae/taistrel?a=roquet&b=trichophoric#cathole",
|
url: "https://headed.com/aleurodidae/taistrel?a=roquet&b=trichophoric#cathole",
|
||||||
"Username": "Haupert"
|
Username: "Haupert"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that the previously stored Jamstash version was '1.0.0' and given the latest version in changelog.json was '1.0.1', when I get the settings, then upgradeVersion will be called", function() {
|
it("Given that the previously stored Jamstash version was '1.0.0' and given the latest version in changelog.json was '1.0.1', when I get the settings, then upgradeVersion will be called", function () {
|
||||||
fakeStorage.JamstashVersion = '1.0.0';
|
fakeStorage.JamstashVersion = '1.0.0';
|
||||||
|
|
||||||
persistence.getSettings();
|
persistence.getSettings();
|
||||||
|
@ -232,7 +263,7 @@ describe("Persistence service", function() {
|
||||||
expect(persistence.upgradeVersion).toHaveBeenCalledWith('1.0.0', '1.0.1');
|
expect(persistence.upgradeVersion).toHaveBeenCalledWith('1.0.0', '1.0.1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that no user settings had been saved in local storage, it returns undefined", function() {
|
it("Given that no user settings had been saved in local storage, it returns undefined", function () {
|
||||||
var settings = persistence.getSettings();
|
var settings = persistence.getSettings();
|
||||||
|
|
||||||
expect(locker.get).toHaveBeenCalledWith('Settings');
|
expect(locker.get).toHaveBeenCalledWith('Settings');
|
||||||
|
@ -240,25 +271,25 @@ describe("Persistence service", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("saveSettings() - given a user settings object, it will be saved in local storage", function() {
|
it("saveSettings() - Given a user settings object, when I save the settings, then it will be set in local storage", function () {
|
||||||
persistence.saveSettings({
|
persistence.saveSettings({
|
||||||
"url": "http://crotalic.com/cabernet/coelenteron?a=dayshine&b=pantaletless#sus",
|
url: "http://crotalic.com/cabernet/coelenteron?a=dayshine&b=pantaletless#sus",
|
||||||
"Username": "Herrig"
|
Username: "Herrig"
|
||||||
});
|
});
|
||||||
expect(locker.put).toHaveBeenCalledWith('Settings', {
|
expect(locker.put).toHaveBeenCalledWith('Settings', {
|
||||||
"url": "http://crotalic.com/cabernet/coelenteron?a=dayshine&b=pantaletless#sus",
|
url: "http://crotalic.com/cabernet/coelenteron?a=dayshine&b=pantaletless#sus",
|
||||||
"Username": "Herrig"
|
Username: "Herrig"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("deleteSettings() - deletes the saved user settings from local storage", function() {
|
it("deleteSettings() - When I delete the settings, then they will be erased from local storage", function () {
|
||||||
persistence.deleteSettings();
|
persistence.deleteSettings();
|
||||||
expect(locker.forget).toHaveBeenCalledWith('Settings');
|
expect(locker.forget).toHaveBeenCalledWith('Settings');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getVersion() -", function() {
|
describe("getVersion() -", function () {
|
||||||
it("Given a previously saved Jamstash version in local storage, it retrieves it", function() {
|
it("Given a previously saved Jamstash version in local storage, when I get the version, then a string version number will be returned", function () {
|
||||||
fakeStorage = { 'JamstashVersion': '1.2.5' };
|
fakeStorage = { JamstashVersion: '1.2.5' };
|
||||||
|
|
||||||
var version = persistence.getVersion();
|
var version = persistence.getVersion();
|
||||||
|
|
||||||
|
@ -266,7 +297,7 @@ describe("Persistence service", function() {
|
||||||
expect(version).toBe('1.2.5');
|
expect(version).toBe('1.2.5');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that no Jamstash version was previously saved in local storage, it returns undefined", function() {
|
it("Given that no Jamstash version was previously saved in local storage, when I get the version, then undefined will be returned", function () {
|
||||||
var version = persistence.getVersion();
|
var version = persistence.getVersion();
|
||||||
|
|
||||||
expect(locker.get).toHaveBeenCalledWith('JamstashVersion');
|
expect(locker.get).toHaveBeenCalledWith('JamstashVersion');
|
||||||
|
@ -274,8 +305,8 @@ describe("Persistence service", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("upgradeVersion() -", function() {
|
describe("upgradeVersion() -", function () {
|
||||||
it("Given that Jamstash version '1.0.0' was previously stored in local storage, when I upgrade the storage version to '1.0.1', Jamstash version '1.0.1' will be in local storage and the user will be notified", function() {
|
it("Given that Jamstash version '1.0.0' was previously stored in local storage, when I upgrade the storage version to '1.0.1', Jamstash version '1.0.1' will be in local storage and the user will be notified", function () {
|
||||||
fakeStorage.JamstashVersion = '1.0.0';
|
fakeStorage.JamstashVersion = '1.0.0';
|
||||||
|
|
||||||
persistence.upgradeVersion('1.0.0', '1.0.1');
|
persistence.upgradeVersion('1.0.0', '1.0.1');
|
||||||
|
@ -284,8 +315,8 @@ describe("Persistence service", function() {
|
||||||
expect(notifications.updateMessage).toHaveBeenCalledWith('Version 1.0.0 to 1.0.1', true);
|
expect(notifications.updateMessage).toHaveBeenCalledWith('Version 1.0.0 to 1.0.1', true);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Given that changesets for versions '1.0.1' and '1.0.2' were defined,", function() {
|
describe("Given that changesets for versions '1.0.1' and '1.0.2' were defined,", function () {
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
fakeVersionChangesets.versions = [
|
fakeVersionChangesets.versions = [
|
||||||
{
|
{
|
||||||
version: '1.0.1',
|
version: '1.0.1',
|
||||||
|
@ -316,7 +347,7 @@ describe("Persistence service", function() {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
it("when I upgrade the storage version from '1.0.0' to '1.0.2', both changesets have been applied", function() {
|
it("when I upgrade the storage version from '1.0.0' to '1.0.2', then both changesets will be applied", function () {
|
||||||
persistence.upgradeVersion('1.0.0', '1.0.2');
|
persistence.upgradeVersion('1.0.0', '1.0.2');
|
||||||
expect(locker.put).toHaveBeenCalledWith('Settings', {
|
expect(locker.put).toHaveBeenCalledWith('Settings', {
|
||||||
DefaultSearchType: 0,
|
DefaultSearchType: 0,
|
||||||
|
@ -326,7 +357,7 @@ describe("Persistence service", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("when I upgrade the storage version from '1.0.0' to '1.0.1', only the '1.0.1' changeset has been applied", function() {
|
it("when I upgrade the storage version from '1.0.0' to '1.0.1', only the '1.0.1' changeset will be applied", function () {
|
||||||
persistence.upgradeVersion('1.0.0', '1.0.1');
|
persistence.upgradeVersion('1.0.0', '1.0.1');
|
||||||
expect(locker.put).toHaveBeenCalledWith('Settings', {
|
expect(locker.put).toHaveBeenCalledWith('Settings', {
|
||||||
DefaultSearchType: 0,
|
DefaultSearchType: 0,
|
||||||
|
@ -339,7 +370,7 @@ describe("Persistence service", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("when I upgrade the storage version from '1.0.1' to '1.0.2', only the '1.0.2' changeset has been applied", function() {
|
it("when I upgrade the storage version from '1.0.1' to '1.0.2', only the '1.0.2' changeset will be applied", function () {
|
||||||
persistence.upgradeVersion('1.0.1', '1.0.2');
|
persistence.upgradeVersion('1.0.1', '1.0.2');
|
||||||
expect(locker.put).toHaveBeenCalledWith('Settings', {
|
expect(locker.put).toHaveBeenCalledWith('Settings', {
|
||||||
DefaultSearchType: {
|
DefaultSearchType: {
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
<link href="" rel="stylesheet" type="text/css" data-name="theme" />
|
<link href="" rel="stylesheet" type="text/css" data-name="theme" />
|
||||||
<!-- build:css(app) styles/concat.min.css -->
|
<!-- build:css(app) styles/concat.min.css -->
|
||||||
<link rel="stylesheet" href="player/player.css" />
|
<link rel="stylesheet" href="player/player.css" />
|
||||||
|
<link rel="stylesheet" href="subsonic/subsonic.css" />
|
||||||
<link rel="stylesheet" href="player/repeat-directive/repeat-directive.css" />
|
<link rel="stylesheet" href="player/repeat-directive/repeat-directive.css" />
|
||||||
<link rel="stylesheet" href="subsonic/breadcrumbs-directive/breadcrumbs-directive.css" />
|
<link rel="stylesheet" href="subsonic/breadcrumbs-directive/breadcrumbs-directive.css" />
|
||||||
<!-- endbuild -->
|
<!-- endbuild -->
|
||||||
|
|
|
@ -62,7 +62,6 @@ angular.module('jamstash.settings.service', [])
|
||||||
ShowQueue: false
|
ShowQueue: false
|
||||||
};
|
};
|
||||||
this.SavedCollections = [];
|
this.SavedCollections = [];
|
||||||
this.SavedGenres = [];
|
|
||||||
this.Player1 = '#playdeck_1';
|
this.Player1 = '#playdeck_1';
|
||||||
this.archiveUrl = 'https://archive.org/';
|
this.archiveUrl = 'https://archive.org/';
|
||||||
this.ChangeLog = null;
|
this.ChangeLog = null;
|
||||||
|
|
23
app/subsonic/subsonic.css
Normal file
23
app/subsonic/subsonic.css
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
.icon {
|
||||||
|
height: 12px;
|
||||||
|
width: 12px;
|
||||||
|
margin: 3px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-item-remove {
|
||||||
|
height: 18px;
|
||||||
|
width: 20px;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-item-remove:hover {
|
||||||
|
background-color: #DEECFB;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-item-remove:hover .icon-remove {
|
||||||
|
fill: #4D4D4F;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-remove {
|
||||||
|
fill: #adadad;
|
||||||
|
}
|
|
@ -148,15 +148,51 @@
|
||||||
<div class="title">Random</div>
|
<div class="title">Random</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="index" id="auto">Genre Playlists</li>
|
<li class="index" id="auto">Genre Playlists</li>
|
||||||
<select id="Genres" name="Genres" class="large" ng-model="selectedGenre" ng-options="o for o in Genres">
|
<select
|
||||||
|
id="Genres"
|
||||||
|
name="Genres"
|
||||||
|
class="large"
|
||||||
|
ng-model="selectedGenre"
|
||||||
|
ng-options="o for o in Genres"
|
||||||
|
>
|
||||||
<option value="">[Select Genre]</option>
|
<option value="">[Select Genre]</option>
|
||||||
</select>
|
</select>
|
||||||
<li class="item" ng-repeat="o in playlistsGenre" ng-click="getRandomSongs('display', o)" ng-class="{'selected': selectedAutoPlaylist == o}">
|
<li
|
||||||
|
class="item"
|
||||||
|
ng-repeat="genrePlaylist in genrePlaylists track by $index"
|
||||||
|
ng-click="getRandomSongs('display', genrePlaylist)"
|
||||||
|
ng-class="{'selected': selectedAutoPlaylist === genrePlaylist}"
|
||||||
|
>
|
||||||
<div class="itemactions">
|
<div class="itemactions">
|
||||||
<a class="add" href="" title="Add To Play Queue" ng-click="getRandomSongs('add', o)" stop-event="click"></a>
|
<a
|
||||||
<a class="play" href="" title="Play" ng-click="getRandomSongs('play', o)" stop-event="click"></a>
|
class="add"
|
||||||
|
href=""
|
||||||
|
title="Add To Play Queue"
|
||||||
|
ng-click="getRandomSongs('add', genrePlaylist)"
|
||||||
|
stop-event="click"
|
||||||
|
></a>
|
||||||
|
<a
|
||||||
|
class="play"
|
||||||
|
href=""
|
||||||
|
title="Play"
|
||||||
|
ng-click="getRandomSongs('play', genrePlaylist)"
|
||||||
|
stop-event="click"
|
||||||
|
></a>
|
||||||
|
</div>
|
||||||
|
<span class="title">
|
||||||
|
{{ genrePlaylist }}
|
||||||
|
</span>
|
||||||
|
<div
|
||||||
|
title="Remove this auto-playlist"
|
||||||
|
class="list-item-remove"
|
||||||
|
ng-click="deleteGenrePlaylist(genrePlaylist)"
|
||||||
|
stop-event="click"
|
||||||
|
>
|
||||||
|
<svg class="icon">
|
||||||
|
<title>Remove this auto-playlist</title>
|
||||||
|
<use xlink:href="images/sprite/iconic.svg#x" class="icon-remove"></use>
|
||||||
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="title">{{o}}</div>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="simplelist mainlist noselect">
|
<ul class="simplelist mainlist noselect">
|
||||||
|
|
|
@ -210,18 +210,6 @@ angular.module('jamstash.subsonic.controller', [
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.searching = {
|
|
||||||
query: '',
|
|
||||||
typeId: globals.settings.DefaultSearchType,
|
|
||||||
types: globals.SearchTypes
|
|
||||||
};
|
|
||||||
$scope.playlistsGenre = globals.SavedGenres;
|
|
||||||
$scope.$watch('selectedGenre', function (newValue, oldValue) {
|
|
||||||
if (newValue !== oldValue) {
|
|
||||||
globals.SavedGenres.push(newValue);
|
|
||||||
utils.setValue('SavedGenres', globals.SavedGenres.join(), false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$scope.rescanLibrary = function (data, event) {
|
$scope.rescanLibrary = function (data, event) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: globals.BaseURL() + '/getUser.view?' + globals.BaseParams() + '&username=' + globals.settings.Username,
|
url: globals.BaseURL() + '/getUser.view?' + globals.BaseParams() + '&username=' + globals.settings.Username,
|
||||||
|
@ -663,6 +651,28 @@ angular.module('jamstash.subsonic.controller', [
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.$watch('selectedGenre', function (newValue, oldValue) {
|
||||||
|
if (newValue && newValue !== oldValue) {
|
||||||
|
$scope.genrePlaylists = _($scope.genrePlaylists)
|
||||||
|
.push(newValue)
|
||||||
|
.uniq()
|
||||||
|
.value();
|
||||||
|
persistence.saveSelectedGenreNames($scope.genrePlaylists);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.loadGenrePlaylists = function () {
|
||||||
|
$scope.genrePlaylists = persistence.loadSelectedGenreNames();
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.deleteGenrePlaylist = function (genrePlaylist) {
|
||||||
|
_.remove($scope.genrePlaylists, function (playlist) {
|
||||||
|
return playlist === genrePlaylist;
|
||||||
|
});
|
||||||
|
persistence.deleteSelectedGenreNames();
|
||||||
|
persistence.saveSelectedGenreNames($scope.genrePlaylists);
|
||||||
|
};
|
||||||
|
|
||||||
$scope.getPodcasts = function () {
|
$scope.getPodcasts = function () {
|
||||||
var promise = subsonic.getPodcasts();
|
var promise = subsonic.getPodcasts();
|
||||||
$scope.handleErrors(promise).then(function (podcasts) {
|
$scope.handleErrors(promise).then(function (podcasts) {
|
||||||
|
@ -722,10 +732,18 @@ angular.module('jamstash.subsonic.controller', [
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Launch on Startup */
|
/* Launch on Startup */
|
||||||
|
$scope.searching = {
|
||||||
|
query: '',
|
||||||
|
typeId: globals.settings.DefaultSearchType,
|
||||||
|
types: globals.SearchTypes
|
||||||
|
};
|
||||||
|
$scope.genrePlaylists = [];
|
||||||
|
$scope.MusicFolders = [];
|
||||||
$scope.getMusicFolders();
|
$scope.getMusicFolders();
|
||||||
$scope.getArtists();
|
$scope.getArtists();
|
||||||
$scope.getPlaylists();
|
$scope.getPlaylists();
|
||||||
$scope.getGenres();
|
$scope.getGenres();
|
||||||
|
$scope.loadGenrePlaylists();
|
||||||
$scope.getPodcasts();
|
$scope.getPodcasts();
|
||||||
$scope.openDefaultSection();
|
$scope.openDefaultSection();
|
||||||
if ($routeParams.artistId && $routeParams.albumId) {
|
if ($routeParams.artistId && $routeParams.albumId) {
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
describe("Subsonic controller", function() {
|
// jscs:disable validateQuoteMarks
|
||||||
|
describe("Subsonic controller", function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var scope, $rootScope, $controller, $window,
|
var scope, $rootScope, $controller, $window,
|
||||||
_, subsonic, notifications, player, utils, persistence, breadcrumbs, mockGlobals, controllerParams, deferred;
|
_, subsonic, notifications, player, utils, persistence, breadcrumbs, mockGlobals, controllerParams, deferred;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
jasmine.addCustomEqualityTester(angular.equals);
|
jasmine.addCustomEqualityTester(angular.equals);
|
||||||
|
|
||||||
module('jamstash.subsonic.controller');
|
module('jamstash.subsonic.controller');
|
||||||
|
@ -24,7 +25,10 @@ describe("Subsonic controller", function() {
|
||||||
persistence = jasmine.createSpyObj("persistence", [
|
persistence = jasmine.createSpyObj("persistence", [
|
||||||
"getSelectedMusicFolder",
|
"getSelectedMusicFolder",
|
||||||
"saveSelectedMusicFolder",
|
"saveSelectedMusicFolder",
|
||||||
"deleteSelectedMusicFolder"
|
"deleteSelectedMusicFolder",
|
||||||
|
"loadSelectedGenreNames",
|
||||||
|
"saveSelectedGenreNames",
|
||||||
|
"deleteSelectedGenreNames"
|
||||||
]);
|
]);
|
||||||
breadcrumbs = jasmine.createSpyObj("breadcrumbs", [
|
breadcrumbs = jasmine.createSpyObj("breadcrumbs", [
|
||||||
"reset",
|
"reset",
|
||||||
|
@ -95,21 +99,21 @@ describe("Subsonic controller", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("", function() {
|
describe("", function () {
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
$controller('SubsonicController', controllerParams);
|
$controller('SubsonicController', controllerParams);
|
||||||
scope.selectedPlaylist = null;
|
scope.selectedPlaylist = null;
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getSongs -", function() {
|
describe("getSongs -", function () {
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
subsonic.getSongs.and.returnValue(deferred.promise);
|
subsonic.getSongs.and.returnValue(deferred.promise);
|
||||||
subsonic.recursiveGetSongs.and.returnValue(deferred.promise);
|
subsonic.recursiveGetSongs.and.returnValue(deferred.promise);
|
||||||
spyOn(scope, "requestSongs").and.returnValue(deferred.promise);
|
spyOn(scope, "requestSongs").and.returnValue(deferred.promise);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given a music directory that contained 3 songs and given its id and name, when I display it, then subsonic-service will be called, the breadcrumbs will be updated and the songs will be published to the scope", function() {
|
it("Given a music directory that contained 3 songs and given its id and name, when I display it, then subsonic-service will be called, the breadcrumbs will be updated and the songs will be published to the scope", function () {
|
||||||
scope.getSongs('display', 87, 'Covetous Dadayag', "root");
|
scope.getSongs('display', 87, 'Covetous Dadayag', "root");
|
||||||
deferred.resolve({
|
deferred.resolve({
|
||||||
directories: [],
|
directories: [],
|
||||||
|
@ -141,7 +145,7 @@ describe("Subsonic controller", function() {
|
||||||
expect(scope.selectedPodcast).toBeNull();
|
expect(scope.selectedPodcast).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that there was a previous level in the breadcrumbs, when I display a music directory, then the album breadcrumb will be added", function() {
|
it("Given that there was a previous level in the breadcrumbs, when I display a music directory, then the album breadcrumb will be added", function () {
|
||||||
scope.BreadCrumbs = [
|
scope.BreadCrumbs = [
|
||||||
{
|
{
|
||||||
type: 'artist',
|
type: 'artist',
|
||||||
|
@ -163,10 +167,10 @@ describe("Subsonic controller", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given a music directory that contained 2 songs and 1 subdirectory and given its id and name, when I display it, then subsonic-service will be called, the songs and directory will be published to the scope", function() {
|
it("Given a music directory that contained 2 songs and 1 subdirectory and given its id and name, when I display it, then subsonic-service will be called, the songs and directory will be published to the scope", function () {
|
||||||
scope.getSongs('display', 6, 'Potsander dormilona');
|
scope.getSongs('display', 6, 'Potsander dormilona');
|
||||||
deferred.resolve({
|
deferred.resolve({
|
||||||
directories: [{id: 387, type: 'byfolder'}],
|
directories: [{ id: 387, type: 'byfolder' }],
|
||||||
songs: [
|
songs: [
|
||||||
{ id: 102 },
|
{ id: 102 },
|
||||||
{ id: 340 }
|
{ id: 340 }
|
||||||
|
@ -175,7 +179,7 @@ describe("Subsonic controller", function() {
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
|
||||||
expect(scope.album).toEqual([
|
expect(scope.album).toEqual([
|
||||||
{id: 387, type: 'byfolder'}
|
{ id: 387, type: 'byfolder' }
|
||||||
]);
|
]);
|
||||||
expect(scope.song).toEqual([
|
expect(scope.song).toEqual([
|
||||||
{ id: 102 },
|
{ id: 102 },
|
||||||
|
@ -183,21 +187,21 @@ describe("Subsonic controller", function() {
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given a music directory, when I display it, then handleErrors will handle HTTP and Subsonic errors", function() {
|
it("Given a music directory, when I display it, then handleErrors will handle HTTP and Subsonic errors", function () {
|
||||||
spyOn(scope, 'handleErrors').and.returnValue(deferred.promise);
|
spyOn(scope, 'handleErrors').and.returnValue(deferred.promise);
|
||||||
scope.getSongs('display', 88);
|
scope.getSongs('display', 88);
|
||||||
expect(scope.handleErrors).toHaveBeenCalledWith(deferred.promise);
|
expect(scope.handleErrors).toHaveBeenCalledWith(deferred.promise);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given a music directory that didn't contain anything, when I display it, then an error notification will be displayed", function() {
|
it("Given a music directory that didn't contain anything, when I display it, then an error notification will be displayed", function () {
|
||||||
scope.getSongs('display', 214, 'Upside bunemost');
|
scope.getSongs('display', 214, 'Upside bunemost');
|
||||||
deferred.reject({reason: 'This directory is empty.'});
|
deferred.reject({ reason: 'This directory is empty.' });
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
|
||||||
expect(notifications.updateMessage).toHaveBeenCalledWith('This directory is empty.', true);
|
expect(notifications.updateMessage).toHaveBeenCalledWith('This directory is empty.', true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given a music directory that contained 3 songs and given its id, when I add it to the playing queue, then requestSongs() will be called", function() {
|
it("Given a music directory that contained 3 songs and given its id, when I add it to the playing queue, then requestSongs() will be called", function () {
|
||||||
scope.getSongs('add', 720);
|
scope.getSongs('add', 720);
|
||||||
deferred.resolve([
|
deferred.resolve([
|
||||||
{ id: 927 },
|
{ id: 927 },
|
||||||
|
@ -210,7 +214,7 @@ describe("Subsonic controller", function() {
|
||||||
expect(scope.requestSongs).toHaveBeenCalledWith(deferred.promise, 'add');
|
expect(scope.requestSongs).toHaveBeenCalledWith(deferred.promise, 'add');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given a music directory that contained 3 songs and given its id, when I play it, then requestSongs() will be called", function() {
|
it("Given a music directory that contained 3 songs and given its id, when I play it, then requestSongs() will be called", function () {
|
||||||
scope.getSongs('play', 542);
|
scope.getSongs('play', 542);
|
||||||
deferred.resolve([
|
deferred.resolve([
|
||||||
{ id: 905 },
|
{ id: 905 },
|
||||||
|
@ -224,20 +228,22 @@ describe("Subsonic controller", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Given that my library contained 3 songs, ", function() {
|
describe("Given that my library contained 3 songs, ", function () {
|
||||||
var response;
|
var response;
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
response = [
|
response = [
|
||||||
{id:"2548"}, {id:"8986"}, {id:"2986"}
|
{ id: 2548 },
|
||||||
|
{ id: 8986 },
|
||||||
|
{ id: 2986 }
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("", function() {
|
describe("", function () {
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
spyOn(scope, "requestSongs").and.returnValue(deferred.promise);
|
spyOn(scope, "requestSongs").and.returnValue(deferred.promise);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("when I request random starred songs, then subsonic-service will be called, displaying, adding or playing songs will be delegated to requestSongs and the current playlist will be published to the scope", function() {
|
it("when I request random starred songs, then subsonic-service will be called, displaying, adding or playing songs will be delegated to requestSongs and the current playlist will be published to the scope", function () {
|
||||||
subsonic.getRandomStarredSongs.and.returnValue(deferred.promise);
|
subsonic.getRandomStarredSongs.and.returnValue(deferred.promise);
|
||||||
|
|
||||||
scope.getRandomStarredSongs('whatever action');
|
scope.getRandomStarredSongs('whatever action');
|
||||||
|
@ -256,12 +262,12 @@ describe("Subsonic controller", function() {
|
||||||
expect(scope.selectedPodcast).toBeNull();
|
expect(scope.selectedPodcast).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("when I request random songs", function() {
|
describe("when I request random songs", function () {
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
subsonic.getRandomSongs.and.returnValue(deferred.promise);
|
subsonic.getRandomSongs.and.returnValue(deferred.promise);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("from all folders or genres, then subsonic-service will be called, displaying, adding or playing songs will be delegated to requestSongs and the current playlist will be published to the scope", function() {
|
it("from all folders or genres, then subsonic-service will be called, displaying, adding or playing songs will be delegated to requestSongs and the current playlist will be published to the scope", function () {
|
||||||
scope.getRandomSongs('whatever action');
|
scope.getRandomSongs('whatever action');
|
||||||
deferred.resolve(response);
|
deferred.resolve(response);
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
@ -278,7 +284,7 @@ describe("Subsonic controller", function() {
|
||||||
expect(scope.selectedPodcast).toBeNull();
|
expect(scope.selectedPodcast).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("from a given genre, then subsonic-service will be called, displaying, adding or playing songs will be delegated to requestSongs and the current playlist will be published to the scope", function() {
|
it("from a given genre, then subsonic-service will be called, displaying, adding or playing songs will be delegated to requestSongs and the current playlist will be published to the scope", function () {
|
||||||
scope.getRandomSongs('whatever action', 'Rock');
|
scope.getRandomSongs('whatever action', 'Rock');
|
||||||
deferred.resolve(response);
|
deferred.resolve(response);
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
@ -295,7 +301,7 @@ describe("Subsonic controller", function() {
|
||||||
expect(scope.selectedPodcast).toBeNull();
|
expect(scope.selectedPodcast).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("from a given folder id, then subsonic-service will be called, displaying, adding or playing songs will be delegated to requestSongs and the current playlist will be published to the scope", function() {
|
it("from a given folder id, then subsonic-service will be called, displaying, adding or playing songs will be delegated to requestSongs and the current playlist will be published to the scope", function () {
|
||||||
scope.getRandomSongs('whatever action', '', 1);
|
scope.getRandomSongs('whatever action', '', 1);
|
||||||
deferred.resolve(response);
|
deferred.resolve(response);
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
@ -313,12 +319,12 @@ describe("Subsonic controller", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("given a playlist that contained those 3 songs,", function() {
|
describe("given a playlist that contained those 3 songs,", function () {
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
subsonic.getPlaylist.and.returnValue(deferred.promise);
|
subsonic.getPlaylist.and.returnValue(deferred.promise);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("when I request it, then subsonic-service will be called, displaying, adding or playing songs will be delegated to requestSongs and the current playlist will be published to the scope", function() {
|
it("when I request it, then subsonic-service will be called, displaying, adding or playing songs will be delegated to requestSongs and the current playlist will be published to the scope", function () {
|
||||||
scope.getPlaylist('whatever action', 1146);
|
scope.getPlaylist('whatever action', 1146);
|
||||||
deferred.resolve(response);
|
deferred.resolve(response);
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
@ -336,7 +342,7 @@ describe("Subsonic controller", function() {
|
||||||
expect(scope.selectedPodcast).toBeNull();
|
expect(scope.selectedPodcast).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("when I display it, the number of songs in the playlist will be notified", function() {
|
it("when I display it, the number of songs in the playlist will be notified", function () {
|
||||||
scope.getPlaylist('display', 1146);
|
scope.getPlaylist('display', 1146);
|
||||||
deferred.resolve(response);
|
deferred.resolve(response);
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
@ -345,7 +351,7 @@ describe("Subsonic controller", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("given a podcast that contained those 3 songs as episodes, when I request it, then subsonic-service will be called, displaying adding or playing songs will be delegated to requestSongs and the current selected podcast will be published to the scope", function() {
|
it("given a podcast that contained those 3 songs as episodes, when I request it, then subsonic-service will be called, displaying adding or playing songs will be delegated to requestSongs and the current selected podcast will be published to the scope", function () {
|
||||||
subsonic.getPodcast.and.returnValue(deferred.promise);
|
subsonic.getPodcast.and.returnValue(deferred.promise);
|
||||||
|
|
||||||
scope.getPodcast('whatever action', 45);
|
scope.getPodcast('whatever action', 45);
|
||||||
|
@ -366,42 +372,48 @@ describe("Subsonic controller", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("requestSongs -", function() {
|
describe("requestSongs -", function () {
|
||||||
it("when I display songs, it sets the scope with the selected songs", function() {
|
it("when I display songs, it sets the scope with the selected songs", function () {
|
||||||
scope.requestSongs(deferred.promise, 'display');
|
scope.requestSongs(deferred.promise, 'display');
|
||||||
deferred.resolve(response);
|
deferred.resolve(response);
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
|
||||||
expect(scope.song).toEqual([
|
expect(scope.song).toEqual([
|
||||||
{id: "2548"}, {id: "8986"}, {id: "2986"}
|
{ id: 2548 },
|
||||||
|
{ id: 8986 },
|
||||||
|
{ id: 2986 }
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("when I add songs, it adds the selected songs to the playing queue and notifies the user", function() {
|
it("when I add songs, it adds the selected songs to the playing queue and notifies the user", function () {
|
||||||
scope.requestSongs(deferred.promise, 'add');
|
scope.requestSongs(deferred.promise, 'add');
|
||||||
deferred.resolve(response);
|
deferred.resolve(response);
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
|
||||||
expect(player.addSongs).toHaveBeenCalledWith([
|
expect(player.addSongs).toHaveBeenCalledWith([
|
||||||
{id: "2548"}, {id: "8986"}, {id: "2986"}
|
{ id: 2548 },
|
||||||
|
{ id: 8986 },
|
||||||
|
{ id: 2986 }
|
||||||
]);
|
]);
|
||||||
expect(notifications.updateMessage).toHaveBeenCalledWith('3 Song(s) Added to Queue', true);
|
expect(notifications.updateMessage).toHaveBeenCalledWith('3 Song(s) Added to Queue', true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("when I play songs, it plays the first selected song, empties the queue and fills it with the selected songs and it notifies the user", function() {
|
it("when I play songs, it plays the first selected song, empties the queue and fills it with the selected songs and it notifies the user", function () {
|
||||||
scope.requestSongs(deferred.promise, 'play');
|
scope.requestSongs(deferred.promise, 'play');
|
||||||
deferred.resolve(response);
|
deferred.resolve(response);
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
|
||||||
expect(player.emptyQueue).toHaveBeenCalled();
|
expect(player.emptyQueue).toHaveBeenCalled();
|
||||||
expect(player.addSongs).toHaveBeenCalledWith([
|
expect(player.addSongs).toHaveBeenCalledWith([
|
||||||
{id: "2548"}, {id: "8986"}, {id: "2986"}
|
{ id: 2548 },
|
||||||
|
{ id: 8986 },
|
||||||
|
{ id: 2986 }
|
||||||
]);
|
]);
|
||||||
expect(player.playFirstSong).toHaveBeenCalled();
|
expect(player.playFirstSong).toHaveBeenCalled();
|
||||||
expect(notifications.updateMessage).toHaveBeenCalledWith('3 Song(s) Added to Queue', true);
|
expect(notifications.updateMessage).toHaveBeenCalledWith('3 Song(s) Added to Queue', true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("when I request songs, it returns a promise so that I can chain it further", function() {
|
it("when I request songs, it returns a promise so that I can chain it further", function () {
|
||||||
var success = jasmine.createSpy("success");
|
var success = jasmine.createSpy("success");
|
||||||
|
|
||||||
scope.requestSongs(deferred.promise, 'whatever action').then(success);
|
scope.requestSongs(deferred.promise, 'whatever action').then(success);
|
||||||
|
@ -411,11 +423,11 @@ describe("Subsonic controller", function() {
|
||||||
expect(success).toHaveBeenCalled();
|
expect(success).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("when I request songs, it lets handleErrors handle HTTP and Subsonic errors", function() {
|
it("when I request songs, it lets handleErrors handle HTTP and Subsonic errors", function () {
|
||||||
spyOn(scope, 'handleErrors').and.returnValue(deferred.promise);
|
spyOn(scope, 'handleErrors').and.returnValue(deferred.promise);
|
||||||
|
|
||||||
scope.requestSongs(deferred.promise, 'whatever action');
|
scope.requestSongs(deferred.promise, 'whatever action');
|
||||||
deferred.reject({reason: 'Error when contacting the Subsonic server.',
|
deferred.reject({ reason: 'Error when contacting the Subsonic server.' ,
|
||||||
httpError: 404
|
httpError: 404
|
||||||
});
|
});
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
@ -423,22 +435,22 @@ describe("Subsonic controller", function() {
|
||||||
expect(scope.handleErrors).toHaveBeenCalledWith(deferred.promise);
|
expect(scope.handleErrors).toHaveBeenCalledWith(deferred.promise);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("given that I don't have any song in my library, when I request songs, it notifies the user with an error message, does not play a song and does not change the queue", function() {
|
it("given that I don't have any song in my library, when I request songs, it notifies the user with an error message, does not play a song and does not change the queue", function () {
|
||||||
player.queue = [{id: "7666"}];
|
player.queue = [{ id: "7666" }];
|
||||||
|
|
||||||
scope.requestSongs(deferred.promise, 'whatever action');
|
scope.requestSongs(deferred.promise, 'whatever action');
|
||||||
deferred.reject({reason: 'No songs found on the Subsonic server.'});
|
deferred.reject({ reason: 'No songs found on the Subsonic server.' });
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
|
||||||
expect(player.playFirstSong).not.toHaveBeenCalled();
|
expect(player.playFirstSong).not.toHaveBeenCalled();
|
||||||
expect(player.queue).toEqual([{id: "7666"}]);
|
expect(player.queue).toEqual([{ id: "7666" }]);
|
||||||
expect(notifications.updateMessage).toHaveBeenCalledWith('No songs found on the Subsonic server.', true);
|
expect(notifications.updateMessage).toHaveBeenCalledWith('No songs found on the Subsonic server.', true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("handleErrors -", function() {
|
describe("handleErrors -", function () {
|
||||||
it("when I make a request, it returns a promise so that I can chain it further", function() {
|
it("when I make a request, it returns a promise so that I can chain it further", function () {
|
||||||
var success = jasmine.createSpy("success");
|
var success = jasmine.createSpy("success");
|
||||||
|
|
||||||
scope.handleErrors(deferred.promise).then(success);
|
scope.handleErrors(deferred.promise).then(success);
|
||||||
|
@ -448,19 +460,19 @@ describe("Subsonic controller", function() {
|
||||||
expect(success).toHaveBeenCalled();
|
expect(success).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("given that the Subsonic server returns an error, when I make a request, it notifies the user with the error message", function() {
|
it("given that the Subsonic server returns an error, when I make a request, it notifies the user with the error message", function () {
|
||||||
scope.handleErrors(deferred.promise);
|
scope.handleErrors(deferred.promise);
|
||||||
deferred.reject({reason: 'Error when contacting the Subsonic server.',
|
deferred.reject({ reason: 'Error when contacting the Subsonic server.' ,
|
||||||
subsonicError: {code: 10, message:'Required parameter is missing.'}
|
subsonicError: { code: 10, message: 'Required parameter is missing.' }
|
||||||
});
|
});
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
|
||||||
expect(notifications.updateMessage).toHaveBeenCalledWith('Error when contacting the Subsonic server. Required parameter is missing.', true);
|
expect(notifications.updateMessage).toHaveBeenCalledWith('Error when contacting the Subsonic server. Required parameter is missing.', true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("given that the Subsonic server is unreachable, when I make a request, it notifies the user with the HTTP error code", function() {
|
it("given that the Subsonic server is unreachable, when I make a request, it notifies the user with the HTTP error code", function () {
|
||||||
scope.handleErrors(deferred.promise);
|
scope.handleErrors(deferred.promise);
|
||||||
deferred.reject({reason: 'Error when contacting the Subsonic server.',
|
deferred.reject({ reason: 'Error when contacting the Subsonic server.' ,
|
||||||
httpError: 404
|
httpError: 404
|
||||||
});
|
});
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
@ -469,20 +481,20 @@ describe("Subsonic controller", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("reorders playlists by drag and drop - ", function() {
|
describe("reorders playlists by drag and drop - ", function () {
|
||||||
var mockUI;
|
var mockUI;
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
scope.song = [
|
scope.song = [
|
||||||
{id: 1084},
|
{ id: 1084 },
|
||||||
{id: 6810},
|
{ id: 6810 },
|
||||||
{id: 214}
|
{ id: 214 }
|
||||||
];
|
];
|
||||||
mockUI = {
|
mockUI = {
|
||||||
item: {}
|
item: {}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
it("given a song in a list of songs, when I start dragging it, it records what its starting position in the list was", function() {
|
it("given a song in a list of songs, when I start dragging it, it records what its starting position in the list was", function () {
|
||||||
mockUI.item.index = jasmine.createSpy('index').and.returnValue('1');
|
mockUI.item.index = jasmine.createSpy('index').and.returnValue('1');
|
||||||
mockUI.item.data = jasmine.createSpy('data');
|
mockUI.item.data = jasmine.createSpy('data');
|
||||||
|
|
||||||
|
@ -492,7 +504,7 @@ describe("Subsonic controller", function() {
|
||||||
expect(mockUI.item.data).toHaveBeenCalledWith('start', '1');
|
expect(mockUI.item.data).toHaveBeenCalledWith('start', '1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("given a song in a list of songs that I started dragging, when I drop it, its position in the list of songs has changed", function() {
|
it("given a song in a list of songs that I started dragging, when I drop it, its position in the list of songs has changed", function () {
|
||||||
mockUI.item.index = jasmine.createSpy('index').and.returnValue('0');
|
mockUI.item.index = jasmine.createSpy('index').and.returnValue('0');
|
||||||
mockUI.item.data = jasmine.createSpy('data').and.returnValue('1');
|
mockUI.item.data = jasmine.createSpy('data').and.returnValue('1');
|
||||||
|
|
||||||
|
@ -502,31 +514,31 @@ describe("Subsonic controller", function() {
|
||||||
expect(mockUI.item.data).toHaveBeenCalledWith('start');
|
expect(mockUI.item.data).toHaveBeenCalledWith('start');
|
||||||
// The second song should now be first
|
// The second song should now be first
|
||||||
expect(scope.song).toEqual([
|
expect(scope.song).toEqual([
|
||||||
{id: 6810},
|
{ id: 6810 },
|
||||||
{id: 1084},
|
{ id: 1084 },
|
||||||
{id: 214}
|
{ id: 214 }
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given a song, when I call playSong, then the player service's queue will be emptied, the song will be added to the queue and played", function() {
|
it("Given a song, when I call playSong, then the player service's queue will be emptied, the song will be added to the queue and played", function () {
|
||||||
var fakeSong = {"id": 3572};
|
var fakeSong = { id: 3572 };
|
||||||
|
|
||||||
scope.playSong(fakeSong);
|
scope.playSong(fakeSong);
|
||||||
|
|
||||||
expect(player.emptyQueue).toHaveBeenCalled();
|
expect(player.emptyQueue).toHaveBeenCalled();
|
||||||
expect(player.addSong).toHaveBeenCalledWith({"id": 3572});
|
expect(player.addSong).toHaveBeenCalledWith({ id: 3572 });
|
||||||
expect(player.playFirstSong).toHaveBeenCalled();
|
expect(player.playFirstSong).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
//TODO: Hyz: all starred
|
// TODO: Hyz: all starred
|
||||||
|
|
||||||
describe("", function() {
|
describe("", function () {
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
spyOn(scope, "getArtists");
|
spyOn(scope, "getArtists");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given no previously selected music folder, when I select a music folder, then it will be stored in persistence and the artists will be loaded from subsonic", function() {
|
it("Given no previously selected music folder, when I select a music folder, then it will be stored in persistence and the artists will be loaded from subsonic", function () {
|
||||||
scope.SelectedMusicFolder = { id: 22, name: "Cascadia" };
|
scope.SelectedMusicFolder = { id: 22, name: "Cascadia" };
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
|
||||||
|
@ -534,7 +546,7 @@ describe("Subsonic controller", function() {
|
||||||
expect(scope.getArtists).toHaveBeenCalledWith(22);
|
expect(scope.getArtists).toHaveBeenCalledWith(22);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given a previously selected music folder, when I select the 'All Folders' (undefined) music folder, then the stored value will be deleted from persistence and all the artists will be loaded from subsonic", function() {
|
it("Given a previously selected music folder, when I select the 'All Folders' (undefined) music folder, then the stored value will be deleted from persistence and all the artists will be loaded from subsonic", function () {
|
||||||
scope.SelectedMusicFolder = { id: 23, name: "grantable" };
|
scope.SelectedMusicFolder = { id: 23, name: "grantable" };
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
scope.SelectedMusicFolder = undefined;
|
scope.SelectedMusicFolder = undefined;
|
||||||
|
@ -545,33 +557,33 @@ describe("Subsonic controller", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getArtists() -", function() {
|
describe("getArtists() -", function () {
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
subsonic.getArtists.and.returnValue(deferred.promise);
|
subsonic.getArtists.and.returnValue(deferred.promise);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that there were artists in the library, when I load the artists, then subsonic will be queried and an index array containing the artists and a shortcut array containing the shortcuts (such as Podcasts) will be publisehd to the scope", function() {
|
it("Given that there were artists in the library, when I load the artists, then subsonic will be queried and an index array containing the artists and a shortcut array containing the shortcuts (such as Podcasts) will be publisehd to the scope", function () {
|
||||||
scope.getArtists();
|
scope.getArtists();
|
||||||
deferred.resolve({
|
deferred.resolve({
|
||||||
index: [
|
index: [
|
||||||
{id: 520}
|
{ id: 520 }
|
||||||
],
|
],
|
||||||
shortcut: [
|
shortcut: [
|
||||||
{id: 342}
|
{ id: 342 }
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
|
||||||
expect(subsonic.getArtists).toHaveBeenCalled();
|
expect(subsonic.getArtists).toHaveBeenCalled();
|
||||||
expect(scope.index).toEqual([
|
expect(scope.index).toEqual([
|
||||||
{id: 520}
|
{ id: 520 }
|
||||||
]);
|
]);
|
||||||
expect(scope.shortcut).toEqual([
|
expect(scope.shortcut).toEqual([
|
||||||
{id: 342}
|
{ id: 342 }
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given no folder id and given a selected music folder had been set in the scope, when I get the artists, then the selected music folder's id will be used as parameter to subsonic service", function() {
|
it("Given no folder id and given a selected music folder had been set in the scope, when I get the artists, then the selected music folder's id will be used as parameter to subsonic service", function () {
|
||||||
scope.SelectedMusicFolder = { id: 62, name: "dollardee" };
|
scope.SelectedMusicFolder = { id: 62, name: "dollardee" };
|
||||||
|
|
||||||
scope.getArtists();
|
scope.getArtists();
|
||||||
|
@ -579,9 +591,9 @@ describe("Subsonic controller", function() {
|
||||||
expect(subsonic.getArtists).toHaveBeenCalledWith(62);
|
expect(subsonic.getArtists).toHaveBeenCalledWith(62);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that there weren't any artist in the library, when I load the artists, then a notification with an error message will be displayed", function() {
|
it("Given that there weren't any artist in the library, when I load the artists, then a notification with an error message will be displayed", function () {
|
||||||
scope.getArtists();
|
scope.getArtists();
|
||||||
deferred.reject({reason: 'No artist found on the Subsonic server.'});
|
deferred.reject({ reason: 'No artist found on the Subsonic server.' });
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
|
||||||
expect(scope.index).toEqual([]);
|
expect(scope.index).toEqual([]);
|
||||||
|
@ -589,19 +601,19 @@ describe("Subsonic controller", function() {
|
||||||
expect(notifications.updateMessage).toHaveBeenCalledWith('No artist found on the Subsonic server.', true);
|
expect(notifications.updateMessage).toHaveBeenCalledWith('No artist found on the Subsonic server.', true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that the server was unreachable, when I get the music folders, then handleErrors() will deal with the error", function() {
|
it("Given that the server was unreachable, when I get the music folders, then handleErrors() will deal with the error", function () {
|
||||||
spyOn(scope, 'handleErrors').and.returnValue(deferred.promise);
|
spyOn(scope, 'handleErrors').and.returnValue(deferred.promise);
|
||||||
scope.getArtists();
|
scope.getArtists();
|
||||||
expect(scope.handleErrors).toHaveBeenCalledWith(deferred.promise);
|
expect(scope.handleErrors).toHaveBeenCalledWith(deferred.promise);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getAlbumListBy() - Given that the global setting AutoAlbum Size was 3,", function() {
|
describe("getAlbumListBy() - Given that the global setting AutoAlbum Size was 3,", function () {
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
subsonic.getAlbumListBy.and.returnValue(deferred.promise);
|
subsonic.getAlbumListBy.and.returnValue(deferred.promise);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("and given that there were albums in the library, when I get the newest albums, then subsonic will be queried and the albums will be published on the scope", function() {
|
it("and given that there were albums in the library, when I get the newest albums, then subsonic will be queried and the albums will be published on the scope", function () {
|
||||||
scope.getAlbumListBy("newest");
|
scope.getAlbumListBy("newest");
|
||||||
deferred.resolve([
|
deferred.resolve([
|
||||||
{ id: 85, isDir: true },
|
{ id: 85, isDir: true },
|
||||||
|
@ -626,47 +638,47 @@ describe("Subsonic controller", function() {
|
||||||
expect(scope.selectedPodcast).toBeNull();
|
expect(scope.selectedPodcast).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("and given that we had already queried the first 3 most played albums,", function() {
|
describe("and given that we had already queried the first 3 most played albums,", function () {
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
scope.autoAlbums['frequent'].offset = 3;
|
scope.autoAlbums.frequent.offset = 3;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("when I get the next most played albums, then subsonic will be queried with an offset of 6", function() {
|
it("when I get the next most played albums, then subsonic will be queried with an offset of 6", function () {
|
||||||
scope.getAlbumListBy("frequent", "next");
|
scope.getAlbumListBy("frequent", "next");
|
||||||
|
|
||||||
expect(subsonic.getAlbumListBy).toHaveBeenCalledWith("frequent", 6);
|
expect(subsonic.getAlbumListBy).toHaveBeenCalledWith("frequent", 6);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("when I get the previous most played albums, then subsonic will be queried with an offset of 0", function() {
|
it("when I get the previous most played albums, then subsonic will be queried with an offset of 0", function () {
|
||||||
scope.getAlbumListBy("frequent", "prev");
|
scope.getAlbumListBy("frequent", "prev");
|
||||||
|
|
||||||
expect(subsonic.getAlbumListBy).toHaveBeenCalledWith("frequent", 0);
|
expect(subsonic.getAlbumListBy).toHaveBeenCalledWith("frequent", 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("when I get the first 3 top rated albums, then the 'most played' offset will be ignored and subsonic will be queried with an offset of 0", function() {
|
it("when I get the first 3 top rated albums, then the 'most played' offset will be ignored and subsonic will be queried with an offset of 0", function () {
|
||||||
scope.getAlbumListBy("highest");
|
scope.getAlbumListBy("highest");
|
||||||
|
|
||||||
expect(subsonic.getAlbumListBy).toHaveBeenCalledWith("highest", 0);
|
expect(subsonic.getAlbumListBy).toHaveBeenCalledWith("highest", 0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that there weren't any albums in the library, when I get the newest albums, then a notification with an error message will be displayed", function() {
|
it("Given that there weren't any albums in the library, when I get the newest albums, then a notification with an error message will be displayed", function () {
|
||||||
scope.getAlbumListBy("frequent");
|
scope.getAlbumListBy("frequent");
|
||||||
deferred.reject({reason: 'No matching albums found on the Subsonic server.'});
|
deferred.reject({ reason: 'No matching albums found on the Subsonic server.' });
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
|
||||||
expect(scope.album).toEqual([]);
|
expect(scope.album).toEqual([]);
|
||||||
expect(notifications.updateMessage).toHaveBeenCalledWith('No matching albums found on the Subsonic server.', true);
|
expect(notifications.updateMessage).toHaveBeenCalledWith('No matching albums found on the Subsonic server.', true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that the server was unreachable, when I get the newest albums, then handleErrors() will deal with the error", function() {
|
it("Given that the server was unreachable, when I get the newest albums, then handleErrors() will deal with the error", function () {
|
||||||
spyOn(scope, 'handleErrors').and.returnValue(deferred.promise);
|
spyOn(scope, 'handleErrors').and.returnValue(deferred.promise);
|
||||||
scope.getAlbumListBy("newest");
|
scope.getAlbumListBy("newest");
|
||||||
expect(scope.handleErrors).toHaveBeenCalledWith(deferred.promise);
|
expect(scope.handleErrors).toHaveBeenCalledWith(deferred.promise);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("refreshArtists() - When I refresh the artists, then the selected music folder will be reset to undefined and the artists and playlists will be loaded", function() {
|
it("refreshArtists() - When I refresh the artists, then the selected music folder will be reset to undefined and the artists and playlists will be loaded", function () {
|
||||||
spyOn(scope, "getArtists");
|
spyOn(scope, "getArtists");
|
||||||
spyOn(scope, "getPlaylists");
|
spyOn(scope, "getPlaylists");
|
||||||
|
|
||||||
|
@ -677,35 +689,35 @@ describe("Subsonic controller", function() {
|
||||||
expect(scope.getPlaylists).toHaveBeenCalled();
|
expect(scope.getPlaylists).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("When I load the playlists,", function() {
|
describe("When I load the playlists,", function () {
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
subsonic.getPlaylists.and.returnValue(deferred.promise);
|
subsonic.getPlaylists.and.returnValue(deferred.promise);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that there are playlists in the library, it loads the playlists and publishes them to the scope", function() {
|
it("Given that there are playlists in the library, it loads the playlists and publishes them to the scope", function () {
|
||||||
scope.getPlaylists();
|
scope.getPlaylists();
|
||||||
deferred.resolve({
|
deferred.resolve({
|
||||||
playlists: [
|
playlists: [
|
||||||
{id: 588}
|
{ id: 588 }
|
||||||
],
|
],
|
||||||
playlistsPublic: [
|
playlistsPublic: [
|
||||||
{id: 761}
|
{ id: 761 }
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
|
||||||
expect(subsonic.getPlaylists).toHaveBeenCalled();
|
expect(subsonic.getPlaylists).toHaveBeenCalled();
|
||||||
expect(scope.playlists).toEqual([
|
expect(scope.playlists).toEqual([
|
||||||
{id: 588}
|
{ id: 588 }
|
||||||
]);
|
]);
|
||||||
expect(scope.playlistsPublic).toEqual([
|
expect(scope.playlistsPublic).toEqual([
|
||||||
{id: 761}
|
{ id: 761 }
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that there aren't any playlists in the library, it publishes an empty array to the scope and does not notify the user with the error message", function() {
|
it("Given that there aren't any playlists in the library, it publishes an empty array to the scope and does not notify the user with the error message", function () {
|
||||||
scope.getPlaylists();
|
scope.getPlaylists();
|
||||||
deferred.reject({reason: 'No playlist found on the Subsonic server.'});
|
deferred.reject({ reason: 'No playlist found on the Subsonic server.' });
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
|
||||||
expect(subsonic.getPlaylists).toHaveBeenCalled();
|
expect(subsonic.getPlaylists).toHaveBeenCalled();
|
||||||
|
@ -715,7 +727,7 @@ describe("Subsonic controller", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("When I create a playlist, then it will ask for a name, use subsonic-service and reload the playlists", function() {
|
it("When I create a playlist, then it will ask for a name, use subsonic-service and reload the playlists", function () {
|
||||||
$window.prompt.and.returnValue('declassicize');
|
$window.prompt.and.returnValue('declassicize');
|
||||||
subsonic.newPlaylist.and.returnValue(deferred.promise);
|
subsonic.newPlaylist.and.returnValue(deferred.promise);
|
||||||
spyOn(scope, 'getPlaylists');
|
spyOn(scope, 'getPlaylists');
|
||||||
|
@ -729,7 +741,7 @@ describe("Subsonic controller", function() {
|
||||||
expect(scope.getPlaylists).toHaveBeenCalled();
|
expect(scope.getPlaylists).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("When I create a playlist and provide no name, then the playlist won't be created", function() {
|
it("When I create a playlist and provide no name, then the playlist won't be created", function () {
|
||||||
$window.prompt.and.returnValue(null);
|
$window.prompt.and.returnValue(null);
|
||||||
|
|
||||||
scope.newPlaylist();
|
scope.newPlaylist();
|
||||||
|
@ -737,7 +749,7 @@ describe("Subsonic controller", function() {
|
||||||
expect(subsonic.newPlaylist).not.toHaveBeenCalled();
|
expect(subsonic.newPlaylist).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given a selected playlist, when I delete that playlist, it will ask for confirmation, use subsonic-service and reload the playlists", function() {
|
it("Given a selected playlist, when I delete that playlist, it will ask for confirmation, use subsonic-service and reload the playlists", function () {
|
||||||
$window.confirm.and.returnValue(true);
|
$window.confirm.and.returnValue(true);
|
||||||
subsonic.deletePlaylist.and.returnValue(deferred.promise);
|
subsonic.deletePlaylist.and.returnValue(deferred.promise);
|
||||||
spyOn(scope, 'getPlaylists');
|
spyOn(scope, 'getPlaylists');
|
||||||
|
@ -752,7 +764,7 @@ describe("Subsonic controller", function() {
|
||||||
expect(scope.getPlaylists).toHaveBeenCalled();
|
expect(scope.getPlaylists).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given no selected playlist, when I try to delete a playlist, an error notification will be displayed", function() {
|
it("Given no selected playlist, when I try to delete a playlist, an error notification will be displayed", function () {
|
||||||
scope.selectedPlaylist = null;
|
scope.selectedPlaylist = null;
|
||||||
|
|
||||||
scope.deletePlaylist();
|
scope.deletePlaylist();
|
||||||
|
@ -761,7 +773,7 @@ describe("Subsonic controller", function() {
|
||||||
expect(subsonic.deletePlaylist).not.toHaveBeenCalled();
|
expect(subsonic.deletePlaylist).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given a selected playlist, when I save that playlist, the displayed songs will be sent to subsonic-service, the playlist will be displayed again and a notification message will be displayed", function() {
|
it("Given a selected playlist, when I save that playlist, the displayed songs will be sent to subsonic-service, the playlist will be displayed again and a notification message will be displayed", function () {
|
||||||
subsonic.savePlaylist.and.returnValue(deferred.promise);
|
subsonic.savePlaylist.and.returnValue(deferred.promise);
|
||||||
spyOn(scope, 'getPlaylist');
|
spyOn(scope, 'getPlaylist');
|
||||||
scope.selectedPlaylist = 8469;
|
scope.selectedPlaylist = 8469;
|
||||||
|
@ -784,7 +796,7 @@ describe("Subsonic controller", function() {
|
||||||
expect(notifications.updateMessage).toHaveBeenCalledWith('Playlist Updated!', true);
|
expect(notifications.updateMessage).toHaveBeenCalledWith('Playlist Updated!', true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given no selected playlist, when I try to save a playlist, an error notification will be displayed", function() {
|
it("Given no selected playlist, when I try to save a playlist, an error notification will be displayed", function () {
|
||||||
scope.selectedPlaylist = null;
|
scope.selectedPlaylist = null;
|
||||||
|
|
||||||
scope.savePlaylist();
|
scope.savePlaylist();
|
||||||
|
@ -793,31 +805,31 @@ describe("Subsonic controller", function() {
|
||||||
expect(subsonic.savePlaylist).not.toHaveBeenCalled();
|
expect(subsonic.savePlaylist).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getPodcasts() -", function() {
|
describe("getPodcasts() -", function () {
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
subsonic.getPodcasts.and.returnValue(deferred.promise);
|
subsonic.getPodcasts.and.returnValue(deferred.promise);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that there were podcasts in the library, When I load the podcasts, then the podcasts will be published to the scope", function() {
|
it("Given that there were podcasts in the library, When I load the podcasts, then the podcasts will be published to the scope", function () {
|
||||||
scope.getPodcasts();
|
scope.getPodcasts();
|
||||||
deferred.resolve([
|
deferred.resolve([
|
||||||
{id: 9775},
|
{ id: 9775 },
|
||||||
{id: 5880},
|
{ id: 5880 },
|
||||||
{id: 5554}
|
{ id: 5554 }
|
||||||
]);
|
]);
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
|
||||||
expect(subsonic.getPodcasts).toHaveBeenCalled();
|
expect(subsonic.getPodcasts).toHaveBeenCalled();
|
||||||
expect(scope.podcasts).toEqual([
|
expect(scope.podcasts).toEqual([
|
||||||
{id: 9775},
|
{ id: 9775 },
|
||||||
{id: 5880},
|
{ id: 5880 },
|
||||||
{id: 5554}
|
{ id: 5554 }
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that there wasn't any podcast in the library, When I load the podcasts, then an empty array will be published to the scope and the user won't be notified", function() {
|
it("Given that there wasn't any podcast in the library, When I load the podcasts, then an empty array will be published to the scope and the user won't be notified", function () {
|
||||||
scope.getPodcasts();
|
scope.getPodcasts();
|
||||||
deferred.reject({reason: 'No podcast found on the Subsonic server.'});
|
deferred.reject({ reason: 'No podcast found on the Subsonic server.' });
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
|
||||||
expect(subsonic.getPodcasts).toHaveBeenCalled();
|
expect(subsonic.getPodcasts).toHaveBeenCalled();
|
||||||
|
@ -826,12 +838,12 @@ describe("Subsonic controller", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getGenres() -", function() {
|
describe("getGenres() -", function () {
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
subsonic.getGenres.and.returnValue(deferred.promise);
|
subsonic.getGenres.and.returnValue(deferred.promise);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that there were music genres in the library, when I get the genres, then the genre names will be published to the scope", function() {
|
it("Given that there were music genres in the library, when I get the genres, then the genre names will be published to the scope", function () {
|
||||||
scope.getGenres();
|
scope.getGenres();
|
||||||
deferred.resolve([
|
deferred.resolve([
|
||||||
"matriarchalism",
|
"matriarchalism",
|
||||||
|
@ -848,9 +860,9 @@ describe("Subsonic controller", function() {
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that there wasn't any music genre in the library, when I get the genres, then an empty array will be published to the scope and the user won't be notified", function() {
|
it("Given that there wasn't any music genre in the library, when I get the genres, then an empty array will be published to the scope and the user won't be notified", function () {
|
||||||
scope.getGenres();
|
scope.getGenres();
|
||||||
deferred.reject({reason: 'No genre found on the Subsonic server.'});
|
deferred.reject({ reason: 'No genre found on the Subsonic server.' });
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
|
||||||
expect(subsonic.getGenres).toHaveBeenCalled();
|
expect(subsonic.getGenres).toHaveBeenCalled();
|
||||||
|
@ -859,28 +871,68 @@ describe("Subsonic controller", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getMusicFolders() -", function() {
|
it("Given a genre name, when I delete a genre playlist, then the list of genre playlists will be deleted from persistence and saved again without the given genre, and it will be removed from the list of genre playlists in the scope", function () {
|
||||||
beforeEach(function() {
|
scope.genrePlaylists = ['Olivella gravitometer', 'Antonina', 'recondemnation interact'];
|
||||||
|
|
||||||
|
scope.deleteGenrePlaylist('Antonina');
|
||||||
|
|
||||||
|
expect(scope.genrePlaylists).toEqual(['Olivella gravitometer', 'recondemnation interact']);
|
||||||
|
expect(persistence.deleteSelectedGenreNames).toHaveBeenCalled();
|
||||||
|
expect(persistence.saveSelectedGenreNames).toHaveBeenCalledWith(['Olivella gravitometer', 'recondemnation interact']);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Given that the selected genre name changed,", function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
scope.genrePlaylists = ['misanthropy skeipp', 'flourish'];
|
||||||
|
});
|
||||||
|
|
||||||
|
it("then the new value will be added at the end of the genre playlists array and the array will be saved to persistence", function () {
|
||||||
|
scope.selectedGenre = 'standstill gallivant';
|
||||||
|
scope.$apply();
|
||||||
|
|
||||||
|
expect(scope.genrePlaylists).toEqual(['misanthropy skeipp', 'flourish', 'standstill gallivant']);
|
||||||
|
expect(persistence.saveSelectedGenreNames).toHaveBeenCalledWith(['misanthropy skeipp', 'flourish', 'standstill gallivant']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("and the new value is already in the genre playlists array, then the new value won't be duplicated in the array", function () {
|
||||||
|
scope.selectedGenre = 'flourish';
|
||||||
|
scope.$apply();
|
||||||
|
|
||||||
|
expect(scope.genrePlaylists).toEqual(['misanthropy skeipp', 'flourish']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("When I load the selected genre playlists, the genre playlists will be loaded from persistence and published on the scope ", function () {
|
||||||
|
persistence.loadSelectedGenreNames.and.returnValue(['clabber diffidentness', 'perturbancy', 'unnavigable']);
|
||||||
|
|
||||||
|
scope.loadGenrePlaylists();
|
||||||
|
|
||||||
|
expect(scope.genrePlaylists).toEqual(['clabber diffidentness', 'perturbancy', 'unnavigable']);
|
||||||
|
expect(persistence.loadSelectedGenreNames).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("getMusicFolders() -", function () {
|
||||||
|
beforeEach(function () {
|
||||||
subsonic.getMusicFolders.and.returnValue(deferred.promise);
|
subsonic.getMusicFolders.and.returnValue(deferred.promise);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that there were music folders in the library, when I get the music folders, then the folders will be published to the scope", function() {
|
it("Given that there were music folders in the library, when I get the music folders, then the folders will be published to the scope", function () {
|
||||||
scope.getMusicFolders();
|
scope.getMusicFolders();
|
||||||
deferred.resolve([
|
deferred.resolve([
|
||||||
{ id: 74, name: "scirrhosis"},
|
{ id: 74, name: "scirrhosis" },
|
||||||
{ id: 81, name: "drooper"}
|
{ id: 81, name: "drooper" }
|
||||||
]);
|
]);
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
|
||||||
expect(subsonic.getMusicFolders).toHaveBeenCalled();
|
expect(subsonic.getMusicFolders).toHaveBeenCalled();
|
||||||
expect(scope.MusicFolders).toEqual([
|
expect(scope.MusicFolders).toEqual([
|
||||||
{ id: 74, name: "scirrhosis"},
|
{ id: 74, name: "scirrhosis" },
|
||||||
{ id: 81, name: "drooper"}
|
{ id: 81, name: "drooper" }
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Given that there was a selected music folder previously saved in persistence", function() {
|
describe("Given that there was a selected music folder previously saved in persistence", function () {
|
||||||
it("and that it matched one of the music folders returned by subsonic, when I get the music folders, then the scope's selected music folder will be set", function() {
|
it("and that it matched one of the music folders returned by subsonic, when I get the music folders, then the scope's selected music folder will be set", function () {
|
||||||
persistence.getSelectedMusicFolder.and.returnValue({ id: 79, name: "dismember" });
|
persistence.getSelectedMusicFolder.and.returnValue({ id: 79, name: "dismember" });
|
||||||
|
|
||||||
scope.getMusicFolders();
|
scope.getMusicFolders();
|
||||||
|
@ -893,7 +945,7 @@ describe("Subsonic controller", function() {
|
||||||
expect(scope.SelectedMusicFolder).toEqual({ id: 79, name: "dismember" });
|
expect(scope.SelectedMusicFolder).toEqual({ id: 79, name: "dismember" });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("and that it didn't match one of the music folders returned by subsonic, when I get the music folders, then the scope's selected music folder will be undefined", function() {
|
it("and that it didn't match one of the music folders returned by subsonic, when I get the music folders, then the scope's selected music folder will be undefined", function () {
|
||||||
persistence.getSelectedMusicFolder.and.returnValue({ id: 49, name: "metafulminuric" });
|
persistence.getSelectedMusicFolder.and.returnValue({ id: 49, name: "metafulminuric" });
|
||||||
|
|
||||||
scope.getMusicFolders();
|
scope.getMusicFolders();
|
||||||
|
@ -906,111 +958,94 @@ describe("Subsonic controller", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that there weren't any music folder in the library, when I get the music folders, then handleErrors() will deal with the error", function() {
|
it("Given that there weren't any music folder in the library, when I get the music folders, then handleErrors() will deal with the error", function () {
|
||||||
spyOn(scope, 'handleErrors').and.returnValue(deferred.promise);
|
spyOn(scope, 'handleErrors').and.returnValue(deferred.promise);
|
||||||
|
|
||||||
scope.getMusicFolders();
|
scope.getMusicFolders();
|
||||||
deferred.reject({reason: 'No music folder found on the Subsonic server.'});
|
deferred.reject({ reason: 'No music folder found on the Subsonic server.' });
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
|
||||||
expect(scope.handleErrors).toHaveBeenCalledWith(deferred.promise);
|
expect(scope.handleErrors).toHaveBeenCalledWith(deferred.promise);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("search() -", function() {
|
describe("search() -", function () {
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
subsonic.search.and.returnValue(deferred.promise);
|
subsonic.search.and.returnValue(deferred.promise);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that songs containing 'fireboard' existed in my library, when I search for a song that contains 'fireboard', then the scope's songs will be filled with an array containing those songs and the other scope arrays will be emptied", function() {
|
it("Given that songs containing 'fireboard' existed in my library, when I search for a song that contains 'fireboard', then the scope's songs will be filled with an array containing those songs and the other scope arrays will be emptied", function () {
|
||||||
scope.search('fireboard', 0);
|
scope.search('fireboard', 0);
|
||||||
deferred.resolve([
|
deferred.resolve([
|
||||||
{id: 318, name: "antichronically fireboard"},
|
{ id: 318, name: "antichronically fireboard" },
|
||||||
{id: 890, name: "fireboard Rhoda"},
|
{ id: 890, name: "fireboard Rhoda" },
|
||||||
{id: 643, name: "fireboarding stalactical"}
|
{ id: 643, name: "fireboarding stalactical" }
|
||||||
]);
|
]);
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
|
||||||
expect(subsonic.search).toHaveBeenCalledWith('fireboard', 0);
|
expect(subsonic.search).toHaveBeenCalledWith('fireboard', 0);
|
||||||
expect(scope.song).toEqual([
|
expect(scope.song).toEqual([
|
||||||
{id: 318, name: "antichronically fireboard"},
|
{ id: 318, name: "antichronically fireboard" },
|
||||||
{id: 890, name: "fireboard Rhoda"},
|
{ id: 890, name: "fireboard Rhoda" },
|
||||||
{id: 643, name: "fireboarding stalactical"}
|
{ id: 643, name: "fireboarding stalactical" }
|
||||||
]);
|
]);
|
||||||
expect(scope.album).toEqual([]);
|
expect(scope.album).toEqual([]);
|
||||||
expect(breadcrumbs.reset).toHaveBeenCalled();
|
expect(breadcrumbs.reset).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that albums containing 'neolalia' existed in my library, when I search for an album that contains 'neolalia', then the scope's albums will be filled with an array containing those albums and the other scope arrays will be emptied", function() {
|
it("Given that albums containing 'neolalia' existed in my library, when I search for an album that contains 'neolalia', then the scope's albums will be filled with an array containing those albums and the other scope arrays will be emptied", function () {
|
||||||
scope.search('neolalia', 1);
|
scope.search('neolalia', 1);
|
||||||
deferred.resolve([
|
deferred.resolve([
|
||||||
{id: 74, name: "Magdalen neolalia"},
|
{ id: 74, name: "Magdalen neolalia" },
|
||||||
{id: 2, name: "neolalia tribrac"},
|
{ id: 2, name: "neolalia tribrac" },
|
||||||
{id: 19, name: "neolaliaviator"},
|
{ id: 19, name: "neolaliaviator" }
|
||||||
]);
|
]);
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
|
||||||
expect(subsonic.search).toHaveBeenCalledWith('neolalia', 1);
|
expect(subsonic.search).toHaveBeenCalledWith('neolalia', 1);
|
||||||
expect(scope.album).toEqual([
|
expect(scope.album).toEqual([
|
||||||
{id: 74, name: "Magdalen neolalia"},
|
{ id: 74, name: "Magdalen neolalia" },
|
||||||
{id: 2, name: "neolalia tribrac"},
|
{ id: 2, name: "neolalia tribrac" },
|
||||||
{id: 19, name: "neolaliaviator"},
|
{ id: 19, name: "neolaliaviator" }
|
||||||
]);
|
]);
|
||||||
expect(scope.song).toEqual([]);
|
expect(scope.song).toEqual([]);
|
||||||
expect(breadcrumbs.reset).toHaveBeenCalled();
|
expect(breadcrumbs.reset).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given that artists containing 'brazenly' existed in my library, when I search for an artist that contains 'brazenly', then the scope's shortcuts will be filled with an array containing those artists and the other scope arrays will be emptied", function() {
|
it("Given that artists containing 'brazenly' existed in my library, when I search for an artist that contains 'brazenly', then the scope's shortcuts will be filled with an array containing those artists and the other scope arrays will be emptied", function () {
|
||||||
scope.search('brazenly', 2);
|
scope.search('brazenly', 2);
|
||||||
deferred.resolve([
|
deferred.resolve([
|
||||||
{id: 645, name: "brazenly unsheriff"},
|
{ id: 645, name: "brazenly unsheriff" },
|
||||||
{id: 831, name: "planorotund brazenly"},
|
{ id: 831, name: "planorotund brazenly" },
|
||||||
{id: 181, name: "brazenlyon"},
|
{ id: 181, name: "brazenlyon" }
|
||||||
]);
|
]);
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
|
||||||
expect(subsonic.search).toHaveBeenCalledWith('brazenly', 2);
|
expect(subsonic.search).toHaveBeenCalledWith('brazenly', 2);
|
||||||
expect(scope.shortcut).toEqual([
|
expect(scope.shortcut).toEqual([
|
||||||
{id: 645, name: "brazenly unsheriff"},
|
{ id: 645, name: "brazenly unsheriff" },
|
||||||
{id: 831, name: "planorotund brazenly"},
|
{ id: 831, name: "planorotund brazenly" },
|
||||||
{id: 181, name: "brazenlyon"},
|
{ id: 181, name: "brazenlyon" }
|
||||||
]);
|
]);
|
||||||
expect(scope.song).toEqual([]);
|
expect(scope.song).toEqual([]);
|
||||||
expect(scope.album).toEqual([]);
|
expect(scope.album).toEqual([]);
|
||||||
expect(breadcrumbs.reset).toHaveBeenCalled();
|
expect(breadcrumbs.reset).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given any type of search and given that the library didn't contain anything containing 'shindig', when I search for 'shindig', then an error notification will be displayed", function() {
|
it("Given any type of search and given that the library didn't contain anything containing 'shindig', when I search for 'shindig', then an error notification will be displayed", function () {
|
||||||
scope.search('shindig', jasmine.any(Number()));
|
scope.search('shindig', jasmine.any(Number()));
|
||||||
deferred.reject({reason: "No results."});
|
deferred.reject({ reason: "No results." });
|
||||||
scope.$apply();
|
scope.$apply();
|
||||||
|
|
||||||
expect(subsonic.search).toHaveBeenCalledWith('shindig', jasmine.any(Number()));
|
expect(subsonic.search).toHaveBeenCalledWith('shindig', jasmine.any(Number()));
|
||||||
expect(notifications.updateMessage).toHaveBeenCalledWith('No results.', true);
|
expect(notifications.updateMessage).toHaveBeenCalledWith('No results.', true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Given any type of search, When I search for an empty string, then subsonic service won't be called", function() {
|
it("Given any type of search, When I search for an empty string, then subsonic service won't be called", function () {
|
||||||
scope.search('', 34);
|
scope.search('', 34);
|
||||||
|
|
||||||
expect(subsonic.search).not.toHaveBeenCalled();
|
expect(subsonic.search).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("On startup,", function() {
|
|
||||||
//TODO: Hyz: Search types and default types published at startup
|
|
||||||
|
|
||||||
xit("it loads the indexes, the playlists", function() {
|
|
||||||
controllerParams.$scope.getArtists = jasmine.createSpy('getArtists');
|
|
||||||
controllerParams.$scope.getPlaylists = jasmine.createSpy('getPlaylists');
|
|
||||||
// spyOn(scope, 'getArtists');
|
|
||||||
// spyOn(scope, 'getPlaylists');
|
|
||||||
|
|
||||||
$controller('SubsonicController', controllerParams);
|
|
||||||
expect(scope.getArtists).toHaveBeenCalled();
|
|
||||||
expect(scope.getPlaylists).toHaveBeenCalled();
|
|
||||||
|
|
||||||
//TODO: Hyz: Complete with everything called on startup
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue