Unit tests fixed

This commit is contained in:
Juan 2018-10-18 20:48:21 +02:00
parent ecee07530a
commit c4b3296959
15 changed files with 3774 additions and 3896 deletions

View File

@ -34,7 +34,6 @@ export default class Autocomplete extends Input {
this.assignDropdownProps(); this.assignDropdownProps();
this.showField = this.$.dropDown.showField; this.showField = this.$.dropDown.showField;
this.valueField = this.$.dropDown.valueField; this.valueField = this.$.dropDown.valueField;
this.linked = true;
this.refreshSelection(); this.refreshSelection();
} }
@ -43,8 +42,7 @@ export default class Autocomplete extends Input {
} }
set model(value) { set model(value) {
this._model = value; this.dropDownAssign({model: value});
this.assignDropdownProps();
} }
get data() { get data() {
@ -52,8 +50,7 @@ export default class Autocomplete extends Input {
} }
set data(value) { set data(value) {
this._data = value; this.dropDownAssign({data: value});
this.assignDropdownProps();
} }
get url() { get url() {
@ -61,8 +58,14 @@ export default class Autocomplete extends Input {
} }
set url(value) { set url(value) {
this._url = value; this.dropDownAssign({url: value});
this.assignDropdownProps(); }
dropDownAssign(props) {
for (let prop in props)
this[`_${prop}`] = props[prop];
if (this.$.dropDown)
Object.assign(this.$.dropDown, props);
} }
/** /**
@ -101,54 +104,55 @@ export default class Autocomplete extends Input {
} }
refreshSelection() { refreshSelection() {
if (this.selectionIsValid(this._selection)) if (this._field == null) {
this.selection = null;
return;
}
if (!(this.valueField && this.showField)
|| this.selectionIsValid(this._selection))
return; return;
let value = this._field; this.selection = this.fetchSelection();
if (value && this.linked) {
if (this.selectionIsValid(this.initialData)) {
this.selection = this.initialData;
return;
}
if (this.$.dropDown) {
let data;
if (this.$.dropDown.model)
data = this.$.dropDown.model.orgData;
if (data)
for (let i = 0; i < data.length; i++)
if (data[i][this.valueField] === value) {
this.selection = data[i];
return;
}
this.requestSelection(value);
}
} else
this.selection = null;
} }
requestSelection(value) { fetchSelection() {
if (!this.url) return; if (this.selectionIsValid(this.initialData))
let where = {}; return this.initialData;
if (this.multiple) if (!this.$.dropDown)
where[this.valueField] = {inq: this.field}; return null;
else
where[this.valueField] = value;
let filter = { let data;
fields: this.$.dropDown.getFields(), if (this.$.dropDown.model)
where: where data = this.$.dropDown.model.orgData;
};
let json = encodeURIComponent(JSON.stringify(filter)); if (data) {
this.$http.get(`${this.url}?filter=${json}`).then( let selection = data.find(i => this.selectionIsValid(i));
json => this.onSelectionRequest(json.data), if (selection) return selection;
() => this.onSelectionRequest(null) }
);
if (this.url) {
let where = {};
if (this.multiple)
where[this.valueField] = {inq: this.field};
else
where[this.valueField] = this._field;
let filter = {
fields: this.$.dropDown.getFields(),
where: where
};
let json = encodeURIComponent(JSON.stringify(filter));
this.$http.get(`${this.url}?filter=${json}`).then(
json => this.onSelectionRequest(json.data),
() => this.onSelectionRequest()
);
}
return null;
} }
onSelectionRequest(data) { onSelectionRequest(data) {
@ -157,12 +161,8 @@ export default class Autocomplete extends Input {
this.selection = data; this.selection = data;
else else
this.selection = data[0]; this.selection = data[0];
} else { } else
let selection = {}; this.selection = null;
selection[this.showField] = this._field;
selection[this.valueField] = this._field;
this.selection = selection;
}
} }
refreshDisplayed() { refreshDisplayed() {

View File

@ -1,74 +1,58 @@
import './autocomplete.js';
import template from './autocomplete.html';
describe('Component vnAutocomplete', () => { describe('Component vnAutocomplete', () => {
let $element; let $element;
let $scope; let $ctrl;
let $httpBackend;
let controller;
let data = {id: 1, name: 'Bruce Wayne'}; let data = {id: 1, name: 'Bruce Wayne'};
beforeEach(() => { beforeEach(ngModule('vnCore'));
angular.mock.module('client');
});
beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$httpBackend_, _$timeout_) => { beforeEach(angular.mock.inject(($compile, $rootScope) => {
$scope = $rootScope.$new(); $element = $compile(`<vn-autocomplete></vn-autocomplete>`)($rootScope);
$element = angular.element(`<div>${template}</div>`); $ctrl = $element.controller('vnAutocomplete');
$httpBackend = _$httpBackend_;
$httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({});
controller = _$componentController_('vnAutocomplete', {$element, $scope, $httpBackend, $transclude: null});
})); }));
describe('url() setter', () => { afterEach(() => {
it(`should set url controllers property and call refreshSelection`, () => { $element.remove();
spyOn(controller, "refreshSelection"); });
controller.url = "url";
expect(controller.url).toEqual("url"); describe('url() setter', () => {
expect(controller.refreshSelection).toHaveBeenCalledWith(); it(`should set the url property`, () => {
$ctrl.url = '/TestModels';
expect($ctrl.url).toEqual('/TestModels');
}); });
}); });
describe('field() setter/getter', () => { describe('field() setter/getter', () => {
it(`should set field controllers property`, () => { it(`should set the field property`, () => {
controller.field = data.id; $ctrl.field = 'id';
expect(controller.field).toEqual(data.id); expect($ctrl.field).toEqual('id');
}); });
});
describe('selection property', () => {
it(`should set selection finding an existing item in the initialData property`, () => { it(`should set selection finding an existing item in the initialData property`, () => {
controller.valueField = 'id'; $ctrl.initialData = data;
controller.showField = 'name'; $ctrl.field = data.id;
controller.initialData = data;
controller.field = data.id;
expect(controller.selection).toEqual(data); expect($ctrl.selection).toEqual(data);
}); });
it(`should set selection finding an existing item in the data property`, () => { it(`should set selection finding an existing item in the data property`, () => {
controller.valueField = 'id'; $ctrl.data = [data];
controller.showField = 'name'; $ctrl.field = data.id;
controller.data = [data];
controller.field = data.id;
expect(controller.selection).toEqual(data); expect($ctrl.selection).toEqual(data);
}); });
it(`should set selection to null when can't find an existing item in the data property`, () => { it(`should set selection to null when can't find an existing item in the data property`, () => {
controller.valueField = 'id'; $ctrl.field = data.id;
controller.showField = 'name';
controller.field = data.id;
expect(controller.selection).toEqual(null); expect($ctrl.selection).toEqual(null);
}); });
it(`should perform a query if the item id isn't present in the data property`, () => { it(`should perform a query if the item id isn't present in the data property`, inject($httpBackend => {
controller.valueField = 'id'; $ctrl.url = '/TestModels';
controller.showField = 'name';
controller.url = 'localhost';
controller.field = data.id;
let filter = { let filter = {
fields: ['id', 'name'], fields: ['id', 'name'],
@ -76,10 +60,11 @@ describe('Component vnAutocomplete', () => {
}; };
let json = encodeURIComponent(JSON.stringify(filter)); let json = encodeURIComponent(JSON.stringify(filter));
$httpBackend.whenGET(`localhost?filter=${json}`).respond({}); $httpBackend.whenGET(`${$ctrl.url}?filter=${json}`).respond([data]);
$httpBackend.expectGET(`localhost?filter=${json}`); $ctrl.field = data.id;
controller.field = data.id;
$httpBackend.flush(); $httpBackend.flush();
});
expect($ctrl.selection).toEqual(data);
}));
}); });
}); });

View File

@ -20,6 +20,7 @@ export default class DropDown extends Component {
this.$filter = $filter; this.$filter = $filter;
this.valueField = 'id'; this.valueField = 'id';
this.showField = 'name';
this._search = undefined; this._search = undefined;
this._activeOption = -1; this._activeOption = -1;
this.showLoadMore = true; this.showLoadMore = true;

View File

@ -1,56 +1,32 @@
import './drop-down.js';
import template from './drop-down.html';
describe('Component vnDropDown', () => { describe('Component vnDropDown', () => {
let $componentController;
let $timeout;
let $element; let $element;
let $scope; let $ctrl;
let $httpBackend;
let $transitions;
let $q;
let $filter;
let controller;
beforeEach(() => { beforeEach(ngModule('vnCore'));
angular.mock.module('client');
});
beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$timeout_, _$httpBackend_, _$q_, _$filter_, _$transitions_) => { beforeEach(inject(($compile, $rootScope, $document) => {
$componentController = _$componentController_; $element = $compile(`<vn-drop-down></vn-drop-down>`)($rootScope);
$element = angular.element(`<div>${template}</div>`); $document.find('body').append($element);
$timeout = _$timeout_; $ctrl = $element.controller('vnDropDown');
$transitions = _$transitions_;
$q = _$q_;
$filter = _$filter_;
$scope = $rootScope.$new();
$httpBackend = _$httpBackend_;
$httpBackend.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({});
let popoverTemplate = require('../popover/popover.html');
let $popover = angular.element(`<div>${popoverTemplate}</div>`);
$scope.popover = $componentController('vnPopover', {$element: $popover, $scope, $timeout, $transitions});
$scope.popover.$postLink();
$scope.model = $componentController('vnRestModel', {$httpBackend, $q, $filter});
controller = $componentController('vnDropDown', {$element, $scope, $transclude: null, $timeout, $httpBackend, $translate: null});
controller.$postLink();
controller.parent = angular.element('<vn-parent></vn-parent>')[0];
})); }));
describe('show() method', () => { afterEach(() => {
it(`should define controllers _show using the value received as argument`, () => { $element.remove();
controller.show(); });
expect(controller.shown).toEqual(true); describe('show() method', () => {
it(`should enable the show property`, () => {
$ctrl.show();
expect($ctrl.shown).toEqual(true);
}); });
}); });
describe('hide() method', () => { describe('hide() method', () => {
it(`should define controllers _show using the value received as argument`, () => { it(`should disable the show property`, () => {
controller.hide(); $ctrl.hide();
expect(controller.shown).toEqual(false); expect($ctrl.shown).toEqual(false);
}); });
}); });
}); });

View File

@ -1,5 +1,7 @@
<div class="icon-menu"> <div class="icon-menu">
<button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored icon-menu__button" ng-click="$ctrl.onClick($event)"> <button
class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored icon-menu__button"
ng-click="$ctrl.onClick($event)">
<vn-label vn-none translate>{{::$ctrl.label}}</vn-label> <vn-label vn-none translate>{{::$ctrl.label}}</vn-label>
<vn-icon vn-none icon="{{::$ctrl.icon}}"></vn-icon> <vn-icon vn-none icon="{{::$ctrl.icon}}"></vn-icon>
<vn-icon vn-none class="icon-menu__arrow_down" icon="keyboard_arrow_down"></vn-icon> <vn-icon vn-none class="icon-menu__arrow_down" icon="keyboard_arrow_down"></vn-icon>

View File

@ -12,15 +12,13 @@ export default class IconMenu extends Input {
onClick(event) { onClick(event) {
event.preventDefault(); event.preventDefault();
if (this.onOpen) this.onOpen(); this.emit('open');
this.showDropDown(); this.showDropDown();
} }
onDropDownSelect(value) { onDropDownSelect(value) {
this.field = value; this.field = value;
this.emit('change', {value});
if (this.onChange)
this.onChange({value});
} }
showDropDown() { showDropDown() {

View File

@ -1,53 +1,40 @@
import './icon-menu.js';
describe('Component vnIconMenu', () => { describe('Component vnIconMenu', () => {
let $componentController; let $ctrl;
let controller;
let $element; let $element;
beforeEach(() => { beforeEach(ngModule('vnCore'));
angular.mock.module('ticket');
});
beforeEach(angular.mock.inject(_$componentController_ => { beforeEach(inject(($compile, $rootScope) => {
$componentController = _$componentController_; $element = $compile(`<vn-icon-menu></vn-icon-menu>`)($rootScope);
$element = angular.element(`<div class="shown"></div>`); $ctrl = $element.controller('vnIconMenu');
controller = $componentController('vnIconMenu', {$element: $element, $transclude: null});
})); }));
describe('getFields()', () => { afterEach(() => {
it(`should return an array with the fields selectables`, () => { $element.remove();
let fields = controller.getFields();
expect(fields).toEqual(['id', 'name']);
});
}); });
describe('onClick(event)', () => { describe('onClick(event)', () => {
it(`should call preventDefault, onOpen and showDropdown`, () => { it(`should emit the open event`, () => {
let event = {preventDefault: () => {}}; spyOn($ctrl, 'emit');
controller.onOpen = () => {};
spyOn(event, 'preventDefault');
spyOn(controller, 'showDropDown');
spyOn(controller, 'onOpen');
controller.onClick(event); let event = new MouseEvent('click', {
view: $ctrl.element.window,
bubbles: true,
cancelable: true
});
$ctrl.onClick(event);
expect(event.preventDefault).toHaveBeenCalledWith(); expect($ctrl.emit).toHaveBeenCalledWith('open');
expect(controller.showDropDown).toHaveBeenCalledWith();
expect(controller.onOpen).toHaveBeenCalledWith();
}); });
}); });
describe('onDropDownSelect(value)', () => { describe('onDropDownSelect(value)', () => {
it(`should set field to a given value and call onChange`, () => { it(`should set field to the given value and emit the change event`, () => {
controller.onChange = () => {}; spyOn($ctrl, 'emit');
spyOn(controller, 'onChange'); $ctrl.onDropDownSelect('mariano');
controller.onDropDownSelect('mariano'); expect($ctrl.field).toBe('mariano');
expect($ctrl.emit).toHaveBeenCalledWith('change', {value: 'mariano'});
expect(controller.field).toBe('mariano');
expect(controller.onChange).toHaveBeenCalledWith({value: 'mariano'});
}); });
}); });
}); });

View File

@ -64,8 +64,8 @@ export default class Popover extends Component {
} }
/** /**
* Shows the popover. If a parent is specified it is shown in a visible * Shows the popover emitting the open signal. If a parent is specified
* relative position to it. * it is shown in a visible relative position to it.
* *
* @param {HTMLElement} parent Overrides the parent property * @param {HTMLElement} parent Overrides the parent property
*/ */
@ -90,7 +90,7 @@ export default class Popover extends Component {
} }
/** /**
* Hides the popover. * Hides the popover emitting the close signal.
*/ */
hide() { hide() {
if (!this._shown) return; if (!this._shown) return;

View File

@ -1,83 +1,83 @@
import './popover';
describe('Component vnPopover', () => { describe('Component vnPopover', () => {
let $componentController;
let $httpBackend;
let $timeout;
let $element; let $element;
let controller; let $parent;
let $ctrl;
beforeEach(() => { beforeEach(ngModule('vnCore'));
angular.mock.module('client');
});
beforeEach(angular.mock.inject((_$componentController_, _$httpBackend_, _$timeout_) => { beforeEach(inject(($compile, $rootScope, $document) => {
$componentController = _$componentController_; $element = $compile(`<vn-popover>Test</vn-popover>`)($rootScope);
$timeout = _$timeout_; $document.find('body').append($element);
$element = angular.element(`<div class="shown"></div>`); $ctrl = $element.controller('vnPopover');
$httpBackend = _$httpBackend_;
_$httpBackend_.when('GET', /\/locale\/\w+\/[a-z]{2}\.json/).respond({}); $parent = angular.element('<div/>');
controller = $componentController('vnPopover', {$httpBackend, $element}); $document.find('body').append($parent);
})); }));
afterEach(() => {
$element.remove();
$parent.remove();
});
describe('show()', () => { describe('show()', () => {
it(`should do nothing if _shown is defined in the controller`, () => { it(`should enable the shown property and emit the open event`, () => {
controller._shown = true; spyOn($ctrl, 'emit');
$ctrl.show();
spyOn(controller, 'relocate'); expect($ctrl.shown).toBeTruthy();
expect($ctrl.emit).toHaveBeenCalledWith('open');
controller.show();
expect(controller.relocate).not.toHaveBeenCalledWith();
}); });
it(`should not call on onOpen() as it is not defined in the controller`, () => { it(`should do nothing if it's already shown`, () => {
controller.show(); $ctrl.shown = true;
spyOn($ctrl, 'emit');
$ctrl.show();
expect(controller.onOpen).toBeUndefined(); expect($ctrl.emit).not.toHaveBeenCalledWith('open');
}); });
it(`should call onOpen() if its defined`, () => { it(`should check that popover is visible into the screen`, () => {
controller.onOpen = () => {}; $parent.css({
backgroundColor: 'red',
position: 'absolute',
width: '50px',
height: '50px',
top: '0',
left: '100px'
});
$ctrl.show($parent[0]);
spyOn(controller, 'onOpen'); let rect = $ctrl.popover.getBoundingClientRect();
let style = window.getComputedStyle($ctrl.element);
controller.show(); expect(style.visibility).toEqual('visible');
expect(style.display).not.toEqual('none');
expect(controller.onOpen).toHaveBeenCalledWith(); expect(0).toBeLessThanOrEqual(rect.top);
expect(0).toBeLessThanOrEqual(rect.left);
expect($ctrl.window.innerHeight).toBeGreaterThan(rect.bottom);
expect($ctrl.window.innerWidth).toBeGreaterThan(rect.right);
}); });
}); });
describe('hide()', () => { describe('hide()', () => {
it(`should do nothing if _shown is defined in the controller`, () => { it(`should disable the shown property and emit the close event`, inject($timeout => {
controller._shown = false; $ctrl.show();
spyOn($ctrl, 'emit');
controller.hide(); $ctrl.hide();
expect($element[0].classList).toContain('shown');
});
it(`should set _shown property to false and then call onClose() if its defined`, () => {
controller._shown = true;
controller.onClose = () => {};
spyOn(controller, 'onClose');
controller.hide();
$timeout.flush(); $timeout.flush();
expect(controller._shown).toBeFalsy(); expect($ctrl.shown).toBeFalsy();
expect(controller.onClose).toHaveBeenCalledWith(); expect($ctrl.emit).toHaveBeenCalledWith('close');
}); }));
it(`should set _shown property to false and then call deregisterCallback() if its defined`, () => { it(`should do nothing if it's already hidden`, () => {
controller._shown = true; $ctrl.shown = false;
controller.deregisterCallback = () => {}; spyOn($ctrl, 'emit');
spyOn(controller, 'deregisterCallback'); $ctrl.hide();
controller.hide(); expect($ctrl.emit).not.toHaveBeenCalledWith('close');
expect(controller._shown).toBeFalsy();
expect(controller.deregisterCallback).toHaveBeenCalledWith();
}); });
}); });
}); });

View File

@ -85,6 +85,8 @@ describe('Salix', () => {
it('should make a query with the property given and call showOk', () => { it('should make a query with the property given and call showOk', () => {
spyOn(controller, 'showOk'); spyOn(controller, 'showOk');
controller.company = 1; controller.company = 1;
$httpBackend.when('GET', `/api/UserConfigs/getUserConfig`).respond({companyFk: 2});
$httpBackend.expect('GET', `/api/UserConfigs/getUserConfig`);
$httpBackend.when('POST', `/api/UserConfigs/setUserConfig`, {companyFk: 1}).respond(200); $httpBackend.when('POST', `/api/UserConfigs/setUserConfig`, {companyFk: 1}).respond(200);
$httpBackend.expect('POST', `/api/UserConfigs/setUserConfig`, {companyFk: 1}); $httpBackend.expect('POST', `/api/UserConfigs/setUserConfig`, {companyFk: 1});
controller.setUserConfig('companyFk'); controller.setUserConfig('companyFk');

View File

@ -87,8 +87,8 @@ function $exceptionHandler(vnApp, $window) {
} else if (exception.name == 'UserError') { } else if (exception.name == 'UserError') {
message = exception.message; message = exception.message;
} else { } else {
message = 'Ups! Something went wrong'; vnApp.showError('Ups! Something went wrong');
console.error(exception); throw exception;
} }
vnApp.showError(message); vnApp.showError(message);

View File

@ -2,5 +2,24 @@
// current directory and all subdirectories // current directory and all subdirectories
import 'angular'; import 'angular';
import 'angular-mocks'; import 'angular-mocks';
window.inject = angular.mock.inject;
window.ngModule = function(moduleName) {
return angular.mock.module(moduleName, function($provide, $translateProvider) {
// To avoid unexpected request warnings caused by angular translate
// https://angular-translate.github.io/docs/#/guide/22_unit-testing-with-angular-translate
$provide.factory('customLocaleLoader', function($q) {
return function() {
let deferred = $q.defer();
deferred.resolve({});
return deferred.promise;
};
});
$translateProvider.useLoader('customLocaleLoader');
});
};
var testsContext = require.context('./', true, /\.spec\.js$/); var testsContext = require.context('./', true, /\.spec\.js$/);
testsContext.keys().forEach(testsContext); testsContext.keys().forEach(testsContext);

View File

@ -77,40 +77,31 @@ module.exports = function(config) {
'karma-chrome-launcher', 'karma-chrome-launcher',
'karma-firefox-launcher', 'karma-firefox-launcher',
'karma-sourcemap-loader' 'karma-sourcemap-loader'
] ],
customLaunchers: {
FirefoxHeadless: {
base: 'Firefox',
flags: ['-headless']
},
ChromeNoSandboxHeadless: {
base: 'Chrome',
flags: [
'--no-sandbox',
// See https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md
'--headless',
'--disable-gpu',
// Without a remote debugging port, Google Chrome exits immediately.
' --remote-debugging-port=9222'
]
}
}
}; };
let browserConfig; if (process.env.FIREFOX_BIN)
baseConfig.browsers = ['FirefoxHeadless'];
else
baseConfig.browsers = ['ChromeNoSandboxHeadless'];
if (process.env.FIREFOX_BIN) {
browserConfig = {
browsers: ['FirefoxHeadless'],
customLaunchers: {
FirefoxHeadless: {
base: 'Firefox',
flags: ['-headless']
}
}
};
} else {
browserConfig = {
browsers: ['ChromeNoSandboxHeadless'],
customLaunchers: {
ChromeNoSandboxHeadless: {
base: 'Chrome',
flags: [
'--no-sandbox',
// See https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md
'--headless',
'--disable-gpu',
// Without a remote debugging port, Google Chrome exits immediately.
' --remote-debugging-port=9222'
]
}
}
};
}
Object.assign(baseConfig, browserConfig);
config.set(baseConfig); config.set(baseConfig);
}; };

7159
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -16,4 +16,4 @@
"dependencies": { "dependencies": {
"vn-loopback": "file:../loopback" "vn-loopback": "file:../loopback"
} }
} }