diff --git a/chrome/content/zotero/preferences/preferences_search.js b/chrome/content/zotero/preferences/preferences_search.js index 2bc54a4be..c995a5e07 100644 --- a/chrome/content/zotero/preferences/preferences_search.js +++ b/chrome/content/zotero/preferences/preferences_search.js @@ -162,21 +162,8 @@ Zotero_Preferences.Search = { * if a newer version is available */ checkPDFToolsDownloadVersion: Zotero.Promise.coroutine(function* () { - var url = Zotero.Fulltext.pdfToolsDownloadBaseURL + 'latest.json'; - - // Find latest version for this platform try { - var xmlhttp = yield Zotero.HTTP.request("GET", url, { successCodes: [200, 404] }); - - if (xmlhttp.status == 404) { - throw 404; - } - - var platform = Zotero.platform.replace(/\s/g, '-'); - var json = JSON.parse(xmlhttp.responseText); - var latestVersion = json[platform] || json['default']; - - Zotero.debug("Latest PDF tools version for " + platform + " is " + latestVersion); + var latestVersion = yield Zotero.Fulltext.getLatestPDFToolsVersion(); var converterIsRegistered = Zotero.Fulltext.pdfConverterIsRegistered(); var infoIsRegistered = Zotero.Fulltext.pdfInfoIsRegistered(); @@ -189,7 +176,6 @@ Zotero_Preferences.Search = { var infoVersionAvailable = !infoIsRegistered || Zotero.Fulltext.pdfInfoVersion != '3.02a'; var bothAvailable = converterVersionAvailable && infoVersionAvailable; - latestVersion = "3.02a"; } // Install if not installed, version unknown, outdated, or // Xpdf 3.02/3.04 (to upgrade to Poppler), diff --git a/chrome/content/zotero/xpcom/fulltext.js b/chrome/content/zotero/xpcom/fulltext.js index 84ee1c959..fab78f13b 100644 --- a/chrome/content/zotero/xpcom/fulltext.js +++ b/chrome/content/zotero/xpcom/fulltext.js @@ -30,7 +30,7 @@ Zotero.Fulltext = new function(){ this.pdfInfoIsRegistered = pdfInfoIsRegistered; this.isCachedMIMEType = isCachedMIMEType; - this.pdfToolsDownloadBaseURL = 'https://www.zotero.org/download/xpdf/'; + this.pdfToolsDownloadBaseURL = ZOTERO_CONFIG.PDF_TOOLS_URL; this.__defineGetter__("pdfToolsName", function() { return 'Xpdf'; }); this.__defineGetter__("pdfToolsURL", function() { return 'http://www.foolabs.com/xpdf/'; }); this.__defineGetter__("pdfConverterName", function() { return 'pdftotext'; }); @@ -129,6 +129,25 @@ Zotero.Fulltext = new function(){ } + this.getLatestPDFToolsVersion = Zotero.Promise.coroutine(function* () { + if (Zotero.isWin) { + return "3.02a"; + } + + // Find latest version for this platform + var url = Zotero.Fulltext.pdfToolsDownloadBaseURL + 'latest.json'; + var xmlhttp = yield Zotero.HTTP.request("GET", url, { responseType: "json" }); + var json = xmlhttp.response; + + var platform = Zotero.platform.replace(/\s/g, '-'); + var version = json[platform] || json['default']; + + Zotero.debug("Latest PDF tools version for " + platform + " is " + version); + + return version; + }); + + /* * Download and install latest PDF tool */ @@ -328,6 +347,35 @@ Zotero.Fulltext = new function(){ }); + /** + * Unregister and delete PDF tools + * + * Used only for tests + */ + this.uninstallPDFTools = Zotero.Promise.coroutine(function* () { + Zotero.debug("Uninstalling PDF tools"); + + var dataDir = Zotero.getZoteroDirectory().path; + yield Zotero.File.removeIfExists(OS.Path.join(dataDir, _pdfConverterFileName)); + yield Zotero.File.removeIfExists(OS.Path.join(dataDir, _pdfInfoFileName)); + if (_pdfConverter) { + yield Zotero.File.removeIfExists(_pdfConverter.path); + yield Zotero.File.removeIfExists(_pdfConverter.path + ".version"); + } + if (_pdfInfo) { + yield Zotero.File.removeIfExists(_pdfInfo.path); + yield Zotero.File.removeIfExists(_pdfInfo.path + ".version"); + } + if (_pdfConverterScript) yield Zotero.File.removeIfExists(_pdfConverterScript.path); + if (_pdfInfoScript) yield Zotero.File.removeIfExists(_pdfInfoScript.path); + + _pdfConverter = null; + _pdfInfo = null; + _pdfInfoScript = null; + _pdfInfoScript = null; + }); + + function pdfConverterIsRegistered() { return !!_pdfConverter; } diff --git a/resource/config.js b/resource/config.js index 15571ee94..e31d4a1b7 100644 --- a/resource/config.js +++ b/resource/config.js @@ -13,7 +13,8 @@ var ZOTERO_CONFIG = { PREF_BRANCH: 'extensions.zotero.', BOOKMARKLET_ORIGIN: 'https://www.zotero.org', HTTP_BOOKMARKLET_ORIGIN: 'http://www.zotero.org', - BOOKMARKLET_URL: 'https://www.zotero.org/bookmarklet/' + BOOKMARKLET_URL: 'https://www.zotero.org/bookmarklet/', + PDF_TOOLS_URL: "https://www.zotero.org/download/xpdf/" }; EXPORTED_SYMBOLS = ["ZOTERO_CONFIG"]; diff --git a/test/content/runtests.js b/test/content/runtests.js index fb337315b..7cdc0ac95 100644 --- a/test/content/runtests.js +++ b/test/content/runtests.js @@ -140,8 +140,56 @@ if(ZoteroUnit.tests) { if(run) { window.onload = function() { - Zotero.Schema.schemaUpdatePromise.then(function() { - mocha.run(); - }); + Zotero.spawn(function* () { + yield Zotero.Schema.schemaUpdatePromise; + + // Download and cache PDF tools for this platform + // + // To reset, delete test/tests/data/pdf/ directory + var cachePDFTools = Zotero.Promise.coroutine(function* () { + Components.utils.import("resource://zotero/config.js"); + var baseURL = ZOTERO_CONFIG.PDF_TOOLS_URL; + + var path = OS.Path.join(getTestDataDirectory().path, 'pdf'); + yield OS.File.makeDir(path, { ignoreExisting: true }); + + // Get latest tools version for the current platform + var latestPath = OS.Path.join(path, "latest.json"); + var xmlhttp = yield Zotero.HTTP.request("GET", baseURL + "latest.json"); + var json = xmlhttp.responseText; + yield Zotero.File.putContentsAsync(latestPath, json); + json = JSON.parse(json); + + var platform = Zotero.platform.replace(/\s/g, '-'); + var version = json[platform] || json['default']; + + // Create version directory (e.g., data/pdf/3.04) and download tools to it if + // they don't exist + yield OS.File.makeDir(OS.Path.join(path, version), { ignoreExisting: true }); + + var fileName = "pdfinfo-" + platform + (Zotero.isWin ? ".exe" : ""); + var execPath = OS.Path.join(path, version, fileName); + if (!(yield OS.File.exists(execPath))) { + yield Zotero.File.download(baseURL + version + "/" + fileName, execPath); + } + fileName = "pdftotext-" + platform; + execPath = OS.Path.join(path, version, fileName); + if (!(yield OS.File.exists(execPath))) { + yield Zotero.File.download(baseURL + version + "/" + fileName, execPath); + } + + // Point full-text code to the cache directory, so downloads come from there + Zotero.Fulltext.pdfToolsDownloadBaseURL = OS.Path.toFileURI(path) + "/"; + }); + + try { + yield cachePDFTools(); + } + catch (e) { + Zotero.logError(e); + } + + return mocha.run(); + }) }; } \ No newline at end of file diff --git a/test/content/support.js b/test/content/support.js index e66ba4cc5..33d3fbc23 100644 --- a/test/content/support.js +++ b/test/content/support.js @@ -55,17 +55,24 @@ var loadZoteroPane = Zotero.Promise.coroutine(function* () { }); /** - * Waits for a window with a specific URL to open. Returns a promise for the window. + * Waits for a window with a specific URL to open. Returns a promise for the window, and + * optionally passes the window to a callback immediately for use with modal dialogs, + * which prevent async code from continuing */ -function waitForWindow(uri) { +function waitForWindow(uri, callback) { var deferred = Zotero.Promise.defer(); Components.utils.import("resource://gre/modules/Services.jsm"); var loadobserver = function(ev) { ev.originalTarget.removeEventListener("load", loadobserver, false); - if(ev.target.location == uri) { + if(ev.target.location.href == uri) { Services.ww.unregisterNotification(winobserver); - deferred.resolve(ev.target.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor). - getInterface(Components.interfaces.nsIDOMWindow)); + var win = ev.target.docShell + .QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindow); + if (callback) { + callback(win); + } + deferred.resolve(win); } }; var winobserver = {"observe":function(subject, topic, data) { @@ -190,31 +197,23 @@ function getPromiseError(promise) { /** * Ensures that the PDF tools are installed, or installs them if not. - * Returns a promise. + * + * @return {Promise} */ -function installPDFTools() { +var installPDFTools = Zotero.Promise.coroutine(function* () { if(Zotero.Fulltext.pdfConverterIsRegistered() && Zotero.Fulltext.pdfInfoIsRegistered()) { - return Zotero.Promise.resolve(true); + return; } + var version = yield Zotero.Fulltext.getLatestPDFToolsVersion(); + yield Zotero.Fulltext.downloadPDFTool('info', version); + yield Zotero.Fulltext.downloadPDFTool('converter', version); +}); - // Begin install procedure - return loadWindow("chrome://zotero/content/preferences/preferences.xul", { - pane: 'zotero-prefpane-search', - action: 'pdftools-install' - }).then(function(win) { - // Wait for confirmation dialog - return waitForWindow("chrome://global/content/commonDialog.xul").then(function(dlg) { - // Accept confirmation dialog - dlg.document.documentElement.acceptDialog(); - - // Wait for install to finish - return waitForCallback(function() { - return Zotero.Fulltext.pdfConverterIsRegistered() && Zotero.Fulltext.pdfInfoIsRegistered(); - }, 500, 30000).finally(function() { - win.close(); - }); - }); - }); +/** + * @return {Promise} + */ +function uninstallPDFTools() { + return Zotero.Fulltext.removePDFTools(); } /** diff --git a/test/tests/fulltextTest.js b/test/tests/fulltextTest.js index 23b231085..c220f636a 100644 --- a/test/tests/fulltextTest.js +++ b/test/tests/fulltextTest.js @@ -1,18 +1,9 @@ describe("Zotero.Fulltext", function () { describe("#downloadPDFTool()", function () { - var originalBaseURL; - before(function* () { - originalBaseURL = Zotero.Fulltext.pdfToolsDownloadBaseURL; - }) - after(function () { - Zotero.Fulltext.pdfToolsDownloadBaseURL = originalBaseURL; - }) - it("should install the PDF tools", function* () { var version = "3.04"; var dataDir = Zotero.getZoteroDirectory().path; var execFileName = Zotero.Fulltext.pdfInfoFileName; - var execContents = new Array(50001).join('a'); var execPath = OS.Path.join(dataDir, execFileName); var versionFileName = execFileName + '.version'; var versionPath = OS.Path.join(dataDir, versionFileName); @@ -21,6 +12,9 @@ describe("Zotero.Fulltext", function () { var scriptContents = yield Zotero.File.getContentsFromURLAsync( 'resource://zotero/redirect.' + scriptExt ); + var cacheExecPath = OS.Path.join( + getTestDataDirectory().path, "pdf", version, execFileName + ); // Delete existing files try { @@ -36,23 +30,12 @@ describe("Zotero.Fulltext", function () { } catch (e) {} - var tmpDir = Zotero.getTempDirectory(); - // Create temp version directory - var tmpVersionDir = OS.Path.join(tmpDir.path, version); - yield OS.File.makeDir(tmpVersionDir); - // Create dummy executable file to download - var tmpExecPath = OS.Path.join(tmpVersionDir, execFileName); - yield Zotero.File.putContentsAsync(tmpExecPath, execContents); - - // Override the download URL with a file URL for the temp directory - Zotero.Fulltext.pdfToolsDownloadBaseURL = OS.Path.toFileURI(tmpDir.path) + "/"; - yield Zotero.Fulltext.downloadPDFTool('info', version); assert.ok(Zotero.Fulltext.pdfInfoIsRegistered()); assert.equal( - (yield Zotero.File.getContentsAsync(execPath)), - execContents + (yield Zotero.File.getBinaryContentsAsync(cacheExecPath)), + (yield Zotero.File.getBinaryContentsAsync(execPath)) ); assert.equal((yield OS.File.stat(execPath)).unixMode, 0o755); assert.equal( @@ -65,7 +48,8 @@ describe("Zotero.Fulltext", function () { ); assert.equal((yield OS.File.stat(scriptPath)).unixMode, 0o755); - yield OS.File.removeDir(tmpVersionDir); + yield Zotero.Fulltext.uninstallPDFTools(); + assert.isFalse(Zotero.Fulltext.pdfInfoIsRegistered()); }) }) }) diff --git a/test/tests/preferences_searchTest.js b/test/tests/preferences_searchTest.js new file mode 100644 index 000000000..34e18ff41 --- /dev/null +++ b/test/tests/preferences_searchTest.js @@ -0,0 +1,23 @@ +describe("Search Preferences", function () { + describe("PDF Indexing", function () { + it("should install PDF tools if not installed", function* () { + // Begin install procedure + var win = yield loadWindow("chrome://zotero/content/preferences/preferences.xul", { + pane: 'zotero-prefpane-search', + action: 'pdftools-install' + }); + // Wait for confirmation dialog + yield waitForWindow("chrome://global/content/commonDialog.xul", function (dialog) { + // Accept confirmation dialog + dialog.document.documentElement.acceptDialog(); + }); + + // Wait for install to finish + yield waitForCallback(function() { + return Zotero.Fulltext.pdfConverterIsRegistered() + && Zotero.Fulltext.pdfInfoIsRegistered(); + }, 500) + .finally(() => win.close()); + }) + }) +})