diff --git a/client/client/src/address-edit/address-edit.html b/client/client/src/address-edit/address-edit.html index 3518eb274..0497570af 100644 --- a/client/client/src/address-edit/address-edit.html +++ b/client/client/src/address-edit/address-edit.html @@ -8,9 +8,9 @@ url="/client/api/Addresses" id-field="id" data="$ctrl.address" - form="form"> + form="addressForm"> -
+ Address @@ -50,6 +50,11 @@ + +
+ +
+ Notes diff --git a/client/client/src/address-edit/address-edit.js b/client/client/src/address-edit/address-edit.js index 5d093a765..f0f3955ce 100644 --- a/client/client/src/address-edit/address-edit.js +++ b/client/client/src/address-edit/address-edit.js @@ -51,18 +51,22 @@ export default class Controller { return this.$http.post(`/client/api/AddressObservations/crudAddressObservations`, observationsObject); } - _observationsEquals(ob1, ob2) { - return ob1.id === ob2.id && ob1.observationTypeFk === ob2.observationTypeFk && ob1.description === ob2.description; + equalObservations(oldObj, newObj) { + return oldObj.id === newObj.id && oldObj.observationTypeFk === newObj.observationTypeFk && oldObj.description === newObj.description; } submit() { - if (this.$scope.form.$invalid) { + if (this.$scope.addressForm.$invalid || this.$scope.notesForm.$invalid) { + this.vnApp.showMessage( + this.$translate.instant('Some fields are invalid') + ); return false; } let canSubmitWatcher = this.$scope.watcher.dataChanged(); let canSubmitObservations; let repeatedTypes = false; + let emptyFields = false; let types = []; let observationsObj = { delete: this.removedObservations, @@ -70,13 +74,17 @@ export default class Controller { update: [] }; - for (let i = 0; i < this.observations.length; i++) { - let observation = this.observations[i]; + this.observations.forEach(observation => { let isNewObservation = observation.id === undefined; if (observation.observationTypeFk && types.indexOf(observation.observationTypeFk) !== -1) { repeatedTypes = true; - break; + return; + } + + if (observation.observationTypeFk === null || observation.description === null) { + emptyFields = true; + return; } if (observation.observationTypeFk) @@ -84,10 +92,10 @@ export default class Controller { if (isNewObservation && observation.observationTypeFk && observation.description) { observationsObj.create.push(observation); - } else if (!isNewObservation && !this._observationsEquals(this.oldObservations[observation.id], observation)) { + } else if (!isNewObservation && !this.equalObservations(this.oldObservations[observation.id], observation)) { observationsObj.update.push(observation); } - } + }); canSubmitObservations = observationsObj.update.length > 0 || observationsObj.create.length > 0 || observationsObj.delete.length > 0; @@ -95,15 +103,21 @@ export default class Controller { this.vnApp.showMessage( this.$translate.instant('The observation type must be unique') ); + } else if (emptyFields) { + this.vnApp.showMessage( + this.$translate.instant('No field can be blank') + ); } else if (canSubmitWatcher && !canSubmitObservations) { this.$scope.watcher.submit().then(() => { this.$state.go('clientCard.addresses.list', {id: this.$state.params.id}); }); } else if (!canSubmitWatcher && canSubmitObservations) { + console.log('noWatcher canNotes'); this._submitObservations(observationsObj).then(() => { this.$state.go('clientCard.addresses.list', {id: this.$state.params.id}); }); } else if (canSubmitWatcher && canSubmitObservations) { + console.log('canWatcher canNotes'); this.$q.all([this.$scope.watcher.submit(), this._submitObservations(observationsObj)]).then(() => { this.$state.go('clientCard.addresses.list', {id: this.$state.params.id}); }); diff --git a/client/client/src/address-edit/address-edit.spec.js b/client/client/src/address-edit/address-edit.spec.js index 23499bd33..0c9692004 100644 --- a/client/client/src/address-edit/address-edit.spec.js +++ b/client/client/src/address-edit/address-edit.spec.js @@ -27,7 +27,7 @@ describe('Client', () => { it('should return true if two observations are equals independent of control attributes', () => { let ob1 = {id: 1, observationTypeFk: 1, description: 'Spiderman rocks', showAddIcon: true}; let ob2 = {id: 1, observationTypeFk: 1, description: 'Spiderman rocks', showAddIcon: false}; - let equals = controller._observationsEquals(ob2, ob1); + let equals = controller.equalObservations(ob2, ob1); expect(equals).toBeTruthy(); }); @@ -35,7 +35,7 @@ describe('Client', () => { it('should return false if two observations are not equals independent of control attributes', () => { let ob1 = {id: 1, observationTypeFk: 1, description: 'Spiderman rocks', showAddIcon: true}; let ob2 = {id: 1, observationTypeFk: 1, description: 'Spiderman sucks', showAddIcon: true}; - let equals = controller._observationsEquals(ob2, ob1); + let equals = controller.equalObservations(ob2, ob1); expect(equals).toBeFalsy(); }); @@ -45,7 +45,7 @@ describe('Client', () => { it('should perform a GET query to receive the address observations', () => { let filter = {where: {addressFk: 1}, include: {relation: 'observationType'}}; let res = ['some notes']; - $httpBackend.when('GET', `/client/api/AddressObservations?filter=${JSON.stringify(filter)}`).respond(res); + $httpBackend.whenGET(`/client/api/AddressObservations?filter=${JSON.stringify(filter)}`).respond(res); $httpBackend.expectGET(`/client/api/AddressObservations?filter=${JSON.stringify(filter)}`); controller.$onInit(); $httpBackend.flush(); diff --git a/client/core/src/components/watcher/watcher.js b/client/core/src/components/watcher/watcher.js index 7b5317ca4..62224137f 100644 --- a/client/core/src/components/watcher/watcher.js +++ b/client/core/src/components/watcher/watcher.js @@ -203,8 +203,8 @@ export default class Watcher extends Component { } dataChanged() { - if (this.form && this.form.$dirty) return true; let newData = this.copyInNewObject(this.data); + if (this.form && this.form.$dirty) return !isEqual(newData, this.orgData); return !isEqual(newData, this.orgData); } diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 63a0b5415..7e846c609 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -103,8 +103,8 @@ export default { firstObservationTypeSelect: `${components.vnAutocomplete}[field="observation.observationTypeFk"]:nth-child(1) input`, firstObservationTypeSelectOptionOne: `${components.vnAutocomplete}[field="observation.observationTypeFk"] vn-drop-down ul > li:nth-child(1)`, firstObservationDescriptionInput: `vn-horizontal:nth-child(3) > vn-textfield[label="Description"] > div > input`, - secondObservationTypeSelect: `${components.vnAutocomplete}[field="observation.observationTypeFk"]:nth-child(2) input`, - secondObservationTypeSelectOptionTwo: `${components.vnAutocomplete}[field="observation.observationTypeFk"] vn-drop-down ul > li:nth-child(2)`, + secondObservationTypeSelect: `vn-horizontal:nth-child(4) > ${components.vnAutocomplete}[field="observation.observationTypeFk"] input`, + secondObservationTypeSelectOptionTwo: `vn-horizontal:nth-child(4) > ${components.vnAutocomplete}[field="observation.observationTypeFk"] vn-drop-down ul > li:nth-child(2)`, secondObservationDescriptionInput: `vn-horizontal:nth-child(4) > vn-textfield[label="Description"] > div > input`, thirdObservationTypeSelect: `${components.vnAutocomplete}[field="observation.observationTypeFk"]:nth-child(3) input`, thirdObservationTypeSelectOptionThree: `${components.vnAutocomplete}[field="observation.observationTypeFk"] vn-drop-down ul > li:nth-child(3)`, diff --git a/e2e/paths/client-module/06_add_address_notes.spec.js b/e2e/paths/client-module/06_add_address_notes.spec.js index 6a1c0a6c6..fb08cbf10 100644 --- a/e2e/paths/client-module/06_add_address_notes.spec.js +++ b/e2e/paths/client-module/06_add_address_notes.spec.js @@ -1,99 +1,99 @@ -// import selectors from '../../helpers/selectors.js'; -// import createNightmare from '../../helpers/helpers'; +import selectors from '../../helpers/selectors.js'; +import createNightmare from '../../helpers/helpers'; -// describe('Client', () => { -// describe('Add address notes path', () => { -// const nightmare = createNightmare(); +describe('Client', () => { + describe('Add address notes path', () => { + const nightmare = createNightmare(); -// beforeAll(() => { -// return nightmare -// .waitForLogin('developer'); -// }); + beforeAll(() => { + return nightmare + .waitForLogin('developer'); + }); -// it('should click on the Clients button of the top bar menu', () => { -// return nightmare -// .waitToClick(selectors.globalItems.applicationsMenuButton) -// .wait(selectors.globalItems.applicationsMenuVisible) -// .waitToClick(selectors.globalItems.clientsButton) -// .wait(selectors.clientsIndex.createClientButton) -// .parsedUrl() -// .then(url => { -// expect(url.hash).toEqual('#!/clients'); -// }); -// }); + it('should click on the Clients button of the top bar menu', () => { + return nightmare + .waitToClick(selectors.globalItems.applicationsMenuButton) + .wait(selectors.globalItems.applicationsMenuVisible) + .waitToClick(selectors.globalItems.clientsButton) + .wait(selectors.clientsIndex.createClientButton) + .parsedUrl() + .then(url => { + expect(url.hash).toEqual('#!/clients'); + }); + }); -// it('should search for the user Petter Parker', () => { -// return nightmare -// .wait(selectors.clientsIndex.searchResult) -// .type(selectors.clientsIndex.searchClientInput, 'Petter Parker') -// .click(selectors.clientsIndex.searchButton) -// .waitForNumberOfElements(selectors.clientsIndex.searchResult, 1) -// .countSearchResults(selectors.clientsIndex.searchResult) -// .then(result => { -// expect(result).toEqual(1); -// }); -// }); + it('should search for the user Petter Parker', () => { + return nightmare + .wait(selectors.clientsIndex.searchResult) + .type(selectors.clientsIndex.searchClientInput, 'Petter Parker') + .click(selectors.clientsIndex.searchButton) + .waitForNumberOfElements(selectors.clientsIndex.searchResult, 1) + .countSearchResults(selectors.clientsIndex.searchResult) + .then(result => { + expect(result).toEqual(1); + }); + }); -// it(`should click on the search result to access to the client addresses`, () => { -// return nightmare -// .waitForTextInElement(selectors.clientsIndex.searchResult, 'Petter Parker') -// .waitToClick(selectors.clientsIndex.searchResult) -// .waitToClick(selectors.clientAddresses.addressesButton) -// .waitForURL('addresses/list') -// .url() -// .then(url => { -// expect(url).toContain('addresses/list'); -// }); -// }); + it(`should click on the search result to access to the client addresses`, () => { + return nightmare + .waitForTextInElement(selectors.clientsIndex.searchResult, 'Petter Parker') + .waitToClick(selectors.clientsIndex.searchResult) + .waitToClick(selectors.clientAddresses.addressesButton) + .waitForURL('addresses/list') + .url() + .then(url => { + expect(url).toContain('addresses/list'); + }); + }); -// it(`should click on the edit icon of the default address`, () => { -// return nightmare -// .waitForTextInElement(selectors.clientAddresses.defaultAddress, '20 Ingram Street') -// .waitToClick(selectors.clientAddresses.firstEditButton) -// .waitForURL('/edit') -// .url() -// .then(result => { -// expect(result).toContain('/edit'); -// }); -// }); + it(`should click on the edit icon of the default address`, () => { + return nightmare + .waitForTextInElement(selectors.clientAddresses.defaultAddress, '20 Ingram Street') + .waitToClick(selectors.clientAddresses.firstEditButton) + .waitForURL('/edit') + .url() + .then(result => { + expect(result).toContain('/edit'); + }); + }); -// it('should not save a description without observation type', () => { -// return nightmare -// .waitToClick(selectors.clientAddresses.addObservationButton) -// .wait(selectors.clientAddresses.firstObservationDescriptionInput) -// .type(selectors.clientAddresses.firstObservationDescriptionInput, 'first description') -// .waitToClick(selectors.clientAddresses.saveButton) -// .waitForSnackbar() -// .then(result => { -// expect(result).toContain('Some fields are invalid'); -// }); -// }); + it('should not save a description without observation type', () => { + return nightmare + .waitToClick(selectors.clientAddresses.addObservationButton) + .wait(selectors.clientAddresses.firstObservationDescriptionInput) + .type(selectors.clientAddresses.firstObservationDescriptionInput, 'first description') + .waitToClick(selectors.clientAddresses.saveButton) + .waitForSnackbar() + .then(result => { + expect(result).toContain('No field can be blank'); + }); + }); -// it('should not save an observation type without description', () => { -// return nightmare -// .clearInput(selectors.clientAddresses.firstObservationDescriptionInput) -// .waitToClick(selectors.clientAddresses.firstObservationTypeSelect) -// .waitToClick(selectors.clientAddresses.firstObservationTypeSelectOptionOne) -// .waitToClick(selectors.clientAddresses.saveButton) -// .waitForSnackbar() -// .then(result => { -// expect(result).toContain('Some fields are invalid'); -// }); -// }); + it('should not save an observation type without description', () => { + return nightmare + .clearInput(selectors.clientAddresses.firstObservationDescriptionInput) + .waitToClick(selectors.clientAddresses.firstObservationTypeSelect) + .waitToClick(selectors.clientAddresses.firstObservationTypeSelectOptionOne) + .waitToClick(selectors.clientAddresses.saveButton) + .waitForSnackbar() + .then(result => { + expect(result).toContain('Some fields are invalid'); + }); + }); -// it('should create two new observations', () => { -// return nightmare -// .type(selectors.clientAddresses.firstObservationDescriptionInput, 'first description') -// .waitToClick(selectors.clientAddresses.addObservationButton) -// .waitToClick(selectors.clientAddresses.secondObservationTypeSelect) -// .waitToClick(selectors.clientAddresses.secondObservationTypeSelectOptionTwo) -// .type(selectors.clientAddresses.secondObservationDescriptionInput, 'second description') -// .waitToClick(selectors.clientAddresses.saveButton) -// .waitForSnackbar() -// .then(result => { -// expect(result).toContain('pepinillos saved!'); -// }); -// }); -// }); -// }); + it('should create two new observations', () => { + return nightmare + .type(selectors.clientAddresses.firstObservationDescriptionInput, 'first description') + .waitToClick(selectors.clientAddresses.addObservationButton) + .waitToClick(selectors.clientAddresses.secondObservationTypeSelect) + .waitToClick(selectors.clientAddresses.secondObservationTypeSelectOptionTwo) + .type(selectors.clientAddresses.secondObservationDescriptionInput, 'second description') + .waitToClick(selectors.clientAddresses.saveButton) + .waitForSnackbar() + .then(result => { + expect(result).toContain('Data saved!'); + }); + }); + }); +}); diff --git a/e2e/paths/ticket-module/05_create_new_tracking_state.spec.js b/e2e/paths/ticket-module/05_create_new_tracking_state.spec.js index 534c6a0b7..b0547be0e 100644 --- a/e2e/paths/ticket-module/05_create_new_tracking_state.spec.js +++ b/e2e/paths/ticket-module/05_create_new_tracking_state.spec.js @@ -73,7 +73,7 @@ describe('Ticket', () => { .click(selectors.createStateView.saveStateButton) .waitForSnackbar() .then(result => { - expect(result).toContain('El estado no puede estar en blanco'); // OLE! + expect(result).toContain('No changes to save'); }); });