All files / src/core/contexts paymentDetailsContext.ts

97.5% Statements 39/40
67.44% Branches 29/43
100% Functions 3/3
97.36% Lines 37/38

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 1018x   8x 8x     8x 8x           8x 8x 8x     8x                                                             6x 6x 6x 6x 6x 6x 6x       53x 53x 52x   48x   5x 5x   5x         5x                     53x 5x 48x 4x 44x 2x 42x 1x 41x 9x 32x 31x   1x      
import { inject, injectable } from "inversify";
import TransactionType from "../../core/enums/transactionType";
import UnsupportedTxnError from "../../core/errors/unsupportedTxnError";
import { TransactionTypeExtensions } from "../../core/extensions/transactionTypeExtensions";
import PaymentDetails from "../types/paymentDetails";
import { AbstractPaymentDetailsStrategy } from "../strategies/abstractPaymentDetailsStrategy";
import { injectables } from "../../core/types/injectables";
import { ICardOperationStrategy,
    ICrossBorderTransferFeeStrategy,
    ICrossBorderTransferStrategy,
    IDeskWithdrawalStrategy,
    IStandardFeeStrategy,
    IStandardTransferStrategy } from "../../core/types/paymentDetailsStrategies";
import ILogger from "../../core/contracts/ILogger";
import Constants from "../../constants";
import PaymentDetailsProcessingError from "../errors/paymentDetailsProcessingError";
 
@injectable()
export default class PaymentDetailsContext {
    private readonly logger;
    private readonly cardOperationStrategy;
    private readonly crossBorderTransferStrategy;
    private readonly crossBorderTransferFeeStrategy;
    private readonly deskWithdrawalStrategy;
    private readonly standardFeeStrategy;
    private readonly standardTransferStrategy;
 
    public constructor(
        @inject(injectables.ILogger)
        logger: ILogger,
 
        @inject(injectables.ICardOperationStrategy)
        cardOperationStrategy: ICardOperationStrategy,
 
        @inject(injectables.ICrossBorderTransferStrategy)
        crossBorderTransferStrategy: ICrossBorderTransferStrategy,
 
        @inject(injectables.ICrossBorderTransferFeeStrategy)
        crossBorderTransferFeeStrategy: ICrossBorderTransferFeeStrategy,
 
        @inject(injectables.IDeskWithdrawalStrategy)
        deskWithdrawalStrategy: IDeskWithdrawalStrategy,
 
        @inject(injectables.IStandardFeeStrategy)
        standardFeeStrategy: IStandardFeeStrategy,
 
        @inject(injectables.IStandardTransferStrategy)
        standardTransferStrategy: IStandardTransferStrategy
    ) {
        this.logger = logger;
        this.cardOperationStrategy = cardOperationStrategy;
        this.crossBorderTransferStrategy = crossBorderTransferStrategy;
        this.crossBorderTransferFeeStrategy = crossBorderTransferFeeStrategy;
        this.deskWithdrawalStrategy = deskWithdrawalStrategy;
        this.standardFeeStrategy = standardFeeStrategy;
        this.standardTransferStrategy = standardTransferStrategy;
    }
 
    public resolve(reference: string, transactionType: TransactionType, paymentDetailsRaw: string[], additionalDetailsRaw: string[]) {
        try {
            const paymentDetailsStrategy = this.tryGetStrategyByType(transactionType);
            const paymentDetails = paymentDetailsStrategy.tryCreate(paymentDetailsRaw, additionalDetailsRaw);
        
            return paymentDetails;
        } catch(ex) {
            if (ex instanceof UnsupportedTxnError || ex instanceof PaymentDetailsProcessingError) {
                this.logger.warn(ex.message, { transactionReference: reference });
 
                this.logger.log(`Falling back to using default payment details body...`, {
                    transactionReference: reference,
                    transactionType: transactionType
                });
                
                return Constants.defaultPaymentDetails;
            }
 
            throw ex;
        }
    }
    
    /**
     * @throws UnsupportedTxnError
    **/
    private tryGetStrategyByType(transactionType: TransactionType): AbstractPaymentDetailsStrategy<PaymentDetails> {  
        if (TransactionTypeExtensions.isCardOperation(transactionType)) {
            return this.cardOperationStrategy;
        } else if (TransactionTypeExtensions.isCrossBorderTransfer(transactionType)) {
            return this.crossBorderTransferStrategy;
        } else if (TransactionTypeExtensions.isCrossBorderTransferFee(transactionType)) {
            return this.crossBorderTransferFeeStrategy;
        } else if (TransactionTypeExtensions.isDeskWithdrawal(transactionType)) {
            return this.deskWithdrawalStrategy;
        } else if (TransactionTypeExtensions.isStandardFee(transactionType)) {
            return this.standardFeeStrategy;
        } else if (TransactionTypeExtensions.isStandardTransfer(transactionType)) {
            return this.standardTransferStrategy;
        } else {
            throw new UnsupportedTxnError(transactionType);
        }
    }
}