mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 17:37:00 +00:00
feature/Add endpoint createProduct v5.0.0
This commit is contained in:
parent
6ca3afa1b7
commit
669d09af7c
@ -4623,6 +4623,14 @@ object SwaggerDefinitionsJSON {
|
||||
description = descriptionExample.value,
|
||||
meta = metaJson,
|
||||
)
|
||||
val putProductJsonV500 = PutProductJsonV500(
|
||||
parent_product_code = parentProductCodeExample.value,
|
||||
name = productNameExample.value,
|
||||
more_info_url = Some(moreInfoUrlExample.value),
|
||||
terms_and_conditions_url = Some(termsAndConditionsUrlExample.value),
|
||||
description = Some(descriptionExample.value),
|
||||
meta = Some(metaJson)
|
||||
)
|
||||
|
||||
val createMessageJsonV400 = CreateMessageJsonV400(
|
||||
message = messageExample.value,
|
||||
|
||||
@ -12,6 +12,7 @@ import code.api.v2_1_0.JSONFactory210
|
||||
import code.api.v3_0_0.JSONFactory300
|
||||
import code.api.v3_1_0._
|
||||
import code.api.v4_0_0.JSONFactory400.createCustomersMinimalJson
|
||||
import code.api.v4_0_0.{JSONFactory400, PutProductJsonV400}
|
||||
import code.bankconnectors.Connector
|
||||
import code.consent.{ConsentRequests, Consents}
|
||||
import code.entitlement.Entitlement
|
||||
@ -21,9 +22,9 @@ import code.views.Views
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import com.openbankproject.commons.model.enums.StrongCustomerAuthentication
|
||||
import com.openbankproject.commons.model.{BankId, CreditLimit, CreditRating, CustomerFaceImage, UserAuthContextUpdateStatus}
|
||||
import com.openbankproject.commons.model.{BankId, CreditLimit, CreditRating, CustomerFaceImage, ProductCode, UserAuthContextUpdateStatus}
|
||||
import com.openbankproject.commons.util.ApiVersion
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.common.{Empty, Full}
|
||||
import net.liftweb.http.Req
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import net.liftweb.json
|
||||
@ -1019,6 +1020,86 @@ trait APIMethods500 {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
staticResourceDocs += ResourceDoc(
|
||||
createProduct,
|
||||
implementedInApiVersion,
|
||||
nameOf(createProduct),
|
||||
"PUT",
|
||||
"/banks/BANK_ID/products/PRODUCT_CODE",
|
||||
"Create Product",
|
||||
s"""Create or Update Product for the Bank.
|
||||
|
|
||||
|
|
||||
|Typical Super Family values / Asset classes are:
|
||||
|
|
||||
|Debt
|
||||
|Equity
|
||||
|FX
|
||||
|Commodity
|
||||
|Derivative
|
||||
|
|
||||
|$productHiearchyAndCollectionNote
|
||||
|
|
||||
|
|
||||
|${authenticationRequiredMessage(true) }
|
||||
|
|
||||
|
|
||||
|""",
|
||||
putProductJsonV500,
|
||||
productJsonV400.copy(attributes = None, fees = None),
|
||||
List(
|
||||
$UserNotLoggedIn,
|
||||
$BankNotFound,
|
||||
UserHasMissingRoles,
|
||||
UnknownError
|
||||
),
|
||||
List(apiTagProduct, apiTagNewStyle),
|
||||
Some(List(canCreateProduct, canCreateProductAtAnyBank))
|
||||
)
|
||||
lazy val createProduct: OBPEndpoint = {
|
||||
case "banks" :: BankId(bankId) :: "products" :: ProductCode(productCode) :: Nil JsonPut json -> _ => {
|
||||
cc =>
|
||||
for {
|
||||
(Full(u), callContext) <- SS.user
|
||||
_ <- NewStyle.function.hasAtLeastOneEntitlement(failMsg = createProductEntitlementsRequiredText)(bankId.value, u.userId, createProductEntitlements, callContext)
|
||||
failMsg = s"$InvalidJsonFormat The Json body should be the $PutProductJsonV400 "
|
||||
product <- NewStyle.function.tryons(failMsg, 400, callContext) {
|
||||
json.extract[PutProductJsonV500]
|
||||
}
|
||||
parentProductCode <- product.parent_product_code.trim.nonEmpty match {
|
||||
case false =>
|
||||
Future(Empty)
|
||||
case true =>
|
||||
Future(Connector.connector.vend.getProduct(bankId, ProductCode(product.parent_product_code))) map {
|
||||
getFullBoxOrFail(_, callContext, ParentProductNotFoundByProductCode + " {" + product.parent_product_code + "}", 400)
|
||||
}
|
||||
}
|
||||
success <- Future(Connector.connector.vend.createOrUpdateProduct(
|
||||
bankId = bankId.value,
|
||||
code = productCode.value,
|
||||
parentProductCode = parentProductCode.map(_.code.value).toOption,
|
||||
name = product.name,
|
||||
category = null,
|
||||
family = null,
|
||||
superFamily = null,
|
||||
moreInfoUrl = product.more_info_url.getOrElse(""),
|
||||
termsAndConditionsUrl = product.terms_and_conditions_url.getOrElse(""),
|
||||
details = null,
|
||||
description = product.description.getOrElse(""),
|
||||
metaLicenceId = product.meta.map(_.license.id).getOrElse(""),
|
||||
metaLicenceName = product.meta.map(_.license.name).getOrElse("")
|
||||
)) map {
|
||||
connectorEmptyResponse(_, callContext)
|
||||
}
|
||||
} yield {
|
||||
(JSONFactory400.createProductJson(success), HttpCode.`201`(callContext))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ import java.util.Date
|
||||
|
||||
import code.api.util.APIUtil.stringOrNull
|
||||
import code.api.v1_2_1.BankRoutingJsonV121
|
||||
import code.api.v1_4_0.JSONFactory1_4_0.CustomerFaceImageJson
|
||||
import code.api.v1_4_0.JSONFactory1_4_0.{CustomerFaceImageJson, MetaJsonV140}
|
||||
import code.api.v2_1_0.CustomerCreditRatingJSON
|
||||
import code.api.v3_1_0.PostConsentEntitlementJsonV310
|
||||
import code.api.v4_0_0.BankAttributeBankResponseJsonV400
|
||||
@ -80,6 +80,15 @@ case class PostCustomerJsonV500(
|
||||
name_suffix: Option[String] = None
|
||||
)
|
||||
|
||||
case class PutProductJsonV500(
|
||||
parent_product_code: String,
|
||||
name: String,
|
||||
more_info_url: Option[String] = None,
|
||||
terms_and_conditions_url: Option[String] = None,
|
||||
description: Option[String] = None,
|
||||
meta: Option[MetaJsonV140] = None,
|
||||
)
|
||||
|
||||
case class UserAuthContextJsonV500(
|
||||
user_auth_context_id: String,
|
||||
user_id: String,
|
||||
|
||||
169
obp-api/src/test/scala/code/api/v5_0_0/ProductTest.scala
Normal file
169
obp-api/src/test/scala/code/api/v5_0_0/ProductTest.scala
Normal file
@ -0,0 +1,169 @@
|
||||
/**
|
||||
Open Bank Project - API
|
||||
Copyright (C) 2011-2019, TESOBE GmbH
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Email: contact@tesobe.com
|
||||
TESOBE GmbH
|
||||
Osloerstrasse 16/17
|
||||
Berlin 13359, Germany
|
||||
|
||||
This product includes software developed at
|
||||
TESOBE (http://www.tesobe.com/)
|
||||
*/
|
||||
package code.api.v5_0_0
|
||||
|
||||
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON
|
||||
import code.api.util.ApiRole._
|
||||
import code.api.util.APIUtil.OAuth._
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.v4_0_0.OBPAPI4_0_0.Implementations4_0_0
|
||||
import code.api.v5_0_0.OBPAPI5_0_0.Implementations5_0_0
|
||||
import code.api.v4_0_0.{ProductJsonV400, ProductsJsonV400}
|
||||
import code.entitlement.Entitlement
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.model.ErrorMessage
|
||||
import com.openbankproject.commons.util.ApiVersion
|
||||
import net.liftweb.json.Serialization.write
|
||||
import org.scalatest.Tag
|
||||
|
||||
import scala.collection.immutable.Nil
|
||||
|
||||
class ProductTest extends V500ServerSetup {
|
||||
|
||||
override def beforeAll(): Unit = {
|
||||
super.beforeAll()
|
||||
}
|
||||
|
||||
override def afterAll(): Unit = {
|
||||
super.afterAll()
|
||||
}
|
||||
|
||||
/**
|
||||
* Test tags
|
||||
* Example: To run tests with tag "getPermissions":
|
||||
* mvn test -D tagsToInclude
|
||||
*
|
||||
* This is made possible by the scalatest maven plugin
|
||||
*/
|
||||
object VersionOfApi extends Tag(ApiVersion.v5_0_0.toString)
|
||||
object ApiEndpoint1 extends Tag(nameOf(Implementations5_0_0.createProduct))
|
||||
object ApiEndpoint2 extends Tag(nameOf(Implementations4_0_0.getProduct))
|
||||
object ApiEndpoint3 extends Tag(nameOf(Implementations4_0_0.getProducts))
|
||||
|
||||
lazy val testBankId = randomBankId
|
||||
lazy val parentPutProductJsonV500: PutProductJsonV500 = SwaggerDefinitionsJSON.putProductJsonV500.copy(parent_product_code ="")
|
||||
def createProduct(code: String, json: PutProductJsonV500): ProductJsonV400 = {
|
||||
When("We try to create a product v4.0.0")
|
||||
val request500 = (v5_0_0_Request / "banks" / testBankId / "products" / code).PUT <@ (user1)
|
||||
val response500 = makePutRequest(request500, write(json))
|
||||
Then("We should get a 201")
|
||||
response500.code should equal(201)
|
||||
val product = response500.body.extract[ProductJsonV400]
|
||||
product.product_code shouldBe code
|
||||
product.parent_product_code shouldBe json.parent_product_code
|
||||
product.bank_id shouldBe testBankId
|
||||
product.name shouldBe json.name
|
||||
product.more_info_url shouldBe json.more_info_url.getOrElse("")
|
||||
product.terms_and_conditions_url shouldBe json.terms_and_conditions_url.getOrElse("")
|
||||
product.description shouldBe json.description.getOrElse("")
|
||||
product
|
||||
}
|
||||
|
||||
feature("Create Product v4.0.0") {
|
||||
scenario("We will call the Add endpoint without a user credentials", ApiEndpoint1, VersionOfApi) {
|
||||
When("We make a request v4.0.0")
|
||||
val request400 = (v5_0_0_Request / "banks" / testBankId / "products" / "CODE").PUT
|
||||
val response400 = makePutRequest(request400, write(parentPutProductJsonV500))
|
||||
Then("We should get a 401")
|
||||
response400.code should equal(401)
|
||||
And("error should be " + UserNotLoggedIn)
|
||||
response400.body.extract[ErrorMessage].message should equal (UserNotLoggedIn)
|
||||
}
|
||||
scenario("We will call the Add endpoint without a proper role", ApiEndpoint1, VersionOfApi) {
|
||||
When("We make a request v4.0.0")
|
||||
val request500 = (v5_0_0_Request / "banks" / testBankId / "products" / "CODE").PUT <@(user1)
|
||||
val response500 = makePutRequest(request500, write(parentPutProductJsonV500))
|
||||
Then("We should get a 403")
|
||||
response500.code should equal(403)
|
||||
val createProductEntitlements = canCreateProduct :: canCreateProductAtAnyBank :: Nil
|
||||
val createProductEntitlementsRequiredText = UserHasMissingRoles + createProductEntitlements.mkString(" or ")
|
||||
And("error should be " + createProductEntitlementsRequiredText)
|
||||
response500.body.extract[ErrorMessage].message contains (createProductEntitlementsRequiredText) should be (true)
|
||||
}
|
||||
scenario("We will call the Add endpoint with user credentials and role", ApiEndpoint1, ApiEndpoint2, ApiEndpoint3, VersionOfApi) {
|
||||
Entitlement.entitlement.vend.addEntitlement(testBankId, resourceUser1.userId, CanCreateProduct.toString)
|
||||
|
||||
// Create an grandparent
|
||||
val grandparent: ProductJsonV400 = createProduct(code = "GRANDPARENT_CODE", json = parentPutProductJsonV500)
|
||||
|
||||
// Create an parent
|
||||
val product: ProductJsonV400 = createProduct(code = "PARENT_CODE", json = parentPutProductJsonV500.copy(parent_product_code = grandparent.product_code))
|
||||
|
||||
// Get
|
||||
val requestGet400 = (v5_0_0_Request / "banks" / product.bank_id / "products" / product.product_code ).GET <@(user1)
|
||||
val responseGet400 = makeGetRequest(requestGet400)
|
||||
Then("We should get a 200")
|
||||
responseGet400.code should equal(200)
|
||||
val product1 = responseGet400.body.extract[ProductJsonV400]
|
||||
|
||||
// Create an child
|
||||
val childPutProductJsonV400 = parentPutProductJsonV500.copy(parent_product_code = product.product_code)
|
||||
createProduct(code = "PRODUCT_CODE", json = childPutProductJsonV400)
|
||||
|
||||
// Get
|
||||
val requestGetAll400 = (v5_0_0_Request / "banks" / product.bank_id / "products").GET <@(user1)
|
||||
val responseGetAll400 = makeGetRequest(requestGetAll400)
|
||||
Then("We should get a 200")
|
||||
responseGetAll400.code should equal(200)
|
||||
val products: ProductsJsonV400 = responseGetAll400.body.extract[ProductsJsonV400]
|
||||
products.products.size shouldBe 3
|
||||
}
|
||||
scenario("We will call the Add endpoint with user credentials and role and minimal PUT JSON", ApiEndpoint1, ApiEndpoint2, ApiEndpoint3, VersionOfApi) {
|
||||
Entitlement.entitlement.vend.addEntitlement(testBankId, resourceUser1.userId, CanCreateProduct.toString)
|
||||
// Create an grandparent
|
||||
val grandparent: ProductJsonV400 = createProduct(
|
||||
code = "GRANDPARENT_CODE",
|
||||
json = PutProductJsonV500(
|
||||
name = parentPutProductJsonV500.name,
|
||||
parent_product_code = parentPutProductJsonV500.parent_product_code
|
||||
)
|
||||
)
|
||||
// Create an parent
|
||||
val product: ProductJsonV400 = createProduct(code = "PARENT_CODE", json = parentPutProductJsonV500.copy(parent_product_code = grandparent.product_code))
|
||||
|
||||
// Get
|
||||
val requestGet400 = (v5_0_0_Request / "banks" / product.bank_id / "products" / product.product_code ).GET <@(user1)
|
||||
val responseGet400 = makeGetRequest(requestGet400)
|
||||
Then("We should get a 200")
|
||||
responseGet400.code should equal(200)
|
||||
val product1 = responseGet400.body.extract[ProductJsonV400]
|
||||
|
||||
// Create an child
|
||||
val childPutProductJsonV400 = parentPutProductJsonV500.copy(parent_product_code = product.product_code)
|
||||
createProduct(code = "PRODUCT_CODE", json = childPutProductJsonV400)
|
||||
|
||||
// Get
|
||||
val requestGetAll400 = (v5_0_0_Request / "banks" / product.bank_id / "products").GET <@(user1)
|
||||
val responseGetAll400 = makeGetRequest(requestGetAll400)
|
||||
Then("We should get a 200")
|
||||
responseGetAll400.code should equal(200)
|
||||
val products: ProductsJsonV400 = responseGetAll400.body.extract[ProductsJsonV400]
|
||||
products.products.size shouldBe 3
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
27
obp-api/src/test/scala/code/api/v5_0_0/V500ServerSetup.scala
Normal file
27
obp-api/src/test/scala/code/api/v5_0_0/V500ServerSetup.scala
Normal file
@ -0,0 +1,27 @@
|
||||
package code.api.v5_0_0
|
||||
|
||||
import code.api.v4_0_0.BanksJson400
|
||||
import code.setup.{APIResponse, DefaultUsers, ServerSetupWithTestData}
|
||||
import com.openbankproject.commons.util.ApiShortVersions
|
||||
import dispatch.Req
|
||||
|
||||
import scala.util.Random.nextInt
|
||||
|
||||
trait V500ServerSetup extends ServerSetupWithTestData with DefaultUsers {
|
||||
|
||||
def v5_0_0_Request: Req = baseRequest / "obp" / "v5.0.0"
|
||||
def dynamicEndpoint_Request: Req = baseRequest / "obp" / ApiShortVersions.`dynamic-endpoint`.toString
|
||||
def dynamicEntity_Request: Req = baseRequest / "obp" / ApiShortVersions.`dynamic-entity`.toString
|
||||
|
||||
def randomBankId : String = {
|
||||
def getBanksInfo : APIResponse = {
|
||||
val request = v5_0_0_Request / "banks"
|
||||
makeGetRequest(request)
|
||||
}
|
||||
val banksJson = getBanksInfo.body.extract[BanksJson400]
|
||||
val randomPosition = nextInt(banksJson.banks.size)
|
||||
val bank = banksJson.banks(randomPosition)
|
||||
bank.id
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user