diff --git a/addon/index.js b/addon/index.js index 3a6f9a9c..678fda3c 100644 --- a/addon/index.js +++ b/addon/index.js @@ -150,7 +150,7 @@ export type ChangesetDef = {| _notifyVirtualProperties: (?Array) => void, _rollbackKeys: () => Array, rollback: () => ChangesetDef, - rollbackInvalid: () => ChangesetDef, + rollbackInvalid: (string | void) => ChangesetDef, rollbackProperty: () => ChangesetDef, save: (Object) => Promise, merge: (ChangesetDef) => ChangesetDef, @@ -411,11 +411,17 @@ export function changeset( * * @public * @chainable + * @param {String} key optional key to rollback invalid * @return {Changeset} */ - rollbackInvalid() { - this._notifyVirtualProperties(); - set(this, ERRORS, {}); + rollbackInvalid(key /*: string | void */) /*: ChangesetDef */ { + if (key) { + this._notifyVirtualProperties([key]); + this._deleteKey(ERRORS, key); + } else { + this._notifyVirtualProperties(); + set(this, ERRORS, {}); + } return this; }, @@ -425,9 +431,10 @@ export function changeset( * * @public * @chainable + * @param {String} key key to delete off of changes and errors * @return {Changeset} */ - rollbackProperty(key) { + rollbackProperty(key) /*: ChangesetDef */ { this._deleteKey(CHANGES, key); this._deleteKey(ERRORS, key); @@ -501,7 +508,7 @@ export function changeset( /** * Manually push multiple errors to the changeset as an array. If there is - * an existing error or change for `key`. it will be overwritten. + * an existing error or change for `key`, it will be overwritten. */ pushErrors( key /*: string */, diff --git a/tests/unit/changeset-test.js b/tests/unit/changeset-test.js index bc6ec19f..83ebda86 100644 --- a/tests/unit/changeset-test.js +++ b/tests/unit/changeset-test.js @@ -875,6 +875,31 @@ test('#rollbackInvalid clears errors and keeps valid values', function(assert) { assert.deepEqual(get(dummyChangeset, 'errors'), [], 'should rollback'); }); +test('#rollbackInvalid a specific key clears key error and keeps valid values', function(assert) { + let dummyChangeset = new Changeset(dummyModel, dummyValidator); + let expectedChanges = [ + { key: 'firstName', value: 'foo' }, + { key: 'lastName', value: 'bar' } + ]; + let expectedErrors = [ + { key: 'password', validation: ['foo', 'bar'], value: false }, + { key: 'name', validation: 'too short', value: '' } + ]; + dummyChangeset.set('firstName', 'foo'); + dummyChangeset.set('lastName', 'bar'); + dummyChangeset.set('password', false); + dummyChangeset.set('name', ''); + + assert.deepEqual(get(dummyChangeset, 'changes'), expectedChanges, 'precondition'); + assert.deepEqual(get(dummyChangeset, 'errors'), expectedErrors, 'precondition'); + dummyChangeset.rollbackInvalid('name'); + assert.deepEqual(get(dummyChangeset, 'changes'), expectedChanges, 'should not rollback'); + expectedErrors = [ + { key: 'password', validation: ['foo', 'bar'], value: false } + ]; + assert.deepEqual(get(dummyChangeset, 'errors'), expectedErrors, 'should rollback'); +}); + test('#rollbackInvalid resets valid state', function(assert) { let dummyChangeset = new Changeset(dummyModel, dummyValidator); dummyChangeset.set('name', 'a'); @@ -1132,8 +1157,10 @@ test('#addError adds an error to the changeset using the shortcut', function (as assert.ok(get(dummyChangeset, 'isInvalid'), 'should be invalid'); assert.equal(get(dummyChangeset, 'error.email.validation'), 'Email already taken', 'should add the error'); assert.equal(get(dummyChangeset, 'error.email.value'), 'jim@bob.com', 'addError uses already present value'); + assert.deepEqual(get(dummyChangeset, 'changes'), [], 'pushErrors clears the changes on the changeset'); dummyChangeset.set('email', 'unique@email.com'); assert.ok(get(dummyChangeset, 'isValid'), 'should be valid'); + assert.deepEqual(get(dummyChangeset, 'changes')[0], { key: 'email', value: 'unique@email.com' }, 'has correct changes'); }); /** @@ -1149,8 +1176,10 @@ test('#pushErrors pushes an error into an array of existing validations', functi assert.ok(get(dummyChangeset, 'isInvalid'), 'should be invalid'); assert.deepEqual(get(dummyChangeset, 'error.email.validation'), ['Email already taken', 'Invalid email format'], 'should push the error'); assert.equal(get(dummyChangeset, 'error.email.value'), 'jim@bob.com', 'pushErrors uses already present value'); + assert.deepEqual(get(dummyChangeset, 'changes'), [], 'pushErrors clears the changes on the changeset'); dummyChangeset.set('email', 'unique@email.com'); assert.ok(get(dummyChangeset, 'isValid'), 'should be valid'); + assert.deepEqual(get(dummyChangeset, 'changes')[0], { key: 'email', value: 'unique@email.com' }, 'has correct changes'); }); test('#pushErrors pushes an error if no existing validations are present', function (assert) {