1 /* global $, _, CRM:true */
4 describe('crmCaseType', function() {
16 beforeEach(function() {
20 // CRM_Case_XMLProcessor::REL_TYPE_CNAME
22 'REL_TYPE_CNAME': 'label_b_a'
24 module('crmCaseType');
25 module('crmJsonComparator');
26 inject(function(crmJsonComparator
) {
27 crmJsonComparator
.register(jasmine
);
31 beforeEach(inject(function(_
$controller_
, _
$compile_
, _
$httpBackend_
, _
$q_
, _
$rootScope_
, _
$timeout_
) {
32 $controller
= _
$controller_
;
33 $compile
= _
$compile_
;
34 $httpBackend
= _
$httpBackend_
;
36 $rootScope
= _
$rootScope_
;
37 $timeout
= _
$timeout_
;
40 describe('CaseTypeCtrl', function() {
41 beforeEach(function () {
47 "option_group_id": "25",
60 "option_group_id": "25",
76 "option_group_id": "28",
90 "option_group_id": "28",
107 "option_group_id": "2",
108 "label": "ADC referral",
110 "name": "ADC referral",
121 "option_group_id": "2",
122 "label": "Add Client To Case",
124 "name": "Add Client To Case",
136 "option_group_id": "2",
137 "label": "Open Case",
147 "icon": "fa-folder-open-o"
151 "option_group_id": "2",
152 "label": "Medical evaluation",
154 "name": "Medical evaluation",
169 "name_a_b": "Benefits Specialist is",
170 "label_a_b": "Benefits Specialist is",
171 "name_b_a": "Benefits Specialist",
172 "label_b_a": "Benefits Specialist",
173 "description": "Benefits Specialist",
174 "contact_type_a": "Individual",
175 "contact_type_b": "Individual",
181 "name_a_b": "Case Coordinator is",
182 "label_a_b": "Case Coordinator is",
183 "name_b_a": "Case Coordinator",
184 "label_b_a": "Case Coordinator",
185 "description": "Case Coordinator",
186 "contact_type_a": "Individual",
187 "contact_type_b": "Individual",
195 "name": "housing_support",
196 "title": "Housing Support",
197 "description": "Help homeless individuals obtain temporary and long-term housing",
205 {"name": "Open Case", "max_instances": "1"}
209 "name": "standard_timeline",
210 "label": "Standard Timeline",
215 "status": "Completed"
218 "name": "Medical evaluation",
219 "reference_activity": "Open Case",
220 "reference_offset": "1",
221 "reference_select": "newest"
228 "name": "Homeless Services Coordinator",
236 scope
= $rootScope
.$new();
237 ctrl
= $controller('CaseTypeCtrl', {$scope
: scope
, apiCalls
: apiCalls
});
240 it('should load activity statuses', function() {
241 expect(scope
.activityStatuses
).toEqualData(apiCalls
.actStatuses
.values
);
244 it('should load activity types', function() {
245 expect(scope
.activityTypes
['ADC referral']).toEqualData(apiCalls
.actTypes
.values
[0]);
248 it('addActivitySet should add an activitySet to the case type', function() {
249 scope
.addActivitySet('timeline');
250 var activitySets
= scope
.caseType
.definition
.activitySets
;
251 var newSet
= activitySets
[activitySets
.length
- 1];
252 expect(newSet
.name
).toBe('timeline_1');
253 expect(newSet
.timeline
).toBe('1');
254 expect(newSet
.label
).toBe('Timeline');
257 it('addActivitySet handles second timeline correctly', function() {
258 scope
.addActivitySet('timeline');
259 scope
.addActivitySet('timeline');
260 var activitySets
= scope
.caseType
.definition
.activitySets
;
261 var newSet
= activitySets
[activitySets
.length
- 1];
262 expect(newSet
.name
).toBe('timeline_2');
263 expect(newSet
.timeline
).toBe('1');
264 expect(newSet
.label
).toBe('Timeline #2');
268 describe('crmAddName', function () {
271 beforeEach(function() {
272 scope
= $rootScope
.$new();
273 scope
.activityTypeOptions
= [1, 2, 3];
274 element
= '<span crm-add-name crm-options="activityTypeOptions"></span>';
276 spyOn(CRM
.$.fn
, 'crmSelect2').and
.callThrough();
278 element
= $compile(element
)(scope
);
282 describe('when initialized', function () {
285 beforeEach (function () {
286 var dataFunction
= CRM
.$.fn
.crmSelect2
.calls
.argsFor(0)[0].data
;
287 returnValue
= dataFunction();
290 it('updates the UI with updated value of scope variable', function () {
291 expect(returnValue
).toEqual({ results
: scope
.activityTypeOptions
});
296 describe('crmEditableTabTitle', function () {
297 var element
, titleLabel
, penIcon
, saveButton
, cancelButton
;
299 beforeEach(function() {
300 scope
= $rootScope
.$new();
301 element
= '<div crm-editable-tab-title title="Click to edit">' +
302 '<span>{{ activitySet.label }}</span>' +
305 scope
.activitySet
= { label
: 'Title'};
306 element
= $compile(element
)(scope
);
308 titleLabel
= $(element
).find('span');
309 penIcon
= $(element
).find('i.fa-pencil');
310 saveButton
= $(element
).find('button[type=button]');
311 cancelButton
= $(element
).find('button[type=cancel]');
316 describe('when initialized', function () {
317 it('hides the save and cancel button', function () {
318 expect(saveButton
.parent().css('display') === 'none').toBe(true);
319 expect(cancelButton
.parent().css('display') === 'none').toBe(true);
323 describe('when clicked on title label', function () {
324 beforeEach(function () {
328 it('hides the pen icon', function () {
329 expect(penIcon
.css('display') === 'none').toBe(true);
332 it('shows the save button', function () {
333 expect(saveButton
.parent().css('display') !== 'none').toBe(true);
336 it('makes the title editable', function () {
337 expect(titleLabel
.attr('contenteditable')).toBe('true');
341 describe('when clicked outside of the editable area', function () {
342 beforeEach(function () {
344 titleLabel
.text('Updated Title');
350 it('shows the pen icon', function () {
351 expect(penIcon
.css('display') !== 'none').toBe(true);
354 it('hides the save and cancel button', function () {
355 expect(saveButton
.parent().css('display') === 'none').toBe(true);
356 expect(cancelButton
.parent().css('display') === 'none').toBe(true);
359 it('makes the title non editable', function () {
360 expect(titleLabel
.attr('contenteditable')).not
.toBe('true');
363 it('does not update the title in angular context', function () {
364 expect(scope
.activitySet
.label
).toBe('Title');
368 describe('when ESCAPE key is pressed while typing', function () {
369 beforeEach(function () {
370 var eventObj
= $.Event('keydown');
371 eventObj
.key
= 'Escape';
374 titleLabel
.text('Updated Title');
375 titleLabel
.trigger(eventObj
);
379 it('shows the pen icon', function () {
380 expect(penIcon
.css('display') !== 'none').toBe(true);
383 it('hides the save and cancel button', function () {
384 expect(saveButton
.parent().css('display') === 'none').toBe(true);
385 expect(cancelButton
.parent().css('display') === 'none').toBe(true);
388 it('makes the title non editable', function () {
389 expect(titleLabel
.attr('contenteditable')).not
.toBe('true');
392 it('does not update the title', function () {
393 expect(scope
.activitySet
.label
).toBe('Title');
397 describe('when ENTER key is pressed while typing', function () {
398 beforeEach(function () {
399 var eventObj
= $.Event('keydown');
400 eventObj
.key
= 'Enter';
403 titleLabel
.text('Updated Title');
404 titleLabel
.trigger(eventObj
);
408 it('shows the pen icon', function () {
409 expect(penIcon
.css('display') !== 'none').toBe(true);
412 it('hides the save and cancel button', function () {
413 expect(saveButton
.parent().css('display') === 'none').toBe(true);
414 expect(cancelButton
.parent().css('display') === 'none').toBe(true);
417 it('makes the title non editable', function () {
418 expect(titleLabel
.attr('contenteditable')).not
.toBe('true');
421 it('updates the title in angular context', function () {
422 expect(scope
.activitySet
.label
).toBe('Updated Title');
426 describe('when SAVE button is clicked', function () {
427 beforeEach(function () {
429 titleLabel
.text('Updated Title');
434 it('shows the pen icon', function () {
435 expect(penIcon
.css('display') !== 'none').toBe(true);
438 it('hides the save and cancel button', function () {
439 expect(saveButton
.parent().css('display') === 'none').toBe(true);
440 expect(cancelButton
.parent().css('display') === 'none').toBe(true);
443 it('makes the title non editable', function () {
444 expect(titleLabel
.attr('contenteditable')).not
.toBe('true');
447 it('updates the title in angular context', function () {
448 expect(scope
.activitySet
.label
).toBe('Updated Title');
452 describe('when CANCEL button is clicked', function () {
453 beforeEach(function () {
455 titleLabel
.text('Updated Title');
456 cancelButton
.click();
460 it('shows the pen icon', function () {
461 expect(penIcon
.css('display') !== 'none').toBe(true);
464 it('hides the save and cancel button', function () {
465 expect(saveButton
.parent().css('display') === 'none').toBe(true);
466 expect(cancelButton
.parent().css('display') === 'none').toBe(true);
469 it('makes the title non editable', function () {
470 expect(titleLabel
.attr('contenteditable')).not
.toBe('true');
473 it('does not update the title in angular context', function () {
474 expect(scope
.activitySet
.label
).toBe('Title');
479 describe('CaseTypeListCtrl', function() {
480 var caseTypes
, crmApiSpy
;
482 beforeEach(function() {
490 crmApiSpy
= jasmine
.createSpy('crmApi').and
.returnValue($q
.resolve());
491 scope
= $rootScope
.$new();
492 ctrl
= $controller('CaseTypeListCtrl', {
494 caseTypes
: caseTypes
,
499 it('should store an index of case types', function() {
500 expect(scope
.caseTypes
).toEqual(caseTypes
.values
);
503 describe('toggleCaseType', function() {
504 var caseType
= { id
: _
.uniqueId() };
506 describe('when the case is active', function() {
507 beforeEach(function() {
508 caseType
.is_active
= '1';
510 scope
.toggleCaseType(caseType
);
513 it('sets the case type as inactive', function() {
514 expect(crmApiSpy
).toHaveBeenCalledWith('CaseType', 'create', jasmine
.objectContaining({
521 describe('when the case is inactive', function() {
522 beforeEach(function() {
523 caseType
.is_active
= '0';
525 scope
.toggleCaseType(caseType
);
528 it('sets the case type as active', function() {
529 expect(crmApiSpy
).toHaveBeenCalledWith('CaseType', 'create', jasmine
.objectContaining({
537 describe('deleteCaseType', function() {
538 var caseType
= { id
: _
.uniqueId() };
540 beforeEach(function() {
541 crmApiSpy
.and
.returnValue($q
.resolve(caseType
));
542 scope
.caseTypes
[caseType
.id
] = caseType
;
544 scope
.deleteCaseType(caseType
);
548 describe('when the case type can be deleted', function() {
549 it('deletes the case from the api', function() {
550 expect(crmApiSpy
).toHaveBeenCalledWith('CaseType', 'delete', { id
: caseType
.id
}, jasmine
.any(Object
));
553 it('removes the case type from the list', function() {
554 expect(scope
.caseTypes
[caseType
.id
]).toBeUndefined();
558 describe('when the case type cannot be delted', function() {
559 var error
= { error_message
: 'Error Message' };
561 beforeEach(function() {
564 crmApiSpy
.and
.returnValue($q
.reject(error
));
565 scope
.caseTypes
[caseType
.id
] = caseType
;
568 scope
.deleteCaseType(caseType
);
571 errorHandler
= crmApiSpy
.calls
.mostRecent().args
[3].error
;
575 it('displays the error message', function() {
576 expect(CRM
.alert
).toHaveBeenCalledWith(error
.error_message
, 'Error', 'error');
580 describe('revertCaseType', function() {
587 describe('when reverting a case type', function() {
588 beforeEach(function() {
589 scope
.revertCaseType(caseType
);
592 it('resets the case type information using the api', function() {
593 expect(crmApiSpy
).toHaveBeenCalledWith('CaseType', 'create', jasmine
.objectContaining({