| describe('uib-accordion', function() { |
| var $animate, $scope; |
| |
| beforeEach(module('ui.bootstrap.accordion')); |
| beforeEach(module('ngAnimateMock')); |
| beforeEach(module('template/accordion/accordion.html')); |
| beforeEach(module('template/accordion/accordion-group.html')); |
| |
| beforeEach(inject(function(_$animate_, $rootScope) { |
| $animate = _$animate_; |
| $scope = $rootScope; |
| })); |
| |
| describe('controller', function () { |
| var ctrl, $element, $attrs; |
| beforeEach(inject(function($controller) { |
| $attrs = {}; |
| ctrl = $controller('UibAccordionController', { $scope: $scope, $attrs: $attrs }); |
| })); |
| |
| describe('addGroup', function() { |
| it('adds a the specified panel to the collection', function() { |
| var group1, group2; |
| ctrl.addGroup(group1 = $scope.$new()); |
| ctrl.addGroup(group2 = $scope.$new()); |
| expect(ctrl.groups.length).toBe(2); |
| expect(ctrl.groups[0]).toBe(group1); |
| expect(ctrl.groups[1]).toBe(group2); |
| }); |
| }); |
| |
| describe('closeOthers', function() { |
| var group1, group2, group3; |
| beforeEach(function() { |
| ctrl.addGroup(group1 = { isOpen: true, $on : angular.noop }); |
| ctrl.addGroup(group2 = { isOpen: true, $on : angular.noop }); |
| ctrl.addGroup(group3 = { isOpen: true, $on : angular.noop }); |
| }); |
| it('should close other panels if close-others attribute is not defined', function() { |
| delete $attrs.closeOthers; |
| ctrl.closeOthers(group2); |
| expect(group1.isOpen).toBe(false); |
| expect(group2.isOpen).toBe(true); |
| expect(group3.isOpen).toBe(false); |
| }); |
| |
| it('should close other panels if close-others attribute is true', function() { |
| $attrs.closeOthers = 'true'; |
| ctrl.closeOthers(group3); |
| expect(group1.isOpen).toBe(false); |
| expect(group2.isOpen).toBe(false); |
| expect(group3.isOpen).toBe(true); |
| }); |
| |
| it('should not close other panels if close-others attribute is false', function() { |
| $attrs.closeOthers = 'false'; |
| ctrl.closeOthers(group2); |
| expect(group1.isOpen).toBe(true); |
| expect(group2.isOpen).toBe(true); |
| expect(group3.isOpen).toBe(true); |
| }); |
| |
| describe('setting accordionConfig', function() { |
| var originalCloseOthers; |
| beforeEach(inject(function(uibAccordionConfig) { |
| originalCloseOthers = uibAccordionConfig.closeOthers; |
| uibAccordionConfig.closeOthers = false; |
| })); |
| afterEach(inject(function(uibAccordionConfig) { |
| // return it to the original value |
| uibAccordionConfig.closeOthers = originalCloseOthers; |
| })); |
| |
| it('should not close other panels if accordionConfig.closeOthers is false', function() { |
| ctrl.closeOthers(group2); |
| expect(group1.isOpen).toBe(true); |
| expect(group2.isOpen).toBe(true); |
| expect(group3.isOpen).toBe(true); |
| }); |
| }); |
| }); |
| |
| describe('removeGroup', function() { |
| it('should remove the specified panel', function() { |
| var group1, group2, group3; |
| ctrl.addGroup(group1 = $scope.$new()); |
| ctrl.addGroup(group2 = $scope.$new()); |
| ctrl.addGroup(group3 = $scope.$new()); |
| ctrl.removeGroup(group2); |
| expect(ctrl.groups.length).toBe(2); |
| expect(ctrl.groups[0]).toBe(group1); |
| expect(ctrl.groups[1]).toBe(group3); |
| }); |
| it('should ignore remove of non-existing panel', function() { |
| var group1, group2; |
| ctrl.addGroup(group1 = $scope.$new()); |
| ctrl.addGroup(group2 = $scope.$new()); |
| expect(ctrl.groups.length).toBe(2); |
| ctrl.removeGroup({}); |
| expect(ctrl.groups.length).toBe(2); |
| }); |
| it('should remove a panel when the scope is destroyed', function() { |
| var group1, group2, group3; |
| ctrl.addGroup(group1 = $scope.$new()); |
| ctrl.addGroup(group2 = $scope.$new()); |
| ctrl.addGroup(group3 = $scope.$new()); |
| group2.$destroy(); |
| expect(ctrl.groups.length).toBe(2); |
| expect(ctrl.groups[0]).toBe(group1); |
| expect(ctrl.groups[1]).toBe(group3); |
| }); |
| }); |
| }); |
| |
| describe('uib-accordion', function() { |
| var scope, $compile, $templateCache, element; |
| |
| beforeEach(inject(function($rootScope, _$compile_, _$templateCache_) { |
| scope = $rootScope; |
| $compile = _$compile_; |
| $templateCache = _$templateCache_; |
| })); |
| |
| it('should expose the controller on the view', function() { |
| $templateCache.put('template/accordion/accordion.html', '<div>{{accordion.text}}</div>'); |
| |
| element = $compile('<uib-accordion></uib-accordion>')(scope); |
| scope.$digest(); |
| |
| var ctrl = element.controller('uibAccordion'); |
| expect(ctrl).toBeDefined(); |
| |
| ctrl.text = 'foo'; |
| scope.$digest(); |
| |
| expect(element.html()).toBe('<div class="ng-binding">foo</div>'); |
| }); |
| |
| it('should allow custom templates', function() { |
| $templateCache.put('foo/bar.html', '<div>baz</div>'); |
| |
| element = $compile('<accordion template-url="foo/bar.html"></accordion>')(scope); |
| scope.$digest(); |
| expect(element.html()).toBe('<div>baz</div>'); |
| }); |
| }); |
| |
| describe('uib-accordion-group', function() { |
| |
| var scope, $compile; |
| var element, groups; |
| var findGroupLink = function(index) { |
| return groups.eq(index).find('a').eq(0); |
| }; |
| var findGroupBody = function(index) { |
| return groups.eq(index).find('.panel-collapse').eq(0); |
| }; |
| |
| beforeEach(inject(function(_$rootScope_, _$compile_) { |
| scope = _$rootScope_; |
| $compile = _$compile_; |
| })); |
| |
| it('should allow custom templates', inject(function($templateCache) { |
| $templateCache.put('foo/bar.html', '<div>baz</div>'); |
| |
| var tpl = |
| '<uib-accordion>' + |
| '<uib-accordion-group heading="title 1" template-url="foo/bar.html"></uib-accordion-group>' + |
| '</uib-accordion>'; |
| |
| element = $compile(tpl)(scope); |
| scope.$digest(); |
| expect(element.find('[template-url]').html()).toBe('baz'); |
| })); |
| |
| describe('with static panels', function() { |
| beforeEach(function() { |
| var tpl = |
| '<uib-accordion>' + |
| '<uib-accordion-group heading="title 1">Content 1</uib-accordion-group>' + |
| '<uib-accordion-group heading="title 2">Content 2</uib-accordion-group>' + |
| '</uib-accordion>'; |
| element = angular.element(tpl); |
| $compile(element)(scope); |
| scope.$digest(); |
| groups = element.find('.panel'); |
| }); |
| afterEach(function() { |
| element.remove(); |
| }); |
| |
| it('should create accordion panels with content', function() { |
| expect(groups.length).toEqual(2); |
| expect(findGroupLink(0).text()).toEqual('title 1'); |
| expect(findGroupBody(0).text().trim()).toEqual('Content 1'); |
| expect(findGroupLink(1).text()).toEqual('title 2'); |
| expect(findGroupBody(1).text().trim()).toEqual('Content 2'); |
| }); |
| |
| it('should change selected element on click', function() { |
| findGroupLink(0).click(); |
| scope.$digest(); |
| expect(findGroupBody(0).scope().isOpen).toBe(true); |
| |
| findGroupLink(1).click(); |
| scope.$digest(); |
| expect(findGroupBody(0).scope().isOpen).toBe(false); |
| expect(findGroupBody(1).scope().isOpen).toBe(true); |
| }); |
| |
| it('should toggle element on click', function() { |
| findGroupLink(0).click(); |
| scope.$digest(); |
| expect(findGroupBody(0).scope().isOpen).toBe(true); |
| findGroupLink(0).click(); |
| scope.$digest(); |
| expect(findGroupBody(0).scope().isOpen).toBe(false); |
| }); |
| |
| it('should add, by default, "panel-open" when opened', function() { |
| var group = groups.eq(0); |
| findGroupLink(0).click(); |
| scope.$digest(); |
| expect(group).toHaveClass('panel-open'); |
| |
| findGroupLink(0).click(); |
| scope.$digest(); |
| expect(group).not.toHaveClass('panel-open'); |
| }); |
| |
| it('should toggle element on spacebar when focused', function() { |
| var group = groups.eq(0); |
| findGroupLink(0)[0].focus(); |
| var e = $.Event('keypress'); |
| e.which = 32; |
| findGroupLink(0).trigger(e); |
| |
| expect(group).toHaveClass('panel-open'); |
| |
| e = $.Event('keypress'); |
| e.which = 32; |
| findGroupLink(0).trigger(e); |
| |
| expect(group).not.toHaveClass('panel-open'); |
| }); |
| |
| it('should not toggle with any other keyCode', function() { |
| var group = groups.eq(0); |
| findGroupLink(0)[0].focus(); |
| var e = $.Event('keypress'); |
| e.which = 65; |
| findGroupLink(0).trigger(e); |
| |
| expect(group).not.toHaveClass('panel-open'); |
| }); |
| }); |
| |
| describe('with open-class attribute', function() { |
| beforeEach(function() { |
| var tpl = |
| '<uib-accordion>' + |
| '<uib-accordion-group heading="title 1" open-class="custom-open-class">Content 1</uib-accordion-group>' + |
| '<uib-accordion-group heading="title 2" open-class="custom-open-class">Content 2</uib-accordion-group>' + |
| '</uib-accordion>'; |
| element = angular.element(tpl); |
| $compile(element)(scope); |
| scope.$digest(); |
| groups = element.find('.panel'); |
| }); |
| afterEach(function() { |
| element.remove(); |
| }); |
| |
| it('should add custom-open-class when opened', function() { |
| var group = groups.eq(0); |
| findGroupLink(0).click(); |
| scope.$digest(); |
| expect(group).toHaveClass('custom-open-class'); |
| |
| findGroupLink(0).click(); |
| scope.$digest(); |
| expect(group).not.toHaveClass('custom-open-class'); |
| }); |
| }); |
| |
| describe('with dynamic panels', function() { |
| var model; |
| beforeEach(function() { |
| var tpl = |
| '<uib-accordion>' + |
| '<uib-accordion-group ng-repeat="group in groups" heading="{{group.name}}">{{group.content}}</uib-accordion-group>' + |
| '</uib-accordion>'; |
| element = angular.element(tpl); |
| model = [ |
| {name: 'title 1', content: 'Content 1'}, |
| {name: 'title 2', content: 'Content 2'} |
| ]; |
| |
| $compile(element)(scope); |
| scope.$digest(); |
| }); |
| |
| it('should have no panels initially', function() { |
| groups = element.find('.panel'); |
| expect(groups.length).toEqual(0); |
| }); |
| |
| it('should have a panel for each model item', function() { |
| scope.groups = model; |
| scope.$digest(); |
| groups = element.find('.panel'); |
| expect(groups.length).toEqual(2); |
| expect(findGroupLink(0).text()).toEqual('title 1'); |
| expect(findGroupBody(0).text().trim()).toEqual('Content 1'); |
| expect(findGroupLink(1).text()).toEqual('title 2'); |
| expect(findGroupBody(1).text().trim()).toEqual('Content 2'); |
| }); |
| |
| it('should react properly on removing items from the model', function() { |
| scope.groups = model; |
| scope.$digest(); |
| groups = element.find('.panel'); |
| expect(groups.length).toEqual(2); |
| |
| scope.groups.splice(0,1); |
| scope.$digest(); |
| groups = element.find('.panel'); |
| expect(groups.length).toEqual(1); |
| }); |
| }); |
| |
| describe('is-open attribute', function() { |
| beforeEach(function() { |
| var tpl = |
| '<uib-accordion>' + |
| '<uib-accordion-group heading="title 1" is-open="open.first">Content 1</uib-accordion-group>' + |
| '<uib-accordion-group heading="title 2" is-open="open.second">Content 2</uib-accordion-group>' + |
| '</uib-accordion>'; |
| element = angular.element(tpl); |
| scope.open = { first: false, second: true }; |
| $compile(element)(scope); |
| scope.$digest(); |
| groups = element.find('.panel'); |
| }); |
| |
| it('should open the panel with isOpen set to true', function() { |
| expect(findGroupBody(0).scope().isOpen).toBe(false); |
| expect(findGroupBody(1).scope().isOpen).toBe(true); |
| }); |
| |
| it('should toggle variable on element click', function() { |
| findGroupLink(0).click(); |
| scope.$digest(); |
| expect(scope.open.first).toBe(true); |
| |
| findGroupLink(0).click(); |
| scope.$digest(); |
| expect(scope.open.second).toBe(false); |
| }); |
| }); |
| |
| describe('is-open attribute with dynamic content', function() { |
| beforeEach(function() { |
| var tpl = |
| '<uib-accordion>' + |
| '<uib-accordion-group heading="title 1" is-open="open1"><div ng-repeat="item in items">{{item}}</div></uib-accordion-group>' + |
| '<uib-accordion-group heading="title 2" is-open="open2">Static content</uib-accordion-group>' + |
| '</uib-accordion>'; |
| element = angular.element(tpl); |
| scope.items = ['Item 1', 'Item 2', 'Item 3']; |
| scope.open1 = true; |
| scope.open2 = false; |
| angular.element(document.body).append(element); |
| $compile(element)(scope); |
| scope.$digest(); |
| $animate.flush(); |
| groups = element.find('.panel'); |
| }); |
| |
| afterEach(function() { |
| element.remove(); |
| }); |
| |
| it('should have visible panel body when the group with isOpen set to true', function() { |
| expect(findGroupBody(0)).toHaveClass('in'); |
| expect(findGroupBody(1)).not.toHaveClass('in'); |
| }); |
| }); |
| |
| describe('is-open attribute with dynamic groups', function() { |
| beforeEach(function() { |
| var tpl = |
| '<uib-accordion>' + |
| '<uib-accordion-group ng-repeat="group in groups" heading="{{group.name}}" is-open="group.open">{{group.content}}</uib-accordion-group>' + |
| '</uib-accordion>'; |
| element = angular.element(tpl); |
| scope.groups = [ |
| {name: 'title 1', content: 'Content 1', open: false}, |
| {name: 'title 2', content: 'Content 2', open: true} |
| ]; |
| $compile(element)(scope); |
| scope.$digest(); |
| |
| groups = element.find('.panel'); |
| }); |
| |
| it('should have visible group body when the group with isOpen set to true', function() { |
| expect(findGroupBody(0).scope().isOpen).toBe(false); |
| expect(findGroupBody(1).scope().isOpen).toBe(true); |
| }); |
| |
| it('should toggle element on click', function() { |
| findGroupLink(0).click(); |
| scope.$digest(); |
| expect(findGroupBody(0).scope().isOpen).toBe(true); |
| expect(scope.groups[0].open).toBe(true); |
| |
| findGroupLink(0).click(); |
| scope.$digest(); |
| expect(findGroupBody(0).scope().isOpen).toBe(false); |
| expect(scope.groups[0].open).toBe(false); |
| }); |
| }); |
| |
| describe('`is-disabled` attribute', function() { |
| var groupBody; |
| beforeEach(function() { |
| var tpl = |
| '<uib-accordion>' + |
| '<uib-accordion-group heading="title 1" is-disabled="disabled">Content 1</uib-accordion-group>' + |
| '</uib-accordion>'; |
| element = angular.element(tpl); |
| scope.disabled = true; |
| $compile(element)(scope); |
| scope.$digest(); |
| groups = element.find('.panel'); |
| groupBody = findGroupBody(0); |
| }); |
| |
| it('should open the panel with isOpen set to true', function() { |
| expect(groupBody.scope().isOpen).toBeFalsy(); |
| }); |
| |
| it('should not toggle if disabled', function() { |
| findGroupLink(0).click(); |
| scope.$digest(); |
| expect(groupBody.scope().isOpen).toBeFalsy(); |
| }); |
| |
| it('should toggle after enabling', function() { |
| scope.disabled = false; |
| scope.$digest(); |
| expect(groupBody.scope().isOpen).toBeFalsy(); |
| |
| findGroupLink(0).click(); |
| scope.$digest(); |
| expect(groupBody.scope().isOpen).toBeTruthy(); |
| }); |
| |
| it('should have text-muted styling', function() { |
| expect(findGroupLink(0).find('span:first')).toHaveClass('text-muted'); |
| }); |
| }); |
| |
| // This is re-used in both the uib-accordion-heading element and the uib-accordion-heading attribute tests |
| function isDisabledStyleCheck() { |
| var tpl = |
| '<uib-accordion ng-init="a = [1,2,3]">' + |
| '<uib-accordion-group heading="I get overridden" is-disabled="true">' + |
| '<uib-accordion-heading>Heading Element <span ng-repeat="x in a">{{x}}</span> </uib-accordion-heading>' + |
| 'Body' + |
| '</uib-accordion-group>' + |
| '</uib-accordion>'; |
| scope.disabled = true; |
| element = $compile(tpl)(scope); |
| scope.$digest(); |
| groups = element.find('.panel'); |
| |
| expect(findGroupLink(0).find('span').hasClass('text-muted')).toBe(true); |
| } |
| |
| describe('uib-accordion-heading element', function() { |
| beforeEach(function() { |
| var tpl = |
| '<uib-accordion ng-init="a = [1,2,3]">' + |
| '<uib-accordion-group heading="I get overridden">' + |
| '<uib-accordion-heading>Heading Element <span ng-repeat="x in a">{{x}}</span> </uib-accordion-heading>' + |
| 'Body' + |
| '</uib-accordion-group>' + |
| '</uib-accordion>'; |
| element = $compile(tpl)(scope); |
| scope.$digest(); |
| groups = element.find('.panel'); |
| }); |
| |
| it('transcludes the <uib-accordion-heading> content into the heading link', function() { |
| expect(findGroupLink(0).text()).toBe('Heading Element 123 '); |
| }); |
| |
| it('attaches the same scope to the transcluded heading and body', function() { |
| expect(findGroupLink(0).find('span.ng-scope').scope().$id).toBe(findGroupBody(0).find('span').scope().$id); |
| }); |
| |
| it('should wrap the transcluded content in a span', function() { |
| expect(findGroupLink(0).find('span:first').length).toEqual(1); |
| }); |
| |
| it('should have disabled styling when is-disabled is true', isDisabledStyleCheck); |
| |
| }); |
| |
| describe('uib-accordion-heading attribute', function() { |
| beforeEach(function() { |
| var tpl = |
| '<uib-accordion ng-init="a = [1,2,3]">' + |
| '<uib-accordion-group heading="I get overridden">' + |
| '<div uib-accordion-heading>Heading Element <span ng-repeat="x in a">{{x}}</span> </div>' + |
| 'Body' + |
| '</uib-accordion-group>' + |
| '</uib-accordion>'; |
| element = $compile(tpl)(scope); |
| scope.$digest(); |
| groups = element.find('.panel'); |
| }); |
| |
| it('transcludes the <uib-accordion-heading> content into the heading link', function() { |
| expect(findGroupLink(0).text()).toBe('Heading Element 123 '); |
| }); |
| |
| it('attaches the same scope to the transcluded heading and body', function() { |
| expect(findGroupLink(0).find('span.ng-scope').scope().$id).toBe(findGroupBody(0).find('span').scope().$id); |
| }); |
| |
| it('should have disabled styling when is-disabled is true', isDisabledStyleCheck); |
| |
| }); |
| |
| describe('uib-accordion-heading, with repeating uib-accordion-groups', function() { |
| it('should clone the uib-accordion-heading for each group', function() { |
| element = $compile('<uib-accordion><uib-accordion-group ng-repeat="x in [1,2,3]"><uib-accordion-heading>{{x}}</uib-accordion-heading></uib-accordion-group></uib-accordion>')(scope); |
| scope.$digest(); |
| groups = element.find('.panel'); |
| expect(groups.length).toBe(3); |
| expect(findGroupLink(0).text()).toBe('1'); |
| expect(findGroupLink(1).text()).toBe('2'); |
| expect(findGroupLink(2).text()).toBe('3'); |
| }); |
| }); |
| |
| describe('uib-accordion-heading attribute, with repeating uib-accordion-groups', function() { |
| it('should clone the uib-accordion-heading for each group', function() { |
| element = $compile('<uib-accordion><uib-accordion-group ng-repeat="x in [1,2,3]"><div uib-accordion-heading>{{x}}</div></uib-accordion-group></uib-accordion>')(scope); |
| scope.$digest(); |
| groups = element.find('.panel'); |
| expect(groups.length).toBe(3); |
| expect(findGroupLink(0).text()).toBe('1'); |
| expect(findGroupLink(1).text()).toBe('2'); |
| expect(findGroupLink(2).text()).toBe('3'); |
| }); |
| }); |
| |
| describe('uib-accordion group panel class - #3968', function() { |
| it('should use the default value when panel class is falsy', function() { |
| element = $compile('<uib-accordion><uib-accordion-group heading="Heading">Content</uib-accordion-group></uib-accordion>')(scope); |
| scope.$digest(); |
| groups = element.find('.panel'); |
| expect(groups.eq(0)).toHaveClass('panel-default'); |
| |
| element = $compile('<uib-accordion><uib-accordion-group heading="Heading" panel-class="">Content</uib-accordion-group></uib-accordion>')(scope); |
| scope.$digest(); |
| groups = element.find('.panel'); |
| expect(groups.eq(0)).toHaveClass('panel-default'); |
| }); |
| |
| it('should use the specified value when not falsy', function() { |
| element = $compile('<uib-accordion><uib-accordion-group heading="Heading" panel-class="custom-class">Content</uib-accordion-group></uib-accordion>')(scope); |
| scope.$digest(); |
| groups = element.find('.panel'); |
| expect(groups.eq(0)).toHaveClass('custom-class'); |
| expect(groups.eq(0)).not.toHaveClass('panel-default'); |
| }); |
| }); |
| }); |
| }); |
| |
| /* Deprecation tests below */ |
| |
| describe('accordion deprecation', function() { |
| beforeEach(module('ui.bootstrap.accordion')); |
| beforeEach(module('ngAnimateMock')); |
| beforeEach(module('template/accordion/accordion.html')); |
| beforeEach(module('template/accordion/accordion-group.html')); |
| |
| it('should suppress warning', function() { |
| module(function($provide) { |
| $provide.value('$accordionSuppressWarning', true); |
| }); |
| |
| inject(function($compile, $log, $rootScope) { |
| spyOn($log, 'warn'); |
| |
| var element = |
| '<accordion ng-init="a = [1,2,3]">' + |
| '<accordion-group heading="I get overridden">' + |
| '<div accordion-heading>Heading Element <span ng-repeat="x in a">{{x}}</span> </div>' + |
| 'Body' + |
| '</accordion-group>' + |
| '</accordion>'; |
| element = $compile(element)($rootScope); |
| $rootScope.$digest(); |
| expect($log.warn.calls.count()).toBe(0); |
| }); |
| }); |
| |
| it('should give warning by default', inject(function($compile, $log, $rootScope) { |
| spyOn($log, 'warn'); |
| |
| var element = |
| '<accordion ng-init="a = [1,2,3]">' + |
| '<accordion-group heading="I get overridden">' + |
| '<div accordion-heading>Heading Element <span ng-repeat="x in a">{{x}}</span> </div>' + |
| 'Body' + |
| '</accordion-group>' + |
| '</accordion>'; |
| element = $compile(element)($rootScope); |
| $rootScope.$digest(); |
| |
| expect($log.warn.calls.count()).toBe(4); |
| expect($log.warn.calls.argsFor(0)).toEqual(['AccordionController is now deprecated. Use UibAccordionController instead.']); |
| expect($log.warn.calls.argsFor(1)).toEqual(['accordion-heading is now deprecated. Use uib-accordion-heading instead.']); |
| expect($log.warn.calls.argsFor(2)).toEqual(['accordion-group is now deprecated. Use uib-accordion-group instead.']); |
| expect($log.warn.calls.argsFor(3)).toEqual(['accordion is now deprecated. Use uib-accordion instead.']); |
| })); |
| }); |