256 lines
8.8 KiB
JavaScript
256 lines
8.8 KiB
JavaScript
|
|
/* Copyright (c) 2015 Mirantis, Inc.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
not use this file except in compliance with the License. You may obtain
|
|
a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
License for the specific language governing permissions and limitations
|
|
under the License.
|
|
*/
|
|
describe('merlin directives', function() {
|
|
'use strict';
|
|
|
|
var $compile, $scope, $httpBackend;
|
|
|
|
beforeEach(function() {
|
|
module('merlin', function($provide) {
|
|
$provide.value('fieldTemplates', ['number', 'text']);
|
|
});
|
|
module('preprocessedTemplates');
|
|
});
|
|
|
|
beforeEach(inject(function(_$compile_, _$rootScope_, _$httpBackend_, _$templateCache_) {
|
|
$compile = _$compile_;
|
|
$scope = _$rootScope_.$new();
|
|
$httpBackend = _$httpBackend_;
|
|
$httpBackend.whenGET('/static/merlin/templates/fields/text.html').respond(
|
|
200, _$templateCache_.get('/static/merlin/templates/fields/text.html'));
|
|
$httpBackend.whenGET('/static/merlin/templates/fields/number.html').respond(
|
|
200, _$templateCache_.get('/static/merlin/templates/fields/number.html'));
|
|
}));
|
|
|
|
describe('<panel>', function() {
|
|
function getPanelHeading(panelElem) {
|
|
var div = panelElem.children().children().eq(0);
|
|
return div.hasClass('panel-heading') && div;
|
|
}
|
|
|
|
function getPanelRemoveButton(panelElem) {
|
|
var iTag = panelElem.find('i').eq(1);
|
|
return iTag.hasClass('fa-times-circle') && iTag;
|
|
}
|
|
|
|
function getCollapseBtn(groupElem) {
|
|
return groupElem.find('a').eq(0);
|
|
}
|
|
|
|
function getPanelBody(panelElem) {
|
|
var div = panelElem.children().children().eq(1);
|
|
return div.hasClass('panel-body') && div;
|
|
}
|
|
|
|
function makePanelElem(contents) {
|
|
var panel = $compile('<panel ' + contents + '></panel>')($scope);
|
|
$scope.$digest();
|
|
return panel;
|
|
}
|
|
|
|
function makePanelWithInnerTags() {
|
|
var element = $compile('<panel><span class="inner"></span></panel>')($scope);
|
|
$scope.$digest();
|
|
return element;
|
|
}
|
|
|
|
it('shows panel heading when and only when title is passed via attr', function() {
|
|
var title = 'My Panel',
|
|
element1 = makePanelElem('title="' + title +'"'),
|
|
element2 = makePanelElem('');
|
|
|
|
expect(getPanelHeading(element1).hasClass('ng-hide')).toBe(false);
|
|
expect(element1.html()).toContain(title);
|
|
expect(getPanelHeading(element2).hasClass('ng-hide')).toBe(true);
|
|
});
|
|
|
|
it('requires both `title` and `removable` to be removable', function() {
|
|
var title = 'My Panel',
|
|
element1, element2;
|
|
|
|
element1 = makePanelElem('title="' + title +'" removable="true"');
|
|
element2 = makePanelElem('title="' + title +'"');
|
|
|
|
expect(getPanelRemoveButton(element1).hasClass('ng-hide')).toBe(false);
|
|
expect(getPanelRemoveButton(element2).hasClass('ng-hide')).toBe(true);
|
|
});
|
|
|
|
it('with `on-remove`, but without `removable` is not removable', function() {
|
|
var title = 'My Panel',
|
|
element1, element2;
|
|
|
|
$scope.remove = function() {};
|
|
element1 = makePanelElem(
|
|
'title="' + title +'" removable="true" on-remove="remove()"');
|
|
element2 = makePanelElem('title="' + title +'" on-remove="remove()"');
|
|
|
|
expect(getPanelRemoveButton(element1).hasClass('ng-hide')).toBe(false);
|
|
expect(getPanelRemoveButton(element2).hasClass('ng-hide')).toBe(true);
|
|
});
|
|
|
|
it('contents are inserted into div.panel-body tag', function() {
|
|
var panel = makePanelWithInnerTags();
|
|
|
|
expect(getPanelBody(panel).find('span').hasClass('inner')).toBe(true);
|
|
});
|
|
|
|
it('starts as being expanded', function() {
|
|
var panel = makePanelWithInnerTags(),
|
|
body = getPanelBody(panel);
|
|
|
|
expect(body.hasClass('collapse')).toBe(true);
|
|
expect(body.hasClass('in')).toBe(true);
|
|
});
|
|
|
|
it('starts to collapse after pressing on triangle next to group title', function() {
|
|
// NOTE(tsufiev): I wasn't able to test the final .collapse state (without .in)
|
|
// most probably due to transition from .collapse.in -> .collapsing -> .collapse
|
|
// is made with means of CSS, not
|
|
var element = makePanelWithInnerTags(),
|
|
body = getPanelBody(element),
|
|
link = getCollapseBtn(element);
|
|
|
|
link.triggerHandler('click');
|
|
|
|
expect(body.hasClass('collapse')).toBe(false);
|
|
expect(body.hasClass('collapsing')).toBe(true);
|
|
});
|
|
|
|
});
|
|
|
|
describe('<collapsible-group>', function() {
|
|
function getGroupBody(groupElem) {
|
|
var div = groupElem.children().children().eq(1);
|
|
return div.hasClass('section-body') && div;
|
|
}
|
|
|
|
function getGroupRemoveBtn(groupElem) {
|
|
var div = groupElem.children().children().eq(0).children().eq(2);
|
|
return div.hasClass('remove-entry') && div;
|
|
}
|
|
|
|
function getGroupAddBtn(groupElem) {
|
|
var div = groupElem.children().children().eq(0).children().eq(1);
|
|
return div.hasClass('add-entry') && div;
|
|
}
|
|
|
|
function getCollapseBtn(groupElem) {
|
|
return groupElem.children().children().eq(0).children().eq(0).find('a');
|
|
}
|
|
|
|
function makeGroupElement(contents) {
|
|
var group = $compile(
|
|
'<collapsible-group ' + contents + '></collapsible-group>')($scope);
|
|
$scope.$digest();
|
|
return group;
|
|
}
|
|
|
|
function makeGroupWithInnerTags() {
|
|
var group = $compile(
|
|
'<collapsible-group><span class="inner"></span></collapsible-group>'
|
|
)($scope);
|
|
$scope.$digest();
|
|
return group;
|
|
}
|
|
|
|
it('starts as being expanded', function() {
|
|
var element = makeGroupWithInnerTags(),
|
|
body = getGroupBody(element);
|
|
|
|
expect(body.hasClass('collapse')).toBe(true);
|
|
expect(body.hasClass('in')).toBe(true);
|
|
});
|
|
|
|
it('starts to collapse after pressing on triangle next to group title', function() {
|
|
// NOTE(tsufiev): I wasn't able to test the final .collapse state (without .in)
|
|
// most probably due to transition from .collapse.in -> .collapsing -> .collapse
|
|
// is made with means of CSS, not
|
|
var element = makeGroupWithInnerTags(),
|
|
body = getGroupBody(element),
|
|
link = getCollapseBtn(element);
|
|
|
|
link.triggerHandler('click');
|
|
|
|
expect(body.hasClass('collapse')).toBe(false);
|
|
expect(body.hasClass('collapsing')).toBe(true);
|
|
});
|
|
|
|
it('requires to specify just `on-remove` to make group removable', function() {
|
|
var element1, element2;
|
|
$scope.remove = function() {};
|
|
element1 = makeGroupElement('');
|
|
element2 = makeGroupElement('on-remove="remove()"');
|
|
|
|
expect(getGroupRemoveBtn(element1).hasClass('ng-hide')).toBe(true);
|
|
expect(getGroupRemoveBtn(element2).hasClass('ng-hide')).toBe(false);
|
|
});
|
|
|
|
it('requires to specify `on-add` to make group additive', function() {
|
|
var element1, element2;
|
|
$scope.add = function() {};
|
|
element1 = makeGroupElement('');
|
|
element2 = makeGroupElement('on-add="add()"');
|
|
|
|
expect(getGroupAddBtn(element1).hasClass('ng-hide')).toBe(true);
|
|
expect(getGroupAddBtn(element2).hasClass('ng-hide')).toBe(false);
|
|
});
|
|
|
|
it('`additive` attribute set explicitly to `false` makes group not additive', function() {
|
|
var element;
|
|
$scope.add = function() {};
|
|
element = makeGroupElement('on-add="add()" additive="false"');
|
|
|
|
expect(getGroupAddBtn(element).hasClass('ng-hide')).toBe(true);
|
|
});
|
|
|
|
it('contents are inserted into div.collapse tag', function() {
|
|
var element = makeGroupWithInnerTags();
|
|
|
|
expect(getGroupBody(element).find('span').hasClass('inner')).toBe(true);
|
|
});
|
|
|
|
});
|
|
|
|
describe('<typed-field>', function() {
|
|
function makeFieldElem(contents) {
|
|
return $compile(
|
|
'<div><typed-field ' + contents + '></typed-field></div>')($scope);
|
|
}
|
|
|
|
it('type of resulting field is determined by `type` attribute', function() {
|
|
var element1, element2;
|
|
$scope.value1 = {type: 'text'};
|
|
$scope.value2 = {type: 'number'};
|
|
element1 = makeFieldElem('value="value1" type="{$ value1.type $}"');
|
|
element2 = makeFieldElem('value="value2" type="{$ value2.type $}"');
|
|
$httpBackend.flush();
|
|
$scope.$digest();
|
|
|
|
expect(element1.html()).toContain('<textarea');
|
|
expect(element2.html()).toContain('<input type="number"');
|
|
});
|
|
|
|
it('field is not rendered until the corresponding template has been served', function() {
|
|
var element;
|
|
$scope.value = {type: 'text'};
|
|
element = makeFieldElem('value="value" type="{$ value.type $}"');
|
|
expect(element.html()).not.toContain('<textarea');
|
|
|
|
$httpBackend.flush();
|
|
expect(element.html()).toContain('<textarea');
|
|
})
|
|
});
|
|
}); |