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,34 @@
'use strict';
var assert = require('chai').assert;
var rmrf = require('rimraf').sync;
var helper = require('./helper');
var fs = require('fs');
var path = require('path');
suite('ADB tests', function() {
suiteSetup(function() {
helper.cleanupWorkspace();
rmrf('build/test/integration/result');
});
suiteTeardown(function() {
helper.cleanupWorkspace();
rmrf('build/test/integration/result');
});
test('make install-test-media', function(done) {
var expectedCommand = 'push test_media/Pictures /sdcard/DCIM\n' +
'push test_media/Movies /sdcard/Movies\n' +
'push test_media/Music /sdcard/Music\n';
helper.exec('ADB=build/test/bin/fake-adb make install-test-media',
function(error, stdout, stderr) {
helper.checkError(error, stdout, stderr);
var presetsContent = fs.readFileSync(path.join(process.cwd(), 'build',
'test', 'integration', 'result'));
assert.equal(presetsContent, expectedCommand);
done();
});
});
});

View file

@ -0,0 +1,77 @@
'use strict';
var assert = require('chai').assert;
var helper = require('./helper');
var fs = require('fs');
var path = require('path');
suite('Build GAIA from different app list', function() {
suiteSetup(helper.cleanupWorkspace);
teardown(helper.cleanupWorkspace);
test('GAIA_DEVICE_TYPE=tablet make', function(done) {
helper.exec('GAIA_DEVICE_TYPE=tablet make', function(err, stdout, stderr) {
helper.checkError(err, stdout, stderr);
// zip path for system app
var zipPath = path.join(process.cwd(), 'profile', 'webapps',
'sms.gaiamobile.org', 'application.zip');
// sms should not exists in Tablet builds
assert.isFalse(fs.existsSync(zipPath));
// vertical homescreen should exist in tablet builds
var zipVertHomePath = path.join(process.cwd(), 'profile', 'webapps',
'verticalhome.gaiamobile.org', 'application.zip');
assert.isTrue(fs.existsSync(zipVertHomePath));
done();
});
});
test('GAIA_DEVICE_TYPE=phone make', function(done) {
helper.exec('GAIA_DEVICE_TYPE=phone make', function(err, stdout, stderr) {
helper.checkError(err, stdout, stderr);
// zip path for sms app
var zipPath = path.join(process.cwd(), 'profile', 'webapps',
'sms.gaiamobile.org', 'application.zip');
// sms should not exists in Tablet builds
assert.ok(fs.existsSync(zipPath));
// vertical homescreen should exists
var zipVertHomePath = path.join(process.cwd(), 'profile', 'webapps',
'verticalhome.gaiamobile.org', 'application.zip');
assert.ok(fs.existsSync(zipVertHomePath));
// Check init.json
var initPath = path.join(process.cwd(), 'build_stage',
'verticalhome', 'js', 'init.json');
assert.ok(fs.existsSync(initPath),
'init.json should exist');
done();
});
});
test('GAIA_DEVICE_TYPE=tv make', function(done) {
helper.exec('GAIA_DEVICE_TYPE=tv make', function(err, stdout, stderr) {
helper.checkError(err, stdout, stderr);
// zip path for homescreen-stingray app
var zipPath = path.join(process.cwd(), 'profile', 'webapps',
'smart-home.gaiamobile.org', 'application.zip');
// smart-home should exist in tv builds
assert.ok(fs.existsSync(zipPath));
// vertical homescreen should not exist
var zipVertHomePath = path.join(process.cwd(), 'profile', 'webapps',
'verticalhome.gaiamobile.org', 'application.zip');
assert.isFalse(fs.existsSync(zipVertHomePath));
done();
});
});
});

View file

@ -0,0 +1,153 @@
'use strict';
var assert = require('chai').assert;
var fs = require('fs');
var path = require('path');
var AdmZip = require('adm-zip');
var helper = require('./helper');
suite('Integration tests', function() {
suiteSetup(helper.cleanupWorkspace);
teardown(helper.cleanupWorkspace);
function verifyIncludedFilesFromHtml(appName) {
var zipPath = path.join(process.cwd(), 'profile', 'webapps',
appName + '.gaiamobile.org', 'application.zip');
var zip = new AdmZip(zipPath);
var zipEntries = zip.getEntries();
if (zipEntries.length === 0) {
return;
}
for (var f = 0; f < zipEntries.length; f++) {
var fileName = zipEntries[f].entryName;
var extention =
fileName.substr(fileName.lastIndexOf('.') + 1).toLowerCase();
if (extention === 'html') {
extractSharedFile(zip, zipEntries[f], appName);
}
}
function extractSharedFile(zip, file, appName) {
var SHARED_USAGE =
/<(?:script|link).+=['"]\.?\.?\/?(shared\/[^\/]+\/[^''\s]+)["']/g;
var content = zip.readAsText(file);
var matches;
while((matches = SHARED_USAGE.exec(content))!== null) {
var filePathInHtml = matches[1];
var fileInZip = zip.readFile(zip.getEntry(filePathInHtml));
var fileInApps;
if (/\.(png|gif|jpg)$/.test(filePathInHtml)) {
continue;
}
if (filePathInHtml.indexOf('shared/') === 0) {
fileInApps = fs.readFileSync(
path.join(process.cwd(), filePathInHtml));
} else {
fileInApps = fs.readFileSync(path.join(process.cwd(),
'apps', appName, filePathInHtml));
}
assert.deepEqual(fileInZip, fileInApps, filePathInHtml);
}
}
}
function verifyIncludedImagesSize(appName, reso, official) {
var zipPath = path.join(process.cwd(), 'profile', 'webapps',
appName + '.gaiamobile.org', 'application.zip');
var zip = new AdmZip(zipPath);
var zipEntries = zip.getEntries();
if (zipEntries.length === 0) {
return;
}
for (var f = 0; f < zipEntries.length; f++) {
var fileInZip = zipEntries[f];
var fileName = fileInZip.entryName;
if (/\.(png|gif|jpg)$/.test(fileName)) {
// Manually modify the pathname of the browser branding images as
// these are packaged differently than normal images.
if (reso !== 1 &&
fileName.indexOf('shared/resources/branding/browser_') === -1) {
fileName = fileName.replace(
/(.*)(\.(png|gif|jpg))$/, '$1@' + reso + 'x$2');
}
compareWithApps(appName, fileName, fileInZip, reso, official);
}
}
function compareWithApps(appName, filePath, fileEntry, reso, official) {
var fileInApps;
var fileOfZip = zip.readFile(fileEntry);
if (filePath.indexOf('/branding/') !== -1) {
filePath = filePath.replace('/branding/',
official ? '/branding/official/' : '/branding/unofficial/');
}
if (filePath.indexOf('shared/') === 0) {
filePath = path.join(process.cwd(), filePath);
} else {
filePath = path.join(process.cwd(), 'apps', appName, filePath);
}
if (fs.existsSync(filePath)) {
fileInApps = fs.readFileSync(filePath);
} else {
filePath = filePath.replace('@' + reso + 'x', '');
fileInApps = fs.readFileSync(filePath);
}
assert.deepEqual(fileOfZip, fileInApps, filePath + ' no found');
}
}
test('make APP=system, checking all of the files are available',
function(done) {
helper.exec('make APP=system', function(error, stdout, stderr) {
helper.checkError(error, stdout, stderr);
verifyIncludedFilesFromHtml('system');
verifyIncludedImagesSize('system', 1, false);
done();
});
});
test('make with GAIA_DEV_PIXELS_PER_PX=1.5', function(done) {
helper.exec('GAIA_DEV_PIXELS_PER_PX=1.5 APP=system make ',
function(error, stdout, stderr) {
helper.checkError(error, stdout, stderr);
verifyIncludedImagesSize('system', 1.5, false);
done();
}
);
});
test('make app with custom origin', function(done) {
// add custom-origin app to apps list
var appsListPath = path.join('build', 'config', 'phone',
'apps-engineering.list');
fs.renameSync(appsListPath, appsListPath + '.bak');
fs.writeFileSync(appsListPath,
'apps/*\nbuild/test/fixtures/custom-origin\n');
var extConfigPath = path.join('build', 'config',
'additional-extensions.json');
var restoreFunc = helper.emptyJsonFile(extConfigPath);
helper.exec('DEBUG=1 make', function(error, stdout, stderr) {
fs.unlinkSync(appsListPath);
fs.renameSync(appsListPath + '.bak', appsListPath);
helper.checkError(error, stdout, stderr);
var webappsPath = path.join(process.cwd(), 'profile-debug',
'webapps', 'webapps.json');
var webapps = JSON.parse(fs.readFileSync(webappsPath));
assert.isNotNull(webapps['test.mozilla.com']);
assert.equal(
webapps['test.mozilla.com'].origin, 'app://test.mozilla.com');
restoreFunc();
done();
});
});
});

View file

@ -0,0 +1,46 @@
'use strict';
var assert = require('chai').assert;
var fs = require('fs');
var path = require('path');
var vm = require('vm');
var helper = require('./helper');
var rmrf = require('rimraf').sync;
suite('Make with desktop custom core apps location', function() {
suiteSetup(helper.cleanupWorkspace);
teardown(helper.cleanupWorkspace);
test('make with desktop custom core apps location', function(done) {
var coreAppPath = path.join(process.cwd(), 'profile-coreapptest');
var coretest = function(error, stdout, stderr) {
helper.checkError(error, stdout, stderr);
var expectedUserPrefs = {
'b2g.coreappsdir': coreAppPath
};
var userjs = fs.readFileSync(
path.join('profile', 'user.js'),
{ encoding: 'utf8' }
);
var sandbox = helper.getPrefsSandbox();
vm.runInNewContext(userjs, sandbox);
helper.checkPrefs(sandbox.userPrefs, expectedUserPrefs);
var oldAppPath = path.join(process.cwd(), 'profile', 'webapps');
// Make sure we have no webapps directory in the profile, this
// will now be created by gecko on start.
assert(!fs.existsSync(oldAppPath));
var manifestPath = path.join(coreAppPath, 'webapps',
'webapps.json');
assert(fs.existsSync(manifestPath));
var appPath = path.join(coreAppPath, 'webapps',
'system.gaiamobile.org', 'application.zip');
assert(fs.existsSync(appPath));
rmrf(coreAppPath);
done();
};
helper.exec('COREWEBAPPS_DIR=' + coreAppPath +' make ',
coretest);
});
});

View file

@ -0,0 +1,82 @@
'use strict';
var assert = require('chai').assert;
var fs = require('fs');
var path = require('path');
var vm = require('vm');
var helper = require('./helper');
var dive = require('diveSync');
suite('Make with DEBUG=1', function() {
suiteSetup(helper.cleanupWorkspace);
teardown(helper.cleanupWorkspace);
test('make with DEBUG=1', function(done) {
// avoid downloading extension from addon website
var extConfigPath = path.join('build', 'config',
'additional-extensions.json');
var restoreFunc = helper.emptyJsonFile(extConfigPath);
helper.exec('DEBUG=1 make', function(error, stdout, stderr) {
helper.checkError(error, stdout, stderr);
var installedExtsPath = path.join('build_stage', 'additional-extensions',
'downloaded.json');
var expectedSettings = {
'homescreen.manifestURL':
'app://homescreen.gaiamobile.org/manifest.webapp',
'rocketbar.searchAppURL': 'app://search.gaiamobile.org/index.html'
};
var expectedUserPrefs = {
'image.mozsamplesize.enabled': true,
'docshell.device_size_is_page_size': true,
'marionette.defaultPrefs.enabled': true,
'nglayout.debug.disable_xul_cache': true,
'nglayout.debug.disable_xul_fastload': true,
'javascript.options.showInConsole': true,
'browser.dom.window.dump.enabled': true,
'dom.report_all_js_exceptions': true,
'dom.w3c_touch_events.enabled': 1,
'webgl.verbose': true,
'toolkit.identity.debug': true,
'extensions.gaia.dir': process.cwd(),
'extensions.gaia.domain': 'gaiamobile.org',
'extensions.gaia.port': 8080,
'extensions.gaia.locales_debug_path': 'locales',
'extensions.gaia.official': false,
'extensions.gaia.locales_file': 'shared/resources/languages.json',
'extensions.gaia.locale_basedir': '',
'extensions.gaia.device_pixel_suffix': '',
'extensions.autoDisableScopes': 0
};
var settingsPath = path.join(process.cwd(), 'profile-debug',
'settings.json');
var settings = JSON.parse(fs.readFileSync(settingsPath));
var userjs = fs.readFileSync(
path.join('profile-debug', 'user.js'),
{ encoding: 'utf8' }
);
var sandbox = helper.getPrefsSandbox();
vm.runInNewContext(userjs, sandbox);
var zipCount = 0;
dive(path.join(process.cwd(), 'profile-debug'), function(err, file) {
if (err) {
throw err;
}
if (file.indexOf('application.zip') !== -1) {
zipCount++;
}
});
assert.ok(fs.existsSync(installedExtsPath));
helper.checkSettings(settings, expectedSettings);
helper.checkPrefs(sandbox.userPrefs, expectedUserPrefs);
// expect one zip file for each "external" app.
assert.equal(zipCount, 6, 'we should have six zip files in ' +
'profile-debug directory');
restoreFunc();
done();
});
});
});

View file

@ -0,0 +1,335 @@
'use strict';
/* jshint maxlen: 130 */
var rmrf = require('rimraf').sync;
var AdmZip = require('adm-zip');
var helper = require('./helper');
var path = require('path');
var assert = require('chai').assert;
var fs = require('fs');
var http = require('http');
suite('Distribution mechanism', function() {
var cusDir;
var server;
var variantPath;
var originalVariant;
setup(function() {
rmrf('profile');
rmrf('build_stage');
// Setup local server and handle manifest downloading to avoid remote
// server dependency
var fakeManifest = {
'version': '1.0',
'name': 'Fake',
'description': 'Fake app'
};
server = http.createServer(function(req, res) {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(fakeManifest));
});
// Change manifestURL from
// https://mobile.twitter.com/cache/twitter.webapp
// to
// http://localhost:9999/manifest.webapp
cusDir = path.join(process.cwd(), 'customization');
variantPath = path.join(cusDir, 'variant.json');
var port = 9999;
originalVariant = fs.readFileSync(variantPath, { encoding: 'utf8' });
var variant = JSON.parse(originalVariant);
variant.apps.Twitter.manifestURL = 'http://localhost:' + port +
'/manifest.webapp';
fs.writeFileSync(variantPath, JSON.stringify(variant));
server.listen(port);
});
function validatePreloadSettingDB() {
var settingsPath = path.join(process.cwd(), 'profile', 'settings.json');
var settings = JSON.parse(fs.readFileSync(settingsPath));
var expectedSettings;
expectedSettings = JSON.parse(
fs.readFileSync(path.join(cusDir, 'settings.json')));
var keyboardManifestURL = 'app://keyboard.gaiamobile.org/manifest.webapp';
var expectedLayouts = {};
// For test only, so deliberately makes English map to cs and es layout
expectedLayouts[keyboardManifestURL] = {cs: true, es: true};
expectedSettings = {
'wap.push.enabled': true,
'keyboard.enabled-layouts': expectedLayouts,
'keyboard.default-layouts': expectedLayouts
};
helper.checkSettings(settings, expectedSettings);
}
function validateSettings() {
var setingsZipPath = path.join(process.cwd(), 'profile',
'webapps', 'settings.gaiamobile.org', 'application.zip');
helper.checkFileContentByPathInZip(
setingsZipPath, 'resources/support.json',
path.join(cusDir, 'support.json'), true);
helper.checkFileContentByPathInZip(
setingsZipPath, 'resources/device-features.json',
path.join(cusDir, 'device-features.json'), true);
}
function validateOperatorVariant() {
var zipPath = path.join(process.cwd(), 'profile',
'webapps', 'operatorvariant.gaiamobile.org', 'application.zip');
var variantConfig = {
'wallpaper':'/resources/wallpaper-7b8d66705b283f474c5892e70ece5890df7f9be2.json',
'default_contacts':'/resources/mobizilla_contacts.json',
'support_contacts':'/resources/mobizilla_support_contacts.json',
'keyboard_settings':'/resources/keyboard-88cf36fbc274369ce1c2bea24dffce3017cc6f69.json',
'network_type':'/resources/mobizilla_network_type.json',
'known_networks':'/resources/mobizilla_known_networks.json',
'nfc':'/resources/nfc-93c047a6d0389e755cacdbd6bb0986fff0576aee.json',
'sms':'/resources/mobizilla_sms.json',
'ringtone':'/resources/ringtone-8261e854cb494bf7f3a2a25510e595931244292a.json',
'power':'/resources/power-0ccc24f04b44aaadc8962735b5f86eabc5bb71e6.json',
'data_ftu':true,
'search': '/resources/mobizilla_search.json',
'topsites':'/resources/mobizilla_topsites.json',
'browser': '/resources/mobizilla_bookmarks.json'
};
var expectedCustom = {
'310-260': variantConfig,
'311-261': variantConfig
};
helper.checkFileContentInZip(zipPath, 'resources/customization.json',
expectedCustom, true);
helper.checkFileInZip(zipPath,
'resources/wallpaper-7b8d66705b283f474c5892e70ece5890df7f9be2.json',
path.join(cusDir, 'mobizilla',
'mobizilla_expected_wallpaper.json'));
helper.checkFileInZip(zipPath,
'resources/mobizilla_contacts.json',
path.join(cusDir, 'mobizilla',
'mobizilla_contacts.json'));
helper.checkFileInZip(zipPath,
'resources/mobizilla_support_contacts.json',
path.join(cusDir, 'mobizilla',
'mobizilla_support_contacts.json'));
helper.checkFileInZip(zipPath,
'resources/keyboard-88cf36fbc274369ce1c2bea24dffce3017cc6f69.json',
path.join(cusDir, 'mobizilla',
'mobizilla_expected_keyboard.json'));
helper.checkFileInZip(zipPath,
'resources/mobizilla_network_type.json',
path.join(cusDir, 'mobizilla',
'mobizilla_network_type.json'));
helper.checkFileInZip(zipPath,
'resources/mobizilla_known_networks.json',
path.join(cusDir, 'mobizilla',
'mobizilla_known_networks.json'));
helper.checkFileInZip(zipPath,
'resources/nfc-93c047a6d0389e755cacdbd6bb0986fff0576aee.json',
path.join(cusDir, 'mobizilla',
'mobizilla_expected_nfc.json'));
helper.checkFileInZip(zipPath,
'resources/mobizilla_sms.json',
path.join(cusDir, 'mobizilla',
'mobizilla_sms.json'));
helper.checkFileInZip(zipPath,
'resources/ringtone-8261e854cb494bf7f3a2a25510e595931244292a.json',
path.join(cusDir, 'mobizilla',
'mobizilla_expected_ringtone.json'));
helper.checkFileInZip(zipPath,
'resources/power-0ccc24f04b44aaadc8962735b5f86eabc5bb71e6.json',
path.join(cusDir, 'mobizilla',
'mobizilla_expected_power.json'));
helper.checkFileInZip(zipPath,
'resources/mobizilla_search.json',
path.join(cusDir, 'mobizilla',
'mobizilla_expected_search.json'));
helper.checkFileInZip(zipPath,
'resources/mobizilla_topsites.json',
path.join(cusDir, 'mobizilla',
'mobizilla_expected_topsites.json'));
helper.checkFileInZip(zipPath,
'resources/mobizilla_bookmarks.json',
path.join(cusDir, 'mobizilla',
'mobizilla_expected_bookmarks.json'));
}
function validateWappush() {
var wappushZipPath = path.join(process.cwd(), 'profile',
'webapps', 'wappush.gaiamobile.org', 'application.zip');
helper.checkFileContentByPathInZip(wappushZipPath, 'js/whitelist.json',
path.join(cusDir, 'wappush-whitelist.json'), true);
}
function validateWallpaper() {
var zipPath = path.join(process.cwd(), 'profile',
'webapps', 'wallpaper.gaiamobile.org', 'application.zip');
helper.checkFileContentByPathInZip(zipPath, 'resources/list.json',
path.join(cusDir, 'wallpapers', 'list.json'), true);
helper.checkFileContentByPathInZip(zipPath,
'resources/customize.png',
path.join(cusDir, 'wallpapers', 'customize.png'), false);
}
function validateSystem() {
var sysZipPath = path.join(process.cwd(), 'profile',
'webapps', 'system.gaiamobile.org', 'application.zip');
helper.checkFileContentByPathInZip(sysZipPath, 'resources/icc.json',
path.join(cusDir, 'icc.json'), true);
helper.checkFileContentByPathInZip(sysZipPath, 'resources/wapuaprof.json',
path.join(cusDir, 'wapuaprof.json'), true);
helper.checkFileContentByPathInZip(sysZipPath,
'resources/power/carrie_power_on.png',
path.join(cusDir, 'power', 'carrie_power_on.png'), false);
}
function validateUuid() {
var uuidMapping = JSON.parse(fs.readFileSync(
path.join(process.cwd(), 'customization','uuid.json')
));
var webappsPath = path.join(process.cwd(), 'profile', 'webapps');
for (let appname in uuidMapping) {
assert.ok(
fs.existsSync(path.join(webappsPath, uuidMapping[appname])),
'uuid for directory name in profile/webapps should exists, app name: ' +
appname + ', uuid: ' + uuidMapping[appname]
);
}
}
function parseCustimizeImageSetting(appConfig) {
if (typeof appConfig !== 'object') {
return '';
}
var expectedContent =
'//\n' +
'// This file is automatically generated: DO NOT EDIT.\n' +
'//\n'+
'// The default value of these variables depends on the\n'+
'// GAIA_MEMORY_PROFILE environment variable. Set\n'+
'// GAIA_MEMORY_PROFILE=low when building Gaia to get default\n'+
'// values suitable for low-memory devices.\n'+
'//\n'+
'// To customize these values, create a gallery.json file in the\n' +
'// distribution directory with content like this:\n' + '//\n' +
'// {\n' +
'// "maxImagePixelSize": 6000000,\n' +
'// "maxSnapshotPixelSize": 4000000,\n' +
'// "maxPickPixelSize": 480000,\n' +
'// "maxEditPixelSize": 480000 }\n' +
'// }\n' +
'//\n' +
'// Optionally, you can also define variables to specify the\n' +
'// minimum EXIF preview size that will be displayed as a\n' +
'// full-screen preview by adding a property like this:\n' +
'//\n' +
'// "requiredEXIFPreviewSize": { "width": 640, "height": 480}\n' +
'//\n' +
'// If you do not specify this property then EXIF previews will only\n' +
'// be used if they are big enough to fill the screen in either\n' +
'// width or height in both landscape and portrait mode.\n' +
'//\n' +
'var CONFIG_MAX_IMAGE_PIXEL_SIZE = ' +
appConfig.maxImagePixelSize + ';\n' +
'var CONFIG_MAX_SNAPSHOT_PIXEL_SIZE = ' +
appConfig.maxSnapshotPixelSize + ';\n' +
'var CONFIG_MAX_PICK_PIXEL_SIZE = ' +
appConfig.maxPickPixelSize + ';\n' +
'var CONFIG_MAX_EDIT_PIXEL_SIZE = ' +
appConfig.maxEditPixelSize + ';\n';
if (appConfig.requiredEXIFPreviewSize) {
expectedContent +=
'var CONFIG_REQUIRED_EXIF_PREVIEW_WIDTH = ' +
appConfig.requiredEXIFPreviewSize.width + ';\n' +
'var CONFIG_REQUIRED_EXIF_PREVIEW_HEIGHT = ' +
appConfig.requiredEXIFPreviewSize.height + ';\n';
} else {
expectedContent +=
'var CONFIG_REQUIRED_EXIF_PREVIEW_WIDTH = 0;\n' +
'var CONFIG_REQUIRED_EXIF_PREVIEW_HEIGHT = 0;\n';
}
return expectedContent;
}
function validateGallery() {
var cusPath = path.join(cusDir, 'gallery.json');
var cusConfig = JSON.parse(fs.readFileSync(cusPath));
var appZip = new AdmZip(path.join(process.cwd(), 'profile',
'webapps', 'gallery.gaiamobile.org', 'application.zip'));
var presetsContent = appZip.readAsText(appZip.getEntry('js/config.js'));
var expectContent = parseCustimizeImageSetting(cusConfig);
assert.equal(presetsContent, expectContent);
}
function validateHomescreen() {
var appZip = new AdmZip(path.join(process.cwd(), 'profile',
'webapps', 'homescreen.gaiamobile.org', 'application.zip'));
var config = JSON.parse(appZip.readAsText(appZip.getEntry('js/init.json')));
assert.equal(config.grid[0][0].name, 'Camera');
assert.equal(config.grid[0][1].entry_point, 'dialer');
assert.equal(config.grid[0][2].name, 'Messages');
assert.equal(config.grid[0][3].name, 'Marketplace');
assert.equal(config.grid[2][0].name, 'Calendar');
assert.isTrue(fs.existsSync(path.join(process.cwd(), 'profile',
'svoperapps', 'Twitter')),
'profile/svoperapps/Twitter directory should exist');
assert.isTrue(fs.existsSync(path.join(process.cwd(), 'profile',
'svoperapps', 'Twitter', 'manifest.webapp')),
'manifest for Twitter should exist');
}
function validateVariantSettings() {
var expected = {
'310-260': ['Twitter'],
'311-261': ['Twitter']
};
var configPath = path.join(process.cwd(), 'profile', 'svoperapps',
'singlevariantconf.json');
var config = fs.readFileSync(configPath, {encoding: 'utf8'});
assert.deepEqual(JSON.parse(config), expected);
}
test('build with GAIA_DISTRIBUTION_DIR', function(done) {
cusDir = path.join(process.cwd(), 'customization');
var cmd = 'GAIA_DISTRIBUTION_DIR=' + cusDir + ' make';
helper.exec(cmd, function(error, stdout, stderr) {
helper.checkError(error, stdout, stderr);
validatePreloadSettingDB();
validateSettings();
validateOperatorVariant();
validateWappush();
validateSystem();
validateGallery();
validateHomescreen();
validateWallpaper();
validateVariantSettings();
validateUuid();
done();
});
});
teardown(function() {
rmrf('profile');
rmrf('build_stage');
// Close server and restore file to original.
server.close();
fs.writeFileSync(variantPath, originalVariant);
});
});

View file

@ -0,0 +1,174 @@
'use strict';
var assert = require('chai').assert;
var fs = require('fs');
var AdmZip = require('adm-zip');
var childProcess = require('child_process');
var rmrf = require('rimraf').sync;
function getPrefsSandbox() {
var sandbox = {
prefs: {},
userPrefs: {},
user_pref: function(key, value) {
sandbox.userPrefs[key] = value;
},
pref: function(key, value) {
sandbox.prefs[key] = value;
}
};
return sandbox;
}
function checkError(error, stdout, stderr) {
if (error) {
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
console.log('error: ' + error);
}
assert.equal(error, null);
}
function checkSettings(settings, expectedSettings) {
Object.keys(expectedSettings).forEach(function(key) {
assert.isDefined(settings[key], 'key ' + key + ' is defined');
assert.deepEqual(settings[key], expectedSettings[key],
'value of settings key ' + key + ' equal ' + expectedSettings[key]);
});
}
function checkPrefs(actual, expected) {
Object.keys(expected).forEach(function(key) {
assert.isDefined(actual[key], 'key ' + key + ' is defined');
assert.deepEqual(actual[key], expected[key], 'value of settings key ' +
key + ' equal ' + expected[key]);
});
}
function checkWebappsScheme(webapps) {
var configKeys = ['origin', 'installOrigin', 'receipt', 'installTime',
'updateTime', 'manifestURL', 'localId', 'appStatus'];
Object.keys(webapps).forEach(function(key) {
var webapp = webapps[key];
configKeys.forEach(function(configKey) {
assert.equal((configKey in webapp), true,
key + ' of webapps.json has not defined ' + configKey);
});
var schemes = ['app'];
// Allow mochitest apps and hosted apps to use the "http(s)?://" scheme.
if (webapp.origin.indexOf('mochi.test') !== -1 ||
webapp.appStatus === 1) {
schemes.push('http');
}
assert.isTrue(schemes.some(function(scheme) {
return webapp.origin.indexOf(scheme) === 0;
}));
});
}
function checkFilePathInZip(zipPath, expectedPath) {
var zip = new AdmZip(zipPath);
var entries = zip.getEntries();
var result = entries.some(function(entry) {
return entry.entryName.indexOf(expectedPath) !== -1;
});
assert.ok(result, 'Checking ' + expectedPath + ' in ' + zipPath);
}
function checkFileInZip(zipPath, pathInZip, expectedPath) {
var stat = fs.statSync(expectedPath);
if (stat && stat.isDirectory()) {
var list = fs.readdirSync(expectedPath);
list.forEach(function(filename) {
checkFileInZip(
zipPath, pathInZip + '/' + filename, expectedPath + '/' + filename);
});
return;
}
var expected = fs.readFileSync(expectedPath);
checkFileContentInZip(zipPath, pathInZip, expected);
}
function checkFileContentInZip(zipPath, pathInZip, expectedContent, isJSON) {
var zip = new AdmZip(zipPath);
var entry = zip.getEntry(pathInZip);
var actual = isJSON ? JSON.parse(zip.readAsText(entry)) : zip.readFile(entry);
assert.deepEqual(actual, expectedContent,
'Checking ' + pathInZip + ' in ' + zipPath);
}
function checkFileContentByPathInZip(zipPath, pathInZip,
expectedFilePath,isJSON) {
var actual;
try {
actual =
isJSON ? JSON.parse(fs.readFileSync(expectedFilePath)) :
fs.readFileSync(expectedFilePath);
} catch (e) {
actual = isJSON ? {} : null;
}
checkFileContentInZip(zipPath, pathInZip, actual, isJSON);
}
function matchFileContentInZip(zipPath, pathInZip, matchPattern) {
var zip = new AdmZip(zipPath);
var entry = zip.getEntry(pathInZip);
var content = zip.readAsText(entry);
assert.ok(matchPattern.test(content));
}
function exec(command, options, callback) {
var opts = {
maxBuffer: 4096 * 1024
};
if (typeof options !== 'function') {
for (var key in options) {
if (options.hasOwnProperty(key)) {
opts[key] = options[key];
}
}
} else {
callback = options;
}
childProcess.exec(command, opts, callback);
}
function emptyJsonFile(filePath) {
var content = fs.readFileSync(filePath);
fs.unlinkSync(filePath);
fs.writeFileSync(filePath, '{}');
var restoreFunc = function() {
fs.writeFileSync(filePath, content);
};
return restoreFunc;
}
function cleanupWorkspace() {
rmrf('profile');
rmrf('profile-debug');
rmrf('build_stage');
rmrf(exports.localesDir);
}
exports.localesDir = 'tmplocales';
exports.getPrefsSandbox = getPrefsSandbox;
exports.checkError = checkError;
exports.checkSettings = checkSettings;
exports.checkPrefs = checkPrefs;
exports.checkWebappsScheme = checkWebappsScheme;
exports.checkFilePathInZip = checkFilePathInZip;
exports.checkFileInZip = exports.checkDirInZip = checkFileInZip;
exports.checkFileContentInZip = checkFileContentInZip;
exports.checkFileContentByPathInZip = checkFileContentByPathInZip;
exports.matchFileContentInZip = matchFileContentInZip;
exports.emptyJsonFile = emptyJsonFile;
exports.exec = exec;
exports.cleanupWorkspace = cleanupWorkspace;

View file

@ -0,0 +1,112 @@
'use strict';
var assert = require('chai').assert;
var fs = require('fs');
var path = require('path');
var AdmZip = require('adm-zip');
var helper = require('./helper');
suite('L10n logic tests', function() {
var appsListPath = path.join(
'build', 'config', 'phone', 'apps-engineering.list');
var apps = [
'apps/*',
'build/test/fixtures/test-l10n-optimize-entries',
'build/test/fixtures/test-l10n-optimize-legacy',
'build/test/fixtures/test-l10n-optimize-no-fetch',
'build/test/fixtures/test-l10n-missing',
'build/test/fixtures/test-l10n-duplicates',
'' // a line-break is required at the end of an apps file
];
suiteSetup(function() {
helper.cleanupWorkspace();
// add test-l10n-* apps to the apps list
fs.renameSync(appsListPath, appsListPath + '.bak');
fs.writeFileSync(appsListPath, apps.join('\n'));
});
suiteTeardown(function() {
fs.unlinkSync(appsListPath);
fs.renameSync(appsListPath + '.bak', appsListPath);
helper.cleanupWorkspace();
});
test('make test-l10n-optimize-entries builds JSON', function(done) {
helper.exec('APP=test-l10n-optimize-entries make',
function(error, stdout, stderr) {
helper.checkError(error, stdout, stderr);
var expected = {entity1: 'My Entity', entity2: 'Entity 2'};
var testZip = new AdmZip(path.join(
process.cwd(), 'profile', 'webapps',
'test-l10n-optimize-entries.gaiamobile.org', 'application.zip'));
var entries = JSON.parse(
testZip.readAsText(
testZip.getEntry('locales-obj/index.en-US.json')));
assert.deepEqual(entries, expected);
done();
}
);
});
test('make test-l10n-optimize-legacy builds legacy JSON', function(done) {
helper.exec('APP=test-l10n-optimize-legacy make',
function(error, stdout, stderr) {
helper.checkError(error, stdout, stderr);
var expected = [{'$i':'entity1','$v':'My Entity'}];
var testZip = new AdmZip(path.join(
process.cwd(), 'profile', 'webapps',
'test-l10n-optimize-legacy.gaiamobile.org', 'application.zip'));
var entries = JSON.parse(
testZip.readAsText(
testZip.getEntry('locales-obj/index.en-US.json')));
assert.deepEqual(entries, expected);
done();
}
);
});
test('make test-l10n-optimize-no-fetch build noFetch file', function(done) {
helper.exec('APP=test-l10n-optimize-no-fetch make',
function(error, stdout, stderr) {
helper.checkError(error, stdout, stderr);
var expectedScript = '<script type="application/l10n" lang="en-US">\n'+
' [{"$i":"entity1","$v":"My Entity"}]\n' +
'</script>';
var testZip = new AdmZip(path.join(
process.cwd(), 'profile', 'webapps',
'test-l10n-optimize-no-fetch.gaiamobile.org', 'application.zip'));
var indexHtml =
testZip.readAsText(testZip.getEntry('index.html'));
assert.ok(indexHtml.indexOf(expectedScript) !== -1);
done();
}
);
});
test('make test-l10n-missing detects a missing string', function(done) {
helper.exec('APP=test-l10n-missing make',
function(error, stdout, stderr) {
assert.include(
stdout,
'[Error] L10nError: "entity0" not found in en-US ' +
'(app://test-l10n-missing.gaiamobile.org)');
done();
}
);
});
test('make test-l10n-duplicates detects a duplicate string', function(done) {
helper.exec('APP=test-l10n-duplicates make',
function(error, stdout, stderr) {
assert.include(
stdout,
'[Error] L10nError: Duplicate string "entity1" found in en-US ' +
'(app://test-l10n-duplicates.gaiamobile.org)');
done();
}
);
});
});

View file

@ -0,0 +1,345 @@
'use strict';
/* jshint maxlen: 130 */
var assert = require('chai').assert;
var fs = require('fs');
var path = require('path');
var vm = require('vm');
var helper = require('./helper');
var dive = require('diveSync');
var AdmZip = require('adm-zip');
const MAX_PROFILE_SIZE_MB = 65;
const MAX_PROFILE_SIZE = MAX_PROFILE_SIZE_MB * 1024 * 1024;
const REBUILD_TEST_FILE = path.join(
process.cwd() + '/apps/system/rebuild_test.txt');
const WEBAPPS_DIR = path.join(process.cwd() + '/profile/webapps');
suite('Make and remake tests', function() {
suiteSetup(helper.cleanupWorkspace);
teardown(function() {
helper.cleanupWorkspace();
cleanTestFiles();
});
var ignoredApps = getCustomizedBuildApp();
function cleanTestFiles() {
if (fs.existsSync(REBUILD_TEST_FILE)) {
fs.unlinkSync(REBUILD_TEST_FILE);
}
}
function getTimestamp(dirPath, filter) {
var timestamp = {};
dive(dirPath, { filter: filter }, function(err, file) {
if (err) {
throw err;
}
timestamp[file] = fs.statSync(file).mtime.getTime();
});
return timestamp;
}
function getWebapps() {
var file = fs.readFileSync(
WEBAPPS_DIR + '/webapps.json', { encoding: 'utf8' });
return Object.keys(JSON.parse(file)).filter(function(app) {
return (/\{.+\}/.test(app) === -1);
});
}
function getCustomizedBuildApp() {
var cwd = process.cwd();
var apps = [];
var filter = function(file, dir) {
// There are other folders we could avoid but walking the node_modules
// folder can be problematic when using pre-built caches (and it's slow).
if (dir && (file.indexOf(cwd + '/node_modules') !== 0)) {
return true;
}
var pattern = new RegExp(
'(' + cwd + '/apps|' + cwd + '/dev_apps)\\S+/build/build.js$');
return pattern.test(file);
};
dive(cwd, { filter: filter }, function(err, file) {
if (err) {
throw err;
}
var domain = '.gaiamobile.org';
apps.push(file.match(/(\S+)\/(\S+)\/build\/build\.js/)[2] + domain);
});
return apps;
}
test('make without rule & variable', function(done) {
helper.exec('make', function(error, stdout, stderr) {
helper.checkError(error, stdout, stderr);
// expected values for prefs and user_prefs
var expectedUserPrefs = {
'network.http.max-connections-per-server': 15,
'dom.mozInputMethod.enabled': true,
'ril.debugging.enabled': false,
'dom.mms.version': 17,
'b2g.wifi.allow_unsafe_wpa_eap': true
};
var expectedPrefs = {
'geo.gps.supl_server': 'supl.izatcloud.net',
'geo.gps.supl_port': 22024,
'dom.payment.provider.0.name': 'firefoxmarket',
'dom.payment.provider.0.description': 'marketplace.firefox.com',
'dom.payment.provider.0.uri': 'https://marketplace.firefox.com/mozpay/?req=',
'dom.payment.provider.0.type': 'mozilla/payments/pay/v1',
'dom.payment.provider.0.requestMethod': 'GET',
'dom.payment.skipHTTPSCheck': true,
'dom.payment.debug': true,
'dom.payment.provider.1.name': 'firefoxmarketdev',
'dom.payment.provider.1.description': 'marketplace-dev.allizom.org',
'dom.payment.provider.1.uri': 'https://marketplace-dev.allizom.org/mozpay/?req=',
'dom.payment.provider.1.type': 'mozilla-dev/payments/pay/v1',
'dom.payment.provider.1.requestMethod': 'GET',
'dom.payment.provider.2.name': 'firefoxmarketstage',
'dom.payment.provider.2.description': 'marketplace.allizom.org',
'dom.payment.provider.2.uri': 'https://marketplace.allizom.org/mozpay/?req=',
'dom.payment.provider.2.type': 'mozilla-stage/payments/pay/v1',
'dom.payment.provider.2.requestMethod': 'GET',
'dom.payment.provider.3.name': 'mockpayprovider',
'dom.payment.provider.3.description': 'Mock Payment Provider',
'dom.payment.provider.3.uri': 'http://ferjm.github.io/gaia-mock-payment-provider/index.html?req=',
'dom.payment.provider.3.type': 'tests/payments/pay/v1',
'dom.payment.provider.3.requestMethod': 'GET'
};
// expected values for settings.json from build/config/common-settings.json
var settingsPath = path.join(process.cwd(), 'profile', 'settings.json');
var commonSettingsPath = path.join(process.cwd(), 'build', 'config',
'common-settings.json');
var settings = JSON.parse(fs.readFileSync(settingsPath));
var commonSettings = JSON.parse(fs.readFileSync(commonSettingsPath));
// we change these settings values in build/settings.js if
// TARGET_BUILD_VARIANT is not 'user'
var ignoreSettings = [
'apz.force-enable',
'debug.console.enabled',
'developer.menu.enabled'
];
ignoreSettings.forEach(function(key) {
if (commonSettings[key] !== undefined) {
delete commonSettings[key];
}
});
// path in zip for unofficial branding
var pathInZip = 'shared/resources/branding/initlogo.png';
// zip path for system app
var zipPath = path.join(process.cwd(), 'profile', 'webapps',
'system.gaiamobile.org', 'application.zip');
// expected branding file, it should be a unofficial branding if we
// execute |make| without rule and variable.
var expectedBrandingPath = path.join(process.cwd(),
'shared', 'resources', 'branding', 'unofficial', 'initlogo.png');
// Read user.js and use vm module to execute javascript in user.js
var userjs = fs.readFileSync(
path.join('profile', 'user.js'),
{ encoding: 'utf8' }
);
var sandbox = helper.getPrefsSandbox();
vm.runInNewContext(userjs, sandbox);
var webapps = JSON.parse(fs.readFileSync(path.join(process.cwd(),
'profile', 'webapps', 'webapps.json')));
helper.checkSettings(settings, commonSettings);
helper.checkPrefs(sandbox.userPrefs, expectedUserPrefs);
helper.checkPrefs(sandbox.prefs, expectedPrefs);
helper.checkWebappsScheme(webapps);
helper.checkFileInZip(zipPath, pathInZip, expectedBrandingPath);
// Check config.js file of gallery
var hsGalleryZip = new AdmZip(path.join(process.cwd(), 'profile',
'webapps', 'gallery.gaiamobile.org', 'application.zip'));
var hsGalleryConfigJs =
hsGalleryZip.readAsText(hsGalleryZip.getEntry('js/config.js'));
var expectedScript =
'//\n' +
'// This file is automatically generated: DO NOT EDIT.\n' +
'//\n'+
'// The default value of these variables depends on the\n'+
'// GAIA_MEMORY_PROFILE environment variable. Set\n'+
'// GAIA_MEMORY_PROFILE=low when building Gaia to get default\n'+
'// values suitable for low-memory devices.\n'+
'//\n'+
'// To customize these values, create a gallery.json file in the\n' +
'// distribution directory with content like this:\n' + '//\n' +
'// {\n' +
'// "maxImagePixelSize": 6000000,\n' +
'// "maxSnapshotPixelSize": 4000000,\n' +
'// "maxPickPixelSize": 480000,\n' +
'// "maxEditPixelSize": 480000 }\n' +
'// }\n' +
'//\n' +
'// Optionally, you can also define variables to specify the\n' +
'// minimum EXIF preview size that will be displayed as a\n' +
'// full-screen preview by adding a property like this:\n' +
'//\n' +
'// "requiredEXIFPreviewSize": { "width": 640, "height": 480}\n' +
'//\n' +
'// If you do not specify this property then EXIF previews will only\n' +
'// be used if they are big enough to fill the screen in either\n' +
'// width or height in both landscape and portrait mode.\n' +
'//\n' +
'var CONFIG_MAX_IMAGE_PIXEL_SIZE = ' +
5 * 1024 * 1024 + ';\n' +
'var CONFIG_MAX_SNAPSHOT_PIXEL_SIZE = ' +
5 * 1024 * 1024 + ';\n' +
'var CONFIG_MAX_PICK_PIXEL_SIZE = ' +
0 + ';\n' +
'var CONFIG_MAX_EDIT_PIXEL_SIZE = ' +
0 + ';\n' +
'var CONFIG_REQUIRED_EXIF_PREVIEW_WIDTH = 0;\n' +
'var CONFIG_REQUIRED_EXIF_PREVIEW_HEIGHT = 0;\n';
assert.equal(hsGalleryConfigJs, expectedScript,
'Gallery config js is not expected');
var musicMetadataScriptPath = path.join(process.cwd(), 'build_stage',
'music', 'js', 'metadata', 'metadata_scripts.js');
assert.ok(fs.existsSync(musicMetadataScriptPath), 'metadata_scripts.js ' +
'should exist');
var galleryMetadataScriptPath = path.join(process.cwd(), 'build_stage',
'gallery', 'js', 'metadata_scripts.js');
assert.ok(fs.existsSync(galleryMetadataScriptPath),
'metadata_scripts.js should exist');
assert.ok(fs.existsSync(galleryMetadataScriptPath),
'frame_scripts.js should exist');
var profileSize = 0;
dive(path.join(process.cwd(), 'profile'), function(err, file) {
if (err) {
throw err;
}
profileSize += fs.statSync(file).size;
});
assert(profileSize < MAX_PROFILE_SIZE,
'profile size should be less than ' + MAX_PROFILE_SIZE_MB +
'MB, current is ' + (profileSize / 1024 / 1024).toFixed(2) + 'MB');
done();
});
});
test('make twice without modifying anything', function(done) {
var previousOtherAppsTime;
var currentOtherAppsTime;
var previousUUIDAppsTime;
var currentUUIDAppsTime;
var previousWebapps;
var currentWebapps;
var options = {
maxBuffer: 400 * 1024,
env: {
PATH: process.env.PATH,
HOME: process.env.HOME
}
};
var filterOtherApps = function(file, dir) {
if (dir) {
return true;
}
var hasCustomizedBuild = ignoredApps.some(function(domain) {
return file.indexOf(domain) !== -1;
});
return !hasCustomizedBuild && !/(\{.+\}|webapps\.json)/.test(file);
};
var filterUUIDApps = function(file, dir) {
if (dir) {
return true;
}
return /\{.+\}/.test(file);
};
helper.exec('make', options, function(error, stdout, stderr) {
helper.checkError(error, stdout, stderr);
previousOtherAppsTime = getTimestamp(WEBAPPS_DIR, filterOtherApps);
previousUUIDAppsTime = getTimestamp(WEBAPPS_DIR, filterUUIDApps);
previousWebapps = getWebapps();
helper.exec('make', options, function(error, stdout, stderr) {
var webapps = JSON.parse(fs.readFileSync(path.join(process.cwd(),
'profile', 'webapps', 'webapps.json')));
helper.checkError(error, stdout, stderr);
helper.checkWebappsScheme(webapps);
currentOtherAppsTime = getTimestamp(WEBAPPS_DIR, filterOtherApps);
currentUUIDAppsTime = getTimestamp(WEBAPPS_DIR, filterUUIDApps);
currentWebapps = getWebapps();
assert.deepEqual(previousOtherAppsTime, currentOtherAppsTime);
assert.sameMembers(previousWebapps, currentWebapps);
assert.equal(Object.keys(previousUUIDAppsTime).length,
Object.keys(currentUUIDAppsTime).length);
done();
});
});
});
test('make twice with adding a file', function(done) {
var previousSystemTime;
var currentSystemTime;
var previousOtherAppsTime;
var currentOtherAppsTime;
var previousWebapps;
var currentWebapps;
var options = {
maxBuffer: 400 * 1024,
env: {
PATH: process.env.PATH,
HOME: process.env.HOME
}
};
var systemAppfilter = function(file, dir) {
if (dir) {
return true;
}
return (file.indexOf('system.gaiamobile.org') !== -1);
};
var otherAppsFilter = function(file, dir) {
if (dir) {
return true;
}
var hasCustomizedBuild = ignoredApps.some(function(domain) {
return file.indexOf(domain) !== -1;
});
return !hasCustomizedBuild &&
/(\{.+\}|system\.gaiamobile\.org|webapps\.json)/.test(file) === false;
};
helper.exec('make', options, function(error, stdout, stderr) {
helper.checkError(error, stdout, stderr);
previousSystemTime = getTimestamp(WEBAPPS_DIR, systemAppfilter);
previousOtherAppsTime = getTimestamp(WEBAPPS_DIR, otherAppsFilter);
previousWebapps = getWebapps();
fs.writeFileSync(REBUILD_TEST_FILE, 'test');
helper.exec('make', options, function(error, stdout, stderr) {
var webapps = JSON.parse(fs.readFileSync(path.join(process.cwd(),
'profile', 'webapps', 'webapps.json')));
helper.checkError(error, stdout, stderr);
helper.checkWebappsScheme(webapps);
currentSystemTime = getTimestamp(WEBAPPS_DIR, systemAppfilter);
currentOtherAppsTime = getTimestamp(WEBAPPS_DIR, otherAppsFilter);
currentWebapps = getWebapps();
assert.notDeepEqual(previousSystemTime, currentSystemTime);
assert.deepEqual(previousOtherAppsTime, currentOtherAppsTime);
assert.sameMembers(previousWebapps, currentWebapps);
done();
});
});
});
});

View file

@ -0,0 +1,26 @@
'use strict';
var path = require('path');
var helper = require('./helper');
suite('MOZILLA_OFFICAL=1', function() {
suiteSetup(helper.cleanupWorkspace);
teardown(helper.cleanupWorkspace);
test('make with MOZILLA_OFFICIAL=1', function(done) {
helper.exec('MOZILLA_OFFICIAL=1 make', function(error, stdout, stderr) {
helper.checkError(error, stdout, stderr);
// path in zip for unofficial branding
var pathInZip = 'shared/resources/branding/initlogo.png';
// zip path for system app
var zipPath = path.join(process.cwd(), 'profile', 'webapps',
'system.gaiamobile.org', 'application.zip');
var expectedBrandingPath = path.join(process.cwd(),
'shared', 'resources', 'branding', 'official', 'initlogo.png');
helper.checkFileInZip(zipPath, pathInZip, expectedBrandingPath);
done();
});
});
});

View file

@ -0,0 +1,73 @@
'use strict';
var assert = require('chai').assert;
var path = require('path');
var AdmZip = require('adm-zip');
var helper = require('./helper');
suite('Multilocale integration tests', function() {
var localesDir = 'build/test/resources/locales';
var localesFileObj = {'en-US': '', 'zh-CN': ''};
suiteSetup(helper.cleanupWorkspace);
teardown(helper.cleanupWorkspace);
function makeHelper(localesFilePath, localesDir, concat, done) {
var settingsZipPath = path.join(process.cwd(), 'profile', 'webapps',
'settings.gaiamobile.org', 'application.zip');
var cnPathInZip = 'locales-obj/index.zh-CN.json';
var cnSettingsProperties = 'locales/settings.zh-CN.properties';
var langPathInZip = 'shared/resources/languages.json';
var command = 'LOCALES_FILE=' + localesFilePath +
' LOCALE_BASEDIR=' + localesDir +
' make';
if (!concat) {
command = 'GAIA_CONCAT_LOCALES=0 ' + command;
}
helper.exec(command, function(error, stdout, stderr) {
helper.checkError(error, stdout, stderr);
var zip = new AdmZip(settingsZipPath);
if (concat) {
assert.isNotNull(zip.getEntry(cnPathInZip),
'concat file ' + cnPathInZip + ' should exist');
} else {
assert.isNotNull(zip.getEntry(cnSettingsProperties),
'properties file ' + cnSettingsProperties + ' should exist');
}
assert.deepEqual(JSON.parse(zip.readAsText(langPathInZip)),
localesFileObj);
var manifest =
JSON.parse(zip.readAsText(zip.getEntry('manifest.webapp')));
assert.equal(manifest.locales['en-US'].description, 'Gaia Settings');
done();
});
}
test('make with relative l10n path', function(done) {
var localesFilePath = path.join(localesDir, 'languages.json');
makeHelper(localesFilePath, localesDir, true, done);
});
test('make with absolute l10n path', function(done) {
var localesFilePath =
path.join(process.cwd(), localesDir, 'languages.json');
var absoluteLocalesDir = path.join(process.cwd(), localesDir);
makeHelper(localesFilePath, absoluteLocalesDir, true, done);
});
test('make with relative l10n path but without concat', function(done) {
var localesFilePath = path.join(localesDir, 'languages.json');
makeHelper(localesFilePath, localesDir, false, done);
});
test('make with absolute l10n path but without concat', function(done) {
var localesFilePath =
path.join(process.cwd(), localesDir, 'languages.json');
var absoluteLocalesDir = path.join(process.cwd(), localesDir);
makeHelper(localesFilePath, absoluteLocalesDir, false, done);
});
});

View file

@ -0,0 +1,18 @@
'use strict';
var helper = require('./helper');
suite('GAIA_OPTIMIZE=1', function() {
suiteSetup(helper.cleanupWorkspace);
teardown(helper.cleanupWorkspace);
test('make with GAIA_OPTIMIZE=1 BUILD_DEBUG=1',
function(done) {
helper.exec('GAIA_OPTIMIZE=1 BUILD_DEBUG=1 make',
function(error, stdout, stderr) {
helper.checkError(error, stdout, stderr);
done();
}
);
});
});

View file

@ -0,0 +1,42 @@
'use strict';
var assert = require('chai').assert;
var fs = require('fs');
var path = require('path');
var vm = require('vm');
var helper = require('./helper');
suite('PRODUCTION=1', function() {
suiteSetup(helper.cleanupWorkspace);
teardown(helper.cleanupWorkspace);
test('make with PRODUCTION=1', function(done) {
helper.exec('PRODUCTION=1 make', function(error, stdout, stderr) {
helper.checkError(error, stdout, stderr);
var settingsPath = path.join(process.cwd(), 'profile', 'settings.json');
var settings = JSON.parse(fs.readFileSync(settingsPath));
var expectedSettings = {
'feedback.url': 'https://input.mozilla.org/api/v1/feedback/'
};
var userjs = fs.readFileSync(
path.join('profile', 'user.js'),
{ encoding: 'utf8' }
);
var sandbox = helper.getPrefsSandbox();
vm.runInNewContext(userjs, sandbox);
helper.checkSettings(settings, expectedSettings);
assert.isUndefined(sandbox.prefs['dom.payment.skipHTTPSCheck']);
// zip path for system app
var zipPath = path.join(process.cwd(), 'profile', 'webapps',
'uitest.gaiamobile.org', 'application.zip');
// uitest should not exists in production builds
assert.isFalse(fs.existsSync(zipPath));
done();
});
});
});

View file

@ -0,0 +1,37 @@
'use strict';
/* jshint node: true, mocha: true */
/* global suiteSetup */
var assert = require('chai').assert;
var path = require('path');
var AdmZip = require('adm-zip');
var helper = require('./helper');
suite('buildtime pseudolocalizations', function() {
suiteSetup(helper.cleanupWorkspace);
teardown(helper.cleanupWorkspace);
test('are included by default', function(done) {
helper.exec('make', function(error, stdout, stderr) {
helper.checkError(error, stdout, stderr);
var zipPath = path.join(process.cwd(), 'profile', 'webapps',
'system.gaiamobile.org', 'application.zip');
var zip = new AdmZip(zipPath);
var enUSFileInZip = zip.getEntry('locales-obj/index.en-US.json');
var psaccentPathInZip = 'locales-obj/index.fr-x-psaccent.json';
var psaccentFileInZip = zip.getEntry(psaccentPathInZip);
assert.isNotNull(
psaccentFileInZip,
'Accented English file ' + psaccentPathInZip + ' should exist');
assert.notDeepEqual(
JSON.parse(zip.readAsText(psaccentFileInZip)),
JSON.parse(zip.readAsText(enUSFileInZip)),
'Accented English file should not be identical to regular English');
done();
});
});
});

View file

@ -0,0 +1,18 @@
'use strict';
var helper = require('./helper');
suite('shared CSS', function() {
suiteSetup(helper.cleanupWorkspace);
teardown(helper.cleanupWorkspace);
test('make APP=test-shared-css-app, checking shared css are imported',
function(done) {
var command = 'make APP=test-shared-css-app ' +
'GAIA_APP_CONFIG=' + __dirname + '/../fixtures/shared_css.list';
helper.exec(command, function(error, stdout, stderr) {
helper.checkError(error, stdout, stderr);
done();
});
});
});