ember-data-factory-guy 0.9.9 → 0.9.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6e4648a11858529bb5355b440b02b0ca24a7f8bf
4
- data.tar.gz: 423900ef7416682118d3c180677af2f8fcf77468
3
+ metadata.gz: 5e79cf8c600cf6d977adb4d9c988e0d31486785a
4
+ data.tar.gz: 64dd2732df1804268becf7d76c3f3c593d05be12
5
5
  SHA512:
6
- metadata.gz: 611b82bee5d7602ed3d0294fe0d4cc1e66061ab0c98f103de3250a9be83b9e082652505dccd4c6b5bf33ee45f3008b4c9a62bac5f131741f4ab95b9a85c7d970
7
- data.tar.gz: 9efc3f1265f49dc5ebec18410d018e67077132be6298b9aaa547acab83fe839c70d961c6771d81e6bab0c97cd3711c65ed6ef01a86d9b477c26290414dd67c21
6
+ metadata.gz: d3b8ab0f269111f6b6583e4cae4936e3e7b3f055a1ae56bb2128494d61729790172fe6f5768f94f6a810077918fdfb9adf34502d5dc391ff07464e19c767ce25
7
+ data.tar.gz: f2dba9d3a2e780cd58afadf3f32c913924a53e927c7c36886f8906116dc6497ffcdc39f80c437ff6920ff50406a31f6bd035feb7f0f7a89a9b246a36044a3d7d
data/Gruntfile.js CHANGED
@@ -11,6 +11,7 @@ module.exports = function(grunt) {
11
11
  'src/model_definition.js',
12
12
  'src/factory_guy.js',
13
13
  'src/mock_create_request.js',
14
+ 'src/mock_update_request.js',
14
15
  'src/store.js',
15
16
  'src/factory_guy_test_mixin.js',
16
17
  ],
@@ -23,6 +24,7 @@ module.exports = function(grunt) {
23
24
  'src/model_definition.js',
24
25
  'src/factory_guy.js',
25
26
  'src/mock_create_request.js',
27
+ 'src/mock_update_request.js',
26
28
  'src/store.js',
27
29
  'src/factory_guy_test_mixin.js',
28
30
  'src/epilogue.js'
@@ -40,6 +42,7 @@ module.exports = function(grunt) {
40
42
  'src/model_definition.js',
41
43
  'src/factory_guy.js',
42
44
  'src/mock_create_request.js',
45
+ 'src/mock_update_request.js',
43
46
  'src/store.js',
44
47
  'src/factory_guy_test_mixin.js',
45
48
  'bower_components/jquery-mockjax/jquery.mockjax.js'],
data/README.md CHANGED
@@ -15,7 +15,7 @@ of ember-data-factory-guy.
15
15
  - 0.7.1.1 -> ember-data-1.0.0-beta.10
16
16
  - 0.8.6 -> ember-data-1.0.0-beta.11
17
17
  - 0.9.8 -> ember-data-1.0.0-beta.12
18
- - 0.9.9 -> ember-data-1.0.0-beta.15
18
+ - 0.9.10 -> ember-data-1.0.0-beta.15
19
19
 
20
20
  **Support for fixture adapter is working for versions 0.9.3 -> 0.9.8**
21
21
 
@@ -44,7 +44,7 @@ gem 'ember-data-factory-guy', group: test
44
44
  or for particular version:
45
45
 
46
46
  ```ruby
47
- gem 'ember-data-factory-guy', '0.9.9', group: test
47
+ gem 'ember-data-factory-guy', '0.9.10', group: test
48
48
  ```
49
49
 
50
50
  then:
@@ -79,7 +79,7 @@ or for particular version:
79
79
  "dependencies": {
80
80
  "foo-dependency": "latest",
81
81
  "other-foo-dependency": "latest",
82
- "ember-data-factory-guy": "0.9.9"
82
+ "ember-data-factory-guy": "0.9.10"
83
83
  }
84
84
  ```
85
85
 
@@ -814,8 +814,17 @@ chainable methods, or options hash.
814
814
 
815
815
 
816
816
  ##### handleUpdate
817
+
818
+ - Use chainable methods to build response:
819
+ - andFail - request should fail, use options argument to pass status and response text
820
+ - andSucceed - update should succeed, this is the default behavior, use this after a ```andFail``` call
821
+
817
822
  - handleUpdate(model)
818
823
  - handleUpdate(modelType, id)
824
+ - Use hash of options to build response:
825
+ - status - HTTP status code, defaults to 200.
826
+ - response - what the server has responded, only used on failure cases, default is empty on failure and model json on succees.
827
+ - succeed - indicates if the resquest should succeed, defaults to true.
819
828
  - need to wrap tests using handleUpdate with: Ember.run.function() { 'your test' })
820
829
 
821
830
  *success case is the default*
@@ -834,15 +843,54 @@ chainable methods, or options hash.
834
843
  profile.save() //=> will succeed
835
844
  ````
836
845
 
846
+ ######Using chainable methods
847
+
848
+ *mocking a failed update*
849
+
850
+ ```javascript
851
+ var profile = FactoryGuy.make('profile');
852
+
853
+ // set the succeed flag to 'false'
854
+ testHelper.handleUpdate('profile', profile.id).andFail({status: 422, response: "{error: 'Invalid data'}"});
855
+ // or
856
+ testHelper.handleUpdate(profile).andFail({status: 422, response: "{error: 'Invalid data'}"});
857
+
858
+ profile.set('description', 'bad value');
859
+ profile.save() //=> will fail
860
+ ````
861
+
862
+ *mocking a failed update and retry with succees*
863
+
864
+ ```javascript
865
+ var profile = FactoryGuy.make('profile');
866
+
867
+ // set the succeed flag to 'false'
868
+ var mockUpdate = testHelper.handleUpdate('profile', profile.id);
869
+ // or
870
+ var mockUpdate = testHelper.handleUpdate(profile);
871
+
872
+ mockUpdate.andFail({status: 422, response: "{error: 'Invalid data'}"});
873
+
874
+ profile.set('description', 'bad value');
875
+ profile.save() //=> will fail
876
+
877
+ // Some logic for retrying...
878
+
879
+ mockUpdate.andSucceed();
880
+ profile.save() //=> will succeed!
881
+ ````
882
+
883
+ ######Using hash of options
884
+
837
885
  *mocking a failed update*
838
886
 
839
887
  ```javascript
840
888
  var profile = FactoryGuy.make('profile');
841
889
 
842
890
  // set the succeed flag to 'false'
843
- testHelper.handleUpdate('profile', profile.id, false);
891
+ testHelper.handleUpdate('profile', profile.id, {succeed: false});
844
892
  // or
845
- testHelper.handleUpdate(profile, false);
893
+ testHelper.handleUpdate(profile, {succeed: false});
846
894
 
847
895
  profile.set('description', 'bad value');
848
896
  profile.save() //=> will fail
data/bower.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ember-data-factory-guy",
3
- "version": "0.9.9",
3
+ "version": "0.9.10",
4
4
  "authors": [
5
5
  "Daniel Sudol <dansudol@yahoo.com>",
6
6
  "Opak Alex <opak.alexandr@gmail.com>"
@@ -649,6 +649,55 @@ var MockCreateRequest = function(url, store, modelName, options) {
649
649
  $.mockjax(this.handler);
650
650
  };
651
651
 
652
+ var MockUpdateRequest = function(url, model, mapFind, options) {
653
+ var status = options.status || 200;
654
+ var succeed = true;
655
+ var response = null;
656
+
657
+ if ('succeed' in options) {
658
+ succeed = options.succeed;
659
+ }
660
+
661
+ if ('response' in options) {
662
+ response = options.response;
663
+ }
664
+
665
+ this.andSucceed = function(options) {
666
+ succeed = true;
667
+ return this;
668
+ };
669
+
670
+ this.andFail = function(options) {
671
+ succeed = false;
672
+ status = options.status || 500;
673
+ if ('response' in options) {
674
+ response = options.response;
675
+ }
676
+ return this;
677
+ };
678
+
679
+ this.handler = function(settings) {
680
+ if (!succeed) {
681
+ this.status = status;
682
+ if (response !== null) {
683
+ this.responseText = response;
684
+ }
685
+ } else {
686
+ var json = model.toJSON({includeId: true});
687
+ this.responseText = mapFind(model.constructor.typeKey, json);
688
+ this.status = 200;
689
+ }
690
+ };
691
+
692
+ var requestConfig = {
693
+ url: url,
694
+ dataType: 'json',
695
+ type: 'PUT',
696
+ response: this.handler
697
+ };
698
+
699
+ $.mockjax(requestConfig);
700
+ };
652
701
  (function () {
653
702
  DS.Store.reopen({
654
703
  /**
@@ -1196,34 +1245,35 @@ var FactoryGuyTestMixin = Em.Mixin.create({
1196
1245
  Handling ajax PUT ( update record ) for a model type. You can mock
1197
1246
  failed update by passing in success argument as false.
1198
1247
 
1199
- @param {String} type model type like 'user' for User model
1248
+ @param {String} type model type like 'user' for User model, or a model instance
1200
1249
  @param {String} id id of record to update
1201
- @param {Boolean} succeed optional flag to indicate if the request
1202
- should succeed ( default is true )
1250
+ @param {Object} options options object
1203
1251
  */
1204
1252
  handleUpdate: function () {
1205
- var args = Array.prototype.slice.call(arguments)
1253
+ var args = Array.prototype.slice.call(arguments);
1206
1254
  Ember.assert("To handleUpdate pass in a model instance or a type and an id", args.length>0)
1207
- var succeed = true;
1208
- if (typeof args[args.length-1] == 'boolean') {
1209
- args.pop()
1210
- succeed = false;
1255
+
1256
+ var options = {};
1257
+ if (args.length > 1 && typeof args[args.length - 1] === 'object') {
1258
+ options = args.pop();
1211
1259
  }
1212
- Ember.assert("To handleUpdate pass in a model instance or a type and an id",args.length>0)
1213
- var type, id;
1260
+
1261
+ var model, type, id;
1262
+ var store = this.getStore();
1263
+
1214
1264
  if (args[0] instanceof DS.Model) {
1215
- var model = args[0];
1216
- type = model.constructor.typeKey;
1265
+ model = args[0];
1217
1266
  id = model.id;
1267
+ type = model.constructor.typeKey;
1218
1268
  } else if (typeof args[0] == "string" && typeof parseInt(args[1]) == "number") {
1219
1269
  type = args[0];
1220
1270
  id = args[1];
1271
+ model = store.getById(type, id)
1221
1272
  }
1222
- Ember.assert("To handleUpdate pass in a model instance or a type and an id",type && id)
1223
- this.stubEndpointForHttpRequest(this.buildURL(type, id), {}, {
1224
- type: 'PUT',
1225
- status: succeed ? 200 : 500
1226
- });
1273
+ Ember.assert("To handleUpdate pass in a model instance or a type and an id",type && id);
1274
+
1275
+ var url = this.buildURL(type, id);
1276
+ return new MockUpdateRequest(url, model, this.mapFind, options);
1227
1277
  },
1228
1278
  /**
1229
1279
  Handling ajax DELETE ( delete record ) for a model type. You can mock
@@ -644,6 +644,55 @@ var MockCreateRequest = function(url, store, modelName, options) {
644
644
  $.mockjax(this.handler);
645
645
  };
646
646
 
647
+ var MockUpdateRequest = function(url, model, mapFind, options) {
648
+ var status = options.status || 200;
649
+ var succeed = true;
650
+ var response = null;
651
+
652
+ if ('succeed' in options) {
653
+ succeed = options.succeed;
654
+ }
655
+
656
+ if ('response' in options) {
657
+ response = options.response;
658
+ }
659
+
660
+ this.andSucceed = function(options) {
661
+ succeed = true;
662
+ return this;
663
+ };
664
+
665
+ this.andFail = function(options) {
666
+ succeed = false;
667
+ status = options.status || 500;
668
+ if ('response' in options) {
669
+ response = options.response;
670
+ }
671
+ return this;
672
+ };
673
+
674
+ this.handler = function(settings) {
675
+ if (!succeed) {
676
+ this.status = status;
677
+ if (response !== null) {
678
+ this.responseText = response;
679
+ }
680
+ } else {
681
+ var json = model.toJSON({includeId: true});
682
+ this.responseText = mapFind(model.constructor.typeKey, json);
683
+ this.status = 200;
684
+ }
685
+ };
686
+
687
+ var requestConfig = {
688
+ url: url,
689
+ dataType: 'json',
690
+ type: 'PUT',
691
+ response: this.handler
692
+ };
693
+
694
+ $.mockjax(requestConfig);
695
+ };
647
696
  (function () {
648
697
  DS.Store.reopen({
649
698
  /**
@@ -1191,34 +1240,35 @@ var FactoryGuyTestMixin = Em.Mixin.create({
1191
1240
  Handling ajax PUT ( update record ) for a model type. You can mock
1192
1241
  failed update by passing in success argument as false.
1193
1242
 
1194
- @param {String} type model type like 'user' for User model
1243
+ @param {String} type model type like 'user' for User model, or a model instance
1195
1244
  @param {String} id id of record to update
1196
- @param {Boolean} succeed optional flag to indicate if the request
1197
- should succeed ( default is true )
1245
+ @param {Object} options options object
1198
1246
  */
1199
1247
  handleUpdate: function () {
1200
- var args = Array.prototype.slice.call(arguments)
1248
+ var args = Array.prototype.slice.call(arguments);
1201
1249
  Ember.assert("To handleUpdate pass in a model instance or a type and an id", args.length>0)
1202
- var succeed = true;
1203
- if (typeof args[args.length-1] == 'boolean') {
1204
- args.pop()
1205
- succeed = false;
1250
+
1251
+ var options = {};
1252
+ if (args.length > 1 && typeof args[args.length - 1] === 'object') {
1253
+ options = args.pop();
1206
1254
  }
1207
- Ember.assert("To handleUpdate pass in a model instance or a type and an id",args.length>0)
1208
- var type, id;
1255
+
1256
+ var model, type, id;
1257
+ var store = this.getStore();
1258
+
1209
1259
  if (args[0] instanceof DS.Model) {
1210
- var model = args[0];
1211
- type = model.constructor.typeKey;
1260
+ model = args[0];
1212
1261
  id = model.id;
1262
+ type = model.constructor.typeKey;
1213
1263
  } else if (typeof args[0] == "string" && typeof parseInt(args[1]) == "number") {
1214
1264
  type = args[0];
1215
1265
  id = args[1];
1266
+ model = store.getById(type, id)
1216
1267
  }
1217
- Ember.assert("To handleUpdate pass in a model instance or a type and an id",type && id)
1218
- this.stubEndpointForHttpRequest(this.buildURL(type, id), {}, {
1219
- type: 'PUT',
1220
- status: succeed ? 200 : 500
1221
- });
1268
+ Ember.assert("To handleUpdate pass in a model instance or a type and an id",type && id);
1269
+
1270
+ var url = this.buildURL(type, id);
1271
+ return new MockUpdateRequest(url, model, this.mapFind, options);
1222
1272
  },
1223
1273
  /**
1224
1274
  Handling ajax DELETE ( delete record ) for a model type. You can mock
@@ -1 +1 @@
1
- var Sequence=function(fn){var index=1;this.next=function(){return fn.call(this,index++)};this.reset=function(){index=1}};var MissingSequenceError=function(message){this.toString=function(){return message}};if(FactoryGuy!==undefined){FactoryGuy.sequence=Sequence;FactoryGuy.missingSequenceError=MissingSequenceError}var ModelDefinition=function(model,config){var sequences={};var traits={};var defaultAttributes={};var namedModels={};var modelId=1;var sequenceName=null;this.model=model;this.matchesName=function(name){return model==name||namedModels[name]};this.nextId=function(){return modelId++};this.generate=function(name,sequenceFn){if(sequenceFn){if(!sequences[name]){sequences[name]=new Sequence(sequenceFn)}}var sequence=sequences[name];if(!sequence){throw new MissingSequenceError("Can not find that sequence named ["+sequenceName+"] in '"+model+"' definition")}return sequence.next()};this.build=function(name,opts,traitArgs){var traitsObj={};traitArgs.forEach(function(trait){$.extend(traitsObj,traits[trait])});var modelAttributes=namedModels[name]||{};var fixture=$.extend({},defaultAttributes,modelAttributes,traitsObj,opts);for(var attribute in fixture){if(Ember.typeOf(fixture[attribute])=="function"){fixture[attribute]=fixture[attribute].call(this,fixture)}else if(Ember.typeOf(fixture[attribute])=="object"){if(FactoryGuy.getStore()){if(FactoryGuy.isAttributeRelationship(this.model,attribute)){fixture[attribute]=FactoryGuy.build(attribute,fixture[attribute])}}else{fixture[attribute]=FactoryGuy.build(attribute,fixture[attribute])}}}if(!fixture.id){fixture.id=this.nextId()}return fixture};this.buildList=function(name,number,traits,opts){var arr=[];for(var i=0;i<number;i++){arr.push(this.build(name,opts,traits))}return arr};this.reset=function(){modelId=1;for(var name in sequences){sequences[name].reset()}};var parseDefault=function(object){if(!object){return}defaultAttributes=object};var parseTraits=function(object){if(!object){return}traits=object};var parseSequences=function(object){if(!object){return}for(sequenceName in object){var sequenceFn=object[sequenceName];if(Ember.typeOf(sequenceFn)!="function"){throw new Error("Problem with ["+sequenceName+"] sequence definition. Sequences must be functions")}object[sequenceName]=new Sequence(sequenceFn)}sequences=object};var parseConfig=function(config){parseSequences(config.sequences);delete config.sequences;parseTraits(config.traits);delete config.traits;parseDefault(config.default);delete config.default;namedModels=config};parseConfig(config)};if(FactoryGuy!==undefined){FactoryGuy.modelDefiniton=ModelDefinition}var FactoryGuy={modelDefinitions:{},define:function(model,config){if(this.modelDefinitions[model]){this.modelDefinitions[model].merge(config)}else{this.modelDefinitions[model]=new ModelDefinition(model,config)}},setStore:function(store){Ember.assert("FactoryGuy#setStore needs a valid store instance.You passed in ["+store+"]",store instanceof DS.Store);this.store=store},getStore:function(){return this.store},isAttributeRelationship:function(typeName,attribute){if(!this.store){Ember.debug("FactoryGuy does not have the application's store. Use FactoryGuy.setStore(store) before making any fixtures");return true}var model=this.store.modelFor(typeName);return!!model.typeForRelationship(attribute)},generate:function(nameOrFunction){var sortaRandomName=Math.floor((1+Math.random())*65536).toString(16)+Date.now();return function(){if(Em.typeOf(nameOrFunction)=="function"){return this.generate(sortaRandomName,nameOrFunction)}else{return this.generate(nameOrFunction)}}},belongsTo:function(fixtureName,opts){return function(){return FactoryGuy.build(fixtureName,opts)}},association:function(fixtureName,opts){Ember.deprecate("DEPRECATION Warning: use FactoryGuy.belongsTo instead");return this.belongsTo(fixtureName,opts)},hasMany:function(fixtureName,number,opts){return function(){return FactoryGuy.buildList(fixtureName,number,opts)}},lookupModelForFixtureName:function(name){var definition=this.lookupDefinitionForFixtureName(name);if(definition){return definition.model}},lookupDefinitionForFixtureName:function(name){for(var model in this.modelDefinitions){var definition=this.modelDefinitions[model];if(definition.matchesName(name)){return definition}}},build:function(){var args=Array.prototype.slice.call(arguments);var opts={};var name=args.shift();if(!name){throw new Error("Build needs a factory name to build")}if(Ember.typeOf(args[args.length-1])=="object"){opts=args.pop()}var traits=args;var definition=this.lookupDefinitionForFixtureName(name);if(!definition){throw new Error("Can't find that factory named ["+name+"]")}return definition.build(name,opts,traits)},buildList:function(){var args=Array.prototype.slice.call(arguments);var name=args.shift();var number=args.shift();if(!name||!number){throw new Error("buildList needs a name and a number ( at least ) to build with")}var opts={};if(Ember.typeOf(args[args.length-1])=="object"){opts=args.pop()}var traits=args;var definition=this.lookupDefinitionForFixtureName(name);if(!definition){throw new Error("Can't find that factory named ["+name+"]")}return definition.buildList(name,number,traits,opts)},make:function(){var store=this.store;Ember.assert("FactoryGuy does not have the application's store. Use FactoryGuy.setStore(store) before making any fixtures",store);var fixture=this.build.apply(this,arguments);var name=arguments[0];var modelName=this.lookupModelForFixtureName(name);var modelType=store.modelFor(modelName);if(store.usingFixtureAdapter()){store.setAssociationsForFixtureAdapter(modelType,modelName,fixture);fixture=FactoryGuy.pushFixture(modelType,fixture);store.loadModelForFixtureAdapter(modelType,fixture);return fixture}else{return store.makeModel(modelType,fixture)}},makeList:function(){Ember.assert("FactoryGuy does not have the application's store. Use FactoryGuy.setStore(store) before making any fixtures",this.store);var arr=[];var args=Array.prototype.slice.call(arguments);Ember.assert("makeList needs at least 2 arguments, a name and a number",args.length>=2);var number=args.splice(1,1)[0];Ember.assert("Second argument to makeList should be a number (of fixtures to make.)",typeof number=="number");for(var i=0;i<number;i++){arr.push(this.make.apply(this,args))}return arr},resetModels:function(store){for(var model in this.modelDefinitions){var definition=this.modelDefinitions[model];definition.reset();try{var modelType=store.modelFor(definition.model);if(store.usingFixtureAdapter()){modelType.FIXTURES=[]}store.unloadAll(modelType)}catch(e){console.log("resetModels",e)}}},pushFixture:function(modelClass,fixture){var index;if(!modelClass.FIXTURES){modelClass.FIXTURES=[]}index=this.indexOfFixture(modelClass.FIXTURES,fixture);if(index>-1){modelClass.FIXTURES.splice(index,1)}modelClass.FIXTURES.push(fixture);return fixture},indexOfFixture:function(fixtures,fixture){var index=-1,id=fixture.id+"";Ember.A(fixtures).find(function(r,i){if(""+Ember.get(r,"id")===id){index=i;return true}else{return false}});return index},clear:function(opts){if(!opts){this.modelDefinitions={}}}};var MockCreateRequest=function(url,store,modelName,options){var succeed=options.succeed===undefined?true:options.succeed;var matchArgs=options.match;var returnArgs=options.returns;var responseJson={};var expectedRequest={};var modelType=store.modelFor(modelName);this.calculate=function(){if(matchArgs){var tmpRecord=store.createRecord(modelName,matchArgs);expectedRequest=tmpRecord.serialize(matchArgs);tmpRecord.deleteRecord()}if(succeed){var definition=FactoryGuy.modelDefinitions[modelName];if(responseJson[modelName]){responseJson[modelName]=$.extend({id:responseJson[modelName].id},matchArgs,returnArgs)}else{responseJson[modelName]=$.extend({id:definition.nextId()},matchArgs,returnArgs)}Ember.get(modelType,"relationshipsByName").forEach(function(relationship){if(relationship.kind=="belongsTo"){delete responseJson[modelName][relationship.key]}})}};this.match=function(matches){matchArgs=matches;this.calculate();return this};this.andReturn=function(returns){returnArgs=returns;this.calculate();return this};this.andFail=function(){succeed=false;return this};this.handler=function(settings){if(settings.url!=url||settings.type!="POST"){return false}if(matchArgs){var requestData=JSON.parse(settings.data)[modelName];for(var attribute in expectedRequest){if(expectedRequest[attribute]&&requestData[attribute]!=expectedRequest[attribute]){return false}}}var responseStatus=succeed?200:500;return{responseText:responseJson,status:responseStatus}};this.calculate();$.mockjax(this.handler)};(function(){DS.Store.reopen({usingFixtureAdapter:function(){var adapter=this.adapterFor("application");return adapter instanceof DS.FixtureAdapter},makeFixture:function(){Ember.deprecate("DEPRECATION Warning: use FactoryGuy.make instead");FactoryGuy.make.call(FactoryGuy,arguments)},makeList:function(){Ember.deprecate("DEPRECATION Warning: use FactoryGuy.makeList instead");FactoryGuy.makeList.call(FactoryGuy,arguments)},makeModel:function(modelType,fixture){var store=this,modelName=store.modelFor(modelType).typeKey,model;Em.run(function(){store.findEmbeddedAssociationsForRESTAdapter(modelType,fixture);if(fixture.type){modelName=fixture.type.underscore();modelType=store.modelFor(modelName)}model=store.push(modelName,fixture);store.setAssociationsForRESTAdapter(modelType,modelName,model)});return model},setAssociationsForFixtureAdapter:function(modelType,modelName,fixture){var self=this;var adapter=this.adapterFor("application");Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){var hasManyRelation,belongsToRecord;if(relationship.kind=="hasMany"){hasManyRelation=fixture[relationship.key];if(hasManyRelation){$.each(fixture[relationship.key],function(index,object){var id=object;if(Ember.typeOf(object)=="object"){FactoryGuy.pushFixture(relationship.type,object);id=object.id;hasManyRelation[index]=id}var hasManyfixtures=adapter.fixturesForType(relationship.type);var hasManyFixture=adapter.findFixtureById(hasManyfixtures,id);hasManyFixture[modelName]=fixture.id;self.loadModelForFixtureAdapter(relationship.type,hasManyFixture)})}}if(relationship.kind=="belongsTo"){belongsToRecord=fixture[relationship.key];if(belongsToRecord){if(typeof belongsToRecord=="object"){FactoryGuy.pushFixture(relationship.type,belongsToRecord);fixture[relationship.key]=belongsToRecord.id}var hasManyName=self.findHasManyRelationshipNameForFixtureAdapter(relationship.type,relationship.parentType);var belongsToFixtures=adapter.fixturesForType(relationship.type);var belongsTofixture=adapter.findFixtureById(belongsToFixtures,fixture[relationship.key]);if(!belongsTofixture[hasManyName]){belongsTofixture[hasManyName]=[]}belongsTofixture[hasManyName].push(fixture.id);self.loadModelForFixtureAdapter(relationship.type,belongsTofixture)}}})},loadModelForFixtureAdapter:function(modelType,fixture){var storeModel=this.getById(modelType,fixture.id),that=this;if(!Ember.isPresent(storeModel)||storeModel.get("isEmpty")){Ember.run(function(){var dup=Ember.copy(fixture,true);that.push(modelType,fixture);Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){if(fixture[relationship.key]){fixture[relationship.key]=dup[relationship.key]}})})}},findEmbeddedAssociationsForRESTAdapter:function(modelType,fixture){var store=this;Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind=="belongsTo"){var belongsToRecord=fixture[relationship.key];if(Ember.typeOf(belongsToRecord)=="object"){store.findEmbeddedAssociationsForRESTAdapter(relationship.type,belongsToRecord);belongsToRecord=store.push(relationship.type,belongsToRecord);fixture[relationship.key]=belongsToRecord}}if(relationship.kind=="hasMany"){var hasManyRecords=fixture[relationship.key];if(Ember.typeOf(hasManyRecords)=="array"){if(Ember.typeOf(hasManyRecords[0])=="object"){var records=Em.A();hasManyRecords.map(function(object){store.findEmbeddedAssociationsForRESTAdapter(relationship.type,object);var record=store.push(relationship.type,object);records.push(record);return record});fixture[relationship.key]=records}}}})},setAssociationsForRESTAdapter:function(modelType,modelName,model){var self=this;Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind=="hasMany"){var children=model.get(name)||[];children.forEach(function(child){var belongsToName=self.findRelationshipName("belongsTo",child.constructor,model);if(belongsToName){child.set(belongsToName,model)}})}})},findRelationshipName:function(kind,belongToModelType,childModel){var relationshipName;Ember.get(belongToModelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind==kind&&childModel instanceof relationship.type){relationshipName=relationship.key}});return relationshipName},findHasManyRelationshipNameForFixtureAdapter:function(belongToModelType,childModelType){var relationshipName;Ember.get(belongToModelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind=="hasMany"&&childModelType==relationship.type){relationshipName=relationship.key}});return relationshipName},pushPayload:function(type,payload){var typeName,model;if(this.usingFixtureAdapter()){if(Ember.typeOf(type)==="string"&&Ember.isPresent(payload)&&Ember.isPresent(payload.id)){model=this.modelFor(type);FactoryGuy.pushFixture(model,payload);this.push(model,Ember.copy(payload,true))}else if(Ember.typeOf(type)==="object"||Ember.typeOf(payload)==="object"){if(Ember.isBlank(payload)){payload=type}for(var prop in payload){typeName=Ember.String.camelize(Ember.String.singularize(prop));model=this.modelFor(typeName);this.pushMany(model,Ember.makeArray(Ember.copy(payload[prop],true)));Ember.ArrayPolyfills.forEach.call(Ember.makeArray(payload[prop]),function(hash){FactoryGuy.pushFixture(model,hash)},this)}}else{throw new Ember.Error("Assertion Failed: You cannot use `store#pushPayload` with this method signature pushPayload("+type+","+payload+")")}}else{this._super(type,payload)}}})})();var FactoryGuyTestMixin=Em.Mixin.create({setup:function(app){this.set("container",app.__container__);FactoryGuy.setStore(this.getStore());return this},useFixtureAdapter:function(app){app.ApplicationAdapter=DS.FixtureAdapter;this.getStore().adapterFor("application").simulateRemoteResponse=false},usingActiveModelSerializer:function(type){var store=this.getStore();var modelType=store.modelFor(type);var serializer=store.serializerFor(modelType.typeKey);return serializer instanceof DS.ActiveModelSerializer},find:function(type,id){return this.getStore().find(type,id)},make:function(){return FactoryGuy.make.apply(FactoryGuy,arguments)},getStore:function(){return this.get("container").lookup("store:main")},stubEndpointForHttpRequest:function(url,json,options){options=options||{};var request={url:url,dataType:"json",responseText:json,type:options.type||"GET",status:options.status||200};if(options.urlParams){request.urlParams=options.urlParams}if(options.data){request.data=options.data}$.mockjax(request)},buildURL:function(typeName,id){var type=this.getStore().modelFor(typeName);return this.getStore().adapterFor(type).buildURL(type.typeKey,id)},mapFindAll:function(modelName,json){var responseJson={};responseJson[modelName.pluralize()]=json;return responseJson},mapFind:function(modelName,json){var responseJson={};responseJson[modelName.pluralize()]=json;return responseJson},handleFindAll:function(){var records=FactoryGuy.makeList.apply(FactoryGuy,arguments);var name=arguments[0];var modelName=FactoryGuy.lookupModelForFixtureName(name);var json=records.map(function(record){return record.toJSON({includeId:true})});var responseJson=this.mapFindAll(modelName,json);var url=this.buildURL(modelName);this.stubEndpointForHttpRequest(url,responseJson)},handleFindMany:function(){Ember.deprecate("DEPRECATION Warning: use handleFindAll instead");this.handleFindAll.apply(this,arguments)},handleFind:function(){var args=Array.prototype.slice.call(arguments);Ember.assert("To handleFindOne pass in a model instance or a type and model options",args.length>0);var record,modelName;if(args[0]instanceof DS.Model){record=args[0];modelName=record.constructor.typeKey}else{record=FactoryGuy.make.apply(FactoryGuy,arguments);var name=arguments[0];modelName=FactoryGuy.lookupModelForFixtureName(name)}var json=record.toJSON({includeId:true});var responseJson=this.mapFind(modelName,json);var url=this.buildURL(modelName,record.id);this.stubEndpointForHttpRequest(url,responseJson)},handleFindOne:function(){this.handleFind.apply(this,arguments)},handleFindQuery:function(modelName,searchParams,records){Ember.assert("The second argument of searchParams must be an array",Em.typeOf(searchParams)=="array");if(records){Ember.assert("The third argument ( records ) must be an array - found type:"+Em.typeOf(records),Em.typeOf(records)=="array")}else{records=[]}var json=records.map(function(record){return record.toJSON({includeId:true})});var responseJson=this.mapFindAll(modelName,json);var url=this.buildURL(modelName);this.stubEndpointForHttpRequest(url,responseJson,{urlParams:searchParams})},handleCreate:function(modelName,options){var url=this.buildURL(modelName);var store=this.getStore();var opts=options===undefined?{}:options;return new MockCreateRequest(url,store,modelName,opts)},handleUpdate:function(){var args=Array.prototype.slice.call(arguments);Ember.assert("To handleUpdate pass in a model instance or a type and an id",args.length>0);var succeed=true;if(typeof args[args.length-1]=="boolean"){args.pop();succeed=false}Ember.assert("To handleUpdate pass in a model instance or a type and an id",args.length>0);var type,id;if(args[0]instanceof DS.Model){var model=args[0];type=model.constructor.typeKey;id=model.id}else if(typeof args[0]=="string"&&typeof parseInt(args[1])=="number"){type=args[0];id=args[1]}Ember.assert("To handleUpdate pass in a model instance or a type and an id",type&&id);this.stubEndpointForHttpRequest(this.buildURL(type,id),{},{type:"PUT",status:succeed?200:500})},handleDelete:function(type,id,succeed){succeed=succeed===undefined?true:succeed;this.stubEndpointForHttpRequest(this.buildURL(type,id),{},{type:"DELETE",status:succeed?200:500})},teardown:function(){FactoryGuy.resetModels(this.getStore());$.mockjax.clear()}});if(FactoryGuy!==undefined){FactoryGuy.testMixin=FactoryGuyTestMixin}
1
+ var Sequence=function(fn){var index=1;this.next=function(){return fn.call(this,index++)};this.reset=function(){index=1}};var MissingSequenceError=function(message){this.toString=function(){return message}};if(FactoryGuy!==undefined){FactoryGuy.sequence=Sequence;FactoryGuy.missingSequenceError=MissingSequenceError}var ModelDefinition=function(model,config){var sequences={};var traits={};var defaultAttributes={};var namedModels={};var modelId=1;var sequenceName=null;this.model=model;this.matchesName=function(name){return model==name||namedModels[name]};this.nextId=function(){return modelId++};this.generate=function(name,sequenceFn){if(sequenceFn){if(!sequences[name]){sequences[name]=new Sequence(sequenceFn)}}var sequence=sequences[name];if(!sequence){throw new MissingSequenceError("Can not find that sequence named ["+sequenceName+"] in '"+model+"' definition")}return sequence.next()};this.build=function(name,opts,traitArgs){var traitsObj={};traitArgs.forEach(function(trait){$.extend(traitsObj,traits[trait])});var modelAttributes=namedModels[name]||{};var fixture=$.extend({},defaultAttributes,modelAttributes,traitsObj,opts);for(var attribute in fixture){if(Ember.typeOf(fixture[attribute])=="function"){fixture[attribute]=fixture[attribute].call(this,fixture)}else if(Ember.typeOf(fixture[attribute])=="object"){if(FactoryGuy.getStore()){if(FactoryGuy.isAttributeRelationship(this.model,attribute)){fixture[attribute]=FactoryGuy.build(attribute,fixture[attribute])}}else{fixture[attribute]=FactoryGuy.build(attribute,fixture[attribute])}}}if(!fixture.id){fixture.id=this.nextId()}return fixture};this.buildList=function(name,number,traits,opts){var arr=[];for(var i=0;i<number;i++){arr.push(this.build(name,opts,traits))}return arr};this.reset=function(){modelId=1;for(var name in sequences){sequences[name].reset()}};var parseDefault=function(object){if(!object){return}defaultAttributes=object};var parseTraits=function(object){if(!object){return}traits=object};var parseSequences=function(object){if(!object){return}for(sequenceName in object){var sequenceFn=object[sequenceName];if(Ember.typeOf(sequenceFn)!="function"){throw new Error("Problem with ["+sequenceName+"] sequence definition. Sequences must be functions")}object[sequenceName]=new Sequence(sequenceFn)}sequences=object};var parseConfig=function(config){parseSequences(config.sequences);delete config.sequences;parseTraits(config.traits);delete config.traits;parseDefault(config.default);delete config.default;namedModels=config};parseConfig(config)};if(FactoryGuy!==undefined){FactoryGuy.modelDefiniton=ModelDefinition}var FactoryGuy={modelDefinitions:{},define:function(model,config){if(this.modelDefinitions[model]){this.modelDefinitions[model].merge(config)}else{this.modelDefinitions[model]=new ModelDefinition(model,config)}},setStore:function(store){Ember.assert("FactoryGuy#setStore needs a valid store instance.You passed in ["+store+"]",store instanceof DS.Store);this.store=store},getStore:function(){return this.store},isAttributeRelationship:function(typeName,attribute){if(!this.store){Ember.debug("FactoryGuy does not have the application's store. Use FactoryGuy.setStore(store) before making any fixtures");return true}var model=this.store.modelFor(typeName);return!!model.typeForRelationship(attribute)},generate:function(nameOrFunction){var sortaRandomName=Math.floor((1+Math.random())*65536).toString(16)+Date.now();return function(){if(Em.typeOf(nameOrFunction)=="function"){return this.generate(sortaRandomName,nameOrFunction)}else{return this.generate(nameOrFunction)}}},belongsTo:function(fixtureName,opts){return function(){return FactoryGuy.build(fixtureName,opts)}},association:function(fixtureName,opts){Ember.deprecate("DEPRECATION Warning: use FactoryGuy.belongsTo instead");return this.belongsTo(fixtureName,opts)},hasMany:function(fixtureName,number,opts){return function(){return FactoryGuy.buildList(fixtureName,number,opts)}},lookupModelForFixtureName:function(name){var definition=this.lookupDefinitionForFixtureName(name);if(definition){return definition.model}},lookupDefinitionForFixtureName:function(name){for(var model in this.modelDefinitions){var definition=this.modelDefinitions[model];if(definition.matchesName(name)){return definition}}},build:function(){var args=Array.prototype.slice.call(arguments);var opts={};var name=args.shift();if(!name){throw new Error("Build needs a factory name to build")}if(Ember.typeOf(args[args.length-1])=="object"){opts=args.pop()}var traits=args;var definition=this.lookupDefinitionForFixtureName(name);if(!definition){throw new Error("Can't find that factory named ["+name+"]")}return definition.build(name,opts,traits)},buildList:function(){var args=Array.prototype.slice.call(arguments);var name=args.shift();var number=args.shift();if(!name||!number){throw new Error("buildList needs a name and a number ( at least ) to build with")}var opts={};if(Ember.typeOf(args[args.length-1])=="object"){opts=args.pop()}var traits=args;var definition=this.lookupDefinitionForFixtureName(name);if(!definition){throw new Error("Can't find that factory named ["+name+"]")}return definition.buildList(name,number,traits,opts)},make:function(){var store=this.store;Ember.assert("FactoryGuy does not have the application's store. Use FactoryGuy.setStore(store) before making any fixtures",store);var fixture=this.build.apply(this,arguments);var name=arguments[0];var modelName=this.lookupModelForFixtureName(name);var modelType=store.modelFor(modelName);if(store.usingFixtureAdapter()){store.setAssociationsForFixtureAdapter(modelType,modelName,fixture);fixture=FactoryGuy.pushFixture(modelType,fixture);store.loadModelForFixtureAdapter(modelType,fixture);return fixture}else{return store.makeModel(modelType,fixture)}},makeList:function(){Ember.assert("FactoryGuy does not have the application's store. Use FactoryGuy.setStore(store) before making any fixtures",this.store);var arr=[];var args=Array.prototype.slice.call(arguments);Ember.assert("makeList needs at least 2 arguments, a name and a number",args.length>=2);var number=args.splice(1,1)[0];Ember.assert("Second argument to makeList should be a number (of fixtures to make.)",typeof number=="number");for(var i=0;i<number;i++){arr.push(this.make.apply(this,args))}return arr},resetModels:function(store){for(var model in this.modelDefinitions){var definition=this.modelDefinitions[model];definition.reset();try{var modelType=store.modelFor(definition.model);if(store.usingFixtureAdapter()){modelType.FIXTURES=[]}store.unloadAll(modelType)}catch(e){console.log("resetModels",e)}}},pushFixture:function(modelClass,fixture){var index;if(!modelClass.FIXTURES){modelClass.FIXTURES=[]}index=this.indexOfFixture(modelClass.FIXTURES,fixture);if(index>-1){modelClass.FIXTURES.splice(index,1)}modelClass.FIXTURES.push(fixture);return fixture},indexOfFixture:function(fixtures,fixture){var index=-1,id=fixture.id+"";Ember.A(fixtures).find(function(r,i){if(""+Ember.get(r,"id")===id){index=i;return true}else{return false}});return index},clear:function(opts){if(!opts){this.modelDefinitions={}}}};var MockCreateRequest=function(url,store,modelName,options){var succeed=options.succeed===undefined?true:options.succeed;var matchArgs=options.match;var returnArgs=options.returns;var responseJson={};var expectedRequest={};var modelType=store.modelFor(modelName);this.calculate=function(){if(matchArgs){var tmpRecord=store.createRecord(modelName,matchArgs);expectedRequest=tmpRecord.serialize(matchArgs);tmpRecord.deleteRecord()}if(succeed){var definition=FactoryGuy.modelDefinitions[modelName];if(responseJson[modelName]){responseJson[modelName]=$.extend({id:responseJson[modelName].id},matchArgs,returnArgs)}else{responseJson[modelName]=$.extend({id:definition.nextId()},matchArgs,returnArgs)}Ember.get(modelType,"relationshipsByName").forEach(function(relationship){if(relationship.kind=="belongsTo"){delete responseJson[modelName][relationship.key]}})}};this.match=function(matches){matchArgs=matches;this.calculate();return this};this.andReturn=function(returns){returnArgs=returns;this.calculate();return this};this.andFail=function(){succeed=false;return this};this.handler=function(settings){if(settings.url!=url||settings.type!="POST"){return false}if(matchArgs){var requestData=JSON.parse(settings.data)[modelName];for(var attribute in expectedRequest){if(expectedRequest[attribute]&&requestData[attribute]!=expectedRequest[attribute]){return false}}}var responseStatus=succeed?200:500;return{responseText:responseJson,status:responseStatus}};this.calculate();$.mockjax(this.handler)};var MockUpdateRequest=function(url,model,mapFind,options){var status=options.status||200;var succeed=true;var response=null;if("succeed"in options){succeed=options.succeed}if("response"in options){response=options.response}this.andSucceed=function(options){succeed=true;return this};this.andFail=function(options){succeed=false;status=options.status||500;if("response"in options){response=options.response}return this};this.handler=function(settings){if(!succeed){this.status=status;if(response!==null){this.responseText=response}}else{var json=model.toJSON({includeId:true});this.responseText=mapFind(model.constructor.typeKey,json);this.status=200}};var requestConfig={url:url,dataType:"json",type:"PUT",response:this.handler};$.mockjax(requestConfig)};(function(){DS.Store.reopen({usingFixtureAdapter:function(){var adapter=this.adapterFor("application");return adapter instanceof DS.FixtureAdapter},makeFixture:function(){Ember.deprecate("DEPRECATION Warning: use FactoryGuy.make instead");FactoryGuy.make.call(FactoryGuy,arguments)},makeList:function(){Ember.deprecate("DEPRECATION Warning: use FactoryGuy.makeList instead");FactoryGuy.makeList.call(FactoryGuy,arguments)},makeModel:function(modelType,fixture){var store=this,modelName=store.modelFor(modelType).typeKey,model;Em.run(function(){store.findEmbeddedAssociationsForRESTAdapter(modelType,fixture);if(fixture.type){modelName=fixture.type.underscore();modelType=store.modelFor(modelName)}model=store.push(modelName,fixture);store.setAssociationsForRESTAdapter(modelType,modelName,model)});return model},setAssociationsForFixtureAdapter:function(modelType,modelName,fixture){var self=this;var adapter=this.adapterFor("application");Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){var hasManyRelation,belongsToRecord;if(relationship.kind=="hasMany"){hasManyRelation=fixture[relationship.key];if(hasManyRelation){$.each(fixture[relationship.key],function(index,object){var id=object;if(Ember.typeOf(object)=="object"){FactoryGuy.pushFixture(relationship.type,object);id=object.id;hasManyRelation[index]=id}var hasManyfixtures=adapter.fixturesForType(relationship.type);var hasManyFixture=adapter.findFixtureById(hasManyfixtures,id);hasManyFixture[modelName]=fixture.id;self.loadModelForFixtureAdapter(relationship.type,hasManyFixture)})}}if(relationship.kind=="belongsTo"){belongsToRecord=fixture[relationship.key];if(belongsToRecord){if(typeof belongsToRecord=="object"){FactoryGuy.pushFixture(relationship.type,belongsToRecord);fixture[relationship.key]=belongsToRecord.id}var hasManyName=self.findHasManyRelationshipNameForFixtureAdapter(relationship.type,relationship.parentType);var belongsToFixtures=adapter.fixturesForType(relationship.type);var belongsTofixture=adapter.findFixtureById(belongsToFixtures,fixture[relationship.key]);if(!belongsTofixture[hasManyName]){belongsTofixture[hasManyName]=[]}belongsTofixture[hasManyName].push(fixture.id);self.loadModelForFixtureAdapter(relationship.type,belongsTofixture)}}})},loadModelForFixtureAdapter:function(modelType,fixture){var storeModel=this.getById(modelType,fixture.id),that=this;if(!Ember.isPresent(storeModel)||storeModel.get("isEmpty")){Ember.run(function(){var dup=Ember.copy(fixture,true);that.push(modelType,fixture);Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){if(fixture[relationship.key]){fixture[relationship.key]=dup[relationship.key]}})})}},findEmbeddedAssociationsForRESTAdapter:function(modelType,fixture){var store=this;Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind=="belongsTo"){var belongsToRecord=fixture[relationship.key];if(Ember.typeOf(belongsToRecord)=="object"){store.findEmbeddedAssociationsForRESTAdapter(relationship.type,belongsToRecord);belongsToRecord=store.push(relationship.type,belongsToRecord);fixture[relationship.key]=belongsToRecord}}if(relationship.kind=="hasMany"){var hasManyRecords=fixture[relationship.key];if(Ember.typeOf(hasManyRecords)=="array"){if(Ember.typeOf(hasManyRecords[0])=="object"){var records=Em.A();hasManyRecords.map(function(object){store.findEmbeddedAssociationsForRESTAdapter(relationship.type,object);var record=store.push(relationship.type,object);records.push(record);return record});fixture[relationship.key]=records}}}})},setAssociationsForRESTAdapter:function(modelType,modelName,model){var self=this;Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind=="hasMany"){var children=model.get(name)||[];children.forEach(function(child){var belongsToName=self.findRelationshipName("belongsTo",child.constructor,model);if(belongsToName){child.set(belongsToName,model)}})}})},findRelationshipName:function(kind,belongToModelType,childModel){var relationshipName;Ember.get(belongToModelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind==kind&&childModel instanceof relationship.type){relationshipName=relationship.key}});return relationshipName},findHasManyRelationshipNameForFixtureAdapter:function(belongToModelType,childModelType){var relationshipName;Ember.get(belongToModelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind=="hasMany"&&childModelType==relationship.type){relationshipName=relationship.key}});return relationshipName},pushPayload:function(type,payload){var typeName,model;if(this.usingFixtureAdapter()){if(Ember.typeOf(type)==="string"&&Ember.isPresent(payload)&&Ember.isPresent(payload.id)){model=this.modelFor(type);FactoryGuy.pushFixture(model,payload);this.push(model,Ember.copy(payload,true))}else if(Ember.typeOf(type)==="object"||Ember.typeOf(payload)==="object"){if(Ember.isBlank(payload)){payload=type}for(var prop in payload){typeName=Ember.String.camelize(Ember.String.singularize(prop));model=this.modelFor(typeName);this.pushMany(model,Ember.makeArray(Ember.copy(payload[prop],true)));Ember.ArrayPolyfills.forEach.call(Ember.makeArray(payload[prop]),function(hash){FactoryGuy.pushFixture(model,hash)},this)}}else{throw new Ember.Error("Assertion Failed: You cannot use `store#pushPayload` with this method signature pushPayload("+type+","+payload+")")}}else{this._super(type,payload)}}})})();var FactoryGuyTestMixin=Em.Mixin.create({setup:function(app){this.set("container",app.__container__);FactoryGuy.setStore(this.getStore());return this},useFixtureAdapter:function(app){app.ApplicationAdapter=DS.FixtureAdapter;this.getStore().adapterFor("application").simulateRemoteResponse=false},usingActiveModelSerializer:function(type){var store=this.getStore();var modelType=store.modelFor(type);var serializer=store.serializerFor(modelType.typeKey);return serializer instanceof DS.ActiveModelSerializer},find:function(type,id){return this.getStore().find(type,id)},make:function(){return FactoryGuy.make.apply(FactoryGuy,arguments)},getStore:function(){return this.get("container").lookup("store:main")},stubEndpointForHttpRequest:function(url,json,options){options=options||{};var request={url:url,dataType:"json",responseText:json,type:options.type||"GET",status:options.status||200};if(options.urlParams){request.urlParams=options.urlParams}if(options.data){request.data=options.data}$.mockjax(request)},buildURL:function(typeName,id){var type=this.getStore().modelFor(typeName);return this.getStore().adapterFor(type).buildURL(type.typeKey,id)},mapFindAll:function(modelName,json){var responseJson={};responseJson[modelName.pluralize()]=json;return responseJson},mapFind:function(modelName,json){var responseJson={};responseJson[modelName.pluralize()]=json;return responseJson},handleFindAll:function(){var records=FactoryGuy.makeList.apply(FactoryGuy,arguments);var name=arguments[0];var modelName=FactoryGuy.lookupModelForFixtureName(name);var json=records.map(function(record){return record.toJSON({includeId:true})});var responseJson=this.mapFindAll(modelName,json);var url=this.buildURL(modelName);this.stubEndpointForHttpRequest(url,responseJson)},handleFindMany:function(){Ember.deprecate("DEPRECATION Warning: use handleFindAll instead");this.handleFindAll.apply(this,arguments)},handleFind:function(){var args=Array.prototype.slice.call(arguments);Ember.assert("To handleFindOne pass in a model instance or a type and model options",args.length>0);var record,modelName;if(args[0]instanceof DS.Model){record=args[0];modelName=record.constructor.typeKey}else{record=FactoryGuy.make.apply(FactoryGuy,arguments);var name=arguments[0];modelName=FactoryGuy.lookupModelForFixtureName(name)}var json=record.toJSON({includeId:true});var responseJson=this.mapFind(modelName,json);var url=this.buildURL(modelName,record.id);this.stubEndpointForHttpRequest(url,responseJson)},handleFindOne:function(){this.handleFind.apply(this,arguments)},handleFindQuery:function(modelName,searchParams,records){Ember.assert("The second argument of searchParams must be an array",Em.typeOf(searchParams)=="array");if(records){Ember.assert("The third argument ( records ) must be an array - found type:"+Em.typeOf(records),Em.typeOf(records)=="array")}else{records=[]}var json=records.map(function(record){return record.toJSON({includeId:true})});var responseJson=this.mapFindAll(modelName,json);var url=this.buildURL(modelName);this.stubEndpointForHttpRequest(url,responseJson,{urlParams:searchParams})},handleCreate:function(modelName,options){var url=this.buildURL(modelName);var store=this.getStore();var opts=options===undefined?{}:options;return new MockCreateRequest(url,store,modelName,opts)},handleUpdate:function(){var args=Array.prototype.slice.call(arguments);Ember.assert("To handleUpdate pass in a model instance or a type and an id",args.length>0);var options={};if(args.length>1&&typeof args[args.length-1]==="object"){options=args.pop()}var model,type,id;var store=this.getStore();if(args[0]instanceof DS.Model){model=args[0];id=model.id;type=model.constructor.typeKey}else if(typeof args[0]=="string"&&typeof parseInt(args[1])=="number"){type=args[0];id=args[1];model=store.getById(type,id)}Ember.assert("To handleUpdate pass in a model instance or a type and an id",type&&id);var url=this.buildURL(type,id);return new MockUpdateRequest(url,model,this.mapFind,options)},handleDelete:function(type,id,succeed){succeed=succeed===undefined?true:succeed;this.stubEndpointForHttpRequest(this.buildURL(type,id),{},{type:"DELETE",status:succeed?200:500})},teardown:function(){FactoryGuy.resetModels(this.getStore());$.mockjax.clear()}});if(FactoryGuy!==undefined){FactoryGuy.testMixin=FactoryGuyTestMixin}
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ember-data-factory-guy",
3
- "version": "0.9.9",
3
+ "version": "0.9.10",
4
4
  "authors": [
5
5
  "Daniel Sudol <dansudol@yahoo.com>",
6
6
  "Opak Alex <opak.alexandr@gmail.com>"
@@ -268,34 +268,35 @@ var FactoryGuyTestMixin = Em.Mixin.create({
268
268
  Handling ajax PUT ( update record ) for a model type. You can mock
269
269
  failed update by passing in success argument as false.
270
270
 
271
- @param {String} type model type like 'user' for User model
271
+ @param {String} type model type like 'user' for User model, or a model instance
272
272
  @param {String} id id of record to update
273
- @param {Boolean} succeed optional flag to indicate if the request
274
- should succeed ( default is true )
273
+ @param {Object} options options object
275
274
  */
276
275
  handleUpdate: function () {
277
- var args = Array.prototype.slice.call(arguments)
276
+ var args = Array.prototype.slice.call(arguments);
278
277
  Ember.assert("To handleUpdate pass in a model instance or a type and an id", args.length>0)
279
- var succeed = true;
280
- if (typeof args[args.length-1] == 'boolean') {
281
- args.pop()
282
- succeed = false;
278
+
279
+ var options = {};
280
+ if (args.length > 1 && typeof args[args.length - 1] === 'object') {
281
+ options = args.pop();
283
282
  }
284
- Ember.assert("To handleUpdate pass in a model instance or a type and an id",args.length>0)
285
- var type, id;
283
+
284
+ var model, type, id;
285
+ var store = this.getStore();
286
+
286
287
  if (args[0] instanceof DS.Model) {
287
- var model = args[0];
288
- type = model.constructor.typeKey;
288
+ model = args[0];
289
289
  id = model.id;
290
+ type = model.constructor.typeKey;
290
291
  } else if (typeof args[0] == "string" && typeof parseInt(args[1]) == "number") {
291
292
  type = args[0];
292
293
  id = args[1];
294
+ model = store.getById(type, id)
293
295
  }
294
- Ember.assert("To handleUpdate pass in a model instance or a type and an id",type && id)
295
- this.stubEndpointForHttpRequest(this.buildURL(type, id), {}, {
296
- type: 'PUT',
297
- status: succeed ? 200 : 500
298
- });
296
+ Ember.assert("To handleUpdate pass in a model instance or a type and an id",type && id);
297
+
298
+ var url = this.buildURL(type, id);
299
+ return new MockUpdateRequest(url, model, this.mapFind, options);
299
300
  },
300
301
  /**
301
302
  Handling ajax DELETE ( delete record ) for a model type. You can mock
@@ -0,0 +1,49 @@
1
+ var MockUpdateRequest = function(url, model, mapFind, options) {
2
+ var status = options.status || 200;
3
+ var succeed = true;
4
+ var response = null;
5
+
6
+ if ('succeed' in options) {
7
+ succeed = options.succeed;
8
+ }
9
+
10
+ if ('response' in options) {
11
+ response = options.response;
12
+ }
13
+
14
+ this.andSucceed = function(options) {
15
+ succeed = true;
16
+ return this;
17
+ };
18
+
19
+ this.andFail = function(options) {
20
+ succeed = false;
21
+ status = options.status || 500;
22
+ if ('response' in options) {
23
+ response = options.response;
24
+ }
25
+ return this;
26
+ };
27
+
28
+ this.handler = function(settings) {
29
+ if (!succeed) {
30
+ this.status = status;
31
+ if (response !== null) {
32
+ this.responseText = response;
33
+ }
34
+ } else {
35
+ var json = model.toJSON({includeId: true});
36
+ this.responseText = mapFind(model.constructor.typeKey, json);
37
+ this.status = 200;
38
+ }
39
+ };
40
+
41
+ var requestConfig = {
42
+ url: url,
43
+ dataType: 'json',
44
+ type: 'PUT',
45
+ response: this.handler
46
+ };
47
+
48
+ $.mockjax(requestConfig);
49
+ };
@@ -28,7 +28,7 @@ module('FactoryGuyTestMixin (using mockjax) with DS.RESTAdapter', {
28
28
  setup: function () {
29
29
  testHelper = TestHelper.setup(DS.RESTAdapter);
30
30
  store = testHelper.getStore();
31
- make = function() {return FactoryGuy.make.apply(FactoryGuy,arguments)}
31
+ make = function() {return FactoryGuy.make.apply(FactoryGuy,arguments);}
32
32
  },
33
33
  teardown: function () {
34
34
  Em.run(function() {
@@ -623,17 +623,16 @@ asyncTest("#handleFindAll with traits and fixture options", function () {
623
623
  test("#handleUpdate with incorrect parameters", function(assert) {
624
624
  assert.throws(function(){testHelper.handleUpdate()},"missing everything");
625
625
  assert.throws(function(){testHelper.handleUpdate('profile')},"missing id");
626
- assert.throws(function(){testHelper.handleUpdate('profile', false)},"missing id");
627
- assert.throws(function(){testHelper.handleUpdate('profile', true)},"missing id");
626
+ assert.throws(function(){testHelper.handleUpdate('profile', {})},"missing id");
628
627
  });
629
628
 
630
- asyncTest("#handleUpdate the with modelType and id", function() {
631
- Em.run(function() {
629
+ asyncTest("#handleUpdate the with modelType and id", function () {
630
+ Em.run(function () {
632
631
  var profile = make('profile');
633
632
  testHelper.handleUpdate('profile', profile.id);
634
633
 
635
- profile.set('description','new desc');
636
- profile.save().then(function(profile) {
634
+ profile.set('description', 'new desc');
635
+ profile.save().then(function (profile) {
637
636
  ok(profile.get('description') == 'new desc');
638
637
  start();
639
638
  });
@@ -641,52 +640,170 @@ asyncTest("#handleUpdate the with modelType and id", function() {
641
640
  });
642
641
 
643
642
 
644
- asyncTest("#handleUpdate the with model", function() {
645
- Em.run(function() {
643
+ asyncTest("#handleUpdate the with model", function () {
644
+ Em.run(function () {
646
645
  var profile = make('profile');
647
- testHelper.handleUpdate(profile, true, {e:1});
646
+ testHelper.handleUpdate(profile);
648
647
 
649
- profile.set('description','new desc');
650
- profile.save().then(function(profile) {
648
+ profile.set('description', 'new desc');
649
+ profile.save().then(function (profile) {
651
650
  ok(profile.get('description') == 'new desc');
652
651
  start();
653
652
  });
654
653
  });
655
654
  });
656
655
 
657
- asyncTest("#handleUpdate the with modelType and id that fails", function() {
658
- Em.run(function() {
656
+ asyncTest("#handleUpdate the with modelType and id that fails", function () {
657
+ Em.run(function () {
659
658
  var profile = make('profile');
660
- testHelper.handleUpdate('profile', profile.id, false);
661
659
 
662
- profile.set('description','new desc');
660
+ testHelper.handleUpdate('profile', profile.id, {succeed: false, status: 500});
661
+
662
+ profile.set('description', 'new desc');
663
663
  profile.save().then(
664
- function() {},
665
- function() {
666
- ok(true)
664
+ function () {
665
+ },
666
+ function () {
667
+ ok(true);
667
668
  start();
668
669
  }
669
- )
670
+ );
670
671
  });
671
672
  });
672
673
 
673
- asyncTest("#handleUpdate with model that fails", function() {
674
- Em.run(function() {
674
+ asyncTest("#handleUpdate with model that fails", function () {
675
+ Em.run(function () {
675
676
  var profile = make('profile');
676
677
 
677
- testHelper.handleUpdate(profile, false);
678
+ testHelper.handleUpdate(profile, {succeed: false, status: 500});
678
679
 
679
- profile.set('description','new desc');
680
+ profile.set('description', 'new desc');
680
681
  profile.save().then(
681
- function() {},
682
- function() {
683
- ok(true)
684
- start();
685
- }
686
- )
682
+ function () {
683
+ },
684
+ function () {
685
+ ok(true);
686
+ start();
687
+ }
688
+ );
687
689
  });
688
690
  });
689
691
 
692
+ asyncTest("#handleUpdate with model that fails with custom response", function () {
693
+ Em.run(function () {
694
+ var profile = make('profile');
695
+
696
+ testHelper.handleUpdate(profile, {succeed: false, status: 400, response: "{error: 'invalid data'}"});
697
+
698
+ profile.set('description', 'new desc');
699
+ profile.save().then(
700
+ function () {
701
+ },
702
+ function (reason) {
703
+ ok(true);
704
+ equal(reason.status, 400);
705
+ equal(reason.responseText, "{error: 'invalid data'}");
706
+ start();
707
+ }
708
+ );
709
+ });
710
+ });
711
+
712
+ asyncTest("#handleUpdate the with modelType and id that fails chained", function () {
713
+ Em.run(function () {
714
+ var profile = make('profile');
715
+
716
+ testHelper.handleUpdate('profile', profile.id).andFail({
717
+ status: 500
718
+ });
719
+
720
+ profile.set('description', 'new desc');
721
+ profile.save().then(
722
+ function () {
723
+ },
724
+ function (reason) {
725
+ ok(true);
726
+ equal(reason.status, 500);
727
+ start();
728
+ }
729
+ );
730
+ });
731
+ });
732
+
733
+ asyncTest("#handleUpdate with model that fails chained", function () {
734
+ Em.run(function () {
735
+ var profile = make('profile');
736
+
737
+ testHelper.handleUpdate(profile).andFail({
738
+ status: 500
739
+ });
740
+
741
+ profile.set('description', 'new desc');
742
+ profile.save().then(
743
+ function () {
744
+ },
745
+ function (reason) {
746
+ ok(true);
747
+ equal(reason.status, 500);
748
+ start();
749
+ }
750
+ );
751
+ });
752
+ });
753
+
754
+ asyncTest("#handleUpdate with model that fail with custom response", function () {
755
+ Em.run(function () {
756
+ var profile = make('profile');
757
+
758
+ testHelper.handleUpdate(profile).andFail({
759
+ status: 400,
760
+ response: "{error: 'invalid data'}"
761
+ });
762
+
763
+ profile.set('description', 'new desc');
764
+ profile.save().then(
765
+ function () {
766
+ },
767
+ function (reason) {
768
+ ok(true);
769
+ equal(reason.responseText, "{error: 'invalid data'}");
770
+ start();
771
+ }
772
+ );
773
+ });
774
+ });
775
+
776
+ asyncTest("#handleUpdate with model that fail and then succeeds", function () {
777
+ Em.run(function () {
778
+ var profile = make('profile');
779
+
780
+ var updateMock = testHelper.handleUpdate(profile).andFail({
781
+ status: 400,
782
+ response: "{error: 'invalid data'}"
783
+ });
784
+
785
+ profile.set('description', 'new desc');
786
+ profile.save().then(
787
+ function () {
788
+ },
789
+ function (reason) {
790
+ equal(reason.responseText, "{error: 'invalid data'}", "Could not save model.");
791
+ }
792
+ ).then(function () {
793
+ updateMock.andSucceed();
794
+
795
+ ok(!profile.get('valid'), "Profile is invalid.");
796
+
797
+ profile.save().then(
798
+ function () {
799
+ ok(!profile.get('saving'), "Saved model");
800
+ ok(profile.get('description') == 'new desc', "Description was updated.");
801
+ start();
802
+ }
803
+ );
804
+ });
805
+ });
806
+ });
690
807
 
691
808
  /////// handleDelete //////////
692
809
 
@@ -644,6 +644,55 @@ var MockCreateRequest = function(url, store, modelName, options) {
644
644
  $.mockjax(this.handler);
645
645
  };
646
646
 
647
+ var MockUpdateRequest = function(url, model, mapFind, options) {
648
+ var status = options.status || 200;
649
+ var succeed = true;
650
+ var response = null;
651
+
652
+ if ('succeed' in options) {
653
+ succeed = options.succeed;
654
+ }
655
+
656
+ if ('response' in options) {
657
+ response = options.response;
658
+ }
659
+
660
+ this.andSucceed = function(options) {
661
+ succeed = true;
662
+ return this;
663
+ };
664
+
665
+ this.andFail = function(options) {
666
+ succeed = false;
667
+ status = options.status || 500;
668
+ if ('response' in options) {
669
+ response = options.response;
670
+ }
671
+ return this;
672
+ };
673
+
674
+ this.handler = function(settings) {
675
+ if (!succeed) {
676
+ this.status = status;
677
+ if (response !== null) {
678
+ this.responseText = response;
679
+ }
680
+ } else {
681
+ var json = model.toJSON({includeId: true});
682
+ this.responseText = mapFind(model.constructor.typeKey, json);
683
+ this.status = 200;
684
+ }
685
+ };
686
+
687
+ var requestConfig = {
688
+ url: url,
689
+ dataType: 'json',
690
+ type: 'PUT',
691
+ response: this.handler
692
+ };
693
+
694
+ $.mockjax(requestConfig);
695
+ };
647
696
  (function () {
648
697
  DS.Store.reopen({
649
698
  /**
@@ -1191,34 +1240,35 @@ var FactoryGuyTestMixin = Em.Mixin.create({
1191
1240
  Handling ajax PUT ( update record ) for a model type. You can mock
1192
1241
  failed update by passing in success argument as false.
1193
1242
 
1194
- @param {String} type model type like 'user' for User model
1243
+ @param {String} type model type like 'user' for User model, or a model instance
1195
1244
  @param {String} id id of record to update
1196
- @param {Boolean} succeed optional flag to indicate if the request
1197
- should succeed ( default is true )
1245
+ @param {Object} options options object
1198
1246
  */
1199
1247
  handleUpdate: function () {
1200
- var args = Array.prototype.slice.call(arguments)
1248
+ var args = Array.prototype.slice.call(arguments);
1201
1249
  Ember.assert("To handleUpdate pass in a model instance or a type and an id", args.length>0)
1202
- var succeed = true;
1203
- if (typeof args[args.length-1] == 'boolean') {
1204
- args.pop()
1205
- succeed = false;
1250
+
1251
+ var options = {};
1252
+ if (args.length > 1 && typeof args[args.length - 1] === 'object') {
1253
+ options = args.pop();
1206
1254
  }
1207
- Ember.assert("To handleUpdate pass in a model instance or a type and an id",args.length>0)
1208
- var type, id;
1255
+
1256
+ var model, type, id;
1257
+ var store = this.getStore();
1258
+
1209
1259
  if (args[0] instanceof DS.Model) {
1210
- var model = args[0];
1211
- type = model.constructor.typeKey;
1260
+ model = args[0];
1212
1261
  id = model.id;
1262
+ type = model.constructor.typeKey;
1213
1263
  } else if (typeof args[0] == "string" && typeof parseInt(args[1]) == "number") {
1214
1264
  type = args[0];
1215
1265
  id = args[1];
1266
+ model = store.getById(type, id)
1216
1267
  }
1217
- Ember.assert("To handleUpdate pass in a model instance or a type and an id",type && id)
1218
- this.stubEndpointForHttpRequest(this.buildURL(type, id), {}, {
1219
- type: 'PUT',
1220
- status: succeed ? 200 : 500
1221
- });
1268
+ Ember.assert("To handleUpdate pass in a model instance or a type and an id",type && id);
1269
+
1270
+ var url = this.buildURL(type, id);
1271
+ return new MockUpdateRequest(url, model, this.mapFind, options);
1222
1272
  },
1223
1273
  /**
1224
1274
  Handling ajax DELETE ( delete record ) for a model type. You can mock
@@ -1361,12 +1411,10 @@ if (FactoryGuy !== undefined) {
1361
1411
  return null;
1362
1412
  }
1363
1413
  }
1414
+
1364
1415
  // Inspect the data submitted in the request (either POST body or GET query string)
1365
1416
  if ( handler.data ) {
1366
- // console.log('request.data', requestSettings.data )
1367
- // console.log('handler.data', handler.data )
1368
- // console.log('data equal', isMockDataEqual(handler.data, requestSettings.data) )
1369
- if ( ! requestSettings.data || !isMockDataEqual(handler.data, requestSettings.data) ) {
1417
+ if ( ! requestSettings.data || !isMockDataEqual(handler.data, requestSettings.data) ) {
1370
1418
  // They're not identical, do not mock this request
1371
1419
  return null;
1372
1420
  }
@@ -1377,6 +1425,7 @@ if (FactoryGuy !== undefined) {
1377
1425
  // The request type doesn't match (GET vs. POST)
1378
1426
  return null;
1379
1427
  }
1428
+
1380
1429
  return handler;
1381
1430
  }
1382
1431
 
@@ -1740,7 +1789,6 @@ if (FactoryGuy !== undefined) {
1740
1789
  }
1741
1790
 
1742
1791
  mockHandler = getMockForRequest( mockHandlers[k], requestSettings );
1743
-
1744
1792
  if(!mockHandler) {
1745
1793
  // No valid mock found for this request
1746
1794
  continue;
@@ -1792,7 +1840,7 @@ if (FactoryGuy !== undefined) {
1792
1840
  }
1793
1841
 
1794
1842
  copyUrlParameters(mockHandler, origSettings);
1795
- //console.log('here copyUrlParameters', 'mockHandler=>',mockHandler, 'requestSettings=>',requestSettings, 'origSettings=>',origSettings)
1843
+
1796
1844
  (function(mockHandler, requestSettings, origSettings, origHandler) {
1797
1845
 
1798
1846
  mockRequest = _ajax.call($, $.extend(true, {}, origSettings, {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ember-data-factory-guy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.9
4
+ version: 0.9.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Sudol
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-02-20 00:00:00.000000000 Z
12
+ date: 2015-02-23 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Easily create Fixtures for Ember Data
15
15
  email:
@@ -37,6 +37,7 @@ files:
37
37
  - src/factory_guy_test_mixin.js
38
38
  - src/has_many.js
39
39
  - src/mock_create_request.js
40
+ - src/mock_update_request.js
40
41
  - src/model_definition.js
41
42
  - src/prologue.js
42
43
  - src/sequence.js