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,504 @@
suite('controllers/settings', function() {
/*jshint maxlen:false*/
'use strict';
suiteSetup(function(done) {
var self = this;
requirejs([
'controllers/settings',
'lib/settings',
'lib/setting',
'app',
'views/notification',
'views/settings'
], function(
SettingsController, Settings, Setting,
App, NotificationViews, SettingsView) {
self.SettingsController = SettingsController.SettingsController;
self.NotificationViews = NotificationViews;
self.SettingsView = SettingsView;
self.Settings = Settings;
self.Setting = Setting;
self.App = App;
done();
});
});
setup(function() {
var self = this;
this.app = sinon.createStubInstance(this.App);
this.app.require = sinon.stub();
this.app.require.callsArgWith(1, this.SettingsView);
// Settings
this.app.el = {};
this.app.activity = { active: false };
this.app.formatPictureSizes = sinon.stub();
this.app.formatRecorderProfiles = sinon.stub();
this.app.settings = sinon.createStubInstance(this.Settings);
this.app.settings.mode = sinon.createStubInstance(this.Setting);
this.app.settings.pictureSizes = sinon.createStubInstance(this.Setting);
this.app.settings.pictureSizesFront = sinon.createStubInstance(this.Setting);
this.app.settings.pictureSizesBack = sinon.createStubInstance(this.Setting);
this.app.settings.recorderProfiles = sinon.createStubInstance(this.Setting);
this.app.settings.recorderProfilesFront = sinon.createStubInstance(this.Setting);
this.app.settings.recorderProfilesBack = sinon.createStubInstance(this.Setting);
this.app.settings.flashModesPicture = sinon.createStubInstance(this.Setting);
this.app.settings.flashModesVideo = sinon.createStubInstance(this.Setting);
this.app.settings.hdr = sinon.createStubInstance(this.Setting);
this.app.views = {
notification: sinon.createStubInstance(this.NotificationViews)
};
// SettingsView mock
this.app.SettingsView = sinon.spy(function() {
var view = sinon.createStubInstance(self.SettingsView);
view.render.returns(view);
view.appendTo.returns(view);
view.on.returns(view);
view.fadeOut.callsArg(0);
return view;
});
document.l10n = {
formatValue: key => {
return {
then(fn) { fn('LOCALIZED'); }
};
}
};
// Shortcut
this.notification = this.app.views.notification;
this.settings = this.app.settings;
// Create test instance
this.controller = new this.SettingsController(this.app);
});
teardown(function() {
delete document.l10n;
});
suite('SettingsController()', function() {
test('Should setup aliases for `recorderProfiles`, `pictureSizes` and `flashModes`', function() {
sinon.assert.calledThrice(this.settings.alias);
});
test('Should toggle the settings menu on \'settings:toggle\'', function() {
assert.isTrue(this.app.on.calledWith('settings:toggle', this.controller.toggleSettings));
});
test('Should update the settings when the camera hardware changes', function() {
assert.isTrue(this.app.on.calledWith('camera:newcamera', this.controller.onNewCamera));
});
test('Should format pictreSize titles when the app is localized', function() {
assert.isTrue(this.app.on.calledWith('localized', this.controller.formatPictureSizeTitles));
});
test('Should listen to \'camera:newcamera\'', function() {
assert.isTrue(this.app.on.calledWith('camera:newcamera', this.controller.onNewCamera));
});
});
suite('SettingsController#configurePictureSizes()', function() {
setup(function() {
this.pictureSizes = [];
this.exclude = ['480x320'];
this.app.formatPictureSizes.returns('formatted');
this.settings.pictureSizes.get
.withArgs('exclude')
.returns(this.exclude);
this.settings.pictureSizes.current = sinon.stub()
.returns(this.settings.pictureSizesBack);
document.l10n = {
formatValue: function(id, args) {
return Promise.resolve();
}
};
this.settings.pictureSizes.get
.withArgs('options')
.returns([]);
// Run it
this.controller.configurePictureSizes({
pictureSize: { height: 1536, width: 2048 },
capabilities: {
pictureSizes: this.pictureSizes
}
});
});
test('Should format the raw pictureSizes list', function() {
assert.isTrue(this.app.formatPictureSizes.calledWith(this.pictureSizes));
});
test('Should reset pictureSize options with formatted list', function() {
assert.isTrue(this.settings.pictureSizes.resetOptions.calledWith('formatted'));
});
test('Should pass the raw recorderProfiles into formatRecorderProfiles', function() {
var arg1 = this.app.formatPictureSizes.args[0][0];
assert.equal(arg1, this.pictureSizes);
});
test('Should pass the `exclude`', function() {
var options = this.app.formatPictureSizes.args[0][1];
assert.equal(options.exclude, this.exclude);
});
});
suite('SettingsController#configureRecorderProfiles()', function() {
setup(function() {
this.recorderProfiles = {};
this.formatted = ['1080p', '720p', '480p'];
this.exclude = ['1080p'];
this.newCamera = {
recorderProfile: '720p',
pictureSize: { height: 1536, width: 2048 },
capabilities: {
recorderProfiles: this.recorderProfiles
}
};
this.app.formatRecorderProfiles
.returns(this.formatted);
this.settings.recorderProfiles.get
.withArgs('exclude')
.returns(this.exclude);
this.settings.recorderProfiles.current = sinon.stub()
.returns(this.settings.recorderProfilesBack);
// Run it
this.controller.configureRecorderProfiles(this.newCamera);
});
test('Should format the raw recorderProfiles list', function() {
assert.isTrue(this.app.formatRecorderProfiles.calledWith(this.recorderProfiles));
});
test('Should reset recorderProfiles options with formatted list', function() {
var resetOptions = this.settings.recorderProfiles.resetOptions;
assert.isTrue(resetOptions.calledWith(this.formatted));
});
test('Should pass the raw recorderProfiles into formatRecorderProfiles', function() {
var arg1 = this.app.formatRecorderProfiles.args[0][0];
assert.equal(arg1, this.recorderProfiles);
});
test('Should pass `exclude` option to formatRecorderProfiles', function() {
var options = this.app.formatRecorderProfiles.args[0][1];
assert.equal(options.exclude, this.exclude);
});
test('Should pick the last formatted recorderProfile if `maxFileSize` is defined', function() {
this.settings.recorderProfiles.resetOptions.reset();
this.settings.recorderProfiles.get
.withArgs('maxFileSizeBytes')
.returns(100);
this.controller.configureRecorderProfiles(this.newCamera);
var arg = this.settings.recorderProfiles.resetOptions.args[0][0];
assert.deepEqual(arg, ['480p']);
});
});
suite('SettingsController#onOptionTap()', function() {
setup(function() {
this.setting = sinon.createStubInstance(this.Setting);
sinon.stub(this.controller, 'closeSettings').callsArg(0);
sinon.stub(this.controller, 'notify');
});
test('Should select the given key on the given option', function() {
this.controller.onOptionTap('the-key', this.setting);
assert.isTrue(this.setting.select.calledWith('the-key'));
});
test('Should close the settings menu', function() {
this.controller.onOptionTap('the-key', this.setting);
assert.isTrue(this.controller.closeSettings.called);
});
test('It shows a notification after the settings have closed', function() {
this.controller.onOptionTap('the-key', this.setting);
assert.isTrue(this.controller.notify.calledAfter(this.controller.closeSettings));
});
});
suite('SettingsController#notify()', function() {
setup(function() {
this.setting = sinon.createStubInstance(this.Setting);
this.setting.selected.withArgs('title').returns('l10n-key');
});
test('Should display a notification', function() {
this.controller.notify(this.setting);
assert.isTrue(this.notification.display.called);
});
test('Should not display a notification if flagged `false`', function() {
this.setting.get.withArgs('notifications').returns(false);
this.controller.notify(this.setting);
sinon.assert.notCalled(this.notification.display);
});
});
suite('SettingsController#validMenuItem()', function() {
test('Should return `true` if supported', function() {
var output;
this.app.settings.hdr.supported.returns(true);
output = this.controller.validMenuItem({ key: 'hdr' });
assert.isTrue(output);
this.app.settings.hdr.supported.returns(false);
output = this.controller.validMenuItem({ key: 'hdr' });
assert.isFalse(output);
});
test('Should cope with undefined settings', function() {
assert.isFalse(this.controller.validMenuItem({ key: 'fake' }));
});
});
suite('SettingsController#onNewCamera()', function() {
setup(function() {
this.newCamera = {
recorderProfile: '720p',
pictureSize: { height: 1536, width: 2048 },
capabilities: {
hdr: ['on', 'off'],
pictureSizes: [],
recorderProfiles: [],
flashModes: []
}
};
this.settings.pictureSizes.current = sinon.stub()
.returns(this.settings.pictureSizesBack);
this.settings.recorderProfiles.current = sinon.stub()
.returns(this.settings.recorderProfilesBack);
this.app.settings.pictureSizes.get.returns([]);
this.app.formatRecorderProfiles
.returns(['1080p', '720p', '480p' ]);
});
test('Should filter both \'picture\' and \'video\' flashModes', function() {
var picture = this.settings.flashModesPicture;
var video = this.settings.flashModesVideo;
var capabilities = this.newCamera.capabilities;
this.controller.onNewCamera(this.newCamera);
assert.ok(picture.filterOptions.calledWith(capabilities.flashModes));
assert.ok(video.filterOptions.calledWith(capabilities.flashModes));
});
test('Should filter hdr', function() {
var capabilities = this.newCamera.capabilities;
this.controller.onNewCamera(this.newCamera);
assert.ok(this.settings.hdr.filterOptions.calledWith(capabilities.hdr));
});
test('Should reset pictureSizes and recorderProfiles options', function() {
var recorderProfiles = this.settings.recorderProfiles;
var pictureSizes = this.settings.pictureSizes;
this.controller.onNewCamera(this.newCamera);
assert.ok(recorderProfiles.resetOptions.called);
assert.ok(pictureSizes.resetOptions.called);
});
});
suite('SettingsController#toggleSettings()', function() {
setup(function() {
sinon.stub(this.controller, 'closeSettings');
sinon.stub(this.controller, 'openSettings');
});
test('Should close the settings if a `view` is present', function() {
this.controller.view = 'defined';
this.controller.toggleSettings();
assert.isTrue(this.controller.closeSettings.called);
});
test('Should open the settings if a `view` is not present', function() {
this.controller.view = undefined;
this.controller.toggleSettings();
assert.isTrue(this.controller.openSettings.called);
});
});
suite('SettingsController#openSettings()', function() {
setup(function() {
this.menuItems = [];
sinon.stub(this.controller, 'menuItems').returns(this.menuItems);
// Call it
this.controller.openSettings();
});
test('Should create a new SettingsView passing menu items', function() {
var options = this.app.SettingsView.args[0][0];
assert.isTrue(this.app.SettingsView.called);
assert.equal(options.items, this.menuItems);
});
test('Should render and appendTo app.el', function() {
assert.isTrue(this.controller.view.render.called);
assert.isTrue(this.controller.view.appendTo.calledWith(this.app.el));
});
test('Should bind to `click:close` and `click:option` events', function() {
assert.isTrue(this.controller.view.on.calledWith('click:close'));
assert.isTrue(this.controller.view.on.calledWith('click:option'));
});
test('Should emit a `settings:open` event', function() {
assert.isTrue(this.app.emit.calledWith('settings:opened'));
});
test('Should not do anything if a view already exists', function() {
this.app.SettingsView.reset();
this.controller.view = 'defined';
this.controller.openSettings();
assert.isFalse(this.app.SettingsView.called);
});
});
suite('SettingsController#closeSettings()', function() {
setup(function() {
// Open settings first so we have a view
sinon.stub(this.controller, 'menuItems').returns(this.menuItems);
this.controller.openSettings();
this.view = this.controller.view;
});
test('Should not do anything if no view exists', function() {
this.controller.view = undefined;
this.controller.closeSettings();
assert.isFalse(this.app.emit.calledWith('settings:closed'));
});
test('Should destroy the view', function() {
this.controller.closeSettings();
assert.isTrue(this.view.destroy.called);
});
test('Should null out `view`', function() {
this.controller.closeSettings();
assert.equal(this.controller.view, null);
});
});
suite('SettingsController#formatPictureSizeTitles()', function() {
setup(function(done) {
this.options = [
{
key: '400x300',
data: {
mp: 0,
width: 400,
height: 300,
aspect: '4:3'
}
},
{
key: '1600x900',
data: {
mp: 1,
width: 1600,
height: 900,
aspect: '16:9'
}
},
{
key: '3200x1800',
data: {
mp: 6,
width: 3200,
height: 1800,
aspect: '16:9'
}
}
];
this.settings.pictureSizes.get
.withArgs('options')
.returns(this.options);
document.l10n = {
formatValue: function(id, args) {
return Promise.resolve('MP');
}
};
// Call the test subject
this.controller.formatPictureSizeTitles().then(() => {
done();
});
});
test('Should include MP value for > 1MP', function() {
assert.isTrue(this.options[2].title.indexOf('6MP') > -1, this.options[2].title);
assert.isFalse(this.options[0].title.indexOf('MP') > -1, this.options[0].title);
});
test('Should include the resolution', function() {
assert.isTrue(this.options[0].title.indexOf('400x300') > -1);
});
test('Should use localized \'MP\' string', function() {
document.l10n = {
formatValue: function(id, args) {
return Promise.resolve('MP');
}
};
this.controller.formatPictureSizeTitles();
assert.isTrue(this.options[2].title.indexOf('MP') > -1, this.options[2].title);
});
});
suite('SettingsController#onPickActivity()', function() {
setup(function() {
this.onPickActivity = this.app.on.withArgs('activity:pick').args[0][1];
});
test('Should not save settings changes when in \'pick\' activity', function() {
this.onPickActivity({});
sinon.assert.called(this.settings.dontSave);
});
test('Should set maxPixelSize on pictureSizes settings', function() {
this.onPickActivity({ maxPixelSize: 100 });
sinon.assert.calledWith(this.settings.pictureSizesFront.set, 'maxPixelSize', 100);
sinon.assert.calledWith(this.settings.pictureSizesBack.set, 'maxPixelSize', 100);
});
test('Should set maxPixelSize on pictureSizes settings', function() {
this.onPickActivity({ maxFileSizeBytes: 100 });
sinon.assert.calledWith(this.settings.recorderProfilesFront.set, 'maxFileSizeBytes', 100);
sinon.assert.calledWith(this.settings.recorderProfilesBack.set, 'maxFileSizeBytes', 100);
});
});
});