Skip to content

Setting values at one level of a (nested) EmberData changeset should not overwrite other levels (mergeDeep) #669

Open
@flynnawtc

Description

@flynnawtc

Version

master

Test Case

`
test('#set set with Ember Data Object should not change other nested ember-data objects', async function (assert) {

let store = this.owner.lookup('service:store');

let mockDogModel = store.createRecord('dog', { breed: 'jazzy' });
let mockProfileModel = store.createRecord('profile', {pet: mockDogModel});
let mockUserModel = store.createRecord('user', {
  profile: mockProfileModel,
  save: function () {
    return Promise.resolve(this);
  },
});

let dummyChangeset = Changeset(mockUserModel);

//Check our initial values - these all pass
//assert.strictEqual(dummyChangeset.profile.pet.breed, 'jazzy', 'should not change');  //fails as it is a proxy within a proxy within a model - requires the use of 'get'
assert.strictEqual(dummyChangeset.get('profile.pet.breed'), 'jazzy', 'should not change using get #1');
assert.strictEqual(dummyChangeset.get('profile.pet').breed, 'jazzy', 'should not change using get #2');
assert.strictEqual(dummyChangeset.get('profile').pet.breed, 'jazzy', 'should not change using get #3');

//test fails using either form of setter
//dummyChangeset.set('profile.lastName', 'Mysurname');
set(dummyChangeset, 'profile.lastName', 'Mysurname');

//Log changeset.changes and changeset._changes
let changes = dummyChangeset.changes;
console.log("changes", changes);
console.log("_changes", dummyChangeset._changes);

assert.strictEqual(changes[0].value, 'Mysurname', 'changes with nested key Ember.set');

//Check values after setting unrelated field - these all pass
//assert.strictEqual(dummyChangeset.profile.pet.breed, 'jazzy', 'should not change after other set');  //fails as it is a proxy within a proxy within a model - requires the use of 'get'
assert.strictEqual(dummyChangeset.get('profile.pet.breed'), 'jazzy', 'should not change after other set using get #1');
assert.strictEqual(dummyChangeset.get('profile.pet').breed, 'jazzy', 'should not change after other set using get #2');
assert.strictEqual(dummyChangeset.get('profile').pet.breed, 'jazzy', 'should not change after other set using get #3');

dummyChangeset.execute();
console.log("changes2", changes);
console.log("_changes2", dummyChangeset._changes);

//Recheck values after executing change on unrelated field - these tests FAIL
//assert.strictEqual(dummyChangeset.profile.pet.breed, 'jazzy', 'should not change after execute');  //fails as it is a proxy within a proxy within a model - requires the use of 'get'
assert.strictEqual(dummyChangeset.get('profile.pet.breed'), 'jazzy', 'should not change after execute using get #1');
assert.strictEqual(dummyChangeset.get('profile.pet').breed, 'jazzy', 'should not change after execute using get #2');
assert.strictEqual(dummyChangeset.get('profile').pet.breed, 'jazzy', 'should not change after execute using get #3');

//What did we actually get?
console.log(dummyChangeset.get('profile.pet'));   //returns Proxy(ObjectTreeNode)

});
`

Steps to reproduce

Execute the test above (add to tests/unit/changeset-test.js)

Expected Behavior

All tests would pass - the setting of the profile surname should have no effect on the breed of the pet

Actual Behavior

After calling execute(), the value of profile.pet has been set to a Proxy(objectTreeNode) instead of being left unchanged

changes/_changes as logged before execute()
image

changes/_changes as logged after execute()
image

Note empty 'profile.pet' element in the _changes
The value of dummyChangeSet.profile.pet is being set to this 'empty' object, instead of applying the (non-existent) changes to the existing profile.pet object.
As best I can tell this is because BOTH the hasEmberDataProperty() and propertyIsOnObject() are returning false for profile.pet
When logged to the console, dummyChangeset.get('profile.pet') shows:
image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions