You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-26 17:03:12 +03:00
Fix uploadContent for node.js
9e89e71e broke uploadContent, making it set 'json=true' on the request, so that
we would try to turn raw content into JSON. It also misguidedly set a
client-side timeout of 30s.
Fix that, and add some tests to check uploadContent works.
In mock-request: distinguish between an expectation (ExpectedRequest)
and an actual request (Request). Add support for checking the headers, and the
request options in general, to Request.
This commit is contained in:
@@ -134,6 +134,8 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
cb(new Error('Timeout'));
|
cb(new Error('Timeout'));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// set an initial timeout of 30s; we'll advance it each time we get
|
||||||
|
// a progress notification
|
||||||
xhr.timeout_timer = callbacks.setTimeout(timeout_fn, 30000);
|
xhr.timeout_timer = callbacks.setTimeout(timeout_fn, 30000);
|
||||||
|
|
||||||
xhr.onreadystatechange = function() {
|
xhr.onreadystatechange = function() {
|
||||||
@@ -191,8 +193,8 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
promise = this.authedRequest(
|
promise = this.authedRequest(
|
||||||
callback, "POST", "/upload", queryParams, file.stream, {
|
callback, "POST", "/upload", queryParams, file.stream, {
|
||||||
prefix: "/_matrix/media/v1",
|
prefix: "/_matrix/media/v1",
|
||||||
localTimeoutMs: 30000,
|
|
||||||
headers: {"Content-Type": file.type},
|
headers: {"Content-Type": file.type},
|
||||||
|
json: false,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -538,7 +540,7 @@ module.exports.MatrixHttpApi.prototype = {
|
|||||||
withCredentials: false,
|
withCredentials: false,
|
||||||
qs: queryParams,
|
qs: queryParams,
|
||||||
body: data,
|
body: data,
|
||||||
json: true,
|
json: opts.json === undefined ? true : opts.json,
|
||||||
timeout: localTimeoutMs,
|
timeout: localTimeoutMs,
|
||||||
headers: opts.headers || {},
|
headers: opts.headers || {},
|
||||||
_matrix_opts: this.opts
|
_matrix_opts: this.opts
|
||||||
|
|||||||
@@ -37,6 +37,74 @@ describe("MatrixClient", function() {
|
|||||||
httpBackend.verifyNoOutstandingExpectation();
|
httpBackend.verifyNoOutstandingExpectation();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("uploadContent", function() {
|
||||||
|
var buf = new Buffer('hello world');
|
||||||
|
it("should upload the file", function(done) {
|
||||||
|
httpBackend.when(
|
||||||
|
"POST", "/_matrix/media/v1/upload"
|
||||||
|
).check(function(req) {
|
||||||
|
console.log("Request", req);
|
||||||
|
|
||||||
|
expect(req.data).toEqual(buf);
|
||||||
|
expect(req.queryParams.filename).toEqual("hi.txt");
|
||||||
|
expect(req.queryParams.access_token).toEqual(accessToken);
|
||||||
|
expect(req.headers["Content-Type"]).toEqual("text/plain");
|
||||||
|
expect(req.opts.json).toBeFalsy();
|
||||||
|
expect(req.opts.timeout).toBe(undefined);
|
||||||
|
}).respond(200, {
|
||||||
|
"content_uri": "uri"
|
||||||
|
});
|
||||||
|
|
||||||
|
var prom = client.uploadContent({
|
||||||
|
stream: buf,
|
||||||
|
name: "hi.txt",
|
||||||
|
type: "text/plain",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(prom).toBeDefined();
|
||||||
|
|
||||||
|
var uploads = client.getCurrentUploads();
|
||||||
|
expect(uploads.length).toEqual(1);
|
||||||
|
expect(uploads[0].promise).toBe(prom);
|
||||||
|
expect(uploads[0].loaded).toEqual(0);
|
||||||
|
|
||||||
|
prom.then(function(response) {
|
||||||
|
console.log("Response", response);
|
||||||
|
expect(response.content_uri).toEqual("uri");
|
||||||
|
|
||||||
|
var uploads = client.getCurrentUploads();
|
||||||
|
expect(uploads.length).toEqual(0);
|
||||||
|
}).catch(utils.failTest).done(done);
|
||||||
|
|
||||||
|
httpBackend.flush();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return a promise which can be cancelled", function(done) {
|
||||||
|
var prom = client.uploadContent({
|
||||||
|
stream: buf,
|
||||||
|
name: "hi.txt",
|
||||||
|
type: "text/plain",
|
||||||
|
});
|
||||||
|
|
||||||
|
var uploads = client.getCurrentUploads();
|
||||||
|
expect(uploads.length).toEqual(1);
|
||||||
|
expect(uploads[0].promise).toBe(prom);
|
||||||
|
expect(uploads[0].loaded).toEqual(0);
|
||||||
|
|
||||||
|
prom.then(function(response) {
|
||||||
|
throw Error("request not aborted");
|
||||||
|
}, function(error) {
|
||||||
|
expect(error).toEqual("aborted");
|
||||||
|
|
||||||
|
var uploads = client.getCurrentUploads();
|
||||||
|
expect(uploads.length).toEqual(0);
|
||||||
|
}).catch(utils.failTest).done(done);
|
||||||
|
|
||||||
|
var r = client.cancelUpload(prom);
|
||||||
|
expect(r).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("joinRoom", function() {
|
describe("joinRoom", function() {
|
||||||
it("should no-op if you've already joined a room", function() {
|
it("should no-op if you've already joined a room", function() {
|
||||||
var roomId = "!foo:bar";
|
var roomId = "!foo:bar";
|
||||||
|
|||||||
@@ -11,18 +11,17 @@ function HttpBackend() {
|
|||||||
var self = this;
|
var self = this;
|
||||||
// the request function dependency that the SDK needs.
|
// the request function dependency that the SDK needs.
|
||||||
this.requestFn = function(opts, callback) {
|
this.requestFn = function(opts, callback) {
|
||||||
var realReq = new Request(opts.method, opts.uri, opts.body, opts.qs);
|
var req = new Request(opts, callback);
|
||||||
realReq.callback = callback;
|
console.log("HTTP backend received request: %s", req);
|
||||||
console.log("HTTP backend received request: %s %s", opts.method, opts.uri);
|
self.requests.push(req);
|
||||||
self.requests.push(realReq);
|
|
||||||
|
|
||||||
var abort = function() {
|
var abort = function() {
|
||||||
var idx = self.requests.indexOf(realReq);
|
var idx = self.requests.indexOf(req);
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
console.log("Aborting HTTP request: %s %s", opts.method,
|
console.log("Aborting HTTP request: %s %s", opts.method,
|
||||||
opts.uri);
|
opts.uri);
|
||||||
self.requests.splice(idx, 1);
|
self.requests.splice(idx, 1);
|
||||||
realReq.callback("aborted");
|
req.callback("aborted");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -161,22 +160,32 @@ HttpBackend.prototype = {
|
|||||||
* @return {Request} An expected request.
|
* @return {Request} An expected request.
|
||||||
*/
|
*/
|
||||||
when: function(method, path, data) {
|
when: function(method, path, data) {
|
||||||
var pendingReq = new Request(method, path, data);
|
var pendingReq = new ExpectedRequest(method, path, data);
|
||||||
this.expectedRequests.push(pendingReq);
|
this.expectedRequests.push(pendingReq);
|
||||||
return pendingReq;
|
return pendingReq;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function Request(method, path, data, queryParams) {
|
/**
|
||||||
|
* Represents the expectation of a request.
|
||||||
|
*
|
||||||
|
* <p>Includes the conditions to be matched against, the checks to be made,
|
||||||
|
* and the response to be returned.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @param {string} method
|
||||||
|
* @param {string} path
|
||||||
|
* @param {object?} data
|
||||||
|
*/
|
||||||
|
function ExpectedRequest(method, path, data) {
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
this.queryParams = queryParams;
|
|
||||||
this.callback = null;
|
|
||||||
this.response = null;
|
this.response = null;
|
||||||
this.checks = [];
|
this.checks = [];
|
||||||
}
|
}
|
||||||
Request.prototype = {
|
|
||||||
|
ExpectedRequest.prototype = {
|
||||||
/**
|
/**
|
||||||
* Execute a check when this request has been satisfied.
|
* Execute a check when this request has been satisfied.
|
||||||
* @param {Function} fn The function to execute.
|
* @param {Function} fn The function to execute.
|
||||||
@@ -221,6 +230,44 @@ Request.prototype = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a request made by the app.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @param {object} opts opts passed to request()
|
||||||
|
* @param {function} callback
|
||||||
|
*/
|
||||||
|
function Request(opts, callback) {
|
||||||
|
this.opts = opts;
|
||||||
|
this.callback = callback;
|
||||||
|
|
||||||
|
Object.defineProperty(this, 'method', {
|
||||||
|
get: function() { return opts.method; }
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(this, 'path', {
|
||||||
|
get: function() { return opts.uri; }
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(this, 'data', {
|
||||||
|
get: function() { return opts.body; }
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(this, 'queryParams', {
|
||||||
|
get: function() { return opts.qs; }
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(this, 'headers', {
|
||||||
|
get: function() { return opts.headers || {}; }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Request.prototype = {
|
||||||
|
toString: function() {
|
||||||
|
return this.method + " " + this.path;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The HttpBackend class.
|
* The HttpBackend class.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user