diff --git a/README.md b/README.md index f62486782..9c89490b8 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Our tag line is: Bank as a Platform. Transparency as an Asset. The API uses OAuth 1.0 authentication. -The project roadmap is available [here.](https://trello.com/b/O9IjhPXB/open-bank-project-api) +The project roadmap is available [here.](https://openbankproject.com/roadmap/) ## DOCUMENTATION diff --git a/src/main/resources/props/sample.props.template b/src/main/resources/props/sample.props.template index d699d72fe..969ab533a 100644 --- a/src/main/resources/props/sample.props.template +++ b/src/main/resources/props/sample.props.template @@ -14,6 +14,7 @@ db.url=jdbc:postgresql://localhost:5432/dbname?user=dbusername&password=thepassw #this is needed for oauth to work. it's important to access the api over this url, e.g. # if this is 127.0.0.1 don't use localhost to access it. +# (this needs to be an URL) hostname=http://127.0.0.1:8080 #this is only useful for running the api locally via RunWebApp diff --git a/src/test/scala/code/api/API121Test.scala b/src/test/scala/code/api/API121Test.scala index 08d7713b2..949218d8d 100644 --- a/src/test/scala/code/api/API121Test.scala +++ b/src/test/scala/code/api/API121Test.scala @@ -47,6 +47,7 @@ import APIUtil.OAuth._ import code.views.Views import net.liftweb.json.JsonAST.JString import code.api.test.APIResponse +import net.liftweb.util.Props class API1_2_1Test extends User1AllPrivileges with DefaultUsers with PrivateUser2Accounts { @@ -666,76 +667,79 @@ class API1_2_1Test extends User1AllPrivileges with DefaultUsers with PrivateUser }) } - scenario("we make a payment", Payments) { + if (Props.getBool("messageQueue.createBankAccounts") == false) { + ignore("we make a payment", Payments) {} + } else { + scenario("we make a payment", Payments) { + val testBank = createPaymentTestBank() + val bankId = testBank.bankId + val accountId1 = AccountId("__acc1") + val accountId2 = AccountId("__acc2") + createAccountAndOwnerView(Some(obpuser1), bankId, accountId1, "EUR") + createAccountAndOwnerView(Some(obpuser1), bankId, accountId2, "EUR") - val testBank = createPaymentTestBank() - val bankId = testBank.bankId - val accountId1 = AccountId("__acc1") - val accountId2 = AccountId("__acc2") - createAccountAndOwnerView(Some(obpuser1), bankId, accountId1, "EUR") - createAccountAndOwnerView(Some(obpuser1), bankId, accountId2, "EUR") + def getFromAccount: BankAccount = { + BankAccount(bankId, accountId1).getOrElse(fail("couldn't get from account")) + } - def getFromAccount : BankAccount = { - BankAccount(bankId, accountId1).getOrElse(fail("couldn't get from account")) - } + def getToAccount: BankAccount = { + BankAccount(bankId, accountId2).getOrElse(fail("couldn't get to account")) + } - def getToAccount : BankAccount = { - BankAccount(bankId, accountId2).getOrElse(fail("couldn't get to account")) - } + val fromAccount = getFromAccount + val toAccount = getToAccount - val fromAccount = getFromAccount - val toAccount = getToAccount + val totalTransactionsBefore = transactionCount(fromAccount, toAccount) - val totalTransactionsBefore = transactionCount(fromAccount, toAccount) + val beforeFromBalance = fromAccount.balance + val beforeToBalance = toAccount.balance - val beforeFromBalance = fromAccount.balance - val beforeToBalance = toAccount.balance + val amt = BigDecimal("12.50") - val amt = BigDecimal("12.50") + val payJson = MakePaymentJson(toAccount.bankId.value, toAccount.accountId.value, amt.toString) - val payJson = MakePaymentJson(toAccount.bankId.value, toAccount.accountId.value, amt.toString) + val postResult = postTransaction(fromAccount.bankId.value, fromAccount.accountId.value, view, payJson, user1) - val postResult = postTransaction(fromAccount.bankId.value, fromAccount.accountId.value, view, payJson, user1) + val transId: String = (postResult.body \ "transaction_id") match { + case JString(i) => i + case _ => "" + } + transId should not equal ("") - val transId : String = (postResult.body \ "transaction_id") match { - case JString(i) => i - case _ => "" - } - transId should not equal("") - - val reply = getTransaction( + val reply = getTransaction( fromAccount.bankId.value, fromAccount.accountId.value, view, transId, user1) - Then("we should get a 200 ok code") - reply.code should equal (200) - val transJson = reply.body.extract[TransactionJSON] + Then("we should get a 200 ok code") + reply.code should equal(200) + val transJson = reply.body.extract[TransactionJSON] - val fromAccountTransAmt = transJson.details.value.amount - //the from account transaction should have a negative value - //since money left the account - And("the json we receive back should have a transaction amount equal to the amount specified to pay") - fromAccountTransAmt should equal((-amt).toString) + val fromAccountTransAmt = transJson.details.value.amount + //the from account transaction should have a negative value + //since money left the account + And("the json we receive back should have a transaction amount equal to the amount specified to pay") + fromAccountTransAmt should equal((-amt).toString) - val expectedNewFromBalance = beforeFromBalance - amt - And("the account sending the payment should have a new_balance amount equal to the previous balance minus the amount paid") - transJson.details.new_balance.amount should equal(expectedNewFromBalance.toString) - getFromAccount.balance should equal(expectedNewFromBalance) - val toAccountTransactionsReq = getTransactions(toAccount.bankId.value, toAccount.accountId.value, view, user1) - toAccountTransactionsReq.code should equal(200) - val toAccountTransactions = toAccountTransactionsReq.body.extract[TransactionsJSON] - val newestToAccountTransaction = toAccountTransactions.transactions(0) + val expectedNewFromBalance = beforeFromBalance - amt + And("the account sending the payment should have a new_balance amount equal to the previous balance minus the amount paid") + transJson.details.new_balance.amount should equal(expectedNewFromBalance.toString) + getFromAccount.balance should equal(expectedNewFromBalance) + val toAccountTransactionsReq = getTransactions(toAccount.bankId.value, toAccount.accountId.value, view, user1) + toAccountTransactionsReq.code should equal(200) + val toAccountTransactions = toAccountTransactionsReq.body.extract[TransactionsJSON] + val newestToAccountTransaction = toAccountTransactions.transactions(0) - //here amt should be positive (unlike in the transaction in the "from" account") - And("the newest transaction for the account receiving the payment should have the proper amount") - newestToAccountTransaction.details.value.amount should equal(amt.toString) + //here amt should be positive (unlike in the transaction in the "from" account") + And("the newest transaction for the account receiving the payment should have the proper amount") + newestToAccountTransaction.details.value.amount should equal(amt.toString) - And("the account receiving the payment should have the proper balance") - val expectedNewToBalance = beforeToBalance + amt - newestToAccountTransaction.details.new_balance.amount should equal(expectedNewToBalance.toString) - getToAccount.balance should equal(expectedNewToBalance) + And("the account receiving the payment should have the proper balance") + val expectedNewToBalance = beforeToBalance + amt + newestToAccountTransaction.details.new_balance.amount should equal(expectedNewToBalance.toString) + getToAccount.balance should equal(expectedNewToBalance) - And("there should now be 2 new transactions in the database (one for the sender, one for the receiver") - transactionCount(fromAccount, toAccount) should equal(totalTransactionsBefore + 2) + And("there should now be 2 new transactions in the database (one for the sender, one for the receiver") + transactionCount(fromAccount, toAccount) should equal(totalTransactionsBefore + 2) + } } scenario("we can't make a payment without access to the owner view", Payments) { diff --git a/src/test/scala/code/bankaccountcreation/BankAccountCreationListenerTest.scala b/src/test/scala/code/bankaccountcreation/BankAccountCreationListenerTest.scala index 434c1ff76..c5aa84854 100644 --- a/src/test/scala/code/bankaccountcreation/BankAccountCreationListenerTest.scala +++ b/src/test/scala/code/bankaccountcreation/BankAccountCreationListenerTest.scala @@ -6,6 +6,7 @@ import code.model.{User, BankId} import code.views.Views import net.liftweb.common.Full import net.liftweb.mapper.By +import net.liftweb.util.Props import org.scalatest.Tag import com.tesobe.model.CreateBankAccount import code.model.dataAccess.{APIUser, BankAccountCreationListener} @@ -26,14 +27,14 @@ class BankAccountCreationListenerTest extends ServerSetup with DefaultConnectorT wipeTestData() } - feature("Bank account creation via AMQP messages"){ + 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.find(By(APIUser.provider_, userProvider), By(APIUser.providerId, userId)).getOrElse { APIUser.create. provider_(userProvider). providerId(userId). @@ -43,7 +44,7 @@ class BankAccountCreationListenerTest extends ServerSetup with DefaultConnectorT val expectedBankId = "quxbank" val accountNumber = "123456" - def thenCheckAccountCreated(user : User) = { + 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) @@ -59,56 +60,60 @@ class BankAccountCreationListenerTest extends ServerSetup with DefaultConnectorT Connector.connector.vend.getAccountHolders(BankId(expectedBankId), createdAccount.accountId) should equal(Set(user)) } + if (Props.getBool("payments_enabled", false) == false) { + ignore("a bank account is created at a bank that does not yet exist", BankAccountCreationListenerTag) {} + ignore("a bank account is created at a bank that already exists", BankAccountCreationListenerTag) {} + } else { - scenario("a bank account is created at a bank that does not yet exist", BankAccountCreationListenerTag) { - val bankIdentifier = "qux" - val user = getTestUser() + 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) + 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) + 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") + 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) + //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) - BankAccountCreationListener.createBankAccountListener ! AMQPMessage(msgContent) + BankAccountCreationListener.createBankAccountListener ! AMQPMessage(msgContent) - //sleep to give the actor time to process the message - Thread.sleep(5000) + //sleep to give the actor time to process the message + Thread.sleep(5000) - thenCheckAccountCreated(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) + 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) + 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) + 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) + When("We create a bank account") + val msgContent = CreateBankAccount(userId, userProvider, accountNumber, createdBank.nationalIdentifier, createdBank.bankId.value) - BankAccountCreationListener.createBankAccountListener ! AMQPMessage(msgContent) + BankAccountCreationListener.createBankAccountListener ! AMQPMessage(msgContent) - //sleep to give the actor time to process the message - Thread.sleep(5000) + //sleep to give the actor time to process the message + Thread.sleep(5000) - thenCheckAccountCreated(user) + thenCheckAccountCreated(user) + } } } - }