Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 2034-postcode_autocomplete
gitea/salix/pipeline/head There was a failure building this commit Details

This commit is contained in:
Joan Sanchez 2020-03-02 08:07:14 +01:00
commit 5ccc79df8c
233 changed files with 1767 additions and 689 deletions

View File

@ -32,3 +32,5 @@ rules:
indent: [error, 4] indent: [error, 4]
arrow-parens: [error, as-needed] arrow-parens: [error, as-needed]
jasmine/no-focused-tests: 0 jasmine/no-focused-tests: 0
no-multiple-empty-lines: ["error", { "max": 1, "maxEOF": 1 }]
space-in-parens: ["error", "never"]

View File

@ -24,8 +24,14 @@ module.exports = Self => {
}); });
Self.sendCheckingPresence = async(ctx, workerId, message) => { Self.sendCheckingPresence = async(ctx, workerId, message) => {
if (!workerId) return false;
const models = Self.app.models; const models = Self.app.models;
const account = await models.Account.findById(workerId); const account = await models.Account.findById(workerId);
const userId = ctx.req.accessToken.userId;
if (!account)
throw new Error(`Could not send message "${message}" to worker id ${workerId} from user ${userId}`);
const query = `SELECT worker_isWorking(?) isWorking`; const query = `SELECT worker_isWorking(?) isWorking`;
const [result] = await Self.rawSql(query, [workerId]); const [result] = await Self.rawSql(query, [workerId]);
@ -37,7 +43,7 @@ module.exports = Self => {
} }
}); });
const department = workerDepartment && workerDepartment.department(); const department = workerDepartment && workerDepartment.department();
const channelName = department.chatName; const channelName = department && department.chatName;
if (channelName) if (channelName)
return Self.send(ctx, `#${channelName}`, `@${account.name} => ${message}`); return Self.send(ctx, `#${channelName}`, `@${account.name} => ${message}`);

View File

@ -0,0 +1,6 @@
ALTER TABLE `vn`.`sample`
ADD COLUMN `hasPreview` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1' AFTER `hasCompany`,
CHANGE COLUMN `isVisible` `isVisible` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1' ,
CHANGE COLUMN `hasCompany` `hasCompany` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0' ;
UPDATE `vn`.`sample` SET `hasPreview` = '0' WHERE (`id` = '14');

View File

@ -0,0 +1,2 @@
ALTER TABLE `vn`.`zoneEvent`
ADD COLUMN m3Max DECIMAL(10,2) UNSIGNED NULL DEFAULT NULL AFTER bonus;

View File

@ -1103,11 +1103,11 @@ INSERT INTO `vn`.`annualAverageInvoiced`(`clientFk`, `invoiced`)
(104, 500), (104, 500),
(105, 5000); (105, 5000);
INSERT INTO `vn`.`supplier`(`id`, `name`,`account`,`countryFk`,`nif`,`isFarmer`,`retAccount`,`commission`, `created`, `postcodeFk`, `isActive`, `street`, `city`, `provinceFk`, `postCode`, `payMethodFk`, `payDemFk`) INSERT INTO `vn`.`supplier`(`id`, `name`, `nickname`,`account`,`countryFk`,`nif`,`isFarmer`,`retAccount`,`commission`, `created`, `postcodeFk`, `isActive`, `street`, `city`, `provinceFk`, `postCode`, `payMethodFk`, `payDemFk`)
VALUES VALUES
(1, 'Plants SL', 4000000001, 1, 'A11111111', 0, NULL, 0, CURDATE(), 1111, 1, 'supplier address 1', 'PONTEVEDRA', 1, 15214, 1, 1), (1, 'Plants SL', 'Plants nick', 4000000001, 1, 'A11111111', 0, NULL, 0, CURDATE(), 1111, 1, 'supplier address 1', 'PONTEVEDRA', 1, 15214, 1, 1),
(2, 'Flower King', 4000000002, 1, 'B22222222', 0, NULL, 0, CURDATE(), 2222, 1, 'supplier address 2', 'LONDON', 2, 45671, 1, 2), (2, 'Flower King', 'The king', 4000000002, 1, 'B22222222', 0, NULL, 0, CURDATE(), 2222, 1, 'supplier address 2', 'LONDON', 2, 45671, 1, 2),
(442, 'Verdnatura Levante SL', 4000000442, 1, 'C33333333', 0, NULL, 0, CURDATE(), 3333, 1, 'supplier address 3', 'SILLA', 1, 43022, 1, 2); (442, 'Verdnatura Levante SL', 'Verdnatura', 4000000442, 1, 'C33333333', 0, NULL, 0, CURDATE(), 3333, 1, 'supplier address 3', 'SILLA', 1, 43022, 1, 2);
INSERT INTO `cache`.`cache_calc`(`id`, `cache_id`, `cacheName`, `params`, `last_refresh`, `expires`, `created`, `connection_id`) INSERT INTO `cache`.`cache_calc`(`id`, `cache_id`, `cacheName`, `params`, `last_refresh`, `expires`, `created`, `connection_id`)
VALUES VALUES

View File

@ -40,16 +40,12 @@ let actions = {
}, },
login: async function(userName) { login: async function(userName) {
try { await this.goto(`${defaultURL}/#!/login`);
await this.expectURL('#!/login'); let dialog = await this.evaluate(() => {
} catch (e) { return document.querySelector('button[response="accept"]');
await this.goto(`${defaultURL}/#!/login`); });
let dialog = await this.evaluate(() => { if (dialog)
return document.querySelector('button[response="accept"]'); await this.waitToClick('button[response="accept"]');
});
if (dialog)
await this.waitToClick('button[response="accept"]');
}
await this.doLogin(userName); await this.doLogin(userName);
await this.waitForFunction(() => { await this.waitForFunction(() => {
@ -175,7 +171,7 @@ let actions = {
}, },
waitToClick: async function(selector) { waitToClick: async function(selector) {
await this.waitForSelector(selector, {}); await this.waitForSelector(selector);
await this.click(selector); await this.click(selector);
}, },
@ -327,11 +323,18 @@ let actions = {
}, },
hideSnackbar: async function() { hideSnackbar: async function() {
await this.waitToClick('#shapes .shown button'); await this.waitFor(750); // holds up for the snackbar to be visible for a small period of time.
await this.evaluate(() => {
let hideButton = document.querySelector('#shapes .shown button');
if (hideButton)
return document.querySelector('#shapes .shown button').click();
});
}, },
waitForLastShape: async function(selector) { waitForLastSnackbar: async function() {
await this.wait(selector); const selector = 'vn-snackbar .shown .text';
await this.waitForSelector(selector);
let snackBarText = await this.evaluate(selector => { let snackBarText = await this.evaluate(selector => {
const shape = document.querySelector(selector); const shape = document.querySelector(selector);
@ -341,12 +344,6 @@ let actions = {
return snackBarText; return snackBarText;
}, },
waitForLastSnackbar: async function() {
await this.waitFor(1000); // this needs a refactor to be somehow dynamic ie: page.waitForResponse(urlOrPredicate[, options]) or something to fire waitForLastShape once the request is completed
await this.waitForSpinnerLoad();
return await this.waitForLastShape('vn-snackbar .shown .text');
},
accessToSearchResult: async function(searchValue) { accessToSearchResult: async function(searchValue) {
await this.clearInput('vn-searchbar'); await this.clearInput('vn-searchbar');
await this.write('vn-searchbar', searchValue); await this.write('vn-searchbar', searchValue);
@ -412,7 +409,7 @@ let actions = {
.includes(searchValue.toLowerCase()); .includes(searchValue.toLowerCase());
}, {}, builtSelector, searchValue); }, {}, builtSelector, searchValue);
await this.waitForMutation(`.vn-drop-down`, 'childList'); await this.waitForMutation('.vn-drop-down', 'childList');
await this.waitForContentLoaded(); await this.waitForContentLoaded();
}, },

View File

@ -28,7 +28,7 @@ export async function getBrowser() {
}); });
}); });
page = extendPage(page); page = extendPage(page);
page.setDefaultTimeout(5000); page.setDefaultTimeout(10000);
await page.goto(defaultURL, {waitUntil: 'networkidle0'}); await page.goto(defaultURL, {waitUntil: 'networkidle0'});
return {page, close: browser.close.bind(browser)}; return {page, close: browser.close.bind(browser)};
} }

View File

@ -511,14 +511,16 @@ export default {
}, },
ticketRequests: { ticketRequests: {
addRequestButton: 'vn-ticket-request-index > a > vn-float-button > button', addRequestButton: 'vn-ticket-request-index > a > vn-float-button > button',
request: 'vn-ticket-request-index vn-table vn-tr',
descriptionInput: 'vn-ticket-request-create [ng-model="$ctrl.ticketRequest.description"]', descriptionInput: 'vn-ticket-request-create [ng-model="$ctrl.ticketRequest.description"]',
atender: 'vn-ticket-request-create vn-autocomplete[ng-model="$ctrl.ticketRequest.attenderFk"]', atender: 'vn-ticket-request-create vn-autocomplete[ng-model="$ctrl.ticketRequest.attenderFk"]',
quantity: 'vn-ticket-request-create vn-input-number[ng-model="$ctrl.ticketRequest.quantity"]', quantity: 'vn-ticket-request-create vn-input-number[ng-model="$ctrl.ticketRequest.quantity"]',
price: 'vn-ticket-request-create vn-input-number[ng-model="$ctrl.ticketRequest.price"]', price: 'vn-ticket-request-create vn-input-number[ng-model="$ctrl.ticketRequest.price"]',
firstRemoveRequestButton: 'vn-ticket-request-index vn-icon[icon="delete"]:nth-child(1)', firstRequestQuantity: 'vn-ticket-request-index vn-table vn-tr:nth-child(1) > vn-td:nth-child(6) vn-input-number',
secondRequestQuantity: 'vn-ticket-request-index vn-table vn-tr:nth-child(2) > vn-td:nth-child(6) vn-input-number',
thirdDescription: 'vn-ticket-request-index vn-table vn-tr:nth-child(3) > vn-td:nth-child(2) vn-textfield',
thirdRemoveRequestButton: 'vn-ticket-request-index vn-tr:nth-child(3) vn-icon[icon="delete"]',
thirdRequestQuantity: 'vn-ticket-request-index vn-table vn-tr:nth-child(3) > vn-td:nth-child(6) vn-input-number',
saveButton: 'vn-ticket-request-create button[type=submit]', saveButton: 'vn-ticket-request-create button[type=submit]',
firstDescription: 'vn-ticket-request-index vn-table vn-tr:nth-child(1) > vn-td:nth-child(2) vn-textfield',
}, },
ticketLog: { ticketLog: {
@ -788,7 +790,7 @@ export default {
createdThermograph: 'vn-travel-thermograph-index vn-tbody > vn-tr', createdThermograph: 'vn-travel-thermograph-index vn-tbody > vn-tr',
upload: 'vn-travel-thermograph-create button[type=submit]' upload: 'vn-travel-thermograph-create button[type=submit]'
}, },
agencyBasicData: { zoneBasicData: {
name: 'vn-zone-basic-data vn-textfield[ng-model="$ctrl.zone.name"]', name: 'vn-zone-basic-data vn-textfield[ng-model="$ctrl.zone.name"]',
agency: 'vn-zone-basic-data vn-autocomplete[ng-model="$ctrl.zone.agencyModeFk"]', agency: 'vn-zone-basic-data vn-autocomplete[ng-model="$ctrl.zone.agencyModeFk"]',
maxVolume: 'vn-zone-basic-data vn-input-number[ng-model="$ctrl.zone.m3Max"]', maxVolume: 'vn-zone-basic-data vn-input-number[ng-model="$ctrl.zone.m3Max"]',
@ -799,5 +801,10 @@ export default {
inflation: 'vn-zone-basic-data vn-input-number[ng-model="$ctrl.zone.inflation"]', inflation: 'vn-zone-basic-data vn-input-number[ng-model="$ctrl.zone.inflation"]',
volumetric: 'vn-zone-basic-data vn-check[ng-model="$ctrl.zone.isVolumetric"]', volumetric: 'vn-zone-basic-data vn-check[ng-model="$ctrl.zone.isVolumetric"]',
saveButton: 'vn-zone-basic-data vn-submit > button', saveButton: 'vn-zone-basic-data vn-submit > button',
},
entrySummary: {
header: 'vn-entry-summary > vn-card > h5',
reference: 'vn-entry-summary vn-label-value[label="Reference"]',
confirmed: 'vn-entry-summary vn-check[label="Confirmed"]',
} }
}; };

View File

@ -101,7 +101,6 @@ describe('Client create path', async() => {
}); });
it('should click on the Clients button of the top bar menu', async() => { it('should click on the Clients button of the top bar menu', async() => {
await page.waitFor(500);
await page.waitToClick(selectors.globalItems.applicationsMenuButton); await page.waitToClick(selectors.globalItems.applicationsMenuButton);
await page.wait(selectors.globalItems.applicationsMenuVisible); await page.wait(selectors.globalItems.applicationsMenuVisible);
await page.waitToClick(selectors.globalItems.clientsButton); await page.waitToClick(selectors.globalItems.clientsButton);

View File

@ -160,6 +160,7 @@ describe('Client Edit fiscalData path', () => {
}); });
it('should propagate the Equalization tax changes', async() => { it('should propagate the Equalization tax changes', async() => {
await page.waitFor(1000);
await page.waitToClick(selectors.clientFiscalData.acceptPropagationButton); await page.waitToClick(selectors.clientFiscalData.acceptPropagationButton);
const result = await page.waitForLastSnackbar(); const result = await page.waitForLastSnackbar();

View File

@ -47,7 +47,7 @@ describe('Client Add address path', () => {
expect(result).toEqual('Incoterms is required for a non UEE member'); expect(result).toEqual('Incoterms is required for a non UEE member');
}); });
it(`should receive an error after clicking save button as consignee, incoterms and customsAgent are empty`, async() => { it(`should receive an error after clicking save button as customsAgent is empty`, async() => {
await page.autocompleteSearch(selectors.clientAddresses.incoterms, 'Free Alongside Ship'); await page.autocompleteSearch(selectors.clientAddresses.incoterms, 'Free Alongside Ship');
await page.waitToClick(selectors.clientAddresses.saveButton); await page.waitToClick(selectors.clientAddresses.saveButton);
const result = await page.waitForLastSnackbar(); const result = await page.waitForLastSnackbar();
@ -63,13 +63,20 @@ describe('Client Add address path', () => {
expect(result).toEqual('Data saved!'); expect(result).toEqual('Data saved!');
}); });
it(`should click on the first address button to confirm the new address exists and it's the default one`, async() => { it(`should navigate back to the addresses index`, async() => {
let url = await page.expectURL('/address/index');
expect(url).toBe(true);
});
it(`should confirm the new address exists and it's the default one`, async() => {
await page.waitFor(2000); // needs more than a single second to load the section
const result = await page.waitToGetProperty(selectors.clientAddresses.defaultAddress, 'innerText'); const result = await page.waitToGetProperty(selectors.clientAddresses.defaultAddress, 'innerText');
expect(result).toContain('320 Park Avenue New York'); expect(result).toContain('320 Park Avenue New York');
}); });
it(`should click on the make default icon of the second address`, async() => { it('should click on the make default icon of the second address', async() => {
await page.waitToClick(selectors.clientAddresses.secondMakeDefaultStar); await page.waitToClick(selectors.clientAddresses.secondMakeDefaultStar);
const result = await page.waitForLastSnackbar(); const result = await page.waitForLastSnackbar();
@ -101,6 +108,7 @@ describe('Client Add address path', () => {
}); });
it(`should go back to the addreses section by clicking the cancel button`, async() => { it(`should go back to the addreses section by clicking the cancel button`, async() => {
await page.waitForSelector('#shapes .shown', {hidden: true});
await page.waitToClick(selectors.clientAddresses.cancelEditAddressButton); await page.waitToClick(selectors.clientAddresses.cancelEditAddressButton);
await page.waitToClick('.vn-confirm.shown button[response="accept"]'); await page.waitToClick('.vn-confirm.shown button[response="accept"]');
let url = await page.expectURL('address/index'); let url = await page.expectURL('address/index');

View File

@ -1,7 +1,7 @@
import selectors from '../../helpers/selectors'; import selectors from '../../helpers/selectors';
import getBrowser from '../../helpers/puppeteer'; import getBrowser from '../../helpers/puppeteer';
describe('Client lock verified data path', () => { xdescribe('Client lock verified data path', () => {
let browser; let browser;
let page; let page;
beforeAll(async() => { beforeAll(async() => {
@ -113,7 +113,7 @@ describe('Client lock verified data path', () => {
}); });
}); });
describe('as salesAssistant', () => { xdescribe('as salesAssistant', () => {
it('should log in as salesAssistant then get to the client fiscal data', async() => { it('should log in as salesAssistant then get to the client fiscal data', async() => {
await page.forceReloadSection('client.card.fiscalData'); await page.forceReloadSection('client.card.fiscalData');
await page.loginAndModule('salesAssistant', 'client'); await page.loginAndModule('salesAssistant', 'client');

View File

@ -85,7 +85,7 @@ describe('User config', () => {
await page.autocompleteSearch(selectors.globalItems.userLocalCompany, 'VNL'); await page.autocompleteSearch(selectors.globalItems.userLocalCompany, 'VNL');
let result = await page.waitForLastSnackbar(); let result = await page.waitForLastSnackbar();
expect(result).toEqual('Data saved!'); expect(result).toContain('Data saved!');
}); });
}); });
@ -125,7 +125,7 @@ describe('User config', () => {
await page.clearInput(selectors.globalItems.userConfigThirdAutocomplete); await page.clearInput(selectors.globalItems.userConfigThirdAutocomplete);
let result = await page.waitForLastSnackbar(); let result = await page.waitForLastSnackbar();
expect(result).toEqual('Data saved!'); expect(result).toContain('Data saved!');
}); });
}); });
}); });

View File

@ -32,6 +32,6 @@ describe('Client contacts', () => {
await page.waitToClick(selectors.clientContacts.saveButton); await page.waitToClick(selectors.clientContacts.saveButton);
let result = await page.waitForLastSnackbar(); let result = await page.waitForLastSnackbar();
expect(result).toEqual('Data saved!'); expect(result).toContain('Data saved!');
}); });
}); });

View File

@ -1,7 +1,7 @@
import selectors from '../../helpers/selectors.js'; import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer'; import getBrowser from '../../helpers/puppeteer';
describe('Worker time control path', () => { xdescribe('Worker time control path', () => {
let browser; let browser;
let page; let page;
beforeAll(async() => { beforeAll(async() => {

View File

@ -37,22 +37,21 @@ describe('Item Edit basic data path', () => {
const result = await page.waitForLastSnackbar(); const result = await page.waitForLastSnackbar();
expect(result).toEqual('Data saved!'); expect(result).toEqual('Data saved!');
}, 20000); });
it(`should create a new intrastat`, async() => { it(`should create a new intrastat`, async() => {
await page.waitToClick(selectors.itemBasicData.newIntrastatButton); await page.waitToClick(selectors.itemBasicData.newIntrastatButton);
await page.write(selectors.itemBasicData.newIntrastatId, '588420239'); await page.write(selectors.itemBasicData.newIntrastatId, '588420239');
await page.write(selectors.itemBasicData.newIntrastatDescription, 'Tropical Flowers'); await page.write(selectors.itemBasicData.newIntrastatDescription, 'Tropical Flowers');
await page.waitToClick(selectors.itemBasicData.acceptIntrastatButton); await page.waitToClick(selectors.itemBasicData.acceptIntrastatButton); // this popover obscures the rest of the form for aprox 2 seconds
await page.waitFor(2000);
await page.waitForTextInField(selectors.itemBasicData.intrastat, 'Tropical Flowers'); await page.waitForTextInField(selectors.itemBasicData.intrastat, 'Tropical Flowers');
let newcode = await page.waitToGetProperty(selectors.itemBasicData.intrastat, 'value'); let newcode = await page.waitToGetProperty(selectors.itemBasicData.intrastat, 'value');
expect(newcode).toEqual('588420239 Tropical Flowers'); expect(newcode).toEqual('588420239 Tropical Flowers');
}); });
it(`should save with the new intrastat`, async() => { it('should save with the new intrastat', async() => {
await page.waitFor(250);
await page.waitForTextInField(selectors.itemBasicData.intrastat, 'Tropical Flowers');
await page.waitToClick(selectors.itemBasicData.submitBasicDataButton); await page.waitToClick(selectors.itemBasicData.submitBasicDataButton);
const result = await page.waitForLastSnackbar(); const result = await page.waitForLastSnackbar();

View File

@ -33,7 +33,6 @@ describe('Item regularize path', () => {
}); });
it('should search for an specific item', async() => { it('should search for an specific item', async() => {
await page.clearInput(selectors.itemsIndex.topbarSearch);
await page.write(selectors.itemsIndex.topbarSearch, 'Ranged weapon pistol 9mm'); await page.write(selectors.itemsIndex.topbarSearch, 'Ranged weapon pistol 9mm');
await page.waitToClick(selectors.itemsIndex.searchButton); await page.waitToClick(selectors.itemsIndex.searchButton);
await page.waitForNumberOfElements(selectors.itemsIndex.searchResult, 1); await page.waitForNumberOfElements(selectors.itemsIndex.searchResult, 1);
@ -42,7 +41,7 @@ describe('Item regularize path', () => {
expect(resultCount).toEqual(1); expect(resultCount).toEqual(1);
}); });
it(`should click on the search result to access to the item tax`, async() => { it(`should click on the search result to access to the summary`, async() => {
await page.waitForTextInElement(selectors.itemsIndex.searchResult, 'Ranged weapon pistol 9mm'); await page.waitForTextInElement(selectors.itemsIndex.searchResult, 'Ranged weapon pistol 9mm');
await page.waitToClick(selectors.itemsIndex.searchResult); await page.waitToClick(selectors.itemsIndex.searchResult);
let url = await page.expectURL('/summary'); let url = await page.expectURL('/summary');
@ -80,6 +79,7 @@ describe('Item regularize path', () => {
}); });
it('should clear the user local settings now', async() => { it('should clear the user local settings now', async() => {
await page.waitForContentLoaded();
await page.waitToClick(selectors.globalItems.userMenuButton); await page.waitToClick(selectors.globalItems.userMenuButton);
await page.clearInput(selectors.globalItems.userConfigFirstAutocomplete); await page.clearInput(selectors.globalItems.userConfigFirstAutocomplete);
const result = await page.waitForLastSnackbar(); const result = await page.waitForLastSnackbar();

View File

@ -1,7 +1,7 @@
import selectors from '../../helpers/selectors.js'; import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer'; import getBrowser from '../../helpers/puppeteer';
describe('Item index path', () => { xdescribe('Item index path', () => {
let browser; let browser;
let page; let page;
beforeAll(async() => { beforeAll(async() => {
@ -54,7 +54,8 @@ describe('Item index path', () => {
await page.waitForSelector(selectors.itemsIndex.firstItemId, {hidden: true}); await page.waitForSelector(selectors.itemsIndex.firstItemId, {hidden: true});
}); });
it('should mark all unchecked boxes to leave the index as it was', async() => { xit('should mark all unchecked boxes to leave the index as it was', async() => {
await page.waitForContentLoaded();
await page.waitToClick(selectors.itemsIndex.fieldsToShowButton); await page.waitToClick(selectors.itemsIndex.fieldsToShowButton);
await page.waitToClick(selectors.itemsIndex.idCheckbox); await page.waitToClick(selectors.itemsIndex.idCheckbox);
await page.waitToClick(selectors.itemsIndex.stemsCheckbox); await page.waitToClick(selectors.itemsIndex.stemsCheckbox);

View File

@ -97,6 +97,7 @@ describe('Ticket List sale path', () => {
}); });
it('should select the 2nd and 3th item and delete both', async() => { it('should select the 2nd and 3th item and delete both', async() => {
await page.waitFor(2000);
await page.waitToClick(selectors.ticketSales.secondSaleCheckbox); await page.waitToClick(selectors.ticketSales.secondSaleCheckbox);
await page.waitToClick(selectors.ticketSales.thirdSaleCheckbox); await page.waitToClick(selectors.ticketSales.thirdSaleCheckbox);
await page.waitToClick(selectors.ticketSales.deleteSaleButton); await page.waitToClick(selectors.ticketSales.deleteSaleButton);

View File

@ -9,7 +9,7 @@ describe('Ticket purchase request path', () => {
browser = await getBrowser(); browser = await getBrowser();
page = browser.page; page = browser.page;
await page.loginAndModule('salesPerson', 'ticket'); await page.loginAndModule('salesPerson', 'ticket');
await page.accessToSearchResult('16'); await page.accessToSearchResult('1');
await page.accessToSection('ticket.card.request.index'); await page.accessToSection('ticket.card.request.index');
}); });
@ -17,10 +17,10 @@ describe('Ticket purchase request path', () => {
await browser.close(); await browser.close();
}); });
it(`should add a new request`, async() => { it('should add a new request', async() => {
await page.waitToClick(selectors.ticketRequests.addRequestButton); await page.waitToClick(selectors.ticketRequests.addRequestButton);
await page.write(selectors.ticketRequests.descriptionInput, 'New stuff'); await page.write(selectors.ticketRequests.descriptionInput, 'New stuff');
await page.write(selectors.ticketRequests.quantity, '99'); await page.write(selectors.ticketRequests.quantity, '9');
await page.autocompleteSearch(selectors.ticketRequests.atender, 'buyerNick'); await page.autocompleteSearch(selectors.ticketRequests.atender, 'buyerNick');
await page.write(selectors.ticketRequests.price, '999'); await page.write(selectors.ticketRequests.price, '999');
await page.waitToClick(selectors.ticketRequests.saveButton); await page.waitToClick(selectors.ticketRequests.saveButton);
@ -29,29 +29,52 @@ describe('Ticket purchase request path', () => {
expect(result).toEqual('Data saved!'); expect(result).toEqual('Data saved!');
}); });
it(`should have been redirected to the request index`, async() => { it('should have been redirected to the request index', async() => {
let url = await page.expectURL('/request'); let url = await page.expectURL('/request');
expect(url).toBe(true); expect(url).toBe(true);
}); });
it(`should confirm the new request was added`, async() => { it(`should edit the third request quantity as it's state is still new`, async() => {
await page.reloadSection('ticket.card.request.index'); await page.waitFor(2000); // looks like it needs more than a single second some times to load
const result = await page.waitToGetProperty(selectors.ticketRequests.firstDescription, 'value'); await page.write(selectors.ticketRequests.thirdRequestQuantity, '9');
await page.keyboard.press('Enter');
expect(result).toEqual('New stuff');
});
it(`should delete the added request`, async() => {
await page.waitToClick(selectors.ticketRequests.firstRemoveRequestButton);
const result = await page.waitForLastSnackbar(); const result = await page.waitForLastSnackbar();
expect(result).toEqual('Data saved!'); expect(result).toEqual('Data saved!');
}); });
it(`should confirm the request was deleted`, async() => { it('should confirm the new request was added', async() => {
await page.reloadSection('ticket.card.request.index');
const result = await page.waitToGetProperty(selectors.ticketRequests.thirdRequestQuantity, 'value');
expect(result).toEqual('99');
});
it(`should confirm first request can't be edited as its state is different to new`, async() => {
await page.waitForClassPresent(selectors.ticketRequests.firstRequestQuantity, 'disabled');
const result = await page.isDisabled(selectors.ticketRequests.firstRequestQuantity);
expect(result).toBe(true);
});
it(`should confirm second request can't be edited as its state is different to new`, async() => {
await page.waitForClassPresent(selectors.ticketRequests.secondRequestQuantity, 'disabled');
const result = await page.isDisabled(selectors.ticketRequests.secondRequestQuantity);
expect(result).toBe(true);
});
it('should delete the added request', async() => {
await page.waitToClick(selectors.ticketRequests.thirdRemoveRequestButton);
const result = await page.waitForLastSnackbar();
expect(result).toEqual('Data saved!');
});
it('should confirm the request was deleted', async() => {
await page.reloadSection('ticket.card.request.index'); await page.reloadSection('ticket.card.request.index');
await page.wait(selectors.ticketRequests.addRequestButton); await page.wait(selectors.ticketRequests.addRequestButton);
await page.waitForSelector(selectors.ticketRequests.request, {hidden: true}); await page.waitForSelector(selectors.ticketRequests.thirdDescription, {hidden: true});
}); });
}); });

View File

@ -129,6 +129,7 @@ describe('Ticket descriptor path', () => {
}); });
it('should delete the stowaway', async() => { it('should delete the stowaway', async() => {
await page.waitForContentLoaded();
await page.waitToClick(selectors.ticketDescriptor.moreMenu); await page.waitToClick(selectors.ticketDescriptor.moreMenu);
await page.waitToClick(selectors.ticketDescriptor.moreMenuDeleteStowawayButton); await page.waitToClick(selectors.ticketDescriptor.moreMenuDeleteStowawayButton);
await page.waitToClick(selectors.ticketDescriptor.acceptDeleteStowawayButton); await page.waitToClick(selectors.ticketDescriptor.acceptDeleteStowawayButton);

View File

@ -1,7 +1,7 @@
import selectors from '../../helpers/selectors.js'; import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer'; import getBrowser from '../../helpers/puppeteer';
describe('Claim action path', () => { xdescribe('Claim action path', () => {
let browser; let browser;
let page; let page;
@ -24,7 +24,8 @@ describe('Claim action path', () => {
expect(result).toEqual('Data saved!'); expect(result).toEqual('Data saved!');
}); });
it('should import the second importable ticket', async() => { xit('should import the second importable ticket', async() => {
await page.waitFor(2000); // the animation adding the header element for the claimed total obscures somehow other elements for 2 seconds
await page.waitToClick(selectors.claimAction.importTicketButton); await page.waitToClick(selectors.claimAction.importTicketButton);
await page.waitToClick(selectors.claimAction.secondImportableTicket); await page.waitToClick(selectors.claimAction.secondImportableTicket);
const result = await page.waitForLastSnackbar(); const result = await page.waitForLastSnackbar();
@ -33,6 +34,7 @@ describe('Claim action path', () => {
}); });
it('should edit the second line destination field', async() => { it('should edit the second line destination field', async() => {
await page.waitForContentLoaded();
await page.autocompleteSearch(selectors.claimAction.secondLineDestination, 'Bueno'); await page.autocompleteSearch(selectors.claimAction.secondLineDestination, 'Bueno');
const result = await page.waitForLastSnackbar(); const result = await page.waitForLastSnackbar();
@ -43,7 +45,7 @@ describe('Claim action path', () => {
await page.waitToClick(selectors.claimAction.firstDeleteLine); await page.waitToClick(selectors.claimAction.firstDeleteLine);
const result = await page.waitForLastSnackbar(); const result = await page.waitForLastSnackbar();
expect(result).toEqual('Data saved!'); expect(result).toContain('Data saved!');
}); });
it('should refresh the view to check the remaining line is the expected one', async() => { it('should refresh the view to check the remaining line is the expected one', async() => {
@ -61,6 +63,7 @@ describe('Claim action path', () => {
}); });
it('should check the "is paid with mana" checkbox', async() => { it('should check the "is paid with mana" checkbox', async() => {
page.waitFor(2500); // can't use waitForNavigation here and needs more time than a single second to get the section ready...
await page.waitToClick(selectors.claimAction.isPaidWithManaCheckbox); await page.waitToClick(selectors.claimAction.isPaidWithManaCheckbox);
const result = await page.waitForLastSnackbar(); const result = await page.waitForLastSnackbar();

View File

@ -1,7 +1,7 @@
import selectors from '../../helpers/selectors.js'; import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer'; import getBrowser from '../../helpers/puppeteer';
describe('InvoiceOut descriptor path', () => { xdescribe('InvoiceOut descriptor path', () => {
let browser; let browser;
let page; let page;
@ -26,7 +26,7 @@ describe('InvoiceOut descriptor path', () => {
expect(result).toEqual(1); expect(result).toEqual(1);
}); });
it('should navigate to the invoiceOut index', async() => { xit('should navigate to the invoiceOut index', async() => {
await page.waitToClick(selectors.globalItems.applicationsMenuButton); await page.waitToClick(selectors.globalItems.applicationsMenuButton);
await page.wait(selectors.globalItems.applicationsMenuVisible); await page.wait(selectors.globalItems.applicationsMenuVisible);
await page.waitToClick(selectors.globalItems.invoiceOutButton); await page.waitToClick(selectors.globalItems.invoiceOutButton);

View File

@ -1,103 +0,0 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Agency basic data path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('deliveryBoss', 'zone'); // turns up the agency module name and route aint the same lol
await page.accessToSearchResult('10');
await page.accessToSection('zone.card.basicData');
});
afterAll(async() => {
await browser.close();
});
it('should reach the basic data section', async() => {
let url = await page.expectURL('#!/zone/10/basic-data');
expect(url).toBe(true);
});
it('should edit de form and then save', async() => {
await page.clearInput(selectors.agencyBasicData.name);
await page.write(selectors.agencyBasicData.name, 'Brimstone teleportation');
await page.autocompleteSearch(selectors.agencyBasicData.agency, 'Quantum break device');
await page.write(selectors.agencyBasicData.maxVolume, '10');
await page.clearInput(selectors.agencyBasicData.travelingDays);
await page.write(selectors.agencyBasicData.travelingDays, '1');
await page.clearInput(selectors.agencyBasicData.closing);
await page.type(selectors.agencyBasicData.closing, '2100');
await page.clearInput(selectors.agencyBasicData.price);
await page.write(selectors.agencyBasicData.price, '999');
await page.clearInput(selectors.agencyBasicData.bonus);
await page.write(selectors.agencyBasicData.bonus, '100');
await page.clearInput(selectors.agencyBasicData.inflation);
await page.write(selectors.agencyBasicData.inflation, '200');
await page.waitToClick(selectors.agencyBasicData.volumetric);
await page.waitToClick(selectors.agencyBasicData.saveButton);
});
it('should reload the section', async() => {
await page.reloadSection('zone.card.basicData');
let url = await page.expectURL('#!/zone/10/basic-data');
expect(url).toBe(true);
});
it('should confirm the name was updated', async() => {
const result = await page.waitToGetProperty(selectors.agencyBasicData.name, 'value');
expect(result).toEqual('Brimstone teleportation');
});
it('should confirm the agency was updated', async() => {
const result = await page.waitToGetProperty(selectors.agencyBasicData.agency, 'value');
expect(result).toEqual('Quantum break device');
});
it('should confirm the max volume was updated', async() => {
const result = await page.waitToGetProperty(selectors.agencyBasicData.maxVolume, 'value');
expect(result).toEqual('10');
});
it('should confirm the traveling days were updated', async() => {
const result = await page.waitToGetProperty(selectors.agencyBasicData.travelingDays, 'value');
expect(result).toEqual('1');
});
it('should confirm the closing hour was updated', async() => {
const result = await page.waitToGetProperty(selectors.agencyBasicData.closing, 'value');
expect(result).toEqual('21:00');
});
it('should confirm the price was updated', async() => {
const result = await page.waitToGetProperty(selectors.agencyBasicData.price, 'value');
expect(result).toEqual('999');
});
it('should confirm the bonus was updated', async() => {
const result = await page.waitToGetProperty(selectors.agencyBasicData.bonus, 'value');
expect(result).toEqual('100');
});
it('should confirm the inflation was updated', async() => {
const result = await page.waitToGetProperty(selectors.agencyBasicData.inflation, 'value');
expect(result).toEqual('200');
});
it('should confirm the volumetric checkbox was checked', async() => {
await page.waitForClassPresent(selectors.agencyBasicData.volumetric, 'checked');
});
});

View File

@ -0,0 +1,103 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
xdescribe('Zone basic data path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('deliveryBoss', 'zone'); // turns up the zone module name and route aint the same lol
await page.accessToSearchResult('10');
await page.accessToSection('zone.card.basicData');
});
afterAll(async() => {
await browser.close();
});
it('should reach the basic data section', async() => {
let url = await page.expectURL('#!/zone/10/basic-data');
expect(url).toBe(true);
});
it('should edit de form and then save', async() => {
await page.clearInput(selectors.zoneBasicData.name);
await page.write(selectors.zoneBasicData.name, 'Brimstone teleportation');
await page.autocompleteSearch(selectors.zoneBasicData.agency, 'Quantum break device');
await page.write(selectors.zoneBasicData.maxVolume, '10');
await page.clearInput(selectors.zoneBasicData.travelingDays);
await page.write(selectors.zoneBasicData.travelingDays, '1');
await page.clearInput(selectors.zoneBasicData.closing);
await page.type(selectors.zoneBasicData.closing, '2100');
await page.clearInput(selectors.zoneBasicData.price);
await page.write(selectors.zoneBasicData.price, '999');
await page.clearInput(selectors.zoneBasicData.bonus);
await page.write(selectors.zoneBasicData.bonus, '100');
await page.clearInput(selectors.zoneBasicData.inflation);
await page.write(selectors.zoneBasicData.inflation, '200');
await page.waitToClick(selectors.zoneBasicData.volumetric);
await page.waitToClick(selectors.zoneBasicData.saveButton);
});
xit('should reload the section', async() => {
await page.reloadSection('zone.card.basicData');
let url = await page.expectURL('#!/zone/10/basic-data');
expect(url).toBe(true);
});
it('should confirm the name was updated', async() => {
const result = await page.waitToGetProperty(selectors.zoneBasicData.name, 'value');
expect(result).toEqual('Brimstone teleportation');
});
it('should confirm the agency was updated', async() => {
const result = await page.waitToGetProperty(selectors.zoneBasicData.agency, 'value');
expect(result).toEqual('Quantum break device');
});
it('should confirm the max volume was updated', async() => {
const result = await page.waitToGetProperty(selectors.zoneBasicData.maxVolume, 'value');
expect(result).toEqual('10');
});
it('should confirm the traveling days were updated', async() => {
const result = await page.waitToGetProperty(selectors.zoneBasicData.travelingDays, 'value');
expect(result).toEqual('1');
});
xit('should confirm the closing hour was updated', async() => {
const result = await page.waitToGetProperty(selectors.zoneBasicData.closing, 'value');
expect(result).toEqual('21:00');
});
it('should confirm the price was updated', async() => {
const result = await page.waitToGetProperty(selectors.zoneBasicData.price, 'value');
expect(result).toEqual('999');
});
it('should confirm the bonus was updated', async() => {
const result = await page.waitToGetProperty(selectors.zoneBasicData.bonus, 'value');
expect(result).toEqual('100');
});
it('should confirm the inflation was updated', async() => {
const result = await page.waitToGetProperty(selectors.zoneBasicData.inflation, 'value');
expect(result).toEqual('200');
});
it('should confirm the volumetric checkbox was checked', async() => {
await page.waitForClassPresent(selectors.zoneBasicData.volumetric, 'checked');
});
});

View File

@ -0,0 +1,43 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Entry summary path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('buyer', 'entry');
await page.waitToClick('vn-entry-index vn-tbody > a:nth-child(2)');
});
afterAll(async() => {
await browser.close();
});
it('should reach the second entry summary section', async() => {
let url = await page.expectURL('#!/entry/2/summary');
expect(url).toBe(true);
});
it(`should display details from the entry on the header`, async() => {
await page.waitForTextInElement(selectors.entrySummary.header, 'The king');
const result = await page.waitToGetProperty(selectors.entrySummary.header, 'innerText');
expect(result).toContain('The king');
});
it('should display some entry details like the reference', async() => {
const result = await page.waitToGetProperty(selectors.entrySummary.reference, 'innerText');
expect(result).toContain('Movement 2');
});
it('should display other entry details like the confirmed', async() => {
const result = await page.checkboxState(selectors.entrySummary.confirmed, 'innerText');
expect(result).toContain('unchecked');
});
});

View File

@ -16,7 +16,7 @@ describe('Component vnButtonMenu', () => {
describe('onButtonClick(event)', () => { describe('onButtonClick(event)', () => {
it(`should emit the open event`, () => { it(`should emit the open event`, () => {
spyOn(controller, 'emit'); jest.spyOn(controller, 'emit');
let event = new MouseEvent('click', { let event = new MouseEvent('click', {
view: controller.element.window, view: controller.element.window,
@ -31,7 +31,7 @@ describe('Component vnButtonMenu', () => {
describe('onDropDownSelect(value)', () => { describe('onDropDownSelect(value)', () => {
it(`should set field to the given value and emit the change event`, () => { it(`should set field to the given value and emit the change event`, () => {
spyOn(controller, 'emit'); jest.spyOn(controller, 'emit');
controller.onDropDownSelect({name: 'Item name'}); controller.onDropDownSelect({name: 'Item name'});
expect(controller.field).toBe('Item name'); expect(controller.field).toBe('Item name');

View File

@ -23,7 +23,7 @@
<section <section
ng-repeat="day in ::$ctrl.weekDays" ng-repeat="day in ::$ctrl.weekDays"
translate-attr="::{title: day.name}" translate-attr="::{title: day.name}"
ng-click="$ctrl.selectWeekDay(day.index)"> ng-click="$ctrl.selectWeekDay($event, day.index)">
<span>{{::day.localeChar}}</span> <span>{{::day.localeChar}}</span>
</section> </section>
</div> </div>
@ -38,7 +38,7 @@
on-last="$ctrl.repeatLast()"> on-last="$ctrl.repeatLast()">
<div <div
class="day-number" class="day-number"
ng-click="$ctrl.select(day)"> ng-click="$ctrl.select($event, day)">
{{::day | date: 'd'}} {{::day | date: 'd'}}
</div> </div>
</section> </section>

View File

@ -127,10 +127,11 @@ export default class Calendar extends FormInput {
/* /*
* Day selection event * Day selection event
*/ */
select(day) { select($event, day) {
if (!this.editable) return; if (!this.editable) return;
this.change(day); this.change(day);
this.emit('selection', { this.emit('selection', {
$event: $event,
$days: [day], $days: [day],
$type: 'day' $type: 'day'
}); });
@ -140,7 +141,7 @@ export default class Calendar extends FormInput {
/* /*
* WeekDay selection event * WeekDay selection event
*/ */
selectWeekDay(weekday) { selectWeekDay($event, weekday) {
if (!this.editable) return; if (!this.editable) return;
let days = []; let days = [];
for (let day of this.days) { for (let day of this.days) {
@ -149,6 +150,7 @@ export default class Calendar extends FormInput {
} }
this.field = days[0]; this.field = days[0];
this.emit('selection', { this.emit('selection', {
$event: $event,
$days: days, $days: days,
$type: 'weekday', $type: 'weekday',
$weekday: weekday $weekday: weekday

View File

@ -20,7 +20,7 @@ describe('Component vnCalendar', () => {
describe('moveNext()', () => { describe('moveNext()', () => {
it(`should shift to the next month, then emit a 'move' event`, () => { it(`should shift to the next month, then emit a 'move' event`, () => {
spyOn(controller, 'emit'); jest.spyOn(controller, 'emit');
let nextMonth = new Date(date.getTime()); let nextMonth = new Date(date.getTime());
nextMonth.setMonth(nextMonth.getMonth() + 1); nextMonth.setMonth(nextMonth.getMonth() + 1);
@ -33,7 +33,7 @@ describe('Component vnCalendar', () => {
describe('movePrevious()', () => { describe('movePrevious()', () => {
it(`should shift to the previous month, then emit a 'move' event`, () => { it(`should shift to the previous month, then emit a 'move' event`, () => {
spyOn(controller, 'emit'); jest.spyOn(controller, 'emit');
let previousMonth = new Date(date.getTime()); let previousMonth = new Date(date.getTime());
previousMonth.setMonth(previousMonth.getMonth() - 1); previousMonth.setMonth(previousMonth.getMonth() - 1);
@ -46,13 +46,19 @@ describe('Component vnCalendar', () => {
describe('select()', () => { describe('select()', () => {
it(`should return the selected element, then emit a 'selection' event`, () => { it(`should return the selected element, then emit a 'selection' event`, () => {
spyOn(controller, 'emit'); jest.spyOn(controller, 'emit');
const day = new Date(); const day = new Date();
day.setHours(0, 0, 0, 0); day.setHours(0, 0, 0, 0);
controller.select(day);
const clickEvent = new Event('click');
const target = document.createElement('div');
target.dispatchEvent(clickEvent);
controller.select(clickEvent, day);
let res = { let res = {
$event: clickEvent,
$days: [day], $days: [day],
$type: 'day' $type: 'day'
}; };

View File

@ -17,7 +17,7 @@ describe('Component vnChip', () => {
describe('onRemove()', () => { describe('onRemove()', () => {
it(`should emit remove event`, () => { it(`should emit remove event`, () => {
controller.emit = () => {}; controller.emit = () => {};
spyOn(controller, 'emit'); jest.spyOn(controller, 'emit');
controller.onRemove(); controller.onRemove();
expect(controller.emit).toHaveBeenCalledWith('remove'); expect(controller.emit).toHaveBeenCalledWith('remove');

View File

@ -12,6 +12,15 @@ vn-chip {
max-width: 100%; max-width: 100%;
box-sizing: border-box; box-sizing: border-box;
&.small {
height: 1.5em;
& > div {
padding: 0.6em;
font-size: 0.8rem;
}
}
&.colored { &.colored {
background-color: $color-main; background-color: $color-main;
color: $color-font-bg; color: $color-font-bg;

View File

@ -100,7 +100,7 @@ export default class CrudModel extends ModelProxy {
} }
removeFilter() { removeFilter() {
return applyFilter(null, null); return this.applyFilter(null, null);
} }
/** /**
@ -240,14 +240,12 @@ export default class CrudModel extends ModelProxy {
onRemoteDone(json, filter, append) { onRemoteDone(json, filter, append) {
let data = json.data; let data = json.data;
if (append) if (append)
this.orgData = this.orgData.concat(data); this.orgData = this.orgData.concat(data);
else { else {
this.orgData = data; this.orgData = data;
this.currentFilter = filter; this.currentFilter = filter;
} }
this.data = this.proxiedData.slice(); this.data = this.proxiedData.slice();
this.moreRows = filter.limit && data.length == filter.limit; this.moreRows = filter.limit && data.length == filter.limit;
this.onRequestEnd(); this.onRequestEnd();

View File

@ -26,7 +26,7 @@ describe('Component vnCrudModel', () => {
describe('save()', () => { describe('save()', () => {
it(`should make an HTTP post query and then update the original rows with the returned values`, () => { it(`should make an HTTP post query and then update the original rows with the returned values`, () => {
spyOn(controller, 'applyChanges'); jest.spyOn(controller, 'applyChanges');
controller.insert({value: 'My new item 1'}); controller.insert({value: 'My new item 1'});
controller.insert({value: 'My new item 2'}); controller.insert({value: 'My new item 2'});
@ -47,4 +47,186 @@ describe('Component vnCrudModel', () => {
expect(controller.applyChanges).toHaveBeenCalledWith(); expect(controller.applyChanges).toHaveBeenCalledWith();
}); });
}); });
describe('setter url()', () => {
it('should set the url', () => {
spyOn(controller, 'autoRefresh');
spyOn(controller, 'clear');
controller.url = '/TestUrl';
expect(controller.url).toEqual('/TestUrl');
});
});
describe('isLoading()', () => {
it('should return false if canceler is null', () => {
controller.canceler = null;
expect(controller.isLoading).toBe(false);
});
it('should return true if canceler is not null', () => {
controller.canceler = 'validValue';
expect(controller.isLoading).toBe(true);
});
});
describe('buildFilter()', () => {
it('should build a filter and return it', () => {
controller.order = 'id ASC';
controller.fields = ['id'];
controller.limit = 1;
controller.filter = 'filterTest';
const result = controller.buildFilter();
expect(Object.keys(result).length).toEqual(13);
});
});
describe('sendRequest()', () => {
it('should call refresh() and check that the sendRequest is called', () => {
spyOn(controller, 'sendRequest').and.callThrough();
spyOn(controller, 'onRemoteDone');
spyOn(controller, 'onRemoteError');
const filter = {id: 1};
const serializedParams = encodeURIComponent(JSON.stringify(filter));
$httpBackend.whenRoute('GET', `model?filter=${serializedParams}`).respond();
controller.sendRequest(filter, true);
$httpBackend.flush();
expect(controller.isPaging).toBe(false);
});
});
describe('addFilter()', () => {
it('should call addFilter and check that the new filter has been added', () => {
spyOn(controller, 'refresh');
const filter = {where: {id: 1}};
controller.userFilter = {where: {name: 'test'}};
const filterMerged = {'where': {'and': [{'name': 'test'}, {'id': 1}]}};
controller.addFilter(filter);
expect(controller.userFilter).toEqual(filterMerged);
expect(controller.refresh).toHaveBeenCalledWith();
});
});
describe('applyFilter()', () => {
it('should call applyFilter and check that the refresh() is called', () => {
spyOn(controller, 'refresh');
const filter = {where: {id: 1}};
const params = {where: {id: 2}};
controller.applyFilter(filter, params);
expect(controller.userFilter).toEqual(filter);
expect(controller.userParams).toEqual(params);
expect(controller.refresh).toHaveBeenCalledWith();
});
});
describe('removeFilter()', () => {
it('should check the userFilter and userParams are removed', () => {
controller.removeFilter();
expect(controller.userFilter).toBe(null);
expect(controller.userParams).toBe(null);
});
});
describe('loadMore()', () => {
it('should call sendRequest with the new filter', () => {
spyOn(controller, 'sendRequest');
controller.moreRows = true;
controller.loadMore();
expect(controller.sendRequest).toHaveBeenCalledWith({'skip': 2}, true);
});
});
describe('clear()', () => {
it('should check that orgData and moreRows are set to null', () => {
controller.moreRows = true;
controller.clear();
expect(controller.moreRows).toBe(null);
expect(controller.orgData).toBe(null);
});
});
describe('refresh()', () => {
it('shold resolve a fake promise if this._url is undefined', () => {
spyOn(controller.$q, 'resolve');
controller._url = undefined;
controller.refresh();
expect(controller.$q.resolve).toHaveBeenCalledWith();
});
});
describe('onRemoteDone()', () => {
it('should check onRequestEnd is called, moreRows is true and currentFilter is undefined when append is true', () => {
spyOn(controller, 'onRequestEnd');
const append = true;
const json = {data: [
{
id: 1,
name: 'test'
}]};
const filter = {limit: 1};
controller.onRemoteDone(json, filter, append);
expect(controller.moreRows).toBe(true);
expect(controller.currentFilter).toBeUndefined();
expect(controller.onRequestEnd).toHaveBeenCalledWith();
});
it('should check onRequestEnd is called, moreRows is true and currentFilter is defined when append is false', () => {
spyOn(controller, 'onRequestEnd');
const append = false;
const json = {data: [
{
id: 1,
name: 'test'
}]};
const filter = {limit: 1};
controller.onRemoteDone(json, filter, append);
expect(controller.moreRows).toBe(true);
expect(controller.currentFilter).toBe(filter);
expect(controller.onRequestEnd).toHaveBeenCalledWith();
});
});
describe('onRemoteError()', () => {
it('should check the error', () => {
spyOn(controller, 'onRequestEnd');
let error;
try {
const newError = new Error('TestError');
controller.onRemoteError(newError);
} catch (e) {
error = e.message;
}
expect(controller.onRequestEnd).toHaveBeenCalledWith();
expect(error).toEqual('TestError');
});
});
}); });

View File

@ -30,7 +30,7 @@ describe('Component vnDialog', () => {
it(`should not hide the dialog when false is returned from response handler`, () => { it(`should not hide the dialog when false is returned from response handler`, () => {
controller.show(() => false); controller.show(() => false);
spyOn(controller, 'hide'); jest.spyOn(controller, 'hide');
controller.respond('answer'); controller.respond('answer');
expect(controller.hide).not.toHaveBeenCalled(); expect(controller.hide).not.toHaveBeenCalled();
@ -51,7 +51,7 @@ describe('Component vnDialog', () => {
describe('respond()', () => { describe('respond()', () => {
it(`should do nothing if dialog is already hidden`, () => { it(`should do nothing if dialog is already hidden`, () => {
controller.onResponse = () => {}; controller.onResponse = () => {};
spyOn(controller, 'onResponse'); jest.spyOn(controller, 'onResponse');
controller.respond(); controller.respond();
expect(controller.onResponse).not.toHaveBeenCalledWith(); expect(controller.onResponse).not.toHaveBeenCalledWith();
@ -59,7 +59,7 @@ describe('Component vnDialog', () => {
it(`should call onResponse() if it's defined`, () => { it(`should call onResponse() if it's defined`, () => {
controller.onResponse = () => {}; controller.onResponse = () => {};
spyOn(controller, 'onResponse'); jest.spyOn(controller, 'onResponse');
controller.show(); controller.show();
controller.respond(); controller.respond();
@ -69,7 +69,7 @@ describe('Component vnDialog', () => {
it(`should call onResponse() with the response`, () => { it(`should call onResponse() with the response`, () => {
controller.onResponse = () => {}; controller.onResponse = () => {};
spyOn(controller, 'onResponse'); jest.spyOn(controller, 'onResponse');
controller.show(); controller.show();
controller.respond('response'); controller.respond('response');
@ -79,7 +79,7 @@ describe('Component vnDialog', () => {
it(`should call onAccept() when accept response is given`, () => { it(`should call onAccept() when accept response is given`, () => {
controller.onAccept = () => {}; controller.onAccept = () => {};
spyOn(controller, 'onAccept'); jest.spyOn(controller, 'onAccept');
controller.show(); controller.show();
controller.respond('accept'); controller.respond('accept');

View File

@ -20,7 +20,7 @@ describe('Component vnMultiCheck', () => {
describe('checked() setter', () => { describe('checked() setter', () => {
it(`should set controller _checked property with the argument received then call toggle()`, () => { it(`should set controller _checked property with the argument received then call toggle()`, () => {
spyOn(controller, 'toggle'); jest.spyOn(controller, 'toggle');
controller.checked = crudModel; controller.checked = crudModel;
expect(controller._checked).toEqual(crudModel); expect(controller._checked).toEqual(crudModel);

View File

@ -37,6 +37,22 @@ export default class Popover extends Popup {
super.hide(); super.hide();
} }
get parent() {
return this.__parent;
}
// Bug #2147 Popover loses parent location
set parent(value) {
this.__parent = value;
if (!value) return;
const parentRect = value.getBoundingClientRect();
this.parentRect = {};
for (let prop in parentRect)
this.parentRect[prop] = parentRect[prop];
}
/** /**
* Repositions the popover to a correct location relative to the parent. * Repositions the popover to a correct location relative to the parent.
*/ */
@ -55,7 +71,7 @@ export default class Popover extends Popup {
arrowStyle.top = ''; arrowStyle.top = '';
arrowStyle.bottom = ''; arrowStyle.bottom = '';
let parentRect = this.parent.getBoundingClientRect(); let parentRect = this.parentRect;
let popoverRect = this.windowEl.getBoundingClientRect(); let popoverRect = this.windowEl.getBoundingClientRect();
let arrowRect = arrow.getBoundingClientRect(); let arrowRect = arrow.getBoundingClientRect();
let clamp = (value, min, max) => Math.min(Math.max(value, min), max); let clamp = (value, min, max) => Math.min(Math.max(value, min), max);

View File

@ -22,7 +22,7 @@ describe('Component vnPopover', () => {
describe('show()', () => { describe('show()', () => {
it(`should enable the shown property and emit the open event`, () => { it(`should enable the shown property and emit the open event`, () => {
spyOn(controller, 'emit'); jest.spyOn(controller, 'emit');
controller.show(); controller.show();
expect(controller.shown).toBeTruthy(); expect(controller.shown).toBeTruthy();
@ -31,13 +31,13 @@ describe('Component vnPopover', () => {
it(`should do nothing if it's already shown`, () => { it(`should do nothing if it's already shown`, () => {
controller.shown = true; controller.shown = true;
spyOn(controller, 'emit'); jest.spyOn(controller, 'emit');
controller.show(); controller.show();
expect(controller.emit).not.toHaveBeenCalledWith('open'); expect(controller.emit).not.toHaveBeenCalledWith('open');
}); });
//#1615 migrar karma a jest (this doesn't work anymore, needs fixing) // #1615 migrar karma a jest (this doesn't work anymore, needs fixing)
xit(`should check that popover is visible into the screen`, () => { xit(`should check that popover is visible into the screen`, () => {
$parent.css({ $parent.css({
backgroundColor: 'red', backgroundColor: 'red',
@ -65,7 +65,7 @@ describe('Component vnPopover', () => {
describe('hide()', () => { describe('hide()', () => {
it(`should disable the shown property and emit the close event`, inject($timeout => { it(`should disable the shown property and emit the close event`, inject($timeout => {
controller.show(); controller.show();
spyOn(controller, 'emit'); jest.spyOn(controller, 'emit');
controller.hide(); controller.hide();
$timeout.flush(); $timeout.flush();
@ -75,7 +75,7 @@ describe('Component vnPopover', () => {
it(`should do nothing if it's already hidden`, () => { it(`should do nothing if it's already hidden`, () => {
controller.shown = false; controller.shown = false;
spyOn(controller, 'emit'); jest.spyOn(controller, 'emit');
controller.hide(); controller.hide();
expect(controller.emit).not.toHaveBeenCalledWith('close'); expect(controller.emit).not.toHaveBeenCalledWith('close');

View File

@ -139,7 +139,7 @@ describe('Component vnSearchbar', () => {
describe('doSearch()', () => { describe('doSearch()', () => {
it(`should go to the search state and pass the filter as query param`, () => { it(`should go to the search state and pass the filter as query param`, () => {
spyOn($state, 'go'); jest.spyOn($state, 'go');
controller.searchState = 'search.state'; controller.searchState = 'search.state';
controller.doSearch(filter); controller.doSearch(filter);

View File

@ -63,13 +63,56 @@ export default class Controller extends Component {
show(data) { show(data) {
this.actionHandler = data.actionHandler; this.actionHandler = data.actionHandler;
let shape = this.createShape(data); let shape;
setTimeout(() => const lastShape = this.lastShape;
this.hide(shape), data.timeout || 3000); const lastShapeData = lastShape && lastShape.data;
const isEqual = lastShape && (lastShapeData.shapeType == data.shapeType && lastShapeData.message == data.message);
setTimeout(() => if (lastShape && isEqual) {
shape.classList.add('shown'), 30); shape = lastShape.element;
const shapeText = shape.querySelector('.text');
let chip = shapeText.querySelector('vn-chip');
if (chip) {
const text = chip.querySelector('span');
const number = parseInt(text.innerHTML);
text.innerHTML = number + 1;
} else {
chip = document.createElement('vn-chip');
chip.setAttribute('class', 'warning small');
let parent = document.createElement('div');
let span = document.createElement('span');
let text = document.createTextNode(1);
span.append(text);
parent.append(span);
chip.append(parent);
shapeText.appendChild(chip);
}
lastShape.element.classList.add('shown');
if (this.hideTimeout)
clearTimeout(this.hideTimeout);
} else {
shape = this.createShape(data);
setTimeout(() =>
shape.classList.add('shown'), 30);
}
this.hideTimeout = setTimeout(() => {
this.hide(shape);
this.lastShape = null;
}, data.timeout || 3000);
this.lastShape = {
data: data,
element: shape
};
} }
/** /**

View File

@ -19,10 +19,16 @@ vn-snackbar .shape {
border-radius: .2em; border-radius: .2em;
margin-bottom: 15px; margin-bottom: 15px;
color: white; color: white;
padding: 1em; padding: 0.8em;
&.text { & > .text {
text-align: center text-align: center;
vn-chip {
position: absolute;
left: -1em;
top: -1em;
}
} }
&.shown { &.shown {

View File

@ -17,14 +17,14 @@ describe('Component vnSpinner', () => {
describe('enable()', () => { describe('enable()', () => {
it(`should call start() when enable is set to true`, () => { it(`should call start() when enable is set to true`, () => {
spyOn(controller, 'start'); jest.spyOn(controller, 'start');
controller.enable = true; controller.enable = true;
expect(controller.start).toHaveBeenCalledWith(); expect(controller.start).toHaveBeenCalledWith();
}); });
it(`should call stop() when enable is set to false`, () => { it(`should call stop() when enable is set to false`, () => {
spyOn(controller, 'stop'); jest.spyOn(controller, 'stop');
controller.enable = false; controller.enable = false;
expect(controller.stop).toHaveBeenCalledWith(); expect(controller.stop).toHaveBeenCalledWith();

View File

@ -8,7 +8,7 @@ describe('Component vnStepControl', () => {
beforeEach(angular.mock.inject(($componentController, _$state_) => { beforeEach(angular.mock.inject(($componentController, _$state_) => {
$state = _$state_; $state = _$state_;
spyOn($state, 'go'); jest.spyOn($state, 'go');
controller = $componentController('vnStepControl', {$state: $state}); controller = $componentController('vnStepControl', {$state: $state});
})); }));

View File

@ -20,7 +20,7 @@ describe('Component vnTh', () => {
describe('onInit()', () => { describe('onInit()', () => {
it(`should define controllers order as per defaultOrder then call setOrder()`, () => { it(`should define controllers order as per defaultOrder then call setOrder()`, () => {
controller.defaultOrder = 'DESC'; controller.defaultOrder = 'DESC';
spyOn(controller.table, 'setOrder'); jest.spyOn(controller.table, 'setOrder');
controller.$onInit(); controller.$onInit();
expect(controller.order).toEqual('DESC'); expect(controller.order).toEqual('DESC');
@ -44,7 +44,7 @@ describe('Component vnTh', () => {
}); });
it(`should call the setOrder() function after changing a value`, () => { it(`should call the setOrder() function after changing a value`, () => {
spyOn(controller.table, 'setOrder'); jest.spyOn(controller.table, 'setOrder');
controller.order = 'Change me!'; controller.order = 'Change me!';
expect(controller.table.setOrder).toHaveBeenCalledWith('MyField', 'Change me!'); expect(controller.table.setOrder).toHaveBeenCalledWith('MyField', 'Change me!');
@ -54,7 +54,7 @@ describe('Component vnTh', () => {
describe('onToggleOrder()', () => { describe('onToggleOrder()', () => {
it(`should not call updateArrow() method if field property isn't defined`, () => { it(`should not call updateArrow() method if field property isn't defined`, () => {
controller.column.setAttribute('field', ''); controller.column.setAttribute('field', '');
spyOn(controller, 'updateArrow'); jest.spyOn(controller, 'updateArrow');
controller.onToggleOrder(); controller.onToggleOrder();
@ -64,8 +64,8 @@ describe('Component vnTh', () => {
it(`should call toggleOrder() method if field property and it(`should call toggleOrder() method if field property and
table field property equals and then call updateArrow()`, () => { table field property equals and then call updateArrow()`, () => {
controller.table.field = 'MyField'; controller.table.field = 'MyField';
spyOn(controller, 'toggleOrder'); jest.spyOn(controller, 'toggleOrder');
spyOn(controller, 'updateArrow'); jest.spyOn(controller, 'updateArrow');
controller.onToggleOrder(); controller.onToggleOrder();
@ -76,8 +76,8 @@ describe('Component vnTh', () => {
it(`should call setOrder() method if field property and it(`should call setOrder() method if field property and
table field property doesn't equals and then call updateArrow()`, () => { table field property doesn't equals and then call updateArrow()`, () => {
controller.table.field = 'MyField2'; controller.table.field = 'MyField2';
spyOn(controller.table, 'setOrder'); jest.spyOn(controller.table, 'setOrder');
spyOn(controller, 'updateArrow'); jest.spyOn(controller, 'updateArrow');
controller.onToggleOrder(); controller.onToggleOrder();

View File

@ -37,7 +37,7 @@ describe('Component vnTreeview', () => {
xdescribe('undrop()', () => { xdescribe('undrop()', () => {
it(`should reset all drop events and properties`, () => { it(`should reset all drop events and properties`, () => {
controller.dropping = angular.element(`<vn-treeview-child class="dropping"></vn-treeview-child>`); controller.dropping = angular.element(`<vn-treeview-child class="dropping"></vn-treeview-child>`);
spyOn(controller.dropping.classList, 'remove'); jest.spyOn(controller.dropping.classList, 'remove');
controller.undrop(); controller.undrop();
@ -69,9 +69,7 @@ describe('Component vnTreeview', () => {
describe('fetch()', () => { describe('fetch()', () => {
it(`should call the fetchFunc() method`, () => { it(`should call the fetchFunc() method`, () => {
spyOn(controller, 'fetchFunc').and.returnValue( jest.spyOn(controller, 'fetchFunc');
new Promise(resolve => resolve([{name: 'My item'}]))
);
controller.fetch().then(() => { controller.fetch().then(() => {
expect(controller.data).toBeDefined(); expect(controller.data).toBeDefined();
}); });
@ -82,7 +80,7 @@ describe('Component vnTreeview', () => {
describe('setParent()', () => { describe('setParent()', () => {
it(`should set the parent property recursively to each element of an item list`, () => { it(`should set the parent property recursively to each element of an item list`, () => {
spyOn(controller, 'setParent').and.callThrough(); jest.spyOn(controller, 'setParent');
const items = [{name: 'Item1'}, {name: 'Item2', childs: [ const items = [{name: 'Item1'}, {name: 'Item2', childs: [
{name: 'Item3'} {name: 'Item3'}
]}]; ]}];
@ -97,8 +95,8 @@ describe('Component vnTreeview', () => {
describe('onToggle()', () => { describe('onToggle()', () => {
it(`should call the fold() or unfold() methods`, () => { it(`should call the fold() or unfold() methods`, () => {
spyOn(controller, 'fold'); jest.spyOn(controller, 'fold');
spyOn(controller, 'unfold'); jest.spyOn(controller, 'unfold');
let event = new MouseEvent('click', { let event = new MouseEvent('click', {
bubbles: true, bubbles: true,
@ -130,11 +128,9 @@ describe('Component vnTreeview', () => {
describe('unfold()', () => { describe('unfold()', () => {
it(`should unfold a parent item`, () => { it(`should unfold a parent item`, () => {
const expectedResponse = [{name: 'Item 1'}, {name: 'Item 2'}]; const expectedResponse = [{name: 'Item 1'}, {name: 'Item 2'}];
spyOn(controller, 'fetchFunc').and.returnValue( jest.spyOn(controller, 'fetchFunc');
new Promise(resolve => resolve(expectedResponse)) jest.spyOn(controller, 'setParent');
); jest.spyOn(controller, 'sortFunc');
spyOn(controller, 'setParent');
spyOn(controller, 'sortFunc');
const parent = {name: 'My item', sons: 1}; const parent = {name: 'My item', sons: 1};
const child = {name: 'Item 1'}; const child = {name: 'Item 1'};
child.parent = parent; child.parent = parent;
@ -157,7 +153,7 @@ describe('Component vnTreeview', () => {
view: window view: window
}); });
spyOn(controller, 'removeFunc'); jest.spyOn(controller, 'removeFunc');
const item = {name: 'My item'}; const item = {name: 'My item'};
controller.onRemove(event, item); controller.onRemove(event, item);
@ -187,7 +183,7 @@ describe('Component vnTreeview', () => {
view: window view: window
}); });
spyOn(controller, 'createFunc'); jest.spyOn(controller, 'createFunc');
const parent = {name: 'My item'}; const parent = {name: 'My item'};
controller.onCreate(event, parent); controller.onCreate(event, parent);
@ -197,8 +193,8 @@ describe('Component vnTreeview', () => {
describe('create()', () => { describe('create()', () => {
it(`should unfold an inactive parent and then create a child`, () => { it(`should unfold an inactive parent and then create a child`, () => {
spyOn(controller, 'unfold'); jest.spyOn(controller, 'unfold');
spyOn(controller, 'sortFunc'); jest.spyOn(controller, 'sortFunc');
const parent = {name: 'My item', sons: 2, childs: [ const parent = {name: 'My item', sons: 2, childs: [
{name: 'Item 1'}, {name: 'Item 1'},
{name: 'Item 2'} {name: 'Item 2'}
@ -216,8 +212,8 @@ describe('Component vnTreeview', () => {
}); });
it(`should create a child on an active parent`, () => { it(`should create a child on an active parent`, () => {
spyOn(controller, 'unfold'); jest.spyOn(controller, 'unfold');
spyOn(controller, 'sortFunc'); jest.spyOn(controller, 'sortFunc');
const parent = {name: 'My item', sons: 2, childs: [ const parent = {name: 'My item', sons: 2, childs: [
{name: 'Item 1'}, {name: 'Item 1'},
{name: 'Item 2'} {name: 'Item 2'}
@ -236,9 +232,7 @@ describe('Component vnTreeview', () => {
describe('move()', () => { describe('move()', () => {
it(`should move an item to anocher parent and then unfold the parent`, () => { it(`should move an item to anocher parent and then unfold the parent`, () => {
spyOn(controller, 'unfold').and.returnValue( jest.spyOn(controller, 'unfold');
new Promise(resolve => resolve())
);
const newParent = {name: 'My item 2', sons: 0}; const newParent = {name: 'My item 2', sons: 0};
const parent = {name: 'My item', sons: 3, childs: [ const parent = {name: 'My item', sons: 3, childs: [
{name: 'Item 1'}, {name: 'Item 1'},
@ -255,8 +249,8 @@ describe('Component vnTreeview', () => {
}); });
it(`should move an item to anocher parent`, () => { it(`should move an item to anocher parent`, () => {
spyOn(controller, 'unfold'); jest.spyOn(controller, 'unfold');
spyOn(controller, 'create'); jest.spyOn(controller, 'create');
const newParent = {name: 'My item 2', sons: 0, active: true}; const newParent = {name: 'My item 2', sons: 0, active: true};
const parent = {name: 'My item', sons: 3, childs: [ const parent = {name: 'My item', sons: 3, childs: [
{name: 'Item 1'}, {name: 'Item 1'},

View File

@ -25,10 +25,10 @@ describe('Component vnWatcher', () => {
})); }));
describe('$onInit()', () => { describe('$onInit()', () => {
it(`should call fetchData() if controllers get and url properties are defined`, () => { it('should call fetchData() if controllers get and url properties are defined', () => {
controller.get = () => {}; controller.get = () => {};
controller.url = 'test.com'; controller.url = 'test.com';
spyOn(controller, 'fetchData'); jest.spyOn(controller, 'fetchData').mockReturnThis();
controller.$onInit(); controller.$onInit();
expect(controller.fetchData).toHaveBeenCalledWith(); expect(controller.fetchData).toHaveBeenCalledWith();
@ -45,7 +45,7 @@ describe('Component vnWatcher', () => {
describe('fetchData()', () => { describe('fetchData()', () => {
it(`should perform a query then store the received data into controller.data and call updateOriginalData()`, () => { it(`should perform a query then store the received data into controller.data and call updateOriginalData()`, () => {
spyOn(controller, 'updateOriginalData'); jest.spyOn(controller, 'updateOriginalData');
let json = {data: 'some data'}; let json = {data: 'some data'};
controller.data = [1]; controller.data = [1];
controller.idField = 0; controller.idField = 0;
@ -61,9 +61,9 @@ describe('Component vnWatcher', () => {
}); });
describe('submitBack()', () => { describe('submitBack()', () => {
it(`should call controller.window.history.back() function after calling controllers submit() function`, done => { it('should call controller.window.history.back() function after calling controllers submit() function', done => {
spyOn(controller, 'submit').and.returnValue(Promise.resolve()); jest.spyOn(controller, 'submit').mockReturnValue(Promise.resolve());
spyOn(controller.window.history, 'back'); jest.spyOn(controller.window.history, 'back');
controller.submitBack() controller.submitBack()
.then(() => { .then(() => {
expect(controller.submit).toHaveBeenCalledWith(); expect(controller.submit).toHaveBeenCalledWith();
@ -74,9 +74,9 @@ describe('Component vnWatcher', () => {
}); });
describe('submitGo()', () => { describe('submitGo()', () => {
it(`should call controller.$state.go() function after calling controllers submit() function`, done => { it('should call controller.$state.go() function after calling controllers submit() function', done => {
spyOn(controller, 'submit').and.returnValue(Promise.resolve()); jest.spyOn(controller, 'submit').mockReturnValue(Promise.resolve());
spyOn(controller.$state, 'go'); jest.spyOn(controller.$state, 'go');
let state = 'the.State'; let state = 'the.State';
controller.submitGo(state) controller.submitGo(state)
.then(() => { .then(() => {
@ -112,7 +112,7 @@ describe('Component vnWatcher', () => {
$setSubmitted: () => {}, $setSubmitted: () => {},
$setPristine: () => {} $setPristine: () => {}
}; };
spyOn(controller.form, '$setSubmitted'); jest.spyOn(controller.form, '$setSubmitted');
controller.realSubmit(); controller.realSubmit();
expect(controller.form.$setSubmitted).toHaveBeenCalledWith(); expect(controller.form.$setSubmitted).toHaveBeenCalledWith();
@ -141,7 +141,7 @@ describe('Component vnWatcher', () => {
controller.idField = 'id'; controller.idField = 'id';
controller.url = 'test.com'; controller.url = 'test.com';
let json = {data: 'some data'}; let json = {data: 'some data'};
spyOn(controller, 'writeData').and.callThrough(); jest.spyOn(controller, 'writeData');
$httpBackend.whenPATCH(`${controller.url}/1`, changedData).respond(json); $httpBackend.whenPATCH(`${controller.url}/1`, changedData).respond(json);
$httpBackend.expectPATCH(`${controller.url}/1`); $httpBackend.expectPATCH(`${controller.url}/1`);
controller.realSubmit() controller.realSubmit()
@ -161,7 +161,7 @@ describe('Component vnWatcher', () => {
controller.orgData = {id: 1}; controller.orgData = {id: 1};
controller.url = 'test.com'; controller.url = 'test.com';
let json = {data: 'some data'}; let json = {data: 'some data'};
spyOn(controller, 'writeData').and.callThrough(); jest.spyOn(controller, 'writeData');
$httpBackend.whenPOST(`${controller.url}`, controller.data).respond(json); $httpBackend.whenPOST(`${controller.url}`, controller.data).respond(json);
$httpBackend.expectPOST(`${controller.url}`, controller.data); $httpBackend.expectPOST(`${controller.url}`, controller.data);
controller.realSubmit() controller.realSubmit()
@ -175,7 +175,7 @@ describe('Component vnWatcher', () => {
describe('writeData()', () => { describe('writeData()', () => {
it(`should call Object.asssign() function over controllers.data with json.data, then call updateOriginalData function and finally call resolve() function`, () => { it(`should call Object.asssign() function over controllers.data with json.data, then call updateOriginalData function and finally call resolve() function`, () => {
spyOn(controller, 'updateOriginalData'); jest.spyOn(controller, 'updateOriginalData');
controller.data = {}; controller.data = {};
let json = {data: 'some data'}; let json = {data: 'some data'};
let resolve = jasmine.createSpy('resolve'); let resolve = jasmine.createSpy('resolve');

View File

@ -24,7 +24,7 @@ describe('Directive dialog', () => {
it('should call show() function if dialog is a instance of vnDialog', () => { it('should call show() function if dialog is a instance of vnDialog', () => {
let html = `<div vn-dialog="myDialog"></div>`; let html = `<div vn-dialog="myDialog"></div>`;
spyOn(controller, 'show'); jest.spyOn(controller, 'show');
compile(html); compile(html);
element[0].click(); element[0].click();

View File

@ -0,0 +1,25 @@
const popover = {
show: () => {
return {
then: callback => {
callback();
}
};
},
hide: () => {
return {
then: callback => {
callback();
}
};
},
relocate: () => {
return {
then: callback => {
callback();
}
};
}
};
module.exports = popover;

View File

@ -23,6 +23,12 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.icon-net:before {
content: "\e95b";
}
.icon-anonymous:before {
content: "\e95c";
}
.icon-buyrequest:before { .icon-buyrequest:before {
content: "\e914"; content: "\e914";
} }

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 96 KiB

View File

@ -12,7 +12,7 @@ export default function moduleImport(moduleName) {
case 'ticket' : return import('ticket/front'); case 'ticket' : return import('ticket/front');
case 'order' : return import('order/front'); case 'order' : return import('order/front');
case 'claim' : return import('claim/front'); case 'claim' : return import('claim/front');
case 'agency' : return import('agency/front'); case 'zone' : return import('zone/front');
case 'travel' : return import('travel/front'); case 'travel' : return import('travel/front');
case 'worker' : return import('worker/front'); case 'worker' : return import('worker/front');
case 'invoiceOut' : return import('invoiceOut/front'); case 'invoiceOut' : return import('invoiceOut/front');

View File

@ -26,7 +26,7 @@ describe('Component vnLeftMenu', () => {
describe('depth() setter', () => { describe('depth() setter', () => {
it(`should set depth property and call activateItem()`, () => { it(`should set depth property and call activateItem()`, () => {
spyOn(controller, 'activateItem'); jest.spyOn(controller, 'activateItem');
controller.depth = 3; controller.depth = 3;
expect(controller.depth).toEqual(3); expect(controller.depth).toEqual(3);

View File

@ -32,7 +32,7 @@ Remove: Quitar
# Modules # Modules
Agencies: Agencias Zones: Zonas
Claims: Reclamaciones Claims: Reclamaciones
Clients: Clientes Clients: Clientes
Items: Artículos Items: Artículos

View File

@ -2,7 +2,7 @@ import 'angular';
import 'angular-mocks'; import 'angular-mocks';
import core from './front/core/module.js'; import core from './front/core/module.js';
import './front/salix/components/app/app.js'; import './front/salix/components/app/app.js';
import './modules/agency/front/module.js'; import './modules/zone/front/module.js';
import './modules/claim/front/module.js'; import './modules/claim/front/module.js';
import './modules/client/front/module.js'; import './modules/client/front/module.js';
import './modules/invoiceOut/front/module.js'; import './modules/invoiceOut/front/module.js';

View File

@ -1,16 +0,0 @@
vn-zone-delivery-days {
vn-zone-calendar {
display: flex;
justify-content: center;
flex-wrap: wrap;
& > vn-calendar {
min-width: 16.5em;
}
}
form {
display: flex;
flex-direction: column;
}
}

View File

@ -1,3 +0,0 @@
import {ng} from 'core/vendor';
export default ng.module('agency', ['vnCore']);

View File

@ -36,8 +36,8 @@ describe('claim', () => {
describe('openAddSalesDialog()', () => { describe('openAddSalesDialog()', () => {
it('should call getClaimableFromTicket and $.addSales.show', () => { it('should call getClaimableFromTicket and $.addSales.show', () => {
controller.$ = {addSales: {show: () => {}}}; controller.$ = {addSales: {show: () => {}}};
spyOn(controller, 'getClaimedSales'); jest.spyOn(controller, 'getClaimedSales');
spyOn(controller.$.addSales, 'show'); jest.spyOn(controller.$.addSales, 'show');
controller.openAddSalesDialog(); controller.openAddSalesDialog();
expect(controller.getClaimedSales).toHaveBeenCalledWith(); expect(controller.getClaimedSales).toHaveBeenCalledWith();
@ -58,9 +58,9 @@ describe('claim', () => {
describe('addClaimedSale(saleFk)', () => { describe('addClaimedSale(saleFk)', () => {
it('should make a post and call refresh, hide and showSuccess', () => { it('should make a post and call refresh, hide and showSuccess', () => {
spyOn(controller.$.model, 'refresh'); jest.spyOn(controller.$.model, 'refresh');
spyOn(controller.$.addSales, 'hide'); jest.spyOn(controller.$.addSales, 'hide');
spyOn(controller.vnApp, 'showSuccess'); jest.spyOn(controller.vnApp, 'showSuccess');
$httpBackend.expectPOST(`ClaimEnds/`).respond({}); $httpBackend.expectPOST(`ClaimEnds/`).respond({});
controller.addClaimedSale(1); controller.addClaimedSale(1);
$httpBackend.flush(); $httpBackend.flush();
@ -73,8 +73,8 @@ describe('claim', () => {
describe('deleteClaimedSale(id)', () => { describe('deleteClaimedSale(id)', () => {
it('should make a delete and call refresh and showSuccess', () => { it('should make a delete and call refresh and showSuccess', () => {
spyOn(controller.$.model, 'refresh'); jest.spyOn(controller.$.model, 'refresh');
spyOn(controller.vnApp, 'showSuccess'); jest.spyOn(controller.vnApp, 'showSuccess');
$httpBackend.expectDELETE(`ClaimEnds/1`).respond({}); $httpBackend.expectDELETE(`ClaimEnds/1`).respond({});
controller.deleteClaimedSale(1); controller.deleteClaimedSale(1);
$httpBackend.flush(); $httpBackend.flush();
@ -99,8 +99,8 @@ describe('claim', () => {
describe('importToNewRefundTicket()', () => { describe('importToNewRefundTicket()', () => {
it('should perform a post query and add lines from a new ticket', () => { it('should perform a post query and add lines from a new ticket', () => {
spyOn(controller.$.model, 'refresh'); jest.spyOn(controller.$.model, 'refresh');
spyOn(controller.vnApp, 'showSuccess'); jest.spyOn(controller.vnApp, 'showSuccess');
$httpBackend.expect('POST', `ClaimBeginnings/1/importToNewRefundTicket`).respond({}); $httpBackend.expect('POST', `ClaimBeginnings/1/importToNewRefundTicket`).respond({});
controller.importToNewRefundTicket(); controller.importToNewRefundTicket();
$httpBackend.flush(); $httpBackend.flush();
@ -112,8 +112,8 @@ describe('claim', () => {
describe('showLastTickets()', () => { describe('showLastTickets()', () => {
it('should get a list of tickets and call lastTicketsPopover show() method', () => { it('should get a list of tickets and call lastTicketsPopover show() method', () => {
spyOn(controller.$.lastTicketsModel, 'refresh'); jest.spyOn(controller.$.lastTicketsModel, 'refresh');
spyOn(controller.$.lastTicketsPopover, 'show'); jest.spyOn(controller.$.lastTicketsPopover, 'show');
controller.showLastTickets({}); controller.showLastTickets({});
expect(controller.$.lastTicketsModel.refresh).toHaveBeenCalledWith(); expect(controller.$.lastTicketsModel.refresh).toHaveBeenCalledWith();
@ -123,9 +123,9 @@ describe('claim', () => {
describe('importTicketLines()', () => { describe('importTicketLines()', () => {
it('should perform a post query and add lines from an existent ticket', () => { it('should perform a post query and add lines from an existent ticket', () => {
spyOn(controller.$.model, 'refresh'); jest.spyOn(controller.$.model, 'refresh');
spyOn(controller.vnApp, 'showSuccess'); jest.spyOn(controller.vnApp, 'showSuccess');
spyOn(controller.$.lastTicketsPopover, 'hide'); jest.spyOn(controller.$.lastTicketsPopover, 'hide');
let data = {claimFk: 1, ticketFk: 1}; let data = {claimFk: 1, ticketFk: 1};
$httpBackend.expect('POST', `ClaimEnds/importTicketSales`, data).respond({}); $httpBackend.expect('POST', `ClaimEnds/importTicketSales`, data).respond({});
controller.importTicketLines(1); controller.importTicketLines(1);
@ -139,8 +139,8 @@ describe('claim', () => {
describe('regularize()', () => { describe('regularize()', () => {
it('should perform a post query and reload the claim card', () => { it('should perform a post query and reload the claim card', () => {
spyOn(controller.card, 'reload'); jest.spyOn(controller.card, 'reload');
spyOn(controller.vnApp, 'showSuccess'); jest.spyOn(controller.vnApp, 'showSuccess');
let data = {claimFk: $state.params.id}; let data = {claimFk: $state.params.id};
$httpBackend.expect('POST', `Claims/regularizeClaim`, data).respond({}); $httpBackend.expect('POST', `Claims/regularizeClaim`, data).respond({});
@ -156,9 +156,9 @@ describe('claim', () => {
const greugeTypeId = 7; const greugeTypeId = 7;
const freightPickUpPrice = 11; const freightPickUpPrice = 11;
it('should do nothing', () => { it('should do nothing', () => {
spyOn(controller.$http, 'post'); jest.spyOn(controller.$http, 'post');
spyOn(controller.card, 'reload'); jest.spyOn(controller.card, 'reload');
spyOn(controller.vnApp, 'showSuccess'); jest.spyOn(controller.vnApp, 'showSuccess');
controller.onUpdateGreugeResponse('cancel'); controller.onUpdateGreugeResponse('cancel');
@ -168,8 +168,8 @@ describe('claim', () => {
}); });
it('should make a query and get the greugeTypeId and greuge config', () => { it('should make a query and get the greugeTypeId and greuge config', () => {
spyOn(controller.card, 'reload'); jest.spyOn(controller.card, 'reload');
spyOn(controller.vnApp, 'showSuccess'); jest.spyOn(controller.vnApp, 'showSuccess');
const greugeTypeParams = $httpParamSerializer({filter: {where: {code: 'freightPickUp'}}}); const greugeTypeParams = $httpParamSerializer({filter: {where: {code: 'freightPickUp'}}});
$httpBackend.expect('GET', `GreugeTypes/findOne?${greugeTypeParams}`).respond({id: greugeTypeId}); $httpBackend.expect('GET', `GreugeTypes/findOne?${greugeTypeParams}`).respond({id: greugeTypeId});
@ -183,13 +183,13 @@ describe('claim', () => {
// #1957 - Investigate how to test nested httpBackend requests // #1957 - Investigate how to test nested httpBackend requests
xit('should perform a insert into greuges', () => { xit('should perform a insert into greuges', () => {
spyOn(controller.card, 'reload'); jest.spyOn(controller.card, 'reload');
spyOn(controller.vnApp, 'showSuccess'); jest.spyOn(controller.vnApp, 'showSuccess');
spyOn(controller, 'getGreugeTypeId').and.returnValue(new Promise(resolve => { jest.spyOn(controller, 'getGreugeTypeId').and.returnValue(new Promise(resolve => {
return resolve({id: greugeTypeId}); return resolve({id: greugeTypeId});
})); }));
spyOn(controller, 'getGreugeConfig').and.returnValue(new Promise(resolve => { jest.spyOn(controller, 'getGreugeConfig').and.returnValue(new Promise(resolve => {
return resolve({freightPickUpPrice}); return resolve({freightPickUpPrice});
})); }));

View File

@ -17,7 +17,7 @@ describe('Claim', () => {
describe('onSubmit()', () => { describe('onSubmit()', () => {
it(`should redirect to 'claim.card.detail' state`, () => { it(`should redirect to 'claim.card.detail' state`, () => {
spyOn(controller.$state, 'go'); jest.spyOn(controller.$state, 'go');
controller.onSubmit(); controller.onSubmit();
expect(controller.$state.go).toHaveBeenCalledWith('claim.card.detail'); expect(controller.$state.go).toHaveBeenCalledWith('claim.card.detail');

View File

@ -22,7 +22,7 @@ describe('Item Component vnClaimDescriptor', () => {
}; };
const serializedParams = $httpParamSerializer(params); const serializedParams = $httpParamSerializer(params);
let expectedPath = `api/report/claim-pickup-order?${serializedParams}`; let expectedPath = `api/report/claim-pickup-order?${serializedParams}`;
spyOn(window, 'open'); jest.spyOn(window, 'open').mockReturnThis();
controller.showPickupOrder(); controller.showPickupOrder();
expect(window.open).toHaveBeenCalledWith(expectedPath); expect(window.open).toHaveBeenCalledWith(expectedPath);
@ -43,7 +43,7 @@ describe('Item Component vnClaimDescriptor', () => {
describe('sendPickupOrder(response)', () => { describe('sendPickupOrder(response)', () => {
it('should make a query and call vnApp.showMessage() if the response is accept', () => { it('should make a query and call vnApp.showMessage() if the response is accept', () => {
spyOn(controller.vnApp, 'showMessage'); jest.spyOn(controller.vnApp, 'showMessage');
const params = { const params = {
recipient: 'client@email', recipient: 'client@email',
@ -78,8 +78,8 @@ describe('Item Component vnClaimDescriptor', () => {
let response = 'accept'; let response = 'accept';
controller.claim = {id: 2}; controller.claim = {id: 2};
spyOn(controller.vnApp, 'showSuccess'); jest.spyOn(controller.vnApp, 'showSuccess');
spyOn(controller.$state, 'go'); jest.spyOn(controller.$state, 'go');
$httpBackend.when('DELETE', `Claims/2`).respond(200); $httpBackend.when('DELETE', `Claims/2`).respond(200);
$httpBackend.expect('DELETE', `Claims/2`); $httpBackend.expect('DELETE', `Claims/2`);
controller.deleteClaim(response); controller.deleteClaim(response);

View File

@ -37,8 +37,8 @@ describe('claim', () => {
describe('openAddSalesDialog()', () => { describe('openAddSalesDialog()', () => {
it('should call getClaimableFromTicket and $.addSales.show', () => { it('should call getClaimableFromTicket and $.addSales.show', () => {
spyOn(controller, 'getClaimableFromTicket'); jest.spyOn(controller, 'getClaimableFromTicket');
spyOn(controller.$.addSales, 'show'); jest.spyOn(controller.$.addSales, 'show');
controller.openAddSalesDialog(); controller.openAddSalesDialog();
expect(controller.getClaimableFromTicket).toHaveBeenCalledWith(); expect(controller.getClaimableFromTicket).toHaveBeenCalledWith();
@ -58,8 +58,8 @@ describe('claim', () => {
describe('addClaimedSale(index)', () => { describe('addClaimedSale(index)', () => {
it('should make a post and call refresh, hide and showSuccess', () => { it('should make a post and call refresh, hide and showSuccess', () => {
spyOn(controller.$.addSales, 'hide'); jest.spyOn(controller.$.addSales, 'hide');
spyOn(controller.$state, 'go'); jest.spyOn(controller.$state, 'go');
$httpBackend.expectPOST(`ClaimBeginnings/`).respond({}); $httpBackend.expectPOST(`ClaimBeginnings/`).respond({});
controller.addClaimedSale(1); controller.addClaimedSale(1);
$httpBackend.flush(); $httpBackend.flush();
@ -71,7 +71,7 @@ describe('claim', () => {
describe('deleteClaimedSale(index)', () => { describe('deleteClaimedSale(index)', () => {
it('should make a delete and call refresh and showSuccess', () => { it('should make a delete and call refresh and showSuccess', () => {
spyOn(controller.$.model, 'remove'); jest.spyOn(controller.$.model, 'remove');
$httpBackend.expectDELETE(`ClaimBeginnings/1`).respond({}); $httpBackend.expectDELETE(`ClaimBeginnings/1`).respond({});
controller.deleteClaimedSale(0); controller.deleteClaimedSale(0);
$httpBackend.flush(); $httpBackend.flush();
@ -82,7 +82,7 @@ describe('claim', () => {
describe('setClaimedQuantity(id, claimedQuantity)', () => { describe('setClaimedQuantity(id, claimedQuantity)', () => {
it('should make a patch and call refresh and showSuccess', () => { it('should make a patch and call refresh and showSuccess', () => {
spyOn(controller.vnApp, 'showSuccess'); jest.spyOn(controller.vnApp, 'showSuccess');
$httpBackend.expectPATCH(`ClaimBeginnings/`).respond({}); $httpBackend.expectPATCH(`ClaimBeginnings/`).respond({});
controller.setClaimedQuantity(1, 1); controller.setClaimedQuantity(1, 1);
$httpBackend.flush(); $httpBackend.flush();
@ -112,10 +112,10 @@ describe('claim', () => {
controller.newDiscount = 10; controller.newDiscount = 10;
spyOn(controller.vnApp, 'showSuccess'); jest.spyOn(controller.vnApp, 'showSuccess');
spyOn(controller, 'calculateTotals'); jest.spyOn(controller, 'calculateTotals');
spyOn(controller, 'clearDiscount'); jest.spyOn(controller, 'clearDiscount');
spyOn(controller.$.editPopover, 'hide'); jest.spyOn(controller.$.editPopover, 'hide');
$httpBackend.when('POST', 'Tickets/1/updateDiscount').respond({}); $httpBackend.when('POST', 'Tickets/1/updateDiscount').respond({});
controller.updateDiscount(); controller.updateDiscount();
@ -135,8 +135,8 @@ describe('claim', () => {
stopImmediatePropagation: () => {}, stopImmediatePropagation: () => {},
target: 'the target element' target: 'the target element'
}; };
spyOn(event, 'stopImmediatePropagation'); jest.spyOn(event, 'stopImmediatePropagation');
spyOn(controller.$.descriptor, 'show'); jest.spyOn(controller.$.descriptor, 'show');
controller.showItemDescriptor(event, itemId); controller.showItemDescriptor(event, itemId);

View File

@ -20,7 +20,7 @@ describe('Claim', () => {
describe('onSubmit()', () => { describe('onSubmit()', () => {
it(`should redirect to 'claim.card.action' state`, () => { it(`should redirect to 'claim.card.action' state`, () => {
spyOn(controller.$state, 'go'); jest.spyOn(controller.$state, 'go');
controller.onSubmit(); controller.onSubmit();
expect(controller.$state.go).toHaveBeenCalledWith('claim.card.action'); expect(controller.$state.go).toHaveBeenCalledWith('claim.card.action');

View File

@ -28,8 +28,8 @@ describe('Claim', () => {
it('should make an HTTP Post query', () => { it('should make an HTTP Post query', () => {
const dmsId = 1; const dmsId = 1;
const dmsIndex = 0; const dmsIndex = 0;
spyOn(controller.vnApp, 'showSuccess'); jest.spyOn(controller.vnApp, 'showSuccess');
spyOn(controller.$.model, 'remove'); jest.spyOn(controller.$.model, 'remove');
controller.photos = [{dmsFk: 1}]; controller.photos = [{dmsFk: 1}];
controller.dmsIndex = dmsIndex; controller.dmsIndex = dmsIndex;
@ -62,8 +62,8 @@ describe('Claim', () => {
it('should make an HTTP Post query, then refresh the model data', () => { it('should make an HTTP Post query, then refresh the model data', () => {
const claimId = 1; const claimId = 1;
const dmsIndex = 0; const dmsIndex = 0;
spyOn(controller.vnApp, 'showSuccess'); jest.spyOn(controller.vnApp, 'showSuccess');
spyOn(controller.$.model, 'refresh'); jest.spyOn(controller.$.model, 'refresh');
controller.photos = [{dmsFk: 1}]; controller.photos = [{dmsFk: 1}];
controller.dmsIndex = dmsIndex; controller.dmsIndex = dmsIndex;
controller.dms = {files: []}; controller.dms = {files: []};

View File

@ -28,7 +28,7 @@ describe('Claim', () => {
describe('$onChanges()', () => { describe('$onChanges()', () => {
it('should call getSummary when item.id is defined', () => { it('should call getSummary when item.id is defined', () => {
spyOn(controller, 'getSummary'); jest.spyOn(controller, 'getSummary');
controller.$onChanges(); controller.$onChanges();
expect(controller.getSummary).toHaveBeenCalledWith(); expect(controller.getSummary).toHaveBeenCalledWith();

View File

@ -22,7 +22,10 @@
"type": "Boolean" "type": "Boolean"
}, },
"hasCompany": { "hasCompany": {
"type": "Number" "type": "Boolean"
},
"hasPreview": {
"type": "Boolean"
} }
}, },
"scopes": { "scopes": {

View File

@ -35,7 +35,7 @@ describe('Client', () => {
describe('onSubmit()', () => { describe('onSubmit()', () => {
it('should perform a PATCH and not set value to defaultAddressFk property', () => { it('should perform a PATCH and not set value to defaultAddressFk property', () => {
spyOn(controller.$state, 'go'); jest.spyOn(controller.$state, 'go');
controller.address.isDefaultAddress = false; controller.address.isDefaultAddress = false;
controller.onSubmit(); controller.onSubmit();
@ -44,7 +44,7 @@ describe('Client', () => {
}); });
it('should perform a PATCH and set a value to defaultAddressFk property', () => { it('should perform a PATCH and set a value to defaultAddressFk property', () => {
spyOn(controller.$state, 'go'); jest.spyOn(controller.$state, 'go');
controller.address.isDefaultAddress = true; controller.address.isDefaultAddress = true;
controller.onSubmit(); controller.onSubmit();

View File

@ -36,8 +36,8 @@ describe('Client', () => {
describe('removeObservation()', () => { describe('removeObservation()', () => {
it('should call $.watcher.setDirty() and $.model.remove(index)', () => { it('should call $.watcher.setDirty() and $.model.remove(index)', () => {
spyOn(controller.$.watcher, 'setDirty'); jest.spyOn(controller.$.watcher, 'setDirty');
spyOn(controller.$.model, 'remove'); jest.spyOn(controller.$.model, 'remove');
controller.removeObservation(1); controller.removeObservation(1);
expect(controller.$.model.remove).toHaveBeenCalledWith(1); expect(controller.$.model.remove).toHaveBeenCalledWith(1);
@ -47,7 +47,7 @@ describe('Client', () => {
describe('cancel()', () => { describe('cancel()', () => {
it('should call goToIndex()', () => { it('should call goToIndex()', () => {
spyOn(controller, 'goToIndex'); jest.spyOn(controller, 'goToIndex');
controller.cancel(); controller.cancel();
expect(controller.goToIndex).toHaveBeenCalledWith(); expect(controller.goToIndex).toHaveBeenCalledWith();
@ -56,7 +56,7 @@ describe('Client', () => {
describe('goToIndex()', () => { describe('goToIndex()', () => {
it('should call $state.go("client.card.address.index")', () => { it('should call $state.go("client.card.address.index")', () => {
spyOn(controller.$state, 'go'); jest.spyOn(controller.$state, 'go');
controller.goToIndex(); controller.goToIndex();
expect(controller.$state.go).toHaveBeenCalledWith('client.card.address.index'); expect(controller.$state.go).toHaveBeenCalledWith('client.card.address.index');

View File

@ -22,7 +22,7 @@ describe('Client', () => {
describe('setDefault()', () => { describe('setDefault()', () => {
it('should perform a PATCH and set a value to defaultAddressFk property', () => { it('should perform a PATCH and set a value to defaultAddressFk property', () => {
spyOn(controller, 'sortAddresses'); jest.spyOn(controller, 'sortAddresses');
let address = {id: 1}; let address = {id: 1};
let data = {defaultAddressFk: address.id}; let data = {defaultAddressFk: address.id};
let expectedResult = {defaultAddressFk: address.id}; let expectedResult = {defaultAddressFk: address.id};

View File

@ -31,9 +31,9 @@ describe('Client', () => {
it('should apply the filters on he models and get the client balance', () => { it('should apply the filters on he models and get the client balance', () => {
controller._companyId = 442; controller._companyId = 442;
controller.$stateParams.id = 101; controller.$stateParams.id = 101;
spyOn(controller, 'getBalances'); jest.spyOn(controller, 'getBalances').mockReturnThis();
spyOn(controller.$.model, 'applyFilter').and.returnValue(Promise.resolve()); jest.spyOn(controller.$.model, 'applyFilter').mockReturnValue(Promise.resolve());
spyOn(controller.$.riskModel, 'applyFilter').and.returnValue(Promise.resolve()); jest.spyOn(controller.$.riskModel, 'applyFilter').mockReturnValue(Promise.resolve());
controller.getData().then(() => { controller.getData().then(() => {
expect(controller.$.model.applyFilter).toHaveBeenCalledWith(null, {'clientId': 101, 'companyId': 442}); expect(controller.$.model.applyFilter).toHaveBeenCalledWith(null, {'clientId': 101, 'companyId': 442});
@ -44,14 +44,8 @@ describe('Client', () => {
}); });
describe('company setter/getter', () => { describe('company setter/getter', () => {
it('should return the company', () => {
controller.companyId = null;
expect(controller._companyId).toEqual(jasmine.any(Object));
});
it('should return the company and then call getData()', () => { it('should return the company and then call getData()', () => {
spyOn(controller, 'getData'); jest.spyOn(controller, 'getData').mockReturnThis();
controller.companyId = 442; controller.companyId = 442;
expect(controller._companyId).toEqual(442); expect(controller._companyId).toEqual(442);
@ -70,7 +64,7 @@ describe('Client', () => {
describe('getBalances()', () => { describe('getBalances()', () => {
it('should return the total client balance amount', () => { it('should return the total client balance amount', () => {
spyOn(controller, 'getCurrentBalance').and.callThrough(); jest.spyOn(controller, 'getCurrentBalance');
controller._companyId = 442; controller._companyId = 442;
controller.$.model = {data: controller.$.model = {data:
[{ [{
@ -100,7 +94,7 @@ describe('Client', () => {
describe('balances() setter', () => { describe('balances() setter', () => {
it('should set the balances data and not call the getBalances() method', () => { it('should set the balances data and not call the getBalances() method', () => {
spyOn(controller, 'getBalances'); jest.spyOn(controller, 'getBalances');
controller.$.riskModel.data = null; controller.$.riskModel.data = null;
controller.balances = [{ controller.balances = [{
id: 1, id: 1,
@ -121,7 +115,7 @@ describe('Client', () => {
}); });
it('should set the balances data and then call the getBalances() method', () => { it('should set the balances data and then call the getBalances() method', () => {
spyOn(controller, 'getBalances'); jest.spyOn(controller, 'getBalances').mockReturnThis();
controller.balances = [{ controller.balances = [{
id: 1, id: 1,
debit: 1000, debit: 1000,

View File

@ -15,7 +15,7 @@ describe('Client', () => {
vnApp = _vnApp_; vnApp = _vnApp_;
$scope = $rootScope.$new(); $scope = $rootScope.$new();
$scope.watcher = {}; $scope.watcher = {};
spyOn(vnApp, 'showError'); jest.spyOn(vnApp, 'showError');
controller = $componentController('vnClientBillingData', {$element, $scope}); controller = $componentController('vnClientBillingData', {$element, $scope});
controller.client = {id: 101, name: 'Client name', payMethodFk: 4}; controller.client = {id: 101, name: 'Client name', payMethodFk: 4};
$scope.watcher.orgData = {id: 101, name: 'Client name', payMethodFk: 4}; $scope.watcher.orgData = {id: 101, name: 'Client name', payMethodFk: 4};

View File

@ -33,7 +33,7 @@ describe('Client', () => {
describe('onSubmit()', () => { describe('onSubmit()', () => {
it(`should call submit() on the watcher then expect a callback`, () => { it(`should call submit() on the watcher then expect a callback`, () => {
spyOn($state, 'go'); jest.spyOn($state, 'go');
controller.onSubmit(); controller.onSubmit();
expect(controller.$state.go).toHaveBeenCalledWith('client.card.basicData', {id: '1234'}); expect(controller.$state.go).toHaveBeenCalledWith('client.card.basicData', {id: '1234'});

View File

@ -60,7 +60,7 @@ describe('Client', () => {
describe('closeContract()', () => { describe('closeContract()', () => {
it('should define the classificationId property of the controller and then call the show method()', () => { it('should define the classificationId property of the controller and then call the show method()', () => {
controller.$scope.closeContract = {show: () => {}}; controller.$scope.closeContract = {show: () => {}};
spyOn(controller.$scope.closeContract, 'show'); jest.spyOn(controller.$scope.closeContract, 'show');
expect(controller.classificationId).toBeFalsy(); expect(controller.classificationId).toBeFalsy();
controller.closeContract({id: 1}); controller.closeContract({id: 1});
@ -72,7 +72,7 @@ describe('Client', () => {
describe('returnDialog()', () => { describe('returnDialog()', () => {
it('should call the returnDialog method and perform a PATCH query, then call _getClassifications method', () => { it('should call the returnDialog method and perform a PATCH query, then call _getClassifications method', () => {
spyOn(controller, '_getClassifications'); jest.spyOn(controller, '_getClassifications').mockReturnThis();
controller.classificationId = 1; controller.classificationId = 1;
$httpBackend.when('PATCH', `CreditClassifications/1`).respond(200); $httpBackend.when('PATCH', `CreditClassifications/1`).respond(200);
$httpBackend.expect('PATCH', `CreditClassifications/1`); $httpBackend.expect('PATCH', `CreditClassifications/1`);

View File

@ -42,7 +42,7 @@ describe('Client', () => {
}); });
it('should call show() method when the client have a recovery', () => { it('should call show() method when the client have a recovery', () => {
spyOn(controller.$scope.confirmation, 'show'); jest.spyOn(controller.$scope.confirmation, 'show');
$httpBackend.whenGET(`Recoveries/101/hasActiveRecovery`).respond(true); $httpBackend.whenGET(`Recoveries/101/hasActiveRecovery`).respond(true);
$httpBackend.expectGET(`Recoveries/101/hasActiveRecovery`); $httpBackend.expectGET(`Recoveries/101/hasActiveRecovery`);
controller.onSubmit(); controller.onSubmit();
@ -52,7 +52,7 @@ describe('Client', () => {
}); });
it('should call addCredit() method when the client doesnt have a recovery', () => { it('should call addCredit() method when the client doesnt have a recovery', () => {
spyOn(controller, 'addCredit'); jest.spyOn(controller, 'addCredit');
$httpBackend.whenGET(`Recoveries/101/hasActiveRecovery`).respond(false); $httpBackend.whenGET(`Recoveries/101/hasActiveRecovery`).respond(false);
$httpBackend.expectGET(`Recoveries/101/hasActiveRecovery`); $httpBackend.expectGET(`Recoveries/101/hasActiveRecovery`);
controller.onSubmit(); controller.onSubmit();
@ -64,7 +64,7 @@ describe('Client', () => {
describe('cancel()', () => { describe('cancel()', () => {
it('should call goToIndex()', () => { it('should call goToIndex()', () => {
spyOn(controller, 'goToIndex'); jest.spyOn(controller, 'goToIndex');
controller.cancel(); controller.cancel();
expect(controller.goToIndex).toHaveBeenCalledWith(); expect(controller.goToIndex).toHaveBeenCalledWith();
@ -73,7 +73,7 @@ describe('Client', () => {
describe('returnDialog()', () => { describe('returnDialog()', () => {
it('should call addCredit() when is called with accept', () => { it('should call addCredit() when is called with accept', () => {
spyOn(controller, 'addCredit'); jest.spyOn(controller, 'addCredit');
controller.returnDialog('accept'); controller.returnDialog('accept');
expect(controller.addCredit).toHaveBeenCalledWith(); expect(controller.addCredit).toHaveBeenCalledWith();
@ -82,7 +82,7 @@ describe('Client', () => {
describe('addCredit()', () => { describe('addCredit()', () => {
it('should call the function go() on $state to go to the credit list', () => { it('should call the function go() on $state to go to the credit list', () => {
spyOn($state, 'go'); jest.spyOn($state, 'go');
client.credit = 1; client.credit = 1;
controller.addCredit(); controller.addCredit();

View File

@ -23,7 +23,7 @@ describe('Client', () => {
it(`should not apply any changes if the received id is the same stored in _clientFk`, () => { it(`should not apply any changes if the received id is the same stored in _clientFk`, () => {
controller.client = 'I exist!'; controller.client = 'I exist!';
controller._clientFk = 1; controller._clientFk = 1;
spyOn(controller, 'getCard'); jest.spyOn(controller, 'getCard');
controller.clientFk = 1; controller.clientFk = 1;
expect(controller.client).toEqual('I exist!'); expect(controller.client).toEqual('I exist!');
@ -34,7 +34,7 @@ describe('Client', () => {
it(`should set the received id into _clientFk, set the client to null and then call getCard()`, () => { it(`should set the received id into _clientFk, set the client to null and then call getCard()`, () => {
controller.client = `Please don't`; controller.client = `Please don't`;
controller._clientFk = 1; controller._clientFk = 1;
spyOn(controller, 'getCard'); jest.spyOn(controller, 'getCard');
controller.clientFk = 999; controller.clientFk = 999;
expect(controller.client).toBeNull(); expect(controller.client).toBeNull();
@ -45,7 +45,7 @@ describe('Client', () => {
describe('client()', () => { describe('client()', () => {
it(`should save the client into _client and then call relocate()`, () => { it(`should save the client into _client and then call relocate()`, () => {
spyOn(controller.$.popover, 'relocate'); jest.spyOn(controller.$.popover, 'relocate');
controller.client = `i'm the client!`; controller.client = `i'm the client!`;
$timeout.flush(); $timeout.flush();
@ -56,7 +56,7 @@ describe('Client', () => {
describe('show()', () => { describe('show()', () => {
it(`should call the show()`, () => { it(`should call the show()`, () => {
spyOn(controller.$.popover, 'show'); jest.spyOn(controller.$.popover, 'show');
controller.show(); controller.show();
expect(controller.$.popover.show).toHaveBeenCalledWith(); expect(controller.$.popover.show).toHaveBeenCalledWith();

View File

@ -77,18 +77,15 @@
<tpl-body> <tpl-body>
<div> <div>
<h5 style="text-align: center"> <h5 style="text-align: center">
<span translate>From date</span> <span translate>Send consumer report</span>
</h5> </h5>
<vn-date-picker <vn-date-picker
vn-id="from" vn-id="from"
vn-one vn-one
ng-model="$ctrl.from" ng-model="$ctrl.from"
label="From hour" label="From date"
vn-focus> vn-focus>
</vn-date-picker> </vn-date-picker>
<h5 style="text-align: center">
<span translate>To date</span>
</h5>
<vn-date-picker <vn-date-picker
vn-id="to" vn-id="to"
vn-one vn-one

View File

@ -1,2 +1,4 @@
Simple ticket: Ticket simple Simple ticket: Ticket simple
Send consumer report: Enviar informe de consumo Send consumer report: Enviar informe de consumo
From date: Fecha desde
To date: Fecha hasta

View File

@ -19,8 +19,8 @@ describe('Client', () => {
describe('client() setter', () => { describe('client() setter', () => {
it('should set the client data and then call setDefaultParams() and getAllowedContentTypes()', () => { it('should set the client data and then call setDefaultParams() and getAllowedContentTypes()', () => {
spyOn(controller, 'setDefaultParams'); jest.spyOn(controller, 'setDefaultParams');
spyOn(controller, 'getAllowedContentTypes'); jest.spyOn(controller, 'getAllowedContentTypes');
controller.client = { controller.client = {
id: 15, id: 15,
name: 'Bruce wayne' name: 'Bruce wayne'

View File

@ -19,8 +19,8 @@ describe('Client', () => {
describe('client() setter', () => { describe('client() setter', () => {
it('should set the client data and then call setDefaultParams() and getAllowedContentTypes()', () => { it('should set the client data and then call setDefaultParams() and getAllowedContentTypes()', () => {
spyOn(controller, 'setDefaultParams'); jest.spyOn(controller, 'setDefaultParams');
spyOn(controller, 'getAllowedContentTypes'); jest.spyOn(controller, 'getAllowedContentTypes');
controller._client = undefined; controller._client = undefined;
controller.client = { controller.client = {
id: 15 id: 15

View File

@ -22,8 +22,8 @@ describe('Client', () => {
it('should make an HTTP Post query', () => { it('should make an HTTP Post query', () => {
const dmsId = 1; const dmsId = 1;
const dmsIndex = 0; const dmsIndex = 0;
spyOn(controller.vnApp, 'showSuccess'); jest.spyOn(controller.vnApp, 'showSuccess');
spyOn(controller.$.model, 'remove'); jest.spyOn(controller.$.model, 'remove');
controller.clientDms = [{dmsFk: 1}]; controller.clientDms = [{dmsFk: 1}];
controller.dmsIndex = dmsIndex; controller.dmsIndex = dmsIndex;

View File

@ -24,14 +24,15 @@ export default class Controller extends Component {
const filter = encodeURIComponent(JSON.stringify(filterObj)); const filter = encodeURIComponent(JSON.stringify(filterObj));
const query = `Clients/findOne?filter=${filter}`; const query = `Clients/findOne?filter=${filter}`;
this.$http.get(query).then(res => { this.$http.get(query).then(res => {
if (res.data.id) { const params = {clientId: res.data.id};
const params = {clientId: res.data.id}; const question = $t('Found a client with this phone or email', params, null, null, 'sanitizeParameters');
const question = $t('Found a client with this phone or email', params, null, null, 'sanitizeParameters');
this.client.despiteOfClient = params.clientId; this.client.despiteOfClient = params.clientId;
this.$.confirmDuplicatedClient.question = question; this.$.confirmDuplicatedClient.question = question;
this.$.confirmDuplicatedClient.show(); this.$.confirmDuplicatedClient.show();
} }).catch(error => {
if (error.status == 404)
this.save();
}); });
} }

View File

@ -29,7 +29,7 @@ describe('Client', () => {
describe('onSubmit()', () => { describe('onSubmit()', () => {
it('should call the save() method directly', () => { it('should call the save() method directly', () => {
spyOn(controller, 'save'); jest.spyOn(controller, 'save');
controller.onSubmit(); controller.onSubmit();
@ -37,8 +37,8 @@ describe('Client', () => {
}); });
it('should call the checkExistingClient() if the isTaxDataChecked property is checked', () => { it('should call the checkExistingClient() if the isTaxDataChecked property is checked', () => {
spyOn(controller, 'save'); jest.spyOn(controller, 'save');
spyOn(controller, 'checkExistingClient'); jest.spyOn(controller, 'checkExistingClient');
controller.client.isTaxDataChecked = true; controller.client.isTaxDataChecked = true;
controller.onSubmit(); controller.onSubmit();
@ -51,7 +51,7 @@ describe('Client', () => {
describe('checkExistingClient()', () => { describe('checkExistingClient()', () => {
it('should show a save confirmation when a duplicated client is found and then set the despiteOfClient property', () => { it('should show a save confirmation when a duplicated client is found and then set the despiteOfClient property', () => {
controller.$.confirmDuplicatedClient = {show: () => {}}; controller.$.confirmDuplicatedClient = {show: () => {}};
spyOn(controller.$.confirmDuplicatedClient, 'show'); jest.spyOn(controller.$.confirmDuplicatedClient, 'show');
const filterObj = { const filterObj = {
where: { where: {
and: [ and: [
@ -74,7 +74,7 @@ describe('Client', () => {
describe('checkEtChanges()', () => { describe('checkEtChanges()', () => {
it(`should show a propagation confirmation if isEqualizated property is changed and invoice by address is checked`, () => { it(`should show a propagation confirmation if isEqualizated property is changed and invoice by address is checked`, () => {
controller.$.propagateIsEqualizated = {show: () => {}}; controller.$.propagateIsEqualizated = {show: () => {}};
spyOn(controller.$.propagateIsEqualizated, 'show'); jest.spyOn(controller.$.propagateIsEqualizated, 'show');
const orgData = $scope.watcher.orgData; const orgData = $scope.watcher.orgData;
orgData.hasToInvoiceByAddress = true; orgData.hasToInvoiceByAddress = true;
@ -86,7 +86,7 @@ describe('Client', () => {
}); });
it(`should call to the onAcceptEt() method if isEqualizated property is changed and invoice by address isn't checked`, () => { it(`should call to the onAcceptEt() method if isEqualizated property is changed and invoice by address isn't checked`, () => {
spyOn(controller, 'onAcceptEt'); jest.spyOn(controller, 'onAcceptEt');
const orgData = $scope.watcher.orgData; const orgData = $scope.watcher.orgData;
orgData.hasToInvoiceByAddress = false; orgData.hasToInvoiceByAddress = false;

View File

@ -27,7 +27,7 @@ describe('Client', () => {
describe('onSubmit()', () => { describe('onSubmit()', () => {
it('should call the function go() on $state to go to the greuges list', () => { it('should call the function go() on $state to go to the greuges list', () => {
spyOn($state, 'go'); jest.spyOn($state, 'go');
controller.onSubmit(); controller.onSubmit();
expect(controller.$state.go).toHaveBeenCalledWith('client.card.greuge.index'); expect(controller.$state.go).toHaveBeenCalledWith('client.card.greuge.index');

View File

@ -15,7 +15,7 @@ describe('Client index', () => {
it('should navigate to the ticket index using params as filter', () => { it('should navigate to the ticket index using params as filter', () => {
const client = {id: 101}; const client = {id: 101};
const event = new MouseEvent('click', {cancelable: true}); const event = new MouseEvent('click', {cancelable: true});
spyOn($state, 'go'); jest.spyOn($state, 'go');
controller.filterTickets(client, event); controller.filterTickets(client, event);

View File

@ -20,7 +20,7 @@ describe('Client', () => {
let params = {townFk: 1, provinceFk: 1, countryFk: 1, code: '46460'}; let params = {townFk: 1, provinceFk: 1, countryFk: 1, code: '46460'};
controller.data = {townFk: 1, provinceFk: 1, countryFk: 1, code: '46460'}; controller.data = {townFk: 1, provinceFk: 1, countryFk: 1, code: '46460'};
spyOn(controller.vnApp, 'showMessage'); jest.spyOn(controller.vnApp, 'showMessage');
$httpBackend.when('PATCH', `postcodes`, params).respond(200, params); $httpBackend.when('PATCH', `postcodes`, params).respond(200, params);
$httpBackend.expect('PATCH', `postcodes`, params).respond(params); $httpBackend.expect('PATCH', `postcodes`, params).respond(params);

View File

@ -27,7 +27,7 @@ describe('Client', () => {
describe('onSubmit()', () => { describe('onSubmit()', () => {
it('should call the function go() on $state to go to the recovery list', () => { it('should call the function go() on $state to go to the recovery list', () => {
spyOn($state, 'go'); jest.spyOn($state, 'go');
controller.onSubmit(); controller.onSubmit();
expect(controller.$state.go).toHaveBeenCalledWith('client.card.recovery.index'); expect(controller.$state.go).toHaveBeenCalledWith('client.card.recovery.index');

View File

@ -23,7 +23,7 @@
<vn-autocomplete vn-one vn-id="sampleType" <vn-autocomplete vn-one vn-id="sampleType"
ng-model="$ctrl.clientSample.typeFk" ng-model="$ctrl.clientSample.typeFk"
model="ClientSample.typeFk" model="ClientSample.typeFk"
fields="['code','hasCompany']" fields="['code','hasCompany', 'hasPreview']"
url="Samples/visible" url="Samples/visible"
show-field="description" show-field="description"
value-field="id" value-field="id"
@ -31,7 +31,7 @@
</vn-autocomplete> </vn-autocomplete>
<vn-autocomplete vn-one <vn-autocomplete vn-one
ng-model="$ctrl.companyId" ng-model="$ctrl.companyId"
model="ClientSample.companyId" model="ClientSample.companyFk"
data="companiesData" data="companiesData"
show-field="code" show-field="code"
value-field="id" value-field="id"
@ -42,7 +42,10 @@
</vn-card> </vn-card>
<vn-button-bar> <vn-button-bar>
<vn-submit label="Send"></vn-submit> <vn-submit label="Send"></vn-submit>
<vn-button label="Preview" ng-click="$ctrl.showPreview()"></vn-button> <vn-button ng-if="sampleType.selection.hasPreview"
label="Preview"
ng-click="$ctrl.showPreview()">
</vn-button>
<vn-button ui-sref="client.card.sample.index" label="Cancel"></vn-button> <vn-button ui-sref="client.card.sample.index" label="Cancel"></vn-button>
</vn-button-bar> </vn-button-bar>
</form> </form>

View File

@ -26,13 +26,13 @@ class Controller extends Component {
} }
get companyId() { get companyId() {
if (!this.clientSample.companyId) if (!this.clientSample.companyFk)
this.clientSample.companyId = this.vnConfig.companyFk; this.clientSample.companyFk = this.vnConfig.companyFk;
return this.clientSample.companyId; return this.clientSample.companyFk;
} }
set companyId(value) { set companyId(value) {
this.clientSample.companyId = value; this.clientSample.companyFk = value;
} }
onSubmit() { onSubmit() {
@ -74,11 +74,11 @@ class Controller extends Component {
if (!sampleType) if (!sampleType)
return this.vnApp.showError(this.$translate.instant('Choose a sample')); return this.vnApp.showError(this.$translate.instant('Choose a sample'));
if (sampleType.hasCompany && !this.clientSample.companyId) if (sampleType.hasCompany && !this.clientSample.companyFk)
return this.vnApp.showError(this.$translate.instant('Choose a company')); return this.vnApp.showError(this.$translate.instant('Choose a company'));
if (sampleType.hasCompany) if (sampleType.hasCompany)
params.companyId = this.clientSample.companyId; params.companyId = this.clientSample.companyFk;
if (isPreview) params.isPreview = true; if (isPreview) params.isPreview = true;

View File

@ -52,7 +52,7 @@ describe('Client', () => {
describe('onSubmit()', () => { describe('onSubmit()', () => {
it(`should call sendSample() method`, () => { it(`should call sendSample() method`, () => {
spyOn(controller, 'sendSample'); jest.spyOn(controller, 'sendSample');
controller.onSubmit(); controller.onSubmit();
expect(controller.sendSample).toHaveBeenCalledWith(); expect(controller.sendSample).toHaveBeenCalledWith();
@ -61,7 +61,7 @@ describe('Client', () => {
describe('send()', () => { describe('send()', () => {
it(`should not perform an HTTP query if no recipient is specified`, () => { it(`should not perform an HTTP query if no recipient is specified`, () => {
spyOn(controller.$http, 'get'); jest.spyOn(controller.$http, 'get');
controller.$.sampleType.selection = { controller.$.sampleType.selection = {
hasCompany: false, hasCompany: false,
@ -77,7 +77,7 @@ describe('Client', () => {
}); });
it(`should not perform an HTTP query if no sample is specified`, () => { it(`should not perform an HTTP query if no sample is specified`, () => {
spyOn(controller.$http, 'get'); jest.spyOn(controller.$http, 'get');
controller.$.sampleType.selection = null; controller.$.sampleType.selection = null;
controller.clientSample = { controller.clientSample = {
@ -91,7 +91,7 @@ describe('Client', () => {
}); });
it(`should not perform an HTTP query if company is required and not specified`, () => { it(`should not perform an HTTP query if company is required and not specified`, () => {
spyOn(controller.$http, 'get'); jest.spyOn(controller.$http, 'get');
controller.$.sampleType.selection = { controller.$.sampleType.selection = {
hasCompany: true, hasCompany: true,
@ -107,7 +107,7 @@ describe('Client', () => {
expect(controller.$http.get).not.toHaveBeenCalled(); expect(controller.$http.get).not.toHaveBeenCalled();
}); });
it(`should perform an HTTP query without passing companyId param`, () => { it(`should perform an HTTP query without passing companyFk param`, () => {
controller.$.sampleType.selection = { controller.$.sampleType.selection = {
hasCompany: false, hasCompany: false,
code: 'MyReport' code: 'MyReport'
@ -116,25 +116,34 @@ describe('Client', () => {
clientId: 101, clientId: 101,
recipient: 'client@email.com' recipient: 'client@email.com'
}; };
const expectedParams = {
clientId: 101,
recipient: 'client@email.com'
};
const serializedParams = $httpParamSerializer(expectedParams);
const serializedParams = $httpParamSerializer(controller.clientSample);
$httpBackend.expect('GET', `email/MyReport?${serializedParams}`).respond(true); $httpBackend.expect('GET', `email/MyReport?${serializedParams}`).respond(true);
controller.send(false, () => {}); controller.send(false, () => {});
$httpBackend.flush(); $httpBackend.flush();
}); });
it(`should perform an HTTP query passing companyId param`, () => { it(`should perform an HTTP query passing companyFk param`, () => {
controller.$.sampleType.selection = { controller.$.sampleType.selection = {
hasCompany: true, hasCompany: true,
code: 'MyReport' code: 'MyReport'
}; };
controller.clientSample = { controller.clientSample = {
clientId: 101,
recipient: 'client@email.com',
companyFk: 442
};
const expectedParams = {
clientId: 101, clientId: 101,
recipient: 'client@email.com', recipient: 'client@email.com',
companyId: 442 companyId: 442
}; };
const serializedParams = $httpParamSerializer(expectedParams);
const serializedParams = $httpParamSerializer(controller.clientSample);
$httpBackend.expect('GET', `email/MyReport?${serializedParams}`).respond(true); $httpBackend.expect('GET', `email/MyReport?${serializedParams}`).respond(true);
controller.send(false, () => {}); controller.send(false, () => {});
$httpBackend.flush(); $httpBackend.flush();
@ -143,7 +152,7 @@ describe('Client', () => {
describe('showPreview()', () => { describe('showPreview()', () => {
it(`should open a sample preview`, () => { it(`should open a sample preview`, () => {
spyOn(controller.$.showPreview, 'show'); jest.spyOn(controller.$.showPreview, 'show');
controller.send = (isPreview, cb) => { controller.send = (isPreview, cb) => {
cb({ cb({
@ -158,7 +167,7 @@ describe('Client', () => {
describe('sendSample()', () => { describe('sendSample()', () => {
it(`should perform a query (GET) and call go() method`, () => { it(`should perform a query (GET) and call go() method`, () => {
spyOn(controller.$state, 'go'); jest.spyOn(controller.$state, 'go');
controller.send = (isPreview, cb) => { controller.send = (isPreview, cb) => {
cb({ cb({

View File

@ -27,7 +27,7 @@ describe('Client', () => {
let params = {destinationFk: 101, destination: 111111111, message: 'My SMS'}; let params = {destinationFk: 101, destination: 111111111, message: 'My SMS'};
controller.sms = {destinationFk: 101, destination: 111111111, message: 'My SMS'}; controller.sms = {destinationFk: 101, destination: 111111111, message: 'My SMS'};
spyOn(controller.vnApp, 'showMessage'); jest.spyOn(controller.vnApp, 'showMessage');
$httpBackend.expect('POST', `Clients/101/sendSms`, params).respond(200, params); $httpBackend.expect('POST', `Clients/101/sendSms`, params).respond(200, params);
controller.onResponse('accept'); controller.onResponse('accept');
@ -39,7 +39,7 @@ describe('Client', () => {
it('should call onResponse without the destination and show an error snackbar', () => { it('should call onResponse without the destination and show an error snackbar', () => {
controller.sms = {destinationFk: 101, message: 'My SMS'}; controller.sms = {destinationFk: 101, message: 'My SMS'};
spyOn(controller.vnApp, 'showError'); jest.spyOn(controller.vnApp, 'showError');
controller.onResponse('accept'); controller.onResponse('accept');
@ -49,7 +49,7 @@ describe('Client', () => {
it('should call onResponse without the message and show an error snackbar', () => { it('should call onResponse without the message and show an error snackbar', () => {
controller.sms = {destinationFk: 101, destination: 222222222}; controller.sms = {destinationFk: 101, destination: 222222222};
spyOn(controller.vnApp, 'showError'); jest.spyOn(controller.vnApp, 'showError');
controller.onResponse('accept'); controller.onResponse('accept');

View File

@ -14,10 +14,10 @@ describe('Client', () => {
})); }));
describe('$onChanges()', () => { describe('$onChanges()', () => {
it('should perform a GET query and define summary property', () => { it('should perform a GET query and then define the summary property', () => {
let res = {name: 'Superman', classifications: []}; let res = {name: 'Superman', classifications: []};
spyOn(controller, 'sumRisk'); jest.spyOn(controller, 'sumRisk').mockReturnThis();
$httpBackend.when('GET', `Clients/101/summary`).respond(200, res); $httpBackend.when('GET', `Clients/101/summary`).respond(200, res);
$httpBackend.expect('GET', `Clients/101/summary`); $httpBackend.expect('GET', `Clients/101/summary`);

View File

@ -12,13 +12,13 @@ describe('Component VnClientWebAccess', () => {
$scope = $rootScope.$new(); $scope = $rootScope.$new();
$httpBackend = _$httpBackend_; $httpBackend = _$httpBackend_;
vnApp = _vnApp_; vnApp = _vnApp_;
spyOn(vnApp, 'showError'); jest.spyOn(vnApp, 'showError');
controller = $componentController('vnClientWebAccess', {$scope}); controller = $componentController('vnClientWebAccess', {$scope});
})); }));
describe('$onChanges()', () => { describe('$onChanges()', () => {
it(`should pass client's account data to account then call isCustomer function`, () => { it(`should pass client's account data to account then call isCustomer function`, () => {
spyOn(controller, 'isCustomer'); jest.spyOn(controller, 'isCustomer');
controller.client = {client: 'Bruce Wayne', account: 'Wayne Industries'}; controller.client = {client: 'Bruce Wayne', account: 'Wayne Industries'};
controller.account = {}; controller.account = {};
controller.$onChanges(); controller.$onChanges();

View File

@ -14,7 +14,7 @@ describe('Component vnClientWebPayment', () => {
$scope.model = crudModel; $scope.model = crudModel;
$httpBackend = _$httpBackend_; $httpBackend = _$httpBackend_;
vnApp = _vnApp_; vnApp = _vnApp_;
spyOn(vnApp, 'showError'); jest.spyOn(vnApp, 'showError');
controller = $componentController('vnClientWebPayment', {$scope: $scope}); controller = $componentController('vnClientWebPayment', {$scope: $scope});
})); }));

View File

@ -68,6 +68,14 @@ module.exports = Self => {
type: 'Number', type: 'Number',
description: 'The currency id to filter', description: 'The currency id to filter',
http: {source: 'query'} http: {source: 'query'}
}, {
arg: 'from',
type: 'Date',
description: `The from date filter`
}, {
arg: 'to',
type: 'Date',
description: `The to date filter`
} }
], ],
returns: { returns: {
@ -91,6 +99,10 @@ module.exports = Self => {
return {[param]: {like: `%${value}%`}}; return {[param]: {like: `%${value}%`}};
case 'created': case 'created':
return {'e.created': {gte: value}}; return {'e.created': {gte: value}};
case 'from':
return {'t.landed': {gte: value}};
case 'to':
return {'t.landed': {lte: value}};
case 'id': case 'id':
case 'isBooked': case 'isBooked':
case 'isConfirmed': case 'isConfirmed':

View File

@ -0,0 +1,76 @@
module.exports = Self => {
Self.remoteMethod('getEntry', {
description: 'Returns an entry',
accessType: 'READ',
accepts: {
arg: 'id',
type: 'number',
required: true,
description: 'The entry id',
http: {source: 'path'}
},
returns: {
type: 'object',
root: true
},
http: {
path: `/:id/getEntry`,
verb: 'GET'
}
});
Self.getEntry = async id => {
let filter = {
where: {id: id},
include: [
{
relation: 'supplier',
scope: {
fields: ['id', 'nickname']
}
},
{
relation: 'travel',
scope: {
fields: ['id', 'name', 'shipped', 'landed', 'agencyFk', 'warehouseOutFk', 'warehouseInFk'],
include: [
{
relation: 'agency',
scope: {
fields: ['name']
}
},
{
relation: 'warehouseOut',
scope: {
fields: ['name']
}
},
{
relation: 'warehouseIn',
scope: {
fields: ['name']
}
}
]
}
},
{
relation: 'currency',
scope: {
fields: ['id', 'name']
}
},
{
relation: 'company',
scope: {
fields: ['id', 'code']
}
}
],
};
let entry = await Self.app.models.Entry.findOne(filter);
return entry;
};
};

View File

@ -0,0 +1,31 @@
const app = require('vn-loopback/server/server');
describe('travel getEntry()', () => {
const entryId = 1;
it('should check the entry contains the id', async() => {
const entry = await app.models.Entry.getEntry(entryId);
expect(entry.id).toEqual(entryId);
});
it('should check the entry contains the supplier name', async() => {
const entry = await app.models.Entry.getEntry(entryId);
const supplierName = entry.supplier().nickname;
expect(supplierName).toEqual('Plants nick');
});
it('should check the entry contains the receiver warehouse name', async() => {
const entry = await app.models.Entry.getEntry(entryId);
const receiverWarehouseName = entry.travel().warehouseIn().name;
expect(receiverWarehouseName).toEqual('Warehouse One');
});
it('should check the entry contains the company code', async() => {
const entry = await app.models.Entry.getEntry(entryId);
const companyCode = entry.company().code;
expect(companyCode).toEqual('VNL');
});
});

View File

@ -1,4 +1,5 @@
module.exports = Self => { module.exports = Self => {
require('../methods/entry/filter')(Self); require('../methods/entry/filter')(Self);
require('../methods/entry/getEntry')(Self);
}; };

View File

@ -39,6 +39,9 @@
"commission": { "commission": {
"type": "Number" "type": "Number"
}, },
"isOrdered": {
"type": "Boolean"
},
"created": { "created": {
"type": "date" "type": "date"
}, },

View File

@ -11,11 +11,34 @@ class Controller extends ModuleCard {
fields: ['id', 'code'] fields: ['id', 'code']
} }
}, { }, {
relation: 'travel' relation: 'travel',
scope: {
fields: ['id', 'landed', 'agencyFk', 'warehouseOutFk'],
include: [
{
relation: 'agency',
scope: {
fields: ['name']
}
},
{
relation: 'warehouseOut',
scope: {
fields: ['name']
}
},
{
relation: 'warehouseIn',
scope: {
fields: ['name']
}
}
]
}
}, { }, {
relation: 'supplier', relation: 'supplier',
scope: { scope: {
fields: ['id', 'name'] fields: ['id', 'nickname']
} }
}, { }, {
relation: 'currency' relation: 'currency'
@ -27,7 +50,7 @@ class Controller extends ModuleCard {
} }
} }
ngModule.component('vnEntry Card', { ngModule.component('vnEntryCard', {
template: require('./index.html'), template: require('./index.html'),
controller: Controller controller: Controller
}); });

View File

@ -6,16 +6,37 @@
<a translate-attr="{title: 'Preview'}" ui-sref="entry.card.summary({id: $ctrl.entry.id})"> <a translate-attr="{title: 'Preview'}" ui-sref="entry.card.summary({id: $ctrl.entry.id})">
<vn-icon icon="desktop_windows"></vn-icon> <vn-icon icon="desktop_windows"></vn-icon>
</a> </a>
<span></span> <vn-icon-menu
vn-id="more-button"
icon="more_vert"
show-filter="false"
value-field="callback"
translate-fields="['name']"
data="$ctrl.moreOptions"
on-change="$ctrl.onMoreChange(value)"
on-open="$ctrl.onMoreOpen()">
</vn-icon-menu>
</div> </div>
<div class="body"> <div class="body">
<div class="attributes"> <div class="attributes">
<vn-label-value label="Id" <vn-label-value label="Id"
value="{{$ctrl.entry.id}}"> value="{{$ctrl.entry.id}}">
</vn-label-value> </vn-label-value>
<vn-label-value label="Reference" <vn-label-value label="Supplier"
value="{{$ctrl.entry.ref}}"> value="{{$ctrl.entry.supplier.nickname}}">
</vn-label-value> </vn-label-value>
<vn-label-value label="Agency "
value="{{$ctrl.entry.travel.agency.name}}">
</vn-label-value>
<vn-label-value label="Landed"
value="{{$ctrl.entry.travel.landed | date: 'dd/MM/yyyy'}}">
</vn-label-value>
<vn-label-value label="Warehouse Out"
value="{{$ctrl.entry.travel.warehouseOut.name}}">
</vn-label-value>
</div> </div>
<vn-quick-links
links="$ctrl.quicklinks">
</vn-quick-links>
</div> </div>
</div> </div>

Some files were not shown because too many files have changed in this diff Show More