diff --git a/src/components/BookingBreakdown/BookingBreakdown.example.js b/src/components/BookingBreakdown/BookingBreakdown.example.js index 2491feef..b5adb477 100644 --- a/src/components/BookingBreakdown/BookingBreakdown.example.js +++ b/src/components/BookingBreakdown/BookingBreakdown.example.js @@ -22,7 +22,6 @@ const exampleTransaction = params => { createdAt: created, lastTransitionedAt: created, lastTransition: propTypes.TX_TRANSITION_PREAUTHORIZE, - state: propTypes.TX_STATE_PREAUTHORIZED, // payinTotal, payoutTotal, and lineItems required in params ...params, @@ -160,12 +159,69 @@ export const ProviderSaleSingleNight = { }, }; +export const ProviderSalePreauthorized = { + component: BookingBreakdown, + props: { + userRole: 'provider', + transaction: exampleTransaction({ + lastTransition: propTypes.TX_TRANSITION_PREAUTHORIZE, + payinTotal: new Money(4500, 'USD'), + payoutTotal: new Money(2500, 'USD'), + lineItems: [ + { + code: 'line-item/night', + quantity: new Decimal(1), + unitPrice: new Money(4500, 'USD'), + lineTotal: new Money(4500, 'USD'), + }, + { + code: 'line-item/provider-commission', + unitPrice: new Money(-2000, 'USD'), + lineTotal: new Money(-2000, 'USD'), + }, + ], + }), + booking: exampleBooking({ + start: new Date(Date.UTC(2017, 3, 14)), + end: new Date(Date.UTC(2017, 3, 15)), + }), + }, +}; + +export const ProviderSaleAccepted = { + component: BookingBreakdown, + props: { + userRole: 'provider', + transaction: exampleTransaction({ + lastTransition: propTypes.TX_TRANSITION_ACCEPT, + payinTotal: new Money(4500, 'USD'), + payoutTotal: new Money(2500, 'USD'), + lineItems: [ + { + code: 'line-item/night', + quantity: new Decimal(1), + unitPrice: new Money(4500, 'USD'), + lineTotal: new Money(4500, 'USD'), + }, + { + code: 'line-item/provider-commission', + unitPrice: new Money(-2000, 'USD'), + lineTotal: new Money(-2000, 'USD'), + }, + ], + }), + booking: exampleBooking({ + start: new Date(Date.UTC(2017, 3, 14)), + end: new Date(Date.UTC(2017, 3, 15)), + }), + }, +}; + export const ProviderSaleRejected = { component: BookingBreakdown, props: { userRole: 'provider', transaction: exampleTransaction({ - state: propTypes.TX_STATE_REJECTED, lastTransition: propTypes.TX_TRANSITION_REJECT, payinTotal: new Money(4500, 'USD'), payoutTotal: new Money(2500, 'USD'), @@ -190,12 +246,40 @@ export const ProviderSaleRejected = { }, }; +export const ProviderSaleAutoRejected = { + component: BookingBreakdown, + props: { + userRole: 'provider', + transaction: exampleTransaction({ + lastTransition: propTypes.TX_TRANSITION_AUTO_REJECT, + payinTotal: new Money(4500, 'USD'), + payoutTotal: new Money(2500, 'USD'), + lineItems: [ + { + code: 'line-item/night', + quantity: new Decimal(1), + unitPrice: new Money(4500, 'USD'), + lineTotal: new Money(4500, 'USD'), + }, + { + code: 'line-item/provider-commission', + unitPrice: new Money(-2000, 'USD'), + lineTotal: new Money(-2000, 'USD'), + }, + ], + }), + booking: exampleBooking({ + start: new Date(Date.UTC(2017, 3, 14)), + end: new Date(Date.UTC(2017, 3, 15)), + }), + }, +}; + export const ProviderSaleDelivered = { component: BookingBreakdown, props: { userRole: 'provider', transaction: exampleTransaction({ - state: propTypes.TX_STATE_DELIVERED, lastTransition: propTypes.TX_TRANSITION_MARK_DELIVERED, payinTotal: new Money(4500, 'USD'), payoutTotal: new Money(2500, 'USD'), diff --git a/src/components/BookingBreakdown/BookingBreakdown.js b/src/components/BookingBreakdown/BookingBreakdown.js index 9a83bb90..48d07130 100644 --- a/src/components/BookingBreakdown/BookingBreakdown.js +++ b/src/components/BookingBreakdown/BookingBreakdown.js @@ -111,9 +111,9 @@ export const BookingBreakdownComponent = props => { } let providerTotalMessageId = 'BookingBreakdown.providerTotalDefault'; - if (transaction.attributes.state === propTypes.TX_STATE_DELIVERED) { + if (propTypes.txIsDelivered(transaction)) { providerTotalMessageId = 'BookingBreakdown.providerTotalDelivered'; - } else if (transaction.attributes.state === propTypes.TX_STATE_REJECTED) { + } else if (propTypes.txIsRejectedOrAutorejected(transaction)) { providerTotalMessageId = 'BookingBreakdown.providerTotalRejected'; } diff --git a/src/components/BookingBreakdown/BookingBreakdown.test.js b/src/components/BookingBreakdown/BookingBreakdown.test.js index 0985e574..377be544 100644 --- a/src/components/BookingBreakdown/BookingBreakdown.test.js +++ b/src/components/BookingBreakdown/BookingBreakdown.test.js @@ -1,6 +1,6 @@ import React from 'react'; import Decimal from 'decimal.js'; -import { fakeIntl } from '../../util/test-data'; +import { fakeIntl, createBooking } from '../../util/test-data'; import { renderDeep } from '../../util/test-helpers'; import { types } from '../../util/sdkLoader'; import * as propTypes from '../../util/propTypes'; @@ -8,14 +8,6 @@ import { BookingBreakdownComponent } from './BookingBreakdown'; const { UUID, Money } = types; -const exampleBooking = attributes => { - return { - id: new UUID('example-booking'), - type: 'booking', - attributes, - }; -}; - const exampleTransaction = params => { const created = new Date(Date.UTC(2017, 1, 1)); return { @@ -25,7 +17,6 @@ const exampleTransaction = params => { createdAt: created, lastTransitionedAt: created, lastTransition: propTypes.TX_TRANSITION_PREAUTHORIZE, - state: propTypes.TX_STATE_PREAUTHORIZED, // payinTotal, payoutTotal, and lineItems required in params ...params, @@ -50,7 +41,7 @@ describe('BookingBreakdown', () => { }, ], })} - booking={exampleBooking({ + booking={createBooking('example-booking', { start: new Date(Date.UTC(2017, 3, 14)), end: new Date(Date.UTC(2017, 3, 16)), })} @@ -76,7 +67,7 @@ describe('BookingBreakdown', () => { }, ], })} - booking={exampleBooking({ + booking={createBooking('example-booking', { start: new Date(Date.UTC(2017, 3, 14)), end: new Date(Date.UTC(2017, 3, 16)), })} @@ -107,7 +98,7 @@ describe('BookingBreakdown', () => { }, ], })} - booking={exampleBooking({ + booking={createBooking('example-booking', { start: new Date(Date.UTC(2017, 3, 14)), end: new Date(Date.UTC(2017, 3, 16)), })} diff --git a/src/components/OrderDetailsPanel/OrderDetailsPanel.js b/src/components/OrderDetailsPanel/OrderDetailsPanel.js index 129afb1d..3602ab2a 100644 --- a/src/components/OrderDetailsPanel/OrderDetailsPanel.js +++ b/src/components/OrderDetailsPanel/OrderDetailsPanel.js @@ -21,92 +21,89 @@ const breakdown = transaction => { : null; }; -const orderTitle = (orderState, listingLink, customerName, lastTransition) => { - const rejectedTranslationId = lastTransition === propTypes.TX_TRANSITION_AUTO_REJECT - ? 'OrderDetailsPanel.orderAutoRejectedTitle' - : 'OrderDetailsPanel.orderRejectedTitle'; - - switch (orderState) { - case propTypes.TX_STATE_PREAUTHORIZED: - return ( - - - - +const orderTitle = (transaction, listingLink, customerName) => { + if (propTypes.txIsPreauthorized(transaction)) { + return ( + + - ); - case propTypes.TX_STATE_ACCEPTED: - return ( - - - - - + + + ); + } else if (propTypes.txIsAccepted(transaction)) { + return ( + + + - ); - case propTypes.TX_STATE_REJECTED: - return ; - case propTypes.TX_STATE_DELIVERED: - return ( - - ); - default: - return null; + + + ); + } else if (propTypes.txIsRejected(transaction)) { + return ; + } else if (propTypes.txIsAutorejected(transaction)) { + return ( + + ); + } else if (propTypes.txIsDelivered(transaction)) { + return ; + } else { + return null; } }; -const orderMessage = ( - orderState, - listingTitle, - providerName, - lastTransitionedAt, - lastTransition -) => { +const orderMessage = (transaction, listingTitle, providerName) => { const transitionDate = ( - + ); - - const rejectedTranslationId = lastTransition === propTypes.TX_TRANSITION_AUTO_REJECT - ? 'OrderDetailsPanel.orderAutoRejectedStatus' - : 'OrderDetailsPanel.orderRejectedStatus'; - - switch (orderState) { - case propTypes.TX_STATE_PREAUTHORIZED: - return ( - - ); - case propTypes.TX_STATE_ACCEPTED: - return ( - - ); - case propTypes.TX_STATE_REJECTED: - return ( - - ); - case propTypes.TX_STATE_DELIVERED: - return ( - - ); - default: - return null; + if (propTypes.txIsPreauthorized(transaction)) { + return ( + + ); + } else if (propTypes.txIsAccepted(transaction)) { + return ( + + ); + } else if (propTypes.txIsRejected(transaction)) { + return ( + + ); + } else if (propTypes.txIsAutorejected(transaction)) { + return ( + + ); + } else if (propTypes.txIsDelivered(transaction)) { + return ( + + ); + } else { + return null; } }; @@ -140,9 +137,6 @@ export const OrderDetailsPanelComponent = props => { const authorDisplayName = userDisplayName(currentProvider, bannedUserDisplayName); const customerDisplayName = userDisplayName(currentCustomer, bannedUserDisplayName); - const transactionState = currentTransaction.attributes.state; - const lastTransitionedAt = currentTransaction.attributes.lastTransitionedAt; - const lastTransition = currentTransaction.attributes.lastTransitione; let listingLink = null; @@ -163,21 +157,10 @@ export const OrderDetailsPanelComponent = props => { : currentListing.attributes.title; const bookingInfo = breakdown(currentTransaction); - const orderHeading = orderTitle( - transactionState, - listingLink, - customerDisplayName, - lastTransition - ); + const orderHeading = orderTitle(currentTransaction, listingLink, customerDisplayName); const message = listingDeleted ? orderMessageDeletedListing - : orderMessage( - transactionState, - listingLink, - authorDisplayName, - lastTransitionedAt, - lastTransition - ); + : orderMessage(currentTransaction, listingLink, authorDisplayName); const firstImage = currentListing.images && currentListing.images.length > 0 ? currentListing.images[0] @@ -255,7 +238,6 @@ export const OrderDetailsPanelComponent = props => { OrderDetailsPanelComponent.defaultProps = { rootClassName: null, className: null, - lastTransition: null, }; const { string } = PropTypes; diff --git a/src/components/OrderDetailsPanel/OrderDetailsPanel.test.js b/src/components/OrderDetailsPanel/OrderDetailsPanel.test.js index 5fbbac92..9d71d71c 100644 --- a/src/components/OrderDetailsPanel/OrderDetailsPanel.test.js +++ b/src/components/OrderDetailsPanel/OrderDetailsPanel.test.js @@ -4,32 +4,89 @@ import { types } from '../../util/sdkLoader'; import { createBooking, createListing, createUser, createTransaction } from '../../util/test-data'; import { renderShallow } from '../../util/test-helpers'; import { fakeIntl } from '../../util/test-data'; +import * as propTypes from '../../util/propTypes'; import { BookingBreakdown } from '../../components'; import { OrderDetailsPanelComponent } from './OrderDetailsPanel.js'; +const { Money } = types; + +const baseTxAttrs = { + total: new Money(16500, 'USD'), + booking: createBooking('booking1', { + start: new Date(Date.UTC(2017, 5, 10)), + end: new Date(Date.UTC(2017, 5, 13)), + }), + listing: createListing('listing1'), + provider: createUser('provider'), + customer: createUser('customer'), +}; + +const txPreauthorized = createTransaction({ + id: 'order-preauthorized', + lastTransition: propTypes.TX_TRANSITION_PREAUTHORIZE, + ...baseTxAttrs, +}); + +const txAccepted = createTransaction({ + id: 'order-accepted', + lastTransition: propTypes.TX_TRANSITION_ACCEPT, + ...baseTxAttrs, +}); + +const txRejected = createTransaction({ + id: 'order-rejected', + lastTransition: propTypes.TX_TRANSITION_REJECT, + ...baseTxAttrs, +}); + +const txAutoRejected = createTransaction({ + id: 'order-autorejected', + lastTransition: propTypes.TX_TRANSITION_AUTO_REJECT, + ...baseTxAttrs, +}); + +const txDelivered = createTransaction({ + id: 'order-delivered', + lastTransition: propTypes.TX_TRANSITION_MARK_DELIVERED, + ...baseTxAttrs, +}); + describe('OrderDetailsPanel', () => { - it('matches snapshot', () => { - const { Money } = types; - const tx = createTransaction({ - id: 'order-tx', - state: 'state/preauthorized', - total: new Money(16500, 'USD'), - booking: createBooking('booking1', { - start: new Date(Date.UTC(2017, 5, 10)), - end: new Date(Date.UTC(2017, 5, 13)), - }), - listing: createListing('listing1'), - provider: createUser('provider'), - customer: createUser('customer'), - }); - const tree = renderShallow(); + it('preauthorized matches snapshot', () => { + const tree = renderShallow( + + ); + expect(tree).toMatchSnapshot(); + }); + it('accepted matches snapshot', () => { + const tree = renderShallow( + + ); + expect(tree).toMatchSnapshot(); + }); + it('rejected matches snapshot', () => { + const tree = renderShallow( + + ); + expect(tree).toMatchSnapshot(); + }); + it('autorejected matches snapshot', () => { + const tree = renderShallow( + + ); + expect(tree).toMatchSnapshot(); + }); + it('delivered matches snapshot', () => { + const tree = renderShallow( + + ); expect(tree).toMatchSnapshot(); }); it('renders correct total price', () => { const { Money } = types; const tx = createTransaction({ id: 'order-tx', - state: 'state/preauthorized', + lastTransition: propTypes.TX_TRANSITION_PREAUTHORIZE, total: new Money(16500, 'USD'), booking: createBooking('booking1', { start: new Date(Date.UTC(2017, 5, 10)), diff --git a/src/components/OrderDetailsPanel/__snapshots__/OrderDetailsPanel.test.js.snap b/src/components/OrderDetailsPanel/__snapshots__/OrderDetailsPanel.test.js.snap index bd276447..de84932a 100644 --- a/src/components/OrderDetailsPanel/__snapshots__/OrderDetailsPanel.test.js.snap +++ b/src/components/OrderDetailsPanel/__snapshots__/OrderDetailsPanel.test.js.snap @@ -1,4 +1,1176 @@ -exports[`OrderDetailsPanel matches snapshot 1`] = ` +exports[`OrderDetailsPanel accepted matches snapshot 1`] = ` +
+
+
+ +
+
+ +
+
+

+ + + + + + listing1 title + , + } + } /> + +

+
+ + + , + } + } /> +
+
+
+
+

+ +

+ +
+
+
+ +
+
+ +
+
+

+ listing1 title +

+

+ +

+
+

+ +

+ +
+
+
+
+`; + +exports[`OrderDetailsPanel autorejected matches snapshot 1`] = ` +
+
+
+ +
+
+ +
+
+

+ + listing1 title + , + } + } /> +

+
+ + + , + } + } /> +
+
+
+
+

+ +

+ +
+
+
+ +
+
+ +
+
+

+ listing1 title +

+

+ +

+
+

+ +

+ +
+
+
+
+`; + +exports[`OrderDetailsPanel delivered matches snapshot 1`] = ` +
+
+
+ +
+
+ +
+
+

+ + listing1 title + , + } + } /> +

+
+ + + , + } + } /> +
+
+
+
+

+ +

+ +
+
+
+ +
+
+ +
+
+

+ listing1 title +

+

+ +

+
+

+ +

+ +
+
+
+
+`; + +exports[`OrderDetailsPanel preauthorized matches snapshot 1`] = `
@@ -141,7 +1313,6 @@ exports[`OrderDetailsPanel matches snapshot 1`] = ` "amount": 16400, "currency": "USD", }, - "state": "state/preauthorized", }, "booking": Object { "attributes": Object { @@ -167,7 +1338,7 @@ exports[`OrderDetailsPanel matches snapshot 1`] = ` "type": "user", }, "id": UUID { - "uuid": "order-tx", + "uuid": "order-preauthorized", }, "listing": Object { "attributes": Object { @@ -319,7 +1490,6 @@ exports[`OrderDetailsPanel matches snapshot 1`] = ` "amount": 16400, "currency": "USD", }, - "state": "state/preauthorized", }, "booking": Object { "attributes": Object { @@ -345,7 +1515,394 @@ exports[`OrderDetailsPanel matches snapshot 1`] = ` "type": "user", }, "id": UUID { - "uuid": "order-tx", + "uuid": "order-preauthorized", + }, + "listing": Object { + "attributes": Object { + "address": "listing1 address", + "closed": false, + "deleted": false, + "description": "listing1 description", + "geolocation": LatLng { + "lat": 40, + "lng": 60, + }, + "price": Money { + "amount": 5500, + "currency": "USD", + }, + "title": "listing1 title", + }, + "id": UUID { + "uuid": "listing1", + }, + "type": "listing", + }, + "provider": Object { + "attributes": Object { + "banned": false, + "profile": Object { + "abbreviatedName": "provider abbreviated name", + "displayName": "provider display name", + }, + }, + "id": UUID { + "uuid": "provider", + }, + "type": "user", + }, + "type": "transaction", + } + } + userRole="customer" /> +
+
+ + +`; + +exports[`OrderDetailsPanel rejected matches snapshot 1`] = ` +
+
+
+ +
+
+ +
+
+

+ + listing1 title + , + } + } /> +

+
+ + + , + } + } /> +
+
+
+
+

+ +

+ +
+
+
+ +
+
+ +
+
+

+ listing1 title +

+

+ +

+
+

+ +

+ { : null; }; -const saleTitle = (saleState, listingLink, customerName) => { - switch (saleState) { - case propTypes.TX_STATE_PREAUTHORIZED: - return ( - - ); - case propTypes.TX_STATE_ACCEPTED: - return ( - - ); - case propTypes.TX_STATE_REJECTED: - return ( - - ); - case propTypes.TX_STATE_DELIVERED: - return ( - - ); - default: - return null; +const saleTitle = (transaction, listingLink, customerName) => { + if (propTypes.txIsPreauthorized(transaction)) { + return ( + + ); + } else if (propTypes.txIsAccepted(transaction)) { + return ( + + ); + } else if (propTypes.txIsRejected(transaction)) { + return ( + + ); + } else if (propTypes.txIsAutorejected(transaction)) { + return ( + + ); + } else if (propTypes.txIsDelivered(transaction)) { + return ( + + ); + } else { + return null; } }; -const saleMessage = (saleState, customerName, lastTransitionedAt, lastTransition) => { +const saleMessage = (transaction, customerName) => { const formattedDate = ( ); - const rejectedStatusTranslationId = lastTransition === propTypes.TX_TRANSITION_AUTO_REJECT - ? 'SaleDetailsPanel.saleAutoRejectedStatus' - : 'SaleDetailsPanel.saleRejectedStatus'; - switch (saleState) { - case propTypes.TX_STATE_PREAUTHORIZED: - return ( - - ); - case propTypes.TX_STATE_ACCEPTED: { - return ( - - ); - } - case propTypes.TX_STATE_REJECTED: - return ; - case propTypes.TX_STATE_DELIVERED: - return ( - - ); - default: - return null; + if (propTypes.txIsPreauthorized(transaction)) { + return ; + } else if (propTypes.txIsAccepted(transaction)) { + return ; + } else if (propTypes.txIsRejected(transaction)) { + return ; + } else if (propTypes.txIsAutorejected(transaction)) { + return ( + + ); + } else if (propTypes.txIsDelivered(transaction)) { + return ( + + ); + } else { + return null; } }; @@ -123,9 +124,6 @@ export const SaleDetailsPanelComponent = props => { }); const customerDisplayName = userDisplayName(currentCustomer, bannedUserDisplayName); - const transactionState = currentTransaction.attributes.state; - const lastTransitionedAt = currentTransaction.attributes.lastTransitionedAt; - const lastTransition = currentTransaction.attributes.lastTransition; let listingLink = null; @@ -141,21 +139,19 @@ export const SaleDetailsPanelComponent = props => { const bookingInfo = breakdown(currentTransaction); - const title = saleTitle(transactionState, listingLink, customerDisplayName, lastTransition); + const title = saleTitle(currentTransaction, listingLink, customerDisplayName); const message = isCustomerBanned ? intl.formatMessage({ id: 'SaleDetailsPanel.customerBannedStatus', }) - : saleMessage(transactionState, customerDisplayName, lastTransitionedAt, lastTransition); + : saleMessage(currentTransaction, customerDisplayName); const listingTitle = currentListing.attributes.title; const firstImage = currentListing.images && currentListing.images.length > 0 ? currentListing.images[0] : null; - const isPreauthorizedState = currentTransaction.attributes.state === - propTypes.TX_STATE_PREAUTHORIZED; - const canShowButtons = isPreauthorizedState && !isCustomerBanned; + const canShowButtons = propTypes.txIsPreauthorized(currentTransaction) && !isCustomerBanned; const buttonsDisabled = acceptInProgress || rejectInProgress; const acceptErrorMessage = acceptSaleError @@ -260,7 +256,6 @@ export const SaleDetailsPanelComponent = props => { SaleDetailsPanelComponent.defaultProps = { rootClassName: null, className: null, - lastTransition: null, acceptSaleError: null, rejectSaleError: null, }; diff --git a/src/components/SaleDetailsPanel/SaleDetailsPanel.test.js b/src/components/SaleDetailsPanel/SaleDetailsPanel.test.js index 0bd976a0..a286d976 100644 --- a/src/components/SaleDetailsPanel/SaleDetailsPanel.test.js +++ b/src/components/SaleDetailsPanel/SaleDetailsPanel.test.js @@ -4,29 +4,107 @@ import { types } from '../../util/sdkLoader'; import { createTransaction, createBooking, createListing, createUser } from '../../util/test-data'; import { renderShallow } from '../../util/test-helpers'; import { fakeIntl } from '../../util/test-data'; +import * as propTypes from '../../util/propTypes'; import { BookingBreakdown } from '../../components'; import { SaleDetailsPanelComponent } from './SaleDetailsPanel.js'; const noop = () => null; +const { Money } = types; + +const baseTxAttrs = { + total: new Money(16500, 'USD'), + commission: new Money(1000, 'USD'), + booking: createBooking('booking1', { + start: new Date(Date.UTC(2017, 5, 10)), + end: new Date(Date.UTC(2017, 5, 13)), + }), + listing: createListing('listing1'), + customer: createUser('customer1'), + lastTransitionedAt: new Date(Date.UTC(2017, 5, 10)), +}; +const txPreauthorized = createTransaction({ + id: 'sale-preauthorized', + lastTransition: propTypes.TX_TRANSITION_PREAUTHORIZE, + ...baseTxAttrs, +}); + +const txAccepted = createTransaction({ + id: 'sale-accepted', + lastTransition: propTypes.TX_TRANSITION_ACCEPT, + ...baseTxAttrs, +}); + +const txRejected = createTransaction({ + id: 'sale-rejected', + lastTransition: propTypes.TX_TRANSITION_REJECT, + ...baseTxAttrs, +}); + +const txAutoRejected = createTransaction({ + id: 'sale-autorejected', + lastTransition: propTypes.TX_TRANSITION_AUTO_REJECT, + ...baseTxAttrs, +}); + +const txDelivered = createTransaction({ + id: 'sale-delivered', + lastTransition: propTypes.TX_TRANSITION_MARK_DELIVERED, + ...baseTxAttrs, +}); + describe('SaleDetailsPanel', () => { - it('matches snapshot', () => { - const { Money } = types; - const transaction = createTransaction({ - id: 'sale-tx', - state: 'state/preauthorized', - total: new Money(16500, 'USD'), - commission: new Money(1000, 'USD'), - booking: createBooking('booking1', { - start: new Date(Date.UTC(2017, 5, 10)), - end: new Date(Date.UTC(2017, 5, 13)), - }), - listing: createListing('listing1'), - customer: createUser('customer1'), - lastTransitionedAt: new Date(Date.UTC(2017, 5, 10)), - }); + it('preauthorized matches snapshot', () => { const props = { - transaction, + transaction: txPreauthorized, + onAcceptSale: noop, + onRejectSale: noop, + acceptInProgress: false, + rejectInProgress: false, + intl: fakeIntl, + }; + const tree = renderShallow(); + expect(tree).toMatchSnapshot(); + }); + it('accepted matches snapshot', () => { + const props = { + transaction: txAccepted, + onAcceptSale: noop, + onRejectSale: noop, + acceptInProgress: false, + rejectInProgress: false, + intl: fakeIntl, + }; + const tree = renderShallow(); + expect(tree).toMatchSnapshot(); + }); + it('rejected matches snapshot', () => { + const props = { + transaction: txRejected, + onAcceptSale: noop, + onRejectSale: noop, + acceptInProgress: false, + rejectInProgress: false, + intl: fakeIntl, + }; + const tree = renderShallow(); + expect(tree).toMatchSnapshot(); + }); + it('autorejected matches snapshot', () => { + const props = { + transaction: txAutoRejected, + onAcceptSale: noop, + onRejectSale: noop, + acceptInProgress: false, + rejectInProgress: false, + intl: fakeIntl, + }; + const tree = renderShallow(); + expect(tree).toMatchSnapshot(); + }); + it('delivered matches snapshot', () => { + const props = { + transaction: txDelivered, onAcceptSale: noop, onRejectSale: noop, acceptInProgress: false, @@ -37,10 +115,9 @@ describe('SaleDetailsPanel', () => { expect(tree).toMatchSnapshot(); }); it('renders correct total price', () => { - const { Money } = types; const transaction = createTransaction({ id: 'sale-tx', - state: 'state/preauthorized', + lastTransition: propTypes.TX_TRANSITION_PREAUTHORIZE, total: new Money(16500, 'USD'), commission: new Money(1000, 'USD'), booking: createBooking('booking1', { diff --git a/src/components/SaleDetailsPanel/__snapshots__/SaleDetailsPanel.test.js.snap b/src/components/SaleDetailsPanel/__snapshots__/SaleDetailsPanel.test.js.snap index dd3f8af3..0071a5d9 100644 --- a/src/components/SaleDetailsPanel/__snapshots__/SaleDetailsPanel.test.js.snap +++ b/src/components/SaleDetailsPanel/__snapshots__/SaleDetailsPanel.test.js.snap @@ -1,4 +1,1054 @@ -exports[`SaleDetailsPanel matches snapshot 1`] = ` +exports[`SaleDetailsPanel accepted matches snapshot 1`] = ` +
+
+
+ +
+
+ +
+
+
+ +
+

+ + listing1 title + , + } + } /> +

+

+ + + , + } + } /> +

+
+
+
+

+ +

+ +
+
+
+ +
+

+ +

+
+ +
+
+
+
+`; + +exports[`SaleDetailsPanel autorejected matches snapshot 1`] = ` +
+
+
+ +
+
+ +
+
+
+ +
+

+ + listing1 title + , + } + } /> +

+

+ + + , + } + } /> +

+
+
+
+

+ +

+ +
+
+
+ +
+

+ +

+
+ +
+
+
+
+`; + +exports[`SaleDetailsPanel delivered matches snapshot 1`] = ` +
+
+
+ +
+
+ +
+
+
+ +
+

+ + listing1 title + , + } + } /> +

+

+ + + , + } + } /> +

+
+
+
+

+ +

+ +
+
+
+ +
+

+ +

+
+ +
+
+
+
+`; + +exports[`SaleDetailsPanel preauthorized matches snapshot 1`] = `
@@ -167,7 +1217,6 @@ exports[`SaleDetailsPanel matches snapshot 1`] = ` "amount": 15500, "currency": "USD", }, - "state": "state/preauthorized", }, "booking": Object { "attributes": Object { @@ -193,7 +1242,7 @@ exports[`SaleDetailsPanel matches snapshot 1`] = ` "type": "user", }, "id": UUID { - "uuid": "sale-tx", + "uuid": "sale-preauthorized", }, "listing": Object { "attributes": Object { @@ -302,7 +1351,6 @@ exports[`SaleDetailsPanel matches snapshot 1`] = ` "amount": 15500, "currency": "USD", }, - "state": "state/preauthorized", }, "booking": Object { "attributes": Object { @@ -328,7 +1376,357 @@ exports[`SaleDetailsPanel matches snapshot 1`] = ` "type": "user", }, "id": UUID { - "uuid": "sale-tx", + "uuid": "sale-preauthorized", + }, + "listing": Object { + "attributes": Object { + "address": "listing1 address", + "closed": false, + "deleted": false, + "description": "listing1 description", + "geolocation": LatLng { + "lat": 40, + "lng": 60, + }, + "price": Money { + "amount": 5500, + "currency": "USD", + }, + "title": "listing1 title", + }, + "id": UUID { + "uuid": "listing1", + }, + "type": "listing", + }, + "provider": null, + "type": "transaction", + } + } + userRole="provider" /> +
+
+
+
+`; + +exports[`SaleDetailsPanel rejected matches snapshot 1`] = ` +
+
+
+ +
+
+ +
+
+
+ +
+

+ + listing1 title + , + } + } /> +

+

+ + + , + } + } /> +

+
+
+
+

+ +

+ +
+
+
+ +
+

+ +

+
+ { createdAt: now, lastTransitionedAt: now, lastTransition: propTypes.TX_TRANSITION_PREAUTHORIZE, - state: propTypes.TX_STATE_PREAUTHORIZED, payinTotal: totalPrice, payoutTotal: totalPrice, lineItems: [ diff --git a/src/containers/BookingDatesForm/BookingDatesForm.test.js b/src/containers/BookingDatesForm/BookingDatesForm.test.js index c9b2755c..2095f898 100644 --- a/src/containers/BookingDatesForm/BookingDatesForm.test.js +++ b/src/containers/BookingDatesForm/BookingDatesForm.test.js @@ -50,7 +50,6 @@ describe('BookingDatesForm', () => { expect(booking.attributes.start).toEqual(startDate); expect(booking.attributes.end).toEqual(endDate); expect(transaction.attributes.lastTransition).toEqual(propTypes.TX_TRANSITION_PREAUTHORIZE); - expect(transaction.attributes.state).toEqual(propTypes.TX_STATE_PREAUTHORIZED); expect(transaction.attributes.payinTotal).toEqual(new Money(2198, 'USD')); expect(transaction.attributes.payoutTotal).toEqual(new Money(2198, 'USD')); expect(transaction.attributes.lineItems).toEqual([ diff --git a/src/containers/InboxPage/InboxPage.js b/src/containers/InboxPage/InboxPage.js index 5438681a..38e77ba5 100644 --- a/src/containers/InboxPage/InboxPage.js +++ b/src/containers/InboxPage/InboxPage.js @@ -39,8 +39,7 @@ const formatDate = (intl, date) => { // Translated name of the state of the given transaction const txState = (intl, tx, isOrder) => { - const { attributes: { state } } = tx; - if (state === propTypes.TX_STATE_ACCEPTED) { + if (propTypes.txIsAccepted(tx)) { return { nameClassName: css.nameAccepted, bookingClassName: css.bookingAccepted, @@ -50,7 +49,7 @@ const txState = (intl, tx, isOrder) => { id: 'InboxPage.stateAccepted', }), }; - } else if (state === propTypes.TX_STATE_REJECTED) { + } else if (propTypes.txIsRejectedOrAutorejected(tx)) { return { nameClassName: css.nameDeclined, bookingClassName: css.bookingDeclined, @@ -60,7 +59,7 @@ const txState = (intl, tx, isOrder) => { id: 'InboxPage.stateDeclined', }), }; - } else if (state === propTypes.TX_STATE_DELIVERED) { + } else if (propTypes.txIsDelivered(tx)) { return { nameClassName: css.nameDelivered, bookingClassName: css.bookingDelivered, @@ -101,7 +100,7 @@ export const InboxItem = props => { const otherUserDisplayName = userDisplayName(otherUser, bannedUserDisplayName); const stateData = txState(intl, tx, isOrder); - const isSaleNotification = !isOrder && tx.attributes.state === propTypes.TX_STATE_PREAUTHORIZED; + const isSaleNotification = !isOrder && propTypes.txIsPreauthorized(tx); const rowNotificationDot = isSaleNotification ?
: null; const lastTransitionedAt = formatDate(intl, tx.attributes.lastTransitionedAt); const bookingStart = formatDate(intl, booking.attributes.start); diff --git a/src/containers/InboxPage/InboxPage.test.js b/src/containers/InboxPage/InboxPage.test.js index 3fe348ea..a19fc4fb 100644 --- a/src/containers/InboxPage/InboxPage.test.js +++ b/src/containers/InboxPage/InboxPage.test.js @@ -5,6 +5,7 @@ import { fakeIntl, createUser, createTransaction, createBooking } from '../../ut import { InboxPageComponent, InboxItem } from './InboxPage'; import routesConfiguration from '../../routesConfiguration'; import { flattenRoutes } from '../../util/routes'; +import { TX_TRANSITION_PREAUTHORIZE } from '../../util/propTypes'; const noop = () => null; @@ -39,14 +40,14 @@ describe('InboxPage', () => { transactions: [ createTransaction({ id: 'order-1', - state: 'state/preauthorized', + lastTransition: TX_TRANSITION_PREAUTHORIZE, provider, lastTransitionedAt: new Date(Date.UTC(2017, 0, 15)), booking: booking1, }), createTransaction({ id: 'order-2', - state: 'state/preauthorized', + lastTransition: TX_TRANSITION_PREAUTHORIZE, provider, lastTransitionedAt: new Date(Date.UTC(2016, 0, 15)), booking: booking2, @@ -86,14 +87,14 @@ describe('InboxPage', () => { transactions: [ createTransaction({ id: 'sale-1', - state: 'state/preauthorized', + lastTransition: TX_TRANSITION_PREAUTHORIZE, customer, lastTransitionedAt: new Date(Date.UTC(2017, 0, 15)), booking: booking1, }), createTransaction({ id: 'sale-2', - state: 'state/preauthorized', + lastTransition: TX_TRANSITION_PREAUTHORIZE, customer, lastTransitionedAt: new Date(Date.UTC(2016, 0, 15)), booking: booking2, diff --git a/src/containers/InboxPage/__snapshots__/InboxPage.test.js.snap b/src/containers/InboxPage/__snapshots__/InboxPage.test.js.snap index c8c6cfa2..ec68e807 100644 --- a/src/containers/InboxPage/__snapshots__/InboxPage.test.js.snap +++ b/src/containers/InboxPage/__snapshots__/InboxPage.test.js.snap @@ -127,7 +127,6 @@ exports[`InboxPage matches snapshot 1`] = ` "amount": 900, "currency": "USD", }, - "state": "state/preauthorized", }, "booking": Object { "attributes": Object { @@ -215,7 +214,6 @@ exports[`InboxPage matches snapshot 1`] = ` "amount": 900, "currency": "USD", }, - "state": "state/preauthorized", }, "booking": Object { "attributes": Object { @@ -437,7 +435,6 @@ exports[`InboxPage matches snapshot 3`] = ` "amount": 900, "currency": "USD", }, - "state": "state/preauthorized", }, "booking": Object { "attributes": Object { @@ -525,7 +522,6 @@ exports[`InboxPage matches snapshot 3`] = ` "amount": 900, "currency": "USD", }, - "state": "state/preauthorized", }, "booking": Object { "attributes": Object { diff --git a/src/containers/OrderPage/OrderPage.test.js b/src/containers/OrderPage/OrderPage.test.js index 0b34c99e..9525e239 100644 --- a/src/containers/OrderPage/OrderPage.test.js +++ b/src/containers/OrderPage/OrderPage.test.js @@ -8,6 +8,7 @@ import { fakeIntl, } from '../../util/test-data'; import { renderShallow } from '../../util/test-helpers'; +import { TX_TRANSITION_PREAUTHORIZE } from '../../util/propTypes'; import { OrderPageComponent } from './OrderPage'; const noop = () => null; @@ -17,7 +18,7 @@ describe('OrderPage', () => { const txId = 'tx-order-1'; const transaction = createTransaction({ id: txId, - state: 'state/preauthorized', + lastTransition: TX_TRANSITION_PREAUTHORIZE, booking: createBooking('booking1', { start: new Date(Date.UTC(2017, 5, 10)), end: new Date(Date.UTC(2017, 5, 13)), diff --git a/src/containers/OrderPage/__snapshots__/OrderPage.test.js.snap b/src/containers/OrderPage/__snapshots__/OrderPage.test.js.snap index 6a0c4e9d..5599df1c 100644 --- a/src/containers/OrderPage/__snapshots__/OrderPage.test.js.snap +++ b/src/containers/OrderPage/__snapshots__/OrderPage.test.js.snap @@ -86,7 +86,6 @@ exports[`OrderPage matches snapshot 1`] = ` "amount": 900, "currency": "USD", }, - "state": "state/preauthorized", }, "booking": Object { "attributes": Object { diff --git a/src/containers/SalePage/SalePage.test.js b/src/containers/SalePage/SalePage.test.js index faa564b1..2c5a74a4 100644 --- a/src/containers/SalePage/SalePage.test.js +++ b/src/containers/SalePage/SalePage.test.js @@ -8,6 +8,7 @@ import { fakeIntl, } from '../../util/test-data'; import { renderShallow } from '../../util/test-helpers'; +import { TX_TRANSITION_PREAUTHORIZE } from '../../util/propTypes'; import { SalePageComponent } from './SalePage'; const noop = () => null; @@ -17,7 +18,7 @@ describe('SalePage', () => { const txId = 'tx-sale-1'; const transaction = createTransaction({ id: txId, - state: 'state/preauthorized', + lastTransition: TX_TRANSITION_PREAUTHORIZE, booking: createBooking('booking1', { start: new Date(Date.UTC(2017, 5, 10)), end: new Date(Date.UTC(2017, 5, 13)), diff --git a/src/containers/SalePage/__snapshots__/SalePage.test.js.snap b/src/containers/SalePage/__snapshots__/SalePage.test.js.snap index e2fc9d4b..3a600384 100644 --- a/src/containers/SalePage/__snapshots__/SalePage.test.js.snap +++ b/src/containers/SalePage/__snapshots__/SalePage.test.js.snap @@ -93,7 +93,6 @@ exports[`SalePage matches snapshot 1`] = ` "amount": 900, "currency": "USD", }, - "state": "state/preauthorized", }, "booking": Object { "attributes": Object { diff --git a/src/ducks/user.duck.js b/src/ducks/user.duck.js index ea8c59e4..57ec1e71 100644 --- a/src/ducks/user.duck.js +++ b/src/ducks/user.duck.js @@ -1,5 +1,4 @@ import { updatedEntities, denormalisedEntities } from '../util/data'; -import { TX_STATE_PREAUTHORIZED } from '../util/propTypes'; // ================ Action types ================ // @@ -299,7 +298,14 @@ export const fetchCurrentUserNotifications = () => const apiQueryParams = { only: 'sale', - states: [TX_STATE_PREAUTHORIZED], + + // TODO: Currently the API supports only filtering by tx + // state. However, the state will be removed and support for + // filtering by last transitions is added. The code below should + // be changed at that point. + states: ['state/preauthorized'], + // last_transitions: [TX_TRANSITION_PREAUTHORIZE], + page: 1, per_page: NOTIFICATION_PAGE_SIZE, }; diff --git a/src/util/propTypes.js b/src/util/propTypes.js index e89e6446..d2669da5 100644 --- a/src/util/propTypes.js +++ b/src/util/propTypes.js @@ -20,6 +20,7 @@ import { PropTypes } from 'react'; import Decimal from 'decimal.js'; import { types as sdkTypes } from './sdkLoader'; +import { ensureTransaction } from './data'; const { UUID, LatLng, LatLngBounds, Money } = sdkTypes; const { arrayOf, bool, func, instanceOf, number, oneOf, shape, string } = PropTypes; @@ -135,18 +136,6 @@ export const booking = shape({ }), }); -export const TX_STATE_ACCEPTED = 'state/accepted'; -export const TX_STATE_REJECTED = 'state/rejected'; -export const TX_STATE_PREAUTHORIZED = 'state/preauthorized'; -export const TX_STATE_DELIVERED = 'state/delivered'; - -export const TX_STATES = [ - TX_STATE_ACCEPTED, - TX_STATE_REJECTED, - TX_STATE_PREAUTHORIZED, - TX_STATE_DELIVERED, -]; - // When the customer requests a booking, a transaction is created. The // initial state is preauthorized that is transitioned with the // initial preauthorize transition. The customer can see this @@ -175,6 +164,20 @@ export const TX_TRANSITIONS = [ TX_TRANSITION_MARK_DELIVERED, ]; +const txLastTransition = tx => ensureTransaction(tx).attributes.lastTransition; + +export const txIsPreauthorized = tx => txLastTransition(tx) === TX_TRANSITION_PREAUTHORIZE; + +export const txIsAccepted = tx => txLastTransition(tx) === TX_TRANSITION_ACCEPT; + +export const txIsRejected = tx => txLastTransition(tx) === TX_TRANSITION_REJECT; + +export const txIsAutorejected = tx => txLastTransition(tx) === TX_TRANSITION_AUTO_REJECT; + +export const txIsRejectedOrAutorejected = tx => txIsRejected(tx) || txIsAutorejected(tx); + +export const txIsDelivered = tx => txLastTransition(tx) === TX_TRANSITION_MARK_DELIVERED; + // Denormalised transaction object export const transaction = shape({ id: uuid.isRequired, @@ -183,7 +186,6 @@ export const transaction = shape({ createdAt: instanceOf(Date).isRequired, lastTransitionedAt: instanceOf(Date).isRequired, lastTransition: oneOf(TX_TRANSITIONS).isRequired, - state: oneOf(TX_STATES).isRequired, payinTotal: money.isRequired, payoutTotal: money.isRequired, lineItems: arrayOf( diff --git a/src/util/test-data.js b/src/util/test-data.js index 5086bd02..4145ec80 100644 --- a/src/util/test-data.js +++ b/src/util/test-data.js @@ -89,7 +89,6 @@ export const createListing = (id, attributes = {}, includes = {}) => ({ export const createTransaction = options => { const { id, - state = propTypes.TX_STATE_PREAUTHORIZED, lastTransition = propTypes.TX_TRANSITION_PREAUTHORIZE, total = new Money(1000, 'USD'), commission = new Money(100, 'USD'), @@ -106,7 +105,6 @@ export const createTransaction = options => { attributes: { createdAt: new Date(Date.UTC(2017, 4, 1)), lastTransitionedAt, - state, lastTransition, payinTotal: total, payoutTotal: new Money(total.amount - commission.amount, total.currency),