mirror of
https://github.com/kiwix/kiwix-js.git
synced 2025-08-03 11:16:38 -04:00
399 lines
19 KiB
JavaScript
399 lines
19 KiB
JavaScript
/**
|
||
* 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¶m2=titi",
|
||
"A/Che%20cosa%20%C3%A8%20l'amore%3F.html?param1=toto¶m2=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();
|
||
};
|