updated tests
gitea/salix/2003-adress_validate_uee_members There was a failure building this commit Details

This commit is contained in:
Joan Sanchez 2020-01-28 09:03:20 +01:00
parent 2eeab485e3
commit 0044bd2efa
16 changed files with 468 additions and 149 deletions

View File

@ -78,7 +78,7 @@ INSERT INTO `vn`.`worker`(`id`, `code`, `firstName`, `lastName`, `userFk`,`bossF
INSERT INTO `vn`.`country`(`id`, `country`, `isUeeMember`, `code`, `currencyFk`, `ibanLength`)
VALUES
(1, 'España', 0, 'ES', 1, 24),
(1, 'España', 1, 'ES', 1, 24),
(2, 'Italia', 1, 'IT', 1, 27),
(3, 'Alemania', 1, 'DE', 1, 22),
(4, 'Rumania', 1, 'RO', 1, 24),
@ -182,8 +182,8 @@ INSERT INTO `vn`.`province`(`id`, `name`, `countryFk`, `warehouseFk`)
(1, 'Province one', 1, NULL),
(2, 'Province two', 1, NULL),
(3, 'Province three', 1, NULL),
(4, 'Province four', 1, NULL),
(5, 'Province five', 2, NULL);
(4, 'Province four', 2, NULL),
(5, 'Province five', 13, NULL);
INSERT INTO `vn`.`town`(`id`, `name`, `provinceFk`)
VALUES
@ -1966,3 +1966,8 @@ INSERT INTO `vn`.`travelThermograph`(`thermographFk`, `created`, `warehouseFk`,
INSERT INTO `vn`.`incoterms` (`code`, `name`)
VALUES
('FAS', 'Free Alongside Ship');
INSERT INTO `vn`.`customsAgent` (`id`, `fiscalName`, `street`, `nif`, `phone`, `email`)
VALUES
(1, 'Agent one', '1007 Mountain Drive, Gotham', 'N1111111111', '111111111', 'agentone@gotham.com'),
(2, 'Agent two', '1007 Mountain Drive, Gotham', 'N2222222222', '222222222', 'agenttwo@gotham.com');

View File

@ -61,5 +61,7 @@
"MESSAGE_BOUGHT_UNITS": "Bought {{quantity}} units of {{concept}} (#{{itemId}}) for the ticket id [#{{ticketId}}]({{{url}}})",
"MESSAGE_INSURANCE_CHANGE": "I have changed the insurence credit of client [{{clientName}} (#{{clientId}})]({{{url}}}) to *{{credit}} €*",
"MESSAGE_CHANGED_PAYMETHOD": "I have changed the pay method for client [{{clientName}} (#{{clientId}})]({{{url}}})",
"MESSAGE_CLAIM_ITEM_REGULARIZE": "I sent *{{quantity}}* units of [{{concept}} (#{{itemId}})]({{{itemUrl}}}) to {{nickname}} coming from ticket id [#{{ticketId}}]({{{ticketUrl}}})"
"MESSAGE_CLAIM_ITEM_REGULARIZE": "I sent *{{quantity}}* units of [{{concept}} (#{{itemId}})]({{{itemUrl}}}) to {{nickname}} coming from ticket id [#{{ticketId}}]({{{ticketUrl}}})",
"Customs agent is required for a non UEE member": "Customs agent is required for a non UEE member",
"Incoterms is required for a non UEE member": "Incoterms is required for a non UEE member"
}

View File

@ -1,44 +0,0 @@
module.exports = function(Self) {
Self.remoteMethod('createDefaultAddress', {
description: 'Creates both client and its web account',
accepts: {
arg: 'data',
type: 'object',
http: {source: 'body'}
},
returns: {
root: true,
type: 'Object'
},
http: {
verb: 'post',
path: '/createDefaultAddress'
}
});
Self.createDefaultAddress = async data => {
const Address = Self.app.models.Address;
const Client = Self.app.models.Client;
const tx = await Address.beginTransaction({});
try {
let options = {transaction: tx};
let address = data.address;
let newAddress = await Address.create(address, options);
let client = await Client.findById(address.clientFk, null, options);
if (data.isDefaultAddress) {
await client.updateAttributes({
defaultAddressFk: newAddress.id
}, options);
}
await tx.commit();
return newAddress;
} catch (e) {
await tx.rollback();
throw e;
}
};
};

View File

@ -1,37 +0,0 @@
const app = require('vn-loopback/server/server');
describe('Address createDefaultAddress', () => {
let address;
let client;
afterAll(async done => {
await client.updateAttributes({defaultAddressFk: 1});
await address.destroy();
done();
});
it('should verify that client defaultAddressFk is untainted', async() => {
client = await app.models.Client.findById(101);
expect(client.defaultAddressFk).toEqual(1);
});
it('should create a new address and set as a client default address', async() => {
let data = {
address: {
clientFk: 101,
nickname: 'My address',
street: 'Wall Street',
city: 'New York',
},
isDefaultAddress: true
};
address = await app.models.Address.createDefaultAddress(data);
client = await app.models.Client.findById(101);
expect(client.defaultAddressFk).toEqual(address.id);
});
});

View File

@ -0,0 +1,121 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = function(Self) {
Self.remoteMethodCtx('createAddress', {
description: 'Creates client address updating default address',
accepts: [{
arg: 'id',
type: 'Number',
description: 'The client id',
http: {source: 'path'}
},
{
arg: 'nickname',
type: 'String',
required: true
},
{
arg: 'city',
type: 'String',
required: true
},
{
arg: 'street',
type: 'String',
required: true
},
{
arg: 'phone',
type: 'String'
},
{
arg: 'mobile',
type: 'String'
},
{
arg: 'postalCode',
type: 'String'
},
{
arg: 'provinceId',
type: 'Number'
},
{
arg: 'agencyModeId',
type: 'Number'
},
{
arg: 'incotermsId',
type: 'String'
},
{
arg: 'customsAgentId',
type: 'Number'
},
{
arg: 'isActive',
type: 'Boolean'
},
{
arg: 'isDefaultAddress',
type: 'Boolean'
}],
returns: {
root: true,
type: 'Object'
},
http: {
verb: 'post',
path: '/:id/createAddress'
}
});
Self.createAddress = async(ctx, clientId) => {
const models = Self.app.models;
const args = ctx.args;
const tx = await models.Address.beginTransaction({});
try {
const options = {transaction: tx};
const province = await models.Province.findById(args.provinceId, {
include: {
relation: 'country'
}
}, options);
const isUeeMember = province.country().isUeeMember;
if (!isUeeMember && !args.incotermsId)
throw new UserError(`Incoterms is required for a non UEE member`);
if (!isUeeMember && !args.customsAgentId)
throw new UserError(`Customs agent is required for a non UEE member`);
const newAddress = await models.Address.create({
clientFk: clientId,
nickname: args.nickname,
incotermsFk: args.incotermsId,
customsAgentFk: args.customsAgentId,
city: args.city,
street: args.street,
phone: args.phone,
postalCode: args.postalCode,
provinceFk: args.provinceId,
agencyModeFk: args.agencyModeId,
isActive: args.isActive
}, options);
const client = await Self.findById(clientId, null, options);
if (args.isDefaultAddress) {
await client.updateAttributes({
defaultAddressFk: newAddress.id
}, options);
}
await tx.commit();
return newAddress;
} catch (e) {
await tx.rollback();
throw e;
}
};
};

View File

@ -0,0 +1,87 @@
const app = require('vn-loopback/server/server');
describe('Address createAddress', () => {
const clientId = 101;
const provinceId = 5;
const incotermsId = 'FAS';
const customAgentOneId = 1;
let address;
let client;
afterAll(async done => {
await client.updateAttributes({defaultAddressFk: 1});
await address.destroy();
done();
});
it('should throw a non uee member error if no incoterms is defined', async() => {
const expectedResult = 'My edited address';
const ctx = {
args: {
provinceId: provinceId,
nickname: expectedResult,
street: 'Wall Street',
city: 'New York',
customsAgentId: customAgentOneId
}
};
try {
await app.models.Client.createAddress(ctx, clientId);
} catch (e) {
err = e;
}
expect(err).toBeDefined();
expect(err.message).toEqual('Incoterms is required for a non UEE member');
});
it('should throw a non uee member error if no customsAgent is defined', async() => {
const expectedResult = 'My edited address';
const ctx = {
args: {
provinceId: provinceId,
nickname: expectedResult,
street: 'Wall Street',
city: 'New York',
incotermsId: incotermsId
}
};
try {
await app.models.Client.createAddress(ctx, clientId);
} catch (e) {
err = e;
}
expect(err).toBeDefined();
expect(err.message).toEqual('Customs agent is required for a non UEE member');
});
it('should verify that client defaultAddressFk is untainted', async() => {
client = await app.models.Client.findById(clientId);
expect(client.defaultAddressFk).toEqual(1);
});
it('should create a new address and set as a client default address', async() => {
const ctx = {
args: {
provinceId: 1,
nickname: 'My address',
street: 'Wall Street',
city: 'New York',
incotermsId: incotermsId,
customsAgentId: customAgentOneId,
isDefaultAddress: true
}
};
address = await app.models.Client.createAddress(ctx, clientId);
client = await app.models.Client.findById(clientId);
expect(client.defaultAddressFk).toEqual(address.id);
});
});

View File

@ -0,0 +1,100 @@
const app = require('vn-loopback/server/server');
describe('Address updateAddress', () => {
const clientId = 101;
const addressId = 1;
const provinceId = 5;
const incotermsId = 'FAS';
const customAgentOneId = 1;
let oldAddress;
let address;
afterAll(async done => {
await address.updateAttributes({
nickname: oldAddress.nickname,
provinceFk: 1,
customsAgentFk: null,
incotermsFk: null
});
done();
});
it('should throw a non uee member error if no incoterms is defined', async() => {
const expectedResult = 'My edited address';
const ctx = {
args: {
provinceFk: provinceId,
nickname: expectedResult,
customsAgentFk: customAgentOneId
}
};
try {
await app.models.Client.updateAddress(ctx, clientId, addressId);
} catch (e) {
err = e;
}
expect(err).toBeDefined();
expect(err.message).toEqual('Incoterms is required for a non UEE member');
});
it('should throw a non uee member error if no customsAgent is defined', async() => {
const expectedResult = 'My edited address';
const ctx = {
args: {
provinceFk: provinceId,
nickname: expectedResult,
incotermsFk: incotermsId
}
};
try {
await app.models.Client.updateAddress(ctx, clientId, addressId);
} catch (e) {
err = e;
}
expect(err).toBeDefined();
expect(err.message).toEqual('Customs agent is required for a non UEE member');
});
it('should update the adress from a non uee member and not throw an error', async() => {
const expectedResult = 'My edited address';
const ctx = {
args: {
provinceFk: provinceId,
nickname: expectedResult,
incotermsFk: incotermsId,
customsAgentFk: customAgentOneId
}
};
oldAddress = await app.models.Address.findById(addressId);
await app.models.Client.updateAddress(ctx, clientId, addressId);
address = await app.models.Address.findById(addressId);
expect(address.nickname).toEqual(expectedResult);
});
it('should update the address', async() => {
const expectedResult = 'My second time edited address';
const ctx = {
args: {
nickname: expectedResult
}
};
oldAddress = await app.models.Address.findById(addressId);
await app.models.Client.updateAddress(ctx, clientId, addressId);
address = await app.models.Address.findById(addressId);
expect(address.nickname).toEqual(expectedResult);
});
});

View File

@ -0,0 +1,119 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = function(Self) {
Self.remoteMethod('updateAddress', {
description: 'Updates a client address updating default address',
accepts: [{
arg: 'ctx',
type: 'Object',
http: {source: 'context'}
},
{
arg: 'clientId',
type: 'Number',
description: 'The client id',
http: {source: 'path'}
},
{
arg: 'addressId',
type: 'Number',
description: 'The address id',
http: {source: 'path'}
},
{
arg: 'nickname',
type: 'String'
},
{
arg: 'city',
type: 'String'
},
{
arg: 'street',
type: 'String'
},
{
arg: 'phone',
type: 'String'
},
{
arg: 'mobile',
type: 'String'
},
{
arg: 'postalCode',
type: 'String'
},
{
arg: 'provinceFk',
type: 'Number'
},
{
arg: 'agencyModeFk',
type: 'Number'
},
{
arg: 'incotermsFk',
type: 'String'
},
{
arg: 'customsAgentFk',
type: 'Number'
},
{
arg: 'isActive',
type: 'Boolean'
},
{
arg: 'isEqualizated',
type: 'Boolean'
}],
returns: {
root: true,
type: 'Object'
},
http: {
verb: 'patch',
path: '/:clientId/updateAddress/:addressId'
}
});
Self.updateAddress = async(ctx, clientId, addressId) => {
const models = Self.app.models;
const args = ctx.args;
const tx = await models.Address.beginTransaction({});
try {
const options = {transaction: tx};
const address = await models.Address.findOne({
where: {
id: addressId,
clientFk: clientId
}
});
const provinceId = args.provinceFk || address.provinceFk;
const province = await models.Province.findById(provinceId, {
include: {
relation: 'country'
}
}, options);
const isUeeMember = province.country().isUeeMember;
const incotermsId = args.incotermsFk || address.incotermsFk;
if (!isUeeMember && !incotermsId)
throw new UserError(`Incoterms is required for a non UEE member`);
const customsAgentId = args.customsAgentFk || address.customsAgentFk;
if (!isUeeMember && !customsAgentId)
throw new UserError(`Customs agent is required for a non UEE member`);
delete args.ctx; // Remove unwanted properties
const updatedAddress = await address.updateAttributes(ctx.args, options);
await tx.commit();
return updatedAddress;
} catch (e) {
await tx.rollback();
throw e;
}
};
};

View File

@ -3,9 +3,6 @@ let getFinalState = require('vn-loopback/util/hook').getFinalState;
let isMultiple = require('vn-loopback/util/hook').isMultiple;
module.exports = Self => {
// Methods
require('../methods/address/createDefaultAddress')(Self);
Self.validateAsync('isEqualizated', cannotHaveET, {
message: 'Cannot check Equalization Tax in this NIF/CIF'
});
@ -25,35 +22,6 @@ module.exports = Self => {
done();
}
Self.validateAsync('customsAgentFk', validateCustomsAgent,
{message: 'Customs agent is required for a non UEE member'}
);
async function validateCustomsAgent(err, done) {
if (!await isUeeMember(this.provinceFk) && !this.customsAgentFk) err();
done();
}
Self.validateAsync('incotermsFk', validateIncoterms,
{message: 'Incoterms is required for a non UEE member'}
);
async function validateIncoterms(err, done) {
if (!await isUeeMember(this.provinceFk) && !this.incotermsFk) err();
done();
}
async function isUeeMember(provinceId) {
const models = Self.app.models;
const province = await models.Province.findById(provinceId, {
include: {
relation: 'country'
}
});
return province.country().isUeeMember;
}
Self.validateAsync('postalCode', hasValidPostcode, {
message: `The postcode doesn't exists. Ensure you put the correct format`
});

View File

@ -25,6 +25,8 @@ module.exports = Self => {
require('../methods/client/uploadFile')(Self);
require('../methods/client/lastActiveTickets')(Self);
require('../methods/client/sendSms')(Self);
require('../methods/client/createAddress')(Self);
require('../methods/client/updateAddress')(Self);
// Validations

View File

@ -2,9 +2,10 @@ const app = require('vn-loopback/server/server');
describe('loopback model address', () => {
let createdAddressId;
const clientId = 101;
afterAll(async done => {
let client = await app.models.Client.findById(101);
let client = await app.models.Client.findById(clientId);
await app.models.Address.destroyById(createdAddressId);
await client.updateAttribute('isEqualizated', false);
@ -28,14 +29,14 @@ describe('loopback model address', () => {
});
it('should set isEqualizated to true of a given Client to trigger any new address to have it', async() => {
let client = await app.models.Client.findById(101);
let client = await app.models.Client.findById(clientId);
expect(client.isEqualizated).toBeFalsy();
await client.updateAttribute('isEqualizated', true);
let newAddress = await app.models.Address.create({
clientFk: 101,
clientFk: clientId,
agencyModeFk: 5,
city: 'here',
isActive: true,
@ -44,7 +45,9 @@ describe('loopback model address', () => {
phone: '555555555',
postalCode: '46000',
provinceFk: 1,
street: 'Test address'
street: 'Test address',
incotermsFk: 'FAS',
customsAgentFk: 1
});
expect(newAddress.isEqualizated).toBeTruthy();

View File

@ -1,8 +1,9 @@
<vn-watcher
vn-id="watcher"
url="Addresses/createDefaultAddress"
url="Clients/{{$ctrl.$params.id}}/createAddress"
id-field="id"
data="$ctrl.data"
data="$ctrl.address"
params="$ctrl.address"
save="post"
form="form">
</vn-watcher>
@ -19,7 +20,7 @@
<vn-horizontal>
<vn-check
vn-one
label="Default" ng-model="$ctrl.data.isDefaultAddress">
label="Default" ng-model="$ctrl.address.isDefaultAddress">
</vn-check>
</vn-horizontal>
<vn-horizontal>
@ -41,7 +42,7 @@
<vn-autocomplete
vn-one
vn-id="province"
ng-model="$ctrl.address.provinceFk"
ng-model="$ctrl.address.provinceId"
url="Provinces"
show-field="name"
value-field="id"
@ -97,7 +98,7 @@
<vn-horizontal>
<vn-autocomplete
vn-one
ng-model="$ctrl.address.agencyModeFk"
ng-model="$ctrl.address.agencyModeId"
url="AgencyModes/isActive"
show-field="name"
value-field="id"
@ -118,14 +119,14 @@
</vn-horizontal>
<vn-horizontal>
<vn-autocomplete vn-one
ng-model="$ctrl.address.incotermsFk"
ng-model="$ctrl.address.incotermsId"
url="Incoterms"
show-field="name"
value-field="code"
label="Incoterms">
</vn-autocomplete>
<vn-autocomplete vn-one
ng-model="$ctrl.address.customsAgentFk"
ng-model="$ctrl.address.customsAgentId"
url="CustomsAgents"
show-field="fiscalName"
value-field="id"

View File

@ -5,14 +5,10 @@ export default class Controller extends Component {
constructor($element, $) {
super($element, $);
this.data = {
address: {
clientFk: parseInt(this.$params.id),
isActive: true
},
this.address = {
isActive: true,
isDefaultAddress: false
};
this.address = this.data.address;
}
get postcodeSelection() {
@ -37,7 +33,7 @@ export default class Controller extends Component {
onSubmit() {
this.$.watcher.submit().then(res => {
if (res.data && this.data.isDefaultAddress)
if (this.address.isDefaultAddress)
this.client.defaultAddressFk = res.data.id;
this.$state.go('client.card.address.index');

View File

@ -30,14 +30,13 @@ describe('Client', () => {
}));
it('should define and set address property', () => {
expect(controller.data.address.clientFk).toBe(1234);
expect(controller.data.address.isActive).toBe(true);
expect(controller.address.isActive).toBe(true);
});
describe('onSubmit()', () => {
it('should perform a PATCH and not set value to defaultAddressFk property', () => {
spyOn(controller.$state, 'go');
controller.data.isDefaultAddress = false;
controller.address.isDefaultAddress = false;
controller.onSubmit();
expect(controller.client.defaultAddressFk).toEqual(121);
@ -46,7 +45,7 @@ describe('Client', () => {
it('should perform a PATCH and set a value to defaultAddressFk property', () => {
spyOn(controller.$state, 'go');
controller.data.isDefaultAddress = true;
controller.address.isDefaultAddress = true;
controller.onSubmit();
expect(controller.client.defaultAddressFk).toEqual(124);

View File

@ -6,9 +6,9 @@
</mg-ajax>
<vn-watcher
vn-id="watcher"
data="$ctrl.address"
url="Addresses"
url="Clients/{{$ctrl.$params.id}}/updateAddress"
id-field="id"
data="$ctrl.address"
form="form">
</vn-watcher>
<vn-crud-model
@ -59,7 +59,7 @@
<vn-autocomplete
vn-one
vn-id="province"
ng-model="$ctrl.address.provinceFk"
ng-model="$ctrl.address.provinceId"
url="Provinces"
show-field="name"
value-field="id"
@ -111,8 +111,7 @@
</vn-horizontal>
<vn-horizontal>
<vn-autocomplete vn-one
initial-data="$ctrl.address.agencyMode"
ng-model="$ctrl.address.agencyModeFk"
ng-model="$ctrl.address.agencyModeId"
url="AgencyModes/isActive"
show-field="name"
value-field="id"
@ -133,14 +132,14 @@
</vn-horizontal>
<vn-horizontal>
<vn-autocomplete vn-one
ng-model="$ctrl.address.incotermsFk"
ng-model="$ctrl.address.incotermsId"
url="Incoterms"
show-field="name"
value-field="code"
label="Incoterms">
</vn-autocomplete>
<vn-autocomplete vn-one
ng-model="$ctrl.address.customsAgentFk"
ng-model="$ctrl.address.customsAgentId"
url="CustomsAgents"
show-field="fiscalName"
value-field="id"

View File

@ -20,11 +20,9 @@ export default class Controller extends Component {
}
onSubmit() {
this.$.watcher.check();
this.$.watcher.realSubmit()
this.$.watcher.submit()
.then(() => this.$.model.save(true))
.then(() => {
this.$.watcher.notifySaved();
this.card.reload();
this.goToIndex();
});