merge conflict

This commit is contained in:
Daniel Herrero 2018-01-16 13:56:09 +01:00
commit 7503179cb8
20 changed files with 260 additions and 84 deletions

View File

@ -1,53 +1,67 @@
# Project Title # 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 ### Prerequisites
For testing purposes you will need to install globally the following items: You will need to install globally the following items:
npm install -g karma $ npm install -g karma
npm install -g karma-cli $ npm install -g karma-cli
$ npm install -g gulp
## Getting Started // ### Installing $ npm install -g webpack
$ npm install -g nodemon
Pull from repo.
install nodejs v6 or above.
install nginx globally. 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: on root run:
npm install $ npm install
gulp install $ gulp install
lauching nginx: lauching nginx:
./dev.sh $ ./dev.sh
launching frontend: launching frontend:
gulp client $ gulp client
or start nginx before client on sequence
$ gulp clientDev
launching backend: 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 ## Running the tests
for client-side unit tests run from project's root: for client-side unit tests run from project's root:
karma start $ karma start
for server-side unit tests run from project's root: 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 ### Break down into end to end tests
on root run: Run local database plus e2e paths:
$ gulp e2e
gulp docker Just the e2e paths as the fixtures are untainted:
$ npm run e2e
wait 10 secs for db to be ready
npm run e2e
## Built With ## Built With

View File

@ -5,6 +5,7 @@
form="form" form="form"
save="post"> save="post">
</vn-watcher> </vn-watcher>
<form pad-medium name="form" ng-submit="$ctrl.onSubmit()"> <form pad-medium name="form" ng-submit="$ctrl.onSubmit()">
<vn-card> <vn-card>
<vn-vertical pad-medium> <vn-vertical pad-medium>

View File

@ -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');
});
});
});
});

View File

@ -29,7 +29,6 @@ export function directive(interpolate, compile, $window) {
throw new Error(`vnValidation: Entity '${entityName}' doesn't exist`); throw new Error(`vnValidation: Entity '${entityName}' doesn't exist`);
let validations = entity.validations[fieldName]; let validations = entity.validations[fieldName];
if (!validations || validations.length == 0) if (!validations || validations.length == 0)
return; return;

View File

@ -2,7 +2,7 @@ import {validator} from 'vendor';
export const validators = { export const validators = {
presence: value => { presence: value => {
if (validator.isEmpty(value)) if (validator.isEmpty(value ? String(value) : ''))
throw new Error(`Value can't be empty`); throw new Error(`Value can't be empty`);
}, },
absence: value => { absence: value => {
@ -74,7 +74,7 @@ export function validate(value, conf) {
try { try {
checkNull(value, conf); checkNull(value, conf);
if (validator && value != null) if (validator) // && value != null ??
validator(value, conf); validator(value, conf);
} catch (e) { } catch (e) {
let message = conf.message ? conf.message : e.message; let message = conf.message ? conf.message : e.message;

View File

@ -4,11 +4,11 @@ import Nightmare from 'nightmare';
export default function createNightmare(width = 1280, height = 720) { export default function createNightmare(width = 1280, height = 720) {
const nightmare = new Nightmare({show: true, typeInterval: 10, x: 0, y: 0}).viewport(width, height); 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); fail(error);
}); });
nightmare.on('console', function(type, message) { nightmare.on('console', (type, message) => {
if (type === 'error') { if (type === 'error') {
fail(message); fail(message);
} }

View File

@ -128,11 +128,15 @@ export default {
greuge: { greuge: {
greugeButton: `${components.vnMenuItem}[ui-sref="clientCard.greuge.list"]`, greugeButton: `${components.vnMenuItem}[ui-sref="clientCard.greuge.list"]`,
addGreugeFloatButton: `${components.vnFloatButton}`, addGreugeFloatButton: `${components.vnFloatButton}`,
amountInput: `${components.vnTextfield}[name="Amount"]`, amountInput: `${components.vnTextfield}[name="amount"]`,
descriptionInput: `${components.vnTextfield}[name="Description"]`, descriptionInput: `${components.vnTextfield}[name="description"]`,
typeInput: `${components.vnAutocomplete}[field="$ctrl.greuge.greugeTypeFk"] > vn-vertical > ${components.vnTextfield}`, 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`, typeSecondOption: `${components.vnAutocomplete}[field="$ctrl.greuge.greugeTypeFk"] > vn-vertical > vn-drop-down > vn-vertical > vn-auto:nth-child(2) > ul > li`,
saveButton: `${components.vnSubmit}` saveButton: `${components.vnSubmit}`,
// firstGreugeText: '' 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'
} }
}; };

View File

@ -86,7 +86,7 @@ describe('create client path', () => {
.wait(selectors.globalItems.snackbarIsActive) .wait(selectors.globalItems.snackbarIsActive)
.getInnerText(selectors.globalItems.snackbarIsActive) .getInnerText(selectors.globalItems.snackbarIsActive)
.then(result => { .then(result => {
expect(result).toEqual('No changes to save'); expect(result).toEqual('Some fields are invalid');
done(); done();
}) })
.catch(catchErrors(done)); .catch(catchErrors(done));
@ -100,7 +100,7 @@ describe('create client path', () => {
.wait(selectors.globalItems.snackbarIsActive) .wait(selectors.globalItems.snackbarIsActive)
.getInnerText(selectors.globalItems.snackbarIsActive) .getInnerText(selectors.globalItems.snackbarIsActive)
.then(result => { .then(result => {
expect(result).toContain('Error'); expect(result).toContain('Some fields are invalid');
done(); done();
}) })
.catch(catchErrors(done)); .catch(catchErrors(done));
@ -115,7 +115,7 @@ describe('create client path', () => {
.wait(selectors.globalItems.snackbarIsActive) .wait(selectors.globalItems.snackbarIsActive)
.getInnerText(selectors.globalItems.snackbarIsActive) .getInnerText(selectors.globalItems.snackbarIsActive)
.then(result => { .then(result => {
expect(result).toContain('Error'); expect(result).toContain('Some fields are invalid');
done(); done();
}) })
.catch(catchErrors(done)); .catch(catchErrors(done));
@ -130,7 +130,7 @@ describe('create client path', () => {
.wait(selectors.globalItems.snackbarIsActive) .wait(selectors.globalItems.snackbarIsActive)
.getInnerText(selectors.globalItems.snackbarIsActive) .getInnerText(selectors.globalItems.snackbarIsActive)
.then(result => { .then(result => {
expect(result).toContain('Error'); expect(result).toContain('Some fields are invalid');
done(); done();
}) })
.catch(catchErrors(done)); .catch(catchErrors(done));
@ -145,7 +145,7 @@ describe('create client path', () => {
.wait(selectors.globalItems.snackbarIsActive) .wait(selectors.globalItems.snackbarIsActive)
.getInnerText(selectors.globalItems.snackbarIsActive) .getInnerText(selectors.globalItems.snackbarIsActive)
.then(result => { .then(result => {
expect(result).toContain('Error'); expect(result).toContain('Some fields are invalid');
done(); done();
}) })
.catch(catchErrors(done)); .catch(catchErrors(done));
@ -175,7 +175,7 @@ describe('create client path', () => {
.wait(selectors.globalItems.snackbarIsActive) .wait(selectors.globalItems.snackbarIsActive)
.getInnerText(selectors.globalItems.snackbarIsActive) .getInnerText(selectors.globalItems.snackbarIsActive)
.then(result => { .then(result => {
expect(result).toContain('Error'); expect(result).toContain('Some fields are invalid');
done(); done();
}) })
.catch(catchErrors(done)); .catch(catchErrors(done));
@ -190,7 +190,7 @@ describe('create client path', () => {
.wait(selectors.globalItems.snackbarIsActive) .wait(selectors.globalItems.snackbarIsActive)
.getInnerText(selectors.globalItems.snackbarIsActive) .getInnerText(selectors.globalItems.snackbarIsActive)
.then(result => { .then(result => {
expect(result).toContain('Error'); expect(result).toContain('Some fields are invalid');
done(); done();
}) })
.catch(catchErrors(done)); .catch(catchErrors(done));

View File

@ -103,7 +103,7 @@ describe('Edit addresses path', () => {
.wait(selectors.globalItems.snackbarIsActive) .wait(selectors.globalItems.snackbarIsActive)
.getInnerText(selectors.globalItems.snackbarIsActive) .getInnerText(selectors.globalItems.snackbarIsActive)
.then(result => { .then(result => {
expect(result).toContain('Error'); expect(result).toContain('Some fields are invalid');
done(); done();
}) })
.catch(catchErrors(done)); .catch(catchErrors(done));
@ -117,7 +117,7 @@ describe('Edit addresses path', () => {
.wait(selectors.globalItems.snackbarIsActive) .wait(selectors.globalItems.snackbarIsActive)
.getInnerText(selectors.globalItems.snackbarIsActive) .getInnerText(selectors.globalItems.snackbarIsActive)
.then(result => { .then(result => {
expect(result).toContain('Error'); expect(result).toContain('Some fields are invalid');
done(); done();
}) })
.catch(catchErrors(done)); .catch(catchErrors(done));
@ -132,7 +132,7 @@ describe('Edit addresses path', () => {
.wait(selectors.globalItems.snackbarIsActive) .wait(selectors.globalItems.snackbarIsActive)
.getInnerText(selectors.globalItems.snackbarIsActive) .getInnerText(selectors.globalItems.snackbarIsActive)
.then(result => { .then(result => {
expect(result).toContain('Error'); expect(result).toContain('Some fields are invalid');
done(); done();
}) })
.catch(catchErrors(done)); .catch(catchErrors(done));
@ -147,7 +147,7 @@ describe('Edit addresses path', () => {
.wait(selectors.globalItems.snackbarIsActive) .wait(selectors.globalItems.snackbarIsActive)
.getInnerText(selectors.globalItems.snackbarIsActive) .getInnerText(selectors.globalItems.snackbarIsActive)
.then(result => { .then(result => {
expect(result).toContain('Error'); expect(result).toContain('Some fields are invalid');
done(); done();
}) })
.catch(catchErrors(done)); .catch(catchErrors(done));
@ -162,7 +162,7 @@ describe('Edit addresses path', () => {
.wait(selectors.globalItems.snackbarIsActive) .wait(selectors.globalItems.snackbarIsActive)
.getInnerText(selectors.globalItems.snackbarIsActive) .getInnerText(selectors.globalItems.snackbarIsActive)
.then(result => { .then(result => {
expect(result).toContain('Error'); expect(result).toContain('Some fields are invalid');
done(); done();
}) })
.catch(catchErrors(done)); .catch(catchErrors(done));
@ -178,7 +178,7 @@ describe('Edit addresses path', () => {
.wait(selectors.globalItems.snackbarIsActive) .wait(selectors.globalItems.snackbarIsActive)
.getInnerText(selectors.globalItems.snackbarIsActive) .getInnerText(selectors.globalItems.snackbarIsActive)
.then(result => { .then(result => {
expect(result).toContain('Error'); expect(result).toContain('Some fields are invalid');
done(); done();
}) })
.catch(catchErrors(done)); .catch(catchErrors(done));
@ -193,7 +193,7 @@ describe('Edit addresses path', () => {
.wait(selectors.globalItems.snackbarIsActive) .wait(selectors.globalItems.snackbarIsActive)
.getInnerText(selectors.globalItems.snackbarIsActive) .getInnerText(selectors.globalItems.snackbarIsActive)
.then(result => { .then(result => {
expect(result).toContain('Error'); expect(result).toContain('Some fields are invalid');
done(); done();
}) })
.catch(catchErrors(done)); .catch(catchErrors(done));
@ -207,7 +207,7 @@ describe('Edit addresses path', () => {
.wait(selectors.globalItems.snackbarIsActive) .wait(selectors.globalItems.snackbarIsActive)
.getInnerText(selectors.globalItems.snackbarIsActive) .getInnerText(selectors.globalItems.snackbarIsActive)
.then(result => { .then(result => {
expect(result).toContain('Error'); expect(result).toContain('Some fields are invalid');
done(); done();
}) })
.catch(catchErrors(done)); .catch(catchErrors(done));
@ -222,7 +222,7 @@ describe('Edit addresses path', () => {
.wait(selectors.globalItems.snackbarIsActive) .wait(selectors.globalItems.snackbarIsActive)
.getInnerText(selectors.globalItems.snackbarIsActive) .getInnerText(selectors.globalItems.snackbarIsActive)
.then(result => { .then(result => {
expect(result).toContain('Error'); expect(result).toContain('Some fields are invalid');
done(); done();
}) })
.catch(catchErrors(done)); .catch(catchErrors(done));

View File

@ -102,7 +102,7 @@ describe('Add greuge path', () => {
.wait(selectors.globalItems.snackbarIsActive) .wait(selectors.globalItems.snackbarIsActive)
.getInnerText(selectors.globalItems.snackbarIsActive) .getInnerText(selectors.globalItems.snackbarIsActive)
.then(result => { .then(result => {
expect(result).toContain('Error'); expect(result).toContain('Some fields are invalid');
done(); done();
}) })
.catch(catchErrors(done)); .catch(catchErrors(done));
@ -111,25 +111,25 @@ describe('Add greuge path', () => {
it(`should receive an error if all fields are empty but date and amount on submit`, done => { it(`should receive an error if all fields are empty but date and amount on submit`, done => {
nightmare nightmare
.type(selectors.greuge.amountInput, 999) .type(selectors.greuge.amountInput, 999)
.click(selectors.credit.saveButton) .click(selectors.greuge.saveButton)
.wait(selectors.globalItems.snackbarIsActive) .wait(selectors.globalItems.snackbarIsActive)
.getInnerText(selectors.globalItems.snackbarIsActive) .getInnerText(selectors.globalItems.snackbarIsActive)
.then(result => { .then(result => {
expect(result).toContain('Error'); expect(result).toContain('Some fields are invalid');
done(); done();
}) })
.catch(catchErrors(done)); .catch(catchErrors(done));
}); });
it(`should receive an error if all fields are empty but date and amount on submit`, done => { it(`should receive an error if all fields are empty but date and description on submit`, done => {
nightmare nightmare
.clearInput(selectors.greuge.amountInput) .clearInput(selectors.greuge.amountInput)
.type(selectors.greuge.descriptionInput, 'Bat-flying suite with anti-APCR rounds') .type(selectors.greuge.descriptionInput, 'new armor for Batman!')
.click(selectors.credit.saveButton) .click(selectors.greuge.saveButton)
.wait(selectors.globalItems.snackbarIsActive) .wait(selectors.globalItems.snackbarIsActive)
.getInnerText(selectors.globalItems.snackbarIsActive) .getInnerText(selectors.globalItems.snackbarIsActive)
.then(result => { .then(result => {
expect(result).toContain('Error'); expect(result).toContain('Some fields are invalid');
done(); done();
}) })
.catch(catchErrors(done)); .catch(catchErrors(done));
@ -140,11 +140,39 @@ describe('Add greuge path', () => {
.clearInput(selectors.greuge.descriptionInput) .clearInput(selectors.greuge.descriptionInput)
.waitToClick(selectors.greuge.typeInput) .waitToClick(selectors.greuge.typeInput)
.waitToClick(selectors.greuge.typeSecondOption) .waitToClick(selectors.greuge.typeSecondOption)
.click(selectors.credit.saveButton) .click(selectors.greuge.saveButton)
.wait(selectors.globalItems.snackbarIsActive) .wait(selectors.globalItems.snackbarIsActive)
.getInnerText(selectors.globalItems.snackbarIsActive) .getInnerText(selectors.globalItems.snackbarIsActive)
.then(result => { .then(result => {
expect(result).toContain('Error'); 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(); done();
}) })
.catch(catchErrors(done)); .catch(catchErrors(done));

View File

@ -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));
});
});

View File

@ -40,7 +40,7 @@ gulp.task('client', ['clean'], function() {
gulp.task('nginxRestart', callback => { gulp.task('nginxRestart', callback => {
let isWindows = /^win/.test(process.platform); let isWindows = /^win/.test(process.platform);
let command = isWindows ? './dev.cmd' : './dev.sh'; let command = isWindows ? '.\\dev.cmd' : './dev.sh';
exec(command, (err, stdout, stderr) => { exec(command, (err, stdout, stderr) => {
console.log(stdout); console.log(stdout);
callback(err); callback(err);

View File

@ -72,8 +72,7 @@
"build": "webpack --progress --colors", "build": "webpack --progress --colors",
"dev": "webpack-dev-server --progress --colors", "dev": "webpack-dev-server --progress --colors",
"lint": "eslint ./ --cache --ignore-pattern .gitignore", "lint": "eslint ./ --cache --ignore-pattern .gitignore",
"test": "node services_tests", "test": "nodemon -q services_tests.js -w services",
"testWatcher": "nodemon -q services_tests.js -w services",
"e2e": "node e2e_tests" "e2e": "node e2e_tests"
} }
} }

View File

@ -18,15 +18,9 @@ module.exports = function(Self) {
// Validations // Validations
Self.validatesUniquenessOf('name', {
message: 'El nombre debe ser único'
});
Self.validatesUniquenessOf('fi', { Self.validatesUniquenessOf('fi', {
message: 'El NIF/CIF debe ser único' message: 'El NIF/CIF debe ser único'
}); });
Self.validatesPresenceOf('socialName', {
message: 'Debe especificarse la razón social'
});
Self.validatesUniquenessOf('socialName', { Self.validatesUniquenessOf('socialName', {
message: 'La razón social debe ser única' message: 'La razón social debe ser única'
}); });

View File

@ -22,7 +22,8 @@
"description": "Fiscal indentifier" "description": "Fiscal indentifier"
}, },
"socialName": { "socialName": {
"type": "string" "type": "string",
"required": true
}, },
"contact": { "contact": {
"type": "string" "type": "string"

View File

@ -2,11 +2,8 @@ module.exports = function(Self) {
require('../methods/greuge/filter.js')(Self); require('../methods/greuge/filter.js')(Self);
require('../methods/greuge/totalGreuge.js')(Self); require('../methods/greuge/totalGreuge.js')(Self);
Self.validatesPresenceOf('description', 'amount', 'greugeTypeFk', {
message: 'Importe es un campo obligatorio'
});
Self.validatesLengthOf('description', { Self.validatesLengthOf('description', {
max: 45, max: 45,
message: 'description es un campo max 45' message: 'La description debe tener maximo 45 caracteres'
}); });
}; };

View File

@ -14,10 +14,12 @@
"description": "Identifier" "description": "Identifier"
}, },
"description": { "description": {
"type": "String" "type": "String",
"required": true
}, },
"amount": { "amount": {
"type": "Number" "type": "Number",
"required": true
}, },
"shipped": { "shipped": {
"type": "date" "type": "date"
@ -35,7 +37,8 @@
"greugeType": { "greugeType": {
"type": "belongsTo", "type": "belongsTo",
"model": "GreugeType", "model": "GreugeType",
"foreignKey": "greugeTypeFk" "foreignKey": "greugeTypeFk",
"required": true
} }
} }
} }

View File

@ -525,5 +525,5 @@ INSERT INTO `vn`.`mandateType`(`id`, `name`)
INSERT INTO `vn`.`mandate`(`id`, `clientFk`, `companyFk`, `code`, `created`, `mandateTypeFk`) INSERT INTO `vn`.`mandate`(`id`, `clientFk`, `companyFk`, `code`, `created`, `mandateTypeFk`)
VALUES VALUES
(1, 1, 442, '1-1', CURDATE(), 2); (1, 2, 442, '1-1', CURDATE(), 2);

View File

@ -17,13 +17,12 @@ var jasmine = new Jasmine();
var SpecReporter = require('jasmine-spec-reporter').SpecReporter; var SpecReporter = require('jasmine-spec-reporter').SpecReporter;
jasmine.loadConfig({ jasmine.loadConfig({
spec_dir: 'services/', spec_dir: 'services',
spec_files: [ spec_files: [
'**/specs/*[sS]pec.js' 'client/common/**/*[sS]pec.js'
], ],
helpers: [ helpers: [
// to implement '/services/utils/jasmineHelpers.js'
// '/api/utils/jasmineHelpers.js'
] ]
}); });
@ -36,6 +35,5 @@ jasmine.addReporter(new SpecReporter({
} }
})); }));
exports.start = () => { jasmine.execute();
jasmine.execute();
};