342 lines
13 KiB
Go
342 lines
13 KiB
Go
package mt
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/mayswind/ezbookkeeping/pkg/core"
|
|
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
|
)
|
|
|
|
func TestMT940DataReaderParse(t *testing.T) {
|
|
reader := &mt940DataReader{
|
|
allLines: []string{
|
|
"{1:F01TESTBANK123456789}{2:I940TESTBANK}{4:",
|
|
":20:MT940-2025001",
|
|
":21:RELATEDREFERENCE",
|
|
":25:123456789",
|
|
":28C:123/1",
|
|
":60F:C250601CNY1234,56",
|
|
":61:2506010602DY123,45NTRFTEST//ABC123456",
|
|
":86:First Transaction",
|
|
"Additional Info",
|
|
":61:2506020620CY234,56NSTFFOOBAR//DEF789012",
|
|
":86:Second Transaction",
|
|
"More Info",
|
|
":62F:C250602CNY2345,67",
|
|
":64:C250602CNY2345,67",
|
|
"-}",
|
|
},
|
|
}
|
|
context := core.NewNullContext()
|
|
|
|
actualData, err := reader.read(context)
|
|
assert.Nil(t, err)
|
|
|
|
assert.Equal(t, "MT940-2025001", actualData.StatementReferenceNumber)
|
|
assert.Equal(t, "RELATEDREFERENCE", actualData.RelatedReference)
|
|
assert.Equal(t, "123456789", actualData.AccountId)
|
|
assert.Equal(t, "123/1", actualData.SequentialNumber)
|
|
|
|
assert.Equal(t, MT_MARK_CREDIT, actualData.OpeningBalance.DebitCreditMark)
|
|
assert.Equal(t, "250601", actualData.OpeningBalance.Date)
|
|
assert.Equal(t, "CNY", actualData.OpeningBalance.Currency)
|
|
assert.Equal(t, "1234,56", actualData.OpeningBalance.Amount)
|
|
|
|
assert.Equal(t, 2, len(actualData.Statements))
|
|
|
|
assert.Equal(t, "250601", actualData.Statements[0].ValueDate)
|
|
assert.Equal(t, "0602", actualData.Statements[0].EntryDate)
|
|
assert.Equal(t, MT_MARK_DEBIT, actualData.Statements[0].CreditDebitMark)
|
|
assert.Equal(t, "Y", actualData.Statements[0].FundsCode)
|
|
assert.Equal(t, "123,45", actualData.Statements[0].Amount)
|
|
assert.Equal(t, "NTRF", actualData.Statements[0].TransactionTypeIdentificationCode)
|
|
assert.Equal(t, "TEST", actualData.Statements[0].ReferenceForAccountOwner)
|
|
assert.Equal(t, "ABC123456", actualData.Statements[0].ReferenceOfAccountServicingInstitution)
|
|
assert.Equal(t, "First Transaction", actualData.Statements[0].InformationToAccountOwner[0])
|
|
assert.Equal(t, "Additional Info", actualData.Statements[0].InformationToAccountOwner[1])
|
|
|
|
assert.Equal(t, "250602", actualData.Statements[1].ValueDate)
|
|
assert.Equal(t, "0620", actualData.Statements[1].EntryDate)
|
|
assert.Equal(t, MT_MARK_CREDIT, actualData.Statements[1].CreditDebitMark)
|
|
assert.Equal(t, "Y", actualData.Statements[0].FundsCode)
|
|
assert.Equal(t, "234,56", actualData.Statements[1].Amount)
|
|
assert.Equal(t, "NSTF", actualData.Statements[1].TransactionTypeIdentificationCode)
|
|
assert.Equal(t, "FOOBAR", actualData.Statements[1].ReferenceForAccountOwner)
|
|
assert.Equal(t, "DEF789012", actualData.Statements[1].ReferenceOfAccountServicingInstitution)
|
|
assert.Equal(t, "Second Transaction", actualData.Statements[1].InformationToAccountOwner[0])
|
|
assert.Equal(t, "More Info", actualData.Statements[1].InformationToAccountOwner[1])
|
|
|
|
assert.Equal(t, MT_MARK_CREDIT, actualData.ClosingBalance.DebitCreditMark)
|
|
assert.Equal(t, "250602", actualData.ClosingBalance.Date)
|
|
assert.Equal(t, "CNY", actualData.ClosingBalance.Currency)
|
|
assert.Equal(t, "2345,67", actualData.ClosingBalance.Amount)
|
|
|
|
assert.Equal(t, MT_MARK_CREDIT, actualData.ClosingAvailableBalance.DebitCreditMark)
|
|
assert.Equal(t, "250602", actualData.ClosingAvailableBalance.Date)
|
|
assert.Equal(t, "CNY", actualData.ClosingAvailableBalance.Currency)
|
|
assert.Equal(t, "2345,67", actualData.ClosingAvailableBalance.Amount)
|
|
}
|
|
|
|
func TestMT940DataReaderParse_NoBlockHeaderFooter(t *testing.T) {
|
|
reader := &mt940DataReader{
|
|
allLines: []string{
|
|
":20:MT940-2025001",
|
|
":25:123456789",
|
|
":28C:123/1",
|
|
":60F:C250601CNY1234,56",
|
|
":61:2506010602DY123,45NTRFTEST//ABC123456",
|
|
":86:First Transaction",
|
|
},
|
|
}
|
|
context := core.NewNullContext()
|
|
|
|
actualData, err := reader.read(context)
|
|
assert.Nil(t, err)
|
|
|
|
assert.Equal(t, "MT940-2025001", actualData.StatementReferenceNumber)
|
|
assert.Equal(t, "123456789", actualData.AccountId)
|
|
assert.Equal(t, "123/1", actualData.SequentialNumber)
|
|
|
|
assert.Equal(t, MT_MARK_CREDIT, actualData.OpeningBalance.DebitCreditMark)
|
|
assert.Equal(t, "250601", actualData.OpeningBalance.Date)
|
|
assert.Equal(t, "CNY", actualData.OpeningBalance.Currency)
|
|
assert.Equal(t, "1234,56", actualData.OpeningBalance.Amount)
|
|
|
|
assert.Equal(t, 1, len(actualData.Statements))
|
|
|
|
assert.Equal(t, "250601", actualData.Statements[0].ValueDate)
|
|
assert.Equal(t, "0602", actualData.Statements[0].EntryDate)
|
|
assert.Equal(t, MT_MARK_DEBIT, actualData.Statements[0].CreditDebitMark)
|
|
assert.Equal(t, "Y", actualData.Statements[0].FundsCode)
|
|
assert.Equal(t, "123,45", actualData.Statements[0].Amount)
|
|
assert.Equal(t, "NTRF", actualData.Statements[0].TransactionTypeIdentificationCode)
|
|
assert.Equal(t, "TEST", actualData.Statements[0].ReferenceForAccountOwner)
|
|
assert.Equal(t, "ABC123456", actualData.Statements[0].ReferenceOfAccountServicingInstitution)
|
|
assert.Equal(t, "First Transaction", actualData.Statements[0].InformationToAccountOwner[0])
|
|
}
|
|
|
|
func TestMT940DataReaderParse_ReferenceForTheAccountOwnerTwoLine(t *testing.T) {
|
|
reader := &mt940DataReader{
|
|
allLines: []string{
|
|
":61:250601D123,45NTRFABCDEFGHIJKLMNOP",
|
|
"QRSTUVWXYZ",
|
|
},
|
|
}
|
|
context := core.NewNullContext()
|
|
|
|
actualData, err := reader.read(context)
|
|
assert.Nil(t, err)
|
|
|
|
assert.Equal(t, 1, len(actualData.Statements))
|
|
|
|
assert.Equal(t, "250601", actualData.Statements[0].ValueDate)
|
|
assert.Equal(t, MT_MARK_DEBIT, actualData.Statements[0].CreditDebitMark)
|
|
assert.Equal(t, "123,45", actualData.Statements[0].Amount)
|
|
assert.Equal(t, "NTRF", actualData.Statements[0].TransactionTypeIdentificationCode)
|
|
assert.Equal(t, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", actualData.Statements[0].ReferenceForAccountOwner)
|
|
}
|
|
|
|
func TestMT940DataReaderParse_InformationToAccountOwnerSixLine(t *testing.T) {
|
|
reader := &mt940DataReader{
|
|
allLines: []string{
|
|
":61:250601D123,45NTRFTEST",
|
|
":86:Additional Info Line 1",
|
|
"Additional Info Line 2",
|
|
"Additional Info Line 3",
|
|
"Additional Info Line 4",
|
|
"Additional Info Line 5",
|
|
"Additional Info Line 6",
|
|
},
|
|
}
|
|
context := core.NewNullContext()
|
|
|
|
actualData, err := reader.read(context)
|
|
assert.Nil(t, err)
|
|
|
|
assert.Equal(t, 1, len(actualData.Statements))
|
|
|
|
assert.Equal(t, "250601", actualData.Statements[0].ValueDate)
|
|
assert.Equal(t, MT_MARK_DEBIT, actualData.Statements[0].CreditDebitMark)
|
|
assert.Equal(t, "123,45", actualData.Statements[0].Amount)
|
|
assert.Equal(t, "NTRF", actualData.Statements[0].TransactionTypeIdentificationCode)
|
|
assert.Equal(t, "TEST", actualData.Statements[0].ReferenceForAccountOwner)
|
|
assert.Equal(t, 6, len(actualData.Statements[0].InformationToAccountOwner))
|
|
assert.Equal(t, "Additional Info Line 1", actualData.Statements[0].InformationToAccountOwner[0])
|
|
assert.Equal(t, "Additional Info Line 2", actualData.Statements[0].InformationToAccountOwner[1])
|
|
assert.Equal(t, "Additional Info Line 3", actualData.Statements[0].InformationToAccountOwner[2])
|
|
assert.Equal(t, "Additional Info Line 4", actualData.Statements[0].InformationToAccountOwner[3])
|
|
assert.Equal(t, "Additional Info Line 5", actualData.Statements[0].InformationToAccountOwner[4])
|
|
assert.Equal(t, "Additional Info Line 6", actualData.Statements[0].InformationToAccountOwner[5])
|
|
}
|
|
|
|
func TestMT940DataReaderParse_InformationToAccountOwnerMoreThanSixLine(t *testing.T) {
|
|
reader := &mt940DataReader{
|
|
allLines: []string{
|
|
":61:250601D123,45NTRFTEST",
|
|
":86:Additional Info Line 1",
|
|
"Additional Info Line 2",
|
|
"Additional Info Line 3",
|
|
"Additional Info Line 4",
|
|
"Additional Info Line 5",
|
|
"Additional Info Line 6",
|
|
"Additional Info Line 7",
|
|
},
|
|
}
|
|
context := core.NewNullContext()
|
|
|
|
actualData, err := reader.read(context)
|
|
assert.Nil(t, err)
|
|
|
|
assert.Equal(t, 1, len(actualData.Statements))
|
|
|
|
assert.Equal(t, "250601", actualData.Statements[0].ValueDate)
|
|
assert.Equal(t, MT_MARK_DEBIT, actualData.Statements[0].CreditDebitMark)
|
|
assert.Equal(t, "123,45", actualData.Statements[0].Amount)
|
|
assert.Equal(t, "NTRF", actualData.Statements[0].TransactionTypeIdentificationCode)
|
|
assert.Equal(t, "TEST", actualData.Statements[0].ReferenceForAccountOwner)
|
|
assert.Equal(t, 6, len(actualData.Statements[0].InformationToAccountOwner))
|
|
assert.Equal(t, "Additional Info Line 1", actualData.Statements[0].InformationToAccountOwner[0])
|
|
assert.Equal(t, "Additional Info Line 2", actualData.Statements[0].InformationToAccountOwner[1])
|
|
assert.Equal(t, "Additional Info Line 3", actualData.Statements[0].InformationToAccountOwner[2])
|
|
assert.Equal(t, "Additional Info Line 4", actualData.Statements[0].InformationToAccountOwner[3])
|
|
assert.Equal(t, "Additional Info Line 5", actualData.Statements[0].InformationToAccountOwner[4])
|
|
assert.Equal(t, "Additional Info Line 6", actualData.Statements[0].InformationToAccountOwner[5])
|
|
}
|
|
|
|
func TestMT940DataReaderParse_DuplicateBlockHeader(t *testing.T) {
|
|
reader := &mt940DataReader{
|
|
allLines: []string{
|
|
"{1:F01TESTBANK123456789}{2:I940TESTBANK}{4:",
|
|
":20:MT940-2025001",
|
|
":25:123456789",
|
|
":28C:123/1",
|
|
":60F:C250601CNY1234,56",
|
|
"{1:F01TESTBANK123456789}{2:I940TESTBANK}{4:",
|
|
":61:2506010602DY123,45NTRFTEST//ABC123456",
|
|
":86:First Transaction",
|
|
"-}",
|
|
},
|
|
}
|
|
context := core.NewNullContext()
|
|
|
|
actualData, err := reader.read(context)
|
|
assert.Nil(t, err)
|
|
|
|
assert.Equal(t, "", actualData.StatementReferenceNumber)
|
|
assert.Equal(t, "", actualData.AccountId)
|
|
assert.Equal(t, "", actualData.SequentialNumber)
|
|
|
|
assert.Nil(t, actualData.OpeningBalance)
|
|
|
|
assert.Equal(t, 1, len(actualData.Statements))
|
|
|
|
assert.Equal(t, "250601", actualData.Statements[0].ValueDate)
|
|
assert.Equal(t, "0602", actualData.Statements[0].EntryDate)
|
|
assert.Equal(t, MT_MARK_DEBIT, actualData.Statements[0].CreditDebitMark)
|
|
assert.Equal(t, "Y", actualData.Statements[0].FundsCode)
|
|
assert.Equal(t, "123,45", actualData.Statements[0].Amount)
|
|
assert.Equal(t, "NTRF", actualData.Statements[0].TransactionTypeIdentificationCode)
|
|
assert.Equal(t, "TEST", actualData.Statements[0].ReferenceForAccountOwner)
|
|
assert.Equal(t, "ABC123456", actualData.Statements[0].ReferenceOfAccountServicingInstitution)
|
|
}
|
|
|
|
func TestMT940DataReaderParse_EmptyContent(t *testing.T) {
|
|
reader := &mt940DataReader{
|
|
allLines: []string{},
|
|
}
|
|
context := core.NewNullContext()
|
|
|
|
_, err := reader.read(context)
|
|
assert.EqualError(t, err, errs.ErrNotFoundTransactionDataInFile.Message)
|
|
}
|
|
|
|
func TestMT940DataReaderParseBalance_ValidBalance(t *testing.T) {
|
|
reader := &mt940DataReader{}
|
|
context := core.NewNullContext()
|
|
|
|
balance, err := reader.parseBalance(context, "C250601CNY1234,56")
|
|
assert.Nil(t, err)
|
|
assert.Equal(t, MT_MARK_CREDIT, balance.DebitCreditMark)
|
|
assert.Equal(t, "250601", balance.Date)
|
|
assert.Equal(t, "CNY", balance.Currency)
|
|
assert.Equal(t, "1234,56", balance.Amount)
|
|
|
|
balance, err = reader.parseBalance(context, "D250602USD2345,67")
|
|
assert.Nil(t, err)
|
|
assert.Equal(t, MT_MARK_DEBIT, balance.DebitCreditMark)
|
|
assert.Equal(t, "250602", balance.Date)
|
|
assert.Equal(t, "USD", balance.Currency)
|
|
assert.Equal(t, "2345,67", balance.Amount)
|
|
}
|
|
|
|
func TestMT940DataReaderParseBalance_InvalidBalance(t *testing.T) {
|
|
reader := &mt940DataReader{}
|
|
context := core.NewNullContext()
|
|
|
|
_, err := reader.parseBalance(context, "X250601CNY1234,56")
|
|
assert.EqualError(t, err, errs.ErrTransactionTypeInvalid.Message)
|
|
|
|
_, err = reader.parseBalance(context, "C")
|
|
assert.EqualError(t, err, errs.ErrInvalidMT940File.Message)
|
|
}
|
|
|
|
func TestMT940DataReaderParseStatement_ValidFields(t *testing.T) {
|
|
reader := &mt940DataReader{}
|
|
context := core.NewNullContext()
|
|
|
|
statement, err := reader.parseStatement(context, "2506010602RDY123,45NTRFTEST//ABC123456")
|
|
assert.Nil(t, err)
|
|
assert.Equal(t, "250601", statement.ValueDate)
|
|
assert.Equal(t, "0602", statement.EntryDate)
|
|
assert.Equal(t, MT_MARK_REVERSAL_DEBIT, statement.CreditDebitMark)
|
|
assert.Equal(t, "Y", statement.FundsCode)
|
|
assert.Equal(t, "123,45", statement.Amount)
|
|
assert.Equal(t, "NTRF", statement.TransactionTypeIdentificationCode)
|
|
assert.Equal(t, "TEST", statement.ReferenceForAccountOwner)
|
|
assert.Equal(t, "ABC123456", statement.ReferenceOfAccountServicingInstitution)
|
|
|
|
statement, err = reader.parseStatement(context, "250601RC234,56NSTFFOOBAR")
|
|
assert.Nil(t, err)
|
|
assert.Equal(t, "250601", statement.ValueDate)
|
|
assert.Equal(t, "", statement.EntryDate)
|
|
assert.Equal(t, MT_MARK_REVERSAL_CREDIT, statement.CreditDebitMark)
|
|
assert.Equal(t, "234,56", statement.Amount)
|
|
assert.Equal(t, "NSTF", statement.TransactionTypeIdentificationCode)
|
|
assert.Equal(t, "FOOBAR", statement.ReferenceForAccountOwner)
|
|
}
|
|
|
|
func TestMT940DataReaderParseStatement_InvalidField(t *testing.T) {
|
|
reader := &mt940DataReader{}
|
|
context := core.NewNullContext()
|
|
|
|
_, err := reader.parseStatement(context, "250601X123,45NTRFTest")
|
|
assert.EqualError(t, err, errs.ErrTransactionTypeInvalid.Message)
|
|
}
|
|
|
|
func TestMT940DataReaderParseStatement_MissingField(t *testing.T) {
|
|
reader := &mt940DataReader{}
|
|
context := core.NewNullContext()
|
|
|
|
// Missing entry date
|
|
_, err := reader.parseStatement(context, "2406")
|
|
assert.EqualError(t, err, errs.ErrInvalidMT940File.Message)
|
|
|
|
// Missing debit/credit mark
|
|
_, err = reader.parseStatement(context, "250601060234,56NTRFTEST//ABC123456")
|
|
assert.EqualError(t, err, errs.ErrTransactionTypeInvalid.Message)
|
|
|
|
// Missing amount
|
|
_, err = reader.parseStatement(context, "250601DNTRFTEST//ABC123456")
|
|
assert.EqualError(t, err, errs.ErrAmountInvalid.Message)
|
|
|
|
// Missing transaction type identification code
|
|
_, err = reader.parseStatement(context, "250601D234,56TEST//ABC123456")
|
|
assert.EqualError(t, err, errs.ErrInvalidMT940File.Message)
|
|
|
|
// Missing reference for account owner
|
|
_, err = reader.parseStatement(context, "250601D234,56NTRF//ABC123456")
|
|
assert.EqualError(t, err, errs.ErrInvalidMT940File.Message)
|
|
}
|