Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correctly handle recipient information in edit mode #203

Merged
merged 5 commits into from
Feb 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/helpers/__mocks__/form.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = {
validateFormData: jest.fn(currentFormData => currentFormData.validation),
getInvoiceData: jest.fn(),
getInvoiceData: jest.fn(currentFormData => currentFormData),
};
59 changes: 59 additions & 0 deletions app/helpers/__tests__/form.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
validateDiscount,
validateTax,
validateNote,
setEditRecipient
} from '../form';

// Mocks
Expand Down Expand Up @@ -626,3 +627,61 @@ describe('validateNote', () => {
expect(validation).toEqual(true);
});
});

describe('set correct recipient information to use in edit mode', () => {
let allContacts;
beforeEach(() => {
allContacts = [
{
_id: uuidv4(),
fullname: faker.name.findName(),
email: faker.internet.email(),
company: faker.company.companyName(),
phone: faker.phone.phoneNumber(),
},
{
_id: uuidv4(),
fullname: faker.name.findName(),
email: faker.internet.email(),
company: faker.company.companyName(),
phone: faker.phone.phoneNumber(),
},
{
_id: uuidv4(),
fullname: faker.name.findName(),
email: faker.internet.email(),
company: faker.company.companyName(),
phone: faker.phone.phoneNumber(),
}
];
});

it('should return current contact if it exist', () => {
const currentContact = allContacts[1];
const editRecipient = setEditRecipient(allContacts, currentContact);
expect(editRecipient).toEqual({
newRecipient: false,
select: currentContact,
})
});

it('should create a new contact if the current contact does not exist', () => {
const currentContact = {
_id: 'random-string',
fullname: faker.name.findName(),
email: faker.internet.email(),
company: faker.company.companyName(),
phone: faker.phone.phoneNumber(),
};
const editRecipient = setEditRecipient(allContacts, currentContact);
expect(editRecipient).toEqual({
newRecipient: true,
new: {
fullname: currentContact.fullname,
email: currentContact.email,
company: currentContact.company,
phone: currentContact.phone,
},
})
});
});
45 changes: 35 additions & 10 deletions app/helpers/form.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const openDialog = require('../renderers/dialog');
import { isEmpty } from 'lodash';
import { isEmpty, pick, includes } from 'lodash';
import i18n from '../../i18n/i18n';
import uuidv4 from 'uuid/v4';

function validateFormData(formData) {
const {
Expand Down Expand Up @@ -42,8 +43,14 @@ function getInvoiceData(formData) {
const invoiceData = { rows };
// Set Recipient
if (recipient.newRecipient) {
invoiceData.recipient = recipient.new;
// Add id & created_at so the invoice records will remembers
invoiceData.recipient = Object.assign({}, recipient.new, {
_id: uuidv4(),
created_at: Date.now(),
});
} else {
// TODO
// Migh as well filter out _rev
invoiceData.recipient = recipient.select;
}
// Set Invoice DueDate
Expand Down Expand Up @@ -110,7 +117,7 @@ function validateRows(rows) {
openDialog({
type: 'warning',
title: i18n.t('dialog:validation:rows:emptyDescription:title'),
message: i18n.t('dialog:validation:rows:emptyDescription:message')
message: i18n.t('dialog:validation:rows:emptyDescription:message'),
});
validated = false;
break;
Expand All @@ -120,7 +127,7 @@ function validateRows(rows) {
openDialog({
type: 'warning',
title: i18n.t('dialog:validation:rows:priceZero:title'),
message: i18n.t('dialog:validation:rows:priceZero:message')
message: i18n.t('dialog:validation:rows:priceZero:message'),
});
validated = false;
break;
Expand All @@ -130,7 +137,7 @@ function validateRows(rows) {
openDialog({
type: 'warning',
title: i18n.t('dialog:validation:rows:qtyZero:title'),
message: i18n.t('dialog:validation:rows:qtyZero:message')
message: i18n.t('dialog:validation:rows:qtyZero:message'),
});
validated = false;
break;
Expand All @@ -146,7 +153,7 @@ function validateDueDate(isRequired, dueDate) {
openDialog({
type: 'warning',
title: i18n.t('dialog:validation:dueDate:title'),
message: i18n.t('dialog:validation:dueDate:message')
message: i18n.t('dialog:validation:dueDate:message'),
});
return false;
}
Expand All @@ -161,7 +168,7 @@ function validateCurrency(isRequired, currency) {
openDialog({
type: 'warning',
title: i18n.t('dialog:validation:currency:title'),
message: i18n.t('dialog:validation:currency:message')
message: i18n.t('dialog:validation:currency:message'),
});
return false;
}
Expand All @@ -177,7 +184,7 @@ function validateDiscount(isRequired, discount) {
openDialog({
type: 'warning',
title: i18n.t('dialog:validation:discount:title'),
message: i18n.t('dialog:validation:discount:message')
message: i18n.t('dialog:validation:discount:message'),
});
return false;
}
Expand All @@ -193,7 +200,7 @@ function validateTax(isRequired, tax) {
openDialog({
type: 'warning',
title: i18n.t('dialog:validation:tax:title'),
message: i18n.t('dialog:validation:tax:message')
message: i18n.t('dialog:validation:tax:message'),
});
return false;
}
Expand All @@ -209,7 +216,7 @@ function validateNote(isRequired, note) {
openDialog({
type: 'warning',
title: i18n.t('dialog:validation:note:title'),
message: i18n.t('dialog:validation:note:message')
message: i18n.t('dialog:validation:note:message'),
});
return false;
}
Expand All @@ -218,6 +225,23 @@ function validateNote(isRequired, note) {
return true;
}

// SET RECIPIENT INFORMATION IN EDIT MODE
function setEditRecipient(allContacts, currentContact) {
if (allContacts.length) {
const contactIDs = allContacts.map(contact => contact._id);
if (includes(contactIDs, currentContact._id)) {
return {
newRecipient: false,
select: currentContact,
};
}
}
return {
newRecipient: true,
new: pick(currentContact, ['fullname', 'company', 'phone', 'email']),
};
}

export {
getInvoiceData,
validateFormData,
Expand All @@ -228,4 +252,5 @@ export {
validateDiscount,
validateTax,
validateNote,
setEditRecipient,
};
6 changes: 1 addition & 5 deletions app/middlewares/ContactsMW.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,7 @@ const ContactsMW = ({ dispatch }) => next => action => {
}

case ACTION_TYPES.CONTACT_SAVE: {
const doc = Object.assign({}, action.payload, {
_id: uuidv4(),
created_at: Date.now(),
});
return saveDoc('contacts', doc)
return saveDoc('contacts', action.payload)
.then(newDocs => {
next({
type: ACTION_TYPES.CONTACT_SAVE,
Expand Down
2 changes: 1 addition & 1 deletion app/middlewares/FormMW.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const FormMW = ({ dispatch, getState }) => next => action => {
}
// Save Contact to DB if it's a new one
if (currentFormData.recipient.newRecipient) {
const newContactData = currentFormData.recipient.new;
const newContactData = currentInvoiceData.recipient;
dispatch(ContactsActions.saveContact(newContactData));
}
// Clear The Form
Expand Down
25 changes: 21 additions & 4 deletions app/middlewares/InvoicesMW.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,27 @@ const InvoicesMW = ({ dispatch }) => next => action => {

case ACTION_TYPES.INVOICE_EDIT: {
// Continue
next(action);
// Change Tab to Form
dispatch(UIActions.changeActiveTab('form'));
break;
return getAllDocs('contacts')
.then(allDocs => {
next(
Object.assign({}, action, {
payload: Object.assign({}, action.payload, {
contacts: allDocs
})
})
);
// Change Tab to Form
dispatch(UIActions.changeActiveTab('form'));
})
.catch(err => {
next({
type: ACTION_TYPES.UI_NOTIFICATION_NEW,
payload: {
type: 'warning',
message: err.message,
},
});
});
}

case ACTION_TYPES.INVOICE_UPDATE: {
Expand Down
15 changes: 4 additions & 11 deletions app/middlewares/__tests__/ContactsMW.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,7 @@ describe('Contacts Middleware', () => {
middleware(Actions.saveContact(newContact));
// Expect
expect(saveDoc).toHaveBeenCalled();
expect(saveDoc).toHaveBeenCalledWith(
'contacts',
Object.assign({}, newContact, {
_id: 'id-string',
created_at: 'now',
})
);
expect(saveDoc).toHaveBeenCalledWith('contacts', newContact);
});

it('should save records to DB', () => {
Expand All @@ -126,6 +120,8 @@ describe('Contacts Middleware', () => {
it('should call next and dispatch notification ', () => {
// Setup
const newContact = {
_id: 'id-string',
created_at: 'now',
fullname: faker.name.findName(),
email: faker.internet.email(),
};
Expand All @@ -140,10 +136,7 @@ describe('Contacts Middleware', () => {
Object.assign({}, action, {
payload: [
...mockData.contactsRecords,
Object.assign({}, newContact, {
_id: 'id-string',
created_at: 'now',
}),
newContact
],
})
);
Expand Down
9 changes: 4 additions & 5 deletions app/middlewares/__tests__/FormMW.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ describe('Form Middleware', () => {
getState = jest.fn(() => ({
form: {
validation: true,
recipient: { newRecipient: true },
recipient: {
newRecipient: true
},
settings: {
editMode: {
active: false,
Expand All @@ -26,11 +28,8 @@ describe('Form Middleware', () => {
},
}));
const middleware = FormMW({ dispatch, getState })(next);

// Action
const action = Actions.saveFormData();
middleware(action);

middleware(Actions.saveFormData());
// Expect
expect(getState.mock.calls.length).toBe(1);
// Save the Invoice, Save new contact & Clear the Form
Expand Down
27 changes: 17 additions & 10 deletions app/middlewares/__tests__/InvoicesMW.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -303,16 +303,23 @@ describe('Invoices Middleware', () => {
};
// Execute
const action = Actions.editInvoice(currentInvoice);
middleware(action);
// Call next
expect(next.mock.calls.length).toBe(1);
expect(next).toHaveBeenCalledWith(action);
// Dispatch change Tab action
expect(dispatch.mock.calls.length).toBe(1);
expect(dispatch).toHaveBeenCalledWith({
type: ACTION_TYPES.UI_TAB_CHANGE,
payload: 'form'
});
middleware(action).then(() => {
// Call next
expect(next.mock.calls.length).toBe(1);
expect(next).toHaveBeenCalledWith(
Object.assign({}, action, {
payload: Object.assign({}, action.payload, {
contacts: mockData.contactsRecords
})
})
);
// Dispatch change Tab action
expect(dispatch.mock.calls.length).toBe(1);
expect(dispatch).toHaveBeenCalledWith({
type: ACTION_TYPES.UI_TAB_CHANGE,
payload: 'form'
});
})
});
})

Expand Down
12 changes: 8 additions & 4 deletions app/reducers/FormReducer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import currencies from '../../libs/currencies.json';
// Retrive settings
const appConfig = require('electron').remote.require('electron-settings');
const invoiceSettings = appConfig.get('invoice');
// Helper
import { setEditRecipient } from '../helpers/form';

const initialState = {
recipient: {
Expand Down Expand Up @@ -114,13 +116,15 @@ const FormReducer = handleActions(
dueDate,
discount,
note,
contacts,
} = action.payload;
return Object.assign({}, state, {
// Populate data
recipient: Object.assign({}, state.recipient, {
newRecipient: false,
select: recipient,
}),
recipient: Object.assign(
{},
state.recipient,
setEditRecipient(contacts, recipient)
),
rows,
currency,
dueDate:
Expand Down
Loading