github.com/companieshouse/lfp-pay-api@v0.0.0-20230203133422-0ca455cd79f9/validators/payable_transactions_test.go (about)

     1  package validators
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"testing"
     7  
     8  	"github.com/companieshouse/lfp-pay-api-core/models"
     9  	"github.com/companieshouse/lfp-pay-api/config"
    10  	"github.com/jarcoal/httpmock"
    11  	. "github.com/smartystreets/goconvey/convey"
    12  )
    13  
    14  func createE5Response(txType string, isPaid bool, isDCA bool, outstandingAmount int) string {
    15  	isPaidString := "true"
    16  	if !isPaid {
    17  		isPaidString = "false"
    18  	}
    19  
    20  	accountStatus := ""
    21  	if isDCA {
    22  		accountStatus = "DCA"
    23  	}
    24  
    25  	return fmt.Sprintf(`
    26  		{
    27  			"page": {
    28  			"size": 4,
    29  				"totalElements": 4,
    30  				"totalPages": 1,
    31  				"number": 0
    32  			},
    33  			"data": [
    34  			{
    35  				"companyCode": "LP",
    36  				"ledgerCode": "EW",
    37  				"customerCode": "10000024",
    38  				"transactionReference": "00378420",
    39  				"transactionDate": "2017-11-28",
    40  				"madeUpDate": "2017-02-28",
    41  				"amount": 150,
    42  				"outstandingAmount": %d,
    43  				"isPaid": %s,
    44  				"transactionType": "%s",
    45  				"transactionSubType": "EU",
    46  				"typeDescription": "Penalty Ltd Wel & Eng <=1m     LTDWA    ",
    47  				"dueDate": "2017-12-12",
    48  				"accountStatus": "%s"
    49  			}
    50  		]
    51  	}
    52  	`, outstandingAmount, isPaidString, txType, accountStatus)
    53  }
    54  
    55  const multiplePenalties = `
    56  {
    57    "page" : {
    58      "size" : 2,
    59      "totalElements" : 2,
    60      "totalPages" : 1,
    61      "number" : 0
    62    },
    63    "data" : [ {
    64      "companyCode" : "LP",
    65      "ledgerCode" : "EW",
    66      "customerCode" : "05838070",
    67      "transactionReference" : "00482774",
    68      "transactionDate" : "2018-04-30",
    69      "madeUpDate" : "2017-06-30",
    70      "amount" : 150,
    71      "outstandingAmount" : 150,
    72      "isPaid" : false,
    73      "transactionType" : "1",
    74      "transactionSubType" : "EU",
    75      "typeDescription" : "Penalty Ltd Wel & Eng <=1m     LTDWA    ",
    76      "dueDate" : "2018-05-14"
    77    }, {
    78      "companyCode" : "LP",
    79      "ledgerCode" : "EW",
    80      "customerCode" : "05838070",
    81      "transactionReference" : "00556352",
    82      "transactionDate" : "2019-06-27",
    83      "madeUpDate" : "2018-06-30",
    84      "amount" : 750,
    85      "outstandingAmount" : 750,
    86      "isPaid" : false,
    87      "transactionType" : "1",
    88      "transactionSubType" : "EJ",
    89      "typeDescription" : "Double DBL LTD E&W>1<3 MNTH   DLTWB     ",
    90      "dueDate" : "2019-07-11"
    91    } ]
    92  }
    93  `
    94  
    95  func TestUnitPayableTransactions(t *testing.T) {
    96  	os.Chdir("..")
    97  	cfg, _ := config.Get()
    98  	cfg.E5APIURL = "https://e5"
    99  	cfg.E5Username = "SYSTEM"
   100  
   101  	url := "https://e5/arTransactions/10000024?ADV_userName=SYSTEM&companyCode=LP&fromDate=1990-01-01"
   102  
   103  	Convey("error is returned when transaction does not exist", t, func() {
   104  		httpmock.Activate()
   105  		defer httpmock.DeactivateAndReset()
   106  
   107  		e5Response := createE5Response("1", false, false, 150)
   108  		httpmock.RegisterResponder("GET", url, httpmock.NewStringResponder(200, e5Response))
   109  
   110  		txs := []models.TransactionItem{
   111  			models.TransactionItem{TransactionID: "123"},
   112  		}
   113  
   114  		validTxs, err := TransactionsArePayable("10000024", txs)
   115  
   116  		So(validTxs, ShouldBeNil)
   117  		So(err, ShouldBeError, ErrTransactionDoesNotExist)
   118  	})
   119  
   120  	Convey("error is returned if type is not a penalty", t, func() {
   121  		httpmock.Activate()
   122  		defer httpmock.DeactivateAndReset()
   123  
   124  		e5Response := createE5Response("2", false, false, 150)
   125  		httpmock.RegisterResponder("GET", url, httpmock.NewStringResponder(200, e5Response))
   126  
   127  		txs := []models.TransactionItem{
   128  			models.TransactionItem{TransactionID: "00378420"},
   129  		}
   130  
   131  		validTxs, err := TransactionsArePayable("10000024", txs)
   132  
   133  		So(validTxs, ShouldBeNil)
   134  		So(err, ShouldBeError, ErrTransactionNotPayable)
   135  	})
   136  
   137  	Convey("error is returned if transaction is already paid", t, func() {
   138  		httpmock.Activate()
   139  		defer httpmock.DeactivateAndReset()
   140  
   141  		e5Response := createE5Response("1", true, false, 150)
   142  		httpmock.RegisterResponder("GET", url, httpmock.NewStringResponder(200, e5Response))
   143  
   144  		txs := []models.TransactionItem{
   145  			models.TransactionItem{TransactionID: "00378420"},
   146  		}
   147  
   148  		validTxs, err := TransactionsArePayable("10000024", txs)
   149  
   150  		So(validTxs, ShouldBeNil)
   151  		So(err, ShouldBeError, ErrTransactionIsPaid)
   152  	})
   153  
   154  	Convey("type and made up date are taken from E5", t, func() {
   155  		httpmock.Activate()
   156  		defer httpmock.DeactivateAndReset()
   157  
   158  		e5Response := createE5Response("1", false, false, 150)
   159  		httpmock.RegisterResponder("GET", url, httpmock.NewStringResponder(200, e5Response))
   160  
   161  		txs := []models.TransactionItem{
   162  			models.TransactionItem{TransactionID: "00378420", Amount: 150},
   163  		}
   164  
   165  		validTxs, err := TransactionsArePayable("10000024", txs)
   166  
   167  		So(err, ShouldBeNil)
   168  		So(validTxs[0].MadeUpDate, ShouldEqual, "2017-02-28")
   169  		So(validTxs[0].Type, ShouldEqual, "penalty")
   170  		So(validTxs[0].Amount, ShouldEqual, 150)
   171  		So(validTxs[0].IsPaid, ShouldEqual, false)
   172  		So(validTxs[0].IsDCA, ShouldEqual, false)
   173  	})
   174  
   175  	Convey("error is returned if trying to part pay a transaction", t, func() {
   176  		httpmock.Activate()
   177  		defer httpmock.DeactivateAndReset()
   178  
   179  		e5Response := createE5Response("1", false, false, 150)
   180  		httpmock.RegisterResponder("GET", url, httpmock.NewStringResponder(200, e5Response))
   181  
   182  		txs := []models.TransactionItem{
   183  			models.TransactionItem{TransactionID: "00378420", Amount: 100},
   184  		}
   185  
   186  		validTxs, err := TransactionsArePayable("10000024", txs)
   187  
   188  		So(validTxs, ShouldBeNil)
   189  		So(err, ShouldBeError, ErrTransactionAmountMismatch)
   190  	})
   191  
   192  	Convey("error when company has multiple penalties", t, func() {
   193  		httpmock.Activate()
   194  		defer httpmock.DeactivateAndReset()
   195  
   196  		httpmock.RegisterResponder("GET", url, httpmock.NewStringResponder(200, multiplePenalties))
   197  
   198  		txs := []models.TransactionItem{
   199  			{TransactionID: "00378420", Amount: 100},
   200  		}
   201  
   202  		validTxs, err := TransactionsArePayable("10000024", txs)
   203  
   204  		So(validTxs, ShouldBeNil)
   205  		So(err, ShouldBeError, ErrMultiplePenalties)
   206  	})
   207  
   208  	Convey("error is returned if transaction is in DCA status", t, func() {
   209  		httpmock.Activate()
   210  		defer httpmock.DeactivateAndReset()
   211  
   212  		e5Response := createE5Response("1", false, true, 150)
   213  		httpmock.RegisterResponder("GET", url, httpmock.NewStringResponder(200, e5Response))
   214  
   215  		txs := []models.TransactionItem{
   216  			{TransactionID: "00378420", Amount: 150},
   217  		}
   218  
   219  		validTxs, err := TransactionsArePayable("10000024", txs)
   220  
   221  		So(validTxs, ShouldBeNil)
   222  		So(err, ShouldBeError, ErrTransactionDCA)
   223  	})
   224  
   225  	Convey("error is returned if penalty is part paid", t, func() {
   226  		httpmock.Activate()
   227  		defer httpmock.DeactivateAndReset()
   228  
   229  		e5Response := createE5Response("1", false, true, 50)
   230  		httpmock.RegisterResponder("GET", url, httpmock.NewStringResponder(200, e5Response))
   231  
   232  		txs := []models.TransactionItem{
   233  			{TransactionID: "00378420", Amount: 50},
   234  		}
   235  
   236  		validTxs, err := TransactionsArePayable("10000024", txs)
   237  
   238  		So(validTxs, ShouldBeNil)
   239  		So(err, ShouldBeError, ErrTransactionIsPartPaid)
   240  	})
   241  }