Merge remote-tracking branch 'upstream/4.5' into 4.5-4.6-2015-04-13-16-08-08
[civicrm-core.git] / tests / qunit / crm-backbone / test.js
1 (function(CRM,_){
2 /* ------------ Fixtures/constants ------------ */
3
4 var VALID_CONTACT_ID = 3;
5 var MALFORMED_CONTACT_ID = 'z';
6
7 var ContactModel = Backbone.Model.extend({});
8 CRM.Backbone.extendModel(ContactModel, 'Contact');
9 CRM.Backbone.trackSaved(ContactModel);
10
11 var ContactCollection = Backbone.Collection.extend({
12 model: ContactModel
13 });
14 CRM.Backbone.extendCollection(ContactCollection);
15
16 /* ------------ Assertions ------------ */
17
18 /**
19 * Assert "result" contains an API error.
20 * @param result
21 */
22 function assertApiError(result) {
23 equal(1, result.is_error, 'Expected error boolean');
24 ok(result.error_message.length > 0, 'Expected error message');
25 }
26
27 /**
28 * When calling an AJAX operation which should return successfully,
29 * make sure that there's no error by setting a callback (error: onUnexpectedError)
30 */
31 function onUnexpectedError(ignore, result) {
32 if (result && result.error_message) {
33 ok(false, "API returned an unexpected error: " + result.error_message);
34 } else {
35 ok(false, "API returned an unexpected error: (missing message)");
36 }
37 start();
38 }
39
40 /**
41 * When calling an AJAX operation which should return an error,
42 * make sure that there's no success by setting a callback (success: onUnexpectedSuccess)
43 */
44 function onUnexpectedSuccess(ignore) {
45 ok(false, "API succeeded - but failure was expected");
46 start();
47 }
48
49 /* ------------ Test cases ------------ */
50
51 module('model - read');
52
53 asyncTest("fetch (ok)", function() {
54 var c = new ContactModel({id: VALID_CONTACT_ID});
55 c.fetch({
56 error: onUnexpectedError,
57 success: function() {
58 notEqual(-1, _.indexOf(['Individual', 'Household', 'Organization'], c.get('contact_type')), 'Loaded contact with valid contact_type');
59 ok(c.get('display_name') !== '', 'Loaded contact with valid name');
60 start();
61 }
62 });
63 });
64
65 asyncTest("fetch (error)", function() {
66 var c = new ContactModel({id: MALFORMED_CONTACT_ID});
67 c.fetch({
68 success: onUnexpectedSuccess,
69 error: function(model, error) {
70 assertApiError(error);
71 start();
72 }
73 });
74 });
75
76 module('model - create');
77
78 asyncTest("create/read/delete/read (ok)", function() {
79 var TOKEN = new Date().getTime();
80 var c1 = new ContactModel({
81 contact_type: "Individual",
82 first_name: "George" + TOKEN,
83 last_name: "Anon" + TOKEN
84 });
85 equal(c1.isSaved(), false, "");
86
87 // Create the new contact
88 c1.save({}, {
89 error: onUnexpectedError,
90 success: function() {
91 equal(c1.get("first_name"), "George" + TOKEN, "save() should return new first name");
92 equal(c1.isSaved(), true, "");
93
94 // Fetch the newly created contact
95 var c2 = new ContactModel({id: c1.get('id')});
96 equal(c2.isSaved(), true, "");
97 c2.fetch({
98 error: onUnexpectedError,
99 success: function() {
100 equal(c2.get("first_name"), c1.get("first_name"), "fetch() should return first name");
101 equal(c2.isSaved(), true, "");
102
103 // Destroy the newly created contact
104 c2.destroy({
105 error: onUnexpectedError,
106 success: function() {
107 equal(c2.isSaved(), true, "");
108
109 // Attempt (but fail) to fetch the deleted contact
110 var c3 = new ContactModel({id: c1.get('id')});
111 equal(c3.isSaved(), true, "");
112 c3.fetch({
113 success: onUnexpectedSuccess,
114 error: function(model, error) {
115 assertApiError(error);
116 start();
117 }
118 }); // fetch
119 }
120 }); // destroy
121 }
122 }); // fetch
123 }
124 }); // save
125 });
126
127 asyncTest("create (error)", function() {
128 var TOKEN = new Date().getTime();
129 var c1 = new ContactModel({
130 // MISSING: contact_type: "Individual",
131 first_name: "George" + TOKEN,
132 last_name: "Anon" + TOKEN
133 });
134
135 // Create the new contact
136 c1.save({}, {
137 success: onUnexpectedSuccess,
138 error: function(model, error) {
139 assertApiError(error);
140 start();
141 }
142 });
143 });
144
145 module('model - update');
146
147 asyncTest("update (ok)", function() {
148 var NICKNAME = "George" + new Date().getTime();
149 var c = new ContactModel({id: VALID_CONTACT_ID});
150 equal(c.isSaved(), true, "");
151 c.set({
152 nick_name: NICKNAME
153 });
154 equal(c.isSaved(), false, "");
155 c.save({}, {
156 error: onUnexpectedError,
157 success: function() {
158 equal(c.get("nick_name"), NICKNAME, "save() should return new nickname");
159 _.defer(function(){
160 equal(c.isSaved(), true, "");
161
162 // read back - make sure the save worked
163 var c2 = new ContactModel({id: VALID_CONTACT_ID});
164 c2.fetch({
165 error: onUnexpectedError,
166 success: function() {
167 equal(c2.get("nick_name"), NICKNAME, "fetch() should return new nickname");
168 start();
169 }
170 });
171 });
172 }
173 });
174 });
175
176 asyncTest("update (error)", function() {
177 var NICKNAME = "George" + new Date().getTime();
178 var c = new ContactModel({id: VALID_CONTACT_ID});
179 equal(c.isSaved(), true, "");
180 c.set({
181 contact_type: 'Not-a.va+lidConta(ype'
182 });
183 equal(c.isSaved(), false, "");
184 c.save({}, {
185 success: onUnexpectedSuccess,
186 error: function(model, error) {
187 assertApiError(error);
188 _.defer(function(){
189 equal(c.isSaved(), false, "");
190 start();
191 });
192 }
193 });
194 });
195
196
197 module('collection - read');
198
199 asyncTest("fetch by contact_type (passive criteria, 1+ results)", function() {
200 var c = new ContactCollection([], {
201 crmCriteria: {
202 contact_type: 'Organization'
203 }
204 });
205 c.fetch({
206 error: onUnexpectedError,
207 success: function() {
208 ok(c.models.length > 0, "Expected at least one contact");
209 c.each(function(model) {
210 equal(model.get('contact_type'), 'Organization', 'Expected contact with type organization');
211 ok(model.get('display_name') !== '', 'Expected contact with valid name');
212 });
213 start();
214 }
215 });
216 });
217
218 asyncTest("fetch by contact_type (active criteria, 1+ results)", function() {
219 var criteria = new Backbone.Model({
220 contact_type: 'Organization'
221 });
222 var c = new ContactCollection([], {
223 crmCriteriaModel: criteria
224 });
225 c.fetch({
226 error: onUnexpectedError,
227 success: function() {
228 ok(c.models.length > 0, "Expected at least one contact");
229 c.each(function(model) {
230 equal(model.get('contact_type'), 'Organization', 'Expected contact with type organization');
231 ok(model.get('display_name') !== '', 'Expected contact with valid name');
232 });
233 start();
234 }
235 });
236 });
237
238 asyncTest("fetch by contact_type (active criteria revision, 1+ results)", function() {
239 var criteria = new Backbone.Model({
240 contact_type: 'Household'
241 });
242 var c = new ContactCollection([], {
243 crmCriteriaModel: criteria
244 });
245 c.fetch({
246 error: onUnexpectedError,
247 success: function() {
248 ok(c.models.length > 0, "Expected at least one contact");
249 c.each(function(model) {
250 equal(model.get('contact_type'), 'Household', 'Expected contact with type household');
251 ok(model.get('display_name') !== '', 'Expected contact with valid name');
252 });
253
254 criteria.set('contact_type', 'Organization');
255 _.delay(function() {
256 ok(c.models.length > 0, "Expected at least one contact");
257 c.each(function(model) {
258 equal(model.get('contact_type'), 'Organization', 'Expected contact with type organization');
259 ok(model.get('display_name') !== '', 'Expected contact with valid name');
260 });
261 start();
262 }, 1000);
263 }
264 });
265 });
266
267 asyncTest("fetch by crazy name (0 results)", function() {
268 var c = new ContactCollection([], {
269 crmCriteria: {
270 display_name: 'asdf23vmlk2309lk2lkasdk-23ASDF32f'
271 }
272 });
273 c.fetch({
274 error: onUnexpectedError,
275 success: function() {
276 equal(c.models.length, 0, "Expected no contacts");
277 start();
278 }
279 });
280 });
281
282 asyncTest("fetch by malformed ID (error)", function() {
283 var c = new ContactCollection([], {
284 crmCriteria: {
285 id: MALFORMED_CONTACT_ID
286 }
287 });
288 c.fetch({
289 success: onUnexpectedSuccess,
290 error: function(collection, error) {
291 assertApiError(error);
292 start();
293 }
294 });
295 });
296
297 module('findCreate');
298
299 asyncTest("findCreate by ID (1 result)", function() {
300 CRM.Backbone.findCreate({
301 CollectionClass: ContactCollection,
302 crmCriteria: {
303 id: VALID_CONTACT_ID
304 },
305 error: onUnexpectedError,
306 success: function(model) {
307 equal(model.get('id'), VALID_CONTACT_ID);
308 ok(model.get('contact_type') !== '', 'Expected contact with valid type');
309 ok(model.get('id'), 'Expected contact with valid ID');
310 start();
311 }
312 });
313 });
314
315 asyncTest("findCreate by crazy name (0 results) - autocreate", function() {
316 CRM.Backbone.findCreate({
317 CollectionClass: ContactCollection,
318 crmCriteria: {
319 organization_name: 'asdf23vmlk2309lk2lkasdk-23ASDF32f'
320 },
321 defaults: {
322 contact_type: 'Organization'
323 },
324 error: onUnexpectedError,
325 success: function(model) {
326 equal(model.get('organization_name'), 'asdf23vmlk2309lk2lkasdk-23ASDF32f', 'Expected default values from crmCriteria');
327 equal(model.get('contact_type'), 'Organization', 'Expected default values from parameters');
328 ok(!model.get('id'), 'Expected contact without valid ID');
329 start();
330 }
331 });
332 });
333
334 asyncTest("findCreate by malformed ID (error)", function() {
335 CRM.Backbone.findCreate({
336 CollectionClass: ContactCollection,
337 crmCriteria: {
338 id: MALFORMED_CONTACT_ID
339 },
340 success: onUnexpectedSuccess,
341 error: function(collection, error) {
342 assertApiError(error);
343 start();
344 }
345 });
346 });
347
348 })(CRM,CRM._);