2019-10-12 23:12:37 +00:00
package net.dankito.fints
2020-04-23 22:50:14 +00:00
import net.dankito.fints.banks.InMemoryBankFinder
2020-04-28 16:34:11 +00:00
import net.dankito.fints.callback.FinTsClientCallback
2019-10-12 23:12:37 +00:00
import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Laenderkennzeichen
import net.dankito.fints.messages.datenelemente.implementierte.Dialogsprache
import net.dankito.fints.messages.datenelemente.implementierte.KundensystemStatus
import net.dankito.fints.messages.datenelemente.implementierte.KundensystemStatusWerte
2019-12-29 14:07:05 +00:00
import net.dankito.fints.messages.datenelemente.implementierte.tan.TanEinsatzOption
2019-12-30 21:30:53 +00:00
import net.dankito.fints.messages.datenelemente.implementierte.tan.TanGeneratorTanMedium
2019-12-29 14:07:05 +00:00
import net.dankito.fints.messages.datenelemente.implementierte.tan.TanMedienArtVersion
2019-12-29 16:47:41 +00:00
import net.dankito.fints.messages.datenelemente.implementierte.tan.TanMediumKlasse
2020-01-20 23:54:06 +00:00
import net.dankito.fints.messages.segmente.id.CustomerSegmentId
2019-10-12 23:12:37 +00:00
import net.dankito.fints.model.*
2019-10-20 22:51:21 +00:00
import net.dankito.fints.model.mapper.BankDataMapper
2019-10-13 16:54:12 +00:00
import net.dankito.fints.response.client.FinTsClientResponse
2019-10-12 23:12:37 +00:00
import net.dankito.fints.util.Java8Base64Service
import org.assertj.core.api.Assertions.assertThat
2019-12-30 21:30:53 +00:00
import org.junit.Assert
2019-10-12 23:12:37 +00:00
import org.junit.Ignore
import org.junit.Test
2020-05-12 17:04:38 +00:00
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.util.*
2019-10-20 22:47:01 +00:00
import java.util.concurrent.atomic.AtomicBoolean
2019-10-12 23:12:37 +00:00
@Ignore // not an automatic test, supply your settings below
class FinTsClientTest {
2020-05-12 17:04:38 +00:00
companion object {
val DateTimeFormatForUniqueBankTransferUsage = DateTimeFormatter . ofPattern ( " yyyy-MM-dd'T'HH:mm:ss.SSS " )
}
2019-10-20 22:47:01 +00:00
private val didAskUserForTanProcedure = AtomicBoolean ( false )
private val didAskUserToEnterTan = AtomicBoolean ( false )
2019-10-15 16:23:03 +00:00
private val callback = object : FinTsClientCallback {
2019-10-13 16:54:12 +00:00
2020-01-19 15:50:26 +00:00
override fun askUserForTanProcedure ( supportedTanProcedures : List < TanProcedure > , suggestedTanProcedure : TanProcedure ? ) : TanProcedure ? {
return suggestedTanProcedure // simply return suggestedTanProcedure as in most cases it's the best fitting one
}
2019-12-31 15:01:00 +00:00
override fun enterTan ( customer : CustomerData , tanChallenge : TanChallenge ) : EnterTanResult {
2019-10-20 22:47:01 +00:00
didAskUserToEnterTan . set ( true )
2019-12-31 15:01:00 +00:00
return EnterTanResult . userDidNotEnterTan ( )
2019-10-16 12:11:19 +00:00
}
2020-01-01 17:49:47 +00:00
override fun enterTanGeneratorAtc ( customer : CustomerData , tanMedium : TanGeneratorTanMedium ) : EnterTanGeneratorAtcResult {
2019-12-30 21:30:53 +00:00
Assert . fail ( " Bank asks you to synchronize your TAN generator for card ${tanMedium.cardNumber} " +
2019-12-30 23:22:23 +00:00
" (card sequence number ${tanMedium.cardSequenceNumber} ). Please do this via your online banking portal or Banking UI. " )
2020-01-01 17:49:47 +00:00
return EnterTanGeneratorAtcResult . userDidNotEnterTan ( ) // should actually never be called
2019-12-30 21:30:53 +00:00
}
2019-10-15 16:23:03 +00:00
}
private val underTest = object : FinTsClient ( callback , Java8Base64Service ( ) ) {
fun testSynchronizeCustomerSystemId ( bank : BankData , customer : CustomerData ) : FinTsClientResponse {
2019-10-13 16:54:12 +00:00
return synchronizeCustomerSystemId ( bank , customer )
}
}
2019-10-12 23:12:37 +00:00
2019-10-20 22:56:44 +00:00
private val BankDataAnonymous = BankData ( " 10070000 " , Laenderkennzeichen . Germany , " https://fints.deutsche-bank.de/ " , " DEUTDEBBXXX " )
2019-10-12 23:12:37 +00:00
// TODO: add your settings here:
2020-04-23 22:50:14 +00:00
private val bankInfo = InMemoryBankFinder ( ) . findBankByBankCode ( " <your bank code (BLZ) here> " ) . first ( )
2019-10-20 22:51:21 +00:00
private val Bank = BankDataMapper ( ) . mapFromBankInfo ( bankInfo )
private val Customer = CustomerData ( " <your customer id (Kontonummer) here> " , " <your PIN here> " )
2019-10-12 23:12:37 +00:00
@Test
fun getAnonymousBankInfo ( ) {
// when
2019-10-13 15:24:47 +00:00
val result = underTest . getAnonymousBankInfo ( BankDataAnonymous )
2019-10-12 23:12:37 +00:00
// then
2019-10-13 17:44:16 +00:00
assertThat ( result . isSuccessful ) . isTrue ( )
2019-10-15 21:36:59 +00:00
assertThat ( BankDataAnonymous . supportedHbciVersions ) . isNotEmpty ( )
assertThat ( BankDataAnonymous . supportedTanProcedures ) . isNotEmpty ( )
assertThat ( BankDataAnonymous . supportedJobs ) . isNotEmpty ( )
assertThat ( BankDataAnonymous . supportedLanguages ) . isNotEmpty ( )
assertThat ( BankDataAnonymous . name ) . isNotEmpty ( )
2019-10-12 23:12:37 +00:00
}
2019-10-20 22:47:01 +00:00
@Test
2019-10-30 22:02:59 +00:00
fun addAccount ( ) {
2019-10-20 22:47:01 +00:00
// when
2019-10-30 22:02:59 +00:00
val result = underTest . addAccount ( Bank , Customer )
2019-10-20 22:47:01 +00:00
// then
assertThat ( result . isSuccessful ) . isTrue ( )
assertThat ( didAskUserForTanProcedure ) . isFalse ( )
assertThat ( Bank . name ) . isNotEmpty ( )
assertThat ( Bank . supportedJobs ) . isNotEmpty ( ) // supported jobs are now known
assertThat ( Bank . supportedTanProcedures ) . isNotEmpty ( ) // supported tan procedures are now known
assertThat ( Bank . supportedHbciVersions ) . isNotEmpty ( ) // supported HBIC versions are now known
assertThat ( Bank . supportedLanguages ) . isNotEmpty ( ) // supported languages are now known
assertThat ( Customer . name ) . isNotEmpty ( )
assertThat ( Customer . supportedTanProcedures ) . isNotEmpty ( )
assertThat ( Customer . selectedLanguage ) . isNotEqualTo ( Dialogsprache . Default ) // language is set now
assertThat ( Customer . customerSystemId ) . isNotEqualTo ( KundensystemStatus . SynchronizingCustomerSystemId ) // customer system id is now set
assertThat ( Customer . customerSystemStatus ) . isEqualTo ( KundensystemStatusWerte . Benoetigt ) // customerSystemStatus is set now
assertThat ( Customer . accounts ) . isNotEmpty ( ) // accounts are now known
assertThat ( Customer . accounts . first ( ) . allowedJobs ) . isNotEmpty ( ) // allowed jobs are now known
}
2019-10-12 23:12:37 +00:00
@Test
fun synchronizeCustomerSystemId ( ) {
// when
2019-10-15 16:23:03 +00:00
val result = underTest . testSynchronizeCustomerSystemId ( Bank , Customer )
2019-10-12 23:12:37 +00:00
// then
2019-10-13 17:44:16 +00:00
assertThat ( result . isSuccessful ) . isTrue ( )
2019-10-12 23:12:37 +00:00
assertThat ( Customer . customerSystemId ) . isNotEqualTo ( KundensystemStatus . SynchronizingCustomerSystemId ) // customer system id is now set
assertThat ( Customer . selectedLanguage ) . isNotEqualTo ( Dialogsprache . Default ) // language is set now
assertThat ( Customer . customerSystemStatus ) . isEqualTo ( KundensystemStatusWerte . Benoetigt ) // customerSystemStatus is set now
}
@Test
fun getTransactions ( ) {
2020-01-20 23:54:06 +00:00
// given
underTest . addAccount ( Bank , Customer ) // retrieve basic data, e.g. accounts
2020-05-12 22:06:24 +00:00
val account = Customer . accounts . firstOrNull { it . allowedJobNames . contains ( CustomerSegmentId . AccountTransactionsMt940 . id ) }
2020-01-20 23:54:06 +00:00
assertThat ( account ) . describedAs ( " We need at least one account that supports retrieving account transactions ( ${CustomerSegmentId.AccountTransactionsMt940.id} ) " ) . isNotNull ( )
2019-10-13 18:12:04 +00:00
// when
2019-10-12 23:12:37 +00:00
// some banks support retrieving account transactions of last 90 days without TAN
2020-01-20 23:54:06 +00:00
val result = underTest . tryGetTransactionsOfLast90DaysWithoutTan ( Bank , Customer , account !! , false )
2019-10-12 23:12:37 +00:00
// then
2019-10-13 17:44:16 +00:00
assertThat ( result . isSuccessful ) . isTrue ( )
2019-10-13 16:08:42 +00:00
assertThat ( result . bookedTransactions ) . isNotEmpty ( )
2019-10-12 23:12:37 +00:00
}
2019-12-29 14:07:05 +00:00
@Test
fun getTanMediaList ( ) {
2019-12-29 16:51:52 +00:00
assertThat ( Customer . tanMedia ) . isEmpty ( )
2019-12-29 14:07:05 +00:00
// when
2019-12-29 16:47:41 +00:00
val result = underTest . getTanMediaList ( Bank , Customer , TanMedienArtVersion . Alle , TanMediumKlasse . AlleMedien )
2019-12-29 14:07:05 +00:00
// then
assertThat ( result . isSuccessful ) . isTrue ( )
assertThat ( result . tanMediaList ) . isNotNull ( )
assertThat ( result . tanMediaList !! . usageOption ) . isEqualByComparingTo ( TanEinsatzOption . KundeKannGenauEinMediumZuEinerZeitNutzen ) // TODO: may adjust to your value
assertThat ( result . tanMediaList !! . tanMedia ) . isNotEmpty ( )
2019-12-29 16:51:52 +00:00
assertThat ( Customer . tanMedia ) . isNotEmpty ( )
2019-12-29 14:07:05 +00:00
}
@Ignore // only works with banks that don't support HKTAB version 5
@Test ( expected = UnsupportedOperationException :: class )
fun getTanMediaList _UnsupportedTanMediumClass ( ) {
// when
2019-12-29 16:47:41 +00:00
underTest . getTanMediaList ( Bank , Customer , TanMedienArtVersion . Alle , TanMediumKlasse . BilateralVereinbart )
2019-12-29 14:07:05 +00:00
// then
// exception gets thrown
}
2019-10-12 23:12:37 +00:00
@Test
fun testBankTransfer ( ) {
2019-10-20 22:47:01 +00:00
// given
2020-01-20 23:54:06 +00:00
underTest . addAccount ( Bank , Customer ) // retrieve basic data, e.g. accounts
// we need at least one account that supports cash transfer
val account = Customer . accounts . firstOrNull { it . allowedJobNames . contains ( CustomerSegmentId . SepaBankTransfer . id ) }
assertThat ( account ) . describedAs ( " We need at least one account that supports cash transfer ( ${CustomerSegmentId.SepaBankTransfer.id} ) " ) . isNotNull ( )
2019-10-20 22:47:01 +00:00
2020-01-20 23:54:06 +00:00
// IBAN should be set
assertThat ( account ?. iban ) . describedAs ( " Account IBAN must be set " ) . isNotNull ( )
2019-10-20 22:47:01 +00:00
// transfer 1 cent to yourself. Transferring money to oneself also doesn't require to enter a TAN according to PSD2
2020-05-12 17:04:38 +00:00
val BankTransferData = BankTransferData ( Customer . name , account ?. iban !! , Bank . bic , 0.01 . toBigDecimal ( ) ,
" ${DateTimeFormatForUniqueBankTransferUsage.format(LocalDateTime.now())} Test transaction ${UUID.randomUUID()} " )
2019-10-20 22:47:01 +00:00
2019-10-12 23:12:37 +00:00
// when
2020-01-20 23:54:06 +00:00
val result = underTest . doBankTransfer ( BankTransferData , Bank , Customer , account )
2019-10-12 23:12:37 +00:00
// then
2019-10-13 17:44:16 +00:00
assertThat ( result . isSuccessful ) . isTrue ( )
2019-10-12 23:12:37 +00:00
}
}