VulpesOS/gaia/apps/homescreen/test/unit/pages_test.js
OverSu b38dea0597 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.
2026-09-30 23:13:03 +02:00

414 lines
12 KiB
JavaScript
Executable file

/* jshint nonew: false */
/* global Pages, PagesStore */
'use strict';
require('/shared/test/unit/load_body_html_helper.js');
require('mocks/mock_datastore.js');
require('/js/pages.js');
suite('Pages', () => {
var pages;
setup(() => {
window.PagesStore = window.Datastore;
loadBodyHTML('_index.html');
pages = new Pages();
});
suite('Pages constructor', () => {
var stub;
teardown(() => {
stub.restore();
});
test('should initialise the pages store', done => {
stub = sinon.stub(PagesStore.prototype, 'init', () => {
done();
return Promise.reject();
});
new Pages();
});
test('should get the list of pinned pages', done => {
stub = sinon.stub(PagesStore.prototype, 'getAll', () => {
done();
return Promise.reject();
});
new Pages();
});
test('should mark the pages panel empty if no pages', done => {
stub = sinon.stub(PagesStore.prototype, 'getAll', () => {
return { then: callback => {
callback([]);
done(() => {
assert.isTrue(document.getElementById('pages-panel').classList.
contains('empty'));
});
}};
});
new Pages();
});
});
suite('Pages#addPinnedPage()', () => {
var pinCard;
var createElementStub;
var updatePinnedPageStub;
var appendChildStub;
setup(() => {
pinCard = document.createElement('div');
createElementStub = sinon.stub(document, 'createElement', () => pinCard);
updatePinnedPageStub = sinon.stub(pages, 'updatePinnedPage');
appendChildStub = sinon.stub(pages.pages, 'appendChild');
});
teardown(() => {
createElementStub.restore();
updatePinnedPageStub.restore();
appendChildStub.restore();
});
test('should remove .empty from the pages panel', () => {
var pagesPanel = document.getElementById('pages-panel');
assert.isTrue(pages.empty);
assert.isTrue(pagesPanel.classList.contains('empty'));
pages.addPinnedPage();
assert.isFalse(pages.empty);
assert.isFalse(pagesPanel.classList.contains('empty'));
});
test('should add a card to the pages list', () => {
pages.addPinnedPage();
assert.isTrue(createElementStub.calledWith('gaia-pin-card'));
assert.isTrue(updatePinnedPageStub.calledOnce);
assert.isTrue(appendChildStub.calledOnce);
});
test('should make card accessible', () => {
pages.addPinnedPage();
assert.equal(pinCard.tabIndex, 0);
assert.equal(pinCard.getAttribute('role'), 'link');
});
});
suite('Pages#updatePinnedPage()', () => {
var clock;
var createObjectURLStub;
var mockPinnedPage = {
title: 'Mock pinned page',
url: 'Mock URL',
pinTime: 4242,
screenshot: 'Mock screenshot',
meta: {
'theme-color': 'Mock color'
}
};
var mockCard = {
title: null,
dataset: { id: null },
style: { order: 0 },
background: null,
meta: null,
icon: null
};
var mockIconBlob = 'Mock icon blob';
setup(() => {
clock = sinon.useFakeTimers();
createObjectURLStub = sinon.stub(URL, 'createObjectURL', blob => blob);
});
teardown(() => {
clock.restore();
createObjectURLStub.restore();
});
test('should set title, url and order', () => {
pages.updatePinnedPage(mockCard, mockPinnedPage);
assert.equal(mockCard.title, mockPinnedPage.title);
assert.equal(mockCard.dataset.id, mockPinnedPage.url);
var pinTime = -Math.round(mockPinnedPage.pinTime / 1000);
assert.equal(mockCard.style.order, pinTime);
});
test('should set screenshot, themeColor and icon after timeout', done => {
window.IconsHelper = {
getIconBlob: (url, size, page) => {
return {
then: (callback) => {
callback({ blob: mockIconBlob });
assert.equal(mockCard.icon, 'url(' + mockIconBlob + ')');
done();
return { catch: () => {} };
}
};
}
};
pages.updatePinnedPage(mockCard, mockPinnedPage);
clock.tick();
var meta = mockCard.meta;
assert.equal(meta['theme-color'], mockPinnedPage.meta['theme-color']);
assert.equal(meta.screenshot, mockPinnedPage.screenshot);
});
});
suite('Pages#enterEditMode()', () => {
var mockCard;
setup(() => {
mockCard = document.createElement('div');
pages.enterEditMode(mockCard);
});
teardown(() => {
pages.exitEditMode();
});
test('card is marked as selected', () => {
assert.isTrue(mockCard.classList.contains('selected'));
});
test('document is marked as in edit-mode', () => {
assert.isTrue(document.body.classList.contains('edit-mode'));
});
test('delete button is activated', () => {
assert.isTrue(pages.remove.classList.contains('active'));
});
test('previous card is unselected', () => {
var mockCard2 = document.createElement('div');
pages.enterEditMode(mockCard2);
assert.isFalse(mockCard.classList.contains('selected'));
assert.isTrue(mockCard2.classList.contains('selected'));
});
});
suite('Pages#exitEditMode()', () => {
var mockCard;
setup(() => {
mockCard = document.createElement('div');
pages.enterEditMode(mockCard);
pages.exitEditMode();
});
test('card is not marked as selected', () => {
assert.isFalse(mockCard.classList.contains('selected'));
assert.equal(pages.selectedCard, null);
});
test('document is not marked as in edit-mode', () => {
assert.isFalse(document.body.classList.contains('edit-mode'));
});
test('delete button is not activated', () => {
assert.isFalse(pages.remove.classList.contains('active'));
});
});
suite('Pages#removeCard()', () => {
var mockCard;
setup(() => {
mockCard = document.createElement('div');
});
test('removes child from container', () => {
var removeStub = sinon.stub(pages.pages, 'removeChild');
pages.removeCard(mockCard);
assert.isTrue(removeStub.calledWith(mockCard));
});
test('deselects card if card is selected', () => {
pages.selectedCard = mockCard;
var removeStub = sinon.stub(pages.pages, 'removeChild');
pages.removeCard(mockCard);
assert.equal(pages.selectedCard, null);
removeStub.restore();
});
test('shows the empty pinned pages panel when removing last card', done => {
pages.empty = false;
Object.defineProperty(pages.pages, 'children', {
value: { length: 0 },
configurable: true
});
var removeChildStub = sinon.stub(pages.pages, 'removeChild',
(card, callback) => {
callback();
done(() => {
delete pages.pages.children;
removeChildStub.restore();
assert.isTrue(pages.empty);
assert.isTrue(pages.panel.classList.contains('empty'));
});
});
pages.removeCard(mockCard);
});
test('exits edit mode when removing last card', done => {
pages.empty = false;
pages.editMode = true;
Object.defineProperty(pages.pages, 'children', {
value: { length: 0 },
configurable: true
});
var removeChildStub = sinon.stub(pages.pages, 'removeChild',
(card, callback) => {
callback();
done(() => {
delete pages.pages.children;
removeChildStub.restore();
assert.isFalse(pages.editMode);
});
});
pages.removeCard(mockCard);
});
});
suite('Pages#unpinSelectedCard()', () => {
var removeCardStub, storeGetStub, storePutStub, mockEntry, callback;
var mockCard = {
dataset: {
id: 'abc'
}
};
setup(() => {
mockEntry = { data: { pinned: true } };
removeCardStub = sinon.stub(pages, 'removeCard');
storeGetStub =
sinon.stub(pages.pagesStore, 'get', () => {
return Promise.resolve(mockEntry);
});
storePutStub =
sinon.stub(pages.pagesStore.datastore, 'put', (data, id) => {
if (callback) {
callback(data, id);
}
return Promise.resolve();
});
pages.selectedCard = mockCard;
});
teardown(() => {
removeCardStub.restore();
storeGetStub.restore();
storePutStub.restore();
pages.selectedCard = null;
});
test('removes card from container', () => {
pages.unpinSelectedCard();
assert.isTrue(removeCardStub.calledWith(mockCard));
});
test('unpins card in datastore', done => {
callback = (data, id) => {
done(() => {
assert.equal(id, mockCard.dataset.id);
assert.isFalse(mockEntry.data.pinned);
});
};
pages.unpinSelectedCard();
});
});
suite('Pages#handleEvent()', () => {
var mockCard = {
nodeName: 'GAIA-PIN-CARD',
title: 'Mock title',
icon: 'Mock icon',
dataset: {
id: 'Mock URL'
}
};
var mockNotCard = {
nodeName: 'MOCK-NOT-CARD'
};
suite('click', () => {
test('clicking a card should launch a remote window', () => {
var windowOpenStub = sinon.stub(window, 'open',
(url, target, features) => {
assert.equal(url, mockCard.dataset.id);
assert.equal(target, '_blank');
var expectedFeatures = {
name: mockCard.title,
icon: mockCard.icon,
remote: true
};
expectedFeatures = Object.keys(expectedFeatures).
map(function eachFeature(key) {
return encodeURIComponent(key) + '=' +
encodeURIComponent(expectedFeatures[key]);
}).join(',');
assert.equal(features, expectedFeatures);
});
pages.handleEvent({ type: 'click', target: mockCard });
windowOpenStub.restore();
});
test('clicking outside a card should do nothing', () => {
var windowOpenStub = sinon.stub(window, 'open');
pages.handleEvent({ type: 'click', target: mockNotCard });
assert.isFalse(windowOpenStub.called);
windowOpenStub.restore();
});
test('pressing a card in edit mode selects it', () => {
var editModeStub = sinon.stub(pages, 'enterEditMode');
pages.editMode = true;
pages.handleEvent({ type: 'click', target: mockCard });
assert.isTrue(editModeStub.calledWith(mockCard));
editModeStub.restore();
});
test('pressing delete in edit mode unpins a card', () => {
var unpinStub = sinon.stub(pages, 'unpinSelectedCard');
pages.selectedCard = mockCard;
pages.remove.dispatchEvent(new CustomEvent('click'));
assert.isTrue(unpinStub.called);
});
});
suite('contextmenu', () => {
var editModeStub;
setup(() => {
editModeStub = sinon.stub(pages, 'enterEditMode');
});
teardown(() => {
editModeStub.restore();
});
test('long-pressing a card initiates edit mode', () => {
pages.handleEvent({ type: 'contextmenu', target: mockCard });
assert.isTrue(editModeStub.calledWith(mockCard));
});
test('long-pressing not on a card does nothing', () => {
pages.handleEvent({ type: 'contextmenu', target: mockNotCard });
assert.isFalse(editModeStub.called);
});
});
suite('resize', () => {
test('should call pages.synchronise()', () => {
var synchroniseCalled = false;
pages.pages.synchronise = () => { synchroniseCalled = true; };
pages.handleEvent(new CustomEvent('resize'));
assert.isTrue(synchroniseCalled);
});
});
});
});