mirror of
https://github.com/kingomarnajjar/flex-template-web.git
synced 2026-07-27 19:42:11 +10:00
Add state graph description and refactor transaction.js functions to use it.
This commit is contained in:
parent
6d6ebbffc1
commit
caad06353e
8 changed files with 337 additions and 95 deletions
|
|
@ -20,7 +20,7 @@ import {
|
|||
TRANSITION_REVIEW_2_BY_PROVIDER,
|
||||
TX_TRANSITION_ACTOR_CUSTOMER,
|
||||
TX_TRANSITION_ACTOR_PROVIDER,
|
||||
areReviewsCompleted,
|
||||
transitionIsReviewed,
|
||||
} from '../../util/transaction';
|
||||
import { propTypes } from '../../util/types';
|
||||
import * as log from '../../util/log';
|
||||
|
|
@ -122,7 +122,7 @@ const hasUserLeftAReviewFirst = (userRole, lastTransition) => {
|
|||
userRole === TX_TRANSITION_ACTOR_CUSTOMER) ||
|
||||
(lastTransition === TRANSITION_REVIEW_1_BY_PROVIDER &&
|
||||
userRole === TX_TRANSITION_ACTOR_PROVIDER) ||
|
||||
areReviewsCompleted(lastTransition)
|
||||
transitionIsReviewed(lastTransition)
|
||||
);
|
||||
};
|
||||
|
||||
|
|
@ -267,7 +267,7 @@ const Transition = props => {
|
|||
|
||||
let reviewComponent = null;
|
||||
|
||||
if (isReviewTransition(currentTransition) && areReviewsCompleted(lastTransition)) {
|
||||
if (isReviewTransition(currentTransition) && transitionIsReviewed(lastTransition)) {
|
||||
const customerReview =
|
||||
currentTransition === TRANSITION_REVIEW_1_BY_CUSTOMER ||
|
||||
currentTransition === TRANSITION_REVIEW_2_BY_CUSTOMER;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
import { bool } from 'prop-types';
|
||||
import { FormattedMessage, intlShape } from 'react-intl';
|
||||
import { formatMoney } from '../../util/currency';
|
||||
import { txIsCanceled, txIsCompleted, txIsDeclinedOrExpired } from '../../util/transaction';
|
||||
import { txIsCanceled, txIsDelivered, txIsDeclined } from '../../util/transaction';
|
||||
import { propTypes } from '../../util/types';
|
||||
|
||||
import css from './BookingBreakdown.css';
|
||||
|
|
@ -11,9 +11,9 @@ const LineItemUnitPrice = props => {
|
|||
const { transaction, isProvider, intl } = props;
|
||||
|
||||
let providerTotalMessageId = 'BookingBreakdown.providerTotalDefault';
|
||||
if (txIsCompleted(transaction)) {
|
||||
if (txIsDelivered(transaction)) {
|
||||
providerTotalMessageId = 'BookingBreakdown.providerTotalDelivered';
|
||||
} else if (txIsDeclinedOrExpired(transaction)) {
|
||||
} else if (txIsDeclined(transaction)) {
|
||||
providerTotalMessageId = 'BookingBreakdown.providerTotalDeclined';
|
||||
} else if (txIsCanceled(transaction)) {
|
||||
providerTotalMessageId = 'BookingBreakdown.providerTotalCanceled';
|
||||
|
|
|
|||
|
|
@ -285,6 +285,14 @@
|
|||
}
|
||||
}
|
||||
|
||||
.breakdownContainer {
|
||||
display: none;
|
||||
|
||||
@media (--viewportLarge) {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
/* FeedSection subcomponent */
|
||||
.feedHeading {
|
||||
color: var(--matterColorAnti);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import classNames from 'classnames';
|
|||
import {
|
||||
txIsAccepted,
|
||||
txIsCanceled,
|
||||
txIsDeclinedOrExpired,
|
||||
txIsDeclined,
|
||||
txIsEnquired,
|
||||
txIsRequested,
|
||||
txHasBeenDelivered,
|
||||
|
|
@ -203,7 +203,7 @@ export class TransactionPanelComponent extends Component {
|
|||
showDetailCardHeadings: isCustomer,
|
||||
showAddress: isCustomer,
|
||||
};
|
||||
} else if (txIsDeclinedOrExpired(tx)) {
|
||||
} else if (txIsDeclined(tx)) {
|
||||
return {
|
||||
headingState: HEADING_DECLINED,
|
||||
showDetailCardHeadings: isCustomer,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import classNames from 'classnames';
|
|||
import {
|
||||
txIsAccepted,
|
||||
txIsCanceled,
|
||||
txIsDeclinedOrExpired,
|
||||
txIsDeclined,
|
||||
txIsEnquired,
|
||||
txIsRequested,
|
||||
txHasBeenDelivered,
|
||||
|
|
@ -88,7 +88,7 @@ export const txState = (intl, tx, type) => {
|
|||
};
|
||||
|
||||
return requested;
|
||||
} else if (txIsDeclinedOrExpired(tx)) {
|
||||
} else if (txIsDeclined(tx)) {
|
||||
return {
|
||||
nameClassName: css.nameNotEmphasized,
|
||||
bookingClassName: css.bookingNoActionNeeded,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import {
|
|||
txIsEnquired,
|
||||
getReview1Transition,
|
||||
getReview2Transition,
|
||||
txHasFirstReviewBy,
|
||||
txIsInFirstReviewBy,
|
||||
TRANSITION_ACCEPT,
|
||||
TRANSITION_DECLINE,
|
||||
} from '../../util/transaction';
|
||||
|
|
@ -495,7 +495,7 @@ const sendReviewAsFirst = (id, params, role, dispatch, sdk) => {
|
|||
export const sendReview = (role, tx, reviewRating, reviewContent) => (dispatch, getState, sdk) => {
|
||||
const params = { reviewRating, reviewContent };
|
||||
|
||||
const txStateOtherPartyFirst = txHasFirstReviewBy(tx, role !== CUSTOMER);
|
||||
const txStateOtherPartyFirst = txIsInFirstReviewBy(tx, role !== CUSTOMER);
|
||||
|
||||
dispatch(sendReviewRequest());
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
import { ensureTransaction } from './data';
|
||||
|
||||
/**
|
||||
* Transitions
|
||||
*
|
||||
* These strings must sync with values defined in Flex API,
|
||||
* since transaction objects given by API contain info about last transitions.
|
||||
* All the actions in API side happen in transitions,
|
||||
* so we need to understand what those strings mean.
|
||||
*/
|
||||
|
||||
// When a customer makes a booking to a listing, a transaction is
|
||||
// created with the initial request transition.
|
||||
export const TRANSITION_REQUEST = 'transition/request';
|
||||
|
|
@ -34,89 +43,11 @@ export const TRANSITION_EXPIRE_CUSTOMER_REVIEW_PERIOD = 'transition/expire-custo
|
|||
export const TRANSITION_EXPIRE_PROVIDER_REVIEW_PERIOD = 'transition/expire-provider-review-period';
|
||||
export const TRANSITION_EXPIRE_REVIEW_PERIOD = 'transition/expire-review-period';
|
||||
|
||||
export const TRANSITIONS = [
|
||||
TRANSITION_ACCEPT,
|
||||
TRANSITION_CANCEL,
|
||||
TRANSITION_COMPLETE,
|
||||
TRANSITION_DECLINE,
|
||||
TRANSITION_ENQUIRE,
|
||||
TRANSITION_EXPIRE,
|
||||
TRANSITION_EXPIRE_CUSTOMER_REVIEW_PERIOD,
|
||||
TRANSITION_EXPIRE_PROVIDER_REVIEW_PERIOD,
|
||||
TRANSITION_EXPIRE_REVIEW_PERIOD,
|
||||
TRANSITION_REQUEST,
|
||||
TRANSITION_REQUEST_AFTER_ENQUIRY,
|
||||
TRANSITION_REVIEW_1_BY_CUSTOMER,
|
||||
TRANSITION_REVIEW_1_BY_PROVIDER,
|
||||
TRANSITION_REVIEW_2_BY_CUSTOMER,
|
||||
TRANSITION_REVIEW_2_BY_PROVIDER,
|
||||
];
|
||||
|
||||
const txLastTransition = tx => ensureTransaction(tx).attributes.lastTransition;
|
||||
|
||||
export const txIsEnquired = tx => txLastTransition(tx) === TRANSITION_ENQUIRE;
|
||||
|
||||
export const transitionsToRequested = [TRANSITION_REQUEST, TRANSITION_REQUEST_AFTER_ENQUIRY];
|
||||
export const txIsRequested = tx => transitionsToRequested.includes(txLastTransition(tx));
|
||||
|
||||
export const txIsAccepted = tx => txLastTransition(tx) === TRANSITION_ACCEPT;
|
||||
|
||||
export const txIsDeclined = tx => txLastTransition(tx) === TRANSITION_DECLINE;
|
||||
|
||||
export const txIsExpired = tx => txLastTransition(tx) === TRANSITION_EXPIRE;
|
||||
|
||||
export const txIsDeclinedOrExpired = tx => txIsDeclined(tx) || txIsExpired(tx);
|
||||
|
||||
export const txIsCanceled = tx => txLastTransition(tx) === TRANSITION_CANCEL;
|
||||
|
||||
export const txIsCompleted = tx => txLastTransition(tx) === TRANSITION_COMPLETE;
|
||||
|
||||
const firstReviewTransitions = [TRANSITION_REVIEW_1_BY_CUSTOMER, TRANSITION_REVIEW_1_BY_PROVIDER];
|
||||
export const txHasFirstReview = tx => firstReviewTransitions.includes(txLastTransition(tx));
|
||||
|
||||
export const txHasFirstReviewBy = (tx, isCustomer) =>
|
||||
isCustomer
|
||||
? txLastTransition(tx) === TRANSITION_REVIEW_1_BY_CUSTOMER
|
||||
: txLastTransition(tx) === TRANSITION_REVIEW_1_BY_PROVIDER;
|
||||
|
||||
export const txIsReviewed = tx => areReviewsCompleted(txLastTransition(tx));
|
||||
|
||||
export const getReview1Transition = isCustomer =>
|
||||
isCustomer ? TRANSITION_REVIEW_1_BY_CUSTOMER : TRANSITION_REVIEW_1_BY_PROVIDER;
|
||||
|
||||
export const getReview2Transition = isCustomer =>
|
||||
isCustomer ? TRANSITION_REVIEW_2_BY_CUSTOMER : TRANSITION_REVIEW_2_BY_PROVIDER;
|
||||
|
||||
// Check if tx transition is followed by a state where
|
||||
// reviews are completed
|
||||
export const areReviewsCompleted = transition => {
|
||||
return [
|
||||
TRANSITION_EXPIRE_CUSTOMER_REVIEW_PERIOD,
|
||||
TRANSITION_EXPIRE_PROVIDER_REVIEW_PERIOD,
|
||||
TRANSITION_EXPIRE_REVIEW_PERIOD,
|
||||
TRANSITION_REVIEW_2_BY_CUSTOMER,
|
||||
TRANSITION_REVIEW_2_BY_PROVIDER,
|
||||
].includes(transition);
|
||||
};
|
||||
|
||||
export const txHasBeenAccepted = tx => {
|
||||
const transition = txLastTransition(tx);
|
||||
return [
|
||||
TRANSITION_ACCEPT,
|
||||
TRANSITION_REVIEW_1_BY_CUSTOMER,
|
||||
TRANSITION_REVIEW_1_BY_PROVIDER,
|
||||
TRANSITION_REVIEW_2_BY_CUSTOMER,
|
||||
TRANSITION_REVIEW_2_BY_PROVIDER,
|
||||
TRANSITION_EXPIRE_CUSTOMER_REVIEW_PERIOD,
|
||||
TRANSITION_EXPIRE_PROVIDER_REVIEW_PERIOD,
|
||||
TRANSITION_EXPIRE_REVIEW_PERIOD,
|
||||
TRANSITION_COMPLETE,
|
||||
].includes(transition);
|
||||
};
|
||||
|
||||
export const txHasBeenDelivered = tx => {
|
||||
return txHasFirstReview(tx) || txIsReviewed(tx) || txIsCompleted(tx);
|
||||
};
|
||||
/**
|
||||
* Actors
|
||||
*
|
||||
* There are 4 different actors that might initiate transitions:
|
||||
*/
|
||||
|
||||
// Roles of actors that perform transaction transitions
|
||||
export const TX_TRANSITION_ACTOR_CUSTOMER = 'customer';
|
||||
|
|
@ -130,3 +61,210 @@ export const TX_TRANSITION_ACTORS = [
|
|||
TX_TRANSITION_ACTOR_SYSTEM,
|
||||
TX_TRANSITION_ACTOR_OPERATOR,
|
||||
];
|
||||
|
||||
/**
|
||||
* States
|
||||
*
|
||||
* These constants are only for making it clear how transitions work together.
|
||||
* You should not use these constants outside of this file.
|
||||
*
|
||||
* Note: these states are not in sync with states used transaction process definitions
|
||||
* in Marketplace API. Only last transitions are passed along transaction object.
|
||||
*/
|
||||
const STATE_INITIAL = 'initial';
|
||||
const STATE_ENQUIRY = 'enquiry';
|
||||
const STATE_PREAUTHORIZED = 'preauthorized';
|
||||
const STATE_DECLINED = 'declined';
|
||||
const STATE_ACCEPTED = 'accepted';
|
||||
const STATE_CANCELED = 'canceled';
|
||||
const STATE_DELIVERED = 'delivered';
|
||||
const STATE_REVIEWED = 'reviewed';
|
||||
const STATE_REVIEWED_BY_CUSTOMER = 'reviewed-by-customer';
|
||||
const STATE_REVIEWED_BY_PROVIDER = 'reviewed-by-provider';
|
||||
|
||||
/**
|
||||
* Description of transaction process
|
||||
*
|
||||
* You should keep this in sync with transaction process defined in Marketplace API
|
||||
*
|
||||
* Note: we don't use yet any state machine library,
|
||||
* but this description format is following Xstate (FSM library)
|
||||
* https://xstate.js.org/docs/
|
||||
*/
|
||||
const stateDescription = {
|
||||
// id is defined only to support Xstate format.
|
||||
// However if you have multiple transaction processes defined,
|
||||
// it is best to keep them in sync with transaction process aliases.
|
||||
id: 'preauth-with-nightly-booking/release-1',
|
||||
|
||||
// This 'initial' state is a starting point for new transaction
|
||||
initial: STATE_INITIAL,
|
||||
|
||||
// States
|
||||
states: {
|
||||
[STATE_INITIAL]: {
|
||||
on: {
|
||||
[TRANSITION_ENQUIRE]: STATE_ENQUIRY,
|
||||
[TRANSITION_REQUEST]: STATE_PREAUTHORIZED,
|
||||
},
|
||||
},
|
||||
[STATE_ENQUIRY]: {
|
||||
on: {
|
||||
[TRANSITION_REQUEST_AFTER_ENQUIRY]: STATE_PREAUTHORIZED,
|
||||
},
|
||||
},
|
||||
|
||||
[STATE_PREAUTHORIZED]: {
|
||||
on: {
|
||||
[TRANSITION_DECLINE]: STATE_DECLINED,
|
||||
[TRANSITION_EXPIRE]: STATE_DECLINED,
|
||||
[TRANSITION_ACCEPT]: STATE_ACCEPTED,
|
||||
},
|
||||
},
|
||||
|
||||
[STATE_DECLINED]: {},
|
||||
[STATE_ACCEPTED]: {
|
||||
on: {
|
||||
[TRANSITION_CANCEL]: STATE_CANCELED,
|
||||
[TRANSITION_COMPLETE]: STATE_DELIVERED,
|
||||
},
|
||||
},
|
||||
|
||||
[STATE_CANCELED]: {},
|
||||
[STATE_DELIVERED]: {
|
||||
on: {
|
||||
[TRANSITION_EXPIRE_REVIEW_PERIOD]: STATE_REVIEWED,
|
||||
[TRANSITION_REVIEW_1_BY_CUSTOMER]: STATE_REVIEWED_BY_CUSTOMER,
|
||||
[TRANSITION_REVIEW_1_BY_PROVIDER]: STATE_REVIEWED_BY_PROVIDER,
|
||||
},
|
||||
},
|
||||
|
||||
[STATE_REVIEWED_BY_CUSTOMER]: {
|
||||
on: {
|
||||
[TRANSITION_REVIEW_2_BY_PROVIDER]: STATE_REVIEWED,
|
||||
[TRANSITION_EXPIRE_PROVIDER_REVIEW_PERIOD]: STATE_REVIEWED,
|
||||
},
|
||||
},
|
||||
[STATE_REVIEWED_BY_PROVIDER]: {
|
||||
on: {
|
||||
[TRANSITION_REVIEW_2_BY_CUSTOMER]: STATE_REVIEWED,
|
||||
[TRANSITION_EXPIRE_CUSTOMER_REVIEW_PERIOD]: STATE_REVIEWED,
|
||||
},
|
||||
},
|
||||
[STATE_REVIEWED]: { type: 'final' },
|
||||
},
|
||||
};
|
||||
|
||||
// Note: currently we assume that state description doesn't contain nested states.
|
||||
const statesFromStateDescription = description => description.states || {};
|
||||
|
||||
// Get all the transitions from states object in an array
|
||||
const getTransitions = states => {
|
||||
const stateNames = Object.keys(states);
|
||||
|
||||
const transitionsReducer = (transitionArray, name) => {
|
||||
const stateTransitions = states[name] && states[name].on;
|
||||
const transitionKeys = stateTransitions ? Object.keys(stateTransitions) : [];
|
||||
return [
|
||||
...transitionArray,
|
||||
...transitionKeys.map(key => ({ key, value: stateTransitions[key] })),
|
||||
];
|
||||
};
|
||||
|
||||
return stateNames.reduce(transitionsReducer, []);
|
||||
};
|
||||
|
||||
// This is a list of all the transitions that this app should be able to handle.
|
||||
export const TRANSITIONS = getTransitions(statesFromStateDescription(stateDescription)).map(
|
||||
t => t.key
|
||||
);
|
||||
|
||||
// This function returns a function that has given stateDesc in scope chain.
|
||||
const getTransitionsToStateFn = stateDesc => state =>
|
||||
getTransitions(statesFromStateDescription(stateDesc))
|
||||
.filter(t => t.value === state)
|
||||
.map(t => t.key);
|
||||
|
||||
// Get all the transitions that lead to specified state.
|
||||
const getTransitionsToState = getTransitionsToStateFn(stateDescription);
|
||||
|
||||
// This is needed to fetch transactions that need response from provider.
|
||||
// I.e. transactions which provider needs to accept or decline
|
||||
export const transitionsToRequested = getTransitionsToState(STATE_PREAUTHORIZED);
|
||||
|
||||
/**
|
||||
* Helper functions to figure out if transaction is in a specific state.
|
||||
* State is based on lastTransition given by transaction object and state description.
|
||||
*/
|
||||
|
||||
const txLastTransition = tx => ensureTransaction(tx).attributes.lastTransition;
|
||||
|
||||
// DEPRECATED: use txIsDelivered instead
|
||||
export const txIsCompleted = tx => txLastTransition(tx) === TRANSITION_COMPLETE;
|
||||
|
||||
export const txIsEnquired = tx =>
|
||||
getTransitionsToState(STATE_ENQUIRY).includes(txLastTransition(tx));
|
||||
|
||||
// Note: state name used in Marketplace API docs (and here) is actually preauthorized
|
||||
// However, word "requested" is used in many places so that we decided to keep it.
|
||||
export const txIsRequested = tx =>
|
||||
getTransitionsToState(STATE_PREAUTHORIZED).includes(txLastTransition(tx));
|
||||
|
||||
export const txIsAccepted = tx =>
|
||||
getTransitionsToState(STATE_ACCEPTED).includes(txLastTransition(tx));
|
||||
|
||||
export const txIsDeclined = tx =>
|
||||
getTransitionsToState(STATE_DECLINED).includes(txLastTransition(tx));
|
||||
|
||||
export const txIsCanceled = tx =>
|
||||
getTransitionsToState(STATE_CANCELED).includes(txLastTransition(tx));
|
||||
|
||||
export const txIsDelivered = tx =>
|
||||
getTransitionsToState(STATE_DELIVERED).includes(txLastTransition(tx));
|
||||
|
||||
const firstReviewTransitions = [
|
||||
...getTransitionsToState(STATE_REVIEWED_BY_CUSTOMER),
|
||||
...getTransitionsToState(STATE_REVIEWED_BY_PROVIDER),
|
||||
];
|
||||
export const txIsInFirstReview = tx => firstReviewTransitions.includes(txLastTransition(tx));
|
||||
|
||||
export const txIsInFirstReviewBy = (tx, isCustomer) =>
|
||||
isCustomer
|
||||
? getTransitionsToState(STATE_REVIEWED_BY_CUSTOMER).includes(txLastTransition(tx))
|
||||
: getTransitionsToState(STATE_REVIEWED_BY_PROVIDER).includes(txLastTransition(tx));
|
||||
|
||||
export const txIsReviewed = tx =>
|
||||
getTransitionsToState(STATE_REVIEWED).includes(txLastTransition(tx));
|
||||
|
||||
/**
|
||||
* Helper functions to figure out if transaction has passed a given state.
|
||||
* This is based on transitions history given by transaction object.
|
||||
*/
|
||||
|
||||
const txTransitions = tx => ensureTransaction(tx).attributes.transitions || [];
|
||||
const hasPassedTransition = (transitionName, tx) =>
|
||||
!!txTransitions(tx).find(t => t.transition === transitionName);
|
||||
|
||||
const hasPassedStateFn = state => tx =>
|
||||
getTransitionsToState(state).filter(t => hasPassedTransition(t, tx)).length > 0;
|
||||
|
||||
export const txHasBeenAccepted = hasPassedStateFn(STATE_ACCEPTED);
|
||||
export const txHasBeenDelivered = hasPassedStateFn(STATE_DELIVERED);
|
||||
|
||||
/**
|
||||
* Other transaction related utility functions
|
||||
*/
|
||||
|
||||
export const transitionIsReviewed = transition =>
|
||||
getTransitionsToState(STATE_REVIEWED).includes(transition);
|
||||
|
||||
export const transitionIsFirstReviewedBy = (transition, isCustomer) =>
|
||||
isCustomer
|
||||
? getTransitionsToState(STATE_REVIEWED_BY_CUSTOMER).includes(transition)
|
||||
: getTransitionsToState(STATE_REVIEWED_BY_PROVIDER).includes(transition);
|
||||
|
||||
export const getReview1Transition = isCustomer =>
|
||||
isCustomer ? TRANSITION_REVIEW_1_BY_CUSTOMER : TRANSITION_REVIEW_1_BY_PROVIDER;
|
||||
|
||||
export const getReview2Transition = isCustomer =>
|
||||
isCustomer ? TRANSITION_REVIEW_2_BY_CUSTOMER : TRANSITION_REVIEW_2_BY_PROVIDER;
|
||||
|
|
|
|||
96
src/util/transaction.test.js
Normal file
96
src/util/transaction.test.js
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
import { createUser, createTransaction, createListing, createTxTransition } from './test-data';
|
||||
|
||||
import {
|
||||
TX_TRANSITION_ACTOR_CUSTOMER,
|
||||
TX_TRANSITION_ACTOR_PROVIDER,
|
||||
TX_TRANSITION_ACTOR_SYSTEM,
|
||||
TRANSITION_REQUEST,
|
||||
TRANSITION_ACCEPT,
|
||||
TRANSITION_COMPLETE,
|
||||
TRANSITION_EXPIRE_REVIEW_PERIOD,
|
||||
txIsAccepted,
|
||||
txIsReviewed,
|
||||
txHasBeenAccepted,
|
||||
txHasBeenDelivered,
|
||||
} from './transaction';
|
||||
|
||||
const transitionRequest = createTxTransition({
|
||||
createdAt: new Date(Date.UTC(2017, 10, 9, 8, 10)),
|
||||
by: TX_TRANSITION_ACTOR_CUSTOMER,
|
||||
transition: TRANSITION_REQUEST,
|
||||
});
|
||||
|
||||
const transitionAccept = createTxTransition({
|
||||
createdAt: new Date(Date.UTC(2017, 10, 9, 8, 12)),
|
||||
by: TX_TRANSITION_ACTOR_PROVIDER,
|
||||
transition: TRANSITION_ACCEPT,
|
||||
});
|
||||
|
||||
const transitionDelivered = createTxTransition({
|
||||
createdAt: new Date(Date.UTC(2017, 10, 16, 8, 12)),
|
||||
by: TX_TRANSITION_ACTOR_SYSTEM,
|
||||
transition: TRANSITION_COMPLETE,
|
||||
});
|
||||
const transitionReviewed = createTxTransition({
|
||||
createdAt: new Date(Date.UTC(2017, 10, 16, 8, 12)),
|
||||
by: TX_TRANSITION_ACTOR_SYSTEM,
|
||||
transition: TRANSITION_EXPIRE_REVIEW_PERIOD,
|
||||
});
|
||||
|
||||
const txRequested = createTransaction({
|
||||
lastTransition: TRANSITION_REQUEST,
|
||||
customer: createUser('user1'),
|
||||
provider: createUser('user2'),
|
||||
listing: createListing('Listing'),
|
||||
transitions: [transitionRequest],
|
||||
});
|
||||
|
||||
const txAccepted = createTransaction({
|
||||
lastTransition: TRANSITION_ACCEPT,
|
||||
customer: createUser('user1'),
|
||||
provider: createUser('user2'),
|
||||
listing: createListing('Listing'),
|
||||
transitions: [transitionRequest, transitionAccept],
|
||||
});
|
||||
|
||||
const txReviewed = createTransaction({
|
||||
lastTransition: TRANSITION_EXPIRE_REVIEW_PERIOD,
|
||||
customer: createUser('user1'),
|
||||
provider: createUser('user2'),
|
||||
listing: createListing('Listing'),
|
||||
transitions: [transitionRequest, transitionAccept, transitionDelivered, transitionReviewed],
|
||||
});
|
||||
|
||||
describe('transaction utils', () => {
|
||||
describe('tx is in correct state', () => {
|
||||
it(`txIsReviewed(txReviewed) succeeds with last transaction: ${TRANSITION_EXPIRE_REVIEW_PERIOD}`, () => {
|
||||
expect(txIsReviewed(txReviewed)).toEqual(true);
|
||||
});
|
||||
it(`txIsAccepted(txReviewed) fails with last transaction: ${TRANSITION_EXPIRE_REVIEW_PERIOD}`, () => {
|
||||
expect(txIsAccepted(txReviewed)).toEqual(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('tx has passed a state X', () => {
|
||||
it('txHasBeenAccepted(txRequested) fails', () => {
|
||||
expect(txHasBeenAccepted(txRequested)).toEqual(false);
|
||||
});
|
||||
it('txHasBeenDelivered(txRequest) fails', () => {
|
||||
expect(txHasBeenDelivered(txRequested)).toEqual(false);
|
||||
});
|
||||
|
||||
it('txHasBeenAccepted(txAccepted) succeeds', () => {
|
||||
expect(txHasBeenAccepted(txAccepted)).toEqual(true);
|
||||
});
|
||||
it('txHasBeenDelivered(txAccepted) fails', () => {
|
||||
expect(txHasBeenDelivered(txAccepted)).toEqual(false);
|
||||
});
|
||||
|
||||
it('txHasBeenAccepted(txReviewed) succeeds', () => {
|
||||
expect(txHasBeenAccepted(txReviewed)).toEqual(true);
|
||||
});
|
||||
it('txHasBeenDelivered(txReviewed) succeeds', () => {
|
||||
expect(txHasBeenDelivered(txReviewed)).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue