kiwix-js/tests/unit/spec/tests.js

399 lines
19 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* tests.js : Unit tests implemented with qunit
*
* Copyright 2013-2014 Mossroy and contributors
* License GPL v3:
*
* This file is part of Kiwix.
*
* Kiwix is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Kiwix is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kiwix (file LICENSE-GPLv3.txt). If not, see <http://www.gnu.org/licenses/>
*/
/* global QUnit, Promise */
// import '../www/js/lib/promisePolyfill.js';
// import '../www/js/lib/arrayFromPolyfill.js';
import '../js/init.js';
// import '../www/js/app.js';
import zimArchive from '../../../www/js/lib/zimArchive.js';
import zimDirEntry from '../../../www/js/lib/zimDirEntry.js';
import util from '../../../www/js/lib/util.js';
import uiUtil from '../../../www/js/lib/uiUtil.js';
import utf8 from '../../../www/js/lib/utf8.js';
var localZimArchive;
/**
* Make an HTTP request for a Blob and return a Promise
*
* @param {String} url URL to download from
* @param {String} name Name to give to the Blob instance
* @returns {Promise<Blob>} A Promise for the Blob
*/
function makeBlobRequest (url, name) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onreadystatechange = function () {
if (xhr.readyState === XMLHttpRequest.DONE) {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 0) {
var blob = new Blob([xhr.response], { type: 'application/octet-stream' });
blob.name = name;
resolve(blob);
} else {
console.error('Error reading file ' + url + ' status:' + xhr.status + ', statusText:' + xhr.statusText);
reject(new Error({
status: xhr.status,
statusText: xhr.statusText
}));
}
}
};
xhr.onerror = function () {
console.error('Error reading file ' + url + ' status:' + xhr.status + ', statusText:' + xhr.statusText);
reject(new Error({
status: xhr.status,
statusText: xhr.statusText
}));
};
xhr.responseType = 'blob';
xhr.send();
});
}
// Let's try to download the ZIM files
var zimArchiveFiles = [];
var splitBlobs = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o'].map(function (c) {
var filename = 'wikipedia_en_ray_charles_2015-06.zima' + c;
return makeBlobRequest('tests/zims/legacy-ray-charles/' + filename, filename);
});
Promise.all(splitBlobs)
.then(function (values) {
zimArchiveFiles = values;
}).then(function () {
// Create a localZimArchive from selected files, in order to run the following tests
localZimArchive = new zimArchive.ZIMArchive(zimArchiveFiles, null, function (zimArchive) {
runTests();
});
});
var runTests = function () {
QUnit.module('environment');
QUnit.test('qunit test', function (assert) {
assert.equal('test', 'test', 'QUnit is properly configured');
});
QUnit.test('check archive files are read', function (assert) {
assert.ok(zimArchiveFiles && zimArchiveFiles[0] && zimArchiveFiles[0].size > 0, 'ZIM file read and not empty');
});
QUnit.module('utils');
QUnit.test('check reading an IEEE_754 float from 4 bytes', function (assert) {
var byteArray = new Uint8Array(4);
// This example is taken from https://fr.wikipedia.org/wiki/IEEE_754#Un_exemple_plus_complexe
// 1100 0010 1110 1101 0100 0000 0000 0000
byteArray[0] = 194;
byteArray[1] = 237;
byteArray[2] = 64;
byteArray[3] = 0;
var float = util.readFloatFrom4Bytes(byteArray, 0);
assert.equal(float, -118.625, 'the IEEE_754 float should be converted as -118.625');
});
QUnit.test('check upper/lower case variations', function (assert) {
var testString1 = 'téléphone';
var testString2 = 'Paris';
var testString3 = 'le Couvre-chef Est sur le porte-manteaux';
var testString4 = 'épée';
var testString5 = '$¥€“«xριστός» †¡Ἀνέστη!”';
var testString6 = 'Καλά Νερά Μαγνησία žižek';
assert.equal(util.allCaseFirstLetters(testString1).indexOf('Téléphone') >= 0, true, 'The first letter should be uppercase');
assert.equal(util.allCaseFirstLetters(testString2).indexOf('paris') >= 0, true, 'The first letter should be lowercase');
assert.equal(util.allCaseFirstLetters(testString3).indexOf('Le Couvre-Chef Est Sur Le Porte-Manteaux') >= 0, true, 'The first letter of every word should be uppercase');
assert.equal(util.allCaseFirstLetters(testString4).indexOf('Épée') >= 0, true, 'The first letter should be uppercase (with accent)');
assert.equal(util.allCaseFirstLetters(testString5).indexOf('$¥€“«Xριστός» †¡ἀνέστη!”') >= 0, true, 'First non-punctuation/non-currency Unicode letter should be uppercase, second (with breath mark) lowercase');
assert.equal(util.allCaseFirstLetters(testString6, 'full').indexOf('ΚΑΛΆ ΝΕΡΆ ΜΑΓΝΗΣΊΑ ŽIŽEK') >= 0, true, 'All Unicode letters should be uppercase');
});
QUnit.test('check removal of parameters in URL', function (assert) {
var baseUrl = "A/Che cosa è l'amore?.html";
var testUrls = [
"A/Che%20cosa%20%C3%A8%20l'amore%3F.html?param1=toto&param2=titi",
"A/Che%20cosa%20%C3%A8%20l'amore%3F.html?param1=toto&param2=titi#anchor",
"A/Che%20cosa%20%C3%A8%20l'amore%3F.html#anchor"
];
testUrls.forEach(function (testUrl) {
assert.equal(decodeURIComponent(
uiUtil.removeUrlParameters(testUrl)
), baseUrl);
});
});
QUnit.module('ZIM initialisation');
QUnit.test('ZIM archive is ready', function (assert) {
assert.ok(localZimArchive.isReady() === true, 'ZIM archive should be set as ready');
});
QUnit.module('ZIM metadata');
QUnit.test('read ZIM language', function (assert) {
var done = assert.async();
assert.expect(1);
var callbackFunction = function (language) {
assert.equal(language, 'eng', 'The language read inside the Metadata should be "eng" for "English"');
done();
};
localZimArchive.getMetadata('Language', callbackFunction);
});
QUnit.test('try to read a missing metadata', function (assert) {
var done = assert.async();
assert.expect(1);
var callbackFunction = function (string) {
assert.equal(string, undefined, 'The metadata zzz should not be found inside the ZIM');
done();
};
localZimArchive.getMetadata('zzz', callbackFunction);
});
QUnit.module('zim_direntry_search_and_read');
QUnit.test("check DirEntry.fromStringId 'A Fool for You'", function (assert) {
var done = assert.async();
var aFoolForYouDirEntry = zimDirEntry.DirEntry.fromStringId(localZimArchive.file, '5856|7|A|0|2|A_Fool_for_You.html|A Fool for You|false|undefined');
assert.expect(2);
var callbackFunction = function (dirEntry, htmlArticle) {
assert.ok(htmlArticle && htmlArticle.length > 0, 'Article not empty');
// Remove new lines
htmlArticle = htmlArticle.replace(/[\r\n]/g, ' ');
assert.ok(htmlArticle.match('^.*<h1[^>]*>A Fool for You</h1>'), "'A Fool for You' title somewhere in the article");
done();
};
localZimArchive.readUtf8File(aFoolForYouDirEntry, callbackFunction);
});
QUnit.test("check findDirEntriesWithPrefix 'A'", function (assert) {
var done = assert.async();
assert.expect(2);
var callbackFunction = function (dirEntryList) {
assert.ok(dirEntryList && dirEntryList.length === 5, 'Article list with 5 results');
var firstDirEntry = dirEntryList[0];
assert.equal(firstDirEntry.getTitleOrUrl(), 'A Fool for You', 'First result should be "A Fool for You"');
done();
};
localZimArchive.findDirEntriesWithPrefix({ prefix: 'A', size: 5 }, callbackFunction, true);
});
QUnit.test("check findDirEntriesWithPrefix 'a'", function (assert) {
var done = assert.async();
assert.expect(2);
var callbackFunction = function (dirEntryList) {
assert.ok(dirEntryList && dirEntryList.length === 5, 'Article list with 5 results');
var firstDirEntry = dirEntryList[0];
assert.equal(firstDirEntry.getTitleOrUrl(), 'A Fool for You', 'First result should be "A Fool for You"');
done();
};
localZimArchive.findDirEntriesWithPrefix({ prefix: 'a', size: 5 }, callbackFunction, true);
});
QUnit.test("check findDirEntriesWithPrefix 'blues brothers'", function (assert) {
var done = assert.async();
assert.expect(2);
var callbackFunction = function (dirEntryList) {
assert.ok(dirEntryList && dirEntryList.length === 3, 'Article list with 3 result');
var firstDirEntry = dirEntryList[0];
assert.equal(firstDirEntry.getTitleOrUrl(), 'Blues Brothers (film)', 'First result should be "Blues Brothers (film)"');
done();
};
localZimArchive.findDirEntriesWithPrefix({ prefix: 'blues brothers', size: 5 }, callbackFunction, true);
});
QUnit.test("article '(The Night Time Is) The Right Time' correctly redirects to 'Night Time Is the Right Time'", function (assert) {
var done = assert.async();
assert.expect(6);
localZimArchive.getDirEntryByPath('A/(The_Night_Time_Is)_The_Right_Time.html').then(function (dirEntry) {
assert.ok(dirEntry !== null, 'DirEntry found');
if (dirEntry !== null) {
assert.ok(dirEntry.isRedirect(), 'DirEntry is a redirect.');
assert.equal(dirEntry.getTitleOrUrl(), '(The Night Time Is) The Right Time', 'Correct redirect title name.');
localZimArchive.resolveRedirect(dirEntry, function (dirEntry) {
assert.ok(dirEntry !== null, 'DirEntry found');
assert.ok(!dirEntry.isRedirect(), 'DirEntry is not a redirect.');
assert.equal(dirEntry.getTitleOrUrl(), 'Night Time Is the Right Time', 'Correct redirected title name.');
done();
});
} else {
done();
}
});
});
QUnit.test("article 'Raelettes' correctly redirects to 'The Raelettes'", function (assert) {
var done = assert.async();
assert.expect(6);
localZimArchive.getDirEntryByPath('A/Raelettes.html').then(function (dirEntry) {
assert.ok(dirEntry !== null, 'DirEntry found');
if (dirEntry !== null) {
assert.ok(dirEntry.isRedirect(), 'DirEntry is a redirect.');
assert.equal(dirEntry.getTitleOrUrl(), 'Raelettes', 'Correct redirect title name.');
localZimArchive.resolveRedirect(dirEntry, function (dirEntry) {
assert.ok(dirEntry !== null, 'DirEntry found');
assert.ok(!dirEntry.isRedirect(), 'DirEntry is not a redirect.');
assert.equal(dirEntry.getTitleOrUrl(), 'The Raelettes', 'Correct redirected title name.');
done();
});
} else {
done();
}
});
});
QUnit.test("article 'Bein Green' correctly redirects to 'Bein' Green", function (assert) {
var done = assert.async();
assert.expect(6);
localZimArchive.getDirEntryByPath('A/Bein_Green.html').then(function (dirEntry) {
assert.ok(dirEntry !== null, 'DirEntry found');
if (dirEntry !== null) {
assert.ok(dirEntry.isRedirect(), 'DirEntry is a redirect.');
assert.equal(dirEntry.getTitleOrUrl(), 'Bein Green', 'Correct redirect title name.');
localZimArchive.resolveRedirect(dirEntry, function (dirEntry) {
assert.ok(dirEntry !== null, 'DirEntry found');
assert.ok(!dirEntry.isRedirect(), 'DirEntry is not a redirect.');
assert.equal(dirEntry.getTitleOrUrl(), "Bein' Green", 'Correct redirected title name.');
done();
});
} else {
done();
}
});
});
QUnit.test("article 'America, the Beautiful' correctly redirects to 'America the Beautiful'", function (assert) {
var done = assert.async();
assert.expect(6);
localZimArchive.getDirEntryByPath('A/America,_the_Beautiful.html').then(function (dirEntry) {
assert.ok(dirEntry !== null, 'DirEntry found');
if (dirEntry !== null) {
assert.ok(dirEntry.isRedirect(), 'DirEntry is a redirect.');
assert.equal(dirEntry.getTitleOrUrl(), 'America, the Beautiful', 'Correct redirect title name.');
localZimArchive.resolveRedirect(dirEntry, function (dirEntry) {
assert.ok(dirEntry !== null, 'DirEntry found');
assert.ok(!dirEntry.isRedirect(), 'DirEntry is not a redirect.');
assert.equal(dirEntry.getTitleOrUrl(), 'America the Beautiful', 'Correct redirected title name.');
done();
});
} else {
done();
}
});
});
QUnit.test("Image 'm/RayCharles_AManAndHisSoul.jpg' can be loaded", function (assert) {
var done = assert.async();
assert.expect(5);
localZimArchive.getDirEntryByPath('I/m/RayCharles_AManAndHisSoul.jpg').then(function (dirEntry) {
assert.ok(dirEntry !== null, 'DirEntry found');
if (dirEntry !== null) {
assert.equal(dirEntry.namespace + '/' + dirEntry.url, 'I/m/RayCharles_AManAndHisSoul.jpg', 'URL is correct.');
assert.equal(dirEntry.getMimetype(), 'image/jpeg', 'MIME type is correct.');
localZimArchive.readBinaryFile(dirEntry, function (title, data) {
assert.equal(data.length, 4951, 'Data length is correct.');
var beginning = new Uint8Array([255, 216, 255, 224, 0, 16, 74, 70,
73, 70, 0, 1, 1, 0, 0, 1]);
assert.equal(data.slice(0, beginning.length).toString(), beginning.toString(), 'Data beginning is correct.');
done();
});
} else {
done();
}
});
});
QUnit.test("Stylesheet '-/s/style.css' can be loaded", function (assert) {
var done = assert.async();
assert.expect(5);
localZimArchive.getDirEntryByPath('-/s/style.css').then(function (dirEntry) {
assert.ok(dirEntry !== null, 'DirEntry found');
if (dirEntry !== null) {
assert.equal(dirEntry.namespace + '/' + dirEntry.url, '-/s/style.css', 'URL is correct.');
assert.equal(dirEntry.getMimetype(), 'text/css', 'MIME type is correct.');
localZimArchive.readBinaryFile(dirEntry, function (dirEntry, data) {
assert.equal(data.length, 104495, 'Data length is correct.');
data = utf8.parse(data);
var beginning = '\n/* start http://en.wikipedia.org/w/load.php?debug=false&lang=en&modules=site&only=styles&skin=vector';
assert.equal(data.slice(0, beginning.length), beginning, 'Content starts correctly.');
done();
});
} else {
done();
}
});
});
QUnit.test("Javascript '-/j/local.js' can be loaded", function (assert) {
var done = assert.async();
assert.expect(5);
localZimArchive.getDirEntryByPath('-/j/local.js').then(function (dirEntry) {
assert.ok(dirEntry !== null, 'DirEntry found');
if (dirEntry !== null) {
assert.equal(dirEntry.namespace + '/' + dirEntry.url, '-/j/local.js', 'URL is correct.');
assert.equal(dirEntry.getMimetype(), 'application/javascript', 'MIME type is correct.');
localZimArchive.readBinaryFile(dirEntry, function (dirEntry, data) {
assert.equal(data.length, 41, 'Data length is correct.');
data = utf8.parse(data);
var beginning = 'console.log( "mw.loader';
assert.equal(data.slice(0, beginning.length), beginning, 'Content starts correctly.');
done();
});
} else {
done();
}
});
});
QUnit.test("Split article 'A/Ray_Charles.html' can be loaded", function (assert) {
var done = assert.async();
assert.expect(7);
localZimArchive.getDirEntryByPath('A/Ray_Charles.html').then(function (dirEntry) {
assert.ok(dirEntry !== null, 'Title found');
if (dirEntry !== null) {
assert.equal(dirEntry.namespace + '/' + dirEntry.url, 'A/Ray_Charles.html', 'URL is correct.');
assert.equal(dirEntry.getMimetype(), 'text/html', 'MIME type is correct.');
localZimArchive.readUtf8File(dirEntry, function (dirEntry2, data) {
assert.equal(dirEntry2.getTitleOrUrl(), 'Ray Charles', 'Title is correct.');
assert.equal(data.length, 157186, 'Data length is correct.');
assert.equal(data.indexOf('the only true genius in show business'), 5535, 'Specific substring at beginning found.');
assert.equal(data.indexOf('Random Access Memories'), 154107, 'Specific substring at end found.');
done();
});
} else {
done();
}
});
});
QUnit.module('zim_random_and_main_article');
QUnit.test('check that a random article is found', function (assert) {
var done = assert.async();
assert.expect(2);
var callbackRandomArticleFound = function (dirEntry) {
assert.ok(dirEntry !== null, 'One DirEntry should be found');
assert.ok(dirEntry.getTitleOrUrl() !== null, 'The random DirEntry should have a title');
done();
};
localZimArchive.getRandomDirEntry(callbackRandomArticleFound);
});
QUnit.test('check that the main article is found', function (assert) {
var done = assert.async();
assert.expect(2);
var callbackMainPageArticleFound = function (dirEntry) {
assert.ok(dirEntry !== null, 'Main DirEntry should be found');
assert.equal(dirEntry.getTitleOrUrl(), 'Summary', 'The main DirEntry should be called Summary');
done();
};
localZimArchive.getMainPageDirEntry(callbackMainPageArticleFound);
});
QUnit.start();
};