ember-data-source 1.13.13 → 1.13.14

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 93e4c4c2eed9329d209f59aecee26e31b08ec5ce
4
- data.tar.gz: 8f5ec20dbef2a1faada8d7304f96e639329ef61e
3
+ metadata.gz: 9699a22612fb166ea94fbf6a0703780fc30d40ce
4
+ data.tar.gz: c5684aa09224ca6d0bcaf3581556f8cfcb370410
5
5
  SHA512:
6
- metadata.gz: 9c645bd7be48d6c714249d2bc41e6ca3d4382d5371a40777a7413e73d2255774e193281a5aa58669b83cbbb42c3a2d927e930cb508812811183abaae6394640b
7
- data.tar.gz: 488ccd915d9655654bc8d303d8f856fbc3bff073060c56ec1831e07600ea4b462c5f96d487d58569f6f7594257049d7a3aa273fb9e6c091c87a8f6a01afce2a7
6
+ metadata.gz: 96b247d5d2fb0cde63e9b11a5a2e2bc777bcecefb118d0d49e939aaf10ee181c4cedfb9cd1829c02a478a42ae6c3926f216fe509d9c17a151b543d9b46d8b1ee
7
+ data.tar.gz: 67871da0a165d7a434284d7e3a4d2804ff1ca593c36a0ac10980c7286e6d880eeb76f067aa83e596cba204bce69cf3c8f508a6fdf414525d104668399ee1deba
@@ -294,7 +294,8 @@ define(
294
294
  var json;
295
295
 
296
296
  run(function () {
297
- json = env.amsSerializer.normalizeResponse(env.store, MediocreVillain, json_hash, '1', 'find');
297
+ var amsSerializer = env.store.serializerFor('application');
298
+ json = amsSerializer.normalizeResponse(env.store, MediocreVillain, json_hash, '1', 'find');
298
299
  });
299
300
 
300
301
  assert.deepEqual(json, {
@@ -329,7 +330,8 @@ define(
329
330
  var json;
330
331
 
331
332
  run(function () {
332
- json = env.amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json_hash, '1', 'find');
333
+ var amsSerializer = env.store.serializerFor('application');
334
+ json = amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json_hash, '1', 'find');
333
335
  });
334
336
 
335
337
  assert.deepEqual(json, {
@@ -461,7 +463,8 @@ define(
461
463
  var json;
462
464
 
463
465
  run(function () {
464
- json = env.amsSerializer.normalizeResponse(env.store, MediocreVillain, json_hash, '1', 'findRecord');
466
+ var amsSerializer = env.store.serializerFor('application');
467
+ json = amsSerializer.normalizeResponse(env.store, MediocreVillain, json_hash, '1', 'findRecord');
465
468
  });
466
469
 
467
470
  assert.deepEqual(json, {
@@ -496,7 +499,8 @@ define(
496
499
  var json;
497
500
 
498
501
  run(function () {
499
- json = env.amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json_hash, '1', 'findRecord');
502
+ var amsSerializer = env.store.serializerFor('application');
503
+ json = amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json_hash, '1', 'findRecord');
500
504
  });
501
505
 
502
506
  assert.deepEqual(json, {
@@ -751,7 +755,8 @@ define(
751
755
  var json;
752
756
 
753
757
  run(function () {
754
- json = env.amsSerializer.normalizeResponse(env.store, MediocreVillain, json_hash, '1', 'find');
758
+ var amsSerializer = env.store.serializerFor('application');
759
+ json = amsSerializer.normalizeResponse(env.store, MediocreVillain, json_hash, '1', 'find');
755
760
  });
756
761
 
757
762
  assert.deepEqual(json, {
@@ -794,7 +799,8 @@ define(
794
799
  var json;
795
800
 
796
801
  run(function () {
797
- json = env.amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json_hash, '1', 'find');
802
+ var amsSerializer = env.store.serializerFor('application');
803
+ json = amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json_hash, '1', 'find');
798
804
  });
799
805
 
800
806
  assert.deepEqual(json, {
@@ -828,7 +834,8 @@ define(
828
834
  };
829
835
 
830
836
  run(function () {
831
- json = env.amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json, '1', 'find');
837
+ var amsSerializer = env.store.serializerFor('application');
838
+ json = amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json, '1', 'find');
832
839
  });
833
840
 
834
841
  assert.deepEqual(json, {
@@ -857,7 +864,8 @@ define(
857
864
  };
858
865
 
859
866
  run(function () {
860
- json = env.amsSerializer.normalizeResponse(env.store, MediocreVillain, json, '1', 'find');
867
+ var amsSerializer = env.store.serializerFor('application');
868
+ json = amsSerializer.normalizeResponse(env.store, MediocreVillain, json, '1', 'find');
861
869
  });
862
870
 
863
871
  assert.deepEqual(json, {
@@ -1210,7 +1218,8 @@ define(
1210
1218
  var json;
1211
1219
 
1212
1220
  run(function () {
1213
- json = env.amsSerializer.normalizeResponse(env.store, MediocreVillain, json_hash, '1', 'findRecord');
1221
+ var amsSerializer = env.store.serializerFor('application');
1222
+ json = amsSerializer.normalizeResponse(env.store, MediocreVillain, json_hash, '1', 'findRecord');
1214
1223
  });
1215
1224
 
1216
1225
  assert.deepEqual(json, {
@@ -1253,7 +1262,8 @@ define(
1253
1262
  var json;
1254
1263
 
1255
1264
  run(function () {
1256
- json = env.amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json_hash, '1', 'findRecord');
1265
+ var amsSerializer = env.store.serializerFor('application');
1266
+ json = amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json_hash, '1', 'findRecord');
1257
1267
  });
1258
1268
 
1259
1269
  assert.deepEqual(json, {
@@ -1301,7 +1311,8 @@ define(
1301
1311
  var json;
1302
1312
 
1303
1313
  run(function () {
1304
- json = env.amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json_hash, '1', 'findRecord');
1314
+ var amsSerializer = env.store.serializerFor('application');
1315
+ json = amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json_hash, '1', 'findRecord');
1305
1316
  });
1306
1317
 
1307
1318
  assert.deepEqual(json, {
@@ -1354,7 +1365,8 @@ define(
1354
1365
  var json;
1355
1366
 
1356
1367
  run(function () {
1357
- json = env.amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json_hash, '1', 'findRecord');
1368
+ var amsSerializer = env.store.serializerFor('application');
1369
+ json = amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json_hash, '1', 'findRecord');
1358
1370
  });
1359
1371
 
1360
1372
  assert.deepEqual(json, {
@@ -1389,7 +1401,8 @@ define(
1389
1401
  };
1390
1402
 
1391
1403
  run(function () {
1392
- json = env.amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json, '1', 'findRecord');
1404
+ var amsSerializer = env.store.serializerFor('application');
1405
+ json = amsSerializer.normalizeResponse(env.store, DoomsdayDevice, json, '1', 'findRecord');
1393
1406
  });
1394
1407
 
1395
1408
  assert.deepEqual(json, {
@@ -1418,7 +1431,8 @@ define(
1418
1431
  };
1419
1432
 
1420
1433
  run(function () {
1421
- json = env.amsSerializer.normalizeResponse(env.store, MediocreVillain, json, '1', 'findRecord');
1434
+ var amsSerializer = env.store.serializerFor('application');
1435
+ json = amsSerializer.normalizeResponse(env.store, MediocreVillain, json, '1', 'findRecord');
1422
1436
  });
1423
1437
 
1424
1438
  assert.deepEqual(json, {
@@ -1440,7 +1454,8 @@ define(
1440
1454
  };
1441
1455
 
1442
1456
  run(function () {
1443
- json = env.amsSerializer.normalizeResponse(env.store, MediocreVillain, json, '1', 'findRecord');
1457
+ var amsSerializer = env.store.serializerFor('application');
1458
+ json = amsSerializer.normalizeResponse(env.store, MediocreVillain, json, '1', 'findRecord');
1444
1459
  });
1445
1460
 
1446
1461
  assert.deepEqual(json, {
@@ -1498,7 +1513,8 @@ define(
1498
1513
  var json, minion;
1499
1514
 
1500
1515
  run(function () {
1501
- json = env.amsSerializer.normalizeResponse(env.store, DoomsdayDevice, payload, '1', 'findRecord');
1516
+ var amsSerializer = env.store.serializerFor('application');
1517
+ json = amsSerializer.normalizeResponse(env.store, DoomsdayDevice, payload, '1', 'findRecord');
1502
1518
  env.store.push(json);
1503
1519
  minion = env.store.findRecord('doomsday-device', 1);
1504
1520
  });
@@ -1524,7 +1540,8 @@ define(
1524
1540
  var json, villain;
1525
1541
 
1526
1542
  run(function () {
1527
- json = env.amsSerializer.normalizeResponse(env.store, MediocreVillain, payload, '1', 'findRecord');
1543
+ var amsSerializer = env.store.serializerFor('application');
1544
+ json = amsSerializer.normalizeResponse(env.store, MediocreVillain, payload, '1', 'findRecord');
1528
1545
  env.store.push(json);
1529
1546
  villain = env.store.findRecord('mediocre-villain', '1');
1530
1547
  });
@@ -9300,7 +9317,7 @@ define(
9300
9317
  });
9301
9318
 
9302
9319
  test("Repeated failed saves keeps the record in uncommited state", function () {
9303
- expect(2);
9320
+ expect(4);
9304
9321
  var post;
9305
9322
 
9306
9323
  run(function () {
@@ -9313,15 +9330,70 @@ define(
9313
9330
 
9314
9331
  run(function () {
9315
9332
  post.save().then(null, function () {
9333
+ ok(post.get('isError'));
9316
9334
  equal(post.get('currentState.stateName'), 'root.loaded.created.uncommitted');
9317
9335
 
9318
9336
  post.save().then(null, function () {
9337
+ ok(post.get('isError'));
9319
9338
  equal(post.get('currentState.stateName'), 'root.loaded.created.uncommitted');
9320
9339
  });
9321
9340
  });
9322
9341
  });
9323
9342
  });
9324
9343
 
9344
+ test("Repeated failed saves with invalid error marks the record as invalid", function () {
9345
+ expect(2);
9346
+ var post;
9347
+
9348
+ run(function () {
9349
+ post = env.store.createRecord('post', { title: 'toto' });
9350
+ });
9351
+
9352
+ env.adapter.createRecord = function (store, type, snapshot) {
9353
+ var error = new DS.InvalidError([{
9354
+ detail: 'is invalid',
9355
+ source: { pointer: 'data/attributes/title' }
9356
+ }]);
9357
+
9358
+ return Ember.RSVP.reject(error);
9359
+ };
9360
+
9361
+ run(function () {
9362
+ post.save().then(null, function () {
9363
+ equal(post.get('isValid'), false);
9364
+
9365
+ post.save().then(null, function () {
9366
+ equal(post.get('isValid'), false);
9367
+ });
9368
+ });
9369
+ });
9370
+ });
9371
+
9372
+ test("Repeated failed saves with invalid error without payload marks the record as invalid", function () {
9373
+ expect(2);
9374
+ var post;
9375
+
9376
+ run(function () {
9377
+ post = env.store.createRecord('post', { title: 'toto' });
9378
+ });
9379
+
9380
+ env.adapter.createRecord = function (store, type, snapshot) {
9381
+ var error = new DS.InvalidError();
9382
+
9383
+ return Ember.RSVP.reject(error);
9384
+ };
9385
+
9386
+ run(function () {
9387
+ post.save().then(null, function () {
9388
+ equal(post.get('isValid'), false);
9389
+
9390
+ post.save().then(null, function () {
9391
+ equal(post.get('isValid'), false);
9392
+ });
9393
+ });
9394
+ });
9395
+ });
9396
+
9325
9397
  test("Will reject save on invalid", function () {
9326
9398
  expect(1);
9327
9399
  var post;
@@ -16927,6 +16999,7 @@ define(
16927
16999
  User = DS.Model.extend({
16928
17000
  firstName: DS.attr('string'),
16929
17001
  lastName: DS.attr('string'),
17002
+ title: DS.attr('string'),
16930
17003
  handles: DS.hasMany('handle', { async: true, polymorphic: true }),
16931
17004
  company: DS.belongsTo('company', { async: true })
16932
17005
  });
@@ -17016,6 +17089,71 @@ define(
17016
17089
  equal(get(user, 'handles.lastObject.nickname'), '@wycats', 'handles.lastObject.nickname is correct');
17017
17090
  });
17018
17091
  });
17092
+
17093
+ test('Serializer should respect the attrs hash when extracting attributes and relationships', function () {
17094
+ env.registry.register("serializer:user", DS.JSONAPISerializer.extend({
17095
+ attrs: {
17096
+ title: "title_attribute_key",
17097
+ company: { key: 'company_relationship_key' }
17098
+ }
17099
+ }));
17100
+
17101
+ var jsonHash = {
17102
+ data: {
17103
+ type: 'users',
17104
+ id: '1',
17105
+ attributes: {
17106
+ 'title_attribute_key': 'director'
17107
+ },
17108
+ relationships: {
17109
+ 'company_relationship_key': {
17110
+ data: { type: 'companies', id: '2' }
17111
+ }
17112
+ }
17113
+ },
17114
+ included: [{
17115
+ type: 'companies',
17116
+ id: '2',
17117
+ attributes: {
17118
+ name: 'Tilde Inc.'
17119
+ }
17120
+ }]
17121
+ };
17122
+
17123
+ var user = env.store.serializerFor("user").normalizeResponse(env.store, User, jsonHash, '1', 'findRecord');
17124
+
17125
+ equal(user.data.attributes.title, "director");
17126
+ deepEqual(user.data.relationships.company.data, { id: "2", type: "company" });
17127
+ });
17128
+
17129
+ test('Serializer should respect the attrs hash when serializing attributes and relationships', function () {
17130
+ env.registry.register("serializer:user", DS.JSONAPISerializer.extend({
17131
+ attrs: {
17132
+ title: "title_attribute_key",
17133
+ company: { key: 'company_relationship_key' }
17134
+ }
17135
+ }));
17136
+ var company, user;
17137
+
17138
+ run(function () {
17139
+ env.store.push({
17140
+ data: {
17141
+ type: 'company',
17142
+ id: '1',
17143
+ attributes: {
17144
+ name: "Tilde Inc."
17145
+ }
17146
+ }
17147
+ });
17148
+ company = env.store.peekRecord('company', 1);
17149
+ user = env.store.createRecord('user', { firstName: "Yehuda", title: "director", company: company });
17150
+ });
17151
+
17152
+ var payload = env.store.serializerFor("user").serialize(user._createSnapshot());
17153
+
17154
+ equal(payload.data.relationships['company_relationship_key'].data.id, "1");
17155
+ equal(payload.data.attributes['title_attribute_key'], "director");
17156
+ });
17019
17157
  }
17020
17158
  );
17021
17159
 
@@ -17487,6 +17625,90 @@ define(
17487
17625
  equal(payload.my_parent, '2');
17488
17626
  });
17489
17627
 
17628
+ test('Serializer respects if embedded model has an attribute named "type" - #3726', function () {
17629
+ env.registry.register("serializer:parent", DS.JSONSerializer.extend(DS.EmbeddedRecordsMixin, {
17630
+ isNewSerializerAPI: true,
17631
+ attrs: {
17632
+ child: { embedded: 'always' }
17633
+ }
17634
+ }));
17635
+ env.registry.register("serializer:child", DS.JSONSerializer.extend({
17636
+ isNewSerializerAPI: true
17637
+ }));
17638
+ env.registry.register("model:parent", DS.Model.extend({
17639
+ child: DS.belongsTo('child')
17640
+ }));
17641
+ env.registry.register("model:child", DS.Model.extend({
17642
+ type: DS.attr()
17643
+ }));
17644
+
17645
+ var jsonHash = {
17646
+ id: 1,
17647
+ child: {
17648
+ id: 1,
17649
+ type: 'first_type'
17650
+ }
17651
+ };
17652
+
17653
+ Ember.run(function () {
17654
+ var Parent = env.store.modelFor('parent');
17655
+ var payload = env.store.serializerFor('parent').normalizeResponse(env.store, Parent, jsonHash, '1', 'findRecord');
17656
+ deepEqual(payload.included, [{
17657
+ id: '1',
17658
+ type: 'child',
17659
+ attributes: {
17660
+ type: 'first_type'
17661
+ },
17662
+ relationships: {}
17663
+ }]);
17664
+ });
17665
+ });
17666
+
17667
+ test('Serializer respects if embedded model has a relationship named "type" - #3726', function () {
17668
+ env.registry.register("serializer:parent", DS.JSONSerializer.extend(DS.EmbeddedRecordsMixin, {
17669
+ isNewSerializerAPI: true,
17670
+ attrs: {
17671
+ child: { embedded: 'always' }
17672
+ }
17673
+ }));
17674
+ env.registry.register("serializer:child", DS.JSONSerializer.extend({
17675
+ isNewSerializerAPI: true
17676
+ }));
17677
+ env.registry.register("model:parent", DS.Model.extend({
17678
+ child: DS.belongsTo('child')
17679
+ }));
17680
+ env.registry.register("model:child", DS.Model.extend({
17681
+ type: DS.belongsTo('le-type')
17682
+ }));
17683
+ env.registry.register("model:le-type", DS.Model.extend());
17684
+
17685
+ var jsonHash = {
17686
+ id: 1,
17687
+ child: {
17688
+ id: 1,
17689
+ type: "my_type_id"
17690
+ }
17691
+ };
17692
+
17693
+ Ember.run(function () {
17694
+ var Parent = env.store.modelFor('parent');
17695
+ var payload = env.store.serializerFor('parent').normalizeResponse(env.store, Parent, jsonHash, '1', 'findRecord');
17696
+ deepEqual(payload.included, [{
17697
+ id: '1',
17698
+ type: 'child',
17699
+ attributes: {},
17700
+ relationships: {
17701
+ type: {
17702
+ data: {
17703
+ id: 'my_type_id',
17704
+ type: 'le-type'
17705
+ }
17706
+ }
17707
+ }
17708
+ }]);
17709
+ });
17710
+ });
17711
+
17490
17712
  test('Serializer respects `serialize: false` on the attrs hash', function () {
17491
17713
  expect(2);
17492
17714
  env.registry.register("serializer:post", DS.JSONSerializer.extend({
@@ -18380,7 +18602,7 @@ define(
18380
18602
  }
18381
18603
 
18382
18604
  var get = Ember.get;
18383
- var HomePlanet, league, SuperVillain, EvilMinion, YellowMinion, DoomsdayDevice, Comment, Basket, env;
18605
+ var HomePlanet, league, SuperVillain, EvilMinion, YellowMinion, DoomsdayDevice, Comment, Basket, Container, env;
18384
18606
  var run = Ember.run;
18385
18607
 
18386
18608
  module("integration/serializer/rest - RESTSerializer", {
@@ -18415,6 +18637,10 @@ define(
18415
18637
  type: DS.attr('string'),
18416
18638
  size: DS.attr('number')
18417
18639
  });
18640
+ Container = DS.Model.extend({
18641
+ type: DS.belongsTo('basket', { async: true }),
18642
+ volume: DS.attr('string')
18643
+ });
18418
18644
  env = setupStore({
18419
18645
  superVillain: SuperVillain,
18420
18646
  homePlanet: HomePlanet,
@@ -18422,7 +18648,8 @@ define(
18422
18648
  yellowMinion: YellowMinion,
18423
18649
  doomsdayDevice: DoomsdayDevice,
18424
18650
  comment: Comment,
18425
- basket: Basket
18651
+ basket: Basket,
18652
+ container: Container
18426
18653
  });
18427
18654
  env.store.modelFor('super-villain');
18428
18655
  env.store.modelFor('home-planet');
@@ -18899,9 +19126,9 @@ define(
18899
19126
  }));
18900
19127
 
18901
19128
  run(function () {
18902
- env.restSerializer.normalizeArrayResponse(env.store, Basket, {
18903
- basket: [env.store.createRecord('Basket', { type: 'bamboo', size: 10, id: '1' }), env.store.createRecord('Basket', { type: 'yellowMinion', size: 10, id: '65536' })]
18904
- });
19129
+ env.store.push(env.restSerializer.normalizeArrayResponse(env.store, Basket, {
19130
+ basket: [{ type: 'bamboo', size: 10, id: '1' }, { type: 'yellowMinion', size: 10, id: '65536' }]
19131
+ }));
18905
19132
  });
18906
19133
 
18907
19134
  var normalRecord = env.store.peekRecord('basket', '1');
@@ -18914,6 +19141,47 @@ define(
18914
19141
  strictEqual(clashingRecord.get('type'), 'yellowMinion');
18915
19142
  strictEqual(clashingRecord.get('size'), 10);
18916
19143
  });
19144
+
19145
+ test("don't polymorphically deserialize base on the type key in payload when a type attribute exist on a singular response", function () {
19146
+ env.registry.register('serializer:application', DS.RESTSerializer.extend({
19147
+ isNewSerializerAPI: true
19148
+ }));
19149
+
19150
+ run(function () {
19151
+ var restSerializer = env.store.serializerFor('application');
19152
+ env.store.push(restSerializer.normalizeSingleResponse(env.store, Basket, {
19153
+ basket: { type: 'yellowMinion', size: 10, id: '65536' }
19154
+ }, '65536'));
19155
+ });
19156
+
19157
+ var clashingRecord = env.store.peekRecord('basket', '65536');
19158
+ ok(clashingRecord, 'payload with type that matches another model name');
19159
+ strictEqual(clashingRecord.get('type'), 'yellowMinion');
19160
+ strictEqual(clashingRecord.get('size'), 10);
19161
+ });
19162
+
19163
+ test("don't polymorphically deserialize based on the type key in payload when a relationship exists named type", function () {
19164
+ env.registry.register('serializer:application', DS.RESTSerializer.extend({
19165
+ isNewSerializerAPI: true
19166
+ }));
19167
+
19168
+ env.adapter.findRecord = function () {
19169
+ return {
19170
+ containers: [{ id: 42, volume: '10 liters', type: 1 }],
19171
+ baskets: [{ id: 1, size: 4 }]
19172
+ };
19173
+ };
19174
+
19175
+ run(function () {
19176
+ env.store.findRecord('container', 42).then(function (container) {
19177
+ strictEqual(container.get('volume'), '10 liters');
19178
+ return container.get('type');
19179
+ }).then(function (basket) {
19180
+ ok(basket instanceof Basket);
19181
+ equal(basket.get('size'), 4);
19182
+ });
19183
+ });
19184
+ });
18917
19185
  }
18918
19186
  );
18919
19187
 
@@ -21326,13 +21594,13 @@ define(
21326
21594
  willChangeStartIdx = startIdx;
21327
21595
  willChangeRemoveAmt = removeAmt;
21328
21596
  willChangeAddAmt = addAmt;
21329
- return this._super.apply(arguments);
21597
+ return this._super.apply(this, arguments);
21330
21598
  },
21331
21599
  arrayContentDidChange: function (startIdx, removeAmt, addAmt) {
21332
21600
  equal(startIdx, willChangeStartIdx, 'WillChange and DidChange startIdx should match');
21333
21601
  equal(removeAmt, willChangeRemoveAmt, 'WillChange and DidChange removeAmt should match');
21334
21602
  equal(addAmt, willChangeAddAmt, 'WillChange and DidChange addAmt should match');
21335
- return this._super.apply(arguments);
21603
+ return this._super.apply(this, arguments);
21336
21604
  }
21337
21605
  });
21338
21606
  run(function () {
@@ -24339,6 +24607,49 @@ define(
24339
24607
  });
24340
24608
  });
24341
24609
 
24610
+ test("invalid record's attributes can be rollbacked after multiple failed calls - #3677", function () {
24611
+ var person;
24612
+
24613
+ var adapter = DS.RESTAdapter.extend({
24614
+ ajax: function (url, type, hash) {
24615
+ var error = new DS.InvalidError();
24616
+ return Ember.RSVP.reject(error);
24617
+ }
24618
+ });
24619
+
24620
+ env = setupStore({ person: Person, adapter: adapter });
24621
+
24622
+ run(function () {
24623
+ person = env.store.push({
24624
+ data: {
24625
+ type: 'person',
24626
+ id: 1,
24627
+ attributes: {
24628
+ firstName: 'original name'
24629
+ }
24630
+ }
24631
+ });
24632
+
24633
+ person.set('firstName', 'updated name');
24634
+ });
24635
+
24636
+ run(function () {
24637
+ equal(person.get('firstName'), 'updated name', "precondition: firstName is changed");
24638
+
24639
+ person.save().then(null, async(function () {
24640
+ equal(person.get('hasDirtyAttributes'), true, "has dirty attributes");
24641
+ equal(person.get('firstName'), 'updated name', "firstName is still changed");
24642
+
24643
+ return person.save();
24644
+ })).then(null, async(function () {
24645
+ person.rollbackAttributes();
24646
+
24647
+ equal(person.get('hasDirtyAttributes'), false, "has no dirty attributes");
24648
+ equal(person.get('firstName'), 'original name', "after rollbackAttributes() firstName has the original value");
24649
+ }));
24650
+ });
24651
+ });
24652
+
24342
24653
  test("deleted record's attributes can be rollbacked", function () {
24343
24654
  var person, people;
24344
24655
 
@@ -27930,7 +28241,26 @@ define(
27930
28241
 
27931
28242
  // TODO enable import once this is possible
27932
28243
  // import { assertPolymorphicType } from "ember-data/utils";
27933
-
28244
+ // import { modelHasAttributeOrRelationshipNamedType } from "ember-data/utils";
28245
+
28246
+ // TODO enable once we can `import x from y;` in tests
28247
+ // test("modelHasAttributeOrRelationshipNamedType", function() {
28248
+ // var ModelWithTypeAttribute = DS.Model.extend({
28249
+ // type: DS.attr()
28250
+ // });
28251
+ // var ModelWithTypeBelongsTo = DS.Model.extend({
28252
+ // type: DS.belongsTo()
28253
+ // });
28254
+ // var ModelWithTypeHasMany = DS.Model.extend({
28255
+ // type: DS.hasMany()
28256
+ // });
28257
+ //
28258
+ // equal(modelHasAttributeOrRelationshipNamedType(DS.Model), false);
28259
+ //
28260
+ // equal(modelHasAttributeOrRelationshipNamedType(ModelWithTypeAttribute), true);
28261
+ // equal(modelHasAttributeOrRelationshipNamedType(ModelWithTypeBelongsTo), true);
28262
+ // equal(modelHasAttributeOrRelationshipNamedType(ModelWithTypeHasMany), true);
28263
+ // });
27934
28264
  define("ember-data/tests/unit/utils-test", ["exports"], function(__exports__) {
27935
28265
  "use strict";
27936
28266