@@ -4,12 +4,13 @@ import { module, test } from 'qunit';
44
55import { setupTest } from 'ember-qunit' ;
66
7- import Model , { attr , hasMany } from '@ember-data/model' ;
7+ import Model , { attr , belongsTo , hasMany } from '@ember-data/model' ;
88import testInDebug from '@ember-data/unpublished-test-infra/test-support/test-in-debug' ;
99
1010class Person extends Model {
1111 @attr name ;
1212 @hasMany ( 'person' , { async : true , inverse : 'friends' } ) friends ;
13+ @belongsTo ( 'person' , { async : true , inverse : null } ) bestFriend ;
1314}
1415
1516module ( 'Integration | Records | New Record Unload' , function ( hooks ) {
@@ -60,6 +61,77 @@ module('Integration | Records | New Record Unload', function (hooks) {
6061 assert . strictEqual ( people . length , 1 , 'precond - one person left in the store' ) ;
6162 } ) ;
6263
64+ test ( 'Rolling Back Attributes on multiple New (related via async self-reflexive HasMany) Records unloads them safely' , async function ( assert ) {
65+ const store = this . owner . lookup ( 'service:store' ) ;
66+ const Pat = store . createRecord ( 'person' , { name : 'Patrick Wachter' } ) ;
67+ const Matt = store . createRecord ( 'person' , { name : 'Matthew Seidel' , friends : [ Pat ] } ) ;
68+ const friends = Matt . hasMany ( 'friends' ) . value ( ) ;
69+ const people = store . peekAll ( 'person' ) ;
70+
71+ assert . strictEqual ( friends . length , 1 , 'Matt has friends' ) ;
72+ assert . strictEqual ( people . length , 2 , 'precond - two people records in the store' ) ;
73+ assert . true ( Matt . hasDirtyAttributes , 'precond - record has dirty attributes' ) ;
74+ assert . true ( Matt . isNew , 'precond - record is new' ) ;
75+ assert . true ( Pat . hasDirtyAttributes , 'precond - record has dirty attributes' ) ;
76+ assert . true ( Pat . isNew , 'precond - record is new' ) ;
77+
78+ Pat . rollbackAttributes ( ) ;
79+
80+ assert . false ( Pat . isDestroyed , 'Pat record is not yet destroyed' ) ;
81+ assert . true ( Pat . isDestroying , 'Pat record is destroying' ) ;
82+ assert . strictEqual ( friends . length , 0 , 'Matt has no friends' ) ;
83+ assert . strictEqual ( people . length , 1 , 'precond - one person left in the store' ) ;
84+
85+ Matt . rollbackAttributes ( ) ;
86+ assert . false ( Matt . isDestroyed , 'Matt record is not yet destroyed' ) ;
87+ assert . true ( Matt . isDestroying , 'Matt record is destroying' ) ;
88+ assert . strictEqual ( people . length , 0 , 'precond - no people left in the store' ) ;
89+
90+ await settled ( ) ;
91+
92+ assert . true ( Pat . isDestroyed , 'Pat record is destroyed' ) ;
93+ assert . true ( Pat . isDestroying , 'Pat record is destroying' ) ;
94+ assert . true ( Matt . isDestroyed , 'Matt record is destroyed' ) ;
95+ assert . true ( Matt . isDestroying , 'Matt record is destroying' ) ;
96+ assert . strictEqual ( people . length , 0 , 'precond - no people left in the store' ) ;
97+ } ) ;
98+
99+ test ( 'Rolling Back Attributes on multiple New (related via async belongsTo with no inverse) Records unloads them safely' , async function ( assert ) {
100+ const store = this . owner . lookup ( 'service:store' ) ;
101+ const Pat = store . createRecord ( 'person' , { name : 'Patrick Wachter' } ) ;
102+ const Matt = store . createRecord ( 'person' , { name : 'Matthew Seidel' , bestFriend : Pat } ) ;
103+ let bestFriend = Matt . belongsTo ( 'bestFriend' ) . value ( ) ;
104+ const people = store . peekAll ( 'person' ) ;
105+
106+ assert . strictEqual ( people . length , 2 , 'precond - two people records in the store' ) ;
107+ assert . strictEqual ( bestFriend , Pat , 'Matt has a best friend' ) ;
108+ assert . true ( Matt . hasDirtyAttributes , 'precond - record has dirty attributes' ) ;
109+ assert . true ( Matt . isNew , 'precond - record is new' ) ;
110+ assert . true ( Pat . hasDirtyAttributes , 'precond - record has dirty attributes' ) ;
111+ assert . true ( Pat . isNew , 'precond - record is new' ) ;
112+
113+ Pat . rollbackAttributes ( ) ;
114+
115+ bestFriend = Matt . belongsTo ( 'bestFriend' ) . value ( ) ;
116+ assert . strictEqual ( bestFriend , null , 'Matt has no best friend' ) ;
117+ assert . false ( Pat . isDestroyed , 'Pat record is not yet destroyed' ) ;
118+ assert . true ( Pat . isDestroying , 'Pat record is destroying' ) ;
119+ assert . strictEqual ( people . length , 1 , 'precond - one person left in the store' ) ;
120+
121+ Matt . rollbackAttributes ( ) ;
122+ assert . false ( Matt . isDestroyed , 'Matt record is not yet destroyed' ) ;
123+ assert . true ( Matt . isDestroying , 'Matt record is destroying' ) ;
124+ assert . strictEqual ( people . length , 0 , 'precond - no people left in the store' ) ;
125+
126+ await settled ( ) ;
127+
128+ assert . true ( Pat . isDestroyed , 'Pat record is destroyed' ) ;
129+ assert . true ( Pat . isDestroying , 'Pat record is destroying' ) ;
130+ assert . true ( Matt . isDestroyed , 'Matt record is destroyed' ) ;
131+ assert . true ( Matt . isDestroying , 'Matt record is destroying' ) ;
132+ assert . strictEqual ( people . length , 0 , 'precond - no people left in the store' ) ;
133+ } ) ;
134+
63135 test ( 'Unload on a New Record unloads that record safely' , async function ( assert ) {
64136 const store = this . owner . lookup ( 'service:store' ) ;
65137 const Matt = store . push ( {
0 commit comments