Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions core/js/oc-backbone-webdav.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,25 @@
}

function callPropPatch(client, options, model, headers) {
var changes = model.changed;
if (options.wait && _.isEmpty(changes)) {
// usually with "wait" mode, the changes aren't set yet,
changes = options.data;

// if options.patch is not set, then data contains all the data
// instead of just the properties to patch
if (!options.patch) {
// remove reserved properties
delete changes.href;
delete changes[_.result(model, 'idAttribute')];

// note: there is no way to diff with previous values here so
// we just send everything
}
}
return client.propPatch(
options.url,
convertModelAttributesToDavProperties(model.changed, options.davProperties),
convertModelAttributesToDavProperties(changes, options.davProperties),
headers
).then(function(result) {
if (result.status === 207 && result.body && result.body.length > 0) {
Expand All @@ -196,6 +212,11 @@
}

if (isSuccessStatus(result.status)) {
// with wait, we set the changes only after success
if (options.wait) {
model.set(changes, options);
}

if (_.isFunction(options.success)) {
// pass the object's own values because the server
// does not return the updated model
Expand Down Expand Up @@ -236,7 +257,7 @@
options.type,
options.url,
headers,
options.data
JSON.stringify(options.data)
).then(function(result) {
if (!isSuccessStatus(result.status)) {
if (_.isFunction(options.error)) {
Expand Down Expand Up @@ -353,7 +374,7 @@

// Ensure that we have the appropriate request data.
if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
params.data = JSON.stringify(options.attrs || model.toJSON(options));
params.data = options.attrs || model.toJSON(options);
}

// Don't process data on a non-GET request.
Expand Down
230 changes: 143 additions & 87 deletions core/js/tests/specs/oc-backbone-webdavSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,97 +243,164 @@ describe('Backbone Webdav extension', function() {
});
});

it('makes a PROPPATCH request to update model', function() {
var model = new TestModel({
id: '123',
firstName: 'Hello',
lastName: 'World',
age: 32,
married: false
});
describe('updating', function() {
it('makes a PROPPATCH request to update model', function() {
var model = new TestModel({
id: '123',
firstName: 'Hello',
lastName: 'World',
age: 32,
married: false
});

model.save({
firstName: 'Hey',
age: 33,
married: true
model.save({
firstName: 'Hey',
age: 33,
married: true
});

expect(davClientPropPatchStub.calledOnce).toEqual(true);
expect(davClientPropPatchStub.getCall(0).args[0])
.toEqual('http://example.com/owncloud/remote.php/test/123');
expect(davClientPropPatchStub.getCall(0).args[1])
.toEqual({
'{http://owncloud.org/ns}first-name': 'Hey',
'{http://owncloud.org/ns}age': '33',
'{http://owncloud.org/ns}married': 'true'
});
expect(davClientPropPatchStub.getCall(0).args[2]['X-Requested-With'])
.toEqual('XMLHttpRequest');

deferredRequest.resolve({
status: 207,
body: [{
href: 'http://example.com/owncloud/remote.php/test/123',
propStat: [{
status: 'HTTP/1.1 200 OK',
properties: {
'{http://owncloud.org/ns}first-name': '',
'{http://owncloud.org/ns}age-name': '',
'{http://owncloud.org/ns}married': ''
}
}]
}]
});

expect(model.id).toEqual('123');
expect(model.get('firstName')).toEqual('Hey');
expect(model.get('age')).toEqual(33);
expect(model.get('married')).toEqual(true);
});

expect(davClientPropPatchStub.calledOnce).toEqual(true);
expect(davClientPropPatchStub.getCall(0).args[0])
.toEqual('http://example.com/owncloud/remote.php/test/123');
expect(davClientPropPatchStub.getCall(0).args[1])
.toEqual({
'{http://owncloud.org/ns}first-name': 'Hey',
'{http://owncloud.org/ns}age': '33',
'{http://owncloud.org/ns}married': 'true'
it('calls error callback with status code 422 in case of failed PROPPATCH properties', function() {
var successHandler = sinon.stub();
var errorHandler = sinon.stub();
var model = new TestModel({
id: '123',
firstName: 'Hello',
lastName: 'World',
age: 32,
married: false
});
expect(davClientPropPatchStub.getCall(0).args[2]['X-Requested-With'])
.toEqual('XMLHttpRequest');

deferredRequest.resolve({
status: 207,
body: [{
href: 'http://example.com/owncloud/remote.php/test/123',
propStat: [{
status: 'HTTP/1.1 200 OK',
properties: {
'{http://owncloud.org/ns}first-name': '',
'{http://owncloud.org/ns}age-name': '',
'{http://owncloud.org/ns}married': ''
}
model.save({
firstName: 'Hey',
lastName: 'low'
}, {
success: successHandler,
error: errorHandler
});

deferredRequest.resolve({
status: 207,
body: [{
href: 'http://example.com/owncloud/remote.php/test/123',
propStat: [{
status: 'HTTP/1.1 200 OK',
properties: {
'{http://owncloud.org/ns}last-name': ''
}
}, {
status: 'HTTP/1.1 403 Forbidden',
properties: {
'{http://owncloud.org/ns}first-name': ''
}
}]
}]
}]
});
});

expect(model.id).toEqual('123');
expect(model.get('firstName')).toEqual('Hey');
expect(model.get('age')).toEqual(33);
expect(model.get('married')).toEqual(true);
});
expect(davClientPropPatchStub.calledOnce).toEqual(true);

it('calls error callback with status code 422 in case of failed PROPPATCH properties', function() {
var successHandler = sinon.stub();
var errorHandler = sinon.stub();
var model = new TestModel({
id: '123',
firstName: 'Hello',
lastName: 'World',
age: 32,
married: false
expect(successHandler.notCalled).toEqual(true);
expect(errorHandler.calledOnce).toEqual(true);
expect(errorHandler.getCall(0).args[0]).toEqual(model);
expect(errorHandler.getCall(0).args[1].status).toEqual(422);
});

model.save({
firstName: 'Hey',
lastName: 'low'
}, {
success: successHandler,
error: errorHandler
it('calls error handler if error status in PROPPATCH response', function() {
testMethodError(function(success, error) {
var model = new TestModel();
model.save({
firstName: 'Hey'
}, {
success: success,
error: error
});
});
});

deferredRequest.resolve({
status: 207,
body: [{
href: 'http://example.com/owncloud/remote.php/test/123',
propStat: [{
status: 'HTTP/1.1 200 OK',
properties: {
'{http://owncloud.org/ns}last-name': ''
}
}, {
status: 'HTTP/1.1 403 Forbidden',
properties: {
'{http://owncloud.org/ns}first-name': ''
}
it('sends all data when using wait flag', function() {
var successHandler = sinon.stub();
var errorHandler = sinon.stub();
var model = new TestModel({
id: '123',
firstName: 'Hello',
lastName: 'World',
age: 32,
married: false
});

model.save({
firstName: 'Hey',
lastName: 'low'
}, {
wait: true,
success: successHandler,
error: errorHandler
});

// attributes not updated yet
expect(model.get('firstName')).toEqual('Hello');

deferredRequest.resolve({
status: 207,
body: [{
href: 'http://example.com/owncloud/remote.php/test/123',
propStat: [{
status: 'HTTP/1.1 200 OK',
properties: {
'{http://owncloud.org/ns}first-name': '',
'{http://owncloud.org/ns}last-name': ''
}
}]
}]
}]
});
});

expect(davClientPropPatchStub.calledOnce).toEqual(true);

expect(successHandler.notCalled).toEqual(true);
expect(errorHandler.calledOnce).toEqual(true);
expect(errorHandler.getCall(0).args[0]).toEqual(model);
expect(errorHandler.getCall(0).args[1].status).toEqual(422);
expect(davClientPropPatchStub.calledOnce).toEqual(true);
// just resends everything
expect(davClientPropPatchStub.getCall(0).args[1])
.toEqual({
'{http://owncloud.org/ns}first-name': 'Hey',
'{http://owncloud.org/ns}last-name': 'low',
'{http://owncloud.org/ns}age': '32',
'{http://owncloud.org/ns}married': 'false',
});

expect(model.get('firstName')).toEqual('Hey');
expect(successHandler.calledOnce).toEqual(true);
expect(errorHandler.notCalled).toEqual(true);
});
});

it('uses PROPFIND to fetch single model', function() {
Expand Down Expand Up @@ -429,17 +496,6 @@ describe('Backbone Webdav extension', function() {
});
});
});
it('calls error handler if error status in PROPPATCH response', function() {
testMethodError(function(success, error) {
var model = new TestModel();
model.save({
firstName: 'Hey'
}, {
success: success,
error: error
});
});
});
});


Expand Down