Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
14
gaia/tv_apps/smart-home/test/marionette/.jshintrc
Executable file
14
gaia/tv_apps/smart-home/test/marionette/.jshintrc
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"extends": "../../../../.jshintrc",
|
||||
"node": true,
|
||||
"predef": [
|
||||
"suite",
|
||||
"test",
|
||||
"setup",
|
||||
"teardown",
|
||||
"suiteSetup",
|
||||
"suiteTeardown",
|
||||
"marionette",
|
||||
"marionetteScriptFinished"
|
||||
]
|
||||
}
|
||||
124
gaia/tv_apps/smart-home/test/marionette/smart_home_test.js
Executable file
124
gaia/tv_apps/smart-home/test/marionette/smart_home_test.js
Executable file
|
|
@ -0,0 +1,124 @@
|
|||
'use strict';
|
||||
|
||||
var APP_URL = 'app://smart-home.gaiamobile.org';
|
||||
|
||||
var Keys = {
|
||||
'up': '\ue013',
|
||||
'right': '\ue014',
|
||||
'down': '\ue015',
|
||||
'left': '\ue012',
|
||||
'enter': '\ue006',
|
||||
'esc': '\ue00c'
|
||||
};
|
||||
|
||||
var assert = require('chai').assert;
|
||||
|
||||
var containsClass = function(elem, className) {
|
||||
if (elem) {
|
||||
return elem.getAttribute('class').indexOf(className) > -1;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// Bug 1207453 - Skip the test due to unknown test enviroment issue for now.
|
||||
// We should investigate the issue and re-enable the test later.
|
||||
marionette.skip('Smart Home', function() {
|
||||
|
||||
var opts = {
|
||||
hostOptions: {
|
||||
screen: {
|
||||
width: 1920,
|
||||
height: 1080
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var client = marionette.client({
|
||||
profile: opts,
|
||||
// XXX: Set this to true once Accessibility is implemented in TV
|
||||
desiredCapabilities: { raisesAccessibilityExceptions: false }
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
// Launch test app
|
||||
client.apps.launch(APP_URL);
|
||||
client.apps.switchToApp(APP_URL);
|
||||
});
|
||||
|
||||
suite('> Card Filter', function() {
|
||||
test('Hide card filter when enter edit mode and show card filter when' +
|
||||
' exit edit mode ', { devices: ['tv'] }, function () {
|
||||
|
||||
var editButton = client.findElement('#edit-button');
|
||||
var element = client.findElement('#main-section');
|
||||
var searchButton = client.findElement('#search-button');
|
||||
var deckTvCard = client.findElement('#card-list > .card');
|
||||
var deckTvButton = client.findElement('.app-button.deck-tv');
|
||||
|
||||
client.waitFor(function() {
|
||||
return containsClass(deckTvCard, 'focused');
|
||||
});
|
||||
client.waitFor(function() {
|
||||
return containsClass(deckTvButton, 'focused');
|
||||
});
|
||||
|
||||
element.sendKeys(Keys.up);
|
||||
client.waitFor(function() {
|
||||
return containsClass(searchButton, 'focused');
|
||||
});
|
||||
|
||||
element.sendKeys(Keys.right);
|
||||
client.waitFor(function() {
|
||||
return containsClass(editButton, 'focused');
|
||||
});
|
||||
|
||||
element.sendKeys(Keys.enter);
|
||||
client.waitFor(function() {
|
||||
return element.getAttribute('data-mode') === 'edit';
|
||||
});
|
||||
var cardFilter = client.findElement('#filter-tab-group');
|
||||
assert.isTrue(containsClass(cardFilter, 'hidden'));
|
||||
|
||||
element.sendKeys(Keys.up);
|
||||
element.sendKeys(Keys.enter);
|
||||
assert.isFalse(containsClass(cardFilter, 'hidden'));
|
||||
});
|
||||
|
||||
test('Collapse folder when filter is focused',
|
||||
{ devices: ['tv'] }, function() {
|
||||
|
||||
// add new folder
|
||||
client.executeScript(function() {
|
||||
var home = window.wrappedJSObject.home;
|
||||
var newFolder = home.cardManager.insertNewFolder({id: 'new-folder'},
|
||||
home.cardManager._cardList.length);
|
||||
var card = home.cardManager._deserializeCardEntry({group: 'application',
|
||||
manifestURL: 'app://tv-epg.gaiamobile.org/manifest.webapp',
|
||||
type: 'Application'
|
||||
});
|
||||
newFolder.addCard(card);
|
||||
});
|
||||
|
||||
var element = client.findElement('#main-section');
|
||||
var newFolderCard =
|
||||
client.findElement('#card-list div.card:last-child');
|
||||
client.waitFor(function() {
|
||||
return containsClass(newFolderCard, 'focused');
|
||||
});
|
||||
|
||||
// move focus to card filter
|
||||
element.sendKeys(Keys.down);
|
||||
element.sendKeys(Keys.down);
|
||||
|
||||
// wait until animation of card filter ends
|
||||
var cardFilter = client.findElement('#filter-tab-group');
|
||||
client.waitFor(function() {
|
||||
return !containsClass(cardFilter, 'closed');
|
||||
});
|
||||
|
||||
// wait for folder to be collapsed
|
||||
client.helper.waitForElementToDisappear('#folder-list .card');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
18
gaia/tv_apps/smart-home/test/unit/.jshintrc
Executable file
18
gaia/tv_apps/smart-home/test/unit/.jshintrc
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"extends": "../../../../.jshintrc",
|
||||
"predef": [
|
||||
"assert",
|
||||
"suite",
|
||||
"test",
|
||||
"setup",
|
||||
"teardown",
|
||||
"suiteSetup",
|
||||
"suiteTeardown",
|
||||
"require",
|
||||
"requireApp",
|
||||
"sinon",
|
||||
"mocha",
|
||||
"loadBodyHTML"
|
||||
]
|
||||
}
|
||||
|
||||
186
gaia/tv_apps/smart-home/test/unit/card_filter_test.js
Executable file
186
gaia/tv_apps/smart-home/test/unit/card_filter_test.js
Executable file
|
|
@ -0,0 +1,186 @@
|
|||
/* global MockSmartButton, MockMenuGroup, CardFilter */
|
||||
'use strict';
|
||||
require('/shared/test/unit/mocks/mock_event_target.js');
|
||||
require('/bower_components/evt/index.js');
|
||||
requireApp('smart-home/test/unit/mock_smart_button.js');
|
||||
requireApp('smart-home/test/unit/mock_menu_group.js');
|
||||
requireApp('smart-home/js/card_filter.js');
|
||||
|
||||
suite('smart-home/CardFilter', function() {
|
||||
var cardFilter;
|
||||
var mockMenuGroup;
|
||||
var mockSmartButtons;
|
||||
|
||||
var generateSmartButtons = function() {
|
||||
return [
|
||||
new MockSmartButton('filter'),
|
||||
new MockSmartButton('tv'),
|
||||
new MockSmartButton('dashbaord'),
|
||||
new MockSmartButton('device'),
|
||||
new MockSmartButton('application')
|
||||
];
|
||||
};
|
||||
|
||||
suite('> start', function() {
|
||||
setup(function() {
|
||||
mockSmartButtons = generateSmartButtons();
|
||||
mockSmartButtons.forEach(function(button) {
|
||||
sinon.spy(button, 'addEventListener');
|
||||
});
|
||||
|
||||
mockMenuGroup = new MockMenuGroup();
|
||||
sinon.stub(mockMenuGroup, 'querySelectorAll', function() {
|
||||
return mockSmartButtons;
|
||||
});
|
||||
sinon.spy(mockMenuGroup, 'addEventListener');
|
||||
cardFilter = new CardFilter();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
mockMenuGroup = undefined;
|
||||
cardFilter = undefined;
|
||||
mockSmartButtons = undefined;
|
||||
});
|
||||
|
||||
test('start() should register "click" event listeners on smart-button',
|
||||
function() {
|
||||
cardFilter.start(mockMenuGroup);
|
||||
assert.isTrue(mockMenuGroup.querySelectorAll.calledOnce);
|
||||
mockSmartButtons.forEach(function(button) {
|
||||
assert.isTrue(button.addEventListener.calledOnce);
|
||||
});
|
||||
});
|
||||
|
||||
test('start() should listen to "opened" event on menu group', function() {
|
||||
cardFilter.start(mockMenuGroup);
|
||||
assert.isTrue(mockMenuGroup.addEventListener.calledOnce);
|
||||
var call = mockMenuGroup.addEventListener.firstCall;
|
||||
assert.equal(call.args[0], 'opened');
|
||||
assert.isTrue(typeof call.args[1] === 'function');
|
||||
});
|
||||
});
|
||||
|
||||
suite('> stop', function() {
|
||||
setup(function() {
|
||||
mockSmartButtons = generateSmartButtons();
|
||||
mockSmartButtons.forEach(function(button) {
|
||||
sinon.spy(button, 'removeEventListener');
|
||||
});
|
||||
|
||||
mockMenuGroup = new MockMenuGroup();
|
||||
sinon.stub(mockMenuGroup, 'querySelectorAll', function() {
|
||||
return mockSmartButtons;
|
||||
});
|
||||
cardFilter = new CardFilter();
|
||||
cardFilter.start(mockMenuGroup);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
mockMenuGroup = undefined;
|
||||
cardFilter = undefined;
|
||||
mockSmartButtons = undefined;
|
||||
});
|
||||
|
||||
test('stop() should remove "click" event listeners on smart-button',
|
||||
function() {
|
||||
cardFilter.stop();
|
||||
mockSmartButtons.forEach(function(button) {
|
||||
assert.isTrue(button.removeEventListener.calledOnce);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('> handleEvent', function() {
|
||||
setup(function() {
|
||||
mockSmartButtons = generateSmartButtons();
|
||||
|
||||
mockMenuGroup = new MockMenuGroup();
|
||||
sinon.stub(mockMenuGroup, 'querySelectorAll', function() {
|
||||
return mockSmartButtons;
|
||||
});
|
||||
cardFilter = new CardFilter();
|
||||
sinon.spy(cardFilter, 'handleEvent');
|
||||
cardFilter.start(mockMenuGroup);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
mockMenuGroup = undefined;
|
||||
cardFilter = undefined;
|
||||
mockSmartButtons = undefined;
|
||||
});
|
||||
|
||||
test('handleEvent() should be called with event argument', function() {
|
||||
mockSmartButtons[0].dispatchEvent({
|
||||
type: 'click'
|
||||
});
|
||||
assert.isTrue(cardFilter.handleEvent.calledOnce);
|
||||
assert.equal(cardFilter.handleEvent.getCall(0).args[0].type, 'click');
|
||||
});
|
||||
});
|
||||
|
||||
suite('> filter', function() {
|
||||
setup(function() {
|
||||
mockSmartButtons = generateSmartButtons();
|
||||
|
||||
mockMenuGroup = new MockMenuGroup();
|
||||
sinon.stub(mockMenuGroup, 'querySelectorAll', function() {
|
||||
return mockSmartButtons;
|
||||
});
|
||||
cardFilter = new CardFilter();
|
||||
cardFilter.filter = 'filter';
|
||||
sinon.spy(cardFilter, 'emit');
|
||||
cardFilter.start(mockMenuGroup);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
mockMenuGroup = undefined;
|
||||
cardFilter = undefined;
|
||||
mockSmartButtons = undefined;
|
||||
});
|
||||
|
||||
test('should fire filterchanged event when filter is changed', function() {
|
||||
cardFilter.filter = 'tv';
|
||||
assert.isTrue(cardFilter.emit.calledOnce);
|
||||
assert.equal(cardFilter.emit.getCall(0).args[0], 'filterchanged');
|
||||
assert.equal(cardFilter.emit.getCall(0).args[1], 'tv');
|
||||
});
|
||||
});
|
||||
|
||||
suite('> show and hide', function() {
|
||||
setup(function() {
|
||||
mockSmartButtons = generateSmartButtons();
|
||||
|
||||
mockMenuGroup = new MockMenuGroup();
|
||||
sinon.stub(mockMenuGroup, 'querySelectorAll', function() {
|
||||
return mockSmartButtons;
|
||||
});
|
||||
sinon.spy(mockMenuGroup.classList, 'add');
|
||||
sinon.spy(mockMenuGroup.classList, 'remove');
|
||||
cardFilter = new CardFilter();
|
||||
cardFilter.filter = 'filter';
|
||||
cardFilter.start(mockMenuGroup);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
mockMenuGroup.classList.add.restore();
|
||||
mockMenuGroup.classList.remove.restore();
|
||||
mockMenuGroup = undefined;
|
||||
cardFilter = undefined;
|
||||
mockSmartButtons = undefined;
|
||||
});
|
||||
|
||||
test('should add "hidden" class to menu group when calling hide()',
|
||||
function() {
|
||||
cardFilter.hide();
|
||||
assert.isTrue(mockMenuGroup.classList.add.calledWithExactly('hidden'));
|
||||
});
|
||||
|
||||
test('should remove "hidden" class from menu group when calling show()',
|
||||
function() {
|
||||
cardFilter.show();
|
||||
assert.isTrue(
|
||||
mockMenuGroup.classList.remove.calledWithExactly('hidden'));
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
623
gaia/tv_apps/smart-home/test/unit/card_manager_test.js
Executable file
623
gaia/tv_apps/smart-home/test/unit/card_manager_test.js
Executable file
|
|
@ -0,0 +1,623 @@
|
|||
'use strict';
|
||||
/* global Application, CardManager, Deck, Folder, AsyncSemaphore,
|
||||
MockCardStore, MockPipedPromise, MockXMLHttpRequest */
|
||||
|
||||
require('/bower_components/evt/index.js');
|
||||
require('/shared/js/async_semaphore.js');
|
||||
require('/shared/js/uuid.js');
|
||||
require('/shared/js/smart-screen/shared_utils.js');
|
||||
require('/shared/test/unit/mocks/mock_piped_promise.js');
|
||||
require('/shared/test/unit/mocks/mock_card_store.js');
|
||||
require('/shared/test/unit/mocks/mock_xml_http_request.js');
|
||||
require('/shared/js/smart-screen/cards/card.js');
|
||||
require('/shared/js/smart-screen/cards/deck.js');
|
||||
require('/shared/js/smart-screen/cards/folder.js');
|
||||
require('/shared/js/smart-screen/cards/application.js');
|
||||
|
||||
suite('smart-home/CardManager', function() {
|
||||
var realPipedPromise;
|
||||
var decks;
|
||||
var apps;
|
||||
var folders;
|
||||
|
||||
suiteSetup(function(done) {
|
||||
realPipedPromise = window.PipedPromise;
|
||||
// real PipedPromise will make test failed because it waits for
|
||||
// last promise to be resolved. But we need to call done in the last
|
||||
// promise. So we use a MockPipedPromise (which is just a genuine native
|
||||
// Promise) instead.
|
||||
window.PipedPromise = MockPipedPromise;
|
||||
|
||||
decks = {
|
||||
dashboard: new Deck({
|
||||
name: {
|
||||
raw: 'Dashboard'
|
||||
},
|
||||
group: 'dashboard',
|
||||
nativeApp: {
|
||||
name: 'Dashboard',
|
||||
removable: false,
|
||||
manifest: {},
|
||||
manifestURL: 'app://dashboard.gaiamobile.org/manifest.webapp'
|
||||
}
|
||||
}),
|
||||
tv: new Deck({
|
||||
name: {
|
||||
raw: 'TV'
|
||||
},
|
||||
group: 'tv',
|
||||
nativeApp: {
|
||||
name: 'TV',
|
||||
removable: false,
|
||||
manifest: {},
|
||||
manifestURL: 'app://tv-deck.gaiamobile.org/manifest.webapp'
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
apps = {
|
||||
music: new Application({
|
||||
name: {
|
||||
raw: 'Music'
|
||||
},
|
||||
group: 'application',
|
||||
nativeApp: {
|
||||
name: 'Music',
|
||||
removable: false,
|
||||
manifest: {},
|
||||
manifestURL: 'app://music.gaiamobile.org/manifest.webapp'
|
||||
}
|
||||
}),
|
||||
video: new Application({
|
||||
name: {
|
||||
raw: 'Video'
|
||||
},
|
||||
group: 'application',
|
||||
nativeApp: {
|
||||
name: 'Video',
|
||||
removable: false,
|
||||
manifest: {},
|
||||
manifestURL: 'app://video.gaiamobile.org/manifest.webapp'
|
||||
}
|
||||
}),
|
||||
gallery: new Application({
|
||||
name: {
|
||||
raw: 'Gallery'
|
||||
},
|
||||
group: 'application',
|
||||
nativeApp: {
|
||||
name: 'Gallery',
|
||||
removable: false,
|
||||
manifest: {},
|
||||
manifestURL: 'app://gallery.gaiamobile.org/manifest.webapp'
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
folders = {
|
||||
emptyOne: new Folder({
|
||||
name: {
|
||||
raw: 'New Empty Folder'
|
||||
}
|
||||
}),
|
||||
emptyTwo: new Folder({
|
||||
name: {
|
||||
raw: 'New Empty Folder 2'
|
||||
}
|
||||
}),
|
||||
nonEmpty: new Folder({
|
||||
name: {
|
||||
raw: 'Non Empty'
|
||||
},
|
||||
_cardsInFolder: [apps.video, apps.gallery]
|
||||
})
|
||||
};
|
||||
|
||||
require('/shared/js/smart-screen/card_manager.js', function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
decks = undefined;
|
||||
apps = undefined;
|
||||
folders = undefined;
|
||||
window.PipedPromise = realPipedPromise;
|
||||
});
|
||||
|
||||
function prepareCardManagerForTesting() {
|
||||
var result = new CardManager();
|
||||
// We bypass init() because it involves navigator.mozApps.mgmt
|
||||
// Instead we need to prepare necessary properties of cardManager
|
||||
result._asyncSemaphore = new AsyncSemaphore();
|
||||
result._cardStore = MockCardStore;
|
||||
|
||||
result._cardList = [
|
||||
decks.dashboard,
|
||||
apps.music,
|
||||
decks.tv,
|
||||
folders.nonEmpty
|
||||
];
|
||||
|
||||
result.installedApps = {
|
||||
'app://dashboard.gaiamobile.org/manifest.webapp': {
|
||||
name: 'Dashboard',
|
||||
removable: false,
|
||||
manifest: {},
|
||||
manifestURL: 'app://dashboard.gaiamobile.org/manifest.webapp'
|
||||
},
|
||||
'app://music.gaiamobile.org/manifest.webapp': {
|
||||
name: 'Music',
|
||||
removable: false,
|
||||
manifest: {},
|
||||
manifestURL: 'app://music.gaiamobile.org/manifest.webapp'
|
||||
},
|
||||
'app://tv-deck.gaiamobile.org/manifest.webapp': {
|
||||
name: 'TV',
|
||||
removable: false,
|
||||
manifest: {},
|
||||
manifestURL: 'app://tv-deck.gaiamobile.org/manifest.webapp'
|
||||
},
|
||||
'app://video.gaiamobile.org/manifest.webapp': {
|
||||
name: 'Video',
|
||||
removable: false,
|
||||
manifest: {},
|
||||
manifestURL: 'app://video.gaiamobile.org/manifest.webapp'
|
||||
},
|
||||
'app://gallery.gaiamobile.org/manifest.webapp': {
|
||||
name: 'Gallery',
|
||||
removable: false,
|
||||
manifest: {},
|
||||
manifestURL: 'app://gallery.gaiamobile.org/manifest.webapp'
|
||||
},
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
suite('_bestMatchingIcon()', function() {
|
||||
var cardManager;
|
||||
var app;
|
||||
var manifestWithIconsInOrder = {
|
||||
icons: {
|
||||
'32': '/style/icons/32.png',
|
||||
'64': '/style/icons/64.png',
|
||||
'128': '/style/icons/128.png',
|
||||
'256': '/style/icons/256.png'
|
||||
}
|
||||
};
|
||||
var manifestWithIconsInRandom = {
|
||||
icons: {
|
||||
'32': '/style/icons/32.png',
|
||||
'256': '/style/icons/256.png',
|
||||
'128': '/style/icons/128.png',
|
||||
'64': '/style/icons/64.png'
|
||||
}
|
||||
};
|
||||
|
||||
setup(function() {
|
||||
cardManager = new CardManager();
|
||||
app = {
|
||||
origin: 'app://stub.gaiamobile.org/'
|
||||
};
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
cardManager = undefined;
|
||||
app = undefined;
|
||||
});
|
||||
|
||||
test('call without preferredSize', function() {
|
||||
var actual = cardManager._bestMatchingIcon(app, manifestWithIconsInOrder);
|
||||
assert.equal(actual, 'app://stub.gaiamobile.org/style/icons/256.png');
|
||||
});
|
||||
|
||||
test('call with random order of icon size and ' +
|
||||
'without preferredSize ', function() {
|
||||
var actual =
|
||||
cardManager._bestMatchingIcon(app, manifestWithIconsInRandom);
|
||||
assert.equal(actual, 'app://stub.gaiamobile.org/style/icons/256.png');
|
||||
});
|
||||
|
||||
test('call with preferredSize', function() {
|
||||
var actual =
|
||||
cardManager._bestMatchingIcon(app, manifestWithIconsInOrder, 100);
|
||||
assert.equal(actual, 'app://stub.gaiamobile.org/style/icons/128.png');
|
||||
});
|
||||
|
||||
test('call with random order of icon size and ' +
|
||||
'preferredSize ', function() {
|
||||
var actual =
|
||||
cardManager._bestMatchingIcon(app, manifestWithIconsInRandom, 100);
|
||||
assert.equal(actual, 'app://stub.gaiamobile.org/style/icons/128.png');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('_reloadCardList()', function() {
|
||||
var cardManager;
|
||||
var realXMLHttpRequest;
|
||||
|
||||
setup(function() {
|
||||
cardManager = new CardManager();
|
||||
// We bypass init() because it involves navigator.mozApps.mgmt
|
||||
// Instead we need to prepare necessary properties of cardManager
|
||||
cardManager._cardList = [];
|
||||
cardManager._cardStore = MockCardStore;
|
||||
cardManager._asyncSemaphore = new AsyncSemaphore();
|
||||
realXMLHttpRequest = window.XMLHttpRequest;
|
||||
window.XMLHttpRequest = MockXMLHttpRequest;
|
||||
this.sinon.spy(cardManager, 'writeCardlistInCardStore');
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
MockCardStore.mClearData();
|
||||
window.XMLHttpRequest = realXMLHttpRequest;
|
||||
cardManager = undefined;
|
||||
});
|
||||
|
||||
test('should load cardList from datastore if possible', function(done) {
|
||||
MockCardStore.mPrepareData('cardList', [{
|
||||
'name': 'Television',
|
||||
'type': 'Deck'
|
||||
}]);
|
||||
|
||||
cardManager._reloadCardList().then(function() {
|
||||
assert.isTrue(cardManager._cardList.length > 0);
|
||||
assert.equal(cardManager._cardList[0].name, 'Television');
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('should load cardList from file if nothing in datastore',
|
||||
function(done) {
|
||||
cardManager._reloadCardList().then(function() {
|
||||
assert.isTrue(cardManager._cardList.length > 0);
|
||||
assert.equal(cardManager._cardList[0].name, 'Devices');
|
||||
assert.isTrue(cardManager.writeCardlistInCardStore.calledOnce);
|
||||
}, function(reason) {
|
||||
assert.fail('should not reject promise due to ' + reason);
|
||||
}).then(done, done);
|
||||
|
||||
// XXX: We should remove window.setTimeout in test but since we are
|
||||
// guarding this test with done(), let's just put it as is until we
|
||||
// have better solution
|
||||
window.setTimeout(function() {
|
||||
MockXMLHttpRequest.triggerReadyStateChange({
|
||||
status: 200,
|
||||
response: {
|
||||
'card_list': [{
|
||||
'name': 'Devices',
|
||||
'type': 'Deck'
|
||||
}]
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('findCardFromCardList()', function() {
|
||||
var cardManager;
|
||||
var dashboardCardId;
|
||||
var folderCardId;
|
||||
|
||||
setup(function() {
|
||||
cardManager = prepareCardManagerForTesting();
|
||||
dashboardCardId = cardManager._cardList[0].cardId;
|
||||
folderCardId = cardManager._cardList[3].cardId;
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
MockCardStore.mClearData();
|
||||
cardManager = undefined;
|
||||
dashboardCardId = undefined;
|
||||
folderCardId = undefined;
|
||||
});
|
||||
|
||||
test('should find card based on cardId', function() {
|
||||
var card = cardManager.findCardFromCardList({
|
||||
cardId: dashboardCardId
|
||||
});
|
||||
assert.equal(card.name.raw, 'Dashboard');
|
||||
});
|
||||
|
||||
test('should find folder based on cardId', function() {
|
||||
var card = cardManager.findCardFromCardList({
|
||||
cardId: folderCardId
|
||||
});
|
||||
assert.isTrue(card instanceof Folder);
|
||||
assert.equal(card.name.raw, 'Non Empty');
|
||||
});
|
||||
|
||||
test('should return undefined by querying non-existing launchURL',
|
||||
function() {
|
||||
var card = cardManager.findCardFromCardList({
|
||||
manifestURL: 'app://tv-deck.gaiamobile.org/manifest.webapp',
|
||||
launchURL: 'app://tv-deck.gaiamobile.org/#42'
|
||||
});
|
||||
|
||||
assert.isUndefined(card);
|
||||
});
|
||||
|
||||
test('should return undefined if not found', function() {
|
||||
var card = cardManager.findCardFromCardList({
|
||||
cardId: 'incorrect-card-id'
|
||||
});
|
||||
assert.isUndefined(card);
|
||||
});
|
||||
|
||||
test('should find card inside of folder', function() {
|
||||
var card = cardManager.findCardFromCardList({
|
||||
manifestURL: 'app://video.gaiamobile.org/manifest.webapp'
|
||||
});
|
||||
assert.equal(card.name.raw, 'Video');
|
||||
});
|
||||
|
||||
test('should be able to find folder by querying via cardEntry', function() {
|
||||
var folderEntry = folders.nonEmpty.serialize();
|
||||
var card = cardManager.findCardFromCardList({
|
||||
cardEntry: folderEntry
|
||||
});
|
||||
assert.equal(card, folders.nonEmpty);
|
||||
});
|
||||
});
|
||||
|
||||
suite('getFilteredCardList()', function() {
|
||||
var cardManager;
|
||||
|
||||
setup(function() {
|
||||
cardManager = prepareCardManagerForTesting();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
MockCardStore.mClearData();
|
||||
cardManager = undefined;
|
||||
});
|
||||
|
||||
test('should get only apps if filter="application"', function(done) {
|
||||
var filter = 'application';
|
||||
cardManager.getFilteredCardList(filter).then(function(cards) {
|
||||
assert.isTrue(cards.length === 1);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('should get all cards if filter="all"', function(done) {
|
||||
var filter = 'all';
|
||||
cardManager.getFilteredCardList(filter).then(function(cards) {
|
||||
assert.isTrue(cards.length === cardManager._cardList.length);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('should get empty array if filter is undefined', function(done) {
|
||||
cardManager.getFilteredCardList().then(function(cards) {
|
||||
assert.isTrue(cards.length === 0);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('insertNewFolder()', function() {
|
||||
var cardManager;
|
||||
var dashboardCardId;
|
||||
|
||||
setup(function() {
|
||||
cardManager = new CardManager();
|
||||
// We bypass init() because it involves navigator.mozApps.mgmt
|
||||
// Instead we need to prepare necessary properties of cardManager
|
||||
cardManager._asyncSemaphore = new AsyncSemaphore();
|
||||
cardManager._cardStore = MockCardStore;
|
||||
cardManager._cardList = [decks.dashboard];
|
||||
cardManager.installedApps = {
|
||||
'app://dashboard.gaiamobile.org/manifest.webapp': {
|
||||
name: 'Dashboard',
|
||||
removable: false,
|
||||
manifest: {},
|
||||
manifestURL: 'app://dashboard.gaiamobile.org/manifest.webapp'
|
||||
}
|
||||
};
|
||||
dashboardCardId = cardManager._cardList[0].cardId;
|
||||
|
||||
this.sinon.spy(cardManager, 'writeFolderInCardStore');
|
||||
this.sinon.spy(cardManager, 'writeCardlistInCardStore');
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
MockCardStore.mClearData();
|
||||
cardManager = undefined;
|
||||
});
|
||||
|
||||
test('should return new folder instance whenever a new folder is inserted',
|
||||
function() {
|
||||
var newFolder = cardManager.insertNewFolder('an empty folder');
|
||||
|
||||
assert.ok(newFolder.folderId);
|
||||
assert.equal(newFolder.state, Folder.STATES.DETACHED);
|
||||
});
|
||||
|
||||
test('should write to data store when folder has content', function() {
|
||||
var newFolder = cardManager.insertNewFolder('a test folder');
|
||||
assert.isFalse(cardManager.writeCardlistInCardStore.calledOnce);
|
||||
newFolder.addCard(new Application({
|
||||
name: 'Music',
|
||||
group: 'application'
|
||||
}));
|
||||
|
||||
assert.isTrue(cardManager.writeCardlistInCardStore.calledOnce);
|
||||
});
|
||||
|
||||
test('should insert at correct location if index is specified', function() {
|
||||
var targetLocation = 0;
|
||||
var newFolder =
|
||||
cardManager.insertNewFolder('a test folder', targetLocation);
|
||||
assert.isFalse(cardManager.writeCardlistInCardStore.calledOnce);
|
||||
newFolder.addCard(apps.music);
|
||||
|
||||
assert.isTrue(cardManager.writeCardlistInCardStore.calledOnce);
|
||||
assert.equal(cardManager._cardList[targetLocation], newFolder);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('insertCard()', function() {
|
||||
var cardManager;
|
||||
|
||||
setup(function() {
|
||||
cardManager = prepareCardManagerForTesting();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
MockCardStore.mClearData();
|
||||
cardManager = undefined;
|
||||
});
|
||||
|
||||
test('should not be able to insert the same card twice', function() {
|
||||
var expectedCardListLength = cardManager._cardList.length;
|
||||
cardManager.insertCard({
|
||||
cardEntry: {
|
||||
'type': 'Application',
|
||||
'group': 'app',
|
||||
'manifestURL': 'app://music.gaiamobile.org/manifest.webapp'
|
||||
}
|
||||
});
|
||||
assert.equal(cardManager._cardList.length, expectedCardListLength);
|
||||
});
|
||||
|
||||
test('should be able to insert same app twice with different launchURL',
|
||||
function() {
|
||||
var expectedCardListLength = cardManager._cardList.length + 1;
|
||||
cardManager.insertCard({
|
||||
cardEntry: {
|
||||
'type': 'Application',
|
||||
'group': 'tv',
|
||||
'manifestURL': 'app://tv-deck.gaiamobile.org/manifest.webapp',
|
||||
'launchURL': 'app://tv-deck.gaiamobile.org/#42'
|
||||
}
|
||||
});
|
||||
assert.equal(cardManager._cardList.length, expectedCardListLength);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('removeCard()', function() {
|
||||
var cardManager;
|
||||
setup(function() {
|
||||
cardManager = prepareCardManagerForTesting();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
MockCardStore.mClearData();
|
||||
cardManager = undefined;
|
||||
});
|
||||
|
||||
test('should be able to remove card with index specified', function() {
|
||||
assert.ok(
|
||||
cardManager.findCardFromCardList({
|
||||
manifestURL: 'app://music.gaiamobile.org/manifest.webapp'})
|
||||
);
|
||||
|
||||
cardManager.removeCard(1); // remove card of 'Music' app
|
||||
|
||||
assert.isUndefined(
|
||||
cardManager.findCardFromCardList({
|
||||
manifestURL: 'app://music.gaiamobile.org/manifest.webapp'})
|
||||
);
|
||||
});
|
||||
|
||||
test('should be able to remove card within folder', function(done) {
|
||||
assert.ok(
|
||||
cardManager.findCardFromCardList({
|
||||
manifestURL: 'app://video.gaiamobile.org/manifest.webapp'})
|
||||
);
|
||||
|
||||
cardManager.getCardList().then(function(cardList) {
|
||||
cardManager.removeCard(cardList[3].getCardList()[0]);
|
||||
|
||||
assert.isUndefined(
|
||||
cardManager.findCardFromCardList({
|
||||
manifestURL: 'app://video.gaiamobile.org/manifest.webapp'})
|
||||
);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('writeCardlistInCardStore()', function() {
|
||||
var cardManager;
|
||||
|
||||
setup(function() {
|
||||
cardManager = new CardManager();
|
||||
// We bypass init() because it involves navigator.mozApps.mgmt
|
||||
// Instead we need to prepare necessary properties of cardManager
|
||||
cardManager._asyncSemaphore = new AsyncSemaphore();
|
||||
cardManager._cardStore = MockCardStore;
|
||||
|
||||
cardManager._cardList = [
|
||||
decks.dashbaord,
|
||||
folders.emptyOne,
|
||||
folders.emptyTwo,
|
||||
apps.music
|
||||
];
|
||||
|
||||
cardManager.installedApps = {
|
||||
'app://dashboard.gaiamobile.org/manifest.webapp': {
|
||||
name: 'Dashboard',
|
||||
removable: false,
|
||||
manifest: {},
|
||||
manifestURL: 'app://dashboard.gaiamobile.org/manifest.webapp'
|
||||
},
|
||||
'app://music.gaiamobile.org/manifest.webapp': {
|
||||
name: 'Music',
|
||||
removable: false,
|
||||
manifest: {},
|
||||
manifestURL: 'app://music.gaiamobile.org/manifest.webapp'
|
||||
}
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
MockCardStore.mClearData();
|
||||
cardManager = undefined;
|
||||
});
|
||||
|
||||
test('write with empty folder should eliminate it from card list',
|
||||
function(done) {
|
||||
var expectedLength = cardManager._cardList.length - 2;
|
||||
|
||||
cardManager.writeCardlistInCardStore({
|
||||
cleanEmptyFolder: true
|
||||
}).then(function() {
|
||||
assert.equal(cardManager._cardList.length, expectedLength);
|
||||
assert.isTrue(cardManager._cardList.indexOf(folders.emptyOne) < 0);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('swapCard()', function() {
|
||||
var cardManager;
|
||||
|
||||
setup(function() {
|
||||
cardManager = prepareCardManagerForTesting();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
MockCardStore.mClearData();
|
||||
cardManager = undefined;
|
||||
});
|
||||
|
||||
test('swap adjacent cards', function() {
|
||||
var card1 = cardManager._cardList[0];
|
||||
var card2 = cardManager._cardList[1];
|
||||
cardManager.swapCard(card1, card2);
|
||||
assert.equal(cardManager._cardList[0], card2);
|
||||
assert.equal(cardManager._cardList[1], card1);
|
||||
});
|
||||
|
||||
test('swap non-adjacent cards', function() {
|
||||
var card1 = cardManager._cardList[0];
|
||||
var card2 = cardManager._cardList[2];
|
||||
cardManager.swapCard(card1, card2);
|
||||
assert.equal(cardManager._cardList[0], card2);
|
||||
assert.equal(cardManager._cardList[2], card1);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
158
gaia/tv_apps/smart-home/test/unit/filter_manager_test.js
Executable file
158
gaia/tv_apps/smart-home/test/unit/filter_manager_test.js
Executable file
|
|
@ -0,0 +1,158 @@
|
|||
/* global MockCardFilter, FilterManager, MockXScrollable, MockCardManager,
|
||||
MockHome */
|
||||
|
||||
'use strict';
|
||||
require('/bower_components/evt/index.js');
|
||||
requireApp('smart-home/test/unit/mock_card_filter.js');
|
||||
requireApp('smart-home/test/unit/mock_x_scrollable.js');
|
||||
requireApp('smart-home/test/unit/mock_card_manager.js');
|
||||
requireApp('smart-home/test/unit/mock_home.js');
|
||||
requireApp('smart-home/js/filter_manager.js');
|
||||
|
||||
suite('smart-gome/FilterManager', function() {
|
||||
|
||||
var setupDOM = function() {
|
||||
var filterTabGroup = document.createElement('menu');
|
||||
filterTabGroup.id = 'filter-tab-group';
|
||||
filterTabGroup.dataset.iconType = 'filter';
|
||||
filterTabGroup.classList.add('filter-tab-group');
|
||||
|
||||
var bubbles = document.createElement('div');
|
||||
bubbles.id = 'bubbles';
|
||||
|
||||
var cardListElem = document.createElement('div');
|
||||
cardListElem.id = 'card-list';
|
||||
cardListElem.setAttribute('smart-bubbles', 'true');
|
||||
cardListElem.dataset.defaultItem = '0';
|
||||
|
||||
document.body.appendChild(filterTabGroup);
|
||||
document.body.appendChild(bubbles);
|
||||
document.body.appendChild(cardListElem);
|
||||
};
|
||||
|
||||
var teardownDOM = function() {
|
||||
document.body.removeChild(document.getElementById('filter-tab-group'));
|
||||
document.body.removeChild(document.getElementById('bubbles'));
|
||||
document.body.removeChild(document.getElementById('card-list'));
|
||||
};
|
||||
|
||||
suite('> filterchanged event', function() {
|
||||
var realCardFilter;
|
||||
var filterManager;
|
||||
|
||||
setup(function() {
|
||||
realCardFilter = window.CardFilter;
|
||||
window.CardFilter = MockCardFilter;
|
||||
setupDOM();
|
||||
|
||||
filterManager = new FilterManager();
|
||||
filterManager.init({
|
||||
cardListElem: document.getElementById('card-list'),
|
||||
cardScrollable: new MockXScrollable(),
|
||||
home: new MockHome(),
|
||||
cardManager: new MockCardManager()
|
||||
});
|
||||
|
||||
filterManager._smartBubblesElem.play = function() {};
|
||||
filterManager._smartBubblesElem.stopImmediately = function() {};
|
||||
sinon.spy(filterManager._smartBubblesElem, 'play');
|
||||
sinon.spy(filterManager._smartBubblesElem, 'stopImmediately');
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
window.cardFilter = realCardFilter;
|
||||
filterManager._smartBubblesElem.play.restore();
|
||||
filterManager._smartBubblesElem.stopImmediately.restore();
|
||||
filterManager = undefined;
|
||||
teardownDOM();
|
||||
});
|
||||
|
||||
test('start playing animation when filterchanged is fired', function() {
|
||||
var cardListElem = document.getElementById('card-list');
|
||||
filterManager._cardFilter.mFireEvent('filterchanged', 'tv');
|
||||
|
||||
assert.equal(
|
||||
cardListElem.getAttribute('smart-bubbles-direction'), 'down');
|
||||
assert.isTrue(filterManager._smartBubblesElem.play.calledOnce);
|
||||
});
|
||||
|
||||
test('stop playing animation when filterchanged is fired before previous ' +
|
||||
' animation ends', function() {
|
||||
|
||||
filterManager._isFilterChanging = true;
|
||||
filterManager._cardFilter.mFireEvent('filterchanged', 'tv');
|
||||
|
||||
assert.isTrue(filterManager._smartBubblesElem.stopImmediately.calledOnce);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('> all-items-bubbled event', function() {
|
||||
var realCardFilter;
|
||||
var filterManager;
|
||||
var mockXScrollable;
|
||||
var mockCardManager;
|
||||
var mockHome;
|
||||
var cardListElem;
|
||||
|
||||
setup(function() {
|
||||
realCardFilter = window.CardFilter;
|
||||
window.CardFilter = MockCardFilter;
|
||||
setupDOM();
|
||||
|
||||
cardListElem = document.getElementById('card-list');
|
||||
mockXScrollable = new MockXScrollable();
|
||||
mockCardManager = new MockCardManager();
|
||||
filterManager = new FilterManager();
|
||||
mockHome = new MockHome();
|
||||
filterManager.init({
|
||||
cardListElem: cardListElem,
|
||||
cardScrollable: mockXScrollable,
|
||||
home: mockHome,
|
||||
cardManager: mockCardManager
|
||||
});
|
||||
|
||||
filterManager._smartBubblesElem.play = function() {};
|
||||
filterManager._smartBubblesElem.stopImmediately = function() {};
|
||||
sinon.spy(filterManager, 'getFilterByIconName');
|
||||
sinon.spy(mockXScrollable, 'clean');
|
||||
sinon.spy(mockCardManager, 'getFilteredCardList');
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
window.cardFilter = realCardFilter;
|
||||
filterManager.getFilterByIconName.restore();
|
||||
filterManager = undefined;
|
||||
mockXScrollable.clean.restore();
|
||||
mockXScrollable = undefined;
|
||||
mockCardManager.getFilteredCardList.restore();
|
||||
mockCardManager = undefined;
|
||||
mockHome = undefined;
|
||||
teardownDOM();
|
||||
});
|
||||
|
||||
test('clean scrollable and get filtered cards when bubbling down ' +
|
||||
'animation ends', function() {
|
||||
// pretend that we already went through 'onFilterChanged'
|
||||
filterManager._isFilterChanging = true;
|
||||
cardListElem.setAttribute('smart-bubbles-direction', 'down');
|
||||
filterManager._smartBubblesElem.dispatchEvent(
|
||||
new CustomEvent('all-items-bubbled'));
|
||||
|
||||
assert.isTrue(mockXScrollable.clean.calledOnce);
|
||||
assert.isTrue(mockCardManager.getFilteredCardList.calledOnce);
|
||||
});
|
||||
|
||||
test('reset _isFilterChanging to false when bubbling up animation ends',
|
||||
function() {
|
||||
// pretend that we already went through 'onFilterChanged'
|
||||
filterManager._isFilterChanging = true;
|
||||
cardListElem.removeAttribute('smart-bubbles-direction');
|
||||
filterManager._smartBubblesElem.dispatchEvent(
|
||||
new CustomEvent('all-items-bubbled'));
|
||||
|
||||
assert.isFalse(mockXScrollable.clean.calledOnce);
|
||||
assert.isFalse(mockCardManager.getFilteredCardList.calledOnce);
|
||||
});
|
||||
});
|
||||
});
|
||||
144
gaia/tv_apps/smart-home/test/unit/folder_test.js
Executable file
144
gaia/tv_apps/smart-home/test/unit/folder_test.js
Executable file
|
|
@ -0,0 +1,144 @@
|
|||
'use strict';
|
||||
|
||||
/* global Deck, Folder, Application */
|
||||
|
||||
require('/bower_components/evt/index.js');
|
||||
require('/shared/js/uuid.js');
|
||||
require('/shared/js/smart-screen/cards/card.js');
|
||||
require('/shared/js/smart-screen/cards/application.js');
|
||||
require('/shared/js/smart-screen/cards/deck.js');
|
||||
require('/shared/js/smart-screen/cards/folder.js');
|
||||
|
||||
suite('Folder', function() {
|
||||
var folder;
|
||||
var stubFolder;
|
||||
var nonEmptyFolder;
|
||||
var apps;
|
||||
var deck;
|
||||
|
||||
var eventSpy;
|
||||
|
||||
setup(function() {
|
||||
apps = {
|
||||
music: new Application({
|
||||
name: 'Music',
|
||||
nativeApp: {
|
||||
name: 'Music',
|
||||
removable: false,
|
||||
manifest: {},
|
||||
manifestURL: 'app://music.gaiamobile.org/manifest.webapp'
|
||||
}
|
||||
}),
|
||||
video: new Application({
|
||||
name: 'Video',
|
||||
nativeApp: {
|
||||
name: 'Video',
|
||||
removable: false,
|
||||
manifest: {},
|
||||
manifestURL: 'app://video.gaiamobile.org/manifest.webapp'
|
||||
}
|
||||
}),
|
||||
gallery: new Application({
|
||||
name: 'Gallery',
|
||||
nativeApp: {
|
||||
name: 'Gallery',
|
||||
removable: false,
|
||||
manifest: {},
|
||||
manifestURL: 'app://gallery.gaiamobile.org/manifest.webapp'
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
folder = new Folder({
|
||||
name: 'folder under test'
|
||||
});
|
||||
|
||||
deck = new Deck({
|
||||
nativeApp: {},
|
||||
name: 'a deck'
|
||||
});
|
||||
|
||||
stubFolder = new Folder({
|
||||
name: 'folder as stub'
|
||||
});
|
||||
|
||||
nonEmptyFolder = new Folder({
|
||||
name: 'non empty',
|
||||
_cardsInFolder: [apps.music, apps.video, apps.gallery]
|
||||
});
|
||||
|
||||
eventSpy = this.sinon.spy();
|
||||
nonEmptyFolder.on('folder-changed', eventSpy);
|
||||
nonEmptyFolder.on('card-inserted', eventSpy);
|
||||
nonEmptyFolder.on('card-removed', eventSpy);
|
||||
nonEmptyFolder.on('card-updated', eventSpy);
|
||||
nonEmptyFolder.on('card-swapped', eventSpy);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
folder = undefined;
|
||||
deck = undefined;
|
||||
stubFolder = undefined;
|
||||
nonEmptyFolder = undefined;
|
||||
apps = undefined;
|
||||
eventSpy = undefined;
|
||||
});
|
||||
|
||||
var assertFolderIsEmpty = function(target) {
|
||||
assert.isTrue(target._cardsInFolder.length === 0);
|
||||
};
|
||||
|
||||
var assertFolderIsDirty = function(target) {
|
||||
assert.equal(target.state, Folder.STATES.DIRTY);
|
||||
};
|
||||
|
||||
test('should be able to add deck into folder', function() {
|
||||
assertFolderIsEmpty(folder);
|
||||
folder.addCard(deck);
|
||||
assert.equal(folder.getCardList()[0], deck);
|
||||
assertFolderIsDirty(folder);
|
||||
});
|
||||
|
||||
test('should not be able to add folder into folder', function() {
|
||||
assertFolderIsEmpty(stubFolder);
|
||||
folder.addCard(stubFolder);
|
||||
assertFolderIsEmpty(stubFolder);
|
||||
assert.equal(stubFolder.state, Folder.STATES.NORMAL);
|
||||
});
|
||||
|
||||
test('should be able to remove deck from folder', function() {
|
||||
folder.getCardList()[0] = deck;
|
||||
|
||||
folder.removeCard(deck);
|
||||
assertFolderIsEmpty(folder);
|
||||
assertFolderIsDirty(folder);
|
||||
});
|
||||
|
||||
test('should be able to update card in folder', function() {
|
||||
var index = 0;
|
||||
var cardToBeUpdated = nonEmptyFolder.getCardList()[index];
|
||||
cardToBeUpdated.name = 'new gallery';
|
||||
|
||||
assert.isFalse(eventSpy.called);
|
||||
nonEmptyFolder.updateCard(cardToBeUpdated, index);
|
||||
assert.equal(
|
||||
nonEmptyFolder.getCardList()[0].cardId, cardToBeUpdated.cardId);
|
||||
assert.equal(nonEmptyFolder.getCardList()[0].name, cardToBeUpdated.name);
|
||||
assert.isTrue(eventSpy.calledWithExactly(nonEmptyFolder));
|
||||
assert.isTrue(eventSpy.calledWithExactly(cardToBeUpdated, index));
|
||||
assertFolderIsDirty(nonEmptyFolder);
|
||||
});
|
||||
|
||||
test('should be able to swap cards in folder', function() {
|
||||
var card1 = nonEmptyFolder.getCardList()[0];
|
||||
var card2 = nonEmptyFolder.getCardList()[2];
|
||||
|
||||
assert.isFalse(eventSpy.called);
|
||||
nonEmptyFolder.swapCard(card1, card2);
|
||||
assert.equal(nonEmptyFolder.getCardList()[0], card2);
|
||||
assert.equal(nonEmptyFolder.getCardList()[2], card1);
|
||||
assert.isTrue(eventSpy.calledWithExactly(nonEmptyFolder));
|
||||
assert.isTrue(eventSpy.calledWithExactly(card2, card1, 0, 2));
|
||||
assertFolderIsDirty(nonEmptyFolder);
|
||||
});
|
||||
});
|
||||
359
gaia/tv_apps/smart-home/test/unit/home_test.js
Executable file
359
gaia/tv_apps/smart-home/test/unit/home_test.js
Executable file
|
|
@ -0,0 +1,359 @@
|
|||
'use strict';
|
||||
/* global Folder, navigator, MockL10n, document, MocksHelper,
|
||||
XScrollable, MozActivity, SpatialNavigator, CardManager, MessageHandler,
|
||||
Home, SearchBar, FilterManager, Edit, Utils, Application, MockMozActivity,
|
||||
FTEWizard */
|
||||
|
||||
require('/bower_components/evt/index.js');
|
||||
require('/shared/js/uuid.js');
|
||||
require('/shared/js/smart-screen/cards/card.js');
|
||||
require('/shared/js/smart-screen/cards/application.js');
|
||||
require('/shared/js/smart-screen/cards/deck.js');
|
||||
require('/shared/js/smart-screen/cards/folder.js');
|
||||
require('/shared/js/smart-screen/cards/app_bookmark.js');
|
||||
require('/shared/js/smart-screen/clock.js');
|
||||
require('/shared/test/unit/mocks/mock_event_target.js');
|
||||
require('mock_card_manager.js');
|
||||
require('mock_search_bar.js');
|
||||
require('mock_menu_group.js');
|
||||
require('mock_message_handler.js');
|
||||
require('mock_x_scrollable.js');
|
||||
require('mock_card_filter.js');
|
||||
require('mock_edit.js');
|
||||
require('mock_animations.js');
|
||||
require('mock_utils.js');
|
||||
require('mock_filter_manager.js');
|
||||
require('/shared/test/unit/mocks/smart-screen/mock_spatial_navigator.js');
|
||||
require('/shared/test/unit/mocks/smart-screen/mock_key_navigation_adapter.js');
|
||||
require('/shared/test/unit/mocks/smart-screen/mock_f_t_e_wizard.js');
|
||||
require('/shared/test/unit/mocks/mock_l10n.js');
|
||||
require('/shared/test/unit/mocks/mocks_helper.js');
|
||||
require('/shared/test/unit/mocks/mock_moz_activity.js');
|
||||
require('/tv_apps/smart-home/js/home.js');
|
||||
|
||||
var mocksHelperForHomeTest = new MocksHelper([
|
||||
'CardManager',
|
||||
'CardFilter',
|
||||
'SearchBar',
|
||||
'MessageHandler',
|
||||
'XScrollable',
|
||||
'SpatialNavigator',
|
||||
'KeyNavigationAdapter',
|
||||
'Animations',
|
||||
'Edit',
|
||||
'MozActivity',
|
||||
'Utils',
|
||||
'FilterManager',
|
||||
'FTEWizard'
|
||||
]).init();
|
||||
|
||||
suite('home', function() {
|
||||
var realL10n = navigator.mozL10n;
|
||||
var realMozActivity = window.MozActivity;
|
||||
var searchButton, settingsButton, editButton, timeElem;
|
||||
var filterTabGroup, filterAllButton;
|
||||
var subject;
|
||||
var fakeTimer;
|
||||
|
||||
mocksHelperForHomeTest.attachTestHelpers();
|
||||
|
||||
suiteSetup(function() {
|
||||
realL10n = navigator.mozL10n;
|
||||
navigator.mozL10n = MockL10n;
|
||||
|
||||
searchButton = document.createElement('button');
|
||||
searchButton.id = 'search-button';
|
||||
document.body.appendChild(searchButton);
|
||||
|
||||
settingsButton = document.createElement('button');
|
||||
settingsButton.id = 'settings-button';
|
||||
document.body.appendChild(settingsButton);
|
||||
|
||||
editButton = document.createElement('button');
|
||||
editButton.id = 'edit-button';
|
||||
document.body.appendChild(editButton);
|
||||
|
||||
timeElem = document.createElement('div');
|
||||
timeElem.id = 'time';
|
||||
document.body.appendChild(timeElem);
|
||||
|
||||
filterTabGroup = document.createElement('menu-group');
|
||||
filterTabGroup.once = function() {};
|
||||
filterTabGroup.open = function() {};
|
||||
filterTabGroup.close = function() {};
|
||||
filterTabGroup.id = 'filter-tab-group';
|
||||
filterAllButton = document.createElement('smart-button');
|
||||
filterAllButton.id = 'filter-all-button';
|
||||
filterTabGroup.appendChild(filterAllButton);
|
||||
document.body.appendChild(filterTabGroup);
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
navigator.mozL10n = realL10n;
|
||||
document.body.removeChild(searchButton);
|
||||
document.body.removeChild(settingsButton);
|
||||
document.body.removeChild(editButton);
|
||||
document.body.removeChild(timeElem);
|
||||
document.body.removeChild(filterTabGroup);
|
||||
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
subject = new Home();
|
||||
subject.cardScrollable = new XScrollable();
|
||||
subject.folderScrollable = new XScrollable();
|
||||
subject.messageHandler = new MessageHandler();
|
||||
subject.spatialNavigator = new SpatialNavigator();
|
||||
subject.cardManager = new CardManager();
|
||||
subject.searchBar = new SearchBar();
|
||||
subject.filterManager = new FilterManager();
|
||||
subject._fteWizard = new FTEWizard();
|
||||
subject.edit = new Edit();
|
||||
subject.cardListElem = document.createElement('div');
|
||||
subject.spatialNavigator.m_focusedElement = document.createElement('div');
|
||||
subject.isNavigable = true;
|
||||
subject.settingsButton = settingsButton;
|
||||
subject.editButton = editButton;
|
||||
subject.searchButton = searchButton;
|
||||
|
||||
fakeTimer = this.sinon.useFakeTimers();
|
||||
window.MozActivity = MockMozActivity;
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
window.MozActivity = realMozActivity;
|
||||
});
|
||||
|
||||
suite('visibilityChange > ', function() {
|
||||
suite('visible > ', function() {
|
||||
setup(function() {
|
||||
Object.defineProperty(document, 'visibilityState', {
|
||||
value: 'visible',
|
||||
writeable: true,
|
||||
configurable: true
|
||||
});
|
||||
});
|
||||
|
||||
test('should set focus back on current focused element',
|
||||
function(done) {
|
||||
subject.spatialNavigator.focus = done;
|
||||
subject.onVisibilityChange();
|
||||
assert.isTrue(Utils.holdFocusForAnimation.calledOnce);
|
||||
});
|
||||
|
||||
test('should start activity', function(done) {
|
||||
subject.messageHandler.resumeActivity = done;
|
||||
subject.onVisibilityChange();
|
||||
});
|
||||
});
|
||||
|
||||
suite('invisible > ', function() {
|
||||
setup(function() {
|
||||
Object.defineProperty(document, 'visibilityState', {
|
||||
value: 'hidden',
|
||||
writeable: true,
|
||||
configurable: true
|
||||
});
|
||||
});
|
||||
|
||||
test('should stop activity when invisible', function() {
|
||||
var spy = this.sinon.spy(subject.messageHandler, 'stopActivity');
|
||||
subject.onVisibilityChange();
|
||||
assert.isTrue(spy.calledOnce);
|
||||
});
|
||||
|
||||
test('should reset filter', function() {
|
||||
var spy = this.sinon.spy(subject.filterManager, 'resetFilter');
|
||||
subject.onVisibilityChange();
|
||||
assert.isTrue(spy.calledOnce);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('initClock >', function() {
|
||||
test('should set time after time elapsed', function() {
|
||||
subject.initClock();
|
||||
var stub = this.sinon.stub(subject, 'updateClock');
|
||||
fakeTimer.tick(1000);
|
||||
assert.isTrue(stub.calledOnce);
|
||||
});
|
||||
});
|
||||
|
||||
suite('onCardInserted >', function() {
|
||||
test('should insert a card into scrollable', function() {
|
||||
var card1 = new Folder({});
|
||||
var card2 = new Folder({});
|
||||
var stub = this.sinon.stub();
|
||||
var testCase1 = stub.withArgs(sinon.match.truthy, 0);
|
||||
var testCase2 = stub.withArgs(sinon.match.truthy, 1);
|
||||
subject.cardScrollable.insertNodeBefore = stub;
|
||||
|
||||
subject.onCardInserted(subject.cardScrollable, card1, 0);
|
||||
assert.isTrue(testCase1.calledOnce);
|
||||
assert.isFalse(testCase2.calledOnce);
|
||||
subject.onCardInserted(subject.cardScrollable, card2, 1);
|
||||
assert.isTrue(testCase2.calledOnce);
|
||||
});
|
||||
});
|
||||
|
||||
suite('onCardRemoved >', function() {
|
||||
test('should remove specified cards from scrollable', function() {
|
||||
var stub = this.sinon.stub();
|
||||
subject.cardScrollable.removeNodes = stub;
|
||||
subject.onCardRemoved(subject.cardScrollable, [0, 1]);
|
||||
assert.isTrue(stub.withArgs([0, 1]).calledOnce);
|
||||
});
|
||||
});
|
||||
|
||||
suite('onMove >', function() {
|
||||
test('should ask spatial navigator for next focus on non-scrollable target',
|
||||
function() {
|
||||
subject.spatialNavigator.m_focusedElement = document.createElement('div');
|
||||
var stub = this.sinon.stub();
|
||||
subject.spatialNavigator.move = stub;
|
||||
subject.onMove('left');
|
||||
assert.isTrue(stub.calledWith('left'));
|
||||
});
|
||||
|
||||
test('should ask scrollable to move its focus on scrollable target',
|
||||
function() {
|
||||
var scrollable = new XScrollable();
|
||||
scrollable.move = this.sinon.stub();
|
||||
scrollable.move.returns(true);
|
||||
subject.spatialNavigator.m_focusedElement = scrollable;
|
||||
subject.onMove('right');
|
||||
assert.isTrue(scrollable.move.calledWith('right'));
|
||||
});
|
||||
|
||||
test('should ask scrollable to move its focus on scrollable target, but ' +
|
||||
'fall-back to spatial navigator when scrollable didn\'t handle it',
|
||||
function() {
|
||||
var scrollable = new XScrollable();
|
||||
scrollable.move = this.sinon.stub();
|
||||
scrollable.move.returns(false);
|
||||
subject.spatialNavigator.m_focusedElement = scrollable;
|
||||
var spatialNavigatorMoveStub = this.sinon.stub();
|
||||
subject.spatialNavigator.move = spatialNavigatorMoveStub;
|
||||
subject.onMove('up');
|
||||
assert.isTrue(scrollable.move.calledWith('up'));
|
||||
assert.isTrue(spatialNavigatorMoveStub.calledWith('up'));
|
||||
});
|
||||
|
||||
// TODO: add case
|
||||
// 'should bypass logic of onMove if edit.onMove returns true'
|
||||
});
|
||||
|
||||
suite('onEnter >', function() {
|
||||
test('should open settings on settings button', function() {
|
||||
subject.handleFocus(settingsButton);
|
||||
|
||||
assert.equal(MozActivity.calls.length, 0);
|
||||
subject.onEnter();
|
||||
assert.equal(MozActivity.calls[0].name, 'configure');
|
||||
});
|
||||
|
||||
test('should toggle edit mode on edit button', function() {
|
||||
subject.handleFocus(editButton);
|
||||
|
||||
subject.edit.toggleEditMode = this.sinon.stub();
|
||||
subject.onEnter();
|
||||
assert.isTrue(subject.edit.toggleEditMode.calledOnce);
|
||||
});
|
||||
|
||||
test('should launch application on card ', function() {
|
||||
var testCard = document.createElement('div');
|
||||
testCard.dataset.cardId = '123';
|
||||
|
||||
var testApp = new Application({});
|
||||
testApp.launch = this.sinon.stub();
|
||||
subject.cardManager.m_card['123'] = testApp;
|
||||
|
||||
subject.handleFocus(testCard);
|
||||
subject.onEnter();
|
||||
assert.isTrue(testApp.launch.calledOnce);
|
||||
});
|
||||
|
||||
// TODO: add case
|
||||
// 'should bypass logic of onEnter if edit.onEnter returns true'
|
||||
});
|
||||
|
||||
suite('onSearchBarShown >', function() {
|
||||
setup(function() {
|
||||
this.sinon.stub(document, 'addEventListener')
|
||||
.withArgs('visibilitychange').callsArg(1);
|
||||
subject.searchBar.hide = this.sinon.stub();
|
||||
});
|
||||
|
||||
test('should fire search activity', function() {
|
||||
assert.equal(MozActivity.calls.length, 0);
|
||||
subject.onSearchBarShown();
|
||||
assert.equal(MozActivity.calls[0].name, 'search');
|
||||
});
|
||||
|
||||
test('should hide search bar after visibility has changed', function(done) {
|
||||
subject.searchBar.hide = function() {
|
||||
assert.isTrue(true);
|
||||
done();
|
||||
};
|
||||
subject.onSearchBarShown();
|
||||
});
|
||||
});
|
||||
|
||||
suite('onSearchBarHidden >', function() {
|
||||
test('should show search button again', function() {
|
||||
searchButton.classList.add('hidden');
|
||||
subject.onSearchBarHidden();
|
||||
assert.isFalse(searchButton.classList.contains('hidden'));
|
||||
});
|
||||
});
|
||||
|
||||
suite('handleFocus >', function() {
|
||||
test('should switch focus to scrollable target', function() {
|
||||
var spy = this.sinon.spy(subject.cardScrollable, 'focus');
|
||||
subject.handleFocus(subject.cardScrollable);
|
||||
assert.isTrue(spy.calledOnce);
|
||||
});
|
||||
|
||||
test('should switch focus to next focus for normal target', function() {
|
||||
var spy = this.sinon.spy(editButton, 'focus');
|
||||
subject.handleFocus(subject.editButton);
|
||||
assert.isTrue(spy.calledOnce);
|
||||
});
|
||||
|
||||
test('should open menu for menu group target', function() {
|
||||
var stub = this.sinon.stub(subject, 'handleFocusMenuGroup');
|
||||
subject.handleFocus(filterTabGroup);
|
||||
assert.isTrue(stub.calledOnce);
|
||||
});
|
||||
|
||||
test('should call checkFocusedGroup for non-menu elements', function() {
|
||||
var stub = this.sinon.stub(subject, 'checkFocusedGroup');
|
||||
subject.handleFocus(settingsButton);
|
||||
assert.isTrue(stub.withArgs(settingsButton).calledOnce);
|
||||
});
|
||||
});
|
||||
|
||||
suite('checkFocusedGroup >', function() {
|
||||
test('should close group menu when blur', function() {
|
||||
subject.handleFocusMenuGroup(filterTabGroup);
|
||||
var stub = this.sinon.stub(filterTabGroup, 'close');
|
||||
subject.checkFocusedGroup();
|
||||
assert.isTrue(stub.calledOnce);
|
||||
});
|
||||
});
|
||||
|
||||
// TODO: Test items:
|
||||
// handleFocusMenuGroup >
|
||||
// should switch navigable target to child elements of menu on open
|
||||
// should switch navigable target back to menu iteslf on close
|
||||
// handleScrollableItemFocus >
|
||||
// should focus specified item of scrollable
|
||||
// handleScrollableItemUnfocus >
|
||||
// should blur specified item of scrollable
|
||||
// openSettings >
|
||||
// should launch configure activity
|
||||
// updateClock >
|
||||
// should update clock display
|
||||
// restartClock >
|
||||
// should stop and start clock display again
|
||||
});
|
||||
13
gaia/tv_apps/smart-home/test/unit/mock_animations.js
Executable file
13
gaia/tv_apps/smart-home/test/unit/mock_animations.js
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
/* globals evt */
|
||||
|
||||
(function(exports) {
|
||||
'use strict';
|
||||
|
||||
var MockAnimations = evt({
|
||||
init: function() {},
|
||||
doBubbleAnimation: function(parentElem, childClass, length, cb) {
|
||||
cb();
|
||||
}
|
||||
});
|
||||
exports.MockAnimations = MockAnimations;
|
||||
})(window);
|
||||
48
gaia/tv_apps/smart-home/test/unit/mock_card_filter.js
Executable file
48
gaia/tv_apps/smart-home/test/unit/mock_card_filter.js
Executable file
|
|
@ -0,0 +1,48 @@
|
|||
(function(exports) {
|
||||
'use strict';
|
||||
|
||||
var MockCardFilter = function() {
|
||||
this.mEventHandlers = {};
|
||||
};
|
||||
|
||||
MockCardFilter.FILTERS = Object.freeze({
|
||||
'ALL': 'filter',
|
||||
'TV': 'tv',
|
||||
'DASHBOARD': 'dashboard',
|
||||
'DEVICE': 'device',
|
||||
'APPLICATION': 'application'
|
||||
});
|
||||
|
||||
MockCardFilter.prototype = {
|
||||
start: function() {},
|
||||
stop: function() {},
|
||||
on: function(eventName, callback) {
|
||||
if (typeof callback === 'function') {
|
||||
if (!this.mEventHandlers[eventName]) {
|
||||
this.mEventHandlers[eventName] = [];
|
||||
}
|
||||
this.mEventHandlers[eventName].push(callback);
|
||||
}
|
||||
|
||||
},
|
||||
off: function(eventName, callback) {
|
||||
var handlers = this.mEventHandlers[eventName];
|
||||
if (typeof callback === 'function' && handlers) {
|
||||
var index = handlers.indexOf(callback);
|
||||
handlers.splice(index, 1);
|
||||
}
|
||||
},
|
||||
mFireEvent: function(eventName, detail) {
|
||||
var handlers = this.mEventHandlers[eventName];
|
||||
if (handlers) {
|
||||
handlers.forEach(function(callback) {
|
||||
if (typeof callback === 'function') {
|
||||
callback(detail);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.MockCardFilter = MockCardFilter;
|
||||
}(window));
|
||||
40
gaia/tv_apps/smart-home/test/unit/mock_card_manager.js
Executable file
40
gaia/tv_apps/smart-home/test/unit/mock_card_manager.js
Executable file
|
|
@ -0,0 +1,40 @@
|
|||
/* global Promise */
|
||||
(function(exports) {
|
||||
'use strict';
|
||||
|
||||
var MockCardManager = function() {};
|
||||
|
||||
MockCardManager.prototype = {
|
||||
_cardList: [],
|
||||
m_card: {},
|
||||
|
||||
init: function() {
|
||||
return null;
|
||||
},
|
||||
|
||||
mPrepareFilteredCardList: function(filteredCardList) {
|
||||
this.mFilteredCardList = filteredCardList;
|
||||
},
|
||||
|
||||
getFilteredCardList: function(name) {
|
||||
var that = this;
|
||||
return new Promise(function(resolve, reject) {
|
||||
resolve(that.mFilteredCardList);
|
||||
});
|
||||
},
|
||||
|
||||
getCardList: function getCardList() {
|
||||
return Promise.resolve(this._cardList);
|
||||
},
|
||||
|
||||
findCardFromCardList: function(param) {
|
||||
return this.m_card[param.cardId];
|
||||
},
|
||||
|
||||
resolveCardName: function() {
|
||||
return 'cardname';
|
||||
}
|
||||
};
|
||||
|
||||
exports.MockCardManager = MockCardManager;
|
||||
}(window));
|
||||
16
gaia/tv_apps/smart-home/test/unit/mock_edit.js
Executable file
16
gaia/tv_apps/smart-home/test/unit/mock_edit.js
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
/* globals evt */
|
||||
|
||||
(function(exports) {
|
||||
'use strict';
|
||||
|
||||
var MockEdit = function() {
|
||||
};
|
||||
|
||||
MockEdit.prototype = evt({
|
||||
init: function() {},
|
||||
onMove: function() { return false; },
|
||||
onEnter: function() {return false; }
|
||||
});
|
||||
|
||||
exports.MockEdit = MockEdit;
|
||||
})(window);
|
||||
15
gaia/tv_apps/smart-home/test/unit/mock_filter_manager.js
Executable file
15
gaia/tv_apps/smart-home/test/unit/mock_filter_manager.js
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
(function(exports) {
|
||||
'use strict';
|
||||
|
||||
var MockFilterManager = function() {};
|
||||
|
||||
MockFilterManager.prototype = {
|
||||
init: function() {
|
||||
return null;
|
||||
},
|
||||
|
||||
resetFilter: function() {}
|
||||
};
|
||||
|
||||
exports.MockFilterManager = MockFilterManager;
|
||||
}(window));
|
||||
15
gaia/tv_apps/smart-home/test/unit/mock_home.js
Executable file
15
gaia/tv_apps/smart-home/test/unit/mock_home.js
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
(function(exports) {
|
||||
'use strict';
|
||||
|
||||
var MockHome = function() {};
|
||||
|
||||
MockHome.prototype = {
|
||||
edit: {
|
||||
on: function() {},
|
||||
off: function() {}
|
||||
},
|
||||
createCardNode: function() {}
|
||||
};
|
||||
|
||||
exports.MockHome = MockHome;
|
||||
}(window));
|
||||
15
gaia/tv_apps/smart-home/test/unit/mock_menu_group.js
Executable file
15
gaia/tv_apps/smart-home/test/unit/mock_menu_group.js
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
/* global MockEventTarget */
|
||||
(function(exports) {
|
||||
'use strict';
|
||||
|
||||
var MockMenuGroup = function() {};
|
||||
MockMenuGroup.prototype = Object.create(MockEventTarget.prototype);
|
||||
MockMenuGroup.prototype.changeIcon = function() {};
|
||||
MockMenuGroup.prototype.querySelectorAll = function() {};
|
||||
MockMenuGroup.prototype.classList = {
|
||||
add: function() {},
|
||||
remove: function() {}
|
||||
};
|
||||
|
||||
exports.MockMenuGroup = MockMenuGroup;
|
||||
}(window));
|
||||
11
gaia/tv_apps/smart-home/test/unit/mock_message_handler.js
Executable file
11
gaia/tv_apps/smart-home/test/unit/mock_message_handler.js
Executable file
|
|
@ -0,0 +1,11 @@
|
|||
'use strict';
|
||||
|
||||
var MockMessageHandler = function() {
|
||||
|
||||
};
|
||||
|
||||
MockMessageHandler.prototype = {
|
||||
init: function() {},
|
||||
stopActivity: function() {},
|
||||
resumeActivity: function() { return false; }
|
||||
};
|
||||
14
gaia/tv_apps/smart-home/test/unit/mock_search_bar.js
Executable file
14
gaia/tv_apps/smart-home/test/unit/mock_search_bar.js
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
/* globals evt */
|
||||
|
||||
(function(exports) {
|
||||
'use strict';
|
||||
|
||||
var MockSearchBar = function() {
|
||||
};
|
||||
|
||||
MockSearchBar.prototype = evt({
|
||||
init: function() {}
|
||||
});
|
||||
|
||||
exports.MockSearchBar = MockSearchBar;
|
||||
})(window);
|
||||
17
gaia/tv_apps/smart-home/test/unit/mock_smart_button.js
Executable file
17
gaia/tv_apps/smart-home/test/unit/mock_smart_button.js
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
/* global MockEventTarget */
|
||||
(function(exports) {
|
||||
'use strict';
|
||||
|
||||
var MockSmartButton = function(iconType) {
|
||||
this.dataset = {
|
||||
iconType: iconType
|
||||
};
|
||||
this.classList = {
|
||||
add: function() {},
|
||||
remove: function() {}
|
||||
};
|
||||
};
|
||||
MockSmartButton.prototype = Object.create(MockEventTarget.prototype);
|
||||
|
||||
exports.MockSmartButton = MockSmartButton;
|
||||
}(window));
|
||||
12
gaia/tv_apps/smart-home/test/unit/mock_utils.js
Executable file
12
gaia/tv_apps/smart-home/test/unit/mock_utils.js
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
(function(exports) {
|
||||
'use strict';
|
||||
|
||||
var MockUtils = {
|
||||
mHoldFocusForAnimationCalled: false,
|
||||
holdFocusForAnimation: sinon.stub(),
|
||||
mTeardown: function() {
|
||||
this.holdFocusForAnimation = sinon.stub();
|
||||
}
|
||||
};
|
||||
exports.MockUtils = MockUtils;
|
||||
})(window);
|
||||
27
gaia/tv_apps/smart-home/test/unit/mock_x_scrollable.js
Executable file
27
gaia/tv_apps/smart-home/test/unit/mock_x_scrollable.js
Executable file
|
|
@ -0,0 +1,27 @@
|
|||
/* globals evt */
|
||||
|
||||
(function(exports) {
|
||||
'use strict';
|
||||
|
||||
var MockXScrollable = function() {
|
||||
this.currentItem = document.createElement('button');
|
||||
};
|
||||
|
||||
MockXScrollable.prototype = evt({
|
||||
m_items: [],
|
||||
m_colspan: 0,
|
||||
CLASS_NAME: 'XScrollable',
|
||||
addNode: function() {},
|
||||
resetScroll: function() {},
|
||||
clean: function() {},
|
||||
getNode: function(index) {
|
||||
return this.m_items[index];
|
||||
},
|
||||
setColspanOnFocus: function(colspan) {
|
||||
this.m_colspan = colspan;
|
||||
},
|
||||
focus: function() {}
|
||||
});
|
||||
|
||||
exports.MockXScrollable = MockXScrollable;
|
||||
}(window));
|
||||
4
gaia/tv_apps/smart-home/test/unit/setup.js
Executable file
4
gaia/tv_apps/smart-home/test/unit/setup.js
Executable file
|
|
@ -0,0 +1,4 @@
|
|||
'use strict';
|
||||
|
||||
/* global require */
|
||||
require('/shared/test/unit/mocks/mocks_helper.js');
|
||||
Loading…
Reference in a new issue