Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow errors on arbitrary properties, not just defined attributes or relationships. #1984

Merged
merged 1 commit into from Feb 13, 2015
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 3 additions & 7 deletions packages/ember-data/lib/system/model/model.js
Expand Up @@ -1064,14 +1064,10 @@ var Model = Ember.Object.extend(Ember.Evented, {
*/
adapterDidInvalidate: function(errors) {
var recordErrors = get(this, 'errors');
function addError(name) {
if (errors[name]) {
recordErrors.add(name, errors[name]);
}
for (var key in errors) {
if (!errors.hasOwnProperty(key)) continue;
recordErrors.add(key, errors[key]);
}

this.eachAttribute(addError);
this.eachRelationship(addError);
this._saveWasRejected();
},

Expand Down
Expand Up @@ -404,6 +404,48 @@ test("if a created record is marked as invalid by the server, it enters an error
});
});

test("allows errors on arbitrary properties on create", function() {
adapter.createRecord = function(store, type, record) {
if (get(record, 'name').indexOf('Bro') === -1) {
return Ember.RSVP.reject(new DS.InvalidError({ base: ['is a generally unsavoury character'] }));
} else {
return Ember.RSVP.resolve();
}
};

var yehuda = run(function () {
return store.createRecord('person', { id: 1, name: "Yehuda Katz" });
});

// Wrap this in an Ember.run so that all chained async behavior is set up
// before flushing any scheduled behavior.
run(function() {
yehuda.save().then(null, async(function(error) {
equal(get(yehuda, 'isValid'), false, "the record is invalid");
ok(get(yehuda, 'errors.base'), "The errors.base property exists");
deepEqual(get(yehuda, 'errors').errorsFor('base'), [{attribute: 'base', message: "is a generally unsavoury character"}]);

set(yehuda, 'updatedAt', true);
equal(get(yehuda, 'isValid'), false, "the record is still invalid");

set(yehuda, 'name', "Brohuda Brokatz");

equal(get(yehuda, 'isValid'), false, "the record is still invalid as far as we know");
equal(get(yehuda, 'isDirty'), true, "the record has outstanding changes");

equal(get(yehuda, 'isNew'), true, "precond - record is still new");

return yehuda.save();
})).then(async(function(person) {
strictEqual(person, yehuda, "The promise resolves with the saved record");
ok(!get(yehuda, 'errors.base'), "The errors.base property does not exist");
deepEqual(get(yehuda, 'errors').errorsFor('base'), []);
equal(get(yehuda, 'isValid'), true, "record remains valid after committing");
equal(get(yehuda, 'isNew'), false, "record is no longer new");
}));
});
});

test("if a created record is marked as invalid by the server, you can attempt the save again", function() {
var saveCount = 0;
adapter.createRecord = function(store, type, record) {
Expand Down Expand Up @@ -510,6 +552,55 @@ test("if an updated record is marked as invalid by the server, it enters an erro
});


test("records can have errors on arbitrary properties after update", function() {
adapter.updateRecord = function(store, type, record) {
if (get(record, 'name').indexOf('Bro') === -1) {
return Ember.RSVP.reject(new DS.InvalidError({ base: ['is a generally unsavoury character'] }));
} else {
return Ember.RSVP.resolve();
}
};

var yehuda = run(function() {
return store.push('person', { id: 1, name: "Brohuda Brokatz" });
});

run(function() {
store.find('person', 1).then(async(function(person) {
equal(person, yehuda, "The same object is passed through");

equal(get(yehuda, 'isValid'), true, "precond - the record is valid");
set(yehuda, 'name', "Yehuda Katz");
equal(get(yehuda, 'isValid'), true, "precond - the record is still valid as far as we know");

equal(get(yehuda, 'isDirty'), true, "the record is dirty");

return yehuda.save();
})).then(null, async(function(reason) {
equal(get(yehuda, 'isDirty'), true, "the record is still dirty");
equal(get(yehuda, 'isValid'), false, "the record is invalid");
ok(get(yehuda, 'errors.base'), "The errors.base property exists");
deepEqual(get(yehuda, 'errors').errorsFor('base'), [{attribute: 'base', message: "is a generally unsavoury character"}]);

set(yehuda, 'updatedAt', true);
equal(get(yehuda, 'isValid'), false, "the record is still invalid");

set(yehuda, 'name', "Brohuda Brokatz");
equal(get(yehuda, 'isValid'), false, "the record is still invalid after changing (only server can know if it's now valid)");
equal(get(yehuda, 'isDirty'), true, "the record has outstanding changes");

return yehuda.save();
})).then(async(function(yehuda) {
equal(get(yehuda, 'isValid'), true, "record remains valid after committing");
equal(get(yehuda, 'isDirty'), false, "record is no longer new");
ok(!get(yehuda, 'errors.base'), "The errors.base property does not exist");
deepEqual(get(yehuda, 'errors').errorsFor('base'), []);
}));
});
});



test("if an updated record is marked as invalid by the server, you can attempt the save again", function() {
var saveCount = 0;
adapter.updateRecord = function(store, type, record) {
Expand Down