mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 11:06:49 +00:00
Add `technology` field to `implemented_by` JSON to indicate whether an endpoint is implemented using lift or http4s. The field is included only when `includeTechnologyInResponse` is true, which is set for API versions 6.0.0 and 7.0.0. This helps API consumers understand the underlying implementation technology. Update tests to verify technology field presence/absence based on API version. Also improve test setup robustness by making user and account creation idempotent, and update build dependencies to support http4s and pekko.
227 lines
8.5 KiB
Scala
227 lines
8.5 KiB
Scala
package code.setup
|
|
|
|
import bootstrap.liftweb.ToSchemify
|
|
import code.api.JedisMethod
|
|
import code.api.cache.Redis
|
|
import code.api.util.APIUtil
|
|
import code.api.util.ErrorMessages._
|
|
import code.entitlement.Entitlement
|
|
import code.metadata.counterparties.Counterparties
|
|
import code.model._
|
|
import code.model.dataAccess._
|
|
import code.transaction.MappedTransaction
|
|
import code.transactionrequests.MappedTransactionRequest
|
|
import code.util.Helper.MdcLoggable
|
|
import com.openbankproject.commons.model._
|
|
import com.openbankproject.commons.model.enums.AccountRoutingScheme
|
|
import com.openbankproject.commons.model.enums._
|
|
import net.liftweb.common.Box
|
|
import net.liftweb.mapper.{By, MetaMapper}
|
|
import net.liftweb.util.Helpers._
|
|
import org.iban4j
|
|
|
|
import java.util.Date
|
|
import scala.util.Random
|
|
|
|
trait LocalMappedConnectorTestSetup extends TestConnectorSetupWithStandardPermissions with MdcLoggable{
|
|
//TODO: replace all these helpers with connector agnostic methods like createRandomBank
|
|
// that call Connector.createBank etc.
|
|
// (same in LocalRecordConnectorTestSetup)
|
|
// Tests should simply use the currently selected connector
|
|
override protected def createBank(id : String) : Bank = {
|
|
//Note: we do not have the `UniqueIndex` for bank.id(permalink) yet, we but when we have getBankById endpoint,
|
|
//Better set only create one bank for one id.
|
|
MappedBank.findByBankId(BankId(id)).getOrElse(
|
|
MappedBank.create
|
|
.fullBankName(randomString(5))
|
|
.shortBankName(randomString(5))
|
|
.permalink(id)
|
|
.national_identifier(randomString(5))
|
|
.mBankRoutingScheme(randomString(5))
|
|
.mBankRoutingAddress(randomString(5))
|
|
.saveMe)
|
|
}
|
|
|
|
override protected def createCounterparty(bankId: String, accountId: String, counterpartyObpRoutingAddress: String, isBeneficiary: Boolean, createdByUserId:String): CounterpartyTrait = {
|
|
Counterparties.counterparties.vend.createCounterparty(
|
|
createdByUserId = createdByUserId,
|
|
thisBankId = bankId,
|
|
thisAccountId = accountId,
|
|
thisViewId = "",
|
|
name = APIUtil.generateUUID(),
|
|
otherAccountRoutingScheme = "OBP",
|
|
otherAccountRoutingAddress = counterpartyObpRoutingAddress,
|
|
otherBankRoutingScheme = "OBP",
|
|
otherBankRoutingAddress = bankId,
|
|
otherBranchRoutingScheme ="OBP",
|
|
otherBranchRoutingAddress ="Berlin",
|
|
isBeneficiary = isBeneficiary,
|
|
otherAccountSecondaryRoutingScheme ="IBAN",
|
|
otherAccountSecondaryRoutingAddress ="DE89 3704 0044 0532 0130 00",
|
|
description = "String",
|
|
currency = "String",
|
|
bespoke = Nil
|
|
).openOrThrowException(attemptedToOpenAnEmptyBox)
|
|
}
|
|
|
|
override protected def createAccount(bankId: BankId, accountId : AccountId, currency : String) : BankAccount = {
|
|
def getOrCreateRouting(scheme: String, address: String): Unit = {
|
|
val existing = BankAccountRouting.find(
|
|
By(BankAccountRouting.BankId, bankId.value),
|
|
By(BankAccountRouting.AccountId, accountId.value),
|
|
By(BankAccountRouting.AccountRoutingScheme, scheme)
|
|
)
|
|
if (!existing.isDefined) {
|
|
try {
|
|
BankAccountRouting.create
|
|
.BankId(bankId.value)
|
|
.AccountId(accountId.value)
|
|
.AccountRoutingScheme(scheme)
|
|
.AccountRoutingAddress(address)
|
|
.saveMe
|
|
} catch {
|
|
case _: Throwable =>
|
|
}
|
|
}
|
|
()
|
|
}
|
|
|
|
getOrCreateRouting(AccountRoutingScheme.IBAN.toString, iban4j.Iban.random().toString())
|
|
getOrCreateRouting("AccountId", accountId.value)
|
|
|
|
val existingAccount = MappedBankAccount.find(
|
|
By(MappedBankAccount.bank, bankId.value),
|
|
By(MappedBankAccount.theAccountId, accountId.value)
|
|
)
|
|
existingAccount.openOr {
|
|
try {
|
|
MappedBankAccount.create
|
|
.bank(bankId.value)
|
|
.theAccountId(accountId.value)
|
|
.accountCurrency(currency.toUpperCase)
|
|
.accountBalance(900000000)
|
|
.holder(randomString(4))
|
|
.accountLastUpdate(now)
|
|
.accountName(randomString(4))
|
|
.accountNumber(randomString(4))
|
|
.accountLabel(randomString(4))
|
|
.mBranchId(randomString(4))
|
|
.saveMe
|
|
} catch {
|
|
case _: Throwable =>
|
|
MappedBankAccount.find(
|
|
By(MappedBankAccount.bank, bankId.value),
|
|
By(MappedBankAccount.theAccountId, accountId.value)
|
|
).openOrThrowException(attemptedToOpenAnEmptyBox)
|
|
}
|
|
}
|
|
}
|
|
|
|
override protected def updateAccountCurrency(bankId: BankId, accountId : AccountId, currency : String) : BankAccount = {
|
|
MappedBankAccount.find(By(MappedBankAccount.bank, bankId.value), By(MappedBankAccount.theAccountId, accountId.value)).openOrThrowException(attemptedToOpenAnEmptyBox).accountCurrency(currency.toUpperCase).saveMe()
|
|
}
|
|
|
|
def addEntitlement(bankId: String, userId: String, roleName: String): Box[Entitlement] = {
|
|
// Return a Box so we can handle errors later.
|
|
Entitlement.entitlement.vend.addEntitlement(bankId, userId, roleName)
|
|
}
|
|
|
|
override protected def createTransaction(account: BankAccount, startDate: Date, finishDate: Date, isCompleted: Boolean) = {
|
|
//ugly
|
|
val mappedBankAccount = account.asInstanceOf[MappedBankAccount]
|
|
|
|
val accountBalanceBefore = mappedBankAccount.accountBalance.get
|
|
val transactionAmount = Random.nextInt(1000).toLong
|
|
val accountBalanceAfter = accountBalanceBefore + transactionAmount
|
|
|
|
mappedBankAccount.accountBalance(accountBalanceAfter).save
|
|
|
|
// Determine transaction status based on isCompleted parameter
|
|
val transactionStatus = if (isCompleted) {
|
|
TransactionRequestStatus.COMPLETED.toString
|
|
} else {
|
|
TransactionRequestStatus.INITIATED.toString
|
|
}
|
|
|
|
MappedTransaction.create
|
|
.bank(account.bankId.value)
|
|
.account(account.accountId.value)
|
|
.transactionType(randomString(5))
|
|
.tStartDate(startDate)
|
|
.tFinishDate(finishDate)
|
|
.currency(account.currency)
|
|
.amount(transactionAmount)
|
|
.newAccountBalance(accountBalanceAfter)
|
|
.description(randomString(5))
|
|
.counterpartyAccountHolder(randomString(5))
|
|
.counterpartyAccountKind(randomString(5))
|
|
.counterpartyAccountNumber(randomString(5))
|
|
.counterpartyBankName(randomString(5))
|
|
.counterpartyIban(randomString(5))
|
|
.counterpartyNationalId(randomString(5))
|
|
.CPOtherAccountRoutingScheme(randomString(5))
|
|
.CPOtherAccountRoutingAddress(randomString(5))
|
|
.CPOtherAccountSecondaryRoutingScheme(randomString(5))
|
|
.CPOtherAccountSecondaryRoutingAddress(randomString(5))
|
|
.CPOtherBankRoutingScheme(randomString(5))
|
|
.CPOtherBankRoutingAddress(randomString(5))
|
|
.status(transactionStatus) // Use determined transaction status
|
|
.saveMe
|
|
.toTransaction.orNull
|
|
}
|
|
|
|
override protected def createTransactionRequest(account: BankAccount): List[MappedTransactionRequest] = {
|
|
|
|
val firstRequest = MappedTransactionRequest.create
|
|
.mTransactionRequestId(APIUtil.generateUUID())
|
|
.mType("SANDBOX_TAN")
|
|
.mFrom_BankId(account.bankId.value)
|
|
.mFrom_AccountId(account.accountId.value)
|
|
.mTo_BankId(randomString(5))
|
|
.mTo_AccountId(randomString(5))
|
|
.mBody_Value_Currency(account.currency)
|
|
.mBody_Value_Amount("10")
|
|
.mBody_Description("This is a description..")
|
|
.mStatus("COMPLETED")
|
|
.mStartDate(now)
|
|
.mEndDate(now)
|
|
.saveMe
|
|
|
|
val secondRequest = MappedTransactionRequest.create
|
|
.mTransactionRequestId(APIUtil.generateUUID())
|
|
.mType("SANDBOX_TAN")
|
|
.mFrom_BankId(account.bankId.value)
|
|
.mFrom_AccountId(account.accountId.value)
|
|
.mTo_BankId(randomString(5))
|
|
.mTo_AccountId(randomString(5))
|
|
.mBody_Value_Currency(account.currency)
|
|
.mBody_Value_Amount("1001")
|
|
.mBody_Description("This is a description..")
|
|
.mStatus("INITIATED")
|
|
.mStartDate(now)
|
|
.mEndDate(now)
|
|
.saveMe
|
|
|
|
List(firstRequest, secondRequest)
|
|
}
|
|
|
|
override protected def wipeTestData() = {
|
|
//returns true if the model should not be wiped after each test
|
|
def exclusion(m : MetaMapper[_]) = {
|
|
m == Nonce || m == Token || m == Consumer || m == AuthUser || m == ResourceUser
|
|
}
|
|
|
|
//empty the relational db tables after each test
|
|
ToSchemify.models.filterNot(exclusion).foreach(_.bulkDelete_!!())
|
|
|
|
// Flush all data from Redis
|
|
try {
|
|
Redis.use(JedisMethod.FLUSHDB, "")
|
|
} catch {
|
|
case e: Throwable =>
|
|
logger.warn("------------| Redis issue during flushing data |------------")
|
|
logger.warn(e)
|
|
}
|
|
}
|
|
}
|