From 3c97257f523cbbc0549c93374e67edba3ed96f05 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Fri, 19 Jul 2013 13:51:30 -0700 Subject: [PATCH] CRM-12943 - Add CRM.Backbone.*Collection.fetchCreate() ---------------------------------------- * CRM-12943: Make HTML prototype of job UI functional http://issues.civicrm.org/jira/browse/CRM-12943 --- js/crm.backbone.js | 35 +++++++++++++++++++ tests/qunit/crm-backbone/test.js | 59 ++++++++++++++++++++++++++++++-- 2 files changed, 91 insertions(+), 3 deletions(-) diff --git a/js/crm.backbone.js b/js/crm.backbone.js index e84089476c..f12d671006 100644 --- a/js/crm.backbone.js +++ b/js/crm.backbone.js @@ -144,6 +144,41 @@ crmEntityName: CollectionClass.prototype.model.prototype.crmEntityName, toCrmCriteria: function() { return this.crmCriteria || {}; + }, + + /** + * Find a single match, or create a (new) matching record. If a new record is created, + * it will be added to the collection but NOT saved. + * + * @param Object options: + * - success: function(model) + * - error: function(collection, error) + * - defaults: Object values to put on newly created model (if needed) + */ + fetchCreate: function(options) { + options || (options = {}); + this.fetch({ + success: function(collection) { + if (collection.length == 0) { + var attrs = _.extend({}, collection.crmCriteria, options.defaults || {}); + var model = collection._prepareModel(attrs, options); + collection.add(model, options); + options.success(model); + } else if (collection.length == 1) { + options.success(collection.first()); + } else { + options.error(collection, { + is_error: 1, + error_message: 'Too many matches' + }); + } + }, + error: function(collection, errorData) { + if (options.error) { + options.error(collection, errorData); + } + } + }); } }); // Overrides - if specified in CollectionClass, replace diff --git a/tests/qunit/crm-backbone/test.js b/tests/qunit/crm-backbone/test.js index 09a84457fa..e6cb7f7d4f 100644 --- a/tests/qunit/crm-backbone/test.js +++ b/tests/qunit/crm-backbone/test.js @@ -1,7 +1,7 @@ /* ------------ Fixtures/constants ------------ */ var VALID_CONTACT_ID = 3; -var INVALID_CONTACT_ID = 'z'; +var MALFORMED_CONTACT_ID = 'z'; var ContactModel = Backbone.Model.extend({}); CRM.Backbone.extendModel(ContactModel, 'Contact'); @@ -61,7 +61,7 @@ asyncTest("fetch (ok)", function() { }); asyncTest("fetch (error)", function() { - var c = new ContactModel({id: INVALID_CONTACT_ID}); + var c = new ContactModel({id: MALFORMED_CONTACT_ID}); c.fetch({ success: onUnexpectedSuccess, error: function(model, error) { @@ -212,7 +212,7 @@ asyncTest("fetch by crazy name (0 results)", function() { asyncTest("fetch by malformed ID (error)", function() { var c = new ContactCollection([], { crmCriteria: { - id: INVALID_CONTACT_ID + id: MALFORMED_CONTACT_ID } }); c.fetch({ @@ -224,3 +224,56 @@ asyncTest("fetch by malformed ID (error)", function() { }); }); +module('fetchCreate'); + +asyncTest("fetchCreate by ID (1 result)", function() { + var c = new ContactCollection([], { + crmCriteria: { + id: VALID_CONTACT_ID + } + }); + c.fetchCreate({ + error: onUnexpectedError, + success: function(model) { + equal(model.get('id'), VALID_CONTACT_ID); + ok(model.get('contact_type') != '', 'Expected contact with valid type') + ok(model.get('id'), 'Expected contact with valid ID') + start(); + } + }); +}); + +asyncTest("fetchCreate by crazy name (0 results) - autocreate", function() { + var c = new ContactCollection([], { + crmCriteria: { + organization_name: 'asdf23vmlk2309lk2lkasdk-23ASDF32f' + } + }); + c.fetchCreate({ + defaults: { + contact_type: 'Organization' + }, + error: onUnexpectedError, + success: function(model) { + equal(model.get('organization_name'), 'asdf23vmlk2309lk2lkasdk-23ASDF32f', 'Expected default values from crmCriteria'); + equal(model.get('contact_type'), 'Organization', 'Expected default values from parameters'); + ok(!model.get('id'), 'Expected contact without valid ID') + start(); + } + }); +}); + +asyncTest("fetchCreate by malformed ID (error)", function() { + var c = new ContactCollection([], { + crmCriteria: { + id: MALFORMED_CONTACT_ID + } + }); + c.fetch({ + success: onUnexpectedSuccess, + error: function(collection, error) { + assertApiError(error); + start(); + } + }); +}); -- 2.25.1