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:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View file

@ -0,0 +1,519 @@
'use strict';
/* global WallpaperManager, MockLazyLoader, ImageUtils,
MockNavigatorSettings, MockService, MocksHelper */
require('/shared/test/unit/mocks/mock_navigator_moz_settings.js');
require('/shared/js/image_utils.js');
require('/apps/system/js/wallpaper_manager.js');
require('/shared/test/unit/mocks/mock_service.js');
requireApp('system/test/unit/mock_lazy_loader.js');
var mocksForWallpaperManager = new MocksHelper([
'Service',
'LazyLoader'
]).init();
suite('WallpaperManager', function() {
mocksForWallpaperManager.attachTestHelpers();
var subject; // The WallpaperManager instance we're testing.
var wallpaperBlob, bigWallpaperBlob, smallWallpaperBlob;
var dataURL, bigDataURL, smallDataURL, mockPublish;
const DEFAULT_WALLPAPER = 'resources/images/backgrounds/default.png';
suiteSetup(function(done) {
var self = this;
var sw, sh;
// Don't display debug output
WallpaperManager.DEBUG = false;
// Fake URLs. Our xhr mock will recognize these strings and return blobs
dataURL = 'data://justright';
bigDataURL = 'data://toobig';
smallDataURL = 'data://toosmall';
// Map urls to blobs for the fake XHR
var urlToBlobMap = this.urlToBlobMap = {};
this.xhr = sinon.useFakeXMLHttpRequest();
this.xhr.onCreate = function(request) {
setTimeout(function() {
var blob = urlToBlobMap[request.url];
if (blob) {
request.response = blob;
request.onload();
}
else {
request.onerror();
}
});
};
// How big (in device pixels) is the screen in its default orientation?
if (MockService.mockQueryWith('isDefaultPortrait')) {
sw = Math.max(screen.width, screen.height);
sh = Math.min(screen.width, screen.height);
} else {
// Otherwise, the width is the smaller dimension
sw = Math.min(screen.width, screen.height);
sh = Math.max(screen.width, screen.height);
}
this.screenWidth = sw * window.devicePixelRatio;
this.screenHeight = sh * window.devicePixelRatio;
// Create some image blobs
var canvas = document.createElement('canvas');
canvas.width = this.screenWidth;
canvas.height = this.screenHeight;
canvas.toBlob(function(blob) {
wallpaperBlob = blob;
canvas.width = self.screenWidth + 1;
canvas.height = self.screenHeight + 1;
canvas.toBlob(function(blob) {
bigWallpaperBlob = blob;
canvas.width = self.screenWidth >> 1;
canvas.height = self.screenHeight >> 1;
canvas.toBlob(function(blob) {
smallWallpaperBlob = blob;
// Now that we have the images defined, set up the URL mapping
urlToBlobMap[DEFAULT_WALLPAPER] = wallpaperBlob;
urlToBlobMap[dataURL] = wallpaperBlob;
urlToBlobMap[bigDataURL] = bigWallpaperBlob;
urlToBlobMap[smallDataURL] = smallWallpaperBlob;
done();
}, 'image/jpeg');
}, 'image/jpeg');
}, 'image/jpeg');
});
suiteTeardown(function() {
this.xhr.restore();
});
setup(function() {
this.sinon.stub(document, 'getElementById', function() {
return document.createElement('div');
});
var self = this;
// Mock settings
this.realMozSettings = navigator.mozSettings;
navigator.mozSettings = MockNavigatorSettings;
mockPublish = function(e) {
if (self.onWallpaperChange) {
setTimeout(function() {
if (self.onWallpaperChange) {
self.onWallpaperChange('wallpaperchange', e.detail);
}
});
}
};
window.addEventListener('wallpaperchange', mockPublish);
this.sinon.spy(MockLazyLoader, 'load');
// Spy on WallpaperManager methods
var proto = WallpaperManager.prototype;
this.setWallpaperSpy = sinon.spy(proto, '_setWallpaper');
this.toBlobSpy = sinon.spy(proto, '_toBlob');
this.checkSizeSpy = sinon.spy(proto, '_checkSize');
this.saveSpy = sinon.spy(proto, '_save');
this.validateSpy = sinon.spy(proto, '_validate');
this.publishSpy = sinon.spy(proto, '_publish');
subject = new WallpaperManager();
});
teardown(function() {
subject.stop();
this.setWallpaperSpy.restore();
this.toBlobSpy.restore();
this.checkSizeSpy.restore();
this.saveSpy.restore();
this.validateSpy.restore();
this.publishSpy.restore();
window.removeEventListener('wallpaperchange', mockPublish);
navigator.mozSettings = this.realMozSettings;
MockNavigatorSettings.mTeardown();
MockService.mockQueryWith('isDefaultPortrait', true);
this.onWallpaperChange = null;
});
test('start() throws if called twice', function() {
subject.start();
assert.throws(function() { subject.start(); });
});
//
// Test normal startup where we have a validated wallpaper blob in
// the settings db. Verify that a wallpaperchange event is published
// with a blob uri, and that the size of the image is not checked
// or changed, and that the lazy loader is not invoked.
//
test('start with validated blob', function(done) {
var self = this;
// Start with a validated blob in the settings db
MockNavigatorSettings.mSettings['wallpaper.image'] = wallpaperBlob;
MockNavigatorSettings.mSettings['wallpaper.image.valid'] = true;
// We do our assertions once we see a wallpaperchange event published.
this.onWallpaperChange = function(type, data) {
done(() => {
// Check event type
assert.equal(type, 'wallpaperchange');
// Check that we get a blob url
assert.equal(data.url.substring(0, 5), 'blob:');
// Check that the methods were called the expected number of times
sinon.assert.calledOnce(self.setWallpaperSpy);
sinon.assert.notCalled(self.toBlobSpy);
sinon.assert.notCalled(MockLazyLoader.load);
sinon.assert.notCalled(self.checkSizeSpy);
sinon.assert.notCalled(self.saveSpy);
sinon.assert.calledOnce(self.publishSpy);
});
};
subject.start();
});
//
// Test normal startup followed by a change to a new wallpaper blob that
// is too small. Verify that the wallpaper is changed and that the
// resulting wallpaper has the expected size and type. And that the
// LazyLoader is used
//
test('change to new small wallpaper blob', function(done) {
var self = this;
// Start with a validated blob in the settings db
MockNavigatorSettings.mSettings['wallpaper.image'] = wallpaperBlob;
MockNavigatorSettings.mSettings['wallpaper.image.valid'] = true;
// Wait 'till the initial wallpaper is published
this.onWallpaperChange = function(type, data) {
// Test assertions when we get the changed wallpaper
self.onWallpaperChange = function(type, data) {
// Check event type
assert.equal(type, 'wallpaperchange');
// Check that we get a blob url
assert.equal(data.url.substring(0, 5), 'blob:');
// Check that the methods were called the expected number of times
// 3 times: initial, changed, and saved wallpapers
assert.equal(self.setWallpaperSpy.callCount, 3);
assert.ok(self.toBlobSpy.notCalled, '_toBlob called');
assert.ok(MockLazyLoader.load.calledOnce);
assert.ok(self.checkSizeSpy.calledOnce, 'checkSize called');
assert.ok(self.saveSpy.calledOnce, 'save called');
assert.ok(self.validateSpy.notCalled,
'validate not called');
assert.equal(self.publishSpy.callCount, 2, 'publish called');
assert.notEqual(MockNavigatorSettings.mSettings['wallpaper.image'],
smallWallpaperBlob);
assert.notEqual(MockNavigatorSettings.mSettings['wallpaper.image'],
wallpaperBlob);
assert.equal(MockNavigatorSettings.mSettings['wallpaper.image.valid'],
true);
var blob = MockNavigatorSettings.mSettings['wallpaper.image'];
assert.equal(blob.type, ImageUtils.PNG);
ImageUtils.getSizeAndType(blob).then(function resolve(data) {
assert.equal(data.type, ImageUtils.PNG);
assert.equal(data.width, self.screenWidth);
assert.equal(data.height, self.screenHeight);
done();
});
};
navigator.mozSettings.createLock().set({
'wallpaper.image': smallWallpaperBlob
});
};
subject.start();
});
//
// Test normal startup followed by a change to a new wallpaper blob that
// is the right size. Verify that the wallpaper is changed and that the
// resulting wallpaper has the expected size and type. And that the
// LazyLoader is used
//
test('change to new right-size wallpaper blob', function(done) {
var self = this;
// Start with a validated blob in the settings db
MockNavigatorSettings.mSettings['wallpaper.image'] = wallpaperBlob;
MockNavigatorSettings.mSettings['wallpaper.image.valid'] = true;
// Wait 'till the initial wallpaper is published
this.onWallpaperChange = function(type, data) {
// Test assertions when we get the changed wallpaper
self.onWallpaperChange = function(type, data) {
// Check event type
assert.equal(type, 'wallpaperchange');
// Check that we get a blob url
assert.equal(data.url.substring(0, 5), 'blob:');
// Check that the methods were called the expected number of times
assert.equal(self.setWallpaperSpy.callCount, 2);
assert.ok(self.toBlobSpy.notCalled, '_toBlob called');
assert.ok(MockLazyLoader.load.calledOnce);
assert.ok(self.checkSizeSpy.calledOnce, 'checkSize called');
assert.ok(self.saveSpy.notCalled, 'save not called');
assert.ok(self.validateSpy.calledOnce, 'validate called');
assert.equal(self.publishSpy.callCount, 2, 'publish called');
assert.equal(MockNavigatorSettings.mSettings['wallpaper.image'],
wallpaperBlob);
assert.equal(MockNavigatorSettings.mSettings['wallpaper.image.valid'],
true);
done();
};
navigator.mozSettings.createLock().set({
'wallpaper.image': wallpaperBlob
});
};
subject.start();
});
//
// Test the startup process with a blob that has not been validated yet.
// This seems to be what happens on first boot (Somewhere in the build
// system the data uri is converted to a real blob.)
//
test('start with non-validated right-size blob', function(done) {
var self = this;
// Start with an unvalidated blob in the settings db
MockNavigatorSettings.mSettings['wallpaper.image'] = wallpaperBlob;
// We do our assertions once we see a wallpaperchange event published.
this.onWallpaperChange = function(type, data) {
// Check event type
assert.equal(type, 'wallpaperchange');
// Check that we get a blob url
assert.equal(data.url.substring(0, 5), 'blob:');
// Check that the methods were called the expected number of times
assert.ok(self.setWallpaperSpy.calledOnce);
assert.ok(self.toBlobSpy.notCalled);
assert.ok(MockLazyLoader.load.calledOnce);
assert.ok(self.checkSizeSpy.calledOnce);
assert.ok(self.saveSpy.notCalled);
assert.ok(self.validateSpy.calledOnce);
assert.ok(self.publishSpy.calledOnce);
assert.equal(MockNavigatorSettings.mSettings['wallpaper.image'],
wallpaperBlob);
assert.equal(MockNavigatorSettings.mSettings['wallpaper.image.valid'],
true);
done();
};
subject.start();
});
//
// Test the startup process with a blob that has not been validated yet
// and is not the right size. (This happens on first boot if we use a
// FWVGA wallpaper on an WVGA device or vice versa, e.g.)
//
test('start with non-validated wrong-size blob', function(done) {
var self = this;
// Start with an unvalidated blob in the settings db
MockNavigatorSettings.mSettings['wallpaper.image'] = bigWallpaperBlob;
// We do our assertions once we see a wallpaperchange event published.
this.onWallpaperChange = function(type, data) {
// Check event type
assert.equal(type, 'wallpaperchange');
// Check that we get a blob url
assert.equal(data.url.substring(0, 5), 'blob:');
// Check that the methods were called the expected number of times
assert.ok(self.toBlobSpy.notCalled, '_toBlob not called');
assert.ok(MockLazyLoader.load.calledOnce);
assert.ok(self.checkSizeSpy.calledOnce, 'checkSize called');
assert.ok(self.saveSpy.calledOnce, 'save called');
assert.ok(self.validateSpy.notCalled, 'validate not called');
assert.ok(self.publishSpy.calledOnce, 'publish called');
assert.notEqual(MockNavigatorSettings.mSettings['wallpaper.image'],
wallpaperBlob);
assert.equal(MockNavigatorSettings.mSettings['wallpaper.image.valid'],
true);
var blob = MockNavigatorSettings.mSettings['wallpaper.image'];
assert.equal(blob.type, ImageUtils.PNG);
ImageUtils.getSizeAndType(blob).then(function resolve(data) {
assert.equal(data.type, ImageUtils.PNG);
assert.equal(data.width, self.screenWidth);
assert.equal(data.height, self.screenHeight);
done();
});
};
subject.start();
});
//
// Test changed wallpaper in landscape orientation. Verify that
// the wallpaper is resized and that the resulting wallpaper has
// the expected size.
//
test('start and change wallpaper in landscape mode', function(done) {
var self = this;
MockService.mockQueryWith('isDefaultPortrait', false);
// Start with a validated blob in the settings db
MockNavigatorSettings.mSettings['wallpaper.image'] = wallpaperBlob;
MockNavigatorSettings.mSettings['wallpaper.image.valid'] = true;
// Wait 'till the initial wallpaper is published
this.onWallpaperChange = function(type, data) {
// Test assertions when we get the changed wallpaper
self.onWallpaperChange = function(type, data) {
// Check event type
assert.equal(type, 'wallpaperchange');
// Check that we get a blob url
assert.equal(data.url.substring(0, 5), 'blob:');
// Check that the methods were called the expected number of times
// 3 times: initial, changed, and saved wallpapers
assert.equal(self.setWallpaperSpy.callCount, 3);
assert.ok(self.toBlobSpy.notCalled, '_toBlob not called');
assert.ok(MockLazyLoader.load.calledOnce);
assert.ok(self.checkSizeSpy.calledOnce, 'checkSize called');
assert.ok(self.saveSpy.calledOnce, 'save called');
assert.ok(self.validateSpy.notCalled,
'validate not called');
assert.equal(self.publishSpy.callCount, 2, 'publish called');
assert.notEqual(MockNavigatorSettings.mSettings['wallpaper.image'],
wallpaperBlob);
assert.equal(MockNavigatorSettings.mSettings['wallpaper.image.valid'],
true);
var blob = MockNavigatorSettings.mSettings['wallpaper.image'];
ImageUtils.getSizeAndType(blob).then(function resolve(data) {
// Check the resized wallpaper in landscape orientation to have
// width as bigger dimension that equals screenHeight.
assert.equal(data.width, self.screenHeight);
assert.equal(data.height, self.screenWidth);
done();
});
};
navigator.mozSettings.createLock().set({
'wallpaper.image': wallpaperBlob
});
};
subject.start();
});
//
// The tests that follow call this utility function and test what happens
// when we use URLs and invalid values as the wallpaper value.
//
function testWallpaperValue(self, input, expectedOutput, done,
toBlobCallCount,
checkSizeCallCount) {
MockNavigatorSettings.mSettings['wallpaper.image'] = input;
// We do our assertions once we see a wallpaperchange event published.
self.onWallpaperChange = function(type, data) {
try {
// Check that the methods were called the expected number of times
assert.equal(self.toBlobSpy.callCount,
toBlobCallCount || 1,
'convert to blob call count');
assert.ok(MockLazyLoader.load.called,
'lazy loader used');
assert.equal(self.checkSizeSpy.callCount,
checkSizeCallCount || 1,
'check wallpaper called');
assert.ok(self.saveSpy.calledOnce,
'save called once');
assert.ok(self.publishSpy.calledOnce, 'publish called once');
assert.equal(MockNavigatorSettings.mSettings['wallpaper.image.valid'],
true);
var blob = MockNavigatorSettings.mSettings['wallpaper.image'];
if (expectedOutput) {
assert.equal(blob, expectedOutput, 'saved blob is as expected');
done();
}
else {
ImageUtils.getSizeAndType(blob).then(function resolve(data) {
assert.equal(data.width, self.screenWidth);
assert.equal(data.height, self.screenHeight);
done();
})['catch'](function(err) {
assert.isFalse(err);
});
}
}
catch(ex) {
done(ex);
}
};
subject.start();
}
// No value in the settings db at all
test('undefined wallpaper', function(done) {
testWallpaperValue(this, undefined, wallpaperBlob, done);
});
// Non-blob, non-URL value in the settings db
test('invalid wallpaper', function(done) {
testWallpaperValue(this, 1, wallpaperBlob, done);
});
// default wallpaper url in settings db
test('default wallpaper url', function(done) {
testWallpaperValue(this, DEFAULT_WALLPAPER, wallpaperBlob, done);
});
// Data url that resolves to a right-size image
test('right-size data uri', function(done) {
testWallpaperValue(this, this.dataURL, wallpaperBlob, done);
});
// Data url that resolves to a small image
test('small data uri', function(done) {
testWallpaperValue(this, this.smallDataURL, null, done);
});
// Data url that resolves to a big image
test('big data uri', function(done) {
testWallpaperValue(this, this.bigDataURL, null, done);
});
// URL that causes an XHR error and forces fallback on default
test('broken URL', function(done) {
testWallpaperValue(this, '/foo/bar', wallpaperBlob, done, 2);
});
// Invalid image blob that forces fallback on default
test('broken image blob', function(done) {
var badBlob = new Blob(['GIF89a'], { type: 'image/gif' });
testWallpaperValue(this, badBlob, wallpaperBlob, done, 1, 2);
});
// default wallpaper is wrong size
test('default wallpaper url', function(done) {
this.urlToBlobMap[DEFAULT_WALLPAPER] = smallWallpaperBlob;
testWallpaperValue(this, DEFAULT_WALLPAPER, null, done);
});
});