merge
This commit is contained in:
commit
df03a41a68
|
@ -43,11 +43,35 @@ node
|
|||
|
||||
stage ("Stopping/Removing Docker")
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
<<<<<<< HEAD
|
||||
step{
|
||||
env.TAG = env.BUILD_NUMBER - 1;
|
||||
sh "docker-compose down --rmi 'all'"
|
||||
=======
|
||||
environment {
|
||||
env.BUILD_TAG = env.BUILD_NUMBER - 1;
|
||||
>>>>>>> 1acfdf5950d33f4bf972dc2830e05d2f2b1ba99a
|
||||
}
|
||||
>>>>>>> e47138eda088c8d307f58d42cc34cbde7295946f
|
||||
sh "docker-compose down --rmi 'all'"
|
||||
}
|
||||
|
||||
stage ("Generar dockers")
|
||||
{
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
<<<<<<< HEAD
|
||||
step{
|
||||
env.TAG = env.BUILD_NUMBER + 1;
|
||||
sh "docker-compose up -d --build"
|
||||
=======
|
||||
environment {
|
||||
env.BUILD_TAG = env.BUILD_NUMBER;
|
||||
>>>>>>> 1acfdf5950d33f4bf972dc2830e05d2f2b1ba99a
|
||||
}
|
||||
>>>>>>> e47138eda088c8d307f58d42cc34cbde7295946f
|
||||
sh "docker-compose up -d --build"
|
||||
}
|
||||
}
|
||||
|
|
62
README.md
62
README.md
|
@ -1,53 +1,67 @@
|
|||
# Project Title
|
||||
|
||||
One Paragraph of project description goes here
|
||||
Salix is an Enterprise resource planning (ERP) integrated management of core business processes, in real-time and mediated by software and technology developed with the stack listed below.
|
||||
|
||||
Salix is also the scientific name of a beautifull tree! :)
|
||||
|
||||
### Prerequisites
|
||||
|
||||
For testing purposes you will need to install globally the following items:
|
||||
npm install -g karma
|
||||
npm install -g karma-cli
|
||||
|
||||
## Getting Started // ### Installing
|
||||
|
||||
Pull from repo.
|
||||
|
||||
install nodejs v6 or above.
|
||||
You will need to install globally the following items:
|
||||
$ npm install -g karma
|
||||
$ npm install -g karma-cli
|
||||
$ npm install -g gulp
|
||||
$ npm install -g webpack
|
||||
$ npm install -g nodemon
|
||||
|
||||
install nginx globally.
|
||||
|
||||
Ask a senior dev for the datasources.development.json files required to run the project.
|
||||
## Getting Started // ### Installing
|
||||
|
||||
Pull from repository.
|
||||
|
||||
install nodejs v6.
|
||||
|
||||
Ask a senior developer for the datasources.development.json files required to run the project.
|
||||
|
||||
on root run:
|
||||
npm install
|
||||
gulp install
|
||||
$ npm install
|
||||
$ gulp install
|
||||
|
||||
lauching nginx:
|
||||
./dev.sh
|
||||
$ ./dev.sh
|
||||
|
||||
launching frontend:
|
||||
gulp client
|
||||
$ gulp client
|
||||
or start nginx before client on sequence
|
||||
$ gulp clientDev
|
||||
|
||||
launching backend:
|
||||
gulp services
|
||||
$ gulp services
|
||||
or start the local database before services on sequence
|
||||
$ gulp serivcesDev
|
||||
|
||||
Manually reset local fixtures:
|
||||
$ gulp docker
|
||||
|
||||
to check docker images and containers status:
|
||||
$ docker images
|
||||
$ docker ps -a
|
||||
|
||||
## Running the tests
|
||||
|
||||
for client-side unit tests run from project's root:
|
||||
karma start
|
||||
$ karma start
|
||||
|
||||
for server-side unit tests run from project's root:
|
||||
npm run testWatch or test for single run
|
||||
$ npm run test
|
||||
|
||||
### Break down into end to end tests
|
||||
|
||||
on root run:
|
||||
Run local database plus e2e paths:
|
||||
$ gulp e2e
|
||||
|
||||
gulp docker
|
||||
|
||||
wait 10 secs for db to be ready
|
||||
|
||||
npm run e2e
|
||||
Just the e2e paths as the fixtures are untainted:
|
||||
$ npm run e2e
|
||||
|
||||
## Built With
|
||||
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
</vn-auto>
|
||||
<vn-auto pad-medium>
|
||||
<vn-vertical>
|
||||
<vn-horizontal ng-repeat="(field, title) in $ctrl.fieldsToShow" ng-if="$ctrl.client[field]">
|
||||
<vn-horizontal ng-repeat="(field, title) in $ctrl.fieldsToShow">
|
||||
<strong vn-auto>{{::title}}:</strong>
|
||||
<vn-auto margin-small-left>
|
||||
<span ng-if="field.includes('credit')">{{$ctrl.client[field] | number:2}} €</span>
|
||||
<span ng-if="!field.includes('credit')">{{::$ctrl.client[field]}}</span>
|
||||
<span ng-if="field.includes('credit')">{{$ctrl.client[field] || 0 | number:2}} €</span>
|
||||
<span ng-if="!field.includes('credit')">{{$ctrl.client[field]}}</span>
|
||||
</vn-auto>
|
||||
</vn-horizontal>
|
||||
</vn-vertical>
|
||||
|
|
|
@ -5,13 +5,19 @@
|
|||
form="form"
|
||||
save="post">
|
||||
</vn-watcher>
|
||||
<form pad-medium ng-submit="$ctrl.onSubmit()">
|
||||
|
||||
<form pad-medium name="form" ng-submit="$ctrl.onSubmit()">
|
||||
<vn-card>
|
||||
<vn-vertical pad-medium>
|
||||
<vn-title vn-one margin-large-bottom>Add Greuge</vn-title>
|
||||
<vn-horizontal>
|
||||
<vn-textfield vn-one margin-medium-right label="Importe" field="$ctrl.greuge.amount" type="number" vn-focus></vn-textfield>
|
||||
<vn-date-picker vn-one label="Date" model="$ctrl.greuge.shipped"></vn-date-picker>
|
||||
<vn-textfield vn-one margin-medium-right label="Amount" field="$ctrl.greuge.amount" type="number" step="1" vn-focus></vn-textfield>
|
||||
<vn-date-picker vn-one
|
||||
label="Date"
|
||||
model="$ctrl.greuge.shipped"
|
||||
ini-options="{enableTime: true, dateFormat: 'd-m-Y h:i', time_24hr: true}"
|
||||
>
|
||||
</vn-date-picker>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-textfield vn-one margin-medium-right label="Comment" field="$ctrl.greuge.description"></vn-textfield>
|
||||
|
|
|
@ -5,7 +5,7 @@ class ClientGreugeCreate {
|
|||
this.$ = $scope;
|
||||
this.$state = $state;
|
||||
this.greuge = {
|
||||
shipped: $filter('date')(new Date(), 'yyyy-MM-dd')
|
||||
shipped: $filter('date')(new Date(), 'yyyy-MM-dd HH:mm')
|
||||
};
|
||||
}
|
||||
onSubmit() {
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
import './greuge-create.js';
|
||||
|
||||
describe('Client', () => {
|
||||
describe('Component vnClientGreugeCreate', () => {
|
||||
let $componentController;
|
||||
let $scope;
|
||||
let $state;
|
||||
let controller;
|
||||
|
||||
beforeEach(() => {
|
||||
angular.mock.module('client');
|
||||
});
|
||||
|
||||
beforeEach(angular.mock.inject((_$componentController_, $rootScope, _$state_) => {
|
||||
$componentController = _$componentController_;
|
||||
$scope = $rootScope.$new();
|
||||
$state = _$state_;
|
||||
$scope.watcher = {
|
||||
submit: () => {
|
||||
return {
|
||||
then: callback => {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
controller = $componentController('vnClientGreugeCreate', {$scope: $scope});
|
||||
}));
|
||||
|
||||
describe('onSubmit()', () => {
|
||||
it('should call the function go() on $state to go to the greuges list', () => {
|
||||
spyOn($state, 'go');
|
||||
controller.onSubmit();
|
||||
|
||||
expect(controller.$state.go).toHaveBeenCalledWith('clientCard.greuge.list');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -20,5 +20,6 @@
|
|||
"Credit" : "Crédito",
|
||||
"Secured credit": "Crédito asegurado",
|
||||
"Verified data": "Datos comprobados",
|
||||
"Mandate": "Mandato"
|
||||
"Mandate": "Mandato",
|
||||
"Amount": "Importe"
|
||||
}
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
<vn-vertical ng-click="$ctrl.showDropDown = true">
|
||||
<vn-textfield vn-auto label="{{$ctrl.label}}" model="$ctrl.displayValue" readonly="$ctrl.readonly"></vn-textfield>
|
||||
<vn-vertical ng-click="$ctrl.showDropDown = true" tabindex="0">
|
||||
<vn-textfield vn-auto
|
||||
label="{{$ctrl.label}}"
|
||||
model="$ctrl.displayValue"
|
||||
readonly="$ctrl.readonly"
|
||||
tab-index="-1"
|
||||
>
|
||||
</vn-textfield>
|
||||
<vn-drop-down vn-auto
|
||||
items="$ctrl.items"
|
||||
show="$ctrl.showDropDown"
|
||||
|
|
|
@ -25,6 +25,9 @@ ul.vn-autocomplete {
|
|||
}
|
||||
vn-autocomplete {
|
||||
position: relative;
|
||||
vn-vertical {
|
||||
outline:none;
|
||||
}
|
||||
|
||||
.mdl-chip__action {
|
||||
position: absolute;
|
||||
|
|
|
@ -30,6 +30,7 @@ class DatePicker extends Component {
|
|||
this._modelView = null;
|
||||
this._model = undefined;
|
||||
this._optionsChecked = false;
|
||||
this._waitingInit = 0;
|
||||
this.hasFocus = false;
|
||||
this.hasMouseIn = false;
|
||||
componentHandler.upgradeElement($element[0].firstChild);
|
||||
|
@ -39,12 +40,34 @@ class DatePicker extends Component {
|
|||
return this._model;
|
||||
}
|
||||
set model(value) {
|
||||
if (this._optionsChecked) {
|
||||
this._waitingInit = 0;
|
||||
this._model = value;
|
||||
if (value && !this.modelView) {
|
||||
let options = this._getOptions();
|
||||
let initialDateFormat = (options && options.dateFormat) ? options.dateFormat : 'Y-m-d';
|
||||
let initialDateFormat;
|
||||
if (options && options.dateFormat) {
|
||||
initialDateFormat = options.dateFormat;
|
||||
} else {
|
||||
initialDateFormat = this.$translate.use() === 'es' ? 'd-m-Y' : 'Y-m-d';
|
||||
if (options.enableTime) {
|
||||
initialDateFormat += ' H:i:s';
|
||||
}
|
||||
}
|
||||
|
||||
let format = this._formatFlat2Angular(initialDateFormat);
|
||||
this.modelView = this.$filter('date')(value, format);
|
||||
this._modelView = this.$filter('date')(new Date(this._model), format);
|
||||
this.mdlUpdate();
|
||||
}
|
||||
} else if (this._waitingInit < 4) {
|
||||
this._waitingInit++;
|
||||
this.$timeout(() => {
|
||||
this.model = value;
|
||||
}, 250);
|
||||
} else {
|
||||
this.model = null;
|
||||
this.modelView = '';
|
||||
this._waitingInit = 0;
|
||||
}
|
||||
}
|
||||
get modelView() {
|
||||
|
@ -54,10 +77,9 @@ class DatePicker extends Component {
|
|||
this._modelView = value;
|
||||
this.input.value = value;
|
||||
this._setModel(value);
|
||||
this.$timeout(() => {
|
||||
this.mdlUpdate();
|
||||
}, 500);
|
||||
}
|
||||
|
||||
onClear() {
|
||||
this.modelView = null;
|
||||
}
|
||||
|
@ -67,9 +89,11 @@ class DatePicker extends Component {
|
|||
}
|
||||
}
|
||||
mdlUpdate() {
|
||||
this.$timeout(() => {
|
||||
let mdlField = this.element.firstChild.MaterialTextfield;
|
||||
if (mdlField)
|
||||
mdlField.updateClasses_();
|
||||
}, 500);
|
||||
}
|
||||
|
||||
_formatFlat2Angular(string) { // change string Flatpickr format to angular format (d-m-Y -> dd-MM-yyyy)
|
||||
|
@ -90,13 +114,7 @@ class DatePicker extends Component {
|
|||
return parts.join('-');
|
||||
}
|
||||
|
||||
_setModel(value) {
|
||||
let model;
|
||||
if (!value) {
|
||||
model = undefined;
|
||||
} else if (!this.iniOptions || (this.iniOptions.dateFormat && this.iniOptions.dateFormat.startsWith('Y-m-d'))) {
|
||||
model = value;
|
||||
} else {
|
||||
_string2BackFormat(value) {
|
||||
let formats = this.iniOptions.dateFormat.split(/[ZT.,/ :-]/);
|
||||
let aux = value.split(/[ZT.,/ :-]/);
|
||||
let date = {};
|
||||
|
@ -137,7 +155,18 @@ class DatePicker extends Component {
|
|||
hourStr += ':00';
|
||||
}
|
||||
}
|
||||
model = `${dateStr} ${hourStr}`.trim();
|
||||
return `${dateStr} ${hourStr}`.trim();
|
||||
}
|
||||
|
||||
_setModel(value) {
|
||||
let model;
|
||||
let options = this._getOptions();
|
||||
if (!value) {
|
||||
model = undefined;
|
||||
} else if (!options || (options.dateFormat && options.dateFormat.startsWith('Y-m-d'))) {
|
||||
model = value;
|
||||
} else {
|
||||
model = this._string2BackFormat(value);
|
||||
}
|
||||
|
||||
if (this.model !== model) {
|
||||
|
@ -155,8 +184,8 @@ class DatePicker extends Component {
|
|||
if (!this.iniOptions.locale)
|
||||
this.iniOptions.locale = this.$translate.use();
|
||||
|
||||
if (!this.iniOptions.dateFormat && this.iniOptions.locale === 'es')
|
||||
this.iniOptions.dateFormat = 'd-m-Y';
|
||||
if (!this.iniOptions.dateFormat)
|
||||
this.iniOptions.dateFormat = this.iniOptions.locale === 'es' ? 'd-m-Y' : 'Y-m-d';
|
||||
else if (this.iniOptions.dateFormat) {
|
||||
let format = this.iniOptions.dateFormat.split(/[ZT.,/ :-]/);
|
||||
if (format.length <= 1) {
|
||||
|
@ -193,6 +222,12 @@ class DatePicker extends Component {
|
|||
this.vp = undefined;
|
||||
}
|
||||
|
||||
$onChanges(objChange) {
|
||||
if (objChange.iniOptions && objChange.iniOptions.currentValue) {
|
||||
this.iniOptions = Object.assign(this.iniOptions, objChange.iniOptions.currentValue);
|
||||
}
|
||||
}
|
||||
|
||||
$onInit() {
|
||||
this.initPicker();
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ describe('Component vnDatePicker', () => {
|
|||
|
||||
it(`should split the given string into parts`, () => {
|
||||
controller.iniOptions = {dateFormat: 'd/m/Y'};
|
||||
controller._optionsChecked = true;
|
||||
controller.model = '2017-12-23';
|
||||
|
||||
expect(controller.modelView).toBe('23-12-2017');
|
||||
|
|
|
@ -29,7 +29,6 @@ export function directive(interpolate, compile, $window) {
|
|||
throw new Error(`vnValidation: Entity '${entityName}' doesn't exist`);
|
||||
|
||||
let validations = entity.validations[fieldName];
|
||||
|
||||
if (!validations || validations.length == 0)
|
||||
return;
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
</vn-auto>
|
||||
<vn-auto>
|
||||
<ul class="dropdown">
|
||||
<li tabIndex="-1"
|
||||
<li
|
||||
ng-repeat="item in $ctrl.itemsFiltered track by $index"
|
||||
ng-click="$ctrl.selectItem(item)"
|
||||
ng-class="{'active': $index === $ctrl.activeOption, 'checked': item.checked}"
|
||||
|
@ -19,7 +19,6 @@
|
|||
<li
|
||||
ng-if="$ctrl.loadMore&&!$ctrl.removeLoadMore"
|
||||
class="dropdown__loadMore"
|
||||
tabIndex="-1"
|
||||
ng-class="{'active': $ctrl.itemsFiltered.length === $ctrl.activeOption, 'noMore' : !$ctrl.showLoadMore}"
|
||||
ng-click="$ctrl.loadItems()"
|
||||
translate="{{$ctrl.showLoadMore ? 'Show More' : 'No more results'}}"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import {module} from '../module';
|
||||
import './style.scss';
|
||||
import validKey from '../lib/keyCodes';
|
||||
|
||||
export default class DropDown {
|
||||
constructor($element, $filter, $timeout) {
|
||||
|
@ -29,6 +30,9 @@ export default class DropDown {
|
|||
this.$timeout(() => {
|
||||
this._tryToShow++;
|
||||
this.show = true;
|
||||
if (this.activeOption === -1) {
|
||||
this.activeOption = 0;
|
||||
}
|
||||
}, 250);
|
||||
} else {
|
||||
this._tryToShow = 0;
|
||||
|
@ -70,26 +74,27 @@ export default class DropDown {
|
|||
}
|
||||
|
||||
_toggleDropDown(value, oldValue) {
|
||||
if (value && !this._focusingFilter && !oldValue && this.filter) {
|
||||
// open dropDown
|
||||
this.$timeout(() => { // wait angular ngIf
|
||||
this._setFocusInFilterInput();
|
||||
this._eventScroll(value);
|
||||
});
|
||||
} else if (!value && oldValue) {
|
||||
// close dropDown
|
||||
this._eventScroll(value);
|
||||
}
|
||||
|
||||
this.$timeout(() => {
|
||||
this._eventScroll(value);
|
||||
this._calculatePosition(value, oldValue);
|
||||
});
|
||||
}
|
||||
|
||||
_eventScroll(add) {
|
||||
_eventScroll(add, num) {
|
||||
let count = num || 0;
|
||||
if (add) {
|
||||
if (this.container) {
|
||||
this.container.addEventListener('scroll', e => this.loadFromScroll(e));
|
||||
} else {
|
||||
// this.$timeout(() => { // falla al entrar por primera vez xq pierde el foco y cierra el dropdown
|
||||
// this._setFocusInFilterInput();
|
||||
// });
|
||||
} else if (count < 4) {
|
||||
count++;
|
||||
this.$timeout(() => { // wait angular ngIf
|
||||
this._eventScroll(add, count);
|
||||
}, 250);
|
||||
}
|
||||
} else if (this.container) {
|
||||
this.container.removeEventListener('scroll', e => this.loadFromScroll(e));
|
||||
}
|
||||
}
|
||||
|
@ -169,43 +174,43 @@ export default class DropDown {
|
|||
|
||||
onKeydown(event) {
|
||||
if (this.show) {
|
||||
switch (event.keyCode) {
|
||||
case 13: // Enter
|
||||
if (event.keyCode === 13) { // Enter
|
||||
this.$timeout(() => {
|
||||
this.selectOption();
|
||||
});
|
||||
event.preventDefault();
|
||||
break;
|
||||
case 27: // Escape
|
||||
} else if (event.keyCode === 27) { // Escape
|
||||
this.clearSearch();
|
||||
break;
|
||||
case 38: // Arrow up
|
||||
} else if (event.keyCode === 38) { // Arrow up
|
||||
this.activeOption--;
|
||||
this.$timeout(() => {
|
||||
this.setScrollPosition();
|
||||
}, 100);
|
||||
break;
|
||||
case 40: // Arrow down
|
||||
} else if (event.keyCode === 40) { // Arrow down
|
||||
this.activeOption++;
|
||||
this.$timeout(() => {
|
||||
this.setScrollPosition();
|
||||
}, 100);
|
||||
break;
|
||||
case 35: // End
|
||||
} else if (event.keyCode === 35) { // End
|
||||
this.activeOption = this.itemsFiltered.length - 1;
|
||||
this.$timeout(() => {
|
||||
this.setScrollPosition();
|
||||
}, 100);
|
||||
break;
|
||||
case 36: // Start
|
||||
} else if (event.keyCode === 36) { // Start
|
||||
this.activeOption = 0;
|
||||
this.$timeout(() => {
|
||||
this.setScrollPosition();
|
||||
}, 100);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
} else if (this.filter) {
|
||||
let oldValue = this.search || '';
|
||||
if (validKey(event)) {
|
||||
this.search = oldValue + String.fromCharCode(event.keyCode);
|
||||
} else if (event.keyCode === 8) { // backSpace
|
||||
this.search = oldValue.slice(0, -1);
|
||||
}
|
||||
} /* else {
|
||||
console.error(`Error: keyCode ${event.keyCode} not supported`);
|
||||
} */
|
||||
}
|
||||
}
|
||||
setScrollPosition() {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {module} from '../module';
|
||||
|
||||
const isFullEmpty = item => {
|
||||
return (!item && item !== 0) || (typeof item === 'object' && !Object.keys(item).length);
|
||||
return (item === null || item === undefined) || (typeof item === 'object' && !Object.keys(item).length);
|
||||
};
|
||||
|
||||
export default isFullEmpty;
|
||||
|
|
|
@ -14,3 +14,4 @@ export {NAME as INTERPOLATE, Interpolate} from './interpolate';
|
|||
export {NAME as COPY_OBJECT} from './copy';
|
||||
export {NAME as EQUALS_OBJECT} from './equals';
|
||||
export {NAME as GET_DATA_MODIFIED, factory as Modified} from './modified';
|
||||
export {NAME as VALID_KEY} from './keyCodes';
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import {module} from '../module';
|
||||
|
||||
const validKey = key => {
|
||||
let keycode = key.keyCode || key;
|
||||
|
||||
let valid =
|
||||
(keycode > 47 && keycode < 58) || // number keys
|
||||
(keycode > 64 && keycode < 91) || // letter keys
|
||||
(keycode > 95 && keycode < 112) || // numpad keys
|
||||
(keycode > 185 && keycode < 193) || // ;=,-./` (in order)
|
||||
(keycode > 218 && keycode < 223); // [\]' (in order)
|
||||
|
||||
return valid;
|
||||
};
|
||||
|
||||
export default validKey;
|
||||
|
||||
export const NAME = 'validKey';
|
||||
module.value(NAME, validKey);
|
|
@ -2,7 +2,7 @@ import {validator} from 'vendor';
|
|||
|
||||
export const validators = {
|
||||
presence: value => {
|
||||
if (validator.isEmpty(value))
|
||||
if (validator.isEmpty(value ? String(value) : ''))
|
||||
throw new Error(`Value can't be empty`);
|
||||
},
|
||||
absence: value => {
|
||||
|
@ -14,8 +14,8 @@ export const validators = {
|
|||
min: conf.min || conf.is,
|
||||
max: conf.max || conf.is
|
||||
};
|
||||
|
||||
if (!validator.isLength(value, options)) {
|
||||
let val = value ? String(value) : '';
|
||||
if (!validator.isLength(val, options)) {
|
||||
if (conf.is) {
|
||||
throw new Error(`Value should be ${conf.is} characters long`);
|
||||
} else if (conf.min && conf.max) {
|
||||
|
@ -74,7 +74,7 @@ export function validate(value, conf) {
|
|||
try {
|
||||
checkNull(value, conf);
|
||||
|
||||
if (validator && value != null)
|
||||
if (validator) // && value != null ??
|
||||
validator(value, conf);
|
||||
} catch (e) {
|
||||
let message = conf.message ? conf.message : e.message;
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
<div
|
||||
class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label"
|
||||
tabindex="1"
|
||||
ng-focus="$ctrl.hasFocus = true"
|
||||
ng-blur="$ctrl.hasFocus = false"
|
||||
ng-mouseenter="$ctrl.hasMouseIn = true"
|
||||
ng-mouseleave="$ctrl.hasMouseIn = false">
|
||||
<input
|
||||
|
@ -12,7 +9,10 @@
|
|||
ng-model="$ctrl.value"
|
||||
vn-validation="{{$ctrl.rule}}"
|
||||
ng-disabled="$ctrl.disabled"
|
||||
ng-readonly="$ctrl.readonly"/>
|
||||
ng-readonly="$ctrl.readonly"
|
||||
ng-focus="$ctrl.hasFocus = true"
|
||||
ng-blur="$ctrl.hasFocus = false"
|
||||
/>
|
||||
<div class="mdl-chip__action">
|
||||
<i class="material-icons"
|
||||
ng-if="$ctrl.hasInfo"
|
||||
|
|
|
@ -32,6 +32,9 @@ export default class Textfield extends Input {
|
|||
this.hasValue = Boolean(this._value);
|
||||
this.mdlUpdate();
|
||||
}
|
||||
set tabIndex(value) {
|
||||
this.input.tabIndex = value;
|
||||
}
|
||||
mdlUpdate() {
|
||||
let mdlField = this.$element[0].firstChild.MaterialTextfield;
|
||||
if (mdlField)
|
||||
|
@ -54,6 +57,7 @@ module.component('vnTextfield', {
|
|||
disabled: '<?',
|
||||
readonly: '<?',
|
||||
rule: '@?',
|
||||
type: '@?'
|
||||
type: '@?',
|
||||
tabIndex: '@?'
|
||||
}
|
||||
});
|
||||
|
|
|
@ -12,12 +12,13 @@ import isFullEmpty from '../lib/fullEmpty';
|
|||
* properties are provided.
|
||||
*/
|
||||
export default class Watcher extends Component {
|
||||
constructor($element, $scope, $state, $transitions, $http, vnApp, $translate) {
|
||||
constructor($element, $scope, $state, $transitions, $http, vnApp, $translate, $attrs) {
|
||||
super($element);
|
||||
this.$scope = $scope;
|
||||
this.$state = $state;
|
||||
this.$http = $http;
|
||||
this.$translate = $translate;
|
||||
this.$attrs = $attrs;
|
||||
this.vnApp = vnApp;
|
||||
|
||||
this.state = null;
|
||||
|
@ -93,10 +94,10 @@ export default class Watcher extends Component {
|
|||
(resolve, reject) => this.noChanges(reject)
|
||||
);
|
||||
}
|
||||
let changedData = getModifiedData(this.data, this.orgData);
|
||||
let changedData = (this.$attrs.save && this.$attrs.save.toLowerCase() === 'post') ? this.copyInNewObject(this.data) : getModifiedData(this.data, this.orgData);
|
||||
|
||||
if (this.save) {
|
||||
this.save.model = this.copyInNewObject(changedData);
|
||||
this.save.model = changedData; // this.copyInNewObject(changedData);
|
||||
return new Promise((resolve, reject) => {
|
||||
this.save.accept().then(
|
||||
json => this.writeData({data: json}, resolve),
|
||||
|
@ -180,6 +181,7 @@ export default class Watcher extends Component {
|
|||
}
|
||||
|
||||
dataChanged() {
|
||||
if (this.form && !this.form.$dirty) return false;
|
||||
let newData = this.copyInNewObject(this.data);
|
||||
return !isEqual(newData, this.orgData);
|
||||
}
|
||||
|
@ -194,7 +196,7 @@ export default class Watcher extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
Watcher.$inject = ['$element', '$scope', '$state', '$transitions', '$http', 'vnApp', '$translate'];
|
||||
Watcher.$inject = ['$element', '$scope', '$state', '$transitions', '$http', 'vnApp', '$translate', '$attrs'];
|
||||
|
||||
module.component('vnWatcher', {
|
||||
template: require('./watcher.html'),
|
||||
|
|
|
@ -11,6 +11,7 @@ describe('Component vnWatcher', () => {
|
|||
let vnApp;
|
||||
let $translate;
|
||||
let controller;
|
||||
let $attrs;
|
||||
|
||||
beforeEach(() => {
|
||||
angular.mock.module('client');
|
||||
|
@ -25,7 +26,10 @@ describe('Component vnWatcher', () => {
|
|||
$transitions = _$transitions_;
|
||||
$httpBackend = _$httpBackend_;
|
||||
$translate = _$translate_;
|
||||
controller = $componentController('vnWatcher', {$scope, $element, $state, vnApp, $transitions, $httpBackend, $translate});
|
||||
$attrs = {
|
||||
save: "patch"
|
||||
};
|
||||
controller = $componentController('vnWatcher', {$scope, $element, $state, vnApp, $transitions, $httpBackend, $translate, $attrs});
|
||||
}));
|
||||
|
||||
describe('$onInit()', () => {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
"module": "item",
|
||||
"name": "Items",
|
||||
"icon": "/static/images/icon_item.png",
|
||||
"validations" : true,
|
||||
"routes": [
|
||||
{
|
||||
"url": "/item",
|
||||
|
|
|
@ -9,16 +9,9 @@
|
|||
<div style="max-width: 70em; margin: 0 auto;">
|
||||
<vn-card>
|
||||
<vn-vertical pad-large>
|
||||
<vn-title>Create item</vn-title>
|
||||
<vn-horizontal>
|
||||
<vn-textfield vn-one label="Size" field="$ctrl.item.size" vn-focus></vn-textfield>
|
||||
<vn-textfield vn-five label="Category" field="$ctrl.item.category"></vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-textfield vn-one label="Stems" field="$ctrl.item.stems"></vn-textfield>
|
||||
<vn-textfield vn-five label="Description" field="$ctrl.item.description"></vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-title>New item</vn-title>
|
||||
<vn-horizontal>
|
||||
<vn-textfield vn-one label="Name" field="$ctrl.item.name" vn-focus></vn-textfield>
|
||||
<vn-autocomplete vn-one
|
||||
url="/item/api/ItemTypes"
|
||||
label="Type"
|
||||
|
@ -27,15 +20,21 @@
|
|||
field="$ctrl.item.typeFk"
|
||||
>
|
||||
</vn-autocomplete>
|
||||
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete vn-one
|
||||
url="/item/api/Inks"
|
||||
label="Ink"
|
||||
show-field="name"
|
||||
url="/item/api/Intrastats"
|
||||
label="Intrastat"
|
||||
show-field="description"
|
||||
value-field="id"
|
||||
field="$ctrl.item.inkFk"
|
||||
field="$ctrl.item.intrastatFk"
|
||||
order="description ASC"
|
||||
filter-search="{where: {description: {regexp: 'search'}} }"
|
||||
>
|
||||
<tpl-item>{{$parent.$parent.item.description}}</tpl-item>
|
||||
</vn-autocomplete>
|
||||
<vn-textfield vn-one label="Relevancy" field="$ctrl.item.relevancy" type="number"></vn-textfield>
|
||||
|
||||
</vn-horizontal>
|
||||
|
||||
<vn-horizontal>
|
||||
|
@ -45,18 +44,10 @@
|
|||
show-field="name"
|
||||
value-field="id"
|
||||
field="$ctrl.item.originFk"
|
||||
>
|
||||
</vn-autocomplete>
|
||||
|
||||
<vn-autocomplete vn-one
|
||||
url="/item/api/Producers"
|
||||
label="Producer"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
field="$ctrl.item.producerFk"
|
||||
>
|
||||
</vn-autocomplete>
|
||||
></vn-autocomplete>
|
||||
<vn-one></vn-one>
|
||||
</vn-horizontal>
|
||||
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
import ngModule from '../module';
|
||||
|
||||
class ItemCreate {
|
||||
constructor() {
|
||||
this.item = {};
|
||||
constructor($scope, $state) {
|
||||
this.$ = $scope;
|
||||
this.$state = $state;
|
||||
this.item = {
|
||||
relevancy: 0
|
||||
};
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
this.$.watcher.submit().then(
|
||||
json => this.$state.go('item.card.basic', {id: json.data.id})
|
||||
json => this.$state.go('item.card.data', {id: json.data.id})
|
||||
);
|
||||
}
|
||||
}
|
||||
ItemCreate.$inject = ['$scope', '$state'];
|
||||
|
||||
ngModule.component('vnItemCreate', {
|
||||
template: require('./item-create.html'),
|
||||
|
|
|
@ -4,5 +4,8 @@
|
|||
"Category": "Categoría",
|
||||
"Description": "Descripción",
|
||||
"Size": "Tamaño",
|
||||
"Type": "Tipo"
|
||||
"Type": "Tipo",
|
||||
"Name": "Nombre",
|
||||
"Relevancy": "Relevancia",
|
||||
"New item": "Nuevo artículo"
|
||||
}
|
|
@ -1,14 +1,14 @@
|
|||
/* eslint no-console: 0 */
|
||||
import Nightmare from 'nightmare';
|
||||
|
||||
export default function createNightmare(width = 1100, height = 600) {
|
||||
const nightmare = new Nightmare({show: true, typeInterval: 10}).viewport(width, height);
|
||||
export default function createNightmare(width = 1280, height = 720) {
|
||||
const nightmare = new Nightmare({show: true, typeInterval: 10, x: 0, y: 0}).viewport(width, height);
|
||||
|
||||
nightmare.on('page', function(type, message, error) {
|
||||
nightmare.on('page', (type, message, error) => {
|
||||
fail(error);
|
||||
});
|
||||
|
||||
nightmare.on('console', function(type, message) {
|
||||
nightmare.on('console', (type, message) => {
|
||||
if (type === 'error') {
|
||||
fail(message);
|
||||
}
|
||||
|
|
|
@ -78,6 +78,9 @@ export default {
|
|||
IBANInput: `${components.vnTextfield}[name="iban"]`,
|
||||
dueDayInput: `${components.vnTextfield}[name="dueDay"]`,
|
||||
cancelNotificationButton: 'body > vn-app > vn-vertical > vn-vertical > vn-client-card > vn-main-block > vn-horizontal > vn-one > vn-vertical > vn-client-billing-data > vn-dialog > div > form > div.button-bar > tpl-buttons > button:nth-child(1)',
|
||||
receivedCoreVNHCheckbox: `${components.vnCheck}[label='Received core VNH'] > label > input`,
|
||||
receivedCoreVNLCheckbox: `${components.vnCheck}[label='Received core VNL'] > label > input`,
|
||||
receivedB2BVNLCheckbox: `${components.vnCheck}[label='Received B2B VNL'] > label > input`,
|
||||
saveButton: `${components.vnSubmit}`
|
||||
},
|
||||
addresses: {
|
||||
|
@ -121,5 +124,19 @@ export default {
|
|||
creditInput: `${components.vnTextfield}[name="credit"]`,
|
||||
saveButton: `${components.vnSubmit}`,
|
||||
firstCreditText: 'body > vn-app > vn-vertical > vn-vertical > vn-client-card > vn-main-block > vn-horizontal > vn-one > vn-vertical > ui-view > vn-client-credit-list > vn-card > div > vn-vertical > vn-one > vn-horizontal:nth-child(1) > vn-one'
|
||||
},
|
||||
greuge: {
|
||||
greugeButton: `${components.vnMenuItem}[ui-sref="clientCard.greuge.list"]`,
|
||||
addGreugeFloatButton: `${components.vnFloatButton}`,
|
||||
amountInput: `${components.vnTextfield}[name="amount"]`,
|
||||
descriptionInput: `${components.vnTextfield}[name="description"]`,
|
||||
typeInput: `${components.vnAutocomplete}[field="$ctrl.greuge.greugeTypeFk"] > vn-vertical > ${components.vnTextfield}`,
|
||||
typeSecondOption: `${components.vnAutocomplete}[field="$ctrl.greuge.greugeTypeFk"] > vn-vertical > vn-drop-down > vn-vertical > vn-auto:nth-child(2) > ul > li`,
|
||||
saveButton: `${components.vnSubmit}`,
|
||||
firstGreugeText: 'body > vn-app > vn-vertical > vn-vertical > vn-client-card > vn-main-block > vn-horizontal > vn-one > vn-vertical > ui-view > vn-client-greuge-list > vn-card > div > vn-vertical > vn-one > vn-horizontal'
|
||||
},
|
||||
mandate: {
|
||||
mandateButton: `${components.vnMenuItem}[ui-sref="clientCard.mandate"]`,
|
||||
firstMandateText: 'body > vn-app > vn-vertical > vn-vertical > vn-client-card > vn-main-block > vn-horizontal > vn-one > vn-vertical > vn-client-mandate > vn-card > div > vn-vertical > vn-one > vn-horizontal'
|
||||
}
|
||||
};
|
||||
|
|
|
@ -86,7 +86,7 @@ describe('create client path', () => {
|
|||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toEqual('No changes to save');
|
||||
expect(result).toEqual('Some fields are invalid');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
|
@ -100,7 +100,7 @@ describe('create client path', () => {
|
|||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toContain('Error');
|
||||
expect(result).toContain('Some fields are invalid');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
|
@ -115,7 +115,7 @@ describe('create client path', () => {
|
|||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toContain('Error');
|
||||
expect(result).toContain('Some fields are invalid');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
|
@ -130,7 +130,7 @@ describe('create client path', () => {
|
|||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toContain('Error');
|
||||
expect(result).toContain('Some fields are invalid');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
|
@ -145,7 +145,7 @@ describe('create client path', () => {
|
|||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toContain('Error');
|
||||
expect(result).toContain('Some fields are invalid');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
|
@ -175,7 +175,7 @@ describe('create client path', () => {
|
|||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toContain('Error');
|
||||
expect(result).toContain('Some fields are invalid');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
|
@ -190,7 +190,7 @@ describe('create client path', () => {
|
|||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toContain('Error');
|
||||
expect(result).toContain('Some fields are invalid');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
|
|
|
@ -427,7 +427,7 @@ describe('Edit fiscalData path', () => {
|
|||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it('should check the invoice by address checkbox', done => {
|
||||
it('should uncheck the invoice by address checkbox', done => {
|
||||
nightmare
|
||||
.waitToClick(selectors.fiscalData.invoiceByAddressCheckboxInput)
|
||||
.waitToClick(selectors.fiscalData.saveButton)
|
||||
|
@ -440,7 +440,7 @@ describe('Edit fiscalData path', () => {
|
|||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it('should confirm invoice by address checkbox is checked', done => {
|
||||
it('should confirm invoice by address checkbox is unchecked', done => {
|
||||
nightmare
|
||||
.waitForSnackbarReset()
|
||||
.waitToClick(selectors.basicData.basicDataButton)
|
||||
|
@ -451,7 +451,7 @@ describe('Edit fiscalData path', () => {
|
|||
return document.querySelector(selector).checked;
|
||||
}, selectors.fiscalData.invoiceByAddressCheckboxInput)
|
||||
.then(value => {
|
||||
expect(value).toBeTruthy();
|
||||
expect(value).toBeFalsy();
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
|
@ -470,7 +470,7 @@ describe('Edit fiscalData path', () => {
|
|||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it('should confirm Verified data checkbox is checked', done => {
|
||||
it('should confirm Verified data checkbox is unchecked', done => {
|
||||
nightmare
|
||||
.waitForSnackbarReset()
|
||||
.waitToClick(selectors.basicData.basicDataButton)
|
||||
|
@ -481,7 +481,7 @@ describe('Edit fiscalData path', () => {
|
|||
return document.querySelector(selector).checked;
|
||||
}, selectors.fiscalData.verifiedDataCheckboxInput)
|
||||
.then(value => {
|
||||
expect(value).toBeTruthy();
|
||||
expect(value).toBeFalsy();
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
|
|
|
@ -160,35 +160,123 @@ describe('Edit pay method path', () => {
|
|||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
// BUG IBAN validation seems to break down whenever the due day is edited plus due day shouldnt accep values above 31.
|
||||
|
||||
// it(`should edit the due day`, done => {
|
||||
// nightmare
|
||||
// .clearInput(selectors.payMethod.dueDayInput)
|
||||
// .type(selectors.payMethod.dueDayInput, '25')
|
||||
// .waitToClick(selectors.payMethod.saveButton)
|
||||
// .waitToClick(selectors.payMethod.cancelNotificationButton)
|
||||
// .wait(selectors.globalItems.snackbarIsActive)
|
||||
// .getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
// .then(result => {
|
||||
// expect(result).toEqual('Data saved!');
|
||||
// done();
|
||||
// })
|
||||
// .catch(catchErrors(done));
|
||||
// });
|
||||
|
||||
// it('should confirm the due day have been edited', done => {
|
||||
// nightmare
|
||||
// .waitForSnackbarReset()
|
||||
// .waitToClick(selectors.basicData.basicDataButton)
|
||||
// .wait(selectors.basicData.nameInput)
|
||||
// .waitToClick(selectors.payMethod.payMethodButton)
|
||||
// .wait(selectors.payMethod.dueDayInput)
|
||||
// .getInputValue(selectors.payMethod.dueDayInput)
|
||||
// .then(result => {
|
||||
// expect(result).toEqual('25');
|
||||
// done();
|
||||
// })
|
||||
// .catch(catchErrors(done));
|
||||
// });
|
||||
it(`should edit the due day`, done => {
|
||||
nightmare
|
||||
.clearInput(selectors.payMethod.dueDayInput)
|
||||
.type(selectors.payMethod.dueDayInput, '60')
|
||||
.waitToClick(selectors.payMethod.saveButton)
|
||||
.waitToClick(selectors.payMethod.cancelNotificationButton)
|
||||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toEqual('Data saved!');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it('should confirm the due day have been edited', done => {
|
||||
nightmare
|
||||
.waitForSnackbarReset()
|
||||
.waitToClick(selectors.basicData.basicDataButton)
|
||||
.wait(selectors.basicData.nameInput)
|
||||
.waitToClick(selectors.payMethod.payMethodButton)
|
||||
.wait(selectors.payMethod.dueDayInput)
|
||||
.getInputValue(selectors.payMethod.dueDayInput)
|
||||
.then(result => {
|
||||
expect(result).toEqual('60');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it('should uncheck the Received core VNH checkbox', done => {
|
||||
nightmare
|
||||
.waitToClick(selectors.payMethod.receivedCoreVNHCheckbox)
|
||||
.waitToClick(selectors.payMethod.saveButton)
|
||||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toEqual('Data saved!');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it('should confirm Received core VNH checkbox is unchecked', done => {
|
||||
nightmare
|
||||
.waitForSnackbarReset()
|
||||
.waitToClick(selectors.basicData.basicDataButton)
|
||||
.wait(selectors.basicData.nameInput)
|
||||
.waitToClick(selectors.payMethod.payMethodButton)
|
||||
.wait(selectors.payMethod.receivedCoreVNHCheckbox)
|
||||
.evaluate(selector => {
|
||||
return document.querySelector(selector).checked;
|
||||
}, selectors.payMethod.receivedCoreVNHCheckbox)
|
||||
.then(value => {
|
||||
expect(value).toBeFalsy();
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it('should uncheck the Received core VNL checkbox', done => {
|
||||
nightmare
|
||||
.waitToClick(selectors.payMethod.receivedCoreVNLCheckbox)
|
||||
.waitToClick(selectors.payMethod.saveButton)
|
||||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toEqual('Data saved!');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it('should confirm Received core VNL checkbox is unchecked', done => {
|
||||
nightmare
|
||||
.waitForSnackbarReset()
|
||||
.waitToClick(selectors.basicData.basicDataButton)
|
||||
.wait(selectors.basicData.nameInput)
|
||||
.waitToClick(selectors.payMethod.payMethodButton)
|
||||
.wait(selectors.payMethod.receivedCoreVNLCheckbox)
|
||||
.evaluate(selector => {
|
||||
return document.querySelector(selector).checked;
|
||||
}, selectors.payMethod.receivedCoreVNLCheckbox)
|
||||
.then(value => {
|
||||
expect(value).toBeFalsy();
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it('should uncheck the Received B2B VNL checkbox', done => {
|
||||
nightmare
|
||||
.waitToClick(selectors.payMethod.receivedB2BVNLCheckbox)
|
||||
.waitToClick(selectors.payMethod.saveButton)
|
||||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toEqual('Data saved!');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it('should confirm Received B2B VNL checkbox is unchecked', done => {
|
||||
nightmare
|
||||
.waitForSnackbarReset()
|
||||
.waitToClick(selectors.basicData.basicDataButton)
|
||||
.wait(selectors.basicData.nameInput)
|
||||
.waitToClick(selectors.payMethod.payMethodButton)
|
||||
.wait(selectors.payMethod.receivedB2BVNLCheckbox)
|
||||
.evaluate(selector => {
|
||||
return document.querySelector(selector).checked;
|
||||
}, selectors.payMethod.receivedB2BVNLCheckbox)
|
||||
.then(value => {
|
||||
expect(value).toBeFalsy();
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -103,7 +103,7 @@ describe('Edit addresses path', () => {
|
|||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toContain('Error');
|
||||
expect(result).toContain('Some fields are invalid');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
|
@ -117,7 +117,7 @@ describe('Edit addresses path', () => {
|
|||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toContain('Error');
|
||||
expect(result).toContain('Some fields are invalid');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
|
@ -132,7 +132,7 @@ describe('Edit addresses path', () => {
|
|||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toContain('Error');
|
||||
expect(result).toContain('Some fields are invalid');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
|
@ -147,7 +147,7 @@ describe('Edit addresses path', () => {
|
|||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toContain('Error');
|
||||
expect(result).toContain('Some fields are invalid');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
|
@ -162,7 +162,7 @@ describe('Edit addresses path', () => {
|
|||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toContain('Error');
|
||||
expect(result).toContain('Some fields are invalid');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
|
@ -178,7 +178,7 @@ describe('Edit addresses path', () => {
|
|||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toContain('Error');
|
||||
expect(result).toContain('Some fields are invalid');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
|
@ -193,7 +193,7 @@ describe('Edit addresses path', () => {
|
|||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toContain('Error');
|
||||
expect(result).toContain('Some fields are invalid');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
|
@ -207,7 +207,7 @@ describe('Edit addresses path', () => {
|
|||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toContain('Error');
|
||||
expect(result).toContain('Some fields are invalid');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
|
@ -222,7 +222,7 @@ describe('Edit addresses path', () => {
|
|||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toContain('Error');
|
||||
expect(result).toContain('Some fields are invalid');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
|
|
|
@ -2,13 +2,12 @@ import config from '../helpers/config.js';
|
|||
import createNightmare from '../helpers/nightmare';
|
||||
import selectors from '../helpers/selectors.js';
|
||||
import {catchErrors} from '../../services/utils/jasmineHelpers';
|
||||
import { fail } from 'assert';
|
||||
const nightmare = createNightmare();
|
||||
const moduleAccessViewHashURL = '#!/';
|
||||
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
|
||||
|
||||
fdescribe('Add credit path', () => {
|
||||
describe('Add credit path', () => {
|
||||
describe('warm up', () => {
|
||||
it('should warm up login and fixtures', done => {
|
||||
nightmare
|
||||
|
@ -104,7 +103,7 @@ fdescribe('Add credit path', () => {
|
|||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toEqual('Data saved');
|
||||
expect(result).toEqual('Data saved!');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
|
|
|
@ -0,0 +1,180 @@
|
|||
import config from '../helpers/config.js';
|
||||
import createNightmare from '../helpers/nightmare';
|
||||
import selectors from '../helpers/selectors.js';
|
||||
import {catchErrors} from '../../services/utils/jasmineHelpers';
|
||||
const nightmare = createNightmare();
|
||||
const moduleAccessViewHashURL = '#!/';
|
||||
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
|
||||
|
||||
describe('Add greuge path', () => {
|
||||
describe('warm up', () => {
|
||||
it('should warm up login and fixtures', done => {
|
||||
nightmare
|
||||
.login()
|
||||
.waitForURL(moduleAccessViewHashURL)
|
||||
.waitToClick(selectors.globalItems.logOutButton)
|
||||
.then(() => {
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
});
|
||||
|
||||
it('should log in', done => {
|
||||
nightmare
|
||||
.login()
|
||||
.waitForURL(moduleAccessViewHashURL)
|
||||
.url()
|
||||
.then(url => {
|
||||
expect(url).toEqual(config.url + moduleAccessViewHashURL);
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it('should make sure the language is English', done => {
|
||||
nightmare
|
||||
.changeLanguageToEnglish()
|
||||
.then(() => {
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it('should click on the Clients button of the top bar menu', done => {
|
||||
nightmare
|
||||
.waitToClick(selectors.globalItems.applicationsMenuButton)
|
||||
.wait(selectors.globalItems.applicationsMenuVisible)
|
||||
.waitToClick(selectors.globalItems.clientsButton)
|
||||
.wait(selectors.clientsIndex.createClientButton)
|
||||
.url()
|
||||
.then(url => {
|
||||
expect(url).toEqual(config.url + '#!/clients');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it('should search for the user Petter Parker', done => {
|
||||
nightmare
|
||||
.wait(selectors.clientsIndex.searchResult)
|
||||
.type(selectors.clientsIndex.searchClientInput, 'Petter Parker')
|
||||
.click(selectors.clientsIndex.searchButton)
|
||||
.waitForNumberOfElements(selectors.clientsIndex.searchResult, 1)
|
||||
.countSearchResults(selectors.clientsIndex.searchResult)
|
||||
.then(result => {
|
||||
expect(result).toEqual(1);
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it(`should click on the search result to access to the client's greuge`, done => {
|
||||
nightmare
|
||||
.waitForTextInElement(selectors.clientsIndex.searchResult, 'Petter Parker')
|
||||
.waitToClick(selectors.clientsIndex.searchResult)
|
||||
.waitToClick(selectors.greuge.greugeButton)
|
||||
.waitForURL('greuge/list')
|
||||
.url()
|
||||
.then(url => {
|
||||
expect(url).toContain('greuge/list');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it(`should click on the add greuge button`, done => {
|
||||
nightmare
|
||||
.waitToClick(selectors.greuge.addGreugeFloatButton)
|
||||
.waitForURL('greuge/create')
|
||||
.url()
|
||||
.then(url => {
|
||||
expect(url).toContain('greuge/create');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it(`should receive an error if all fields are empty but date on submit`, done => {
|
||||
nightmare
|
||||
.click(selectors.credit.saveButton)
|
||||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toContain('Some fields are invalid');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it(`should receive an error if all fields are empty but date and amount on submit`, done => {
|
||||
nightmare
|
||||
.type(selectors.greuge.amountInput, 999)
|
||||
.click(selectors.greuge.saveButton)
|
||||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toContain('Some fields are invalid');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it(`should receive an error if all fields are empty but date and description on submit`, done => {
|
||||
nightmare
|
||||
.clearInput(selectors.greuge.amountInput)
|
||||
.type(selectors.greuge.descriptionInput, 'new armor for Batman!')
|
||||
.click(selectors.greuge.saveButton)
|
||||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toContain('Some fields are invalid');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it(`should receive an error if all fields are empty but date and type on submit`, done => {
|
||||
nightmare
|
||||
.clearInput(selectors.greuge.descriptionInput)
|
||||
.waitToClick(selectors.greuge.typeInput)
|
||||
.waitToClick(selectors.greuge.typeSecondOption)
|
||||
.click(selectors.greuge.saveButton)
|
||||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toContain('Some fields are invalid');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it(`should create a new greuge with all its data`, done => {
|
||||
nightmare
|
||||
.type(selectors.greuge.amountInput, 999)
|
||||
.type(selectors.greuge.descriptionInput, 'new armor for Batman!')
|
||||
.click(selectors.greuge.saveButton)
|
||||
.wait(selectors.globalItems.snackbarIsActive)
|
||||
.getInnerText(selectors.globalItems.snackbarIsActive)
|
||||
.then(result => {
|
||||
expect(result).toContain('Data saved!');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it('should confirm the greuge was added to the list', done => {
|
||||
nightmare
|
||||
.waitForSnackbarReset()
|
||||
.wait(selectors.greuge.firstGreugeText)
|
||||
.getInnerText(selectors.greuge.firstGreugeText)
|
||||
.then(value => {
|
||||
expect(value).toContain(999);
|
||||
expect(value).toContain('new armor for Batman!');
|
||||
expect(value).toContain('Diff');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
});
|
|
@ -0,0 +1,99 @@
|
|||
import config from '../helpers/config.js';
|
||||
import createNightmare from '../helpers/nightmare';
|
||||
import selectors from '../helpers/selectors.js';
|
||||
import {catchErrors} from '../../services/utils/jasmineHelpers';
|
||||
const nightmare = createNightmare();
|
||||
const moduleAccessViewHashURL = '#!/';
|
||||
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
|
||||
|
||||
describe('mandate path', () => {
|
||||
describe('warm up', () => {
|
||||
it('should warm up login and fixtures', done => {
|
||||
nightmare
|
||||
.login()
|
||||
.waitForURL(moduleAccessViewHashURL)
|
||||
.waitToClick(selectors.globalItems.logOutButton)
|
||||
.then(() => {
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
});
|
||||
|
||||
it('should log in', done => {
|
||||
nightmare
|
||||
.login()
|
||||
.waitForURL(moduleAccessViewHashURL)
|
||||
.url()
|
||||
.then(url => {
|
||||
expect(url).toEqual(config.url + moduleAccessViewHashURL);
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it('should make sure the language is English', done => {
|
||||
nightmare
|
||||
.changeLanguageToEnglish()
|
||||
.then(() => {
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it('should click on the Clients button of the top bar menu', done => {
|
||||
nightmare
|
||||
.waitToClick(selectors.globalItems.applicationsMenuButton)
|
||||
.wait(selectors.globalItems.applicationsMenuVisible)
|
||||
.waitToClick(selectors.globalItems.clientsButton)
|
||||
.wait(selectors.clientsIndex.createClientButton)
|
||||
.url()
|
||||
.then(url => {
|
||||
expect(url).toEqual(config.url + '#!/clients');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it('should search for the user Petter Parker', done => {
|
||||
nightmare
|
||||
.wait(selectors.clientsIndex.searchResult)
|
||||
.type(selectors.clientsIndex.searchClientInput, 'Petter Parker')
|
||||
.click(selectors.clientsIndex.searchButton)
|
||||
.waitForNumberOfElements(selectors.clientsIndex.searchResult, 1)
|
||||
.countSearchResults(selectors.clientsIndex.searchResult)
|
||||
.then(result => {
|
||||
expect(result).toEqual(1);
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it(`should click on the search result to access to the client's mandate`, done => {
|
||||
nightmare
|
||||
.waitForTextInElement(selectors.clientsIndex.searchResult, 'Petter')
|
||||
.waitToClick(selectors.clientsIndex.searchResult)
|
||||
.waitToClick(selectors.mandate.mandateButton)
|
||||
.waitForURL('mandate')
|
||||
.url()
|
||||
.then(url => {
|
||||
expect(url).toContain('mandate');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it('should confirm the client has a mandate of the CORE type', done => {
|
||||
nightmare
|
||||
.wait(selectors.mandate.firstMandateText)
|
||||
.getInnerText(selectors.mandate.firstMandateText)
|
||||
.then(value => {
|
||||
expect(value).toContain('1');
|
||||
expect(value).toContain('WAY');
|
||||
expect(value).toContain('CORE');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
});
|
|
@ -18,8 +18,8 @@ var SpecReporter = require('jasmine-spec-reporter').SpecReporter;
|
|||
|
||||
jasmine.loadConfig({
|
||||
spec_files: [
|
||||
'./e2e/helpers/extensions.js',
|
||||
'./e2e/**/*[sS]pec.js'
|
||||
'./e2e/**/*[sS]pec.js',
|
||||
'./e2e/helpers/extensions.js'
|
||||
],
|
||||
helpers: [
|
||||
'/services/utils/jasmineHelpers.js'
|
||||
|
|
50
gulpfile.js
50
gulpfile.js
|
@ -1,4 +1,5 @@
|
|||
var gulp = require('gulp');
|
||||
const jasmine = require('gulp-jasmine');
|
||||
var gutil = require('gulp-util');
|
||||
var wrap = require('gulp-wrap');
|
||||
var concat = require('gulp-concat');
|
||||
|
@ -37,6 +38,15 @@ gulp.task('client', ['clean'], function() {
|
|||
return gulp.start('watch', 'routes', 'locales', 'webpack-dev-server');
|
||||
});
|
||||
|
||||
gulp.task('nginxRestart', callback => {
|
||||
let isWindows = /^win/.test(process.platform);
|
||||
let command = isWindows ? '.\\dev.cmd' : './dev.sh';
|
||||
exec(command, (err, stdout, stderr) => {
|
||||
console.log(stdout);
|
||||
callback(err);
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('services', () => {
|
||||
process.env.NODE_ENV = gutil.env.env || 'development';
|
||||
const pathServices = './services/';
|
||||
|
@ -49,6 +59,25 @@ gulp.task('services', () => {
|
|||
});
|
||||
});
|
||||
|
||||
gulp.task('clientDev', callback => {
|
||||
runSequence('nginxRestart', 'client', callback);
|
||||
});
|
||||
|
||||
gulp.task('servicesDev', callback => {
|
||||
let isWindows = /^win/.test(process.platform);
|
||||
let command = isWindows ? 'docker inspect dblocal | findstr Status' : 'docker inspect dblocal | grep Status';
|
||||
gutil.env.env = 'test';
|
||||
exec(command, (err, stdout, stderr) => {
|
||||
let isNotRunning = !stdout.includes('running');
|
||||
if (isNotRunning) {
|
||||
runSequence('docker', 'waitForMySQL', 'services');
|
||||
} else {
|
||||
runSequence('services');
|
||||
}
|
||||
callback(err);
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('clean', function() {
|
||||
return del([`${buildDir}/*`, `!${buildDir}/templates`, `!${buildDir}/images`], {force: true});
|
||||
});
|
||||
|
@ -154,34 +183,33 @@ gulp.task('test', callback => {
|
|||
|
||||
// e2e tests
|
||||
gulp.task('e2e', callback => {
|
||||
runSequence('docker', 'runDockerLogs', 'endToEndTests', callback);
|
||||
runSequence('docker', 'waitForMySQL', 'endToEndTests', callback);
|
||||
});
|
||||
|
||||
gulp.task('runDockerLogs', callback => {
|
||||
gulp.task('waitForMySQL', callback => {
|
||||
let maxInterval = 30000;
|
||||
let interval = 1000;
|
||||
let timer = 0;
|
||||
console.log('Waiting for MySQL init process...');
|
||||
let waitForLocaldb = setInterval(() => {
|
||||
if (timer < 15000) {
|
||||
timer += 1000;
|
||||
if (timer < maxInterval) {
|
||||
timer += interval;
|
||||
exec('docker logs --tail 4 dblocal', (err, stdout, stderr) => {
|
||||
if (stdout.includes('MySQL init process done. Ready for start up.')) {
|
||||
console.log('MySQL init process done.');
|
||||
clearInterval(waitForLocaldb);
|
||||
callback(err);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.log('MySQL connection not established whithin 15 secs!');
|
||||
console.log(`MySQL connection not established whithin ${maxInterval / 1000} secs!`);
|
||||
clearInterval(waitForLocaldb);
|
||||
}
|
||||
}, 1000);
|
||||
}, interval);
|
||||
});
|
||||
|
||||
gulp.task('endToEndTests', callback => {
|
||||
exec('npm run e2e', (err, stdout, stderr) => {
|
||||
console.log(stdout);
|
||||
callback(err);
|
||||
});
|
||||
gulp.src('./e2e_tests.js')
|
||||
.pipe(jasmine({reporter: 'none'}));
|
||||
});
|
||||
|
||||
// docker dblocal
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
"gulp-concat": "^2.6.0",
|
||||
"gulp-extend": "^0.2.0",
|
||||
"gulp-install": "^1.1.0",
|
||||
"gulp-jasmine": "^3.0.0",
|
||||
"gulp-print": "^2.0.1",
|
||||
"gulp-util": "^3.0.7",
|
||||
"gulp-wrap": "^0.13.0",
|
||||
|
@ -57,7 +58,9 @@
|
|||
"karma-jasmine": "^1.1.0",
|
||||
"karma-sourcemap-loader": "^0.3.7",
|
||||
"karma-webpack": "^2.0.4",
|
||||
"md5": "^2.2.1",
|
||||
"merge-stream": "^1.0.1",
|
||||
"mysql": "^2.15.0",
|
||||
"nightmare": "^2.10.0",
|
||||
"node-sass": "^3.11.0",
|
||||
"raw-loader": "*",
|
||||
|
@ -71,8 +74,7 @@
|
|||
"build": "webpack --progress --colors",
|
||||
"dev": "webpack-dev-server --progress --colors",
|
||||
"lint": "eslint ./ --cache --ignore-pattern .gitignore",
|
||||
"test": "node services_tests",
|
||||
"testWatcher": "nodemon -q services_tests.js -w services",
|
||||
"test": "nodemon -q services_tests.js -w services",
|
||||
"e2e": "node e2e_tests"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
"posttest": "npm run lint && nsp check"
|
||||
},
|
||||
"dependencies": {
|
||||
"md5": "^2.2.1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
var app = require('../../../server/server');
|
||||
let app = require('../../../server/server');
|
||||
let md5 = require('md5');
|
||||
|
||||
module.exports = function(Client) {
|
||||
Client.remoteMethod('createUserProfile', {
|
||||
|
@ -23,7 +24,7 @@ module.exports = function(Client) {
|
|||
let user = {
|
||||
name: data.userName,
|
||||
email: firstEmail,
|
||||
password: parseInt(Math.random() * 100000000000000)
|
||||
password: md5(parseInt(Math.random() * 100000000000000))
|
||||
};
|
||||
|
||||
app.models.Account.beginTransaction('READ COMMITTED', (error, transaction) => {
|
||||
|
|
|
@ -1,31 +1,77 @@
|
|||
import app from '../../../../server/server';
|
||||
import {catchErrors} from '../../../../../../services/utils/jasmineHelpers';
|
||||
let app = require('../../../../server/server');
|
||||
import {restoreFixtures} from '../../../../../../services/db/testing_fixtures';
|
||||
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
|
||||
|
||||
describe('Client Create()', () => {
|
||||
let data = {
|
||||
name: 'MaxEisenhardt',
|
||||
userName: 'Magneto',
|
||||
email: 'magneto@marvel.com',
|
||||
fi: 'X-tax number',
|
||||
socialName: 'The X-Men'
|
||||
beforeEach(() => {
|
||||
restoreFixtures();
|
||||
});
|
||||
|
||||
let newAccountData = {
|
||||
name: 'Wade',
|
||||
userName: 'Deadpool',
|
||||
email: 'Deadpool@marvel.com',
|
||||
fi: 'DP',
|
||||
socialName: 'Deadpool Marvel'
|
||||
};
|
||||
|
||||
it('should createa new account', done => {
|
||||
app.models.Client.createUserProfile(data, () => {
|
||||
app.models.Account.findOne({where: {name: data.userName}})
|
||||
it('should find Charles Xavier', done => {
|
||||
app.models.Account.findOne({where: {name: 'CharlesXavier'}})
|
||||
.then(account => {
|
||||
expect(account.name).toEqual(data.userName);
|
||||
app.models.Client.findOne({where: {name: data.name}})
|
||||
expect(account.name).toEqual('CharlesXavier');
|
||||
done();
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it("should not find Deadpool as he's not created yet", done => {
|
||||
app.models.Account.findOne({where: {name: newAccountData.userName}})
|
||||
.then(account => {
|
||||
expect(account).toEqual(null);
|
||||
app.models.Client.findOne({where: {name: newAccountData.name}})
|
||||
.then(client => {
|
||||
expect(client.id).toEqual(account.id);
|
||||
expect(client.name).toEqual(data.name);
|
||||
expect(client.email).toEqual(data.email);
|
||||
expect(client.fi).toEqual(data.fi);
|
||||
expect(client.socialName).toEqual(data.socialName);
|
||||
expect(client).toEqual(null);
|
||||
done();
|
||||
});
|
||||
})
|
||||
.catch(catchErrors(done));
|
||||
});
|
||||
|
||||
it('should not be able to create a user if exists', done => {
|
||||
app.models.Client.findOne({where: {name: 'Charles Xavier'}})
|
||||
.then(client => {
|
||||
let formerAccountData = {
|
||||
name: client.name,
|
||||
userName: client.userName,
|
||||
email: client.email,
|
||||
fi: client.fi,
|
||||
socialName: client.socialName
|
||||
};
|
||||
|
||||
expect(app.models.Client.createUserProfile(formerAccountData)).toBeFalsy();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
// awaiting for fixtures
|
||||
// it('should create a new account', done => {
|
||||
// app.models.Client.createUserProfile(data => {
|
||||
// app.models.Account.findOne({where: {name: data.userName}})
|
||||
// .then(account => {
|
||||
// expect(account.name).toEqual(data.userName);
|
||||
// app.models.Client.findOne({where: {name: data.name}})
|
||||
// .then(client => {
|
||||
// expect(client.id).toEqual(account.id);
|
||||
// expect(client.name).toEqual(data.name);
|
||||
// expect(client.email).toEqual(data.email);
|
||||
// expect(client.fi).toEqual(data.fi);
|
||||
// expect(client.socialName).toEqual(data.socialName);
|
||||
// done();
|
||||
// });
|
||||
// })
|
||||
// .catch(catchErrors(done));
|
||||
// });
|
||||
// });
|
||||
});
|
||||
|
|
|
@ -10,7 +10,7 @@ module.exports = function(Self) {
|
|||
let userId = token && token.userId;
|
||||
let app = require('../../server/server');
|
||||
let Employee = app.models.Employee;
|
||||
Employee.findOne({where: {userFk: userId}}, function (err, user){
|
||||
Employee.findOne({where: {userFk: userId}}, (err, user) => {
|
||||
if (user) {
|
||||
ctx.instance.employeeFk = user.id;
|
||||
next();
|
||||
|
|
|
@ -18,15 +18,9 @@ module.exports = function(Self) {
|
|||
|
||||
// Validations
|
||||
|
||||
Self.validatesUniquenessOf('name', {
|
||||
message: 'El nombre debe ser único'
|
||||
});
|
||||
Self.validatesUniquenessOf('fi', {
|
||||
message: 'El NIF/CIF debe ser único'
|
||||
});
|
||||
Self.validatesPresenceOf('socialName', {
|
||||
message: 'Debe especificarse la razón social'
|
||||
});
|
||||
Self.validatesUniquenessOf('socialName', {
|
||||
message: 'La razón social debe ser única'
|
||||
});
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
"description": "Fiscal indentifier"
|
||||
},
|
||||
"socialName": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"required": true
|
||||
},
|
||||
"contact": {
|
||||
"type": "string"
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
module.exports = function(Self) {
|
||||
require('../methods/greuge/filter.js')(Self);
|
||||
require('../methods/greuge/totalGreuge.js')(Self);
|
||||
|
||||
Self.validatesLengthOf('description', {
|
||||
max: 45,
|
||||
message: 'La description debe tener maximo 45 caracteres'
|
||||
});
|
||||
};
|
||||
|
|
|
@ -14,10 +14,12 @@
|
|||
"description": "Identifier"
|
||||
},
|
||||
"description": {
|
||||
"type": "String"
|
||||
"type": "String",
|
||||
"required": true
|
||||
},
|
||||
"amount": {
|
||||
"type": "Number"
|
||||
"type": "Number",
|
||||
"required": true
|
||||
},
|
||||
"shipped": {
|
||||
"type": "date"
|
||||
|
@ -35,7 +37,8 @@
|
|||
"greugeType": {
|
||||
"type": "belongsTo",
|
||||
"model": "GreugeType",
|
||||
"foreignKey": "greugeTypeFk"
|
||||
"foreignKey": "greugeTypeFk",
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
FROM mysql:5.6.37
|
||||
|
||||
ENV MYSQL_ALLOW_EMPTY_PASSWORD yes
|
||||
ENV TZ GMT-1
|
||||
|
||||
COPY localDB01StructureAccount.sql /docker-entrypoint-initdb.d
|
||||
COPY localDB02StructureVn2008.sql /docker-entrypoint-initdb.d
|
||||
|
|
|
@ -459,7 +459,7 @@ INSERT INTO `vn2008`.`empresa_grupo`(`empresa_grupo_id`, `grupo`)
|
|||
|
||||
INSERT INTO `vn2008`.`empresa`(`id`, `abbreviation`, `registro`, `gerente_id`, `alta`, `baja`, `logo`, `oficial`, `cyc`, `rgb`, `mail`, `cuno`, `ODBC_DATE`, `Id_Cliente`, `digito_factura`, `Id_Proveedores_account`, `morosidad`, `empresa_grupo`)
|
||||
VALUES
|
||||
('442', 'WAY', 'Wayne Industries, Inc. operates as a warehouse for steel products. Wayne Industries, Inc. was founded in 1989 and is based in Wayne, Michigan.', '2', '1989-11-19', NULL, NULL, '1', '1', '00FF00', 'BruceWayne@verdnatura.es', NULL, '1989-08-11 12:31:22', '10', '1', NULL, '1', '1');
|
||||
(442, 'WAY', 'Wayne Industries, Inc. operates as a warehouse for steel products. Wayne Industries, Inc. was founded in 1989 and is based in Wayne, Michigan.', '2', '1989-11-19', NULL, NULL, '1', '1', '00FF00', 'BruceWayne@verdnatura.es', NULL, '1989-08-11 12:31:22', '10', '1', NULL, '1', '1');
|
||||
|
||||
INSERT INTO `salix`.`Ticket`(`id`, `agencyFk`, `employeeFk`, `date`, `hour`, `clientFk`, `addressFk`)
|
||||
VALUES
|
||||
|
@ -525,5 +525,5 @@ INSERT INTO `vn`.`mandateType`(`id`, `name`)
|
|||
|
||||
INSERT INTO `vn`.`mandate`(`id`, `clientFk`, `companyFk`, `code`, `created`, `mandateTypeFk`)
|
||||
VALUES
|
||||
(1, 1, 442, '1-1', CURDATE(), 2);
|
||||
(1, 2, 442, '1-1', CURDATE(), 2);
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
let mysql = require('mysql');
|
||||
|
||||
let connection = mysql.createConnection({
|
||||
multipleStatements: false,
|
||||
host: 'localhost',
|
||||
user: 'root',
|
||||
password: '',
|
||||
database: 'salix'
|
||||
});
|
||||
|
||||
export function restoreFixtures() {
|
||||
// connection.connect();
|
||||
// connection.query('CALL truncateDatabase');
|
||||
// connection.disconect();
|
||||
// console.log('fixtures restored');
|
||||
}
|
|
@ -18,10 +18,10 @@
|
|||
}
|
||||
},
|
||||
"relations": {
|
||||
"taxGroup": {
|
||||
"taxClass": {
|
||||
"type": "belongsTo",
|
||||
"model": "TaxGroup",
|
||||
"foreignKey": "taxGroupFk"
|
||||
"model": "TaxClass",
|
||||
"foreignKey": "taxClassFk"
|
||||
},
|
||||
"taxCode": {
|
||||
"type": "belongsTo",
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
module.exports = function(Self) {
|
||||
require('../methods/item/filter.js')(Self);
|
||||
|
||||
Self.validatesPresenceOf('name', {message: 'Cannot be blank'});
|
||||
Self.validatesPresenceOf('originFk', {message: 'Cannot be blank'});
|
||||
};
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
"description": "Identifier"
|
||||
},
|
||||
"name": {
|
||||
"type": "String"
|
||||
"type": "String",
|
||||
"required": true
|
||||
},
|
||||
"size": {
|
||||
"type": "Number"
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"name": "TaxGroup",
|
||||
"name": "TaxClass",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "taxGroup",
|
||||
"table": "taxClass",
|
||||
"database": "vn"
|
||||
}
|
||||
},
|
|
@ -42,7 +42,7 @@
|
|||
"Intrastat": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"TaxGroup": {
|
||||
"TaxClass": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"TaxCode": {
|
||||
|
|
|
@ -24,4 +24,3 @@
|
|||
"acquireTimeout": 20000
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
require('babel-core/register')({presets: ['es2015']});
|
||||
|
||||
process.env.NODE_ENV = 'test';
|
||||
|
||||
process.on('warning', warning => {
|
||||
console.log(warning.name);
|
||||
console.log(warning.message);
|
||||
|
@ -17,13 +19,12 @@ var jasmine = new Jasmine();
|
|||
var SpecReporter = require('jasmine-spec-reporter').SpecReporter;
|
||||
|
||||
jasmine.loadConfig({
|
||||
spec_dir: 'services/',
|
||||
spec_dir: 'services',
|
||||
spec_files: [
|
||||
'**/specs/*[sS]pec.js'
|
||||
'client/common/**/*[sS]pec.js'
|
||||
],
|
||||
helpers: [
|
||||
// to implement
|
||||
// '/api/utils/jasmineHelpers.js'
|
||||
'/services/utils/jasmineHelpers.js'
|
||||
]
|
||||
});
|
||||
|
||||
|
@ -36,6 +37,5 @@ jasmine.addReporter(new SpecReporter({
|
|||
}
|
||||
}));
|
||||
|
||||
exports.start = () => {
|
||||
jasmine.execute();
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue