This commit is contained in:
Carlos Jimenez Ruiz 2019-09-30 14:49:22 +02:00
commit 303f18d359
45 changed files with 1162 additions and 756 deletions

2
.gitignore vendored
View File

@ -10,4 +10,4 @@ npm-debug.log
datasources.*.json datasources.*.json
print.*.json print.*.json
db.json db.json
junitresults.xml junit.xml

4
Jenkinsfile vendored
View File

@ -71,7 +71,7 @@ pipeline {
} }
steps { steps {
nodejs('node-lts') { nodejs('node-lts') {
// sh 'karma start --junit' sh 'jest --ci --reporters=default --reporters=jest-junit --maxWorkers=1'
sh 'gulp backTestDockerOnce --junit --random --run-chown' sh 'gulp backTestDockerOnce --junit --random --run-chown'
} }
} }
@ -158,8 +158,8 @@ pipeline {
script { script {
if (!['master', 'test'].contains(env.BRANCH_NAME)) { if (!['master', 'test'].contains(env.BRANCH_NAME)) {
try { try {
junit '*/junitresults.xml'
junit 'junitresults.xml' junit 'junitresults.xml'
junit 'junit.xml'
} catch (e) { } catch (e) {
echo e.toString() echo e.toString()
} }

View File

@ -75,7 +75,7 @@ let actions = {
}, },
changeLanguageToEnglish: function(done) { changeLanguageToEnglish: function(done) {
let langSelector = 'vn-user-configuration-popover vn-autocomplete[field="$ctrl.lang"]'; let langSelector = '.user-configuration vn-autocomplete[field="$ctrl.lang"]';
this.waitToClick('#user') this.waitToClick('#user')
.wait(langSelector) .wait(langSelector)
@ -180,6 +180,7 @@ let actions = {
.evaluate_now(elementSelector => { .evaluate_now(elementSelector => {
const selectorMatches = document.querySelectorAll(elementSelector); const selectorMatches = document.querySelectorAll(elementSelector);
const element = selectorMatches[0]; const element = selectorMatches[0];
if (selectorMatches.length > 1) if (selectorMatches.length > 1)
throw new Error(`multiple matches of ${elementSelector} found`); throw new Error(`multiple matches of ${elementSelector} found`);
@ -190,17 +191,18 @@ let actions = {
isVisible = true; isVisible = true;
}; };
element.addEventListener('mouseover', eventHandler); element.addEventListener('mouseover', eventHandler);
const elementBoundaries = element.getBoundingClientRect(); const rect = element.getBoundingClientRect();
const x = elementBoundaries.left + element.offsetWidth / 2; const x = rect.left + rect.width / 2;
const y = elementBoundaries.top + element.offsetHeight / 2; const y = rect.top + rect.height / 2;
const elementInCenter = document.elementFromPoint(x, y); const elementInCenter = document.elementFromPoint(x, y);
const elementInTopLeft = document.elementFromPoint(elementBoundaries.left, elementBoundaries.top); const elementInTopLeft = document.elementFromPoint(rect.left, rect.top);
const elementInBottomRight = document.elementFromPoint(elementBoundaries.right, elementBoundaries.bottom); const elementInBottomRight = document.elementFromPoint(rect.right, rect.bottom);
const e = new MouseEvent('mouseover', { const e = new MouseEvent('mouseover', {
view: window, view: window,
bubbles: true, bubbles: true,
cancelable: true, cancelable: true,
}); });
if (elementInCenter) if (elementInCenter)
elementInCenter.dispatchEvent(e); elementInCenter.dispatchEvent(e);
@ -401,10 +403,12 @@ let actions = {
autocompleteSearch: function(autocompleteSelector, searchValue, done) { autocompleteSearch: function(autocompleteSelector, searchValue, done) {
this.wait(`${autocompleteSelector} input`) this.wait(`${autocompleteSelector} input`)
.waitToClick(`${autocompleteSelector} input`) .waitToClick(`${autocompleteSelector} input`)
.write(`${autocompleteSelector} vn-drop-down input`, searchValue) .write(`.vn-popover.shown .vn-drop-down input`, searchValue)
.waitToClick(`${autocompleteSelector} li.active`) .waitToClick(`.vn-popover.shown .vn-drop-down li.active`)
.wait((autocompleteSelector, searchValue) => { .wait((autocompleteSelector, searchValue) => {
return document.querySelector(`${autocompleteSelector} input`).value.toLowerCase().includes(searchValue.toLowerCase()); return document.querySelector(`${autocompleteSelector} input`).value
.toLowerCase()
.includes(searchValue.toLowerCase());
}, autocompleteSelector, searchValue) }, autocompleteSelector, searchValue)
.then(done) .then(done)
.catch(() => { .catch(() => {
@ -412,6 +416,17 @@ let actions = {
}); });
}, },
pickTime: function(selector, time, done) {
this.wait(selector)
.evaluate((selector, time) => {
let input = document.querySelector(selector);
input.value = time;
input.dispatchEvent(new Event('change'));
}, selector, time)
.then(done)
.catch(done);
},
datePicker: function(datePickerSelector, changeMonth, day, done) { datePicker: function(datePickerSelector, changeMonth, day, done) {
this.wait(datePickerSelector) this.wait(datePickerSelector)
.mousedown(datePickerSelector) .mousedown(datePickerSelector)

View File

@ -3,19 +3,19 @@ import components from './components_selectors.js';
export default { export default {
globalItems: { globalItems: {
applicationsMenuButton: '#apps', applicationsMenuButton: '#apps',
applicationsMenuVisible: 'vn-main-menu [vn-id="apps-menu"] ul', applicationsMenuVisible: '.modules-menu',
clientsButton: 'vn-main-menu [vn-id="apps-menu"] ul > li[ui-sref="client.index"]', clientsButton: '.modules-menu > li[ui-sref="client.index"]',
itemsButton: 'vn-main-menu [vn-id="apps-menu"] ul > li[ui-sref="item.index"]', itemsButton: '.modules-menu > li[ui-sref="item.index"]',
ticketsButton: 'vn-main-menu [vn-id="apps-menu"] ul > li[ui-sref="ticket.index"]', ticketsButton: '.modules-menu > li[ui-sref="ticket.index"]',
invoiceOutButton: 'vn-main-menu [vn-id="apps-menu"] ul > li[ui-sref="invoiceOut.index"]', invoiceOutButton: '.modules-menu > li[ui-sref="invoiceOut.index"]',
claimsButton: 'vn-main-menu [vn-id="apps-menu"] ul > li[ui-sref="claim.index"]', claimsButton: '.modules-menu > li[ui-sref="claim.index"]',
returnToModuleIndexButton: 'a[ui-sref="order.index"]', returnToModuleIndexButton: 'a[ui-sref="order.index"]',
userMenuButton: 'vn-topbar #user', userMenuButton: 'vn-topbar #user',
userLocalWarehouse: 'vn-topbar vn-popover vn-autocomplete[field="$ctrl.localWarehouseFk"]', userLocalWarehouse: '.user-configuration vn-autocomplete[field="$ctrl.localWarehouseFk"]',
userLocalBank: 'vn-topbar vn-popover vn-autocomplete[field="$ctrl.localBankFk"]', userLocalBank: '.user-configuration vn-autocomplete[field="$ctrl.localBankFk"]',
userLocalCompany: 'vn-topbar vn-popover vn-autocomplete[field="$ctrl.localCompanyFk"]', userLocalCompany: '.user-configuration vn-autocomplete[field="$ctrl.localCompanyFk"]',
userWarehouse: 'vn-topbar vn-popover vn-autocomplete[field="$ctrl.warehouseFk"]', userWarehouse: '.user-configuration vn-autocomplete[field="$ctrl.warehouseFk"]',
userCompany: 'vn-topbar vn-popover vn-autocomplete[field="$ctrl.companyFk"]', userCompany: '.user-configuration vn-autocomplete[field="$ctrl.companyFk"]',
userConfigFirstAutocompleteClear: '#localWarehouse > div > div > div > vn-icon.clear', userConfigFirstAutocompleteClear: '#localWarehouse > div > div > div > vn-icon.clear',
userConfigSecondAutocompleteClear: '#localBank > div > div > div > vn-icon.clear', userConfigSecondAutocompleteClear: '#localBank > div > div > div > vn-icon.clear',
userConfigThirdAutocompleteClear: '#localCompany > div > div > div > vn-icon.clear', userConfigThirdAutocompleteClear: '#localCompany > div > div > div > vn-icon.clear',
@ -45,7 +45,7 @@ export default {
}, },
clientDescriptor: { clientDescriptor: {
moreMenu: 'vn-client-descriptor vn-icon-menu > div > vn-icon', moreMenu: 'vn-client-descriptor vn-icon-menu > div > vn-icon',
simpleTicketButton: 'vn-client-descriptor vn-popover > div > div.content > div > div.list > ul > li' simpleTicketButton: '.vn-popover.shown .vn-drop-down li'
}, },
clientBasicData: { clientBasicData: {
basicDataButton: 'vn-left-menu a[ui-sref="client.card.basicData"]', basicDataButton: 'vn-left-menu a[ui-sref="client.card.basicData"]',
@ -177,7 +177,7 @@ export default {
dms: { dms: {
deleteFileButton: 'vn-client-dms-index vn-table vn-tr:nth-child(1) vn-icon-button[icon="delete"]', deleteFileButton: 'vn-client-dms-index vn-table vn-tr:nth-child(1) vn-icon-button[icon="delete"]',
firstDocWorker: 'vn-client-dms-index vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(8) > span', firstDocWorker: 'vn-client-dms-index vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(8) > span',
firstDocWorkerDescriptor: 'vn-client-dms-index > vn-worker-descriptor-popover > vn-popover', firstDocWorkerDescriptor: '.vn-popover.shown vn-worker-descriptor',
acceptDeleteButton: 'vn-client-dms-index > vn-confirm button[response="ACCEPT"]' acceptDeleteButton: 'vn-client-dms-index > vn-confirm button[response="ACCEPT"]'
}, },
itemsIndex: { itemsIndex: {
@ -218,7 +218,7 @@ export default {
itemDescriptor: { itemDescriptor: {
goBackToModuleIndexButton: 'vn-item-descriptor a[href="#!/item/index"]', goBackToModuleIndexButton: 'vn-item-descriptor a[href="#!/item/index"]',
moreMenu: 'vn-item-descriptor vn-icon-menu > div > vn-icon', moreMenu: 'vn-item-descriptor vn-icon-menu > div > vn-icon',
moreMenuRegularizeButton: 'vn-item-descriptor vn-drop-down > vn-popover ul > li[name="Regularize stock"]', moreMenuRegularizeButton: '.vn-popover.shown .vn-drop-down li[name="Regularize stock"]',
regularizeQuantityInput: 'vn-item-descriptor > vn-dialog > div > form > div.body > tpl-body > div > vn-textfield > div > div > div.infix > input', regularizeQuantityInput: 'vn-item-descriptor > vn-dialog > div > form > div.body > tpl-body > div > vn-textfield > div > div > div.infix > input',
regularizeWarehouseAutocomplete: 'vn-item-descriptor vn-dialog vn-autocomplete[field="$ctrl.warehouseFk"]', regularizeWarehouseAutocomplete: 'vn-item-descriptor vn-dialog vn-autocomplete[field="$ctrl.warehouseFk"]',
editButton: 'vn-item-card vn-item-descriptor vn-float-button[icon="edit"]', editButton: 'vn-item-card vn-item-descriptor vn-float-button[icon="edit"]',
@ -313,10 +313,10 @@ export default {
total: 'vn-ticket-summary vn-one.taxes > p:nth-child(3) > strong', total: 'vn-ticket-summary vn-one.taxes > p:nth-child(3) > strong',
sale: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr', sale: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr',
firstSaleItemId: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > span', firstSaleItemId: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > span',
firstSaleDescriptorImage: 'vn-ticket-summary vn-item-descriptor-popover > vn-popover vn-item-descriptor img', firstSaleDescriptorImage: '.vn-popover.shown vn-item-descriptor img',
itemDescriptorPopover: 'vn-ticket-summary vn-item-descriptor-popover > vn-popover', itemDescriptorPopover: '.vn-popover.shown vn-item-descriptor',
itemDescriptorPopoverItemDiaryButton: 'vn-ticket-summary > vn-item-descriptor-popover a[href="#!/item/2/diary?warehouseFk=5&ticketFk=20"]', itemDescriptorPopoverItemDiaryButton: 'vn-item-descriptor a[href="#!/item/2/diary?warehouseFk=5&ticketFk=20"]',
popoverDiaryButton: 'vn-ticket-summary vn-item-descriptor-popover vn-item-descriptor vn-icon[icon="icon-transaction"]', popoverDiaryButton: '.vn-popover.shown vn-item-descriptor vn-icon[icon="icon-transaction"]',
firstSaleQuantity: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(3)', firstSaleQuantity: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(3)',
firstSaleDiscount: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(6)', firstSaleDiscount: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(6)',
invoiceOutRef: 'vn-ticket-summary > vn-card > div > vn-horizontal > vn-one:nth-child(1) > vn-label-value:nth-child(6) > section > span', invoiceOutRef: 'vn-ticket-summary > vn-card > div > vn-horizontal > vn-one:nth-child(1) > vn-label-value:nth-child(6) > section > span',
@ -324,7 +324,7 @@ export default {
}, },
ticketsIndex: { ticketsIndex: {
openAdvancedSearchButton: 'vn-ticket-index vn-searchbar t-right-icons > vn-icon[icon="keyboard_arrow_down"]', openAdvancedSearchButton: 'vn-ticket-index vn-searchbar t-right-icons > vn-icon[icon="keyboard_arrow_down"]',
advancedSearchInvoiceOut: 'vn-ticket-index vn-searchbar vn-ticket-search-panel vn-textfield[model="filter.refFk"] input', advancedSearchInvoiceOut: 'vn-ticket-search-panel vn-textfield[model="filter.refFk"] input',
newTicketButton: 'vn-ticket-index > a', newTicketButton: 'vn-ticket-index > a',
searchResult: 'vn-ticket-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr', searchResult: 'vn-ticket-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr',
searchWeeklyResult: 'vn-ticket-weekly-index vn-table vn-tbody > vn-tr', searchWeeklyResult: 'vn-ticket-weekly-index vn-table vn-tbody > vn-tr',
@ -332,11 +332,11 @@ export default {
searchTicketInput: `vn-ticket-index ${components.vnTextfield}`, searchTicketInput: `vn-ticket-index ${components.vnTextfield}`,
searchWeeklyTicketInput: `vn-ticket-weekly-index ${components.vnTextfield}`, searchWeeklyTicketInput: `vn-ticket-weekly-index ${components.vnTextfield}`,
searchWeeklyClearInput: 'vn-ticket-weekly-index vn-searchbar i[class="material-icons clear"]', searchWeeklyClearInput: 'vn-ticket-weekly-index vn-searchbar i[class="material-icons clear"]',
advancedSearchButton: 'vn-ticket-index vn-searchbar > vn-popover vn-ticket-search-panel vn-submit[label="Search"] input', advancedSearchButton: 'vn-ticket-search-panel vn-submit[label="Search"] input',
searchButton: 'vn-ticket-index vn-searchbar vn-icon[icon="search"]', searchButton: 'vn-ticket-index vn-searchbar vn-icon[icon="search"]',
searchWeeklyButton: 'vn-ticket-weekly-index vn-searchbar vn-icon[icon="search"]', searchWeeklyButton: 'vn-ticket-weekly-index vn-searchbar vn-icon[icon="search"]',
moreMenu: 'vn-ticket-index vn-icon-menu[vn-id="more-button"] > div > vn-icon', moreMenu: 'vn-ticket-index vn-icon-menu[vn-id="more-button"] > div > vn-icon',
moreMenuWeeklyTickets: 'vn-ticket-index vn-icon-menu vn-drop-down > vn-popover li:nth-child(2)', moreMenuWeeklyTickets: '.vn-popover.shown .vn-drop-down li:nth-child(2)',
sixthWeeklyTicket: 'vn-ticket-weekly-index vn-table vn-tr:nth-child(6) vn-autocomplete[field="weekly.weekDay"] input', sixthWeeklyTicket: 'vn-ticket-weekly-index vn-table vn-tr:nth-child(6) vn-autocomplete[field="weekly.weekDay"] input',
weeklyTicket: 'vn-ticket-weekly-index vn-table > div > vn-tbody > vn-tr', weeklyTicket: 'vn-ticket-weekly-index vn-table > div > vn-tbody > vn-tr',
firstWeeklyTicketDeleteIcon: 'vn-ticket-weekly-index vn-tr:nth-child(1) vn-icon-button[icon="delete"]', firstWeeklyTicketDeleteIcon: 'vn-ticket-weekly-index vn-tr:nth-child(1) vn-icon-button[icon="delete"]',
@ -355,13 +355,13 @@ export default {
stateLabelValue: 'vn-ticket-descriptor vn-label-value[label="State"]', stateLabelValue: 'vn-ticket-descriptor vn-label-value[label="State"]',
goBackToModuleIndexButton: 'vn-ticket-descriptor a[ui-sref="ticket.index"]', goBackToModuleIndexButton: 'vn-ticket-descriptor a[ui-sref="ticket.index"]',
moreMenu: 'vn-ticket-descriptor vn-icon-menu > div > vn-icon', moreMenu: 'vn-ticket-descriptor vn-icon-menu > div > vn-icon',
moreMenuAddStowaway: 'vn-ticket-descriptor vn-drop-down > vn-popover ul > li[name="Add stowaway"]', moreMenuAddStowaway: '.vn-popover.shown .vn-drop-down li[name="Add stowaway"]',
moreMenuDeleteStowawayButton: 'vn-ticket-descriptor vn-drop-down > vn-popover ul > li[name="Remove stowaway"]', moreMenuDeleteStowawayButton: '.vn-popover.shown .vn-drop-down li[name="Remove stowaway"]',
moreMenuAddToTurn: 'vn-ticket-descriptor vn-drop-down > vn-popover ul > li[name="Add turn"]', moreMenuAddToTurn: '.vn-popover.shown .vn-drop-down li[name="Add turn"]',
moreMenuDeleteTicket: 'vn-ticket-descriptor vn-drop-down > vn-popover ul > li[name="Delete ticket"]', moreMenuDeleteTicket: '.vn-popover.shown .vn-drop-down li[name="Delete ticket"]',
moreMenuMakeInvoice: 'vn-ticket-descriptor vn-drop-down > vn-popover ul > li[name="Make invoice"]', moreMenuMakeInvoice: '.vn-popover.shown .vn-drop-down li[name="Make invoice"]',
moreMenuChangeShippedHour: 'vn-ticket-descriptor vn-drop-down > vn-popover ul > li[name="Change shipped hour"]', moreMenuChangeShippedHour: '.vn-popover.shown .vn-drop-down li[name="Change shipped hour"]',
changeShippedHourInput: 'vn-ticket-descriptor > vn-dialog.ng-isolate-scope.vn-dialog.shown vn-input-time input', changeShippedHourInput: 'vn-ticket-descriptor .vn-dialog.shown vn-input-time input',
addStowawayDialogFirstTicket: 'vn-ticket-descriptor > vn-add-stowaway > vn-dialog vn-table vn-tbody vn-tr', addStowawayDialogFirstTicket: 'vn-ticket-descriptor > vn-add-stowaway > vn-dialog vn-table vn-tbody vn-tr',
shipButton: 'vn-ticket-descriptor > div > div.body > div.quicklinks vn-icon[icon="icon-stowaway"]', shipButton: 'vn-ticket-descriptor > div > div.body > div.quicklinks vn-icon[icon="icon-stowaway"]',
thursdayButton: 'vn-ticket-descriptor > vn-dialog > div > form > div.body > tpl-body > div > vn-tool-bar > vn-button:nth-child(4)', thursdayButton: 'vn-ticket-descriptor > vn-dialog > div > form > div.body > tpl-body > div > vn-tool-bar > vn-button:nth-child(4)',
@ -398,21 +398,21 @@ export default {
ticketSales: { ticketSales: {
saleButton: 'vn-left-menu a[ui-sref="ticket.card.sale"]', saleButton: 'vn-left-menu a[ui-sref="ticket.card.sale"]',
saleLine: 'vn-table div > vn-tbody > vn-tr', saleLine: 'vn-table div > vn-tbody > vn-tr',
saleDescriptorPopover: 'vn-ticket-sale vn-item-descriptor-popover > vn-popover', saleDescriptorPopover: '.vn-popover.shown vn-item-descriptor',
saleDescriptorPopoverSummaryButton: 'vn-item-descriptor-popover a[ui-sref="item.card.summary({id: $ctrl.item.id})"]', saleDescriptorPopoverSummaryButton: '.vn-popover.shown vn-item-descriptor a[ui-sref="item.card.summary({id: $ctrl.item.id})"]',
descriptorItemDiaryButton: 'vn-item-descriptor .quicklinks.ng-scope > vn-horizontal > a > vn-icon > i', descriptorItemDiaryButton: 'vn-item-descriptor .quicklinks.ng-scope > vn-horizontal > a > vn-icon > i',
newItemFromCatalogButton: 'vn-ticket-sale vn-float-button[icon="add"]', newItemFromCatalogButton: 'vn-ticket-sale vn-float-button[icon="add"]',
newItemButton: 'vn-ticket-sale > vn-vertical > vn-card > div > vn-vertical > vn-one > vn-icon-button > button > vn-icon > i', newItemButton: 'vn-ticket-sale > vn-vertical > vn-card > div > vn-vertical > vn-one > vn-icon-button > button > vn-icon > i',
moreMenu: 'vn-ticket-sale vn-tool-bar > vn-button-menu[vn-id="more-button"] > div > button', moreMenu: 'vn-ticket-sale vn-tool-bar > vn-button-menu[vn-id="more-button"] > div > button',
moreMenuCreateClaim: 'vn-ticket-sale vn-tool-bar > vn-button-menu[vn-id="more-button"] vn-drop-down > vn-popover ul > li[name="Add claim"]', moreMenuCreateClaim: '.vn-popover.shown .vn-drop-down li[name="Add claim"]',
moreMenuReserve: 'vn-ticket-sale vn-tool-bar > vn-button-menu[vn-id="more-button"] vn-drop-down > vn-popover ul > li[name="Mark as reserved"]', moreMenuReserve: '.vn-popover.shown .vn-drop-down li[name="Mark as reserved"]',
moreMenuUnmarkReseved: 'vn-ticket-sale vn-tool-bar > vn-button-menu[vn-id="more-button"] vn-drop-down > vn-popover ul > li[name="Unmark as reserved"]', moreMenuUnmarkReseved: '.vn-popover.shown .vn-drop-down li[name="Unmark as reserved"]',
moreMenuUpdateDiscount: 'vn-ticket-sale vn-tool-bar > vn-button-menu[vn-id="more-button"] vn-drop-down > vn-popover ul > li[name="Update discount"]', moreMenuUpdateDiscount: '.vn-popover.shown .vn-drop-down li[name="Update discount"]',
moreMenuUpdateDiscountInput: 'vn-ticket-sale vn-dialog form vn-ticket-sale-edit-discount vn-input-number[model="$ctrl.newDiscount"] input', moreMenuUpdateDiscountInput: 'vn-ticket-sale vn-dialog form vn-ticket-sale-edit-discount vn-input-number[model="$ctrl.newDiscount"] input',
transferQuantityInput: 'vn-ticket-sale vn-popover.transfer.ng-isolate-scope.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable > span > text', transferQuantityInput: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable > span > text',
transferQuantityCell: 'vn-ticket-sale vn-popover.transfer.ng-isolate-scope.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable', transferQuantityCell: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable',
firstSaleClaimIcon: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(1) vn-icon[icon="icon-claims"]', firstSaleClaimIcon: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(1) vn-icon[icon="icon-claims"]',
firstSaleDescriptorImage: 'vn-ticket-sale vn-item-descriptor-popover > vn-popover vn-item-descriptor img', firstSaleDescriptorImage: '.vn-popover.shown vn-item-descriptor img',
firstSaleText: 'vn-table div > vn-tbody > vn-tr:nth-child(1)', firstSaleText: 'vn-table div > vn-tbody > vn-tr:nth-child(1)',
firstSaleThumbnailImage: 'vn-ticket-sale:nth-child(1) vn-tr:nth-child(1) vn-td:nth-child(3) > img', firstSaleThumbnailImage: 'vn-ticket-sale:nth-child(1) vn-tr:nth-child(1) vn-td:nth-child(3) > img',
firstSaleZoomedImage: 'body > div > div > img', firstSaleZoomedImage: 'body > div > div > img',
@ -421,9 +421,9 @@ export default {
firstSaleQuantityClearInput: 'vn-textfield[model="sale.quantity"] div.suffix > i', firstSaleQuantityClearInput: 'vn-textfield[model="sale.quantity"] div.suffix > i',
firstSaleIdInput: 'body > vn-app > div > ui-view > vn-ticket-card > vn-main-block > div > vn-ticket-sale > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(4) > vn-autocomplete > div > div > input', firstSaleIdInput: 'body > vn-app > div > ui-view > vn-ticket-card > vn-main-block > div > vn-ticket-sale > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(4) > vn-autocomplete > div > div > input',
firstSaleIdAutocomplete: 'vn-ticket-sale > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(4) > vn-autocomplete', firstSaleIdAutocomplete: 'vn-ticket-sale > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(4) > vn-autocomplete',
idAutocompleteFirstResult: 'vn-ticket-sale > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(4) > vn-autocomplete > vn-drop-down > vn-popover > div > div.content > div > div.list > ul > li', idAutocompleteFirstResult: '.vn-popover.shown .vn-drop-down li',
firstSalePrice: 'vn-ticket-sale vn-table vn-tr:nth-child(1) > vn-td:nth-child(7) > span', firstSalePrice: 'vn-ticket-sale vn-table vn-tr:nth-child(1) > vn-td:nth-child(7) > span',
firstSalePriceInput: 'vn-ticket-sale:nth-child(1) vn-popover.edit.dialog-summary.ng-isolate-scope.vn-popover.shown vn-input-number input', firstSalePriceInput: '.vn-popover.shown vn-input-number input',
firstSaleDiscount: 'vn-ticket-sale vn-table vn-tr:nth-child(1) > vn-td:nth-child(8) > span', firstSaleDiscount: 'vn-ticket-sale vn-table vn-tr:nth-child(1) > vn-td:nth-child(8) > span',
firstSaleDiscountInput: 'vn-ticket-sale:nth-child(1) vn-ticket-sale-edit-discount vn-input-number input', firstSaleDiscountInput: 'vn-ticket-sale:nth-child(1) vn-ticket-sale-edit-discount vn-input-number input',
firstSaleImport: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(9)', firstSaleImport: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(9)',
@ -449,10 +449,10 @@ export default {
thirdSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(3) vn-check[field="sale.checked"] md-checkbox', thirdSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(3) vn-check[field="sale.checked"] md-checkbox',
deleteSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="delete"]', deleteSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="delete"]',
transferSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="call_split"]', transferSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="call_split"]',
moveToTicketInput: 'vn-ticket-sale vn-popover.transfer vn-textfield[model="$ctrl.transfer.ticketId"] input', moveToTicketInput: '.vn-popover.shown vn-textfield[model="$ctrl.transfer.ticketId"] input',
moveToTicketInputClearButton: 'vn-popover.shown i[title="Clear"]', moveToTicketInputClearButton: '.vn-popover.shown i[title="Clear"]',
moveToTicketButton: 'vn-ticket-sale vn-popover.transfer vn-icon[icon="arrow_forward_ios"]', moveToTicketButton: '.vn-popover.shown vn-icon[icon="arrow_forward_ios"]',
moveToNewTicketButton: 'vn-ticket-sale vn-popover.transfer vn-button[label="New ticket"]', moveToNewTicketButton: '.vn-popover.shown vn-button[label="New ticket"]',
acceptDeleteLineButton: 'vn-ticket-sale > vn-confirm[vn-id="delete-lines"] button[response=ACCEPT]', acceptDeleteLineButton: 'vn-ticket-sale > vn-confirm[vn-id="delete-lines"] button[response=ACCEPT]',
acceptDeleteTicketButton: 'vn-ticket-sale > vn-confirm[vn-id="delete-ticket"] button[response=ACCEPT]', acceptDeleteTicketButton: 'vn-ticket-sale > vn-confirm[vn-id="delete-ticket"] button[response=ACCEPT]',
stateMenuButton: 'vn-ticket-sale vn-tool-bar > vn-button-menu[label="State"]' stateMenuButton: 'vn-ticket-sale vn-tool-bar > vn-button-menu[label="State"]'
@ -524,7 +524,7 @@ export default {
}, },
claimDescriptor: { claimDescriptor: {
moreMenu: 'vn-claim-descriptor vn-icon-menu[vn-id="more-button"]', moreMenu: 'vn-claim-descriptor vn-icon-menu[vn-id="more-button"]',
moreMenuDeleteClaim: 'vn-claim-descriptor vn-icon-menu vn-drop-down li[name="Delete claim"]', moreMenuDeleteClaim: '.vn-popover.shown .vn-drop-down li[name="Delete claim"]',
acceptDeleteClaim: 'vn-claim-descriptor > vn-confirm[vn-id="confirm-delete-claim"] button[response="ACCEPT"]' acceptDeleteClaim: 'vn-claim-descriptor > vn-confirm[vn-id="confirm-delete-claim"] button[response="ACCEPT"]'
}, },
claimSummary: { claimSummary: {
@ -532,13 +532,13 @@ export default {
state: 'vn-claim-summary vn-label-value[label="State"] > section > span', state: 'vn-claim-summary vn-label-value[label="State"] > section > span',
observation: 'vn-claim-summary vn-textarea[model="$ctrl.summary.claim.observation"] > div > textarea', observation: 'vn-claim-summary vn-textarea[model="$ctrl.summary.claim.observation"] > div > textarea',
firstSaleItemId: 'vn-claim-summary vn-horizontal > vn-auto:nth-child(4) > vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(1) > span', firstSaleItemId: 'vn-claim-summary vn-horizontal > vn-auto:nth-child(4) > vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(1) > span',
firstSaleDescriptorImage: 'vn-claim-summary vn-item-descriptor-popover > vn-popover vn-item-descriptor img', firstSaleDescriptorImage: '.vn-popover.shown vn-item-descriptor img',
itemDescriptorPopover: 'vn-claim-summary vn-item-descriptor-popover > vn-popover', itemDescriptorPopover: '.vn-popover.shown vn-item-descriptor',
itemDescriptorPopoverItemDiaryButton: 'vn-claim-summary > vn-item-descriptor-popover a[href="#!/item/2/diary"]', itemDescriptorPopoverItemDiaryButton: '.vn-popover.shown vn-item-descriptor a[href="#!/item/2/diary"]',
firstDevelopmentWorker: 'vn-claim-summary vn-horizontal > vn-auto:nth-child(5) > vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(4) > span', firstDevelopmentWorker: 'vn-claim-summary vn-horizontal > vn-auto:nth-child(5) > vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(4) > span',
firstDevelopmentWorkerGoToClientButton: 'vn-claim-summary > vn-worker-descriptor-popover > vn-popover vn-worker-descriptor div.quicklinks > a[href="#!/client/21/summary"]', firstDevelopmentWorkerGoToClientButton: '.vn-popover.shown vn-worker-descriptor div.quicklinks > a[href="#!/client/21/summary"]',
firstActionTicketId: 'vn-claim-summary > vn-card > div > vn-horizontal > vn-auto:nth-child(6) > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > span', firstActionTicketId: 'vn-claim-summary > vn-card > div > vn-horizontal > vn-auto:nth-child(6) > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > span',
firstActionTicketDescriptor: 'vn-claim-summary > vn-ticket-descriptor-popover > vn-popover > div > div.content > vn-ticket-descriptor' firstActionTicketDescriptor: '.vn-popover.shown vn-ticket-descriptor'
}, },
claimBasicData: { claimBasicData: {
claimStateAutocomplete: 'vn-claim-basic-data vn-autocomplete[field="$ctrl.claim.claimStateFk"]', claimStateAutocomplete: 'vn-claim-basic-data vn-autocomplete[field="$ctrl.claim.claimStateFk"]',
@ -548,8 +548,8 @@ export default {
}, },
claimDetail: { claimDetail: {
secondItemDiscount: 'vn-claim-detail > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(6) > span', secondItemDiscount: 'vn-claim-detail > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(6) > span',
discountInput: 'vn-claim-detail vn-popover vn-input-number[model="$ctrl.newDiscount"] > div > div > div.infix > input', discountInput: '.vn-popover.shown vn-input-number[model="$ctrl.newDiscount"] > div > div > div.infix > input',
discoutPopoverMana: 'vn-claim-detail > vn-popover > div > div.content > div > vn-horizontal > h5', discoutPopoverMana: '.vn-popover.shown .content > div > vn-horizontal > h5',
addItemButton: 'vn-claim-detail a vn-float-button', addItemButton: 'vn-claim-detail a vn-float-button',
firstClaimableSaleFromTicket: 'vn-claim-detail > vn-dialog vn-tbody > vn-tr', firstClaimableSaleFromTicket: 'vn-claim-detail > vn-dialog vn-tbody > vn-tr',
claimDetailLine: 'vn-claim-detail > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr', claimDetailLine: 'vn-claim-detail > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr',
@ -575,7 +575,7 @@ export default {
claimAction: { claimAction: {
importClaimButton: 'vn-claim-action vn-button[label="Import claim"]', importClaimButton: 'vn-claim-action vn-button[label="Import claim"]',
importTicketButton: 'vn-claim-action vn-button[label="Import ticket"]', importTicketButton: 'vn-claim-action vn-button[label="Import ticket"]',
secondImportableTicket: 'vn-claim-action > vn-vertical > vn-popover > div > div.content > div > vn-table > div > vn-tbody > vn-tr:nth-child(2)', secondImportableTicket: '.vn-popover.shown .content > div > vn-table > div > vn-tbody > vn-tr:nth-child(2)',
firstLineDestination: 'vn-claim-action vn-tr:nth-child(1) vn-autocomplete[field="saleClaimed.claimDestinationFk"]', firstLineDestination: 'vn-claim-action vn-tr:nth-child(1) vn-autocomplete[field="saleClaimed.claimDestinationFk"]',
secondLineDestination: 'vn-claim-action vn-tr:nth-child(2) vn-autocomplete[field="saleClaimed.claimDestinationFk"]', secondLineDestination: 'vn-claim-action vn-tr:nth-child(2) vn-autocomplete[field="saleClaimed.claimDestinationFk"]',
firstDeleteLine: 'vn-claim-action vn-tr:nth-child(1) vn-icon-button[icon="delete"]', firstDeleteLine: 'vn-claim-action vn-tr:nth-child(1) vn-icon-button[icon="delete"]',
@ -608,9 +608,9 @@ export default {
itemIdInput: 'vn-order-catalog > vn-side-menu vn-catalog-filter vn-textfield[model="$ctrl.itemFk"] input', itemIdInput: 'vn-order-catalog > vn-side-menu vn-catalog-filter vn-textfield[model="$ctrl.itemFk"] input',
itemTagValueInput: 'vn-order-catalog > vn-side-menu vn-catalog-filter vn-textfield[model="$ctrl.value"] input', itemTagValueInput: 'vn-order-catalog > vn-side-menu vn-catalog-filter vn-textfield[model="$ctrl.value"] input',
openTagSearch: 'vn-order-catalog > vn-side-menu > div > vn-catalog-filter > div > vn-vertical > vn-textfield[model="$ctrl.value"] > div > div > div.rightIcons > t-right-icons > i', openTagSearch: 'vn-order-catalog > vn-side-menu > div > vn-catalog-filter > div > vn-vertical > vn-textfield[model="$ctrl.value"] > div > div > div.rightIcons > t-right-icons > i',
tagAutocomplete: 'vn-order-catalog > vn-side-menu vn-catalog-filter vn-popover vn-order-catalog-search-panel vn-autocomplete[field="filter.tagFk"]', tagAutocomplete: 'vn-order-catalog-search-panel vn-autocomplete[field="filter.tagFk"]',
tagValueInput: 'vn-order-catalog > vn-side-menu vn-catalog-filter vn-popover vn-order-catalog-search-panel vn-textfield[model="filter.value"] input', tagValueInput: 'vn-order-catalog-search-panel vn-textfield[model="filter.value"] input',
searchTagButton: 'vn-order-catalog > vn-side-menu vn-catalog-filter vn-popover vn-order-catalog-search-panel > div > form > vn-horizontal:nth-child(3) > vn-submit > input', searchTagButton: 'vn-order-catalog-search-panel > div > form > vn-horizontal:nth-child(3) > vn-submit > input',
thirdFilterRemoveButton: 'vn-order-catalog > vn-side-menu vn-catalog-filter > div > vn-horizontal.chips > vn-chip:nth-child(3) button', thirdFilterRemoveButton: 'vn-order-catalog > vn-side-menu vn-catalog-filter > div > vn-horizontal.chips > vn-chip:nth-child(3) button',
fourthFilterRemoveButton: 'vn-order-catalog > vn-side-menu vn-catalog-filter > div > vn-horizontal.chips > vn-chip:nth-child(4) button', fourthFilterRemoveButton: 'vn-order-catalog > vn-side-menu vn-catalog-filter > div > vn-horizontal.chips > vn-chip:nth-child(4) button',
}, },
@ -727,9 +727,9 @@ export default {
}, },
invoiceOutDescriptor: { invoiceOutDescriptor: {
moreMenu: 'vn-invoice-out-descriptor vn-icon-menu[vn-id="more-button"]', moreMenu: 'vn-invoice-out-descriptor vn-icon-menu[vn-id="more-button"]',
moreMenuDeleteInvoiceOut: 'vn-invoice-out-descriptor vn-popover li[name="Delete Invoice"]', moreMenuDeleteInvoiceOut: '.vn-popover.shown .vn-drop-down li[name="Delete Invoice"]',
moreMenuBookInvoiceOut: 'vn-invoice-out-descriptor vn-popover li[name="Book invoice"]', moreMenuBookInvoiceOut: '.vn-popover.shown .vn-drop-down li[name="Book invoice"]',
moreMenuShowInvoiceOutPdf: 'vn-invoice-out-descriptor vn-popover li[name="Show invoice PDF"]', moreMenuShowInvoiceOutPdf: '.vn-popover.shown .vn-drop-down li[name="Show invoice PDF"]',
acceptDeleteButton: 'vn-invoice-out-descriptor > vn-confirm[vn-id="deleteConfirmation"] button[response="ACCEPT"]', acceptDeleteButton: 'vn-invoice-out-descriptor > vn-confirm[vn-id="deleteConfirmation"] button[response="ACCEPT"]',
acceptBookingButton: 'vn-invoice-out-descriptor > vn-confirm[vn-id="bookConfirmation"] button[response="ACCEPT"]' acceptBookingButton: 'vn-invoice-out-descriptor > vn-confirm[vn-id="bookConfirmation"] button[response="ACCEPT"]'
}, },

View File

@ -24,7 +24,7 @@ describe('Client DMS', () => {
it(`should click on the first document line worker name making the descriptor visible`, async() => { it(`should click on the first document line worker name making the descriptor visible`, async() => {
const visible = await nightmare const visible = await nightmare
.waitToClick(selectors.dms.firstDocWorker) .waitToClick(selectors.dms.firstDocWorker)
.waitForClassPresent(selectors.dms.firstDocWorkerDescriptor, 'shown') .wait(selectors.dms.firstDocWorkerDescriptor)
.isVisible(selectors.dms.firstDocWorkerDescriptor); .isVisible(selectors.dms.firstDocWorkerDescriptor);
expect(visible).toBeTruthy(); expect(visible).toBeTruthy();

View File

@ -17,8 +17,7 @@ describe('Worker time control path', () => {
const scanTime = '07:00'; const scanTime = '07:00';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.mondayAddTimeButton) .waitToClick(selectors.workerTimeControl.mondayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.firstEntryOfMonday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.firstEntryOfMonday, 'innerText');
@ -29,8 +28,7 @@ describe('Worker time control path', () => {
const scanTime = '10:00'; const scanTime = '10:00';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.mondayAddTimeButton) .waitToClick(selectors.workerTimeControl.mondayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.secondEntryOfMonday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.secondEntryOfMonday, 'innerText');
@ -41,8 +39,7 @@ describe('Worker time control path', () => {
const scanTime = '15:00'; const scanTime = '15:00';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.mondayAddTimeButton) .waitToClick(selectors.workerTimeControl.mondayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.thirdEntryOfMonday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.thirdEntryOfMonday, 'innerText');
@ -53,8 +50,7 @@ describe('Worker time control path', () => {
const scanTime = '10:20'; const scanTime = '10:20';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.mondayAddTimeButton) .waitToClick(selectors.workerTimeControl.mondayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.fourthEntryOfMonday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.fourthEntryOfMonday, 'innerText');
@ -82,8 +78,7 @@ describe('Worker time control path', () => {
const scanTime = '08:00'; const scanTime = '08:00';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.tuesdayAddTimeButton) .waitToClick(selectors.workerTimeControl.tuesdayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.firstEntryOfTuesday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.firstEntryOfTuesday, 'innerText');
@ -94,8 +89,7 @@ describe('Worker time control path', () => {
const scanTime = '10:00'; const scanTime = '10:00';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.tuesdayAddTimeButton) .waitToClick(selectors.workerTimeControl.tuesdayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.secondEntryOfTuesday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.secondEntryOfTuesday, 'innerText');
@ -106,8 +100,7 @@ describe('Worker time control path', () => {
const scanTime = '10:20'; const scanTime = '10:20';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.tuesdayAddTimeButton) .waitToClick(selectors.workerTimeControl.tuesdayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.thirdEntryOfTuesday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.thirdEntryOfTuesday, 'innerText');
@ -118,8 +111,7 @@ describe('Worker time control path', () => {
const scanTime = '16:00'; const scanTime = '16:00';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.tuesdayAddTimeButton) .waitToClick(selectors.workerTimeControl.tuesdayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.fourthEntryOfTuesday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.fourthEntryOfTuesday, 'innerText');
@ -139,8 +131,7 @@ describe('Worker time control path', () => {
const scanTime = '09:00'; const scanTime = '09:00';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.wednesdayAddTimeButton) .waitToClick(selectors.workerTimeControl.wednesdayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.firstEntryOfWednesday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.firstEntryOfWednesday, 'innerText');
@ -151,8 +142,7 @@ describe('Worker time control path', () => {
const scanTime = '10:00'; const scanTime = '10:00';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.wednesdayAddTimeButton) .waitToClick(selectors.workerTimeControl.wednesdayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.secondEntryOfWednesday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.secondEntryOfWednesday, 'innerText');
@ -163,8 +153,7 @@ describe('Worker time control path', () => {
const scanTime = '10:20'; const scanTime = '10:20';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.wednesdayAddTimeButton) .waitToClick(selectors.workerTimeControl.wednesdayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.thirdEntryOfWednesday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.thirdEntryOfWednesday, 'innerText');
@ -175,8 +164,7 @@ describe('Worker time control path', () => {
const scanTime = '17:00'; const scanTime = '17:00';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.wednesdayAddTimeButton) .waitToClick(selectors.workerTimeControl.wednesdayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.fourthEntryOfWednesday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.fourthEntryOfWednesday, 'innerText');
@ -196,8 +184,7 @@ describe('Worker time control path', () => {
const scanTime = '09:59'; const scanTime = '09:59';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.thursdayAddTimeButton) .waitToClick(selectors.workerTimeControl.thursdayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.firstEntryOfThursday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.firstEntryOfThursday, 'innerText');
@ -208,8 +195,7 @@ describe('Worker time control path', () => {
const scanTime = '10:00'; const scanTime = '10:00';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.thursdayAddTimeButton) .waitToClick(selectors.workerTimeControl.thursdayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.secondEntryOfThursday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.secondEntryOfThursday, 'innerText');
@ -220,8 +206,7 @@ describe('Worker time control path', () => {
const scanTime = '10:20'; const scanTime = '10:20';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.thursdayAddTimeButton) .waitToClick(selectors.workerTimeControl.thursdayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.thirdEntryOfThursday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.thirdEntryOfThursday, 'innerText');
@ -232,8 +217,7 @@ describe('Worker time control path', () => {
const scanTime = '17:59'; const scanTime = '17:59';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.thursdayAddTimeButton) .waitToClick(selectors.workerTimeControl.thursdayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.fourthEntryOfThursday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.fourthEntryOfThursday, 'innerText');
@ -253,8 +237,7 @@ describe('Worker time control path', () => {
const scanTime = '07:30'; const scanTime = '07:30';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.fridayAddTimeButton) .waitToClick(selectors.workerTimeControl.fridayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.firstEntryOfFriday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.firstEntryOfFriday, 'innerText');
@ -265,8 +248,7 @@ describe('Worker time control path', () => {
const scanTime = '10:00'; const scanTime = '10:00';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.fridayAddTimeButton) .waitToClick(selectors.workerTimeControl.fridayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.secondEntryOfFriday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.secondEntryOfFriday, 'innerText');
@ -277,8 +259,7 @@ describe('Worker time control path', () => {
const scanTime = '10:20'; const scanTime = '10:20';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.fridayAddTimeButton) .waitToClick(selectors.workerTimeControl.fridayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.thirdEntryOfFriday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.thirdEntryOfFriday, 'innerText');
@ -289,8 +270,7 @@ describe('Worker time control path', () => {
const scanTime = '15:30'; const scanTime = '15:30';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.fridayAddTimeButton) .waitToClick(selectors.workerTimeControl.fridayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.fourthEntryOfFriday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.fourthEntryOfFriday, 'innerText');
@ -319,8 +299,7 @@ describe('Worker time control path', () => {
const scanTime = '06:00'; const scanTime = '06:00';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.saturdayAddTimeButton) .waitToClick(selectors.workerTimeControl.saturdayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.firstEntryOfSaturday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.firstEntryOfSaturday, 'innerText');
@ -331,8 +310,7 @@ describe('Worker time control path', () => {
const scanTime = '13:40'; const scanTime = '13:40';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.saturdayAddTimeButton) .waitToClick(selectors.workerTimeControl.saturdayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.secondEntryOfSaturday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.secondEntryOfSaturday, 'innerText');
@ -352,8 +330,7 @@ describe('Worker time control path', () => {
const scanTime = '05:00'; const scanTime = '05:00';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.sundayAddTimeButton) .waitToClick(selectors.workerTimeControl.sundayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.firstEntryOfSunday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.firstEntryOfSunday, 'innerText');
@ -364,8 +341,7 @@ describe('Worker time control path', () => {
const scanTime = '12:40'; const scanTime = '12:40';
const result = await nightmare const result = await nightmare
.waitToClick(selectors.workerTimeControl.sundayAddTimeButton) .waitToClick(selectors.workerTimeControl.sundayAddTimeButton)
.clearInput(selectors.workerTimeControl.timeDialogInput) .pickTime(selectors.workerTimeControl.timeDialogInput, scanTime)
.write(selectors.workerTimeControl.timeDialogInput, scanTime)
.waitToClick(selectors.workerTimeControl.confirmButton) .waitToClick(selectors.workerTimeControl.confirmButton)
.waitToGetProperty(selectors.workerTimeControl.secondEntryOfSunday, 'innerText'); .waitToGetProperty(selectors.workerTimeControl.secondEntryOfSunday, 'innerText');

View File

@ -43,7 +43,7 @@ describe('Ticket descriptor path', () => {
it(`should update the shipped hour`, async() => { it(`should update the shipped hour`, async() => {
const result = await nightmare const result = await nightmare
.write(selectors.ticketDescriptor.changeShippedHourInput, '0815') .pickTime(selectors.ticketDescriptor.changeShippedHourInput, '08:15')
.waitToClick(selectors.ticketDescriptor.acceptChangeHourButton) .waitToClick(selectors.ticketDescriptor.acceptChangeHourButton)
.waitForLastSnackbar(); .waitForLastSnackbar();
@ -114,8 +114,7 @@ describe('Ticket descriptor path', () => {
.waitToClick(selectors.ticketDescriptor.moreMenu) .waitToClick(selectors.ticketDescriptor.moreMenu)
.waitToClick(selectors.ticketDescriptor.moreMenuAddStowaway) .waitToClick(selectors.ticketDescriptor.moreMenuAddStowaway)
.wait(selectors.ticketDescriptor.addStowawayDialogFirstTicket) .wait(selectors.ticketDescriptor.addStowawayDialogFirstTicket)
.isVisible(selectors.ticketDescriptor.addStowawayDialogFirstTicket); .visible(selectors.ticketDescriptor.addStowawayDialogFirstTicket);
expect(isVisible).toBeTruthy(); expect(isVisible).toBeTruthy();
}); });

View File

@ -59,6 +59,7 @@ describe('claim Summary path', () => {
.exists(selectors.claimSummary.itemDescriptorPopoverItemDiaryButton); .exists(selectors.claimSummary.itemDescriptorPopoverItemDiaryButton);
expect(exists).toBeTruthy(); expect(exists).toBeTruthy();
await nightmare.mousedown('.vn-popover.shown');
}); });
it('should display the claim development details', async() => { it('should display the claim development details', async() => {
@ -82,6 +83,7 @@ describe('claim Summary path', () => {
.exists(selectors.claimSummary.firstDevelopmentWorkerGoToClientButton); .exists(selectors.claimSummary.firstDevelopmentWorkerGoToClientButton);
expect(exists).toBeTruthy(); expect(exists).toBeTruthy();
await nightmare.mousedown('.vn-popover.shown');
}); });
it(`should click on the first action ticket ID making the ticket descriptor visible`, async() => { it(`should click on the first action ticket ID making the ticket descriptor visible`, async() => {

View File

@ -36,6 +36,7 @@ describe('claim Descriptor path', () => {
it(`should be able to see the delete claim button of the descriptor more menu`, async() => { it(`should be able to see the delete claim button of the descriptor more menu`, async() => {
let exists = await nightmare let exists = await nightmare
.waitToClick(selectors.claimDescriptor.moreMenu) .waitToClick(selectors.claimDescriptor.moreMenu)
.wait(selectors.claimDescriptor.moreMenuDeleteClaim)
.exists(selectors.claimDescriptor.moreMenuDeleteClaim); .exists(selectors.claimDescriptor.moreMenuDeleteClaim);
expect(exists).toBeTruthy(); expect(exists).toBeTruthy();

View File

@ -1,8 +1,7 @@
import ngModule from '../../module'; import ngModule from '../../module';
require('./style.scss'); require('./style.scss');
directive.$inject = ['vnTemplate']; export default function directive() {
export default function directive(vnTemplate) {
return { return {
restrict: 'E', restrict: 'E',
transclude: true, transclude: true,

View File

@ -1,11 +0,0 @@
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<select
class="*[className]*"
name="*[name]*"
ng-model="*[model]*"
rule="*[rule]*"
*[enabled]*
ng-transclude>
</select>
<label class="mdl-textfield__label" translate>*[label]*</label>
</div>

View File

@ -1,25 +0,0 @@
import ngModule from '../../module';
import template from './combo.html';
directive.$inject = ['vnTemplate'];
export function directive(vnTemplate) {
return {
restrict: 'E',
transclude: true,
template: (_, $attrs) =>
vnTemplate.getNormalized(template, $attrs, {
label: 'Label',
enabled: 'enabled',
class: 'mdl-textfield__input'
}),
link: function(scope, element, attrs) {
scope.$watch(attrs.model, () => {
let mdlField = element[0].firstChild.MaterialTextfield;
if (mdlField)
mdlField.updateClasses_();
});
componentHandler.upgradeElement(element[0].firstChild);
}
};
}
ngModule.directive('vnCombo', directive);

View File

@ -2,17 +2,19 @@
vn-id="popover" vn-id="popover"
on-open="$ctrl.onOpen()" on-open="$ctrl.onOpen()"
on-close="$ctrl.onClose()"> on-close="$ctrl.onClose()">
<div class="dropdown"> <div class="vn-drop-down">
<div ng-show="$ctrl.showFilter" class="filter"> <div ng-show="$ctrl.showFilter" class="filter">
<vn-textfield <vn-textfield
vn-id="input"
model="$ctrl.search" model="$ctrl.search"
class="search" class="search"
ng-blur="$ctrl.onFocusOut()" ng-blur="$ctrl.onFocusOut()"
label="Search"> label="Search">
</vn-textfield> </vn-textfield>
</div> </div>
<div class="list" tabindex="-1"> <div vn-id="list" class="list" tabindex="-1">
<ul <ul
vn-id="ul"
class="dropdown" class="dropdown"
ng-click="$ctrl.onContainerClick($event)"> ng-click="$ctrl.onContainerClick($event)">
</ul> </ul>

View File

@ -31,10 +31,7 @@ export default class DropDown extends Component {
$postLink() { $postLink() {
super.$postLink(); super.$postLink();
this.input = this.element.querySelector('.search input'); this.$.list.addEventListener('scroll', e => this.onScroll(e));
this.ul = this.element.querySelector('ul');
this.list = this.element.querySelector('.list');
this.list.addEventListener('scroll', e => this.onScroll(e));
} }
get shown() { get shown() {
@ -129,7 +126,7 @@ export default class DropDown extends Component {
moveToOption(option) { moveToOption(option) {
this.activateOption(option); this.activateOption(option);
let list = this.list; let list = this.$.list;
let li = this.activeLi; let li = this.activeLi;
if (!li) return; if (!li) return;
@ -156,7 +153,7 @@ export default class DropDown extends Component {
let data = this.modelData; let data = this.modelData;
if (option >= 0 && data && option < data.length) { if (option >= 0 && data && option < data.length) {
this.activeLi = this.ul.children[option]; this.activeLi = this.$.ul.children[option];
this.activeLi.className = 'active'; this.activeLi.className = 'active';
} }
} }
@ -195,8 +192,8 @@ export default class DropDown extends Component {
onOpen() { onOpen() {
this.document.addEventListener('keydown', this.docKeyDownHandler); this.document.addEventListener('keydown', this.docKeyDownHandler);
this.list.scrollTop = 0; this.$.list.scrollTop = 0;
this.input.focus(); this.$.input.focus();
} }
onClose() { onClose() {
@ -208,7 +205,7 @@ export default class DropDown extends Component {
} }
onScroll() { onScroll() {
let list = this.list; let list = this.$.list;
let shouldLoad = let shouldLoad =
list.scrollTop + list.clientHeight >= (list.scrollHeight - 40) list.scrollTop + list.clientHeight >= (list.scrollHeight - 40)
&& !this.model.isLoading; && !this.model.isLoading;
@ -225,7 +222,7 @@ export default class DropDown extends Component {
onContainerClick(event) { onContainerClick(event) {
if (event.defaultPrevented) return; if (event.defaultPrevented) return;
let index = getPosition(this.ul, event); let index = getPosition(this.$.ul, event);
if (index != -1) { if (index != -1) {
event.preventDefault(); event.preventDefault();
this.selectOption(index); this.selectOption(index);
@ -312,13 +309,13 @@ export default class DropDown extends Component {
} }
} }
this.ul.appendChild(fragment); this.$.ul.appendChild(fragment);
this.activateOption(this._activeOption); this.activateOption(this._activeOption);
this.$.$applyAsync(() => this.$.popover.relocate()); this.$.$applyAsync(() => this.$.popover.relocate());
} }
destroyList() { destroyList() {
this.ul.innerHTML = ''; this.$.ul.innerHTML = '';
if (this.scopes) { if (this.scopes) {
for (let scope of this.scopes) for (let scope of this.scopes)

View File

@ -1,79 +1,77 @@
@import "effects"; @import "effects";
@import "variables"; @import "variables";
vn-drop-down { .vn-drop-down {
.dropdown { display: flex;
display: flex; flex-direction: column;
flex-direction: column; height: inherit;
height: inherit;
& > .filter { & > .filter {
position: relative; position: relative;
& > .search { & > .search {
display: block; display: block;
width: 100%; width: 100%;
box-sizing: border-box; box-sizing: border-box;
border: none; border: none;
font-size: inherit; font-size: inherit;
padding: .6em; padding: .6em;
margin: 0!important; margin: 0!important;
&.not-empty label{ &.not-empty label{
display: none;
}
& .selected label {
font-size: inherit;
bottom: 2px;
color: $color-font-secondary;
}
}
& > vn-icon[icon=clear] {
display: none; display: none;
cursor: pointer;
position: absolute;
right: .5em;
top: .6em;
height: 1em;
color: #888;
border-radius: 50%;
background-color: rgba(255, 255, 255, .8);
font-size: 18px;
&:hover {
color: $color-font;
}
} }
&:hover > vn-icon[icon=clear] { & .selected label {
display: block; font-size: inherit;
bottom: 2px;
color: $color-font-secondary;
} }
} }
& > .list { & > vn-icon[icon=clear] {
max-height: 20em; display: none;
overflow: auto; cursor: pointer;
position: absolute;
right: .5em;
top: .6em;
height: 1em;
color: #888;
border-radius: 50%;
background-color: rgba(255, 255, 255, .8);
font-size: 18px;
&:hover {
color: $color-font;
}
}
&:hover > vn-icon[icon=clear] {
display: block;
}
}
& > .list {
max-height: 20em;
overflow: auto;
ul { ul {
padding: 0; padding: 0;
margin: 0;
list-style-type: none;
}
li, .status {
@extend %clickable;
padding: .6em;
white-space: nowrap;
display: flex;
& > input[type=checkbox] {
margin: 0; margin: 0;
list-style-type: none; margin-right: .6em;
} }
li, .status { &.active {
@extend %clickable; @extend %active;
padding: .6em;
white-space: nowrap;
display: flex;
& > input[type=checkbox] {
margin: 0;
margin-right: .6em;
}
&.active {
@extend %active;
}
}
.status {
color: $color-main;
font-weight: bold;
} }
} }
.status {
color: $color-main;
font-weight: bold;
}
} }
} }

View File

@ -1,3 +1,3 @@
<button class="*[className]*"> <button class="mdl-button mdl-js-button mdl-button--fab mdl-js-ripple-effect mdl-button--colored">
<vn-icon icon="*[icon]*"></vn-icon> <vn-icon icon="{{::$ctrl.icon}}"></vn-icon>
</button> </button>

View File

@ -1,14 +1,8 @@
import ngModule from '../../module'; import ngModule from '../../module';
import template from './float-button.html';
directive.$inject = ['vnTemplate']; ngModule.component('vnFloatButton', {
export function directive(vnTemplate) { template: require('./float-button.html'),
return { bindings: {
restrict: 'E', icon: '@'
template: (_, $attrs) => }
vnTemplate.get(template, $attrs, { });
className: 'mdl-button mdl-js-button mdl-button--fab mdl-js-ripple-effect mdl-button--colored'
})
};
}
ngModule.directive('vnFloatButton', directive);

View File

@ -24,9 +24,7 @@ import './radio-group/radio-group';
import './textarea/textarea'; import './textarea/textarea';
import './icon-button/icon-button'; import './icon-button/icon-button';
import './submit/submit'; import './submit/submit';
import './combo/combo';
import './card/card'; import './card/card';
import './switch/switch';
import './float-button/float-button'; import './float-button/float-button';
import './step-control/step-control'; import './step-control/step-control';
import './label-value/label-value'; import './label-value/label-value';

View File

@ -9,7 +9,6 @@ export default class InputNumber extends Input {
this.hasFocus = false; this.hasFocus = false;
vnTemplate.normalizeInputAttrs($attrs); vnTemplate.normalizeInputAttrs($attrs);
this.registerEvents(); this.registerEvents();
} }
@ -107,10 +106,6 @@ export default class InputNumber extends Input {
if (value) this.input.step = value; if (value) this.input.step = value;
} }
get validationError() {
return this.input.validationMessage;
}
/** /**
* Increases the input value * Increases the input value
*/ */
@ -124,61 +119,7 @@ export default class InputNumber extends Input {
stepDown() { stepDown() {
this.input.stepDown(); this.input.stepDown();
} }
/**
* Validates a valid input value
*
* @return {Boolean} - True if has a valid value
*/
hasValidValue() {
return this.input.checkValidity();
}
/**
* Changes the input element
* if has a validation error
*/
validateValue() {
if (!this.hasValidValue()) {
this.hideError();
this.showError();
} else
this.hideError();
}
/**
* Shows the input validation error
*/
showError() {
const infixElement = this.element.querySelector('.infix');
const infixClassList = infixElement.classList;
const errorSpan = document.createElement('span');
errorSpan.className = 'mdl-textfield__error';
const errorText = document.createTextNode(this.validationError);
errorSpan.append(errorText);
infixElement.append(errorSpan);
infixClassList.add('validated', 'invalid');
}
/**
* Hides the input validation error
*/
hideError() {
const infixElement = this.element.querySelector('.infix');
const infixClassList = infixElement.classList;
const errorElement = this.element.querySelector('.infix span.mdl-textfield__error');
if (errorElement)
errorElement.remove();
infixClassList.remove('validated', 'invalid');
}
} }
InputNumber.$inject = ['$element', '$scope', '$attrs', 'vnTemplate']; InputNumber.$inject = ['$element', '$scope', '$attrs', 'vnTemplate'];
ngModule.component('vnInputNumber', { ngModule.component('vnInputNumber', {

View File

@ -4,7 +4,7 @@
vn-input-number { vn-input-number {
@extend vn-textfield; @extend vn-textfield;
input { input {
text-align: center!important; text-align: center !important;
} }
vn-icon[icon=add], vn-icon[icon=add],
vn-icon[icon=remove]{ vn-icon[icon=remove]{

View File

@ -5,14 +5,11 @@
<div class="infix"> <div class="infix">
<input <input
class="mdl-textfield__input" class="mdl-textfield__input"
type="time" type="time"
ng-model="$ctrl.value"
vn-validation="{{$ctrl.rule}}"
ng-disabled="$ctrl.disabled" ng-disabled="$ctrl.disabled"
ng-readonly="$ctrl.readonly" ng-readonly="$ctrl.readonly"
ng-focus="$ctrl.hasFocus = true" ng-focus="$ctrl.hasFocus = true"
ng-blur="$ctrl.hasFocus = false" ng-blur="$ctrl.hasFocus = false"/>
tabindex="{{$ctrl.input.tabindex}}"/>
<label class="label" translate>{{::$ctrl.label}}</label> <label class="label" translate>{{::$ctrl.label}}</label>
</div> </div>
<div class="underline"></div> <div class="underline"></div>

View File

@ -3,17 +3,16 @@ import Input from '../../lib/input';
import './style.scss'; import './style.scss';
export default class InputTime extends Input { export default class InputTime extends Input {
constructor($element, $scope) { constructor($element, $scope, $filter) {
super($element, $scope); super($element, $scope);
this.$filter = $filter;
this.registerEvents(); this.registerEvents();
} }
/**
* Registers all event emitters
*/
registerEvents() { registerEvents() {
this.input.addEventListener('change', event => { this.input.addEventListener('change', event => {
this.onTimeChange();
this.emit('change', {event}); this.emit('change', {event});
}); });
@ -35,147 +34,31 @@ export default class InputTime extends Input {
* @param {Number} value - Value * @param {Number} value - Value
*/ */
set value(value) { set value(value) {
if (this._value === undefined && value || typeof value === 'string') this.updateValue(value);
value = this.formatTime(value); this.input.value = this.$filter('date')(value, 'HH:mm');
}
updateValue(value) {
this._value = value; this._value = value;
this.hasValue = !(value === null || value === undefined); this.element.classList.toggle('not-empty', value != null);
if (this.hasValue)
this.element.classList.add('not-empty');
else
this.element.classList.remove('not-empty');
this.validateValue(); this.validateValue();
} }
/** onTimeChange() {
* Gets max value let date = null;
*/ let value = this.input.value;
get max() {
return this.input.max;
}
/** if (value) {
* Sets max allowed value let split = value.split(':').map(i => parseInt(i) || null);
* date = new Date(this.value || null);
* @param {Number} value - Value date.setHours(split[0], split[1], 0, 0);
*/
set max(value) {
if (value) this.input.max = value;
}
/**
* Gets min value
*/
get min() {
return this.input.min;
}
/**
* Sets min allowed value
*
* @param {Number} value - Value
*/
set min(value) {
if (value) this.input.min = value;
}
/**
* Gets min step value
*/
get step() {
return parseInt(this.input.step);
}
/**
* Sets min step value
*
* @param {Number} value - Value
*/
set step(value) {
if (value) this.input.step = value;
}
/**
* Returns a formatted hour
* @param {Date} date -a
* @return {String} Formatted hour
*/
formatTime(date) {
if (typeof date === 'string') {
date = new Date(date);
date.setTime(date.getTime() + (date.getTimezoneOffset() * 60000));
} }
date.setSeconds(null); this.updateValue(date);
date.setMilliseconds(null);
return date;
}
/**
* Returns native validation message
*/
get validationError() {
return this.input.validationMessage;
}
/**
* Validates a valid input value
*
* @return {Boolean} - True if has a valid value
*/
hasValidValue() {
return this.input.checkValidity();
}
/**
* Changes the input element
* if has a validation error
*/
validateValue() {
if (!this.hasValidValue()) {
this.hideError();
this.showError();
} else
this.hideError();
}
/**
* Shows the input validation error
*/
showError() {
const infixElement = this.element.querySelector('.infix');
const infixClassList = infixElement.classList;
const errorSpan = document.createElement('span');
errorSpan.className = 'mdl-textfield__error';
const errorText = document.createTextNode(this.validationError);
errorSpan.append(errorText);
infixElement.append(errorSpan);
infixClassList.add('validated', 'invalid');
}
/**
* Hides the input validation error
*/
hideError() {
const infixElement = this.element.querySelector('.infix');
const infixClassList = infixElement.classList;
const errorElement = this.element.querySelector('.infix span.mdl-textfield__error');
if (errorElement)
errorElement.remove();
infixClassList.remove('validated', 'invalid');
} }
} }
InputTime.$inject = ['$element', '$scope', '$attrs', 'vnTemplate', '$transclude']; InputTime.$inject = ['$element', '$scope', '$filter'];
ngModule.component('vnInputTime', { ngModule.component('vnInputTime', {
template: require('./index.html'), template: require('./index.html'),
@ -188,9 +71,6 @@ ngModule.component('vnInputTime', {
label: '@?', label: '@?',
disabled: '<?', disabled: '<?',
readonly: '<?', readonly: '<?',
step: '<?',
min: '<?',
max: '<?',
rule: '@?', rule: '@?',
value: '=model', value: '=model',
vnTabIndex: '@?', vnTabIndex: '@?',

View File

@ -40,19 +40,4 @@ describe('Component vnInputTime', () => {
expect(controller._value).toEqual(null); expect(controller._value).toEqual(null);
}); });
}); });
describe('step() setter/getter', () => {
it(`should set input.step to a given value`, () => {
controller.step = 2;
expect(controller.input.step).toEqual('2');
});
it(`should return a number`, () => {
controller.step = 2;
expect(controller.step).toEqual(2);
expect(typeof controller.step).toEqual('number');
});
});
}); });

View File

@ -6,7 +6,7 @@ vn-input-time {
input[type="time"] { input[type="time"] {
clip-path: inset(0 17px 0 0); clip-path: inset(0 17px 0 0);
outline:none; outline: none;
outline:0; outline: 0;
} }
} }

View File

@ -4,12 +4,8 @@ import Popover from '../popover/popover';
export default class Menu extends Popover { export default class Menu extends Popover {
$postLink() { $postLink() {
super.$postLink(); super.$postLink();
this.element.addEventListener('click', this.popover.addEventListener('click',
() => this.onClick()); () => this.hide());
}
onClick() {
this.hide();
} }
} }

View File

@ -1,4 +1,6 @@
<div class="vn-popover">
<div class="popover"> <div class="popover">
<div class="arrow"></div> <div class="arrow"></div>
<div class="content" ng-transclude></div> <div class="content"></div>
</div>
</div> </div>

View File

@ -1,5 +1,6 @@
import ngModule from '../../module'; import ngModule from '../../module';
import Component from '../../lib/component'; import Component from '../../lib/component';
import template from './popover.html';
import './style.scss'; import './style.scss';
/** /**
@ -11,30 +12,26 @@ import './style.scss';
* @event close Thrown when popover is hidden * @event close Thrown when popover is hidden
*/ */
export default class Popover extends Component { export default class Popover extends Component {
constructor($element, $scope, $timeout, $transitions) { constructor($element, $scope, $timeout, $transitions, $transclude, $compile) {
super($element, $scope); super($element, $scope);
this.$timeout = $timeout; this.$timeout = $timeout;
this.$transitions = $transitions; this.$transitions = $transitions;
this._shown = false; this._shown = false;
}
$postLink() { this.element = $compile(template)($scope)[0];
super.$postLink();
this.$element.addClass('vn-popover');
this.docKeyDownHandler = e => this.onDocKeyDown(e);
this.docFocusInHandler = e => this.onDocFocusIn(e);
this.bgMouseDownHandler = e => this.onBgMouseDown(e);
this.element.addEventListener('focusin',
e => this.onFocusIn(e));
this.popover = this.element.querySelector('.popover'); this.popover = this.element.querySelector('.popover');
this.popover.addEventListener('mousedown', this.popover.addEventListener('mousedown', e => this.onMouseDown(e));
e => this.onMouseDown(e));
this.arrow = this.element.querySelector('.arrow'); this.arrow = this.element.querySelector('.arrow');
this.content = this.element.querySelector('.content'); this.content = this.element.querySelector('.content');
$transclude($scope.$parent,
clone => angular.element(this.content).append(clone));
}
$onDestroy() {
this.hide();
} }
/** /**
@ -74,33 +71,23 @@ export default class Popover extends Component {
if (parent) this.parent = parent; if (parent) this.parent = parent;
let isDescriptorMoreMenu = parent && parent.attributes[0].nodeValue == 'more-button'; this._shown = true;
let leftMenu = this.document.querySelector('div[class="menu left"]');
if (isDescriptorMoreMenu && leftMenu) {
let descriptorDiv = this.document.querySelector('vn-side-menu div[class="vn-descriptor"]');
let leftMenuWidth = leftMenu.offsetWidth;
let descriptorWidth = descriptorDiv.offsetWidth; if (!this.showTimeout) {
this.scrollbarWidth = leftMenuWidth - descriptorWidth; this.document.body.appendChild(this.element);
let newWidth = leftMenuWidth - this.scrollbarWidth; this.element.style.display = 'block';
leftMenu.style.overflow = 'hidden';
leftMenu.style.minWidth = `${newWidth}px`;
leftMenu.style.width = `${newWidth}px`;
this.restoreOverflow = true;
} }
this._shown = true;
this.element.style.display = 'block';
this.$timeout.cancel(this.showTimeout); this.$timeout.cancel(this.showTimeout);
this.showTimeout = this.$timeout(() => { this.showTimeout = this.$timeout(() => {
this.$element.addClass('shown');
this.showTimeout = null; this.showTimeout = null;
this.element.classList.add('shown');
}, 30); }, 30);
this.docKeyDownHandler = e => this.onDocKeyDown(e);
this.document.addEventListener('keydown', this.docKeyDownHandler); this.document.addEventListener('keydown', this.docKeyDownHandler);
this.document.addEventListener('focus', this.docFocusInHandler);
this.bgMouseDownHandler = e => this.onBgMouseDown(e);
this.element.addEventListener('mousedown', this.bgMouseDownHandler); this.element.addEventListener('mousedown', this.bgMouseDownHandler);
this.deregisterCallback = this.$transitions.onStart({}, () => this.hide()); this.deregisterCallback = this.$transitions.onStart({}, () => this.hide());
@ -114,28 +101,22 @@ export default class Popover extends Component {
hide() { hide() {
if (!this._shown) return; if (!this._shown) return;
if (this.restoreOverflow) {
const leftMenu = this.document.querySelector('div[class="menu left"]');
let leftMenuWidth = parseInt(leftMenu.style.width);
let newWidth = leftMenuWidth + this.scrollbarWidth;
leftMenu.style.overflow = 'auto';
leftMenu.style.minWidth = `${newWidth}px`;
leftMenu.style.width = `${newWidth}px`;
this.restoreOverflow = false;
}
this._shown = false; this._shown = false;
this.$element.removeClass('shown'); this.element.classList.remove('shown');
this.$timeout.cancel(this.showTimeout); this.$timeout.cancel(this.showTimeout);
this.showTimeout = this.$timeout(() => { this.showTimeout = this.$timeout(() => {
this.element.style.display = 'none';
this.showTimeout = null; this.showTimeout = null;
this.element.style.display = 'none';
this.document.body.removeChild(this.element);
this.emit('close'); this.emit('close');
}, 250); }, 250);
this.document.removeEventListener('keydown', this.docKeyDownHandler); this.document.removeEventListener('keydown', this.docKeyDownHandler);
this.document.removeEventListener('focusin', this.docFocusInHandler); this.docKeyDownHandler = null;
this.element.removeEventListener('mousedown', this.bgMouseDownHandler); this.element.removeEventListener('mousedown', this.bgMouseDownHandler);
this.bgMouseDownHandler = null;
if (this.deregisterCallback) if (this.deregisterCallback)
this.deregisterCallback(); this.deregisterCallback();
@ -165,7 +146,7 @@ export default class Popover extends Component {
let arrowHeight = Math.floor(arrowRect.height / 2); let arrowHeight = Math.floor(arrowRect.height / 2);
let arrowOffset = arrowHeight + margin / 2; let arrowOffset = arrowHeight + margin / 2;
let docEl = document.documentElement; let docEl = this.document.documentElement;
let maxRight = Math.min(window.innerWidth, docEl.clientWidth) - margin; let maxRight = Math.min(window.innerWidth, docEl.clientWidth) - margin;
let maxBottom = Math.min(window.innerHeight, docEl.clientHeight) - margin; let maxBottom = Math.min(window.innerHeight, docEl.clientHeight) - margin;
let maxWith = maxRight - margin; let maxWith = maxRight - margin;
@ -214,20 +195,10 @@ export default class Popover extends Component {
if (event != this.lastMouseEvent) if (event != this.lastMouseEvent)
this.hide(); this.hide();
} }
onFocusIn(event) {
this.lastFocusEvent = event;
}
onDocFocusIn(event) {
if (event !== this.lastFocusEvent)
this.hide();
}
} }
Popover.$inject = ['$element', '$scope', '$timeout', '$transitions']; Popover.$inject = ['$element', '$scope', '$timeout', '$transitions', '$transclude', '$compile'];
ngModule.component('vnPopover', { ngModule.component('vnPopover', {
template: require('./popover.html'),
controller: Popover, controller: Popover,
transclude: true transclude: true
}); });

View File

@ -1,4 +0,0 @@
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
<input type="checkbox" class="*[className]*" ng-model="*[model]*" ng-change="*[change]*">
<span class="mdl-switch__label">*[label]*</span>
</label>

View File

@ -1,26 +0,0 @@
import ngModule from '../../module';
directive.$inject = ['vnTemplate'];
export default function directive(vnTemplate) {
return {
restrict: 'E',
template: (_, $attrs) =>
vnTemplate.getNormalized(template, $attrs, {
className: 'mdl-switch__input',
label: ''
}),
link: function(scope, element, attrs) {
scope.$watch(attrs.model, () => {
let mdlField = element[0].firstChild.MaterialSwitch;
if (mdlField)
mdlField.updateClasses_();
});
componentHandler.upgradeElement(element[0].firstChild);
}
};
}
ngModule.directive('vnSwitch', directive);
export function factory() {
}
ngModule.factory('vnSwitchMdlFactory', factory);

View File

@ -41,10 +41,8 @@ export default class Textfield extends Input {
set value(value) { set value(value) {
this._value = (value === undefined || value === '') ? null : value; this._value = (value === undefined || value === '') ? null : value;
this.input.value = this._value; this.input.value = this._value;
this.hasValue = this._value !== null; this.hasValue = this._value != null;
this.element.classList.toggle('not-empty', this.hasValue);
if (this.hasValue) this.element.classList.add('not-empty');
else this.element.classList.remove('not-empty');
} }
get value() { get value() {

View File

@ -12,15 +12,14 @@ export function directive() {
restrict: 'A', restrict: 'A',
link: function($scope, $element, $attrs) { link: function($scope, $element, $attrs) {
let id = kebabToCamel($attrs.vnId); let id = kebabToCamel($attrs.vnId);
let controller = $element[0].$ctrl ? let $ctrl = $element[0].$ctrl
$element[0].$ctrl : $element.controller($element[0].tagName.toLowerCase()); ? $element[0].$ctrl
: $element.controller($element[0].tagName.toLowerCase());
if (!id) if (!id)
throw new Error(`vnId: Attribute can't be null`); throw new Error(`vnId: Attribute can't be null`);
if (!controller)
throw new Error(`vnId: Can't find controller for element '${id}'`);
$scope[id] = controller; $scope[id] = $ctrl || $element[0];
} }
}; };
} }

View File

@ -25,14 +25,6 @@ describe('Directive vnId', () => {
}).toThrow(new Error(`vnId: Attribute can't be null`)); }).toThrow(new Error(`vnId: Attribute can't be null`));
}); });
it(`should throw an error when these's no controller defined in $element[0]`, () => {
let html = `<div vn-id="1"></div>`;
expect(() => {
compile(html);
}).toThrow(new Error(`vnId: Can't find controller for element '1'`));
});
// FIXME: Sometimes fails with '$scope is undefined' // FIXME: Sometimes fails with '$scope is undefined'
xit(`should set the controller into the $scope as there are no errors being thrown`, () => { xit(`should set the controller into the $scope as there are no errors being thrown`, () => {
let html = `<form vn-id="1"></form>`; let html = `<form vn-id="1"></form>`;

View File

@ -8,22 +8,101 @@ export default class Input extends Component {
super($element, $scope); super($element, $scope);
this.input = this.element.querySelector('input'); this.input = this.element.querySelector('input');
} }
set disabled(value) { set disabled(value) {
this.input.disabled = value == true; this.input.disabled = value == true;
this.mdlUpdate(); this.mdlUpdate();
} }
get disabled() { get disabled() {
return this.input.disabled; return this.input.disabled;
} }
select() { select() {
this.input.select(); this.input.select();
} }
focus() { focus() {
this.input.focus(); this.input.focus();
} }
mdlUpdate() { mdlUpdate() {
if (this.mdlElement) if (this.mdlElement)
this.mdlElement.updateClasses_(); this.mdlElement.updateClasses_();
} }
get validationError() {
return this.input.validationMessage;
}
/**
* Validates a valid input value
*
* @return {Boolean} - True if has a valid value
*/
hasValidValue() {
return this.input.checkValidity();
}
/**
* Changes the input element
* if has a validation error
*/
validateValue() {
if (!this.hasValidValue()) {
this.hideError();
this.showError();
} else
this.hideError();
}
/**
* Shows the input validation error
*/
showError() {
const infixElement = this.element.querySelector('.infix');
const infixClassList = infixElement.classList;
const errorSpan = document.createElement('span');
errorSpan.className = 'mdl-textfield__error';
const errorText = document.createTextNode(this.validationError);
errorSpan.append(errorText);
infixElement.append(errorSpan);
infixClassList.add('validated', 'invalid');
}
/**
* Hides the input validation error
*/
hideError() {
const infixElement = this.element.querySelector('.infix');
const infixClassList = infixElement.classList;
const errorElement = this.element.querySelector('.infix span.mdl-textfield__error');
if (errorElement)
errorElement.remove();
infixClassList.remove('validated', 'invalid');
}
} }
Input.$inject = ['$element', '$scope']; Input.$inject = ['$element', '$scope'];
export const component = {
transclude: {
leftIcons: '?tLeftIcons',
rightIcons: '?tRightIcons'
},
bindings: {
label: '@?',
disabled: '<?',
readonly: '<?',
rule: '@?',
value: '=model',
vnTabIndex: '@?',
onChange: '&',
onClear: '&'
}
};

View File

@ -19,7 +19,7 @@
</vn-icon-button> </vn-icon-button>
</div> </div>
<vn-menu vn-id="apps-menu"> <vn-menu vn-id="apps-menu">
<ul pad-small> <ul pad-small class="modules-menu">
<li ng-repeat="mod in ::$ctrl.modules" ui-sref="{{::mod.route.state}}"> <li ng-repeat="mod in ::$ctrl.modules" ui-sref="{{::mod.route.state}}">
<vn-icon icon="{{::mod.icon || 'photo'}}"></vn-icon> <vn-icon icon="{{::mod.icon || 'photo'}}"></vn-icon>
<span translate>{{::mod.name}}</span> <span translate>{{::mod.name}}</span>

View File

@ -26,28 +26,29 @@ vn-main-menu {
padding: 0; padding: 0;
margin-left: .3em; margin-left: .3em;
} }
} }
vn-menu.vn-popover > div > div.content > ul { }
list-style-type: none;
margin: 0; .vn-popover .modules-menu {
color: $color-font-dark; list-style-type: none;
margin: 0;
& > li { color: $color-font-dark;
@extend %clickable-light;
background-color: $color-main; & > li {
margin-bottom: .6em; @extend %clickable-light;
padding: .8em; background-color: $color-main;
border-radius: .1em; margin-bottom: .6em;
min-width: 8em; padding: .8em;
white-space: nowrap; border-radius: .1em;
min-width: 8em;
&:last-child { white-space: nowrap;
margin-bottom: 0;
} &:last-child {
& > vn-icon { margin-bottom: 0;
padding-right: .3em; }
vertical-align: middle; & > vn-icon {
} padding-right: .3em;
vertical-align: middle;
} }
} }
} }

View File

@ -11,7 +11,7 @@
order="code"> order="code">
</vn-crud-model> </vn-crud-model>
<vn-popover vn-id="popover"> <vn-popover vn-id="popover">
<vn-vertical class="body"> <vn-vertical class="user-configuration">
<vn-autocomplete <vn-autocomplete
vn-one vn-one
label="Local warehouse" label="Local warehouse"

View File

@ -1,13 +1,6 @@
@import "variables"; @import "variables";
vn-user-configuration-popover { .vn-popover .user-configuration {
vn-popover { min-width: 250px;
color: $color-font; padding: $pad-medium;
vn-vertical {
min-width: 250px;
}
.body {
padding: 16px 16px 6px 16px;
}
}
} }

652
junitresults.xml Normal file
View File

@ -0,0 +1,652 @@
<?xml version="1.0" encoding="UTF-8" ?>
<testsuites disabled="0" errors="0" failures="0" tests="337" time="6.5">
<testsuite name="loopback model Account" timestamp="2019-09-30T13:35:07" hostname="localhost" time="0.023" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="loopback model Account" name="should return true if the user has the given role" time="0.021" />
<testcase classname="loopback model Account" name="should return false if the user doesnt have the given role" time="0.002" />
</testsuite>
<testsuite name="loopback model Company" timestamp="2019-09-30T13:35:07" hostname="localhost" time="0.012" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="loopback model Company" name="should check that the company FTH doesnt exists" time="0.012" />
</testsuite>
<testsuite name="account login()" timestamp="2019-09-30T13:35:07" hostname="localhost" time="0.455" errors="0" tests="0" skipped="0" disabled="0" failures="0">
</testsuite>
<testsuite name="account login().when credentials are correct" timestamp="2019-09-30T13:35:07" hostname="localhost" time="0.45" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="account login().when credentials are correct" name="should return the token" time="0.244" />
<testcase classname="account login().when credentials are correct" name="should return the token if the user doesnt exist but the client does" time="0.206" />
</testsuite>
<testsuite name="account login().when credentials are incorrect" timestamp="2019-09-30T13:35:07" hostname="localhost" time="0.005" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="account login().when credentials are incorrect" name="should throw a 401 error" time="0.004" />
</testsuite>
<testsuite name="account logout()" timestamp="2019-09-30T13:35:07" hostname="localhost" time="0.111" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="account logout()" name="should logout and remove token after valid login" time="0.109" />
<testcase classname="account logout()" name="should throw a 401 error when token is invalid" time="0.002" />
<testcase classname="account logout()" name="should throw an error when no token is passed" time="0" />
</testsuite>
<testsuite name="dms downloadFile()" timestamp="2019-09-30T13:35:07" hostname="localhost" time="0.026" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="dms downloadFile()" name="should return a response for an employee with text content-type" time="0.02" />
<testcase classname="dms downloadFile()" name="should return an error for a user without enough privileges" time="0.006" />
</testsuite>
<testsuite name="dms removeFile()" timestamp="2019-09-30T13:35:07" hostname="localhost" time="0.007" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="dms removeFile()" name="should return an error for a user without enough privileges" time="0.006" />
</testsuite>
<testsuite name="dms updateFile()" timestamp="2019-09-30T13:35:07" hostname="localhost" time="0.007" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="dms updateFile()" name="should return an error for a user without enough privileges" time="0.007" />
</testsuite>
<testsuite name="dms uploadFile()" timestamp="2019-09-30T13:35:07" hostname="localhost" time="0.006" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="dms uploadFile()" name="should return an error for a user without enough privileges" time="0.006" />
</testsuite>
<testsuite name="message send()" timestamp="2019-09-30T13:35:07" hostname="localhost" time="0.016" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="message send()" name="should return a response containing the same message in params" time="0.016" />
</testsuite>
<testsuite name="userConfig getUserConfig()" timestamp="2019-09-30T13:35:07" hostname="localhost" time="0.007" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="userConfig getUserConfig()" name="should return the configuration data of a given user" time="0.007" />
</testsuite>
<testsuite name="Model crud()" timestamp="2019-09-30T13:35:07" hostname="localhost" time="0.053" errors="0" tests="4" skipped="0" disabled="0" failures="0">
<testcase classname="Model crud()" name="should inherit crud method from VnModel" time="0" />
<testcase classname="Model crud()" name="should create a new instance" time="0.027" />
<testcase classname="Model crud()" name="should update the instance" time="0.015" />
<testcase classname="Model crud()" name="should delete the created instance" time="0.011" />
</testsuite>
<testsuite name="Model getSetValues()" timestamp="2019-09-30T13:35:07" hostname="localhost" time="0.004" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="Model getSetValues()" name="should extend getSetValues properties to any model passed" time="0" />
<testcase classname="Model getSetValues()" name="should return an array of set values from model column sourceApp" time="0.003" />
<testcase classname="Model getSetValues()" name="should return an array of set values from table column source_app" time="0.001" />
</testsuite>
<testsuite name="Model rewriteDbError()" timestamp="2019-09-30T13:35:07" hostname="localhost" time="0.012" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="Model rewriteDbError()" name="should extend rewriteDbError properties to any model passed" time="0.001" />
<testcase classname="Model rewriteDbError()" name="should handle a duplicated warehouse error" time="0.01" />
</testsuite>
<testsuite name="claimBeginning" timestamp="2019-09-30T13:35:07" hostname="localhost" time="0.332" errors="0" tests="0" skipped="0" disabled="0" failures="0">
</testsuite>
<testsuite name="claimBeginning.importToNewRefundTicket()" timestamp="2019-09-30T13:35:07" hostname="localhost" time="0.268" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="claimBeginning.importToNewRefundTicket()" name="should create a new ticket with negative sales and insert the negative sales into claimEnd" time="0.268" />
</testsuite>
<testsuite name="Client createWithInsurance" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.055" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="Client createWithInsurance" name="should verify the classifications and insurances are untainted" time="0.011" />
<testcase classname="Client createWithInsurance" name="should not create the insurance if couldnt create the classification" time="0.007" />
<testcase classname="Client createWithInsurance" name="should create a new client credit classification with insurance" time="0.027" />
</testsuite>
<testsuite name="client hasActiveRecovery" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.008" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="client hasActiveRecovery" name="should return false if the client doesn&apos;t owes" time="0.006" />
<testcase classname="client hasActiveRecovery" name="should return true if the client owes" time="0.001" />
</testsuite>
<testsuite name="IBAN validation" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.002" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="IBAN validation" name="should return false for non-IBAN input" time="0.001" />
<testcase classname="IBAN validation" name="should return false for invalid spanish IBAN input" time="0" />
<testcase classname="IBAN validation" name="should return true for valid spanish IBAN" time="0" />
</testsuite>
<testsuite name="TIN validation" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.006" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="TIN validation" name="should return true for any TIN when no country is passed" time="0" />
</testsuite>
<testsuite name="TIN validation.Spanish" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.002" errors="0" tests="5" skipped="0" disabled="0" failures="0">
<testcase classname="TIN validation.Spanish" name="should return true for valid spanish TIN" time="0" />
<testcase classname="TIN validation.Spanish" name="should return false for spanish TIN with exceeded digits" time="0.001" />
<testcase classname="TIN validation.Spanish" name="should return false for spanish TIN with invalid letter" time="0" />
<testcase classname="TIN validation.Spanish" name="should return true for valid spanish CIF" time="0" />
<testcase classname="TIN validation.Spanish" name="should return false for spanish CIF with invalid letter" time="0.001" />
</testsuite>
<testsuite name="TIN validation.Italian" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.002" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="TIN validation.Italian" name="should return true for valid italian TIN" time="0.001" />
<testcase classname="TIN validation.Italian" name="should return false for italian TIN with exceeded digits" time="0" />
<testcase classname="TIN validation.Italian" name="should return false for italian TIN with bad syntax" time="0.001" />
</testsuite>
<testsuite name="TIN validation.Portuguese" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.001" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="TIN validation.Portuguese" name="should return true for valid portuguese TIN" time="0" />
<testcase classname="TIN validation.Portuguese" name="should return false for portuguese TIN with exceeded digits" time="0" />
<testcase classname="TIN validation.Portuguese" name="should return false for portuguese TIN with bad syntax" time="0" />
</testsuite>
<testsuite name="loopback model address" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.116" errors="0" tests="0" skipped="0" disabled="0" failures="0">
</testsuite>
<testsuite name="loopback model address.observe()" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.079" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="loopback model address.observe()" name="should throw an error when deactivating a consignee if its the default address" time="0.005" />
<testcase classname="loopback model address.observe()" name="should set isEqualizated to true of a given Client to trigger any new address to have it" time="0.074" />
</testsuite>
<testsuite name="loopback model Item" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.003" errors="0" tests="0" skipped="0" disabled="0" failures="0">
</testsuite>
<testsuite name="loopback model Item.availableId()" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.003" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="loopback model Item.availableId()" name="should return the next available id for an item" time="0.003" />
</testsuite>
<testsuite name="loopback model State" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.003" errors="0" tests="0" skipped="0" disabled="0" failures="0">
</testsuite>
<testsuite name="loopback model State.isAlertLevelZero()" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.003" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="loopback model State.isAlertLevelZero()" name="should return true if the alerLevel is 0" time="0.001" />
<testcase classname="loopback model State.isAlertLevelZero()" name="should do nothing if the alertLevel isnt 0" time="0" />
</testsuite>
<testsuite name="ticket model TicketTracking" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.031" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="ticket model TicketTracking" name="should save a ticketTraing as the quantity is greater than 0" time="0.012" />
<testcase classname="ticket model TicketTracking" name="should return an error as the quantity is 0" time="0.005" />
<testcase classname="ticket model TicketTracking" name="should return an error as the quantity isnt a number" time="0.005" />
</testsuite>
<testsuite name="Agency getAgenciesWithWarehouse()" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.008" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="Agency getAgenciesWithWarehouse()" name="should return the agencies that can handle the given delivery request" time="0.005" />
<testcase classname="Agency getAgenciesWithWarehouse()" name="should return no agencies if the date is incorrect" time="0.003" />
</testsuite>
<testsuite name="Agency getFirstShipped()" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.003" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="Agency getFirstShipped()" name="should return the first shipped and landed possible for the filter" time="0.002" />
</testsuite>
<testsuite name="agency getLanded()" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.003" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="agency getLanded()" name="should return a landing date" time="0.003" />
</testsuite>
<testsuite name="agency getShipped()" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.005" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="agency getShipped()" name="should return a shipment date" time="0.003" />
<testcase classname="agency getShipped()" name="should not return a shipment date" time="0.002" />
</testsuite>
<testsuite name="Agency landsThatDay()" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.002" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="Agency landsThatDay()" name="should return a list of agencies that can land a shipment on a day for an address" time="0.002" />
</testsuite>
<testsuite name="agency clone()" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.031" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="agency clone()" name="should clone a zone" time="0.02" />
</testsuite>
<testsuite name="agency editPrices()" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.033" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="agency editPrices()" name="should apply price and bonus for a selected day" time="0.008" />
<testcase classname="agency editPrices()" name="should apply price and bonus for all delivery days starting from selected day" time="0.011" />
<testcase classname="agency editPrices()" name="should apply price and bonus for all delivery days" time="0.009" />
</testsuite>
<testsuite name="Claim Create" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.034" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="Claim Create" name="should create a new claim" time="0.013" />
<testcase classname="Claim Create" name="should not be able to create a claim if exists that sale" time="0.007" />
</testsuite>
<testsuite name="claim filter()" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.008" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="claim filter()" name="should return 1 result filtering by id" time="0.002" />
<testcase classname="claim filter()" name="should return 1 result filtering by string" time="0.002" />
<testcase classname="claim filter()" name="should return 4 results filtering by worker id" time="0.002" />
</testsuite>
<testsuite name="claim getSummary()" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.028" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="claim getSummary()" name="should return summary with claim, salesClaimed, developments and actions defined " time="0.028" />
</testsuite>
<testsuite name="regularizeClaim()" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.103" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="regularizeClaim()" name="should change claim state to resolved" time="0.091" />
</testsuite>
<testsuite name="Update Claim" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.038" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="Update Claim" name="should throw an error as the user doesn&apos;t have rights" time="0.008" />
<testcase classname="Update Claim" name="should success to update the claim within privileges " time="0.013" />
<testcase classname="Update Claim" name="should change some sensible fields as salesAssistant" time="0.011" />
</testsuite>
<testsuite name="Update Claim" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.017" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="Update Claim" name="should update the claim isChargedToMana attribute" time="0.005" />
<testcase classname="Update Claim" name="should update the claim responsibility attribute" time="0.006" />
</testsuite>
<testsuite name="TicketDms removeFile()" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.01" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="TicketDms removeFile()" name="should return an error for a user without enough privileges" time="0.01" />
</testsuite>
<testsuite name="Claim importTicketSales()" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.01" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="Claim importTicketSales()" name="should import sales to a claim actions from an specific ticket" time="0.007" />
</testsuite>
<testsuite name="Address createDefaultAddress" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.047" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="Address createDefaultAddress" name="should verify that client defaultAddressFk is untainted" time="0.002" />
<testcase classname="Address createDefaultAddress" name="should create a new address and set as a client default address" time="0.021" />
</testsuite>
<testsuite name="Client activeWorkersWithRole" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.007" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="Client activeWorkersWithRole" name="should return the sales people as result" time="0.003" />
<testcase classname="Client activeWorkersWithRole" name="should return the buyers as result" time="0.004" />
</testsuite>
<testsuite name="Client addressesPropagateRe" timestamp="2019-09-30T13:35:08" hostname="localhost" time="0.089" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="Client addressesPropagateRe" name="should propagate the isEqualizated on both addresses of Mr Wayne and set hasToInvoiceByAddress to false" time="0.064" />
</testsuite>
<testsuite name="Client confirmTransaction" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.068" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="Client confirmTransaction" name="should call confirmTransaction() method to mark transaction as confirmed" time="0.045" />
</testsuite>
<testsuite name="Client Create" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.179" errors="0" tests="4" skipped="0" disabled="0" failures="0">
<testcase classname="Client Create" name="should not find Deadpool as he&apos;s not created yet" time="0.005" />
<testcase classname="Client Create" name="should create a new account" time="0.033" />
<testcase classname="Client Create" name="should find an existing account" time="0.002" />
<testcase classname="Client Create" name="should not be able to create a user if exists" time="0.003" />
</testsuite>
<testsuite name="client getAverageInvoiced()" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.003" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="client getAverageInvoiced()" name="should call the getAverageInvoiced method" time="0.003" />
</testsuite>
<testsuite name="Client get" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.04" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="Client get" name="should receive a formated card of Bruce Wayne" time="0.04" />
</testsuite>
<testsuite name="client getDebt()" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.009" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="client getDebt()" name="should return the client debt" time="0.009" />
</testsuite>
<testsuite name="client getMana()" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.004" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="client getMana()" name="should call the getMana method" time="0.003" />
</testsuite>
<testsuite name="Client getTransations" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.005" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="Client getTransations" name="should call getTransations() method to receive a list of Web Payments from Bruce Wayne" time="0.004" />
</testsuite>
<testsuite name="Client hasCustomerRole" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.007" errors="0" tests="4" skipped="0" disabled="0" failures="0">
<testcase classname="Client hasCustomerRole" name="should call the hasCustomerRole() method with a customer id" time="0.002" />
<testcase classname="Client hasCustomerRole" name="should call the hasCustomerRole() method with a non customer id" time="0.002" />
<testcase classname="Client hasCustomerRole" name="should call the hasCustomerRole() method with an unreal id" time="0.001" />
<testcase classname="Client hasCustomerRole" name="should call the hasCustomerRole() method with an invalid id" time="0.002" />
</testsuite>
<testsuite name="Client isValidClient" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.01" errors="0" tests="6" skipped="0" disabled="0" failures="0">
<testcase classname="Client isValidClient" name="should call the isValidClient() method with a client id and receive true" time="0.002" />
<testcase classname="Client isValidClient" name="should call the isValidClient() method with an employee id to receive false" time="0.002" />
<testcase classname="Client isValidClient" name="should call the isValidClient() method with an unexistant id and receive false" time="0.001" />
<testcase classname="Client isValidClient" name="should call the isValidClient() method with an invalid id and receive false" time="0.001" />
<testcase classname="Client isValidClient" name="should call the isValidClient() method with a customer id which isnt active and return false" time="0.002" />
<testcase classname="Client isValidClient" name="should call the isValidClient() method with a customer id which his data isnt verified and return false" time="0.002" />
</testsuite>
<testsuite name="Client listWorkers" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.002" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="Client listWorkers" name="should call the listWorkers()" time="0.001" />
</testsuite>
<testsuite name="client summary()" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.163" errors="0" tests="7" skipped="0" disabled="0" failures="0">
<testcase classname="client summary()" name="should return a summary object containing data" time="0.026" />
<testcase classname="client summary()" name="should return a summary object containing mana" time="0.021" />
<testcase classname="client summary()" name="should return a summary object containing debt" time="0.023" />
<testcase classname="client summary()" name="should return a summary object containing averageInvoiced" time="0.025" />
<testcase classname="client summary()" name="should return a summary object containing totalGreuge" time="0.021" />
<testcase classname="client summary()" name="should return a summary object without containing active recoveries" time="0.025" />
<testcase classname="client summary()" name="should return a summary object containing active recoveries" time="0.022" />
</testsuite>
<testsuite name="client lastActiveTickets()" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.002" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="client lastActiveTickets()" name="should return the last three active tickets" time="0.002" />
</testsuite>
<testsuite name="Client updateFiscalData" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.042" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="Client updateFiscalData" name="should return an error if the user is not administrative and the isTaxDataChecked value is true" time="0.002" />
<testcase classname="Client updateFiscalData" name="should return an error if the user is administrative and the isTaxDataChecked value is true BUT the params aint valid" time="0.003" />
<testcase classname="Client updateFiscalData" name="should update the client fiscal data and return the count if changes made" time="0.021" />
</testsuite>
<testsuite name="Client uploadFile()" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.008" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="Client uploadFile()" name="should return an error for a user without enough privileges" time="0.007" />
</testsuite>
<testsuite name="ClientDms removeFile()" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.007" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="ClientDms removeFile()" name="should return an error for a user without enough privileges" time="0.007" />
</testsuite>
<testsuite name="Greuge totalGreuge()" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.001" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="Greuge totalGreuge()" name="should call the sumAmount method" time="0.001" />
</testsuite>
<testsuite name="receipt filter()" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.003" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="receipt filter()" name="should return the receipts" time="0.003" />
</testsuite>
<testsuite name="sms send()" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.26" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="sms send()" name="should return the expected message and status code" time="0.26" />
</testsuite>
<testsuite name="invoiceOut book()" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.093" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="invoiceOut book()" name="should check that invoice out booked is untainted" time="0.002" />
<testcase classname="invoiceOut book()" name="should confirm the book property have been updated" time="0.088" />
</testsuite>
<testsuite name="invoiceOut delete()" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.042" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="invoiceOut delete()" name="should check that there is one ticket in the target invoiceOut" time="0.005" />
<testcase classname="invoiceOut delete()" name="should delete the target invoiceOut then check the ticket doesn&apos;t have a refFk anymore" time="0.018" />
</testsuite>
<testsuite name="InvoiceOut download()" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.005" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="InvoiceOut download()" name="should return the downloaded fine name" time="0.004" />
</testsuite>
<testsuite name="InvoiceOut filter()" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.01" errors="0" tests="8" skipped="3" disabled="0" failures="0">
<testcase classname="InvoiceOut filter()" name="should return the invoice out matching ref" time="0.002" />
<testcase classname="InvoiceOut filter()" name="should return the invoice out matching clientFk" time="0.002" />
<testcase classname="InvoiceOut filter()" name="should return the invoice out matching hasPdf" time="0.001" />
<testcase classname="InvoiceOut filter()" name="should return the invoice out matching amount" time="0.003" />
<testcase classname="InvoiceOut filter()" name="should return the invoice out matching min and max" time="0.002" />
<testcase classname="InvoiceOut filter()" name="should return the invoice out matching issued" time="0">
<skipped message="Temporarily disabled with xit" />
</testcase>
<testcase classname="InvoiceOut filter()" name="should return the invoice out matching created" time="0">
<skipped message="Temporarily disabled with xit" />
</testcase>
<testcase classname="InvoiceOut filter()" name="should return the invoice out matching dued" time="0">
<skipped message="Temporarily disabled with xit" />
</testcase>
</testsuite>
<testsuite name="invoiceOut regenerate()" timestamp="2019-09-30T13:35:09" hostname="localhost" time="0.024" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="invoiceOut regenerate()" name="should check that the invoice has a PDF and is not in print generation queue" time="0.006" />
<testcase classname="invoiceOut regenerate()" name="should mark the invoice as doesn&apos;t have PDF and add it to a print queue" time="0.01" />
</testsuite>
<testsuite name="invoiceOut summary()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.045" errors="0" tests="4" skipped="0" disabled="0" failures="0">
<testcase classname="invoiceOut summary()" name="should return a summary object containing data from one invoiceOut" time="0.012" />
<testcase classname="invoiceOut summary()" name="should return a summary object containing data from it&apos;s tickets" time="0.011" />
<testcase classname="invoiceOut summary()" name="should return a summary object containing it&apos;s supplier country" time="0.012" />
<testcase classname="invoiceOut summary()" name="should return a summary object containing idata from it&apos;s tax types" time="0.009" />
</testsuite>
<testsuite name="item clone()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.118" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="item clone()" name="should clone the given item and it should have the expected id" time="0.115" />
<testcase classname="item clone()" name="should attempt to clone the given item but give an error as it doesnt exist" time="0.003" />
</testsuite>
<testsuite name="item filter()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.009" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="item filter()" name="should return 1 result filtering by id" time="0.003" />
<testcase classname="item filter()" name="should return 1 result filtering by barcode" time="0.003" />
<testcase classname="item filter()" name="should return 2 results using filter and tags" time="0.002" />
</testsuite>
<testsuite name="item getDiary()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.012" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="item getDiary()" name="should check the property balance of the 4 resultant entries" time="0.012" />
</testsuite>
<testsuite name="item getLastEntries()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.008" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="item getLastEntries()" name="should return one entry for a given item" time="0.005" />
<testcase classname="item getLastEntries()" name="should return five entries for a given item" time="0.003" />
</testsuite>
<testsuite name="item getSummary()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.055" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="item getSummary()" name="should return summary with item, tags, botanical, niches, available and visible defined " time="0.055" />
</testsuite>
<testsuite name="item new()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.079" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="item new()" name="should create a new item, adding the name as a tag" time="0.04" />
</testsuite>
<testsuite name="regularize()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.047" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="regularize()" name="should create a new ticket and add a line" time="0.042" />
</testsuite>
<testsuite name="item updateTaxes()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.021" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="item updateTaxes()" name="should throw an error if the taxClassFk is blank" time="0.001" />
<testcase classname="item updateTaxes()" name="should update the tax of a given country of an item" time="0.01" />
<testcase classname="item updateTaxes()" name="should confirm the tax class was updated" time="0.001" />
</testsuite>
<testsuite name="item-barcode toItem()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.002" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="item-barcode toItem()" name="should return the same number if there is a barcode and a item with the same ID" time="0.002" />
</testsuite>
<testsuite name="item filterItemTags()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.002" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="item filterItemTags()" name="should filter ItemTags table" time="0.002" />
</testsuite>
<testsuite name="order catalogFilter()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.09" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="order catalogFilter()" name="should return an array of items" time="0.05" />
<testcase classname="order catalogFilter()" name="should now return an array of items based on tag filter" time="0.04" />
</testsuite>
<testsuite name="order filter()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.031" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="order filter()" name="should call the filter method with a basic search" time="0.01" />
<testcase classname="order filter()" name="should call the filter method with a single advanced search" time="0.011" />
<testcase classname="order filter()" name="should call the filter method with a complex advanced search" time="0.01" />
</testsuite>
<testsuite name="order getItemTypeAvailable()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.033" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="order getItemTypeAvailable()" name="should call the getItemTypeAvailable method with a valid order and item category" time="0.007" />
<testcase classname="order getItemTypeAvailable()" name="should call the getItemTypeAvailable method with the same order and different item category" time="0.025" />
</testsuite>
<testsuite name="order getTaxes()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.038" errors="0" tests="4" skipped="0" disabled="0" failures="0">
<testcase classname="order getTaxes()" name="should call the getTaxes method and return undefined if its called with a string" time="0.009" />
<testcase classname="order getTaxes()" name="should call the getTaxes method and return undefined if its called with unknown id" time="0.008" />
<testcase classname="order getTaxes()" name="should call the getTaxes method and return the taxes splited if different type of taxes" time="0.016" />
<testcase classname="order getTaxes()" name="should call the getTaxes method and return the taxes for them same type" time="0.004" />
</testsuite>
<testsuite name="order getTotal()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.005" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="order getTotal()" name="should return the order total" time="0.004" />
</testsuite>
<testsuite name="order getTotalVolume()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.001" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="order getTotalVolume()" name="should return the total" time="0.001" />
</testsuite>
<testsuite name="order getVAT()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.006" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="order getVAT()" name="should return the order VAT" time="0.004" />
</testsuite>
<testsuite name="order getVolumes()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.002" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="order getVolumes()" name="should return the volumes of a given order id" time="0.002" />
</testsuite>
<testsuite name="order isEditable()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.008" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="order isEditable()" name="should return false when the given order is not editable" time="0.004" />
<testcase classname="order isEditable()" name="should return false when the given order doesnt exists" time="0.001" />
<testcase classname="order isEditable()" name="should return true when the given order is editable" time="0.003" />
</testsuite>
<testsuite name="order new()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.021" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="order new()" name="should throw an error if the client isnt active" time="0.003" />
<testcase classname="order new()" name="should create a new order a user when all conditions are met" time="0.011" />
</testsuite>
<testsuite name="order summary()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.088" errors="0" tests="5" skipped="0" disabled="0" failures="0">
<testcase classname="order summary()" name="should return a summary object containing data from 1 order" time="0.023" />
<testcase classname="order summary()" name="should return a summary object containing sales from 1 order" time="0.018" />
<testcase classname="order summary()" name="should return a summary object containing subTotal for 1 order" time="0.016" />
<testcase classname="order summary()" name="should return a summary object containing VAT for 1 order" time="0.015" />
<testcase classname="order summary()" name="should return a summary object containing total for 1 order" time="0.016" />
</testsuite>
<testsuite name="Order updateBasicData" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.02" errors="0" tests="4" skipped="0" disabled="0" failures="0">
<testcase classname="Order updateBasicData" name="should return an error if the order is confirmed" time="0.003" />
<testcase classname="Order updateBasicData" name="should return an error if the order has rows" time="0.002" />
<testcase classname="Order updateBasicData" name="should return an error if the current user is administrative and the isTaxDataChecked value is true BUT the params aint valid" time="0.002" />
<testcase classname="Order updateBasicData" name="should update the client fiscal data and return the count if changes made" time="0.007" />
</testsuite>
<testsuite name="order addToOrder()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.066" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="order addToOrder()" name="should add a row to a given order" time="0.057" />
</testsuite>
<testsuite name="order removes()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.015" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="order removes()" name="should throw an error if rows property is empty" time="0" />
<testcase classname="order removes()" name="should throw an error if the row selected is not editable" time="0.004" />
<testcase classname="order removes()" name="should delete the row" time="0.006" />
</testsuite>
<testsuite name="Route filter()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.028" errors="0" tests="9" skipped="1" disabled="0" failures="0">
<testcase classname="Route filter()" name="should return the routes matching &quot;search&quot;" time="0.009" />
<testcase classname="Route filter()" name="should return the routes matching &quot;from&quot;" time="0">
<skipped message="Temporarily disabled with xit" />
</testcase>
<testcase classname="Route filter()" name="should return the routes matching &quot;to&quot;" time="0.002" />
<testcase classname="Route filter()" name="should return the routes matching &quot;m3&quot;" time="0.003" />
<testcase classname="Route filter()" name="should return the routes matching &quot;description&quot;" time="0.002" />
<testcase classname="Route filter()" name="should return the routes matching &quot;workerFk&quot;" time="0.002" />
<testcase classname="Route filter()" name="should return the routes matching &quot;warehouseFk&quot;" time="0.004" />
<testcase classname="Route filter()" name="should return the routes matching &quot;vehicleFk&quot;" time="0.003" />
<testcase classname="Route filter()" name="should return the routes matching &quot;agencyModeFk&quot;" time="0.002" />
</testsuite>
<testsuite name="route getTickets()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.023" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="route getTickets()" name="should return the tickets for a given route" time="0.023" />
</testsuite>
<testsuite name="route guessPriority()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.021" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="route guessPriority()" name="should confirm the tickets in the target route have no priority yet" time="0.002" />
<testcase classname="route guessPriority()" name="should call guessPriority() and then check the tickets in the target route now have their priorities defined" time="0.008" />
</testsuite>
<testsuite name="route summary()" timestamp="2019-09-30T13:35:10" hostname="localhost" time="0.103" errors="0" tests="5" skipped="0" disabled="0" failures="0">
<testcase classname="route summary()" name="should return a summary object containing data from one route" time="0.024" />
<testcase classname="route summary()" name="should return a summary object containing it&apos;s agency" time="0.021" />
<testcase classname="route summary()" name="should return a summary object containing it&apos;s vehicle" time="0.02" />
<testcase classname="route summary()" name="should return a summary object containing it&apos;s worker" time="0.021" />
<testcase classname="route summary()" name="should return a summary object containing data from the tickets" time="0.017" />
</testsuite>
<testsuite name="route updateVolume()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.048" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="route updateVolume()" name="should confirm the original volume of the route is the expected" time="0.002" />
<testcase classname="route updateVolume()" name="should confirm the route volume is updated when a ticket is added" time="0.024" />
<testcase classname="route updateVolume()" name="should confirm the change is logged" time="0.002" />
</testsuite>
<testsuite name="ticket listPackaging()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.001" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="ticket listPackaging()" name="should call the listPackaging method and return the response" time="0.001" />
</testsuite>
<testsuite name="sale getClaimableFromTicket()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.002" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="sale getClaimableFromTicket()" name="should return the claimable sales of a given ticket" time="0.002" />
</testsuite>
<testsuite name="sale removes()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.029" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="sale removes()" name="should throw an error if the ticket of the given sales is not editable" time="0.007" />
<testcase classname="sale removes()" name="should delete the sales" time="0.013" />
</testsuite>
<testsuite name="sale reserve()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.067" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="sale reserve()" name="should throw an error if the ticket can not be modified" time="0.007" />
<testcase classname="sale reserve()" name="should update the given sales of a ticket to reserved" time="0.036" />
</testsuite>
<testsuite name="sale updateConcept()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.019" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="sale updateConcept()" name="should throw if ID was undefined" time="0.001" />
<testcase classname="sale updateConcept()" name="should update the sale concept" time="0.008" />
</testsuite>
<testsuite name="sale updatePrice()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.108" errors="0" tests="5" skipped="0" disabled="0" failures="0">
<testcase classname="sale updatePrice()" name="should throw an error if the ticket is not editable" time="0.015" />
<testcase classname="sale updatePrice()" name="should return 0 if the price is an empty string" time="0.029" />
<testcase classname="sale updatePrice()" name="should now set price as a decimal number in a string" time="0.023" />
<testcase classname="sale updatePrice()" name="should set price as a decimal number and check the sale has the mana component" time="0.022" />
<testcase classname="sale updatePrice()" name="should check that the mana of salesPerson changed" time="0.001" />
</testsuite>
<testsuite name="sale updateQuantity()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.022" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="sale updateQuantity()" name="should throw an error if the quantity is not a number" time="0.001" />
<testcase classname="sale updateQuantity()" name="should throw an error if the quantity is greater than it should be" time="0.001" />
<testcase classname="sale updateQuantity()" name="should update the quantity of a given sale current line" time="0.02" />
</testsuite>
<testsuite name="ticket listSaleTracking()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.009" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="ticket listSaleTracking()" name="should call the listSaleTracking method and return the response" time="0.005" />
<testcase classname="ticket listSaleTracking()" name="should call the listSaleTracking method and return zero if doesn&apos;t have lines" time="0.004" />
</testsuite>
<testsuite name="ticket editableStates()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.012" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="ticket editableStates()" name="should return the expected state for the given role" time="0.003" />
<testcase classname="ticket editableStates()" name="should returns the expected states by a specific role" time="0.003" />
<testcase classname="ticket editableStates()" name="should return again the expected state by a specific role" time="0.005" />
</testsuite>
<testsuite name="state isEditable()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.018" errors="0" tests="5" skipped="0" disabled="0" failures="0">
<testcase classname="state isEditable()" name="should return false if the given state is not editable by a specific role" time="0.003" />
<testcase classname="state isEditable()" name="should return true if the given state is editable by a specific role" time="0.003" />
<testcase classname="state isEditable()" name="should return true again if the given state is editable by a specific role" time="0.004" />
<testcase classname="state isEditable()" name="should return false if the given state is not editable for the given role" time="0.003" />
<testcase classname="state isEditable()" name="should return true if the given state is editable for the given role" time="0.004" />
</testsuite>
<testsuite name="ticket addSale()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.099" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="ticket addSale()" name="should create a new sale for the ticket with id 13" time="0.072" />
<testcase classname="ticket addSale()" name="should not be able to add a sale if the item quantity is not available" time="0.011" />
<testcase classname="ticket addSale()" name="should not be able to add a sale if the ticket is not editable" time="0.007" />
</testsuite>
<testsuite name="ticket canHaveStowaway()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.004" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="ticket canHaveStowaway()" name="should return true if the ticket warehouse have hasStowaway equal 1" time="0.003" />
<testcase classname="ticket canHaveStowaway()" name="should return false if the ticket warehouse dont have hasStowaway equal 0" time="0.001" />
</testsuite>
<testsuite name="ticket componentUpdate()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.101" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="ticket componentUpdate()" name="should change the agencyMode to modify the sale components value" time="0.048" />
<testcase classname="ticket componentUpdate()" name="should change the agencyMode to go back to the originals sale components value" time="0.05" />
</testsuite>
<testsuite name="ticket filter()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.042" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="ticket filter()" name="should return the tickets matching the filter" time="0.042" />
</testsuite>
<testsuite name="ticket getPossibleStowaways()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.018" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="ticket getPossibleStowaways()" name="should throw an error if Can&apos;t create stowaway for this ticket" time="0.004" />
<testcase classname="ticket getPossibleStowaways()" name="should return an empty list of tickets for a valid ticket" time="0.004" />
<testcase classname="ticket getPossibleStowaways()" name="should return allowed list of tickets for a valid ticket" time="0.01" />
</testsuite>
<testsuite name="ticket getSales()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.006" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="ticket getSales()" name="should return the sales of a ticket" time="0.006" />
</testsuite>
<testsuite name="ticket getSalesPersonMana()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.007" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="ticket getSalesPersonMana()" name="should get the mana of a salesperson of a given ticket" time="0.006" />
<testcase classname="ticket getSalesPersonMana()" name="should return 0 if the given ticket does not exist" time="0.001" />
</testsuite>
<testsuite name="ticket getTaxes()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.007" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="ticket getTaxes()" name="should return the tax of a given ticket" time="0.006" />
</testsuite>
<testsuite name="ticket getTotal()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.012" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="ticket getTotal()" name="should return the total of a ticket" time="0.006" />
<testcase classname="ticket getTotal()" name="should return zero if the ticket doesn&apos;t have lines" time="0.005" />
</testsuite>
<testsuite name="ticket getTotalVolume()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.002" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="ticket getTotalVolume()" name="should return the total volume of a ticket" time="0.002" />
</testsuite>
<testsuite name="ticket getVAT()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.006" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="ticket getVAT()" name="should return the ticket VAT" time="0.006" />
</testsuite>
<testsuite name="ticket getVolume()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.001" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="ticket getVolume()" name="should call the getVolume method" time="0.001" />
</testsuite>
<testsuite name="ticket isEditable()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.043" errors="0" tests="7" skipped="0" disabled="0" failures="0">
<testcase classname="ticket isEditable()" name="should return false if the given ticket is not editable" time="0.009" />
<testcase classname="ticket isEditable()" name="should return false if the given ticket does not exist" time="0.005" />
<testcase classname="ticket isEditable()" name="should return false if the given ticket isDeleted" time="0.005" />
<testcase classname="ticket isEditable()" name="should return true if the given ticket is editable" time="0.007" />
<testcase classname="ticket isEditable()" name="should be able to edit a deleted or invoiced ticket if the role is salesAssistant" time="0.005" />
<testcase classname="ticket isEditable()" name="should be able to edit a deleted or invoiced ticket if the role is productionBoss" time="0.007" />
<testcase classname="ticket isEditable()" name="should not be able to edit a deleted or invoiced ticket if the role is salesPerson" time="0.005" />
</testsuite>
<testsuite name="ticket isEmpty()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.016" errors="0" tests="4" skipped="0" disabled="0" failures="0">
<testcase classname="ticket isEmpty()" name="should return false if the ticket contains any packages" time="0.004" />
<testcase classname="ticket isEmpty()" name="should return false if the ticket contains any services" time="0.003" />
<testcase classname="ticket isEmpty()" name="should return false if the ticket contains any purchase request" time="0.004" />
<testcase classname="ticket isEmpty()" name="should return false if the ticket contains any sale" time="0.005" />
</testsuite>
<testsuite name="ticket makeInvoice()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.12" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="ticket makeInvoice()" name="should invoice a ticket" time="0.084" />
<testcase classname="ticket makeInvoice()" name="should not invoice an already invoiced ticket" time="0.012" />
</testsuite>
<testsuite name="ticket new()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.023" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="ticket new()" name="should throw an error if the client isnt frozen and isnt active" time="0.004" />
<testcase classname="ticket new()" name="should throw an error if the address doesnt exist" time="0.001" />
<testcase classname="ticket new()" name="should return the id of the created ticket" time="0.011" />
</testsuite>
<testsuite name="sale priceDifference()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.055" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="sale priceDifference()" name="should return ticket price differences" time="0.048" />
<testcase classname="sale priceDifference()" name="should return an error if the ticket is not editable" time="0.007" />
</testsuite>
<testsuite name="ticket deleted()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.036" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="ticket deleted()" name="should make sure the ticket is not deleted yet" time="0.001" />
<testcase classname="ticket deleted()" name="should set a ticket to deleted" time="0.012" />
<testcase classname="ticket deleted()" name="should throw an error if the given ticket has a claim" time="0.002" />
</testsuite>
<testsuite name="ticket subtotal()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.005" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="ticket subtotal()" name="should return the subtotal of a ticket" time="0.003" />
<testcase classname="ticket subtotal()" name="should return 0 if the ticket doesn&apos;t have lines" time="0.002" />
</testsuite>
<testsuite name="ticket summary()" timestamp="2019-09-30T13:35:11" hostname="localhost" time="0.144" errors="0" tests="5" skipped="0" disabled="0" failures="0">
<testcase classname="ticket summary()" name="should return a summary object containing data from 1 ticket" time="0.029" />
<testcase classname="ticket summary()" name="should return a summary object containing sales from 1 ticket" time="0.028" />
<testcase classname="ticket summary()" name="should return a summary object containing subtotal for 1 ticket" time="0.033" />
<testcase classname="ticket summary()" name="should return a summary object containing VAT for 1 ticket" time="0.03" />
<testcase classname="ticket summary()" name="should return a summary object containing total for 1 ticket" time="0.024" />
</testsuite>
<testsuite name="sale transferSales()" timestamp="2019-09-30T13:35:12" hostname="localhost" time="0.209" errors="0" tests="5" skipped="0" disabled="0" failures="0">
<testcase classname="sale transferSales()" name="should throw an error as the ticket is not editable" time="0.005" />
<testcase classname="sale transferSales()" name="should throw an error if the receiving ticket is not editable" time="0.01" />
<testcase classname="sale transferSales()" name="should throw an error when attempting to create a new ticket without delivery dates" time="0.009" />
<testcase classname="sale transferSales()" name="should transfer the sales from one ticket to a new one" time="0.046" />
<testcase classname="sale transferSales()" name="should transfer back the sales and set the created ticket as deleted" time="0.054" />
</testsuite>
<testsuite name="sale transferSales().sale transferPartialSales()" timestamp="2019-09-30T13:35:12" hostname="localhost" time="0.082" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="sale transferSales().sale transferPartialSales()" name="should throw an error in the quantity to transfer exceeds the amount from the original sale" time="0.029" />
<testcase classname="sale transferSales().sale transferPartialSales()" name="should partially transfer the sales from one ticket to a new one" time="0.053" />
</testsuite>
<testsuite name="sale updateDiscount()" timestamp="2019-09-30T13:35:12" hostname="localhost" time="0.054" errors="0" tests="4" skipped="0" disabled="0" failures="0">
<testcase classname="sale updateDiscount()" name="should throw an error if no sales were selected" time="0.002" />
<testcase classname="sale updateDiscount()" name="should throw an error if no sales belong to different tickets" time="0.003" />
<testcase classname="sale updateDiscount()" name="should throw an error if the ticket is invoiced already" time="0.009" />
<testcase classname="sale updateDiscount()" name="should update the discount if the salesPerson has mana" time="0.021" />
</testsuite>
<testsuite name="ticket updateEditableTicket()" timestamp="2019-09-30T13:35:12" hostname="localhost" time="0.04" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="ticket updateEditableTicket()" name="should now throw an error if the ticket is not editable" time="0.008" />
<testcase classname="ticket updateEditableTicket()" name="should edit the ticket address" time="0.017" />
</testsuite>
<testsuite name="Ticket uploadFile()" timestamp="2019-09-30T13:35:12" hostname="localhost" time="0.007" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="Ticket uploadFile()" name="should return an error for a user without enough privileges" time="0.007" />
</testsuite>
<testsuite name="TicketDms removeFile()" timestamp="2019-09-30T13:35:12" hostname="localhost" time="0.01" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="TicketDms removeFile()" name="should return an error for a user without enough privileges" time="0.01" />
</testsuite>
<testsuite name="ticket-request confirm()" timestamp="2019-09-30T13:35:12" hostname="localhost" time="0.143" errors="0" tests="4" skipped="0" disabled="0" failures="0">
<testcase classname="ticket-request confirm()" name="should throw an error if the item doesn&apos;t exist" time="0.004" />
<testcase classname="ticket-request confirm()" name="should throw an error if the item is not available" time="0.01" />
<testcase classname="ticket-request confirm()" name="should update the sale details if the request already contains a sale id" time="0.06" />
<testcase classname="ticket-request confirm()" name="should create a new sale for the the request if there&apos;s no sale id" time="0.051" />
</testsuite>
<testsuite name="ticket-request deny()" timestamp="2019-09-30T13:35:12" hostname="localhost" time="0.024" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="ticket-request deny()" name="should return all ticket requests" time="0.016" />
</testsuite>
<testsuite name="ticket-request filter()" timestamp="2019-09-30T13:35:12" hostname="localhost" time="0.03" errors="0" tests="9" skipped="0" disabled="0" failures="0">
<testcase classname="ticket-request filter()" name="should return all ticket requests" time="0.004" />
<testcase classname="ticket-request filter()" name="should return the ticket request matching a generic search value which is the ticket ID" time="0.003" />
<testcase classname="ticket-request filter()" name="should return the ticket request matching a generic search value which is the client address alias" time="0.004" />
<testcase classname="ticket-request filter()" name="should return the ticket request matching the ticket ID" time="0.003" />
<testcase classname="ticket-request filter()" name="should return the ticket request matching the atender ID" time="0.003" />
<testcase classname="ticket-request filter()" name="should return the ticket request matching the isOk triple-state" time="0.003" />
<testcase classname="ticket-request filter()" name="should return the ticket request matching the client ID" time="0.004" />
<testcase classname="ticket-request filter()" name="should return the ticket request matching the warehouse ID" time="0.003" />
<testcase classname="ticket-request filter()" name="should return the ticket request matching the salesPerson ID" time="0.003" />
</testsuite>
<testsuite name="ticket changeState()" timestamp="2019-09-30T13:35:12" hostname="localhost" time="0.084" errors="0" tests="5" skipped="0" disabled="0" failures="0">
<testcase classname="ticket changeState()" name="should throw if the ticket is not editable and the user isnt production" time="0.007" />
<testcase classname="ticket changeState()" name="should throw an error if a worker with employee role attemps to a forbidden state" time="0.007" />
<testcase classname="ticket changeState()" name="should be able to create a ticket tracking line for a not editable ticket if the user has the production role" time="0.016" />
<testcase classname="ticket changeState()" name="should return an array with the created ticket tracking line" time="0.017" />
<testcase classname="ticket changeState()" name="should return an array with the created ticket tracking line when the user is salesperson, uses the state assigned and thes a workerFk given" time="0.017" />
</testsuite>
<testsuite name="device checkUuid()" timestamp="2019-09-30T13:35:12" hostname="localhost" time="0.005" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="device checkUuid()" name="should return an state equal to false" time="0.005" />
</testsuite>
<testsuite name="worker filter()" timestamp="2019-09-30T13:35:12" hostname="localhost" time="0.031" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="worker filter()" name="should return 1 result filtering by id" time="0.021" />
<testcase classname="worker filter()" name="should return 1 result filtering by string" time="0.008" />
<testcase classname="worker filter()" name="should return 2 results filtering by name" time="0.002" />
</testsuite>
<testsuite name="worker isSubordinate()" timestamp="2019-09-30T13:35:12" hostname="localhost" time="0.012" errors="0" tests="3" skipped="0" disabled="0" failures="0">
<testcase classname="worker isSubordinate()" name="should return truthy if a worker is a subordinate" time="0.004" />
<testcase classname="worker isSubordinate()" name="should return truthy for an hr person" time="0.004" />
<testcase classname="worker isSubordinate()" name="should return truthy if the current user is himself" time="0.004" />
</testsuite>
<testsuite name="worker mySubordinates()" timestamp="2019-09-30T13:35:12" hostname="localhost" time="0.011" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="worker mySubordinates()" name="should return an array of subordinates greather than 1" time="0.007" />
<testcase classname="worker mySubordinates()" name="should return an array of one subordinate" time="0.003" />
</testsuite>
<testsuite name="Worker absences()" timestamp="2019-09-30T13:35:12" hostname="localhost" time="0.082" errors="0" tests="4" skipped="0" disabled="0" failures="0">
<testcase classname="Worker absences()" name="should get the absence calendar for the given dates then evaluate the type of absences" time="0.029" />
<testcase classname="Worker absences()" name="should fire the worker 106 on Juny and see he/she has 14" time="0.017" />
<testcase classname="Worker absences()" name="should fire the worker 106 on March and see he/she has 7" time="0.017" />
<testcase classname="Worker absences()" name="should fire the worker 106 on january and see he/she has x" time="0.015" />
</testsuite>
<testsuite name="workerMana getCurrentWorkerMana()" timestamp="2019-09-30T13:35:12" hostname="localhost" time="0.006" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="workerMana getCurrentWorkerMana()" name="should get the mana of the logged worker" time="0.003" />
<testcase classname="workerMana getCurrentWorkerMana()" name="should return 0 if the user doesnt uses mana" time="0.002" />
</testsuite>
<testsuite name="workerTimeControl addAutoTime()" timestamp="2019-09-30T13:35:12" hostname="localhost" time="0.005" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="workerTimeControl addAutoTime()" name="should return an undefined value" time="0.005" />
</testsuite>
<testsuite name="workerTimeControl filter()" timestamp="2019-09-30T13:35:12" hostname="localhost" time="0.011" errors="0" tests="2" skipped="0" disabled="0" failures="0">
<testcase classname="workerTimeControl filter()" name="should return 1 result filtering by id" time="0.005" />
<testcase classname="workerTimeControl filter()" name="should return a privilege error for a non subordinate worker" time="0.006" />
</testsuite>
<testsuite name="workerTimeControl getHoursWorked()" timestamp="2019-09-30T13:35:12" hostname="localhost" time="0.002" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="workerTimeControl getHoursWorked()" name="should return an totalWorkedYear to be defined" time="0.002" />
</testsuite>
<testsuite name="workerTimeControl getWorkedWeek()" timestamp="2019-09-30T13:35:12" hostname="localhost" time="0.002" errors="0" tests="1" skipped="0" disabled="0" failures="0">
<testcase classname="workerTimeControl getWorkedWeek()" name="should return an timeds to be defined" time="0.002" />
</testsuite>
</testsuites>

View File

@ -56,5 +56,6 @@
"You can't delete a confirmed order": "You can't delete a confirmed order", "You can't delete a confirmed order": "You can't delete a confirmed order",
"Value has an invalid format": "Value has an invalid format", "Value has an invalid format": "Value has an invalid format",
"The postcode doesn't exists. Ensure you put the correct format": "The postcode doesn't exists. Ensure you put the correct format", "The postcode doesn't exists. Ensure you put the correct format": "The postcode doesn't exists. Ensure you put the correct format",
"Can't create stowaway for this ticket": "Can't create stowaway for this ticket" "Can't create stowaway for this ticket": "Can't create stowaway for this ticket",
"is not a valid date": "is not a valid date"
} }

View File

@ -16,17 +16,17 @@ describe('sale updateConcept()', () => {
done(); done();
}); });
it('should throw if ID was undefined', async() => { it('should throw if ID was undefined', async() => {
let err;
const newConcept = 'I am he new concept'; const newConcept = 'I am he new concept';
await app.models.Sale.updateConcept(undefined, newConcept) try {
.catch(response => { await app.models.Sale.updateConcept(undefined, newConcept);
expect(response).toEqual(new Error(`Model::findById requiere el argumento id`)); } catch (e) {
error = response; err = e;
}); }
expect(error).toBeDefined(); expect(err).toBeDefined();
}); });
it('should update the sale concept', async() => { it('should update the sale concept', async() => {

View File

@ -1,7 +1,7 @@
import '../index.js'; import '../index.js';
import watcher from 'core/mocks/watcher'; import watcher from 'core/mocks/watcher';
fdescribe('Ticket', () => { describe('Ticket', () => {
describe('Component vnTicketSale', () => { describe('Component vnTicketSale', () => {
let controller; let controller;
let $scope; let $scope;

View File

@ -236,6 +236,7 @@ class Controller {
addTime(response) { addTime(response) {
if (response === 'ACCEPT') { if (response === 'ACCEPT') {
console.log('newTime', this.newTime);
let data = {workerFk: this.worker.id, timed: this.newTime}; let data = {workerFk: this.worker.id, timed: this.newTime};
let query = `/api/WorkerTimeControls/addTime`; let query = `/api/WorkerTimeControls/addTime`;
this.$http.post(query, data).then(() => { this.$http.post(query, data).then(() => {

246
package-lock.json generated
View File

@ -2166,7 +2166,7 @@
}, },
"util": { "util": {
"version": "0.10.3", "version": "0.10.3",
"resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz", "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
"integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
"dev": true, "dev": true,
"requires": { "requires": {
@ -2960,7 +2960,7 @@
"base": { "base": {
"version": "0.11.2", "version": "0.11.2",
"resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
"integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "integrity": "sha1-e95c7RRbbVUakNuH+DxVi060io8=",
"dev": true, "dev": true,
"requires": { "requires": {
"cache-base": "^1.0.1", "cache-base": "^1.0.1",
@ -3159,6 +3159,11 @@
"to-utf8": "0.0.1" "to-utf8": "0.0.1"
} }
}, },
"bowser": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/bowser/-/bowser-2.6.1.tgz",
"integrity": "sha512-hySGUuLhi0KetfxPZpuJOsjM0kRvCiCgPBygBkzGzJNsq/nbJmaO8QJc6xlWfeFFnMvtd/LeKkhDJGVrmVobUA=="
},
"boxen": { "boxen": {
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz",
@ -3288,7 +3293,7 @@
}, },
"browserify-rsa": { "browserify-rsa": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
"integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
"dev": true, "dev": true,
"requires": { "requires": {
@ -3347,7 +3352,7 @@
}, },
"buffer": { "buffer": {
"version": "4.9.1", "version": "4.9.1",
"resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
"integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
"requires": { "requires": {
"base64-js": "^1.0.2", "base64-js": "^1.0.2",
@ -3485,7 +3490,7 @@
"cache-base": { "cache-base": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
"integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "integrity": "sha1-Cn9GQWgxyLZi7jb+TnxZ129marI=",
"dev": true, "dev": true,
"requires": { "requires": {
"collection-visit": "^1.0.0", "collection-visit": "^1.0.0",
@ -3523,7 +3528,7 @@
}, },
"camelcase-keys": { "camelcase-keys": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
"integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
"dev": true, "dev": true,
"requires": { "requires": {
@ -3662,7 +3667,7 @@
"class-utils": { "class-utils": {
"version": "0.3.6", "version": "0.3.6",
"resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
"integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "integrity": "sha1-+TNprouafOAv1B+q0MqDAzGQxGM=",
"dev": true, "dev": true,
"requires": { "requires": {
"arr-union": "^3.1.0", "arr-union": "^3.1.0",
@ -4033,9 +4038,9 @@
} }
}, },
"content-security-policy-builder": { "content-security-policy-builder": {
"version": "2.0.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/content-security-policy-builder/-/content-security-policy-builder-2.0.0.tgz", "resolved": "https://registry.npmjs.org/content-security-policy-builder/-/content-security-policy-builder-2.1.0.tgz",
"integrity": "sha512-j+Nhmj1yfZAikJLImCvPJFE29x/UuBi+/MWqggGGc515JKaZrjuei2RhULJmy0MsstW3E3htl002bwmBNMKr7w==" "integrity": "sha512-/MtLWhJVvJNkA9dVLAp6fg9LxD2gfI6R2Fi1hPmfjYXSahJJzcfvoeDOxSyp4NvxMuwWv3WMssE9o31DoULHrQ=="
}, },
"content-type": { "content-type": {
"version": "1.0.4", "version": "1.0.4",
@ -4679,9 +4684,9 @@
} }
}, },
"dns-prefetch-control": { "dns-prefetch-control": {
"version": "0.1.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/dns-prefetch-control/-/dns-prefetch-control-0.1.0.tgz", "resolved": "https://registry.npmjs.org/dns-prefetch-control/-/dns-prefetch-control-0.2.0.tgz",
"integrity": "sha1-YN20V3dOF48flBXwyrsOhbCzALI=" "integrity": "sha512-hvSnros73+qyZXhHFjx2CMLwoj3Fe7eR9EJsFsqmcI1bB2OBWL/+0YzaEaKssCHnj/6crawNnUyw74Gm2EKe+Q=="
}, },
"dns-txt": { "dns-txt": {
"version": "2.0.2", "version": "2.0.2",
@ -4757,9 +4762,9 @@
} }
}, },
"dont-sniff-mimetype": { "dont-sniff-mimetype": {
"version": "1.0.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/dont-sniff-mimetype/-/dont-sniff-mimetype-1.0.0.tgz", "resolved": "https://registry.npmjs.org/dont-sniff-mimetype/-/dont-sniff-mimetype-1.1.0.tgz",
"integrity": "sha1-WTKJDcn04vGeXrAqIAJuXl78j1g=" "integrity": "sha512-ZjI4zqTaxveH2/tTlzS1wFp+7ncxNZaIEWYg3lzZRHkKf5zPT/MnEG6WL0BhHMJUabkh8GeU5NL5j+rEUCb7Ug=="
}, },
"dot-prop": { "dot-prop": {
"version": "4.2.0", "version": "4.2.0",
@ -4796,7 +4801,7 @@
}, },
"readable-stream": { "readable-stream": {
"version": "1.1.14", "version": "1.1.14",
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
"dev": true, "dev": true,
"requires": { "requires": {
@ -4919,7 +4924,7 @@
"dependencies": { "dependencies": {
"fs-extra": { "fs-extra": {
"version": "0.30.0", "version": "0.30.0",
"resolved": "http://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
"integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=",
"dev": true, "dev": true,
"requires": { "requires": {
@ -5325,10 +5330,13 @@
} }
}, },
"eslint-utils": { "eslint-utils": {
"version": "1.3.1", "version": "1.4.2",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz",
"integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==",
"dev": true "dev": true,
"requires": {
"eslint-visitor-keys": "^1.0.0"
}
}, },
"eslint-visitor-keys": { "eslint-visitor-keys": {
"version": "1.0.0", "version": "1.0.0",
@ -5832,7 +5840,7 @@
}, },
"file-loader": { "file-loader": {
"version": "1.1.11", "version": "1.1.11",
"resolved": "http://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz", "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz",
"integrity": "sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==", "integrity": "sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==",
"dev": true, "dev": true,
"requires": { "requires": {
@ -6196,8 +6204,7 @@
"ansi-regex": { "ansi-regex": {
"version": "2.1.1", "version": "2.1.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"aproba": { "aproba": {
"version": "1.2.0", "version": "1.2.0",
@ -6218,14 +6225,12 @@
"balanced-match": { "balanced-match": {
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"brace-expansion": { "brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"balanced-match": "^1.0.0", "balanced-match": "^1.0.0",
"concat-map": "0.0.1" "concat-map": "0.0.1"
@ -6240,20 +6245,17 @@
"code-point-at": { "code-point-at": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"concat-map": { "concat-map": {
"version": "0.0.1", "version": "0.0.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"console-control-strings": { "console-control-strings": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"core-util-is": { "core-util-is": {
"version": "1.0.2", "version": "1.0.2",
@ -6370,8 +6372,7 @@
"inherits": { "inherits": {
"version": "2.0.3", "version": "2.0.3",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"ini": { "ini": {
"version": "1.3.5", "version": "1.3.5",
@ -6383,7 +6384,6 @@
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"number-is-nan": "^1.0.0" "number-is-nan": "^1.0.0"
} }
@ -6398,7 +6398,6 @@
"version": "3.0.4", "version": "3.0.4",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
} }
@ -6406,14 +6405,12 @@
"minimist": { "minimist": {
"version": "0.0.8", "version": "0.0.8",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"minipass": { "minipass": {
"version": "2.3.5", "version": "2.3.5",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"safe-buffer": "^5.1.2", "safe-buffer": "^5.1.2",
"yallist": "^3.0.0" "yallist": "^3.0.0"
@ -6432,7 +6429,6 @@
"version": "0.5.1", "version": "0.5.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"minimist": "0.0.8" "minimist": "0.0.8"
} }
@ -6513,8 +6509,7 @@
"number-is-nan": { "number-is-nan": {
"version": "1.0.1", "version": "1.0.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"object-assign": { "object-assign": {
"version": "4.1.1", "version": "4.1.1",
@ -6526,7 +6521,6 @@
"version": "1.4.0", "version": "1.4.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"wrappy": "1" "wrappy": "1"
} }
@ -6612,8 +6606,7 @@
"safe-buffer": { "safe-buffer": {
"version": "5.1.2", "version": "5.1.2",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"safer-buffer": { "safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
@ -6649,7 +6642,6 @@
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"code-point-at": "^1.0.0", "code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0", "is-fullwidth-code-point": "^1.0.0",
@ -6669,7 +6661,6 @@
"version": "3.0.1", "version": "3.0.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"ansi-regex": "^2.0.0" "ansi-regex": "^2.0.0"
} }
@ -6713,14 +6704,12 @@
"wrappy": { "wrappy": {
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"yallist": { "yallist": {
"version": "3.0.3", "version": "3.0.3",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
} }
} }
}, },
@ -7003,7 +6992,7 @@
"global-modules": { "global-modules": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
"integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", "integrity": "sha1-bXcPDrUjrHgWTXK15xqIdyZcw+o=",
"dev": true, "dev": true,
"requires": { "requires": {
"global-prefix": "^1.0.1", "global-prefix": "^1.0.1",
@ -7040,7 +7029,7 @@
}, },
"globby": { "globby": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "http://registry.npmjs.org/globby/-/globby-5.0.0.tgz", "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
"integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
"dev": true, "dev": true,
"requires": { "requires": {
@ -7144,7 +7133,7 @@
}, },
"got": { "got": {
"version": "6.7.1", "version": "6.7.1",
"resolved": "http://registry.npmjs.org/got/-/got-6.7.1.tgz", "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz",
"integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=",
"dev": true, "dev": true,
"requires": { "requires": {
@ -7697,7 +7686,7 @@
"dependencies": { "dependencies": {
"es6-promise": { "es6-promise": {
"version": "3.3.1", "version": "3.3.1",
"resolved": "http://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz",
"integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=", "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=",
"dev": true "dev": true
}, },
@ -7775,9 +7764,9 @@
"dev": true "dev": true
}, },
"handlebars": { "handlebars": {
"version": "4.2.1", "version": "4.4.0",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.2.1.tgz", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.4.0.tgz",
"integrity": "sha512-bqPIlDk06UWbVEIFoYj+LVo42WhK96J+b25l7hbFDpxrOXMphFM3fNIm+cluwg4Pk2jiLjWU5nHQY7igGE75NQ==", "integrity": "sha512-xkRtOt3/3DzTKMOt3xahj2M/EqNhY988T+imYSlMgs5fVhLN2fmKVVj0LtEGmb+3UUYV5Qmm1052Mm3dIQxOvw==",
"dev": true, "dev": true,
"requires": { "requires": {
"neo-async": "^2.6.0", "neo-async": "^2.6.0",
@ -7950,47 +7939,47 @@
"dev": true "dev": true
}, },
"helmet": { "helmet": {
"version": "3.18.0", "version": "3.21.1",
"resolved": "https://registry.npmjs.org/helmet/-/helmet-3.18.0.tgz", "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.21.1.tgz",
"integrity": "sha512-TsKlGE5UVkV0NiQ4PllV9EVfZklPjyzcMEMjWlyI/8S6epqgRT+4s4GHVgc25x0TixsKvp3L7c91HQQt5l0+QA==", "integrity": "sha512-IC/54Lxvvad2YiUdgLmPlNFKLhNuG++waTF5KPYq/Feo3NNhqMFbcLAlbVkai+9q0+4uxjxGPJ9bNykG+3zZNg==",
"requires": { "requires": {
"depd": "2.0.0", "depd": "2.0.0",
"dns-prefetch-control": "0.1.0", "dns-prefetch-control": "0.2.0",
"dont-sniff-mimetype": "1.0.0", "dont-sniff-mimetype": "1.1.0",
"expect-ct": "0.2.0", "expect-ct": "0.2.0",
"feature-policy": "0.3.0", "feature-policy": "0.3.0",
"frameguard": "3.1.0", "frameguard": "3.1.0",
"helmet-crossdomain": "0.3.0", "helmet-crossdomain": "0.4.0",
"helmet-csp": "2.7.1", "helmet-csp": "2.9.2",
"hide-powered-by": "1.0.0", "hide-powered-by": "1.1.0",
"hpkp": "2.0.0", "hpkp": "2.0.0",
"hsts": "2.2.0", "hsts": "2.2.0",
"ienoopen": "1.1.0", "ienoopen": "1.1.0",
"nocache": "2.1.0", "nocache": "2.1.0",
"referrer-policy": "1.2.0", "referrer-policy": "1.2.0",
"x-xss-protection": "1.1.0" "x-xss-protection": "1.3.0"
} }
}, },
"helmet-crossdomain": { "helmet-crossdomain": {
"version": "0.3.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/helmet-crossdomain/-/helmet-crossdomain-0.3.0.tgz", "resolved": "https://registry.npmjs.org/helmet-crossdomain/-/helmet-crossdomain-0.4.0.tgz",
"integrity": "sha512-YiXhj0E35nC4Na5EPE4mTfoXMf9JTGpN4OtB4aLqShKuH9d2HNaJX5MQoglO6STVka0uMsHyG5lCut5Kzsy7Lg==" "integrity": "sha512-AB4DTykRw3HCOxovD1nPR16hllrVImeFp5VBV9/twj66lJ2nU75DP8FPL0/Jp4jj79JhTfG+pFI2MD02kWJ+fA=="
}, },
"helmet-csp": { "helmet-csp": {
"version": "2.7.1", "version": "2.9.2",
"resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.7.1.tgz", "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.9.2.tgz",
"integrity": "sha512-sCHwywg4daQ2mY0YYwXSZRsgcCeerUwxMwNixGA7aMLkVmPTYBl7gJoZDHOZyXkqPrtuDT3s2B1A+RLI7WxSdQ==", "integrity": "sha512-Lt5WqNfbNjEJ6ysD4UNpVktSyjEKfU9LVJ1LaFmPfYseg/xPealPfgHhtqdAdjPDopp5zbg/VWCyp4cluMIckw==",
"requires": { "requires": {
"bowser": "^2.6.1",
"camelize": "1.0.0", "camelize": "1.0.0",
"content-security-policy-builder": "2.0.0", "content-security-policy-builder": "2.1.0",
"dasherize": "2.0.0", "dasherize": "2.0.0"
"platform": "1.3.5"
} }
}, },
"hide-powered-by": { "hide-powered-by": {
"version": "1.0.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.0.0.tgz", "resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.1.0.tgz",
"integrity": "sha1-SoWtZYgfYoV/xwr3F0oRhNzM4ys=" "integrity": "sha512-Io1zA2yOA1YJslkr+AJlWSf2yWFkKjvkcL9Ni1XSUqnGLr/qRQe2UI3Cn/J9MsJht7yEVCe0SscY1HgVMujbgg=="
}, },
"hmac-drbg": { "hmac-drbg": {
"version": "1.0.1", "version": "1.0.1",
@ -8731,7 +8720,7 @@
}, },
"is-obj": { "is-obj": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
"integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8="
}, },
"is-path-cwd": { "is-path-cwd": {
@ -8761,7 +8750,7 @@
"is-plain-object": { "is-plain-object": {
"version": "2.0.4", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
"integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "integrity": "sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc=",
"dev": true, "dev": true,
"requires": { "requires": {
"isobject": "^3.0.1" "isobject": "^3.0.1"
@ -9487,6 +9476,18 @@
"throat": "^4.0.0" "throat": "^4.0.0"
} }
}, },
"jest-junit": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-8.0.0.tgz",
"integrity": "sha512-cuD2XM2youMjrOxOu/7H2pLfsO8LfAG4D3WsBxd9fFyI9U0uPpmr/CORH64kbIyZ47X5x1Rbzb9ovUkAEvhEEA==",
"dev": true,
"requires": {
"jest-validate": "^24.0.0",
"mkdirp": "^0.5.1",
"strip-ansi": "^4.0.0",
"xml": "^1.0.1"
}
},
"jest-leak-detector": { "jest-leak-detector": {
"version": "24.9.0", "version": "24.9.0",
"resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz", "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz",
@ -10223,7 +10224,7 @@
}, },
"load-json-file": { "load-json-file": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
"integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
"dev": true, "dev": true,
"requires": { "requires": {
@ -10290,9 +10291,9 @@
} }
}, },
"lodash": { "lodash": {
"version": "4.17.11", "version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
}, },
"lodash._basecopy": { "lodash._basecopy": {
"version": "3.0.1", "version": "3.0.1",
@ -10387,9 +10388,9 @@
} }
}, },
"lodash.mergewith": { "lodash.mergewith": {
"version": "4.6.1", "version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz", "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
"integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==", "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
"dev": true "dev": true
}, },
"lodash.restparam": { "lodash.restparam": {
@ -11012,7 +11013,7 @@
}, },
"media-typer": { "media-typer": {
"version": "0.3.0", "version": "0.3.0",
"resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
}, },
"mem": { "mem": {
@ -11037,7 +11038,7 @@
}, },
"meow": { "meow": {
"version": "3.7.0", "version": "3.7.0",
"resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz", "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
"integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
"dev": true, "dev": true,
"requires": { "requires": {
@ -11160,7 +11161,7 @@
}, },
"minimist": { "minimist": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
}, },
"minstache": { "minstache": {
@ -11174,7 +11175,7 @@
"dependencies": { "dependencies": {
"commander": { "commander": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/commander/-/commander-1.0.4.tgz", "resolved": "http://registry.npmjs.org/commander/-/commander-1.0.4.tgz",
"integrity": "sha1-Xt6xruI8T7VBprcNaSq+8ZZpotM=", "integrity": "sha1-Xt6xruI8T7VBprcNaSq+8ZZpotM=",
"dev": true, "dev": true,
"requires": { "requires": {
@ -11272,7 +11273,7 @@
}, },
"mkdirp": { "mkdirp": {
"version": "0.5.1", "version": "0.5.1",
"resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"requires": { "requires": {
"minimist": "0.0.8" "minimist": "0.0.8"
@ -11280,7 +11281,7 @@
"dependencies": { "dependencies": {
"minimist": { "minimist": {
"version": "0.0.8", "version": "0.0.8",
"resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
} }
} }
@ -11481,7 +11482,7 @@
}, },
"multipipe": { "multipipe": {
"version": "0.1.2", "version": "0.1.2",
"resolved": "http://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz",
"integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=",
"dev": true, "dev": true,
"requires": { "requires": {
@ -11687,7 +11688,7 @@
}, },
"jsesc": { "jsesc": {
"version": "0.5.0", "version": "0.5.0",
"resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
"integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
"dev": true "dev": true
}, },
@ -12329,7 +12330,7 @@
"dependencies": { "dependencies": {
"minimist": { "minimist": {
"version": "0.0.10", "version": "0.0.10",
"resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
"integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=",
"dev": true "dev": true
}, },
@ -12391,7 +12392,7 @@
}, },
"os-homedir": { "os-homedir": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
"dev": true "dev": true
}, },
@ -12407,7 +12408,7 @@
}, },
"os-tmpdir": { "os-tmpdir": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
"dev": true "dev": true
}, },
@ -12785,11 +12786,6 @@
} }
} }
}, },
"platform": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/platform/-/platform-1.3.5.tgz",
"integrity": "sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q=="
},
"plugin-error": { "plugin-error": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz",
@ -12935,7 +12931,7 @@
}, },
"pretty-bytes": { "pretty-bytes": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "http://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz",
"integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=", "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=",
"dev": true, "dev": true,
"requires": { "requires": {
@ -13038,13 +13034,13 @@
}, },
"string_decoder": { "string_decoder": {
"version": "0.10.31", "version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
"dev": true "dev": true
}, },
"through2": { "through2": {
"version": "0.2.3", "version": "0.2.3",
"resolved": "http://registry.npmjs.org/through2/-/through2-0.2.3.tgz", "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz",
"integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=", "integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=",
"dev": true, "dev": true,
"requires": { "requires": {
@ -13485,7 +13481,7 @@
"dependencies": { "dependencies": {
"jsesc": { "jsesc": {
"version": "0.5.0", "version": "0.5.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
"integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
"dev": true "dev": true
} }
@ -13863,7 +13859,7 @@
}, },
"safe-regex": { "safe-regex": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
"integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
"dev": true, "dev": true,
"requires": { "requires": {
@ -13988,7 +13984,7 @@
"dependencies": { "dependencies": {
"source-map": { "source-map": {
"version": "0.4.4", "version": "0.4.4",
"resolved": "http://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
"integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
"dev": true, "dev": true,
"requires": { "requires": {
@ -14306,7 +14302,7 @@
}, },
"string-width": { "string-width": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"dev": true, "dev": true,
"requires": { "requires": {
@ -14408,7 +14404,7 @@
"snapdragon-node": { "snapdragon-node": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
"integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "integrity": "sha1-bBdfhv8UvbByRWPo88GwIaKGhTs=",
"dev": true, "dev": true,
"requires": { "requires": {
"define-property": "^1.0.0", "define-property": "^1.0.0",
@ -14459,7 +14455,7 @@
"snapdragon-util": { "snapdragon-util": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
"integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "integrity": "sha1-+VZHlIbyrNeXAGk/b3uAXkWrVuI=",
"dev": true, "dev": true,
"requires": { "requires": {
"kind-of": "^3.2.0" "kind-of": "^3.2.0"
@ -14740,7 +14736,7 @@
"split-string": { "split-string": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
"integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "integrity": "sha1-fLCd2jqGWFcFxks5pkZgOGguj+I=",
"dev": true, "dev": true,
"requires": { "requires": {
"extend-shallow": "^3.0.0" "extend-shallow": "^3.0.0"
@ -14749,7 +14745,7 @@
"split2": { "split2": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz",
"integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", "integrity": "sha1-GGsldbz4PoW30YRldWI47k7kJJM=",
"dev": true, "dev": true,
"requires": { "requires": {
"through2": "^2.0.2" "through2": "^2.0.2"
@ -15675,7 +15671,7 @@
}, },
"through": { "through": {
"version": "2.3.8", "version": "2.3.8",
"resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
}, },
"through2": { "through2": {
@ -15968,7 +15964,7 @@
}, },
"tty-browserify": { "tty-browserify": {
"version": "0.0.0", "version": "0.0.0",
"resolved": "http://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
"integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
"dev": true "dev": true
}, },
@ -17273,15 +17269,21 @@
} }
}, },
"x-xss-protection": { "x-xss-protection": {
"version": "1.1.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.1.0.tgz", "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.3.0.tgz",
"integrity": "sha512-rx3GzJlgEeZ08MIcDsU2vY2B1QEriUKJTSiNHHUIem6eg9pzVOr2TL3Y4Pd6TMAM5D5azGjcxqI62piITBDHVg==" "integrity": "sha512-kpyBI9TlVipZO4diReZMAHWtS0MMa/7Kgx8hwG/EuZLiA6sg4Ah/4TRdASHhRRN3boobzcYgFRUFSgHRge6Qhg=="
}, },
"xdg-basedir": { "xdg-basedir": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
"integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=" "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ="
}, },
"xml": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz",
"integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=",
"dev": true
},
"xml-crypto": { "xml-crypto": {
"version": "0.8.5", "version": "0.8.5",
"resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-0.8.5.tgz", "resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-0.8.5.tgz",

View File

@ -11,7 +11,7 @@
"dependencies": { "dependencies": {
"compression": "^1.7.3", "compression": "^1.7.3",
"fs-extra": "^5.0.0", "fs-extra": "^5.0.0",
"helmet": "^3.15.1", "helmet": "^3.21.1",
"i18n": "^0.8.3", "i18n": "^0.8.3",
"loopback": "^3.26.0", "loopback": "^3.26.0",
"loopback-boot": "^2.27.1", "loopback-boot": "^2.27.1",
@ -68,6 +68,7 @@
"jasmine-reporters": "^2.3.2", "jasmine-reporters": "^2.3.2",
"jasmine-spec-reporter": "^4.2.1", "jasmine-spec-reporter": "^4.2.1",
"jest": "^24.9.0", "jest": "^24.9.0",
"jest-junit": "^8.0.0",
"json-loader": "^0.5.7", "json-loader": "^0.5.7",
"merge-stream": "^1.0.1", "merge-stream": "^1.0.1",
"minimist": "^1.2.0", "minimist": "^1.2.0",

View File

@ -10,13 +10,13 @@ module.exports = {
send(options) { send(options) {
options.from = `${config.app.senderName} <${config.app.senderMail}>`; options.from = `${config.app.senderName} <${config.app.senderMail}>`;
if (process.env.NODE_ENV !== 'production') if (process.env.NODE_ENV !== 'production') {
if (!config.smtp.user)
return Promise.resolve(true);
options.to = config.app.senderMail; options.to = config.app.senderMail;
}
return this.transporter.sendMail(options); return this.transporter.sendMail(options);
}, }
log() {
},
}; };