Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Input format schema and Api integration added for quote and select ap… #5

Open
wants to merge 17 commits into
base: master
Choose a base branch
from

Conversation

shoaib5261
Copy link

Input format schema and Wakam api integration added for quote and select endpoints

Copy link
Contributor

@AminJELLADParticeep AminJELLADParticeep left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Many things :
1 - rename all occurences of newpricer into "wakam" for the folder and "WakamHome" for class name
2 - you must add test for wakam Service like explained in the readme
3 - put "wakam.home" before in the start of package name.
4 - encaspule all class and object (put in the start private[wakam])
5 - put "wakam.home" in the start of each package

Json.toJson(request)(WakamSubscribe.wakam_subscribe_write)
)
} yield {
response.status match {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should put this before the yield (so between for and yield) and create a method named for instance "parse_wakam_response" and create a test which ... test your method

Json.toJson(request)(WakamQuote.wakam_quote_write)
)
} yield {
response.status match {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same thing here:
"you should put this before the yield (so between for and yield) and create a method named for instance "parse_wakam_response" and create a test which ... test your method"
Moreover is there any way to merge this code with code you wrote below ?

import helpers.{ Enum, EnumHelper }
import play.api.libs.json.{ JsString, JsValue, Writes }

sealed trait Title extends Product with Serializable with Enum
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you have to encaspulate private[wakam]
same thing for all class and object.


object Stage extends EnumHelper[Stage] {

// all name of enumeration are in uppercase
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I appreciate this, but it is relevant when you are sharing code or for a tutorial. All employee (must) knows this, because it is a rule in our enterprise. That's means if you will work for another enterprise this rule won't perhaps not appear or will be be prohibed.

You can delete all comment from this class. At least you seems to prove that you understood the mechanic.

)

object WakamQuote {
private[this] def convert_boolean_option_toString(option: Boolean): String = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can rename this method in "convert_boolean_to_yes_no" , I thing it is more understandable.

Copy link
Contributor

@AminJELLADParticeep AminJELLADParticeep left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete all useless file like NewPricerxxx, normally you had to fill it and rename the class according to the api name.

You did some method like parse_wakam_quote_response. As we said in the readme you have to test your method. This time you can use mock.

"ALLZ04938127",
OffsetDateTime.parse("2015-01-01T00:00:00+01:00", date_formatter)
)
private[this] val selected_quote = Quote("", OffsetDateTime.now(), "", "", "", "", "", "", "", offer_data)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use TimeUtils.now() instead of OffsetDateTime.now().

fail => {
fail.message mustBe ("Les paramétres transmis ne permettent pas d'établir un tarif. Vérifier les modalités transmises.")
},
result => result
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrong way to do that.
Do result => result return nothing so your test is a success. It is like returned "void"
You can use "succeed" from scala test to say here it is a success case

reponse.fold(
fail => ...,
_ => succeed
)

)
}
// ignore
"return selected quote with valid selection" in {
Copy link
Contributor

@AminJELLADParticeep AminJELLADParticeep Aug 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You do not need to put a comment, you can use scalatest to ignore your test.
remplace "in" to "ignore"

@@ -1,12 +1,12 @@
package newpricer.models
package wakam.home.models

/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can delete this file, because you defined somewhere else wakam quote and wakam selec data

import ai.x.play.json.Jsonx
import play.api.libs.json.OFormat

private[wakam] trait WakamJsonParser {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WakamJsonParser

normally this trait regroup all json from your class except custom situation when you need particular write or read in your code. So add all format here, if possible.


/**
* This case class describes the credentials needed to call the insurer's api
* It could be an api token, user / password, etc...
*/
private[newpricer] final case class NewPricerConfig()
private[wakam] final case class WakamConfig(key: String)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now you can rename this class to WakamQuoteConfig

private[this] def parse_wakam_quote_response(response: WSResponse): Fail \/ Offer = {
response.status match {
case 200 => response.json.validate[SuccessCase] match {
case JsSuccess(value, _) => \/-(Offer(
Copy link
Contributor

@AminJELLADParticeep AminJELLADParticeep Aug 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can clearly improve this part of the code (from line 32 to line 46).
See how.
for instance you can play with .map, getOrElse , orElse etc...

@@ -21,6 +21,6 @@ class PricerFactory @Inject() (
}

private[this] val all_pricers = Map(
"new_pricer_9837778b-46b8-412b-a0c8-c3c478c0fda5" -> new_pricer
"new_pricer_9837778b-46b8-412b-a0c8-c3c478c0fda5" -> wakam_home
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace new_pricer by wakam_home.
And also the UUID. you can generate a new UUID online.

Copy link
Contributor

@Driox Driox left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Il ne doit pas y avoir de modification en dehors du module 03-new_pricer
  • le renomage de new_pricer en wakam rend la review impossible car on ne voit pas le diff git : il faut revert ce changement
  • il y a des tests inutiles : il faut les rendre utile

Copy link
Contributor

@AminJELLADParticeep AminJELLADParticeep left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are too much warning in your code.

fail => {
fail.message contains "Les paramétres transmis ne permettent pas d'établir un tarif. Vérifier les modalités transmises."
},
_ => succeed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why have you a success if you received a price ? The aims of this test is to receive an error so this case must fail.

val new_pricer_service: NewPricerService =
new NewPricerService(ws = ws, config = configuration)
val response: Fail \/ PricerResponse = await(new_pricer_service.quote(new_pricer_quote, new_pricer_quote_config))
response.fold(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can simplify this pattern matching :

response match {
 case \/-(Offer(price,_,_,_,_)) =>  price mustBe offer_data.price
 case other => fail(s"unexpected response: $other_response") 
}

fail => {
fail.message contains "Unprocessable entity"
},
_ => succeed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why have you a success if you received a price ? The aims of this test is to receive an error so this case must fail.

)
}

"parse new pricer quote api response and return an offer" in {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You do not need to use network to test parse_new_pricer_quote_response.

First of all this method is only used by NewPricerService and it is not used somewhere else

private[newpricer] def parse_new_pricer_quote_response(response: SuccessCase): Offer

You have to put this private only for the class

private[this] def parse_new_pricer_quote_response(response: SuccessCase): Offer

If you want to use a method which is private for your test, you can use this PrivateMethod from scala play.

Your service need WSClient and Configuration. These things are not useful for us because we do not want to use network, you can mock them, initialize the service and invoke the private method. this should be something like that :

    "parse new pricer quote api response and return an offer" in {
      val ws: WSClient          = mock[WSClient]
      val config: Configuration = mock[Configuration]
      val service               = new NewPricerService(ws = ws, config = config)
      val parse_response        = PrivateMethod[Offer](Symbol("parse_new_pricer_quote_response"))

      val api_response = SuccessCase("8722b2eb-9069-4e5d-a174-889ee5c7c06c", "OK", "241.59")
      val offer: Offer = service invokePrivate parse_response(api_response)

      offer.price mustBe offer_data.price
    }

import scalaz.{ -\/, \/, \/- }
import test.TestHelper
import utils.TimeUtils
import newpricer.models.{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace this by : import newpricer.models._

import org.scalatestplus.play.guice.GuiceOneServerPerTest
import com.typesafe.config.{ Config, ConfigFactory }
import newpricer.models.NewPricerResponse.SuccessCase
import play.api.libs.json.Json
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useless import

@@ -4,4 +4,4 @@ package newpricer.models
* This case class describes the credentials needed to call the insurer's api
* It could be an api token, user / password, etc...
*/
private[newpricer] final case class NewPricerConfig()
private[newpricer] final case class NewPricerQuoteConfig(key: String)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can regroup this and

private[newpricer] case class NewPricerSelectConfig(key: String, partnership_code: String)

at the same file, there are sharing the same aim. Rename the file intor NewPricerConfig.

case class SuccessCase(QuoteReference: String, message: String, MontantTotalPrimeTTC: String)
extends NewPricerResponse

case class FailureCase(message: String) extends NewPricerResponse
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the end, you do not use this class. You can delete it

implicit val new_pricer_subscribe_read: OFormat[NewPricerSubscribe] = Jsonx.formatCaseClass[NewPricerSubscribe]
implicit val beneficiaries_read: Reads[Beneficiaries] = Json.reads[Beneficiaries]
implicit val beneficiaries_write: Writes[Beneficiaries] = new Writes[Beneficiaries] {
override def writes(o: Beneficiaries): JsValue = Json.obj(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

o like object ?
you should rename it for beneficiary.
but why Beneficiaries contains a S ? This class represent one Beneficiary

Copy link
Contributor

@AminJELLADParticeep AminJELLADParticeep left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert also messages.en.conf and messages.fr.conf
revert all file outside of new_pricer expect build.sbt

pricer <- pricer_factory.build(pricer_id) ?| ()
result <- pricer.quote(broker_config)(pricer_id, input) ?| ()
pricer <- pricer_factory.build(pricer_id) ?| ()
result <- pricer.quote(new_pricer_quote_config)(pricer_id, input) ?| ()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert this file

).url}">${routes.QuoteController.format("new_pricer_9837778b-46b8-412b-a0c8-c3c478c0fda5").url}</a></li>
<li>Quote : POST ${routes.QuoteController.quote("new_pricer_9837778b-46b8-412b-a0c8-c3c478c0fda5").url}</li>
<li>Select : POST ${routes.QuoteController.select("new_pricer_9837778b-46b8-412b-a0c8-c3c478c0fda5").url}</li>
"new_pricer_3c25657e-2952-11ed-a261-0242ac120002"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert this file changing UUID is only on Pricer factory

def quote(broker_config: Option[JsValue])(
pricer_id: String,
quote_input: QuoteInput
def quote(new_pricer_quote_config: Option[JsValue])(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert this file

Copy link
Contributor

@AminJELLADParticeep AminJELLADParticeep left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they are some warning due to unused import in your test file.

@@ -6,10 +6,9 @@ import play.twirl.api.Html
@Singleton
class ApplicationController extends BaseController {

def ping = Action {
def ping = Action {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert completely this file, it does not appear in the pr

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean it must not appear in the pr

import scalaz.{ -\/, \/, \/- }
import newpricer.NewPricer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert completely this file, it does not appear in the pr

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean it must not appear in the pr

import com.typesafe.config.{ Config, ConfigFactory }
import newpricer.models.NewPricerResponse.SuccessCase
import org.scalatest.PrivateMethodTester
import org.scalatest.PrivateMethodTester.PrivateMethod
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useless import.

build.sbt Outdated
@@ -21,15 +21,16 @@ lazy val core: Project = (project in file("modules/01-core")).enablePlugins(Play
.settings(commonPlaySettings: _*)
.settings(aggregateReverseRoutes := Seq(root))

lazy val domain: Project = (project in file("modules/02-domain"))
lazy val domain: Project = (project in file("modules/02-domain"))
Copy link
Contributor

@Driox Driox Sep 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes in this file must be revert

Copy link
Contributor

@AminJELLADParticeep AminJELLADParticeep Sep 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these changes are mine, otherwise he can't run the tests

def quote(broker_config: Option[JsValue])(
pricer_id: String,
quote_input: QuoteInput
override def quote(new_pricer_quote_config: Option[JsValue])(
Copy link
Contributor

@Driox Driox Sep 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should not change the public interface you have to implement

new_pricer_quote_config -> broker_config

def select(broker_config: Option[JsValue])(
pricer_id: String,
subscription_input: SelectSubscriptionInput
override def select(new_pricer_select_config: Option[JsValue])(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idem

@@ -4,4 +4,5 @@ package newpricer.models
* This case class describes the credentials needed to call the insurer's api
* It could be an api token, user / password, etc...
*/
private[newpricer] final case class NewPricerConfig()
private[newpricer] final case class NewPricerQuoteConfig(key: String)
private[newpricer] case class NewPricerSelectConfig(key: String, partnership_code: String)
Copy link
Contributor

@Driox Driox Sep 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to choose : either case class are final or not

but your code have to be consistent


private[this] val new_pricer_url = config.get[String]("new_pricer.url")

private[this] def parse_new_pricer_quote_response(response: SuccessCase): Offer = {
Copy link
Contributor

@Driox Driox Sep 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why you don't parse all the data

In the wakam's doc, we have data about Garanties

"Garanties": [{
        "CodeGarantie": "INC",
        "MontantPrimeHT": "15.93",
        "MontantTotalCommissions": "3.35",
        "MontantTotalTaxes": "4.78",
        "MontantPrimeTTC": "20.71",
        "Plafond": "25000.00",
        "Franchise": "150.00"
    }, {
...
}]

You need to parse them and add it into the response, in the OfferItem field

response <- ws.url(s"$new_pricer_url/getPrice").addHttpHeaders("Ocp-Apim-Subscription-Key" -> config.key).post(
Json.toJson(request)(new_pricer_quote_write)
) ?| ()
result <- response.json.validate[SuccessCase] ?| s"error in parsing response from api: ${response.body}"
Copy link
Contributor

@Driox Driox Sep 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where did you handle the error ?

  • 400 Bad Request
  • 401 Unauthorized
  • 524 User defined status code

private[this] def parse_new_pricer_quote_response(response: SuccessCase): Offer = {
Offer(
Price(Amount(amountFromDoubleToCentime(PricerBaseCalculator.average_price(
response.MontantTotalPrimeTTC.toDouble,
Copy link
Contributor

@Driox Driox Sep 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why you put amount with taxes into the fields that should contains the amount without taxes ?

@@ -0,0 +1,183 @@
package newpricer

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should add some test that don't call webservice / network

This test should verify your parser (success and error) with static json data

Copy link
Contributor

@AminJELLADParticeep AminJELLADParticeep left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You created a folded with a list of enumerations, you them in quote and select AND in the input format

)
private[this] val selected_quote: Quote = Quote("", TimeUtils.now(), "", "", "", "", "", "", "", offer_data)
private[this] val get_price_api_success_response = Json.parse(
"""{ "statusCode": 200, "message": "OK", "MontantTotalPrimeHT": "213.16", "MontantTotalCommissions": "42.31", "MontantTotalTaxes": "28.43", "MontantTotalPrimeTTC": "241.59", "CoefficientLatitude": "0.00", "TauxCommissionnementPartenariat": "0.21", "Garanties": [{ "CodeGarantie": "INC", "MontantPrimeHT": "15.93", "MontantTotalCommissions": "3.35", "MontantTotalTaxes": "4.78", "MontantPrimeTTC": "20.71", "Plafond": "25000.00", "Franchise": "150.00" }, { "CodeGarantie": "TEMP", "MontantPrimeHT": "5.36", "MontantTotalCommissions": "1.13", "MontantTotalTaxes": "0.48", "MontantPrimeTTC": "5.84", "Plafond": "25000.00", "Franchise": "150.00" }, { "CodeGarantie": "DDE", "MontantPrimeHT": "90.80", "MontantTotalCommissions": "19.07", "MontantTotalTaxes": "8.17", "MontantPrimeTTC": "98.97", "Plafond": "25000.00", "Franchise": "150.00" }, { "CodeGarantie": "VLX", "MontantPrimeHT": "32.41", "MontantTotalCommissions": "6.81", "MontantTotalTaxes": "2.92", "MontantPrimeTTC": "35.33", "Plafond": "8500.00", "Franchise": "150.00" }, { "CodeGarantie": "RCX", "MontantPrimeHT": "8.32", "MontantTotalCommissions": "1.75", "MontantTotalTaxes": "0.75", "MontantPrimeTTC": "9.07", "Plafond": "6 300 000€ par sinistre dans la limite de 900 000€ pour les dommages matériels et immatériels consécutifs", "Franchise": "0.00" }, { "CodeGarantie": "CATNAT", "MontantPrimeHT": "13.98", "MontantTotalCommissions": "1.12", "MontantTotalTaxes": "1.26", "MontantPrimeTTC": "15.24", "Plafond": "25000.00", "Franchise": "Franchise légale" }, { "CodeGarantie": "CATECH", "MontantPrimeHT": "3.76", "MontantTotalCommissions": "0.79", "MontantTotalTaxes": "0.34", "MontantPrimeTTC": "4.10", "Plafond": "25000.00", "Franchise": "0.00" }, { "CodeGarantie": "DRX", "MontantPrimeHT": "2.78", "MontantTotalCommissions": "0.58", "MontantTotalTaxes": "0.25", "MontantPrimeTTC": "3.03", "Plafond": "20 000€ dans les limites et conditions prévues aux Conditions générales", "Franchise": "Seuil d'intervention de 300€ HT par litiges" }, { "CodeGarantie": "ASS", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "Selon convention", "Franchise": "Selon convention" }, { "CodeGarantie": "GAREAT", "MontantPrimeHT": "3.12", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.28", "MontantPrimeTTC": "3.40", "Plafond": "25000.00", "Franchise": "0.00" }, { "CodeGarantie": "ATTEN", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "5.90", "MontantPrimeTTC": "5.90", "Plafond": "15000.00", "Franchise": "0.00" }, { "CodeGarantie": "ANO", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "2500.00", "Franchise": "150.00" }, { "CodeGarantie": "PHONE", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "1000.00", "Franchise": "150.00" }, { "CodeGarantie": "ORDI", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "1200.00", "Franchise": "150.00" }, { "CodeGarantie": "DOMX", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "15000.00", "Franchise": "150.00" }, { "CodeGarantie": "BDG", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "Valeur du matériel de remplacement", "Franchise": "0.00" }, { "CodeGarantie": "ASSMAT", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "6 300 000€ par sinistre \ndans la limite de \n900 000€ pour les dommages matériels et immatériels consécutifs", "Franchise": "0.00" }, { "CodeGarantie": "RCLOCSAL", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "6 300 000€ par sinistre \ndans la limite de \n900 000€ pour les dommages matériels et immatériels consécutifs", "Franchise": "0.00" }, { "CodeGarantie": "RCLOCSAIS", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "6 300 000€ par sinistre \ndans la limite de \n900 000€ pour les dommages matériels et immatériels consécutifs", "Franchise": "0.00" }, { "CodeGarantie": "RCP", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "A venir", "Franchise": "150.00" }, { "CodeGarantie": "DOM", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "A venir", "Franchise": "150.00" }, { "CodeGarantie": "RCMOB", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "6 300 000€ par sinistre dans la limite de 900 000€ pour les dommages matériels et immatériels consécutifs", "Franchise": "150.00" }, { "CodeGarantie": "REMPMOB", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "8500.00", "Franchise": "150.00" }, { "CodeGarantie": "RCS", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "Limites et conditions prévues aux Conditions générales", "Franchise": "Franchises prévues aux Conditions générales" }, { "CodeGarantie": "CAVIN", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "Valeur de remplacement", "Franchise": "150.00" }, { "CodeGarantie": "CYB", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "A venir", "Franchise": "150.00" }, { "CodeGarantie": "DPER", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "A venir", "Franchise": "150.00" }, { "CodeGarantie": "STOCK", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "A venir", "Franchise": "150.00" }, { "CodeGarantie": "OBJVAL", "MontantPrimeHT": "36.70", "MontantTotalCommissions": "7.71", "MontantTotalTaxes": "3.30", "MontantPrimeTTC": "40.00", "Plafond": "5000.00", "Franchise": "150.00" }, { "CodeGarantie": "ANIDOM", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "230000.00", "Franchise": "150.00" }, { "CodeGarantie": "IA", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "A venir", "Franchise": "150.00" }, { "CodeGarantie": "PJ", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "20 000€ dans les limites et conditions prévues à la Convention Protection juridique", "Franchise": "Seuil d'intervention 350€ TTC par litiges dans les limites et conditions prévues à la Convention Protection juridique" }, { "CodeGarantie": "DEMRC", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "A venir", "Franchise": "150.00" }, { "CodeGarantie": "SHAR", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "Valeur de remplacement", "Franchise": "150.00" }, { "CodeGarantie": "PNOLOC", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "A venir", "Franchise": "A venir" }, { "CodeGarantie": "DEP", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "Matériel contenu : 1 500€", "Franchise": "150.00" }, { "CodeGarantie": "FRPAIE", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "0.00", "Franchise": "0.00" }, { "CodeGarantie": "FRSIGN", "MontantPrimeHT": "0.00", "MontantTotalCommissions": "0.00", "MontantTotalTaxes": "0.00", "MontantPrimeTTC": "0.00", "Plafond": "0.00", "Franchise": "0.00" }], "QuoteReference": "00000000-0000-0000-0000-000000000000" }"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use a json.beautifier here ?
Go to a site for that

error.a.message must include(unexpected_error_response.toString())
}

"return selected quote with valid selection" ignore {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put a comment to explain why this test is ignored

// test ignored due to bad credential ...


}

"return selected quote with missing selection data" ignore {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put a comment to explain why this test is ignored

@@ -0,0 +1,13 @@
package newpricer.models

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NewPricerResponse is never use, this an old relic from another time.
Delete it, you are only using SuccessCase or make this trait usefull but you have to create another case class.

Json.toJson(request)(new_pricer_subscribe_write)
) ?| ()
_ <-
(response.status == 200) ?| s"new pricer returned an error with status ${response.status} and body ${response.body}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i do not know if my superior will want to ask to do create a check_response_status like for quote but for select

Copy link
Contributor

@AminJELLADParticeep AminJELLADParticeep left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you update a cass class :
1 - update input format
2 - update method which use the cass class
3 - update your test. Currently your code does not compile in test.

@@ -0,0 +1,51 @@
package newpricer.models

import newpricer.models.enumerations.{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace
import newpricer.models.enumerations.{
CommercialLatitudeRequested,
ComputerOption,
Deductible,
NomadicBusinessOption,
OccupationStatus,
Stage
}

by
import newpricer.models.enumerations._

private[newpricer] object InputFormatFactory {

/**
* This should be the format of the input required by the quote endpoint
*/
def input_format_quote: List[InputFormat] = {
???
List(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of your input format can be improved.
For instance, if you see FieldType in module "domain", it is an ADT with this enumeration :

  final case object TEXT      extends FieldType
  final case object DATE      extends FieldType
  final case object NUMBER    extends FieldType
  final case object ADDRESS   extends FieldType
  final case object PHONE     extends FieldType
  final case object FILE      extends FieldType
  final case object ENUM      extends FieldType
  final case object OBJECT    extends FieldType
  final case object BOOLEAN   extends FieldType
  final case object SIGNATURE extends FieldType

I see you are already using this, but I want to put in light your recently update about type of three fields :

InputFormat(name = "surface", kind           = NUMBER, mandatory   = true),
InputFormat(name = "movable_capital", kind   = NUMBER, mandatory   = true),
InputFormat(name = "capital_valuables", kind = NUMBER, mandatory   = true),

See if you have to update other fields.

reference_client: String,
start_date_effect: OffsetDateTime,
end_date_effect: OffsetDateTime,
split_payment: String,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this field, you have to change type String to type SplitPayment.
Change also custom write.

See also if other fields have this problem of type.

private[newpricer] sealed trait CommercialLatitudeRequested extends Product with Serializable with Enum

private[newpricer] object CommercialLatitudeRequested extends EnumHelper[CommercialLatitudeRequested] {
final case object `-15%` extends CommercialLatitudeRequested { override def label(): String = "-15%" }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should change in every Enum

override def label(): String = "XXX"

into

val label = "XXX"


/**
* @param request : input for the webservice
* @param config : broker authentication
* @return
*/
private[newpricer] def quote(
request: NewPricerQuoteRequest,
config: NewPricerConfig
request: NewPricerQuote,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you change name of input parameters ?

NewPricerQuoteRequest vs NewPricerQuote
NewPricerConfig vs NewPricerQuoteConfig
NewPricerSelectRequest vs NewPricerSubscribe
NewPricerConfig vs NewPricerSelectConfig

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The data types are changed for (NewPricerQuote and NewPricerSelectConfig) according to the data we are receiving from NewPricer in function call. And for the config attribute as we have different configuration parameters for both quote and select api end points for wakam that's why NewPricerConfig changed to NewPricerQuoteConfig and NewPricerSelectConfig accordingly

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand your answer

We'll try with a smaller scope : please answer why

  • you rename NewPricerQuoteRequest into NewPricerQuote
  • you rename NewPricerSelectRequest into NewPricerSubscribe

Copy link
Author

@shoaib5261 shoaib5261 Sep 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have changed NewPricerQuoteRequest to NewPricerQuote because the data we are getting in the variable request is an object of class NewPricerQuote. If you check the the file NewPricer.scala you can see that json body is parsed to NewPricerQuote object and passed to quote function as parameter as:

    for {
      pricer_request <- quote_input.input_json.validate[NewPricerQuote] ?| ()
      auth           <- broker_config                                   ?| "error.broker.login.required"
      broker_config  <- auth.validate[NewPricerQuoteConfig]             ?| ()
      result         <- service.quote(pricer_request, broker_config)    ?| ()
    } yield {
      result
    }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not a logical answer

You renamed NewPricerQuoteRequest to NewPricerQuote
So obviously you have to take NewPricerQuote as input: it's a consequence and not a cause
The same goes for NewPricerSelectRequest into NewPricerSubscribe

If you have no real reason for the renaming please revert it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind we'll do it

fail => {
fail.message must include("Unprocessable entity")
},
result => fail(s"unexpected response: $result")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This kind of test are misleading

What did you expect here ?

fail.message must include("Unprocessable entity") ?

OR

fail(s"unexpected response: $result") ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should write tests in this format

val input = ...
val result = method_under_test(input...)

val expected_result = ...

result mustBe expected_result

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As in this case I am testing the failure scenario from the method and We got response from method in the form of Fail \/ Response so that's why must matcher is applied to fail case and in case we get any other response then by using the fail method from playspec the test will fail with the unexpected response.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants