mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 17:56:46 +00:00
Merge in changes from develop
This commit is contained in:
commit
50067e5632
@ -39,6 +39,8 @@ import code.metadata.tags.MappedTag
|
||||
import code.metadata.transactionimages.MappedTransactionImage
|
||||
import code.metadata.wheretags.MappedWhereTag
|
||||
import code.metrics.MappedMetric
|
||||
import code.bankbranches.{MappedBankBranch, MappedDataLicense}
|
||||
import code.customerinfo.{MappedCustomerMessage, MappedCustomerInfo}
|
||||
import net.liftweb._
|
||||
import util._
|
||||
import common._
|
||||
@ -176,6 +178,7 @@ class Boot extends Loggable{
|
||||
LiftRules.statelessDispatch.append(v1_2.OBPAPI1_2)
|
||||
LiftRules.statelessDispatch.append(v1_2_1.OBPAPI1_2_1)
|
||||
LiftRules.statelessDispatch.append(v1_3_0.OBPAPI1_3_0)
|
||||
LiftRules.statelessDispatch.append(v1_4_0.OBPAPI1_4_0)
|
||||
|
||||
// add other apis
|
||||
LiftRules.statelessDispatch.append(BankMockAPI)
|
||||
@ -327,5 +330,7 @@ object ToSchemify {
|
||||
ViewPrivileges, ViewImpl, APIUser, MappedAccountHolder,
|
||||
MappedComment, MappedNarrative, MappedTag,
|
||||
MappedTransactionImage, MappedWhereTag, MappedCounterpartyMetadata,
|
||||
MappedCounterpartyWhereTag, MappedBank, MappedBankAccount, MappedTransaction, MappedMetric)
|
||||
MappedCounterpartyWhereTag, MappedBank, MappedBankAccount, MappedTransaction,
|
||||
MappedMetric, MappedCustomerInfo, MappedCustomerMessage,
|
||||
MappedBankBranch, MappedDataLicense)
|
||||
}
|
||||
|
||||
86
src/main/scala/code/api/v1_4_0/APIMethods140.scala
Normal file
86
src/main/scala/code/api/v1_4_0/APIMethods140.scala
Normal file
@ -0,0 +1,86 @@
|
||||
package code.api.v1_4_0
|
||||
|
||||
import code.api.APIFailure
|
||||
import code.api.v1_4_0.JSONFactory1_4_0.AddCustomerMessageJson
|
||||
import code.bankbranches.BankBranches
|
||||
import code.customerinfo.{CustomerMessages, CustomerInfo}
|
||||
import code.model.{BankId, User}
|
||||
import net.liftweb.common.Box
|
||||
import net.liftweb.http.js.JE.JsRaw
|
||||
import net.liftweb.http.{JsonResponse, Req}
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import code.api.util.APIUtil._
|
||||
import net.liftweb.json.Extraction
|
||||
import net.liftweb.json.JsonAST.JObject
|
||||
import net.liftweb.util.Helpers.tryo
|
||||
import code.util.Helper._
|
||||
|
||||
trait APIMethods140 {
|
||||
//needs to be a RestHelper to get access to JsonGet, JsonPost, etc.
|
||||
self: RestHelper =>
|
||||
|
||||
|
||||
val Implementations1_4_0 = new Object(){
|
||||
|
||||
lazy val getCustomerInfo : PartialFunction[Req, Box[User] => Box[JsonResponse]] = {
|
||||
case "banks" :: BankId(bankId) :: "customer" :: Nil JsonGet _ => {
|
||||
user => {
|
||||
for {
|
||||
u <- user ?~! "User must be logged in to retrieve customer info"
|
||||
info <- CustomerInfo.customerInfoProvider.vend.getInfo(bankId, u) ~> APIFailure("No customer info found", 404)
|
||||
} yield {
|
||||
val json = JSONFactory1_4_0.createCustomerInfoJson(info)
|
||||
successJsonResponse(Extraction.decompose(json))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lazy val getCustomerMessages : PartialFunction[Req, Box[User] => Box[JsonResponse]] = {
|
||||
case "banks" :: BankId(bankId) :: "customer" :: "messages" :: Nil JsonGet _ => {
|
||||
user => {
|
||||
for {
|
||||
u <- user ?~! "User must be logged in to retrieve customer messages"
|
||||
} yield {
|
||||
val messages = CustomerMessages.customerMessageProvider.vend.getMessages(u, bankId)
|
||||
val json = JSONFactory1_4_0.createCustomerMessagesJson(messages)
|
||||
successJsonResponse(Extraction.decompose(json))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lazy val addCustomerMessage : PartialFunction[Req, Box[User] => Box[JsonResponse]] = {
|
||||
case "banks" :: BankId(bankId) :: "customer" :: customerNumber :: "messages" :: Nil JsonPost json -> _ => {
|
||||
user => {
|
||||
for {
|
||||
postedData <- tryo{json.extract[AddCustomerMessageJson]} ?~! "Incorrect json format"
|
||||
customer <- CustomerInfo.customerInfoProvider.vend.getUser(bankId, customerNumber) ?~! "No customer found"
|
||||
messageCreated <- booleanToBox(
|
||||
CustomerMessages.customerMessageProvider.vend.addMessage(
|
||||
customer, bankId, postedData.message, postedData.from_department, postedData.from_person),
|
||||
"Server error: could not add message")
|
||||
} yield {
|
||||
successJsonResponse(JsRaw("{}"), 201)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lazy val getBranches : PartialFunction[Req, Box[User] => Box[JsonResponse]] = {
|
||||
case "banks" :: BankId(bankId) :: "branches" :: Nil JsonGet _ => {
|
||||
user => {
|
||||
for {
|
||||
branches <- Box(BankBranches.bankBranchesProvider.vend.getBranches(bankId)) ~> APIFailure("No branch data available", 404)
|
||||
} yield {
|
||||
val json = JSONFactory1_4_0.createBranchesJson(branches)
|
||||
successJsonResponse(Extraction.decompose(json))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
63
src/main/scala/code/api/v1_4_0/JSONFactory1_4_0.scala
Normal file
63
src/main/scala/code/api/v1_4_0/JSONFactory1_4_0.scala
Normal file
@ -0,0 +1,63 @@
|
||||
package code.api.v1_4_0
|
||||
|
||||
import java.util.Date
|
||||
|
||||
import code.bankbranches.BankBranches
|
||||
import code.bankbranches.BankBranches.{BankBranch, DataLicense, BranchData}
|
||||
import code.customerinfo.{CustomerMessage, CustomerInfo}
|
||||
|
||||
object JSONFactory1_4_0 {
|
||||
|
||||
case class CustomerInfoJson(customer_number : String,
|
||||
legal_name : String,
|
||||
mobile_phone_number : String,
|
||||
email : String,
|
||||
face_image : CustomerFaceImageJson)
|
||||
|
||||
case class CustomerFaceImageJson(url : String, date : Date)
|
||||
|
||||
case class CustomerMessagesJson(messages : List[CustomerMessageJson])
|
||||
case class CustomerMessageJson(id : String, date : Date, message : String, from_department : String, from_person : String)
|
||||
|
||||
case class AddCustomerMessageJson(message : String, from_department : String, from_person : String)
|
||||
|
||||
case class BranchDataJson(license : DataLicenseJson, branches : List[BranchJson])
|
||||
case class DataLicenseJson(name : String, url : String)
|
||||
case class BranchJson(id : String, name : String, address : AddressJson)
|
||||
case class AddressJson(line_1 : String, line_2 : String, line_3 : String, line_4 : String, line_5 : String, postcode_zip : String, country : String)
|
||||
|
||||
def createCustomerInfoJson(cInfo : CustomerInfo) : CustomerInfoJson = {
|
||||
|
||||
CustomerInfoJson(customer_number = cInfo.number,
|
||||
legal_name = cInfo.legalName, mobile_phone_number = cInfo.mobileNumber,
|
||||
email = cInfo.email, face_image = CustomerFaceImageJson(url = cInfo.faceImage.url, date = cInfo.faceImage.date))
|
||||
|
||||
}
|
||||
|
||||
def createCustomerMessageJson(cMessage : CustomerMessage) : CustomerMessageJson = {
|
||||
CustomerMessageJson(id = cMessage.messageId, date = cMessage.date,
|
||||
message = cMessage.message, from_department = cMessage.fromDepartment,
|
||||
from_person = cMessage.fromPerson)
|
||||
}
|
||||
|
||||
def createCustomerMessagesJson(messages : List[CustomerMessage]) : CustomerMessagesJson = {
|
||||
CustomerMessagesJson(messages.map(createCustomerMessageJson))
|
||||
}
|
||||
|
||||
def createDataLicenseJson(dataLicense : DataLicense) : DataLicenseJson = {
|
||||
DataLicenseJson(dataLicense.name, dataLicense.url)
|
||||
}
|
||||
|
||||
def createAddressJson(address : BankBranches.Address) : AddressJson = {
|
||||
AddressJson(address.line1, address.line2, address.line3, address.line4, address.line5, address.postCode, address.countryCode)
|
||||
}
|
||||
|
||||
def createBranchJson(bankBranch: BankBranch) : BranchJson = {
|
||||
BranchJson(bankBranch.branchId.value, bankBranch.name, createAddressJson(bankBranch.address))
|
||||
}
|
||||
|
||||
def createBranchesJson(branchData : BranchData) : BranchDataJson = {
|
||||
BranchDataJson(createDataLicenseJson(branchData.license), branchData.branches.map(createBranchJson))
|
||||
}
|
||||
|
||||
}
|
||||
20
src/main/scala/code/api/v1_4_0/OBPAPI1_4_0.scala
Normal file
20
src/main/scala/code/api/v1_4_0/OBPAPI1_4_0.scala
Normal file
@ -0,0 +1,20 @@
|
||||
package code.api.v1_4_0
|
||||
|
||||
import code.api.OBPRestHelper
|
||||
import net.liftweb.common.Loggable
|
||||
|
||||
object OBPAPI1_4_0 extends OBPRestHelper with APIMethods140 with Loggable {
|
||||
|
||||
|
||||
val VERSION = "1.4.0"
|
||||
|
||||
val routes = List(
|
||||
Implementations1_4_0.getCustomerInfo,
|
||||
Implementations1_4_0.getCustomerMessages,
|
||||
Implementations1_4_0.addCustomerMessage,
|
||||
Implementations1_4_0.getBranches)
|
||||
|
||||
routes.foreach(route => {
|
||||
oauthServe(apiPrefix{route})
|
||||
})
|
||||
}
|
||||
60
src/main/scala/code/bankbranches/BankBranches.scala
Normal file
60
src/main/scala/code/bankbranches/BankBranches.scala
Normal file
@ -0,0 +1,60 @@
|
||||
package code.bankbranches
|
||||
|
||||
import code.bankbranches.BankBranches.{BankBranch, DataLicense, BranchData}
|
||||
import code.model.BankId
|
||||
import net.liftweb.common.Logger
|
||||
import net.liftweb.util.SimpleInjector
|
||||
|
||||
object BankBranches extends SimpleInjector {
|
||||
|
||||
case class BankBranchId(value : String)
|
||||
case class BranchData(branches : List[BankBranch], license : DataLicense)
|
||||
|
||||
trait DataLicense {
|
||||
def name : String
|
||||
def url : String
|
||||
}
|
||||
|
||||
trait BankBranch {
|
||||
def branchId : BankBranchId
|
||||
def name : String
|
||||
def address : Address
|
||||
}
|
||||
|
||||
trait Address {
|
||||
def line1 : String
|
||||
def line2 : String
|
||||
def line3 : String
|
||||
def line4 : String
|
||||
def line5 : String
|
||||
def postCode : String
|
||||
//ISO_3166-1_alpha-2
|
||||
def countryCode : String
|
||||
}
|
||||
|
||||
val bankBranchesProvider = new Inject(buildOne _) {}
|
||||
|
||||
def buildOne: BankBranchesProvider = MappedBankBranchesProvider
|
||||
|
||||
}
|
||||
|
||||
trait BankBranchesProvider {
|
||||
|
||||
private val logger = Logger(classOf[BankBranchesProvider])
|
||||
|
||||
final def getBranches(bank : BankId) : Option[BranchData] = {
|
||||
branchDataLicense(bank) match {
|
||||
case Some(license) =>
|
||||
Some(BranchData(branchData(bank), license))
|
||||
case None => {
|
||||
logger.info(s"No branch data license found for bank ${bank.value}")
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected def branchData(bank : BankId) : List[BankBranch]
|
||||
protected def branchDataLicense(bank : BankId) : Option[DataLicense]
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,65 @@
|
||||
package code.bankbranches
|
||||
|
||||
import code.bankbranches.BankBranches.{DataLicense, BankBranchId, Address, BankBranch}
|
||||
import code.model.BankId
|
||||
import net.liftweb.mapper._
|
||||
|
||||
object MappedBankBranchesProvider extends BankBranchesProvider {
|
||||
override protected def branchData(bank: BankId): List[BankBranch] =
|
||||
MappedBankBranch.findAll(By(MappedBankBranch.mBankId, bank.value))
|
||||
|
||||
override protected def branchDataLicense(bank: BankId): Option[DataLicense] =
|
||||
MappedDataLicense.find(By(MappedDataLicense.mBankId, bank.value))
|
||||
}
|
||||
|
||||
class MappedBankBranch extends BankBranch with LongKeyedMapper[MappedBankBranch] with IdPK {
|
||||
|
||||
override def getSingleton = MappedBankBranch
|
||||
|
||||
object mBankId extends MappedText(this)
|
||||
object mName extends MappedText(this)
|
||||
|
||||
object mBranchId extends MappedText(this)
|
||||
|
||||
object mLine1 extends MappedText(this)
|
||||
object mLine2 extends MappedText(this)
|
||||
object mLine3 extends MappedText(this)
|
||||
object mLine4 extends MappedText(this)
|
||||
object mLine5 extends MappedText(this)
|
||||
|
||||
object mCountryCode extends MappedString(this, 2)
|
||||
object mPostCode extends MappedText(this)
|
||||
|
||||
|
||||
override def branchId: BankBranchId = BankBranchId(mBranchId.get)
|
||||
override def name: String = mName.get
|
||||
|
||||
override def address: Address = new Address {
|
||||
override def line1: String = mLine1.get
|
||||
override def line2: String = mLine2.get
|
||||
override def line3: String = mLine3.get
|
||||
override def line4: String = mLine4.get
|
||||
override def line5: String = mLine5.get
|
||||
override def countryCode: String = mCountryCode.get
|
||||
override def postCode: String = mPostCode.get
|
||||
}
|
||||
}
|
||||
|
||||
object MappedBankBranch extends MappedBankBranch with LongKeyedMetaMapper[MappedBankBranch] {
|
||||
override def dbIndexes = UniqueIndex(mBankId, mBranchId) :: Index(mBankId) :: super.dbIndexes
|
||||
}
|
||||
|
||||
class MappedDataLicense extends DataLicense with LongKeyedMapper[MappedDataLicense] with IdPK {
|
||||
override def getSingleton = MappedDataLicense
|
||||
|
||||
object mBankId extends MappedText(this)
|
||||
object mName extends MappedText(this)
|
||||
object mUrl extends MappedText(this)
|
||||
|
||||
override def name: String = mName.get
|
||||
override def url: String = mUrl.get
|
||||
}
|
||||
|
||||
object MappedDataLicense extends MappedDataLicense with LongKeyedMetaMapper[MappedDataLicense] {
|
||||
override def dbIndexes = Index(mBankId) :: super.dbIndexes
|
||||
}
|
||||
34
src/main/scala/code/customerinfo/CustomerInfoProvider.scala
Normal file
34
src/main/scala/code/customerinfo/CustomerInfoProvider.scala
Normal file
@ -0,0 +1,34 @@
|
||||
package code.customerinfo
|
||||
|
||||
import java.util.Date
|
||||
|
||||
import code.model.{BankId, User}
|
||||
import net.liftweb.common.Box
|
||||
import net.liftweb.util.SimpleInjector
|
||||
|
||||
object CustomerInfo extends SimpleInjector {
|
||||
|
||||
val customerInfoProvider = new Inject(buildOne _) {}
|
||||
|
||||
def buildOne: CustomerInfoProvider = MappedCustomerInfoProvider
|
||||
|
||||
}
|
||||
|
||||
trait CustomerInfoProvider {
|
||||
def getInfo(bankId : BankId, user : User) : Box[CustomerInfo]
|
||||
|
||||
def getUser(bankId : BankId, customerId : String) : Box[User]
|
||||
}
|
||||
|
||||
trait CustomerInfo {
|
||||
def number : String
|
||||
def legalName : String
|
||||
def mobileNumber : String
|
||||
def email : String
|
||||
def faceImage : CustomerFaceImage
|
||||
}
|
||||
|
||||
trait CustomerFaceImage {
|
||||
def url : String
|
||||
def date : Date
|
||||
}
|
||||
33
src/main/scala/code/customerinfo/CustomerMessage.scala
Normal file
33
src/main/scala/code/customerinfo/CustomerMessage.scala
Normal file
@ -0,0 +1,33 @@
|
||||
package code.customerinfo
|
||||
|
||||
import java.util.Date
|
||||
|
||||
import code.model.{BankId, User}
|
||||
import net.liftweb.util.SimpleInjector
|
||||
|
||||
|
||||
object CustomerMessages extends SimpleInjector {
|
||||
|
||||
val customerMessageProvider = new Inject(buildOne _) {}
|
||||
|
||||
def buildOne: CustomerMessageProvider = MappedCustomerMessageProvider
|
||||
|
||||
}
|
||||
|
||||
trait CustomerMessageProvider {
|
||||
|
||||
//TODO: pagination? is this sorted by date?
|
||||
def getMessages(user : User, bankId : BankId) : List[CustomerMessage]
|
||||
|
||||
def addMessage(user : User, bankId : BankId, message : String, fromDepartment : String, fromPerson : String) : Boolean
|
||||
|
||||
}
|
||||
|
||||
trait CustomerMessage {
|
||||
//TODO: message language?
|
||||
def messageId : String
|
||||
def date : Date
|
||||
def message : String
|
||||
def fromDepartment : String
|
||||
def fromPerson : String
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
package code.customerinfo
|
||||
|
||||
import java.util.Date
|
||||
|
||||
import code.model.{BankId, User}
|
||||
import code.model.dataAccess.APIUser
|
||||
import net.liftweb.common.Box
|
||||
import net.liftweb.mapper._
|
||||
|
||||
object MappedCustomerInfoProvider extends CustomerInfoProvider {
|
||||
override def getInfo(bankId : BankId, user: User): Box[CustomerInfo] = {
|
||||
MappedCustomerInfo.find(
|
||||
By(MappedCustomerInfo.mUser, user.apiId.value),
|
||||
By(MappedCustomerInfo.mBank, bankId.value))
|
||||
}
|
||||
|
||||
override def getUser(bankId: BankId, customerNumber: String): Box[User] = {
|
||||
MappedCustomerInfo.find(
|
||||
By(MappedCustomerInfo.mBank, bankId.value),
|
||||
By(MappedCustomerInfo.mNumber, customerNumber)
|
||||
).flatMap(_.mUser.obj)
|
||||
}
|
||||
}
|
||||
|
||||
class MappedCustomerInfo extends CustomerInfo with LongKeyedMapper[MappedCustomerInfo] with IdPK with CreatedUpdated {
|
||||
|
||||
def getSingleton = MappedCustomerInfo
|
||||
|
||||
object mUser extends MappedLongForeignKey(this, APIUser)
|
||||
object mBank extends MappedText(this)
|
||||
|
||||
object mNumber extends MappedText(this)
|
||||
object mMobileNumber extends MappedText(this)
|
||||
object mLegalName extends MappedText(this)
|
||||
object mEmail extends MappedEmail(this, 200)
|
||||
object mFaceImageUrl extends MappedText(this)
|
||||
object mFaceImageTime extends MappedDateTime(this)
|
||||
|
||||
override def number: String = mNumber.get
|
||||
override def mobileNumber: String = mMobileNumber.get
|
||||
override def legalName: String = mLegalName.get
|
||||
override def email: String = mEmail.get
|
||||
override def faceImage: CustomerFaceImage = new CustomerFaceImage {
|
||||
override def date: Date = mFaceImageTime.get
|
||||
override def url: String = mFaceImageUrl.get
|
||||
}
|
||||
}
|
||||
|
||||
object MappedCustomerInfo extends MappedCustomerInfo with LongKeyedMetaMapper[MappedCustomerInfo] {
|
||||
//one customer info per bank for each api user
|
||||
override def dbIndexes = UniqueIndex(mBank, mNumber) :: UniqueIndex(mUser, mBank) :: super.dbIndexes
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
package code.customerinfo
|
||||
|
||||
import java.util.Date
|
||||
|
||||
import code.model.{BankId, User}
|
||||
import code.model.dataAccess.APIUser
|
||||
import code.util.MappedUUID
|
||||
import net.liftweb.mapper._
|
||||
|
||||
object MappedCustomerMessageProvider extends CustomerMessageProvider {
|
||||
|
||||
override def getMessages(user: User, bankId : BankId): List[CustomerMessage] = {
|
||||
MappedCustomerMessage.findAll(
|
||||
By(MappedCustomerMessage.user, user.apiId.value),
|
||||
By(MappedCustomerMessage.bank, bankId.value),
|
||||
OrderBy(MappedCustomerMessage.updatedAt, Descending))
|
||||
}
|
||||
|
||||
|
||||
override def addMessage(user: User, bankId: BankId, message: String, fromDepartment: String, fromPerson: String): Boolean = {
|
||||
MappedCustomerMessage.create
|
||||
.mFromDepartment(fromDepartment)
|
||||
.mFromPerson(fromPerson)
|
||||
.mMessage(message)
|
||||
.user(user.apiId.value)
|
||||
.bank(bankId.value).save()
|
||||
}
|
||||
}
|
||||
|
||||
class MappedCustomerMessage extends CustomerMessage
|
||||
with LongKeyedMapper[MappedCustomerMessage] with IdPK with CreatedUpdated {
|
||||
|
||||
def getSingleton = MappedCustomerMessage
|
||||
|
||||
object user extends MappedLongForeignKey(this, APIUser)
|
||||
object bank extends MappedText(this)
|
||||
|
||||
object mFromPerson extends MappedText(this)
|
||||
object mFromDepartment extends MappedText(this)
|
||||
object mMessage extends MappedText(this)
|
||||
object mMessageId extends MappedUUID(this)
|
||||
|
||||
|
||||
override def messageId: String = mMessageId.get
|
||||
override def date: Date = createdAt.get
|
||||
override def fromPerson: String = mFromPerson.get
|
||||
override def fromDepartment: String = mFromDepartment.get
|
||||
override def message: String = mMessage.get
|
||||
}
|
||||
|
||||
object MappedCustomerMessage extends MappedCustomerMessage with LongKeyedMetaMapper[MappedCustomerMessage] {
|
||||
override def dbIndexes = UniqueIndex(mMessageId) :: Index(user, bank, updatedAt) :: super.dbIndexes
|
||||
}
|
||||
@ -55,7 +55,8 @@ package code.model.dataAccess {
|
||||
|
||||
import java.util.UUID
|
||||
|
||||
import code.model.{AccountId, BankId}
|
||||
import code.model.{User, AccountId, BankId}
|
||||
import code.users.Users
|
||||
import com.rabbitmq.client.{ConnectionFactory,Channel}
|
||||
import net.liftmodules.amqp.{
|
||||
AMQPDispatcher,
|
||||
@ -114,7 +115,7 @@ import scala.util.Random
|
||||
}
|
||||
}
|
||||
|
||||
private def createAccount(bankAccountNumber: BankAccountNumber, accountId : AccountId, bank : HostedBank, u: APIUser) : Account = {
|
||||
private def createAccount(bankAccountNumber: BankAccountNumber, accountId : AccountId, bank : HostedBank, u: User) : Account = {
|
||||
//TODO: fill these fields using the HBCI library.
|
||||
import net.liftweb.mongodb.BsonDSL._
|
||||
Account.find(
|
||||
@ -148,11 +149,11 @@ import scala.util.Random
|
||||
}
|
||||
}
|
||||
|
||||
def createAccount(bankAccountNumber: BankAccountNumber, bank: HostedBank, u: APIUser): Account = {
|
||||
def createAccount(bankAccountNumber: BankAccountNumber, bank: HostedBank, u: User): Account = {
|
||||
createAccount(bankAccountNumber, AccountId(UUID.randomUUID().toString), bank, u)
|
||||
}
|
||||
|
||||
def createAccount(accountId: AccountId, bank: HostedBank, u: APIUser): Account = {
|
||||
def createAccount(accountId: AccountId, bank: HostedBank, u: User): Account = {
|
||||
import net.liftweb.mongodb.BsonDSL._
|
||||
val uniqueAccountNumber = {
|
||||
def exists(number : String) = Account.count((Account.accountNumber.name -> number) ~ (Account.bankID.name -> bank.id.get)) > 0
|
||||
@ -173,20 +174,20 @@ import scala.util.Random
|
||||
}, accountId, bank, u)
|
||||
}
|
||||
|
||||
def setAsOwner(bankId : BankId, accountId : AccountId, user: APIUser): Unit = {
|
||||
def setAsOwner(bankId : BankId, accountId : AccountId, user: User): Unit = {
|
||||
createOwnerView(bankId, accountId, user)
|
||||
setAsAccountOwner(bankId, accountId, user)
|
||||
}
|
||||
|
||||
private def setAsAccountOwner(bankId : BankId, accountId : AccountId, user : APIUser) : Unit = {
|
||||
private def setAsAccountOwner(bankId : BankId, accountId : AccountId, user : User) : Unit = {
|
||||
MappedAccountHolder.create
|
||||
.accountBankPermalink(bankId.value)
|
||||
.accountPermalink(accountId.value)
|
||||
.user(user)
|
||||
.user(user.apiId.value)
|
||||
.save
|
||||
}
|
||||
|
||||
private def createOwnerView(bankId : BankId, accountId : AccountId, user: APIUser): Unit = {
|
||||
private def createOwnerView(bankId : BankId, accountId : AccountId, user: User): Unit = {
|
||||
|
||||
val existingOwnerView = ViewImpl.find(
|
||||
By(ViewImpl.permalink_, "owner") ::
|
||||
@ -195,16 +196,16 @@ import scala.util.Random
|
||||
existingOwnerView match {
|
||||
case Full(v) => {
|
||||
logger.info(s"account $accountId at bank $bankId has already an owner view")
|
||||
v.users_.toList.find(_.id == user.id) match {
|
||||
v.users_.toList.find(_.id == user.apiId.value) match {
|
||||
case Some(u) => {
|
||||
logger.info(s"user ${user.email.get} has already an owner view access on account $accountId at bank $bankId")
|
||||
logger.info(s"user ${user.emailAddress} has already an owner view access on account $accountId at bank $bankId")
|
||||
}
|
||||
case _ =>{
|
||||
//TODO: When can this case occur?
|
||||
logger.info(s"creating owner view access to user ${user.email.get}")
|
||||
logger.info(s"creating owner view access to user ${user.emailAddress}")
|
||||
ViewPrivileges
|
||||
.create
|
||||
.user(user)
|
||||
.user(user.apiId.value)
|
||||
.view(v)
|
||||
.save
|
||||
}
|
||||
@ -216,10 +217,10 @@ import scala.util.Random
|
||||
logger.info(s"creating owner view on account account $accountId at bank $bankId")
|
||||
val view = ViewImpl.createAndSaveOwnerView(bankId, accountId, "")
|
||||
|
||||
logger.info(s"creating owner view access to user ${user.email.get}")
|
||||
logger.info(s"creating owner view access to user ${user.emailAddress}")
|
||||
ViewPrivileges
|
||||
.create
|
||||
.user(user)
|
||||
.user(user.apiId.value)
|
||||
.view(view)
|
||||
.save
|
||||
}
|
||||
@ -246,19 +247,18 @@ import scala.util.Random
|
||||
case msg@AMQPMessage(message: CreateBankAccount) => {
|
||||
logger.info(s"got message to create account/bank: ${message.accountNumber} / ${message.bankIdentifier}")
|
||||
|
||||
APIUser.find(
|
||||
By(APIUser.provider_, message.accountOwnerProvider),
|
||||
By(APIUser.providerId, message.accountOwnerId)
|
||||
).map{ user => {
|
||||
val foundUser = Users.users.vend.getUserByProviderId(message.accountOwnerProvider, message.accountOwnerId)
|
||||
foundUser.map{ user => {
|
||||
logger.info("user found for owner view")
|
||||
|
||||
val bank: HostedBank = BankAccountCreation.createBank(message)
|
||||
val bankAccount = BankAccountCreation.createAccount(message, bank, user)
|
||||
BankAccountCreation.setAsOwner(BankId(bank.permalink.get), AccountId(message.accountNumber), user)
|
||||
BankAccountCreation.setAsOwner(BankId(bank.permalink.get), bankAccount.accountId, user)
|
||||
|
||||
logger.info(s"created account ${message.accountNumber} at ${message.bankIdentifier}")
|
||||
logger.info(s"created account with id ${bankAccount.bankId.value} with number ${bankAccount.number} at bank with identifier ${message.bankIdentifier}")
|
||||
|
||||
logger.info(s"Send message to get updates for the account ${message.accountNumber} at ${message.bankIdentifier}")
|
||||
logger.info(s"Send message to get updates for the account with id ${bankAccount.accountId.value}" +
|
||||
s" with number ${bankAccount.number} at bank with identifier ${message.bankIdentifier}")
|
||||
UpdatesRequestSender.sendMsg(UpdateBankAccount(message.accountNumber, message.bankIdentifier))
|
||||
}
|
||||
}.getOrElse(
|
||||
|
||||
4
src/test/scala/code/api/DefaultConnectorTestSetup.scala
Normal file
4
src/test/scala/code/api/DefaultConnectorTestSetup.scala
Normal file
@ -0,0 +1,4 @@
|
||||
package code.api
|
||||
|
||||
//Set the default connector setup here by extending it
|
||||
trait DefaultConnectorTestSetup extends LocalMappedConnectorTestSetup
|
||||
@ -33,10 +33,10 @@ Berlin 13359, Germany
|
||||
package code.api.test
|
||||
|
||||
import code.TestServer
|
||||
import code.api.LocalMappedConnectorTestSetup
|
||||
import code.api.{DefaultConnectorTestSetup, TestConnectorSetup, LocalConnectorTestSetup}
|
||||
import org.scalatest._
|
||||
import dispatch._
|
||||
import net.liftweb.json.{Serialization, NoTypeHints}
|
||||
import net.liftweb.json.{DefaultFormats, Serialization, NoTypeHints}
|
||||
import net.liftweb.common._
|
||||
|
||||
trait ServerSetup extends FeatureSpec with SendServerRequests
|
||||
@ -45,13 +45,13 @@ trait ServerSetup extends FeatureSpec with SendServerRequests
|
||||
with ShouldMatchers with Loggable {
|
||||
|
||||
var server = TestServer
|
||||
implicit val formats = Serialization.formats(NoTypeHints)
|
||||
implicit val formats = DefaultFormats
|
||||
val h = Http
|
||||
def baseRequest = host(server.host, server.port)
|
||||
|
||||
}
|
||||
|
||||
trait ServerSetupWithTestData extends ServerSetup with LocalMappedConnectorTestSetup {
|
||||
trait ServerSetupWithTestData extends ServerSetup with DefaultConnectorTestSetup {
|
||||
|
||||
override def beforeEach() = {
|
||||
super.beforeEach()
|
||||
|
||||
117
src/test/scala/code/api/v1_4_0/BankBranchesTest.scala
Normal file
117
src/test/scala/code/api/v1_4_0/BankBranchesTest.scala
Normal file
@ -0,0 +1,117 @@
|
||||
package code.api.v1_4_0
|
||||
|
||||
import code.api.v1_4_0.JSONFactory1_4_0.{BranchJson, BranchDataJson}
|
||||
import dispatch._
|
||||
import code.bankbranches.BankBranches.{Address, BankBranchId, BankBranch, DataLicense}
|
||||
import code.bankbranches.{BankBranches, BankBranchesProvider}
|
||||
import code.model.BankId
|
||||
|
||||
class BankBranchesTest extends V140ServerSetup {
|
||||
|
||||
val BankWithLicense = BankId("bank-with-license")
|
||||
val BankWithoutLicense = BankId("bank-without-license")
|
||||
|
||||
case class BankBranchImpl(branchId : BankBranchId, name : String, address : Address) extends BankBranch
|
||||
case class AddressImpl(line1 : String, line2 : String, line3 : String, line4 : String,
|
||||
line5 : String, postCode : String, countryCode : String) extends Address
|
||||
|
||||
val fakeAddress1 = AddressImpl("134", "32432", "fff", "fsfsfs", "mvmvmv", "C4SF5", "DE")
|
||||
val fakeAddress2 = fakeAddress1.copy(line1 = "00000")
|
||||
|
||||
val fakeBranch1 = BankBranchImpl(BankBranchId("branch1"), "Branch 1", fakeAddress1)
|
||||
val fakeBranch2 = BankBranchImpl(BankBranchId("branch2"), "Branch 2", fakeAddress2)
|
||||
|
||||
val fakeLicense = new DataLicense {
|
||||
override def name: String = "sample-license"
|
||||
override def url: String = "http://example.com/license"
|
||||
}
|
||||
|
||||
val mockConnector = new BankBranchesProvider {
|
||||
override protected def branchData(bank: BankId): List[BankBranch] = {
|
||||
bank match {
|
||||
// have it return branches even for the bank without a license so we can test the connector does not return them
|
||||
case BankWithLicense | BankWithoutLicense=> List(fakeBranch1, fakeBranch2)
|
||||
case _ => Nil
|
||||
}
|
||||
}
|
||||
|
||||
override protected def branchDataLicense(bank: BankId): Option[DataLicense] = {
|
||||
bank match {
|
||||
case BankWithLicense => Some(fakeLicense)
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def verifySameData(branch: BankBranch, branchJson : BranchJson) = {
|
||||
branch.name should equal (branchJson.name)
|
||||
branch.branchId should equal(BankBranchId(branchJson.id))
|
||||
branch.address.line1 should equal(branchJson.address.line_1)
|
||||
branch.address.line2 should equal(branchJson.address.line_2)
|
||||
branch.address.line3 should equal(branchJson.address.line_3)
|
||||
branch.address.line4 should equal(branchJson.address.line_4)
|
||||
branch.address.line5 should equal(branchJson.address.line_5)
|
||||
branch.address.countryCode should equal(branchJson.address.country)
|
||||
branch.address.postCode should equal(branchJson.address.postcode_zip)
|
||||
}
|
||||
|
||||
override def beforeAll() {
|
||||
super.beforeAll()
|
||||
//use the mock connector
|
||||
BankBranches.bankBranchesProvider.default.set(mockConnector)
|
||||
}
|
||||
|
||||
override def afterAll() {
|
||||
super.afterAll()
|
||||
//reset the default connector
|
||||
BankBranches.bankBranchesProvider.default.set(BankBranches.buildOne)
|
||||
}
|
||||
|
||||
feature("Getting bank branches") {
|
||||
|
||||
scenario("We try to get bank branches for a bank without a data license for branch information") {
|
||||
|
||||
When("We make a request")
|
||||
val request = (v1_4Request / "banks" / BankWithoutLicense.value / "branches").GET
|
||||
val response = makeGetRequest(request)
|
||||
|
||||
Then("We should get a 404")
|
||||
response.code should equal(404)
|
||||
}
|
||||
|
||||
scenario("We try to get bank branches for a bank with a data license for branch information") {
|
||||
When("We make a request")
|
||||
val request = (v1_4Request / "banks" / BankWithLicense.value / "branches").GET
|
||||
val response = makeGetRequest(request)
|
||||
|
||||
Then("We should get a 200")
|
||||
response.code should equal(200)
|
||||
|
||||
And("We should get the right json format")
|
||||
val responseBodyOpt = response.body.extractOpt[BranchDataJson]
|
||||
responseBodyOpt.isDefined should equal(true)
|
||||
val responseBody = responseBodyOpt.get
|
||||
|
||||
And("We should get the right license")
|
||||
val license = responseBody.license
|
||||
license.name should equal(fakeLicense.name)
|
||||
license.url should equal(fakeLicense.url)
|
||||
|
||||
And("We should get the right branches")
|
||||
val branches = responseBody.branches
|
||||
branches.size should equal(2)
|
||||
val first = branches(0)
|
||||
if(first.id == fakeBranch1.branchId.value) {
|
||||
verifySameData(fakeBranch1, first)
|
||||
verifySameData(fakeBranch2, branches(1))
|
||||
} else if (first.id == fakeBranch2.branchId.value) {
|
||||
verifySameData(fakeBranch2, first)
|
||||
verifySameData(fakeBranch1, branches(1))
|
||||
} else {
|
||||
fail("incorrect branches")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
105
src/test/scala/code/api/v1_4_0/CustomerInfoTest.scala
Normal file
105
src/test/scala/code/api/v1_4_0/CustomerInfoTest.scala
Normal file
@ -0,0 +1,105 @@
|
||||
package code.api.v1_4_0
|
||||
|
||||
import java.util.Date
|
||||
|
||||
import code.api.DefaultUsers
|
||||
import code.api.util.APIUtil
|
||||
import code.api.v1_4_0.JSONFactory1_4_0.CustomerInfoJson
|
||||
import code.customerinfo.{CustomerFaceImage, CustomerInfo, CustomerInfoProvider}
|
||||
import code.model.{User, BankId}
|
||||
import net.liftweb.common.{Full, Empty, Box}
|
||||
import dispatch._
|
||||
import code.api.util.APIUtil.OAuth._
|
||||
|
||||
class CustomerInfoTest extends V140ServerSetup with DefaultUsers {
|
||||
|
||||
val mockBankId = BankId("mockbank1")
|
||||
|
||||
case class MockFaceImage(date : Date, url : String) extends CustomerFaceImage
|
||||
case class MockCustomerInfo(number : String, mobileNumber : String,
|
||||
legalName : String, email : String,
|
||||
faceImage : MockFaceImage) extends CustomerInfo
|
||||
|
||||
val mockCustomerFaceImage = MockFaceImage(new Date(1234000), "http://example.com/image1")
|
||||
|
||||
val mockCustomerInfo = MockCustomerInfo("123", "3939", "Bob", "bob@example.com", mockCustomerFaceImage)
|
||||
|
||||
object MockedCustomerInfoProvider extends CustomerInfoProvider {
|
||||
override def getInfo(bankId: BankId, user: User): Box[CustomerInfo] = {
|
||||
if(bankId == mockBankId) Full(mockCustomerInfo)
|
||||
else Empty
|
||||
}
|
||||
|
||||
override def getUser(bankId: BankId, customerId: String): Box[User] = Empty
|
||||
}
|
||||
|
||||
override def beforeAll() {
|
||||
super.beforeAll()
|
||||
//use the mock connector
|
||||
CustomerInfo.customerInfoProvider.default.set(MockedCustomerInfoProvider)
|
||||
}
|
||||
|
||||
override def afterAll() {
|
||||
super.afterAll()
|
||||
//reset the default connector
|
||||
CustomerInfo.customerInfoProvider.default.set(CustomerInfo.buildOne)
|
||||
}
|
||||
|
||||
|
||||
feature("Getting a bank's customer info of the current user") {
|
||||
|
||||
scenario("There is no current user") {
|
||||
Given("There is no logged in user")
|
||||
|
||||
When("We make the request")
|
||||
val request = (v1_4Request / "banks" / mockBankId.value / "customer").GET
|
||||
val response = makeGetRequest(request)
|
||||
|
||||
Then("We should get a 400")
|
||||
response.code should equal(400)
|
||||
}
|
||||
|
||||
scenario("There is a user, but the bank in questions has no customer info") {
|
||||
Given("The bank in question has no customer info")
|
||||
val testBank = BankId("test-bank")
|
||||
val user = obpuser1
|
||||
|
||||
CustomerInfo.customerInfoProvider.vend.getInfo(testBank, user).isEmpty should equal(true)
|
||||
|
||||
When("We make the request")
|
||||
//TODO: need stronger link between obpuser1 and user1
|
||||
val request = (v1_4Request / "banks" / testBank.value / "customer").GET <@(user1)
|
||||
val response = makeGetRequest(request)
|
||||
|
||||
Then("We should get a 404")
|
||||
response.code should equal(404)
|
||||
}
|
||||
|
||||
scenario("There is a user, and the bank in questions has customer info for that user") {
|
||||
Given("The bank in question has customer info")
|
||||
val testBank = mockBankId
|
||||
val user = obpuser1
|
||||
|
||||
CustomerInfo.customerInfoProvider.vend.getInfo(testBank, user).isEmpty should equal(false)
|
||||
|
||||
When("We make the request")
|
||||
//TODO: need stronger link between obpuser1 and user1
|
||||
val request = (v1_4Request / "banks" / testBank.value / "customer").GET <@(user1)
|
||||
val response = makeGetRequest(request)
|
||||
|
||||
Then("We should get a 200")
|
||||
response.code should equal(200)
|
||||
|
||||
And("We should get the right information back")
|
||||
|
||||
val info = response.body.extract[CustomerInfoJson]
|
||||
val received = MockCustomerInfo(info.customer_number, info.mobile_phone_number,
|
||||
info.legal_name, info.email, MockFaceImage(info.face_image.date, info.face_image.url))
|
||||
|
||||
received should equal(mockCustomerInfo)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,77 @@
|
||||
package code.api.v1_4_0
|
||||
|
||||
import code.api.DefaultUsers
|
||||
import code.api.util.APIUtil
|
||||
import code.api.v1_4_0.JSONFactory1_4_0.{AddCustomerMessageJson, CustomerMessagesJson}
|
||||
import code.customerinfo.{MappedCustomerMessage, MappedCustomerInfo, CustomerInfo}
|
||||
import code.model.BankId
|
||||
import dispatch._
|
||||
import code.api.util.APIUtil.OAuth._
|
||||
import net.liftweb.json.Serialization.{read, write}
|
||||
|
||||
//TODO: API test should be independent of CustomerMessages implementation
|
||||
class MappedCustomerMessagesTest extends V140ServerSetup with DefaultUsers {
|
||||
|
||||
implicit val format = APIUtil.formats
|
||||
|
||||
val mockBankId = BankId("mockbank1")
|
||||
val mockCustomerNumber = "9393490320"
|
||||
|
||||
//TODO: need better tests
|
||||
feature("Customer messages") {
|
||||
scenario("Getting messages when none exist") {
|
||||
Given("No messages exist")
|
||||
MappedCustomerMessage.count() should equal(0)
|
||||
|
||||
When("We get the messages")
|
||||
val request = (v1_4Request / "banks" / mockBankId.value / "customer" / "messages").GET <@ user1
|
||||
val response = makeGetRequest(request)
|
||||
|
||||
Then("We should get a 200")
|
||||
response.code should equal(200)
|
||||
|
||||
And("We should get no messages")
|
||||
val json = response.body.extract[CustomerMessagesJson]
|
||||
json.messages.size should equal(0)
|
||||
}
|
||||
|
||||
scenario("Adding a message") {
|
||||
When("We add a message")
|
||||
val request = (v1_4Request / "banks" / mockBankId.value / "customer" / mockCustomerNumber / "messages").POST
|
||||
val messageJson = AddCustomerMessageJson("some message", "some department", "some person")
|
||||
val response = makePostRequest(request, write(messageJson))
|
||||
|
||||
Then("We should get a 201")
|
||||
response.code should equal(201)
|
||||
|
||||
And("We should get that message when we do a get messages request ")
|
||||
val getMessagesRequest = (v1_4Request / "banks" / mockBankId.value / "customer" / "messages").GET <@ user1
|
||||
val getMessagesResponse = makeGetRequest(getMessagesRequest)
|
||||
val json = getMessagesResponse.body.extract[CustomerMessagesJson]
|
||||
json.messages.size should equal(1)
|
||||
|
||||
val msg = json.messages(0)
|
||||
msg.message should equal(messageJson.message)
|
||||
msg.from_department should equal(messageJson.from_department)
|
||||
msg.from_person should equal(messageJson.from_person)
|
||||
msg.id.nonEmpty should equal(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override def beforeAll(): Unit = {
|
||||
super.beforeAll()
|
||||
//TODO: this shouldn't be tied to an implementation
|
||||
//need to create a customer info obj since the customer messages call needs to find user by customer number
|
||||
MappedCustomerInfo.create
|
||||
.mBank(mockBankId.value)
|
||||
.mUser(obpuser1)
|
||||
.mNumber(mockCustomerNumber).save()
|
||||
}
|
||||
|
||||
override def beforeEach(): Unit = {
|
||||
super.beforeEach()
|
||||
MappedCustomerMessage.bulkDelete_!!()
|
||||
}
|
||||
|
||||
}
|
||||
10
src/test/scala/code/api/v1_4_0/V140ServerSetup.scala
Normal file
10
src/test/scala/code/api/v1_4_0/V140ServerSetup.scala
Normal file
@ -0,0 +1,10 @@
|
||||
package code.api.v1_4_0
|
||||
|
||||
import code.api.test.ServerSetup
|
||||
import dispatch._
|
||||
|
||||
trait V140ServerSetup extends ServerSetup {
|
||||
|
||||
def v1_4Request = baseRequest / "obp" / "v1.4.0"
|
||||
|
||||
}
|
||||
@ -1,49 +1,113 @@
|
||||
package code.bankaccountcreation
|
||||
|
||||
import code.api.DefaultConnectorTestSetup
|
||||
import code.api.test.ServerSetup
|
||||
import code.model.{Consumer => OBPConsumer, Token => OBPToken, AccountId, BankId}
|
||||
import code.model.{User, BankId}
|
||||
import code.views.Views
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.mapper.By
|
||||
import org.scalatest.Tag
|
||||
import com.tesobe.model.CreateBankAccount
|
||||
import code.model.dataAccess.{HostedBank, APIUser, BankAccountCreationListener}
|
||||
import code.model.dataAccess.{APIUser, BankAccountCreationListener}
|
||||
import net.liftmodules.amqp.AMQPMessage
|
||||
import net.liftweb.mapper.By
|
||||
import code.bankconnectors.Connector
|
||||
|
||||
class BankAccountCreationListenerTest extends ServerSetup {
|
||||
class BankAccountCreationListenerTest extends ServerSetup with DefaultConnectorTestSetup {
|
||||
|
||||
object AccountHolderSetup extends Tag("account_holder_setup")
|
||||
object BankAccountCreationListenerTag extends Tag("bank_account_creation_listener")
|
||||
|
||||
feature("The account holder gets properly set when a bank account is created"){
|
||||
scenario("a bank account is created", AccountHolderSetup) {
|
||||
override def beforeEach() = {
|
||||
super.beforeEach()
|
||||
wipeTestData()
|
||||
}
|
||||
|
||||
When("We create a bank account")
|
||||
val userId = "foo"
|
||||
val userProvider = "bar"
|
||||
val accountNumber = "123456"
|
||||
val expectedAccountId = AccountId(accountNumber)
|
||||
val bankIdentifier = "qux"
|
||||
val expectedBankId = "quxbank"
|
||||
override def afterEach() = {
|
||||
super.afterEach()
|
||||
wipeTestData()
|
||||
}
|
||||
|
||||
//need to create the user for the bank accout creation process to work
|
||||
val user =
|
||||
feature("Bank account creation via AMQP messages"){
|
||||
|
||||
val userId = "foo"
|
||||
val userProvider = "bar"
|
||||
|
||||
//need to create the user for the bank accout creation process to work
|
||||
def getTestUser() =
|
||||
APIUser.find(By(APIUser.provider_, userProvider), By(APIUser.providerId, userId)).getOrElse{
|
||||
APIUser.create.
|
||||
provider_(userProvider).
|
||||
providerId(userId).
|
||||
saveMe
|
||||
}
|
||||
|
||||
val expectedBankId = "quxbank"
|
||||
val accountNumber = "123456"
|
||||
|
||||
def thenCheckAccountCreated(user : User) = {
|
||||
Then("An account with the proper parameters should be created")
|
||||
val userAccounts = Views.views.vend.getAllAccountsUserCanSee(Full(user))
|
||||
userAccounts.size should equal(1)
|
||||
val createdAccount = userAccounts(0)
|
||||
|
||||
//the account id should be randomly generated
|
||||
createdAccount.accountId.value.nonEmpty should be(true)
|
||||
|
||||
createdAccount.bankId.value should equal(expectedBankId)
|
||||
createdAccount.number should equal(accountNumber)
|
||||
|
||||
And("The account holder should be set correctly")
|
||||
Connector.connector.vend.getAccountHolders(BankId(expectedBankId), createdAccount.accountId) should equal(Set(user))
|
||||
}
|
||||
|
||||
|
||||
scenario("a bank account is created at a bank that does not yet exist", BankAccountCreationListenerTag) {
|
||||
val bankIdentifier = "qux"
|
||||
val user = getTestUser()
|
||||
|
||||
Given("The account doesn't already exist")
|
||||
Views.views.vend.getAllAccountsUserCanSee(Full(user)).size should equal(0)
|
||||
|
||||
And("The bank in question doesn't already exist")
|
||||
Connector.connector.vend.getBank(BankId(expectedBankId)).isDefined should equal(false)
|
||||
|
||||
When("We create a bank account")
|
||||
|
||||
//using expectedBankId as the bank name should be okay as the behaviour should be to slugify the bank name to get the id
|
||||
//what to do if this slugification results in an id collision has not been determined yet
|
||||
val msgContent = CreateBankAccount(userId, userProvider, accountNumber, bankIdentifier, expectedBankId)
|
||||
|
||||
|
||||
//before the bank account is created, it should obviously have no holders
|
||||
Connector.connector.vend.getAccountHolders(BankId(expectedBankId), expectedAccountId) should equal (Set.empty)
|
||||
|
||||
BankAccountCreationListener.createBankAccountListener ! AMQPMessage(msgContent)
|
||||
|
||||
//sleep to give the actor time to process the message
|
||||
Thread.sleep(5000)
|
||||
|
||||
Then("The should be considered the account holder")
|
||||
Connector.connector.vend.getAccountHolders(BankId(expectedBankId), expectedAccountId) should equal(Set(user))
|
||||
thenCheckAccountCreated(user)
|
||||
|
||||
And("A bank should be created")
|
||||
val createdBankBox = Connector.connector.vend.getBank(BankId(expectedBankId))
|
||||
createdBankBox.isDefined should equal(true)
|
||||
val createdBank = createdBankBox.get
|
||||
createdBank.nationalIdentifier should equal(bankIdentifier)
|
||||
|
||||
}
|
||||
|
||||
scenario("a bank account is created at a bank that already exists", BankAccountCreationListenerTag) {
|
||||
val user = getTestUser()
|
||||
Given("The account doesn't already exist")
|
||||
Views.views.vend.getAllAccountsUserCanSee(Full(user)).size should equal(0)
|
||||
|
||||
And("The bank in question already exists")
|
||||
val createdBank = createBank(expectedBankId)
|
||||
|
||||
When("We create a bank account")
|
||||
val msgContent = CreateBankAccount(userId, userProvider, accountNumber, createdBank.nationalIdentifier, createdBank.bankId.value)
|
||||
|
||||
BankAccountCreationListener.createBankAccountListener ! AMQPMessage(msgContent)
|
||||
|
||||
//sleep to give the actor time to process the message
|
||||
Thread.sleep(5000)
|
||||
|
||||
thenCheckAccountCreated(user)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,133 @@
|
||||
package code.bankbranches
|
||||
|
||||
import code.api.test.ServerSetup
|
||||
import code.model.BankId
|
||||
import net.liftweb.mapper.By
|
||||
|
||||
class MappedBankBranchesProviderTest extends ServerSetup {
|
||||
|
||||
private def delete(): Unit = {
|
||||
MappedBankBranch.bulkDelete_!!()
|
||||
MappedDataLicense.bulkDelete_!!()
|
||||
}
|
||||
|
||||
override def beforeAll() = {
|
||||
super.beforeAll()
|
||||
delete()
|
||||
}
|
||||
|
||||
override def afterEach() = {
|
||||
super.afterEach()
|
||||
delete()
|
||||
}
|
||||
|
||||
def defaultSetup() =
|
||||
new {
|
||||
val bankIdWithLicenseAndData = "some-bank"
|
||||
val bankIdWithNoLicense = "unlicensed-bank"
|
||||
|
||||
val license = MappedDataLicense.create
|
||||
.mBankId(bankIdWithLicenseAndData)
|
||||
.mName("some-license")
|
||||
.mUrl("http://www.example.com/license").saveMe()
|
||||
|
||||
val unlicensedBranch = MappedBankBranch.create
|
||||
.mBankId(bankIdWithNoLicense)
|
||||
.mName("unlicensed")
|
||||
.mBranchId("unlicensed")
|
||||
.mCountryCode("es")
|
||||
.mPostCode("4444")
|
||||
.mLine1("a4")
|
||||
.mLine2("b4")
|
||||
.mLine3("c4")
|
||||
.mLine4("d4")
|
||||
.mLine5("e4").saveMe()
|
||||
|
||||
val branch1 = MappedBankBranch.create
|
||||
.mBankId(bankIdWithLicenseAndData)
|
||||
.mName("branch 1")
|
||||
.mBranchId("branch1")
|
||||
.mCountryCode("de")
|
||||
.mPostCode("123213213")
|
||||
.mLine1("a")
|
||||
.mLine2("b")
|
||||
.mLine3("c")
|
||||
.mLine4("d")
|
||||
.mLine5("e").saveMe()
|
||||
|
||||
val branch2 = MappedBankBranch.create
|
||||
.mBankId(bankIdWithLicenseAndData)
|
||||
.mName("branch 2")
|
||||
.mBranchId("branch2")
|
||||
.mCountryCode("fr")
|
||||
.mPostCode("898989")
|
||||
.mLine1("a2")
|
||||
.mLine2("b2")
|
||||
.mLine3("c2")
|
||||
.mLine4("d2")
|
||||
.mLine5("e2").saveMe()
|
||||
}
|
||||
|
||||
feature("MappedBankBranchesProvider") {
|
||||
|
||||
scenario("We try to get branch data for a bank which does not have a data license set") {
|
||||
val fixture = defaultSetup()
|
||||
|
||||
Given("The bank in question has no data license")
|
||||
MappedDataLicense.count(By(MappedDataLicense.mBankId, fixture.bankIdWithNoLicense)) should equal(0)
|
||||
|
||||
And("The bank in question has branches")
|
||||
MappedBankBranch.find(By(MappedBankBranch.mBankId, fixture.bankIdWithNoLicense)).isDefined should equal(true)
|
||||
|
||||
When("We try to get the branch data for that bank")
|
||||
val branchData = MappedBankBranchesProvider.getBranches(BankId(fixture.bankIdWithNoLicense))
|
||||
|
||||
Then("We should get an empty option")
|
||||
branchData should equal(None)
|
||||
|
||||
}
|
||||
|
||||
scenario("We try to get branch data for a bank which does have a data license set") {
|
||||
val fixture = defaultSetup()
|
||||
val expectedBranches = Set(fixture.branch1, fixture.branch2)
|
||||
Given("We have a data license and branches for a bank")
|
||||
MappedDataLicense.count(By(MappedDataLicense.mBankId, fixture.bankIdWithLicenseAndData)) should equal(1)
|
||||
MappedBankBranch.findAll(By(MappedBankBranch.mBankId, fixture.bankIdWithLicenseAndData)).toSet should equal(expectedBranches)
|
||||
|
||||
When("We try to get the branch data for that bank")
|
||||
val branchDataOpt = MappedBankBranchesProvider.getBranches(BankId(fixture.bankIdWithLicenseAndData))
|
||||
|
||||
Then("We should get back the data license and the branches")
|
||||
branchDataOpt.isDefined should equal(true)
|
||||
val branchData = branchDataOpt.get
|
||||
|
||||
branchData.license should equal(fixture.license)
|
||||
branchData.branches.toSet should equal(expectedBranches)
|
||||
}
|
||||
|
||||
scenario("We try to get branch data for a bank with a data license, but no branches") {
|
||||
|
||||
Given("We have a data license for a bank, but no branches")
|
||||
|
||||
val bankWithNoBranches = "bank-with-no-branches"
|
||||
val license = MappedDataLicense.create
|
||||
.mBankId(bankWithNoBranches)
|
||||
.mName("some-license")
|
||||
.mUrl("http://www.example.com/license").saveMe()
|
||||
|
||||
MappedBankBranch.find(By(MappedBankBranch.mBankId, bankWithNoBranches)).isDefined should equal(false)
|
||||
|
||||
When("We try to get the branch data for that bank")
|
||||
val branchDataOpt = MappedBankBranchesProvider.getBranches(BankId(bankWithNoBranches))
|
||||
|
||||
Then("We should get back the data license, and a list branches of size 0")
|
||||
branchDataOpt.isDefined should equal(true)
|
||||
val branchData = branchDataOpt.get
|
||||
|
||||
branchData.license should equal(license)
|
||||
branchData.branches should equal(Nil)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
110
src/test/scala/code/customerinfo/MappedCustomerInfoTest.scala
Normal file
110
src/test/scala/code/customerinfo/MappedCustomerInfoTest.scala
Normal file
@ -0,0 +1,110 @@
|
||||
package code.customerinfo
|
||||
|
||||
import java.util.Date
|
||||
|
||||
import code.api.DefaultUsers
|
||||
import code.api.test.ServerSetup
|
||||
import code.model.BankId
|
||||
import net.liftweb.mapper.By
|
||||
|
||||
class MappedCustomerInfoProviderTest extends ServerSetup with DefaultUsers {
|
||||
|
||||
val testBankId = BankId("bank")
|
||||
|
||||
def createCustomerInfo1() = MappedCustomerInfo.create
|
||||
.mBank(testBankId.value).mEmail("bob@example.com").mFaceImageTime(new Date(12340000))
|
||||
.mFaceImageUrl("http://example.com/image.jpg").mLegalName("John Johnson")
|
||||
.mMobileNumber("12343434").mNumber("343").mUser(obpuser1).saveMe()
|
||||
|
||||
feature("Getting customer info") {
|
||||
|
||||
scenario("No customer info exists for user and we try to get it") {
|
||||
Given("No MappedCustomerInfo exists for a user")
|
||||
MappedCustomerInfo.find(By(MappedCustomerInfo.mUser, obpuser2)).isDefined should equal(false)
|
||||
|
||||
When("We try to get it")
|
||||
val found = MappedCustomerInfoProvider.getInfo(testBankId, obpuser2)
|
||||
|
||||
Then("We don't")
|
||||
found.isDefined should equal(false)
|
||||
}
|
||||
|
||||
scenario("Customer info exists and we try to get it") {
|
||||
val customerInfo1 = createCustomerInfo1()
|
||||
Given("MappedCustomerInfo exists for a user")
|
||||
MappedCustomerInfo.find(By(MappedCustomerInfo.mUser, obpuser1.apiId.value)).isDefined should equal(true)
|
||||
|
||||
When("We try to get it")
|
||||
val foundOpt = MappedCustomerInfoProvider.getInfo(testBankId, obpuser1)
|
||||
|
||||
Then("We do")
|
||||
foundOpt.isDefined should equal(true)
|
||||
|
||||
And("It is the right info")
|
||||
val found = foundOpt.get
|
||||
found should equal(customerInfo1)
|
||||
}
|
||||
}
|
||||
|
||||
feature("Getting a user from a bankId and customer number") {
|
||||
|
||||
scenario("We try to get a user from a customer number that doesn't exist") {
|
||||
val customerNumber = "123213213213213"
|
||||
|
||||
Given("No customer info exists for a certain customer number")
|
||||
MappedCustomerInfo.find(By(MappedCustomerInfo.mNumber, customerNumber)).isDefined should equal(false)
|
||||
|
||||
When("We try to get the user for a bank with that customer number")
|
||||
val found = MappedCustomerInfoProvider.getUser(BankId("some-bank"), customerNumber)
|
||||
|
||||
Then("We should not find a user")
|
||||
found.isDefined should equal(false)
|
||||
}
|
||||
|
||||
scenario("We try to get a user from a customer number that doesn't exist at the bank in question") {
|
||||
val customerNumber = "123213213213213"
|
||||
val bankId = BankId("a-bank")
|
||||
|
||||
Given("Customer info exists for a different bank")
|
||||
MappedCustomerInfo.create.mNumber(customerNumber).mBank(bankId.value).mUser(obpuser1).saveMe()
|
||||
MappedCustomerInfo.count(By(MappedCustomerInfo.mNumber, customerNumber),
|
||||
By(MappedCustomerInfo.mBank, bankId.value)) should equal({
|
||||
MappedCustomerInfo.count(By(MappedCustomerInfo.mNumber, customerNumber))
|
||||
})
|
||||
|
||||
When("We try to get the user for a different bank")
|
||||
val found = MappedCustomerInfoProvider.getUser(BankId(bankId.value + "asdsad"), customerNumber)
|
||||
|
||||
Then("We should not find a user")
|
||||
found.isDefined should equal(false)
|
||||
}
|
||||
|
||||
scenario("We try to get a user from a customer number that does exist at the bank in question") {
|
||||
val customerNumber = "123213213213213"
|
||||
val bankId = BankId("a-bank")
|
||||
|
||||
Given("Customer info exists for that bank")
|
||||
MappedCustomerInfo.create.mNumber(customerNumber).mBank(bankId.value).mUser(obpuser1).saveMe()
|
||||
MappedCustomerInfo.count(By(MappedCustomerInfo.mNumber, customerNumber),
|
||||
By(MappedCustomerInfo.mBank, bankId.value)) should equal(1)
|
||||
|
||||
When("We try to get the user for that bank")
|
||||
val found = MappedCustomerInfoProvider.getUser(bankId, customerNumber)
|
||||
|
||||
Then("We should not find a user")
|
||||
found.isDefined should equal(true)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
override def beforeAll() = {
|
||||
super.beforeAll()
|
||||
MappedCustomerInfo.bulkDelete_!!()
|
||||
}
|
||||
|
||||
override def afterEach() = {
|
||||
super.afterEach()
|
||||
MappedCustomerInfo.bulkDelete_!!()
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user