Merge pull request #1212 from constantine2nd/develop

Product bucket
This commit is contained in:
Simon Redfern 2019-02-08 04:42:21 +01:00 committed by GitHub
commit 213e6a718d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 213 additions and 37 deletions

View File

@ -2090,6 +2090,47 @@ object SwaggerDefinitionsJSON {
)
val productsJsonV210 = ProductsJsonV210(products = List(productJsonV210))
val grandparentProductBucketJsonV310 = ProductBucketJsonV310(
bank_id="testBank2",
code="GRANDPARENT_CODE",
name="product name",
category="category",
family="family",
super_family="super family",
more_info_url="www.example.com/prod1/more-info.html",
details="Details",
description="Description",
meta = metaJson,
parent_product=None
)
val parentProductBucketJsonV310 = ProductBucketJsonV310(
bank_id="testBank2",
code="PARENT_CODE",
name="product name",
category="category",
family="family",
super_family="super family",
more_info_url="www.example.com/prod1/more-info.html",
details="Details",
description="Description",
meta = metaJson,
parent_product=Some(grandparentProductBucketJsonV310)
)
val childProductBucketJsonV310 = ProductBucketJsonV310(
bank_id="testBank2",
code="CHILD_CODE",
name="product name",
category="category",
family="family",
super_family="super family",
more_info_url="www.example.com/prod1/more-info.html",
details="Details",
description="Description",
meta = metaJson,
parent_product=Some(parentProductBucketJsonV310)
)
val postCounterpartyBespokeJson = PostCounterpartyBespokeJson(

View File

@ -145,7 +145,8 @@ object NewStyle {
(nameOf(Implementations3_1_0.createProduct), ApiVersion.v3_1_0.toString),
(nameOf(Implementations3_1_0.updateCustomerAddress), ApiVersion.v3_1_0.toString),
(nameOf(Implementations3_1_0.getProduct), ApiVersion.v3_1_0.toString),
(nameOf(Implementations3_1_0.getProducts), ApiVersion.v3_1_0.toString)
(nameOf(Implementations3_1_0.getProducts), ApiVersion.v3_1_0.toString),
(nameOf(Implementations3_1_0.getProductBucket), ApiVersion.v3_1_0.toString)
)
object HttpCode {

View File

@ -23,7 +23,7 @@ import code.metrics.APIMetrics
import code.model._
import code.model.dataAccess.{AuthUser, BankAccountCreation}
import code.productattribute.ProductAttribute.ProductAttributeType
import code.products.Products.ProductCode
import code.products.Products.{Product, ProductCode}
import code.users.Users
import code.util.Helper
import code.webhook.AccountWebhook
@ -2511,6 +2511,64 @@ trait APIMethods310 {
}
}
resourceDocs += ResourceDoc(
getProductBucket,
implementedInApiVersion,
"getProductBucket",
"GET",
"/banks/BANK_ID/product-bucket/PRODUCT_CODE",
"Get Bank Product",
s"""Returns information about the financial products offered by a bank specified by BANK_ID and PRODUCT_CODE including:
|
|* Name
|* Code
|* Category
|* Family
|* Super Family
|* More info URL
|* Description
|* Terms and Conditions
|* License the data under this endpoint is released under
|${authenticationRequiredMessage(!getProductsIsPublic)}""",
emptyObjectJson,
childProductBucketJsonV310,
List(
UserNotLoggedIn,
ProductNotFoundByProductCode,
UnknownError
),
Catalogs(notCore, notPSD2, OBWG),
List(apiTagProduct)
)
lazy val getProductBucket: OBPEndpoint = {
case "banks" :: BankId(bankId) :: "product-bucket" :: ProductCode(productCode) :: Nil JsonGet _ => {
def getProductBucket(bankId : BankId, productCode : ProductCode): List[Product] = {
Connector.connector.vend.getProduct(bankId, productCode) match {
case Full(p) if p.parentProductCode.value.nonEmpty => p :: getProductBucket(p.bankId, p.parentProductCode)
case Full(p) => List(p)
case _ => List()
}
}
cc => {
for {
(_, callContext) <-
getProductsIsPublic match {
case true => authorizeEndpoint(UserNotLoggedIn, cc)
case false => Future((None, Some(cc)))
}
(_, callContext) <- NewStyle.function.getBank(bankId, callContext)
_ <- Future(Connector.connector.vend.getProduct(bankId, productCode)) map {
unboxFullOrFail(_, callContext, ProductNotFoundByProductCode, 400)
}
product <- Future(getProductBucket(bankId, productCode))
} yield {
(JSONFactory310.createProductBucketJson(product, productCode.value), HttpCode.`200`(callContext))
}
}
}
}
resourceDocs += ResourceDoc(
getProducts,
implementedInApiVersion,

View File

@ -380,6 +380,18 @@ case class ProductJsonV310(bank_id: String,
description: String,
meta : MetaJsonV140)
case class ProductsJsonV310 (products : List[ProductJsonV310])
case class ProductBucketJsonV310 (bank_id: String,
code : String,
name : String,
category: String,
family : String,
super_family : String,
more_info_url: String,
details: String,
description: String,
meta : MetaJsonV140,
parent_product: Option[ProductBucketJsonV310],
)
object JSONFactory310{
def createCheckbookOrdersJson(checkbookOrders: CheckbookOrdersJson): CheckbookOrdersJson =
@ -675,5 +687,63 @@ object JSONFactory310{
def createProductsJson(productsList: List[Product]) : ProductsJsonV310 = {
ProductsJsonV310(productsList.map(createProductJson))
}
def createProductBucketJson(product: Product, productBucket: Option[ProductBucketJsonV310]): ProductBucketJsonV310 = {
ProductBucketJsonV310(
bank_id = product.bankId.toString,
code = product.code.value,
parent_product = productBucket,
name = product.name,
category = product.category,
family = product.family,
super_family = product.superFamily,
more_info_url = product.moreInfoUrl,
details = product.details,
description = product.description,
meta = createMetaJson(product.meta)
)
}
def createProductBucketJson(productsList: List[Product], rootProductCode: String): ProductBucketJsonV310 = {
def getProductBucket(list: List[Product], code: String): Option[ProductBucketJsonV310] = {
productsList.filter(_.code.value == code) match {
case x :: Nil =>
Some(
ProductBucketJsonV310(
bank_id = x.bankId.toString,
code = x.code.value,
parent_product = getProductBucket(productsList, x.parentProductCode.value),
name = x.name,
category = x.category,
family = x.family,
super_family = x.superFamily,
more_info_url = x.moreInfoUrl,
details = x.details,
description = x.description,
meta = createMetaJson(x.meta)
)
)
case Nil =>
None
}
}
val rootElement = productsList.filter(_.code.value == rootProductCode).head
ProductBucketJsonV310(
bank_id = rootElement.bankId.toString,
code = rootElement.code.value,
parent_product = getProductBucket(productsList, rootElement.parentProductCode.value),
name = rootElement.name,
category = rootElement.category,
family = rootElement.family,
super_family = rootElement.superFamily,
more_info_url = rootElement.moreInfoUrl,
details = rootElement.details,
description = rootElement.description,
meta = createMetaJson(rootElement.meta)
)
}
}

View File

@ -327,6 +327,7 @@ object OBPAPI3_1_0 extends OBPRestHelper with APIMethods130 with APIMethods140 w
Implementations3_1_0.updateCustomerAddress ::
Implementations3_1_0.getProduct ::
Implementations3_1_0.getProducts ::
Implementations3_1_0.getProductBucket ::
Nil
val allResourceDocs = Implementations3_1_0.resourceDocs ++

View File

@ -34,6 +34,7 @@ import code.api.util.ErrorMessages._
import code.api.v3_1_0.OBPAPI3_1_0.Implementations3_1_0
import code.entitlement.Entitlement
import com.github.dwickern.macros.NameOf.nameOf
import net.liftweb.json.{Extraction, prettyRender}
import net.liftweb.json.Serialization.write
import org.scalatest.Tag
@ -60,9 +61,10 @@ class ProductTest extends V310ServerSetup {
object ApiEndpoint1 extends Tag(nameOf(Implementations3_1_0.createProduct))
object ApiEndpoint2 extends Tag(nameOf(Implementations3_1_0.getProduct))
object ApiEndpoint3 extends Tag(nameOf(Implementations3_1_0.getProducts))
object ApiEndpoint4 extends Tag(nameOf(Implementations3_1_0.getProductBucket))
lazy val testBankId = randomBankId
lazy val parentPostPutProductJsonV310 = SwaggerDefinitionsJSON.postPutProductJsonV310.copy(bank_id = testBankId, parent_product_code ="")
lazy val parentPostPutProductJsonV310: PostPutProductJsonV310 = SwaggerDefinitionsJSON.postPutProductJsonV310.copy(bank_id = testBankId, parent_product_code ="")
feature("Create Product v3.1.0") {
scenario("We will call the Add endpoint without a user credentials", ApiEndpoint1, VersionOfApi) {
@ -86,25 +88,35 @@ class ProductTest extends V310ServerSetup {
response310.body.extract[ErrorMessage].message should equal (createProductEntitlementsRequiredText)
}
scenario("We will call the Add endpoint with user credentials and role", ApiEndpoint1, ApiEndpoint2, ApiEndpoint3, VersionOfApi) {
// Create
Entitlement.entitlement.vend.addEntitlement(testBankId, resourceUser1.userId, CanCreateProduct.toString)
def createProduct(code: String, json: PostPutProductJsonV310) = {
When("We try to create a product v3.1.0")
val request310 = (v3_1_0_Request / "banks" / testBankId / "products" / "PARENT_CODE").PUT <@(user1)
val response310 = makePutRequest(request310, write(parentPostPutProductJsonV310))
val request310 = (v3_1_0_Request / "banks" / testBankId / "products" / code).PUT <@ (user1)
val response310 = makePutRequest(request310, write(json))
Then("We should get a 201")
response310.code should equal(201)
val product = response310.body.extract[ProductJsonV310]
product.code shouldBe "PARENT_CODE"
product.parent_product_code shouldBe ""
product.bank_id shouldBe parentPostPutProductJsonV310.bank_id
product.name shouldBe parentPostPutProductJsonV310.name
product.category shouldBe parentPostPutProductJsonV310.category
product.super_family shouldBe parentPostPutProductJsonV310.super_family
product.family shouldBe parentPostPutProductJsonV310.family
product.more_info_url shouldBe parentPostPutProductJsonV310.more_info_url
product.details shouldBe parentPostPutProductJsonV310.details
product.description shouldBe parentPostPutProductJsonV310.description
product.code shouldBe code
product.parent_product_code shouldBe json.parent_product_code
product.bank_id shouldBe json.bank_id
product.name shouldBe json.name
product.category shouldBe json.category
product.super_family shouldBe json.super_family
product.family shouldBe json.family
product.more_info_url shouldBe json.more_info_url
product.details shouldBe json.details
product.description shouldBe json.description
product
}
scenario("We will call the Add endpoint with user credentials and role", ApiEndpoint1, ApiEndpoint2, ApiEndpoint3, ApiEndpoint4, VersionOfApi) {
Entitlement.entitlement.vend.addEntitlement(testBankId, resourceUser1.userId, CanCreateProduct.toString)
// Create an grandparent
val grandparent: ProductJsonV310 = createProduct(code = "GRANDPARENT_CODE", json = parentPostPutProductJsonV310)
// Create an parent
val product: ProductJsonV310 = createProduct(code = "PARENT_CODE", json = parentPostPutProductJsonV310.copy(parent_product_code = grandparent.code))
// Get
val requestGet310 = (v3_1_0_Request / "banks" / product.bank_id / "products" / product.code ).GET <@(user1)
@ -113,25 +125,9 @@ class ProductTest extends V310ServerSetup {
responseGet310.code should equal(200)
responseGet310.body.extract[ProductJsonV310]
// Create
// Create an child
val childPostPutProductJsonV310 = parentPostPutProductJsonV310.copy(parent_product_code = product.code)
When("We try to create a product v3.1.0")
val createChildRequest310 = (v3_1_0_Request / "banks" / testBankId / "products" / "CHILD_CODE").PUT <@(user1)
val createChildResponse310 = makePutRequest(createChildRequest310, write(childPostPutProductJsonV310))
Then("We should get a 201")
createChildResponse310.code should equal(201)
val childProduct = createChildResponse310.body.extract[ProductJsonV310]
childProduct.code shouldBe "CHILD_CODE"
childProduct.parent_product_code shouldBe "PARENT_CODE"
childProduct.bank_id shouldBe childPostPutProductJsonV310.bank_id
childProduct.name shouldBe childPostPutProductJsonV310.name
childProduct.category shouldBe childPostPutProductJsonV310.category
childProduct.super_family shouldBe childPostPutProductJsonV310.super_family
childProduct.family shouldBe childPostPutProductJsonV310.family
childProduct.more_info_url shouldBe childPostPutProductJsonV310.more_info_url
childProduct.details shouldBe childPostPutProductJsonV310.details
childProduct.description shouldBe childPostPutProductJsonV310.description
createProduct(code = "CHILD_CODE", json = childPostPutProductJsonV310)
// Get
val requestGetAll310 = (v3_1_0_Request / "banks" / product.bank_id / "products").GET <@(user1)
@ -139,7 +135,16 @@ class ProductTest extends V310ServerSetup {
Then("We should get a 200")
responseGetAll310.code should equal(200)
val products: ProductsJsonV310 = responseGetAll310.body.extract[ProductsJsonV310]
products.products.size shouldBe 2
products.products.size shouldBe 3
// Get bucket
val requestGetBucket310 = (v3_1_0_Request / "banks" / product.bank_id / "product-bucket" / "CHILD_CODE").GET <@(user1)
val responseGetBucket310 = makeGetRequest(requestGetBucket310)
Then("We should get a 200")
org.scalameta.logger.elem(responseGetBucket310)
responseGetBucket310.code should equal(200)
val productBucket: ProductBucketJsonV310 = responseGetBucket310.body.extract[ProductBucketJsonV310]
org.scalameta.logger.elem(prettyRender(Extraction.decompose(productBucket)))
}
}