commit 87a2eece3a272e0059f8a4b0d200c9a7d4f6aae5
parent 300c8e8aea9fbc7fbc92d0a79eb765d6913a62fd
Author: Dan Stillman <dstillman@zotero.org>
Date: Sun, 24 Apr 2016 04:04:40 -0400
Fix #959, 5.0: Submit to Zotero Server is not working
Diffstat:
3 files changed, 148 insertions(+), 127 deletions(-)
diff --git a/chrome/content/zotero/preferences/preferences_advanced.js b/chrome/content/zotero/preferences/preferences_advanced.js
@@ -610,9 +610,10 @@ Zotero_Preferences.Debug_Output = {
},
- submit: function () {
+ submit: Zotero.Promise.coroutine(function* () {
document.getElementById('debug-output-submit').disabled = true;
- document.getElementById('debug-output-submit-progress').hidden = false;
+ var pm = document.getElementById('debug-output-submit-progress');
+ pm.hidden = false;
Components.utils.import("resource://zotero/config.js");
@@ -623,142 +624,98 @@ Zotero_Preferences.Debug_Output = {
);
Zotero_Preferences.Debug_Output.setStore(false);
- var uploadCallback = function (xmlhttp) {
- document.getElementById('debug-output-submit').disabled = false;
- document.getElementById('debug-output-submit-progress').hidden = true;
-
- Zotero.debug(xmlhttp.responseText);
-
- var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
- .getService(Components.interfaces.nsIPromptService);
-
- if (!xmlhttp.responseXML) {
- ps.alert(
- null,
- Zotero.getString('general.error'),
- Zotero.getString('general.invalidResponseServer')
- );
- return;
- }
- var reported = xmlhttp.responseXML.getElementsByTagName('reported');
- if (reported.length != 1) {
- ps.alert(
- null,
- Zotero.getString('general.error'),
- Zotero.getString('general.serverError')
- );
- return;
- }
+ var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+ .getService(Components.interfaces.nsIPromptService);
+ try {
+ var xmlhttp = yield Zotero.HTTP.request(
+ "POST",
+ url,
+ {
+ compressBody: true,
+ body: output,
+ logBodyLength: 30,
+ timeout: 30000,
+ requestObserver: function (req) {
+ // Don't fail during tests, with fake XHR
+ if (!req.channel) {
+ return;
+ }
+ req.channel.notificationCallbacks = {
+ onProgress: function (request, context, progress, progressMax) {
+ pm.mode = 'determined';
+ if (!pm.value || progress > pm.value) {
+ pm.value = progress;
+ }
+ if (!pm.max || progressMax > pm.max) {
+ pm.max = progressMax;
+ }
+ },
+
+ // nsIInterfaceRequestor
+ getInterface: function (iid) {
+ try {
+ return this.QueryInterface(iid);
+ }
+ catch (e) {
+ throw Components.results.NS_NOINTERFACE;
+ }
+ },
+
+ QueryInterface: function(iid) {
+ if (iid.equals(Components.interfaces.nsISupports) ||
+ iid.equals(Components.interfaces.nsIInterfaceRequestor) ||
+ iid.equals(Components.interfaces.nsIProgressEventSink)) {
+ return this;
+ }
+ throw Components.results.NS_NOINTERFACE;
+ },
- var reportID = reported[0].getAttribute('reportID');
- ps.alert(
- null,
- Zotero.getString('zotero.preferences.advanced.debug.title'),
- Zotero.getString('zotero.preferences.advanced.debug.sent', reportID)
+ }
+ }
+ }
);
}
-
- var bufferUploader = function (data) {
- var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
- .getService(Components.interfaces.nsIPromptService);
-
- var oldLen = output.length;
- var newLen = data.length;
- var savings = Math.round(((oldLen - newLen) / oldLen) * 100)
- Zotero.debug("HTTP POST " + newLen + " bytes to " + url
- + " (gzipped from " + oldLen + " bytes; "
- + savings + "% savings)");
-
- if (Zotero.HTTP.browserIsOffline()) {
- ps.alert(
- null,
- Zotero.getString('general.error'),
- Zotero.getString('general.browserIsOffline', Zotero.appName)
- );
- return false;
- }
-
- var req =
- Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].
- createInstance();
- req.open('POST', url, true);
- req.setRequestHeader('Content-Type', "text/plain");
- req.setRequestHeader('Content-Encoding', 'gzip');
-
- req.channel.notificationCallbacks = {
- onProgress: function (request, context, progress, progressMax) {
- var pm = document.getElementById('debug-output-submit-progress');
- pm.mode = 'determined'
- pm.value = progress;
- pm.max = progressMax;
- },
-
- // nsIInterfaceRequestor
- getInterface: function (iid) {
- try {
- return this.QueryInterface(iid);
- }
- catch (e) {
- throw Components.results.NS_NOINTERFACE;
- }
- },
-
- QueryInterface: function(iid) {
- if (iid.equals(Components.interfaces.nsISupports) ||
- iid.equals(Components.interfaces.nsIInterfaceRequestor) ||
- iid.equals(Components.interfaces.nsIProgressEventSink)) {
- return this;
- }
- throw Components.results.NS_NOINTERFACE;
- },
-
+ catch (e) {
+ Zotero.logError(e);
+ let title = Zotero.getString('general.error');
+ let msg;
+ if (e instanceof Zotero.HTTP.UnexpectedStatusException) {
+ msg = Zotero.getString('general.invalidResponseServer');
}
- req.onreadystatechange = function () {
- if (req.readyState == 4) {
- uploadCallback(req);
- }
- };
- try {
- // Send binary data
- let numBytes = data.length, ui8Data = new Uint8Array(numBytes);
- for (let i = 0; i < numBytes; i++) {
- ui8Data[i] = data.charCodeAt(i) & 0xff;
- }
- req.send(ui8Data);
+ else if (e instanceof Zotero.HTTP.BrowserOfflineException) {
+ msg = Zotero.getString('general.browserIsOffline', Zotero.appName);
}
- catch (e) {
- Zotero.debug(e, 1);
- Components.utils.reportError(e);
- ps.alert(
- null,
- Zotero.getString('general.error'),
- Zotero.getString('zotero.preferences.advanced.debug.error')
- );
+ else {
+ msg = Zotero.getString('zotero.preferences.advanced.debug.error');
}
+ ps.alert(null, title, msg);
+ return false;
}
- // Get input stream from debug output data
- var unicodeConverter =
- Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
- .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
- unicodeConverter.charset = "UTF-8";
- var bodyStream = unicodeConverter.convertToInputStream(output);
+ document.getElementById('debug-output-submit').disabled = false;
+ document.getElementById('debug-output-submit-progress').hidden = true;
+
+ Zotero.debug(xmlhttp.responseText);
- // Get listener for when compression is done
- var listener = new Zotero.BufferedInputListener(bufferUploader);
+ var reported = xmlhttp.responseXML.getElementsByTagName('reported');
+ if (reported.length != 1) {
+ ps.alert(
+ null,
+ Zotero.getString('general.error'),
+ Zotero.getString('general.serverError')
+ );
+ return false;
+ }
- // Initialize stream converter
- var converter =
- Components.classes["@mozilla.org/streamconv;1?from=uncompressed&to=gzip"]
- .createInstance(Components.interfaces.nsIStreamConverter);
- converter.asyncConvertData("uncompressed", "gzip", listener, null);
+ var reportID = reported[0].getAttribute('reportID');
+ ps.alert(
+ null,
+ Zotero.getString('zotero.preferences.advanced.debug.title'),
+ Zotero.getString('zotero.preferences.advanced.debug.sent', reportID)
+ );
- // Send input stream to stream converter
- var pump = Components.classes["@mozilla.org/network/input-stream-pump;1"].
- createInstance(Components.interfaces.nsIInputStreamPump);
- pump.init(bodyStream, -1, -1, 0, 0, true);
- pump.asyncRead(converter, null);
- },
+ return true;
+ }),
clear: function () {
diff --git a/test/tests/preferences_advancedTest.js b/test/tests/preferences_advancedTest.js
@@ -1,4 +1,64 @@
describe("Advanced Preferences", function () {
+ describe("General", function () {
+ var server;
+
+ before(function () {
+ server = sinon.fakeServer.create();
+ server.autoRespond = true;
+ Zotero.HTTP.mock = sinon.FakeXMLHttpRequest;
+ });
+
+ after(function () {
+ Zotero.HTTP.mock = null;
+ })
+
+ describe("Debug Output", function () {
+ it("should log output and submit to server", function* () {
+ var win = yield loadWindow("chrome://zotero/content/preferences/preferences.xul", {
+ pane: 'zotero-prefpane-advanced',
+ tabIndex: 0
+ });
+
+ // Wait for tab to load
+ var doc = win.document;
+ var prefwindow = doc.documentElement;
+ var defer = Zotero.Promise.defer();
+ var pane = doc.getElementById('zotero-prefpane-advanced');
+ if (!pane.loaded) {
+ pane.addEventListener('paneload', function () {
+ defer.resolve();
+ })
+ yield defer.promise;
+ }
+
+ var enableButton = doc.getElementById('debug-output-enable');
+ enableButton.click();
+ yield createDataObject('item');
+ enableButton.click();
+
+ server.respond(function (req) {
+ if (req.method == "POST") {
+ req.respond(
+ 200,
+ {},
+ '<?xml version="1.0" encoding="UTF-8"?>\n'
+ + '<xml><reported reportID="1234567890"/></xml>'
+ );
+ }
+ });
+
+ // Make sure Debug ID is shown in dialog
+ var promise = waitForDialog(function (dialog) {
+ assert.match(dialog.document.documentElement.textContent, /D1234567890/);
+ });
+ doc.getElementById('debug-output-submit').click();
+ yield promise;
+
+ win.close();
+ });
+ });
+ });
+
describe("Files & Folders", function () {
describe("Linked Attachment Base Directory", function () {
var setBaseDirectory = Zotero.Promise.coroutine(function* (basePath) {
diff --git a/test/tests/syncEngineTest.js b/test/tests/syncEngineTest.js
@@ -117,6 +117,10 @@ describe("Zotero.Sync.Data.Engine", function () {
yield Zotero.Users.setCurrentUsername("testuser");
})
+ after(function () {
+ Zotero.HTTP.mock = null;
+ });
+
describe("Syncing", function () {
it("should download items into a new library", function* () {
({ engine, client, caller } = yield setup());