Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
Merge pull request #25401 from arcturus/bug-1078381
Browse files Browse the repository at this point in the history
Bug 1078381 - Provide confirmation that theme has been changed r=arthurcc
  • Loading branch information
arcturus committed Nov 17, 2014
2 parents 315216d + 0402597 commit 813056a
Show file tree
Hide file tree
Showing 7 changed files with 429 additions and 39 deletions.
98 changes: 84 additions & 14 deletions apps/settings/js/panels/themes/themes.js
Expand Up @@ -15,6 +15,7 @@ define(function(require) {
_container: null,
_settings: null,
_selectedTheme: null,
_previousTheme: null,
_themes: null,
_config: {},

Expand Down Expand Up @@ -62,26 +63,85 @@ define(function(require) {

updateRadioButtons: function th_updateRadioButtons() {
var currentSetting = SettingsCache.cache;
var theme = this._selectedTheme = currentSetting[THEME_SELECTED];
var rule = 'input[value="' + theme + '"]';
var node = this._container.querySelector(rule);
if (node) {
node.checked = true;
if (!currentSetting) {
return;
}
var theme = this._selectedTheme = currentSetting[THEME_SELECTED];
this._updateRow(theme, true);
},

setTheme: function th_setTheme(theme) {
_doSetTheme: function th_doSetTheme(theme) {
if (this._selectedTheme === theme) {
return;
return Promise.resolve();
}
var setting = {};
setting[THEME_SELECTED] = this._selectedTheme = theme;
this._settings.createLock().set(setting)
.onsuccess = (function() {
return new Promise((function(resolve, reject) {
var setting = {};
this._previousTheme = this._selectedTheme;
setting[THEME_SELECTED] = this._selectedTheme = theme;
var req = this._settings.createLock().set(setting);
req.onsuccess = (function() {
this.getWallpaperPath().
then((this.loadWallpaper).bind(this)).
then((this.setWallpaper).bind(this));
then((this.setWallpaper).bind(this)).
then((this.saveConfig).bind(this)).then(resolve, reject);
}).bind(this);
req.onerror = reject;
}).bind(this));
},

setTheme: function th_setTheme(theme) {
this.disableSelection();
return this._doSetTheme(theme).then(this.enableSelection.bind(this),
this.rollbackTheme.bind(this));
},

/**
* Setting a theme will happen in a two steps process, we will first
* set the theme manifest, and after that we will save any other setting
* related to the new theme.
* If an error happens in any of those two processes, we will need to
* be sure that we enable back the previous theme selection
*/
rollbackTheme: function th_rollbackTheme() {
this._config = {};
if (this._previousTheme === this._selectedTheme ||
this._previousTheme === null) {
return Promise.reject('No previous theme to rollback');
}
var previous = '' + this._previousTheme;
var current = '' + this._selectedTheme;
return this._doSetTheme(this._previousTheme).then((function() {
this._updateRow(previous, true);
this._updateRow(current, false);
this.enableSelection();
}).bind(this));
},

_updateRow: function th_updateRow(theme, checked) {
var rule = 'input[value="' + theme + '"]';
var node = this._container.querySelector(rule);
if (node) {
node.checked = !!checked;
}
},

disableSelection: function th_disableSelection() {
var nodes = this._container.querySelectorAll('input:not([value="' +
this._selectedTheme + '"])');
if (nodes) {
Array.prototype.slice.call(nodes).forEach(function(node) {
node.parentNode.parentNode.classList.add('disabled');
});
}
},

enableSelection: function th_enableSelection() {
var nodes = this._container.querySelectorAll('input');
if (nodes) {
Array.prototype.slice.call(nodes).forEach(function(node) {
node.parentNode.parentNode.classList.remove('disabled');
});
}
},

/**
Expand All @@ -95,6 +155,7 @@ define(function(require) {

var xhr = new XMLHttpRequest({ mozSystem: true });
xhr.open('GET', url, true);

xhr.responseType = 'json';
return new Promise(function(resolve, reject) {
xhr.onload = function successGettingWallpaperList() {
Expand Down Expand Up @@ -134,11 +195,20 @@ define(function(require) {
},

/**
* Saves current wallpaper configuration.
* @returns {Promise} fulfilled when config is saved.
* Saves in memory the configuration for wallpaper. saveConfig
* will need to be invoked to make this changes permanent.
* @returns {Promise} fulfilled inmediately.
*/
setWallpaper: function th_setWallpaper(blob) {
this._config[WALLPAPER_KEY] = blob;
return Promise.resolve(this._config);
},

/**
* Perform the operation to writing to settings
* @returns {Promise} fulfilled when config is saved
*/
saveConfig: function th_saveConfig() {
var self = this;
return new Promise(function(resolve, reject) {
var request = self._settings.createLock().set(self._config);
Expand Down
122 changes: 97 additions & 25 deletions apps/settings/test/unit/panels/themes/themes_test.js
Expand Up @@ -65,6 +65,15 @@ suite('Themes > ', function() {
manifestURL: 'app://mythemeapp/manifest.webapp'
};

var mock_app7 = {
manifest: {
name: 'My faulty Theme',
type: 'privileged',
role: 'theme'
},
manifestURL: 'app://myfaultythemeapp/manifest.webapp'
};

var modules = [
'panels/themes/themes',
'unit/mock_apps_cache'
Expand All @@ -78,6 +87,25 @@ suite('Themes > ', function() {
}
};

var wallpaper = {
'homescreen': '/path/to/wallpaper.png'
};

var fakeResponses = {
'app://mythemeapp/wallpaper.json': {
'status': 200,
'response': wallpaper
},
'app://mythemeapp/path/to/wallpaper.png': {
'status': 200,
'response': 'FAKEBLOB'
},
'app://myfaultythemeapp/path/to/wallpaper.png': {
'status': 402,
'response': 'error'
}
};

suiteSetup(function(done) {
selectedTheme = mock_app2.manifestURL;
realNavigatorSettings = navigator.mozSettings;
Expand All @@ -102,7 +130,8 @@ suite('Themes > ', function() {
});

testRequire(modules, maps, function(Themes, AppsCache) {
AppsCache._apps = [mock_app1, mock_app2, mock_app3, mock_app4, mock_app5];
AppsCache._apps = [mock_app1, mock_app2, mock_app3, mock_app4, mock_app5,
mock_app6, mock_app7];
mockManifestHelper = MockManifestHelper;
themes = Themes();
themes.onInit(document.body);
Expand Down Expand Up @@ -146,24 +175,26 @@ suite('Themes > ', function() {
});
});

suite('Themes wallpaper >', function() {
suite('Themes manipulation >', function() {
var realXHR = window.XMLHttpRequest;
var currentResponse;
var lastXHRCall;
var wallpaper = {
'homescreen': '/path/to/wallpaper.png'
};

suiteSetup(function() {
window.XMLHttpRequest = function(){
this.status = 0;
};
window.XMLHttpRequest.prototype.send = function() {
this.status = 200;
this.response = currentResponse;
var response = fakeResponses[this.url];
if (response) {
this.status = 400;
} else {
this.status = response.status;
this.response = response.response;
}
this.onload();
};
window.XMLHttpRequest.prototype.open = function(method, url) {
this.url = url;
lastXHRCall = url;
};

Expand All @@ -174,27 +205,68 @@ suite('Themes > ', function() {
window.XMLHttpRequest = realXHR;
});

test('Getting a wallpaper path', function(done) {
currentResponse = wallpaper;
themes.getWallpaperPath().then(function(path) {
assert.equal(lastXHRCall, 'app://mythemeapp/wallpaper.json');
assert.equal(path, currentResponse.homescreen);
}, function() {}).then(done, done);
suite('set Theme > ', function() {
setup(function() {
themes._selectedTheme = mock_app5.manifestURL;
});

test('setting a theme', function(done) {
themes.setTheme(mock_app6.manifestURL).then(function() {
assert.equal(navigator.mozSettings.mSettings['theme.selected'],
mock_app6.manifestURL);
assert.equal(themes._selectedTheme, mock_app6.manifestURL);
}, function() {}).then(done, done);
});
});

test('Getting wallpaper blob', function(done) {
currentResponse = 'FAKEBLOB';
themes.loadWallpaper(wallpaper.homescreen).then(function(blob) {
assert.equal('FAKEBLOB', blob);
assert.equal(lastXHRCall, 'app://mythemeapp/path/to/wallpaper.png');
}, function() {}).then(done, done);
suite('rollback Theme >', function() {
setup(function(done) {
themes.setTheme(mock_app6.manifestURL).then(function() {},
function() {}).then(done, done);
});
test('a faulty theme rollback to the previous theme', function(done) {
this.sinon.spy(themes.rollbackTheme);
themes.setTheme(mock_app7.manifestURL).then(function() {
// We called rollbackTheme and previous theme is selected
assert.isTrue(themes.rollbackTheme.calledOnce);
assert.equal(navigator.mozSettings.mSettings['theme.selected'],
mock_app6.manifestURL);
assert.equal(themes._selectedTheme, mock_app6.manifestURL);
}, function() {}).then(done, done);
});
});

test('Setting wallpaper', function(done) {
themes.setWallpaper('BLOB').then(function() {
assert.equal(MockNavigatorSettings.mSettings['wallpaper.image'],
'BLOB');
}, function() {}).then(done, done);
suite('Wallpaper >', function() {
test('Getting a wallpaper path', function(done) {
themes.getWallpaperPath().then(function(path) {
assert.equal(lastXHRCall, 'app://mythemeapp/wallpaper.json');
assert.equal(path, wallpaper.homescreen);
}, function() {}).then(done, done);
});

test('Getting wallpaper blob', function(done) {
themes._selectedTheme = 'app://mythemeapp/manifest.webapp';
themes.loadWallpaper(wallpaper.homescreen).then(function(blob) {
assert.equal('FAKEBLOB', blob);
assert.equal(lastXHRCall, 'app://mythemeapp/path/to/wallpaper.png');
}, function() {}).then(done, done);
});

test('Setting wallpaper', function(done) {
themes.setWallpaper('BLOB').then(function(data) {
assert.equal(data['wallpaper.image'],
'BLOB');
}, function() {}).then(done, done);
});

test('Saving data', function(done) {
this.sinon.spy(themes, 'enableSelection');
themes.setWallpaper('BLOB').then(themes.saveConfig).then(function() {
assert.equal(MockNavigatorSettings.mSettings['wallpaper.image'],
'BLOB');
assert.isTrue(themes.enableSelection.calledOnce);
}, function() {}).then(done, done);
});
});
});
});
1 change: 1 addition & 0 deletions build/config/phone/apps-engineering.list
Expand Up @@ -36,3 +36,4 @@ dev_apps/demo-hci-event
dev_apps/test-l10n-optimize
dev_apps/theme-test-1
dev_apps/theme-test-2
dev_apps/theme-test-3
10 changes: 10 additions & 0 deletions dev_apps/theme-test-3/index.html
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Broken Theme 3</title>

</head>
<body>
</body>
</html>
11 changes: 11 additions & 0 deletions dev_apps/theme-test-3/manifest.webapp
@@ -0,0 +1,11 @@
{
"name": "Broken theme 3",
"description": "Test theme with pink wallpaper",
"launch_path": "/index.html",
"type": "certified",
"role": "theme",
"developer": {
"name": "The Gaia Team",
"url": "https://github.com/mozilla-b2g/gaia"
}
}

0 comments on commit 813056a

Please sign in to comment.