merge
gitea/salix/dev This commit has test failures Details

This commit is contained in:
Javi Gallego 2019-09-30 14:37:51 +02:00
commit 0573fec950
50 changed files with 1139 additions and 579 deletions

2
.gitignore vendored
View File

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

4
Jenkinsfile vendored
View File

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

View File

@ -75,7 +75,7 @@ let actions = {
},
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')
.wait(langSelector)
@ -180,6 +180,7 @@ let actions = {
.evaluate_now(elementSelector => {
const selectorMatches = document.querySelectorAll(elementSelector);
const element = selectorMatches[0];
if (selectorMatches.length > 1)
throw new Error(`multiple matches of ${elementSelector} found`);
@ -190,17 +191,18 @@ let actions = {
isVisible = true;
};
element.addEventListener('mouseover', eventHandler);
const elementBoundaries = element.getBoundingClientRect();
const x = elementBoundaries.left + element.offsetWidth / 2;
const y = elementBoundaries.top + element.offsetHeight / 2;
const rect = element.getBoundingClientRect();
const x = rect.left + rect.width / 2;
const y = rect.top + rect.height / 2;
const elementInCenter = document.elementFromPoint(x, y);
const elementInTopLeft = document.elementFromPoint(elementBoundaries.left, elementBoundaries.top);
const elementInBottomRight = document.elementFromPoint(elementBoundaries.right, elementBoundaries.bottom);
const elementInTopLeft = document.elementFromPoint(rect.left, rect.top);
const elementInBottomRight = document.elementFromPoint(rect.right, rect.bottom);
const e = new MouseEvent('mouseover', {
view: window,
bubbles: true,
cancelable: true,
});
if (elementInCenter)
elementInCenter.dispatchEvent(e);
@ -401,10 +403,12 @@ let actions = {
autocompleteSearch: function(autocompleteSelector, searchValue, done) {
this.wait(`${autocompleteSelector} input`)
.waitToClick(`${autocompleteSelector} input`)
.write(`${autocompleteSelector} vn-drop-down input`, searchValue)
.waitToClick(`${autocompleteSelector} li.active`)
.write(`.vn-popover.shown .vn-drop-down input`, searchValue)
.waitToClick(`.vn-popover.shown .vn-drop-down li.active`)
.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)
.then(done)
.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) {
this.wait(datePickerSelector)
.mousedown(datePickerSelector)

View File

@ -3,19 +3,19 @@ import components from './components_selectors.js';
export default {
globalItems: {
applicationsMenuButton: '#apps',
applicationsMenuVisible: 'vn-main-menu [vn-id="apps-menu"] ul',
clientsButton: 'vn-main-menu [vn-id="apps-menu"] ul > li[ui-sref="client.index"]',
itemsButton: 'vn-main-menu [vn-id="apps-menu"] ul > li[ui-sref="item.index"]',
ticketsButton: 'vn-main-menu [vn-id="apps-menu"] ul > li[ui-sref="ticket.index"]',
invoiceOutButton: 'vn-main-menu [vn-id="apps-menu"] ul > li[ui-sref="invoiceOut.index"]',
claimsButton: 'vn-main-menu [vn-id="apps-menu"] ul > li[ui-sref="claim.index"]',
applicationsMenuVisible: '.modules-menu',
clientsButton: '.modules-menu > li[ui-sref="client.index"]',
itemsButton: '.modules-menu > li[ui-sref="item.index"]',
ticketsButton: '.modules-menu > li[ui-sref="ticket.index"]',
invoiceOutButton: '.modules-menu > li[ui-sref="invoiceOut.index"]',
claimsButton: '.modules-menu > li[ui-sref="claim.index"]',
returnToModuleIndexButton: 'a[ui-sref="order.index"]',
userMenuButton: 'vn-topbar #user',
userLocalWarehouse: 'vn-topbar vn-popover vn-autocomplete[field="$ctrl.localWarehouseFk"]',
userLocalBank: 'vn-topbar vn-popover vn-autocomplete[field="$ctrl.localBankFk"]',
userLocalCompany: 'vn-topbar vn-popover vn-autocomplete[field="$ctrl.localCompanyFk"]',
userWarehouse: 'vn-topbar vn-popover vn-autocomplete[field="$ctrl.warehouseFk"]',
userCompany: 'vn-topbar vn-popover vn-autocomplete[field="$ctrl.companyFk"]',
userLocalWarehouse: '.user-configuration vn-autocomplete[field="$ctrl.localWarehouseFk"]',
userLocalBank: '.user-configuration vn-autocomplete[field="$ctrl.localBankFk"]',
userLocalCompany: '.user-configuration vn-autocomplete[field="$ctrl.localCompanyFk"]',
userWarehouse: '.user-configuration vn-autocomplete[field="$ctrl.warehouseFk"]',
userCompany: '.user-configuration vn-autocomplete[field="$ctrl.companyFk"]',
userConfigFirstAutocompleteClear: '#localWarehouse > div > div > div > vn-icon.clear',
userConfigSecondAutocompleteClear: '#localBank > div > div > div > vn-icon.clear',
userConfigThirdAutocompleteClear: '#localCompany > div > div > div > vn-icon.clear',
@ -45,7 +45,7 @@ export default {
},
clientDescriptor: {
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: {
basicDataButton: 'vn-left-menu a[ui-sref="client.card.basicData"]',
@ -177,7 +177,7 @@ export default {
dms: {
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',
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"]'
},
itemsIndex: {
@ -218,7 +218,7 @@ export default {
itemDescriptor: {
goBackToModuleIndexButton: 'vn-item-descriptor a[href="#!/item/index"]',
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',
regularizeWarehouseAutocomplete: 'vn-item-descriptor vn-dialog vn-autocomplete[field="$ctrl.warehouseFk"]',
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',
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',
firstSaleDescriptorImage: 'vn-ticket-summary vn-item-descriptor-popover > vn-popover vn-item-descriptor img',
itemDescriptorPopover: 'vn-ticket-summary vn-item-descriptor-popover > vn-popover',
itemDescriptorPopoverItemDiaryButton: 'vn-ticket-summary > vn-item-descriptor-popover 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"]',
firstSaleDescriptorImage: '.vn-popover.shown vn-item-descriptor img',
itemDescriptorPopover: '.vn-popover.shown vn-item-descriptor',
itemDescriptorPopoverItemDiaryButton: 'vn-item-descriptor a[href="#!/item/2/diary?warehouseFk=5&ticketFk=20"]',
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)',
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',
@ -324,7 +324,7 @@ export default {
},
ticketsIndex: {
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',
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',
@ -332,11 +332,11 @@ export default {
searchTicketInput: `vn-ticket-index ${components.vnTextfield}`,
searchWeeklyTicketInput: `vn-ticket-weekly-index ${components.vnTextfield}`,
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"]',
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',
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',
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"]',
@ -355,13 +355,13 @@ export default {
stateLabelValue: 'vn-ticket-descriptor vn-label-value[label="State"]',
goBackToModuleIndexButton: 'vn-ticket-descriptor a[ui-sref="ticket.index"]',
moreMenu: 'vn-ticket-descriptor vn-icon-menu > div > vn-icon',
moreMenuAddStowaway: 'vn-ticket-descriptor vn-drop-down > vn-popover ul > li[name="Add stowaway"]',
moreMenuDeleteStowawayButton: 'vn-ticket-descriptor vn-drop-down > vn-popover ul > li[name="Remove stowaway"]',
moreMenuAddToTurn: 'vn-ticket-descriptor vn-drop-down > vn-popover ul > li[name="Add turn"]',
moreMenuDeleteTicket: 'vn-ticket-descriptor vn-drop-down > vn-popover ul > li[name="Delete ticket"]',
moreMenuMakeInvoice: 'vn-ticket-descriptor vn-drop-down > vn-popover ul > li[name="Make invoice"]',
moreMenuChangeShippedHour: 'vn-ticket-descriptor vn-drop-down > vn-popover ul > li[name="Change shipped hour"]',
changeShippedHourInput: 'vn-ticket-descriptor > vn-dialog.ng-isolate-scope.vn-dialog.shown vn-input-time input',
moreMenuAddStowaway: '.vn-popover.shown .vn-drop-down li[name="Add stowaway"]',
moreMenuDeleteStowawayButton: '.vn-popover.shown .vn-drop-down li[name="Remove stowaway"]',
moreMenuAddToTurn: '.vn-popover.shown .vn-drop-down li[name="Add turn"]',
moreMenuDeleteTicket: '.vn-popover.shown .vn-drop-down li[name="Delete ticket"]',
moreMenuMakeInvoice: '.vn-popover.shown .vn-drop-down li[name="Make invoice"]',
moreMenuChangeShippedHour: '.vn-popover.shown .vn-drop-down li[name="Change shipped hour"]',
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',
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)',
@ -398,21 +398,21 @@ export default {
ticketSales: {
saleButton: 'vn-left-menu a[ui-sref="ticket.card.sale"]',
saleLine: 'vn-table div > vn-tbody > vn-tr',
saleDescriptorPopover: 'vn-ticket-sale vn-item-descriptor-popover > vn-popover',
saleDescriptorPopoverSummaryButton: 'vn-item-descriptor-popover a[ui-sref="item.card.summary({id: $ctrl.item.id})"]',
saleDescriptorPopover: '.vn-popover.shown vn-item-descriptor',
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',
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',
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"]',
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"]',
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"]',
moreMenuUpdateDiscount: 'vn-ticket-sale vn-tool-bar > vn-button-menu[vn-id="more-button"] vn-drop-down > vn-popover ul > li[name="Update discount"]',
moreMenuCreateClaim: '.vn-popover.shown .vn-drop-down li[name="Add claim"]',
moreMenuReserve: '.vn-popover.shown .vn-drop-down li[name="Mark as reserved"]',
moreMenuUnmarkReseved: '.vn-popover.shown .vn-drop-down li[name="Unmark as reserved"]',
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',
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',
transferQuantityCell: 'vn-ticket-sale vn-popover.transfer.ng-isolate-scope.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable',
transferQuantityInput: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable > span > text',
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"]',
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)',
firstSaleThumbnailImage: 'vn-ticket-sale:nth-child(1) vn-tr:nth-child(1) vn-td:nth-child(3) > img',
firstSaleZoomedImage: 'body > div > div > img',
@ -421,9 +421,9 @@ export default {
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',
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',
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',
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)',
@ -449,10 +449,10 @@ export default {
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"]',
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',
moveToTicketInputClearButton: 'vn-popover.shown i[title="Clear"]',
moveToTicketButton: 'vn-ticket-sale vn-popover.transfer vn-icon[icon="arrow_forward_ios"]',
moveToNewTicketButton: 'vn-ticket-sale vn-popover.transfer vn-button[label="New ticket"]',
moveToTicketInput: '.vn-popover.shown vn-textfield[model="$ctrl.transfer.ticketId"] input',
moveToTicketInputClearButton: '.vn-popover.shown i[title="Clear"]',
moveToTicketButton: '.vn-popover.shown vn-icon[icon="arrow_forward_ios"]',
moveToNewTicketButton: '.vn-popover.shown vn-button[label="New ticket"]',
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]',
stateMenuButton: 'vn-ticket-sale vn-tool-bar > vn-button-menu[label="State"]'
@ -524,7 +524,7 @@ export default {
},
claimDescriptor: {
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"]'
},
claimSummary: {
@ -532,13 +532,13 @@ export default {
state: 'vn-claim-summary vn-label-value[label="State"] > section > span',
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',
firstSaleDescriptorImage: 'vn-claim-summary vn-item-descriptor-popover > vn-popover vn-item-descriptor img',
itemDescriptorPopover: 'vn-claim-summary vn-item-descriptor-popover > vn-popover',
itemDescriptorPopoverItemDiaryButton: 'vn-claim-summary > vn-item-descriptor-popover a[href="#!/item/2/diary"]',
firstSaleDescriptorImage: '.vn-popover.shown vn-item-descriptor img',
itemDescriptorPopover: '.vn-popover.shown vn-item-descriptor',
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',
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',
firstActionTicketDescriptor: 'vn-claim-summary > vn-ticket-descriptor-popover > vn-popover > div > div.content > vn-ticket-descriptor'
firstActionTicketDescriptor: '.vn-popover.shown vn-ticket-descriptor'
},
claimBasicData: {
claimStateAutocomplete: 'vn-claim-basic-data vn-autocomplete[field="$ctrl.claim.claimStateFk"]',
@ -548,8 +548,8 @@ export default {
},
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',
discountInput: 'vn-claim-detail vn-popover vn-input-number[model="$ctrl.newDiscount"] > div > div > div.infix > input',
discoutPopoverMana: 'vn-claim-detail > vn-popover > div > div.content > div > vn-horizontal > h5',
discountInput: '.vn-popover.shown vn-input-number[model="$ctrl.newDiscount"] > div > div > div.infix > input',
discoutPopoverMana: '.vn-popover.shown .content > div > vn-horizontal > h5',
addItemButton: 'vn-claim-detail a vn-float-button',
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',
@ -575,7 +575,7 @@ export default {
claimAction: {
importClaimButton: 'vn-claim-action vn-button[label="Import claim"]',
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"]',
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"]',
@ -608,9 +608,9 @@ export default {
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',
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"]',
tagValueInput: 'vn-order-catalog > vn-side-menu vn-catalog-filter vn-popover 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',
tagAutocomplete: 'vn-order-catalog-search-panel vn-autocomplete[field="filter.tagFk"]',
tagValueInput: 'vn-order-catalog-search-panel vn-textfield[model="filter.value"] 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',
fourthFilterRemoveButton: 'vn-order-catalog > vn-side-menu vn-catalog-filter > div > vn-horizontal.chips > vn-chip:nth-child(4) button',
},
@ -652,8 +652,8 @@ export default {
kmStartInput: 'vn-route-basic-data vn-input-number[field="$ctrl.route.kmStart"] input',
kmEndInput: 'vn-route-basic-data vn-input-number[model="$ctrl.route.kmEnd"] input',
createdDateInput: 'vn-route-basic-data vn-date-picker[model="$ctrl.route.created"] > div > input',
startedDateInput: 'vn-route-basic-data vn-date-picker[model="$ctrl.route.started"] > div > input',
finishedDateInput: 'vn-route-basic-data vn-date-picker[model="$ctrl.route.finished"] > div > input',
startedHourInput: 'vn-route-basic-data vn-input-time[model="$ctrl.route.started"] input',
finishedHourInput: 'vn-route-basic-data vn-input-time[model="$ctrl.route.finished"] input',
saveButton: 'vn-route-basic-data vn-submit[label="Save"] input'
},
routeTickets: {
@ -727,9 +727,9 @@ export default {
},
invoiceOutDescriptor: {
moreMenu: 'vn-invoice-out-descriptor vn-icon-menu[vn-id="more-button"]',
moreMenuDeleteInvoiceOut: 'vn-invoice-out-descriptor vn-popover li[name="Delete Invoice"]',
moreMenuBookInvoiceOut: 'vn-invoice-out-descriptor vn-popover li[name="Book invoice"]',
moreMenuShowInvoiceOutPdf: 'vn-invoice-out-descriptor vn-popover li[name="Show invoice PDF"]',
moreMenuDeleteInvoiceOut: '.vn-popover.shown .vn-drop-down li[name="Delete Invoice"]',
moreMenuBookInvoiceOut: '.vn-popover.shown .vn-drop-down li[name="Book invoice"]',
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"]',
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() => {
const visible = await nightmare
.waitToClick(selectors.dms.firstDocWorker)
.waitForClassPresent(selectors.dms.firstDocWorkerDescriptor, 'shown')
.wait(selectors.dms.firstDocWorkerDescriptor)
.isVisible(selectors.dms.firstDocWorkerDescriptor);
expect(visible).toBeTruthy();

View File

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

View File

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

View File

@ -59,6 +59,7 @@ describe('claim Summary path', () => {
.exists(selectors.claimSummary.itemDescriptorPopoverItemDiaryButton);
expect(exists).toBeTruthy();
await nightmare.mousedown('.vn-popover.shown');
});
it('should display the claim development details', async() => {
@ -82,6 +83,7 @@ describe('claim Summary path', () => {
.exists(selectors.claimSummary.firstDevelopmentWorkerGoToClientButton);
expect(exists).toBeTruthy();
await nightmare.mousedown('.vn-popover.shown');
});
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() => {
let exists = await nightmare
.waitToClick(selectors.claimDescriptor.moreMenu)
.wait(selectors.claimDescriptor.moreMenuDeleteClaim)
.exists(selectors.claimDescriptor.moreMenuDeleteClaim);
expect(exists).toBeTruthy();

View File

@ -20,8 +20,8 @@ describe('Route basic Data path', () => {
.write(selectors.routeBasicData.kmStartInput, 1)
.clearInput(selectors.routeBasicData.kmEndInput)
.write(selectors.routeBasicData.kmEndInput, 2)
.datePicker(selectors.routeBasicData.startedDateInput, 1, null)
.datePicker(selectors.routeBasicData.finishedDateInput, 1, null)
.write(selectors.routeBasicData.startedHourInput, '0800')
.write(selectors.routeBasicData.finishedHourInput, '1230')
.waitToClick(selectors.routeBasicData.saveButton)
.waitForLastSnackbar();

View File

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

View File

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

View File

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

View File

@ -1,79 +1,77 @@
@import "effects";
@import "variables";
vn-drop-down {
.dropdown {
display: flex;
flex-direction: column;
height: inherit;
.vn-drop-down {
display: flex;
flex-direction: column;
height: inherit;
& > .filter {
position: relative;
& > .filter {
position: relative;
& > .search {
display: block;
width: 100%;
box-sizing: border-box;
border: none;
font-size: inherit;
padding: .6em;
margin: 0!important;
&.not-empty label{
display: none;
}
& .selected label {
font-size: inherit;
bottom: 2px;
color: $color-font-secondary;
}
}
& > vn-icon[icon=clear] {
& > .search {
display: block;
width: 100%;
box-sizing: border-box;
border: none;
font-size: inherit;
padding: .6em;
margin: 0!important;
&.not-empty label{
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] {
display: block;
& .selected label {
font-size: inherit;
bottom: 2px;
color: $color-font-secondary;
}
}
& > .list {
max-height: 20em;
overflow: auto;
& > vn-icon[icon=clear] {
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;
ul {
padding: 0;
&:hover {
color: $color-font;
}
}
&:hover > vn-icon[icon=clear] {
display: block;
}
}
& > .list {
max-height: 20em;
overflow: auto;
ul {
padding: 0;
margin: 0;
list-style-type: none;
}
li, .status {
@extend %clickable;
padding: .6em;
white-space: nowrap;
display: flex;
& > input[type=checkbox] {
margin: 0;
list-style-type: none;
margin-right: .6em;
}
li, .status {
@extend %clickable;
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;
&.active {
@extend %active;
}
}
.status {
color: $color-main;
font-weight: bold;
}
}
}

View File

@ -9,7 +9,6 @@ export default class InputNumber extends Input {
this.hasFocus = false;
vnTemplate.normalizeInputAttrs($attrs);
this.registerEvents();
}
@ -107,10 +106,6 @@ export default class InputNumber extends Input {
if (value) this.input.step = value;
}
get validationError() {
return this.input.validationMessage;
}
/**
* Increases the input value
*/
@ -124,61 +119,7 @@ export default class InputNumber extends 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'];
ngModule.component('vnInputNumber', {

View File

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

View File

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

View File

@ -3,17 +3,16 @@ import Input from '../../lib/input';
import './style.scss';
export default class InputTime extends Input {
constructor($element, $scope) {
constructor($element, $scope, $filter) {
super($element, $scope);
this.$filter = $filter;
this.registerEvents();
}
/**
* Registers all event emitters
*/
registerEvents() {
this.input.addEventListener('change', event => {
this.onTimeChange();
this.emit('change', {event});
});
@ -35,147 +34,31 @@ export default class InputTime extends Input {
* @param {Number} value - Value
*/
set value(value) {
if (this._value === undefined && value || typeof value === 'string')
value = this.formatTime(value);
this.updateValue(value);
this.input.value = this.$filter('date')(value, 'HH:mm');
}
updateValue(value) {
this._value = value;
this.hasValue = !(value === null || value === undefined);
if (this.hasValue)
this.element.classList.add('not-empty');
else
this.element.classList.remove('not-empty');
this.element.classList.toggle('not-empty', value != null);
this.validateValue();
}
/**
* Gets max value
*/
get max() {
return this.input.max;
}
onTimeChange() {
let date = null;
let value = this.input.value;
/**
* Sets max allowed value
*
* @param {Number} value - Value
*/
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));
if (value) {
let split = value.split(':').map(i => parseInt(i) || null);
date = new Date(this.value || null);
date.setHours(split[0], split[1], 0, 0);
}
date.setSeconds(null);
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');
this.updateValue(date);
}
}
InputTime.$inject = ['$element', '$scope', '$attrs', 'vnTemplate', '$transclude'];
InputTime.$inject = ['$element', '$scope', '$filter'];
ngModule.component('vnInputTime', {
template: require('./index.html'),
@ -188,9 +71,6 @@ ngModule.component('vnInputTime', {
label: '@?',
disabled: '<?',
readonly: '<?',
step: '<?',
min: '<?',
max: '<?',
rule: '@?',
value: '=model',
vnTabIndex: '@?',

View File

@ -40,19 +40,4 @@ describe('Component vnInputTime', () => {
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"] {
clip-path: inset(0 17px 0 0);
outline:none;
outline:0;
outline: none;
outline: 0;
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -12,15 +12,14 @@ export function directive() {
restrict: 'A',
link: function($scope, $element, $attrs) {
let id = kebabToCamel($attrs.vnId);
let controller = $element[0].$ctrl ?
$element[0].$ctrl : $element.controller($element[0].tagName.toLowerCase());
let $ctrl = $element[0].$ctrl
? $element[0].$ctrl
: $element.controller($element[0].tagName.toLowerCase());
if (!id)
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`));
});
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'
xit(`should set the controller into the $scope as there are no errors being thrown`, () => {
let html = `<form vn-id="1"></form>`;

View File

@ -8,22 +8,101 @@ export default class Input extends Component {
super($element, $scope);
this.input = this.element.querySelector('input');
}
set disabled(value) {
this.input.disabled = value == true;
this.mdlUpdate();
}
get disabled() {
return this.input.disabled;
}
select() {
this.input.select();
}
focus() {
this.input.focus();
}
mdlUpdate() {
if (this.mdlElement)
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'];
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>
</div>
<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}}">
<vn-icon icon="{{::mod.icon || 'photo'}}"></vn-icon>
<span translate>{{::mod.name}}</span>

View File

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

View File

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

View File

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

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",
"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",
"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

@ -40,6 +40,11 @@
</vn-label-value>
</vn-one>
<vn-horizontal class="buttons">
<vn-icon-button
ng-click="$ctrl.filterTickets(client, $event)"
vn-tooltip="Client tickets"
icon="icon-ticket">
</vn-icon-button>
<vn-icon-button
ng-click="$ctrl.openSummary(client, $event)"
vn-tooltip="Preview"

View File

@ -1,8 +1,9 @@
import ngModule from '../module';
export default class Controller {
constructor($scope, $stateParams) {
constructor($scope, $state) {
this.$ = $scope;
this.$state = $state;
this.clientSelected = null;
}
@ -42,8 +43,16 @@ export default class Controller {
this.clientSelected = client;
this.$.dialogSummaryClient.show();
}
filterTickets(client, event) {
let state = `ticket.index`;
let params = {q: `{"clientFk": ${client.id}}`};
event.preventDefault();
this.$state.go(state, params);
}
}
Controller.$inject = ['$scope', '$stateParams'];
Controller.$inject = ['$scope', '$state'];
ngModule.component('vnClientIndex', {
template: require('./index.html'),

View File

@ -0,0 +1,29 @@
import './index';
describe('Client index', () => {
let $scope;
let controller;
beforeEach(angular.mock.module('client', $translateProvider => {
$translateProvider.translations('en', {});
}));
beforeEach(angular.mock.inject(($componentController, $rootScope, $state) => {
$scope = $rootScope.$new();
controller = $componentController('vnClientIndex', {$scope, $state});
}));
describe('x()', () => {
it('should request to patch the propagation of tax status', () => {
const client = {id: 101};
const event = {preventDefault: () => {}};
spyOn(event, 'preventDefault');
spyOn(controller.$state, 'go');
controller.filterTickets(client, event);
expect(event.preventDefault).toHaveBeenCalledWith();
expect(controller.$state.go).toHaveBeenCalledWith('ticket.index', jasmine.any(Object));
});
});
});

View File

@ -3,3 +3,4 @@ Phone: Teléfono
Town/City: Ciudad
Email: E-mail
View client: Ver cliente
Client tickets: Listado de tickets del cliente

View File

@ -5,7 +5,7 @@
form="form"
save="patch">
</vn-watcher>
<form name="form" ng-submit="watcher.submit()" compact>
<form name="form" ng-submit="$ctrl.onSubmit()" compact>
<vn-card pad-large>
<vn-horizontal>
<vn-autocomplete
@ -56,18 +56,21 @@
</vn-input-number>
</vn-horizontal>
<vn-horizontal>
<vn-date-picker
<vn-input-time
label="Hour started"
model="$ctrl.route.started">
</vn-input-time>
<vn-input-time
label="Hour finished"
model="$ctrl.route.finished">
</vn-input-time>
</vn-horizontal>
<vn-horizontal>
<vn-textfield
vn-one
label="Date started"
model="$ctrl.route.started"
ini-options="{dateFormat: 'd-m-Y'}">
</vn-date-picker>
<vn-date-picker
vn-one
label="Date finished"
model="$ctrl.route.finished"
ini-options="{dateFormat: 'd-m-Y'}">
</vn-date-picker>
label="Description"
field="$ctrl.route.description" vn-focus>
</vn-textfield>
</vn-horizontal>
</vn-card>
<vn-button-bar>

View File

@ -1,8 +1,24 @@
import ngModule from '../module';
class Controller {
constructor($scope, $state) {
this.$scope = $scope;
this.$state = $state;
}
onSubmit() {
this.$scope.watcher.submit().then(() => {
this.card.reload();
});
}
}
ngModule.component('vnRouteBasicData', {
template: require('./index.html'),
controller: Controller,
bindings: {
route: '<'
},
require: {
card: '^vnRouteCard'
}
});

View File

@ -2,3 +2,4 @@ Date finished: Fecha fin
Date started: Fecha inicio
Km start: Km de inicio
Km end: Km de fin
Description: Descripción

View File

@ -40,7 +40,7 @@
<vn-icon
vn-tooltip="Volume exceded"
icon="icon-volume"
ng-class="{bright: $ctrl.route.m3 > $ctrl.route.vehicle.m3}">
ng-class="{bright: $ctrl.route.m3 > $ctrl.route.vehicle.m3 && $ctrl.route.vehicle.m3 != NULL}">
</vn-icon>
</div>
<div class="quicklinks">
@ -74,5 +74,5 @@
<vn-confirm
vn-id="updateVolumeConfirmation"
on-response="$ctrl.updateVolume(response)"
question="Are you sure you want to book this invoice?">
question="Are you sure you want to update the volume?">
</vn-confirm>

View File

@ -1,5 +1,4 @@
import ngModule from '../module';
import {createDecipher} from 'crypto';
class Controller {
constructor($, $http, vnApp, $translate, aclService) {

View File

@ -4,3 +4,4 @@ Send route report: Enviar informe de ruta
Show route report: Ver informe de ruta
Update volume: Actualizar volumen
Volume updated: Volumen actualizado
Are you sure you want to update the volume?: Estas seguro que quieres actualizar el volumen?

View File

@ -6,8 +6,8 @@
"dependencies": ["client", "worker", "ticket"],
"menu": [
{"state": "route.card.basicData", "icon": "settings"},
{"state": "route.card.log", "icon": "history"},
{"state": "route.card.tickets", "icon": "icon-ticket"}],
{"state": "route.card.tickets", "icon": "icon-ticket"},
{"state": "route.card.log", "icon": "history"}],
"routes": [
{
"url": "/route",

View File

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

View File

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

View File

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

24
package-lock.json generated
View File

@ -7764,9 +7764,9 @@
"dev": true
},
"handlebars": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.3.3.tgz",
"integrity": "sha512-VupOxR91xcGojfINrzMqrvlyYbBs39sXIrWa7YdaQWeBudOlvKEGvCczMfJPgnuwHE/zyH1M6J+IUP6cgDVyxg==",
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.4.0.tgz",
"integrity": "sha512-xkRtOt3/3DzTKMOt3xahj2M/EqNhY988T+imYSlMgs5fVhLN2fmKVVj0LtEGmb+3UUYV5Qmm1052Mm3dIQxOvw==",
"dev": true,
"requires": {
"neo-async": "^2.6.0",
@ -9476,6 +9476,18 @@
"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": {
"version": "24.9.0",
"resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz",
@ -17266,6 +17278,12 @@
"resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
"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": {
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-0.8.5.tgz",

View File

@ -68,6 +68,7 @@
"jasmine-reporters": "^2.3.2",
"jasmine-spec-reporter": "^4.2.1",
"jest": "^24.9.0",
"jest-junit": "^8.0.0",
"json-loader": "^0.5.7",
"merge-stream": "^1.0.1",
"minimist": "^1.2.0",

View File

@ -10,13 +10,13 @@ module.exports = {
send(options) {
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;
}
return this.transporter.sendMail(options);
},
log() {
},
}
};