Skip to content

Commit

Permalink
NOJIRA: Unify calls to lookup functions
Browse files Browse the repository at this point in the history
  • Loading branch information
ssaleem-ee committed May 10, 2024
1 parent 3df8fa0 commit 6c9442d
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 33 deletions.
41 changes: 26 additions & 15 deletions app/controllers/AddressSearchController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ package controllers

import access.AccessChecker
import config.ConfigHelper
import model.request.{LookupByCountryRequest, LookupByCountryRequestFilter, LookupByPostTownRequest, LookupByPostcodeRequest, LookupByUprnRequest}
import model.address.Postcode
import model.request.{LookupByCountryRequest, LookupByCountryRequestFilter, LookupByPostTownRequest, LookupByPostcodeRequest, LookupByUprnRequest, LookupRequest}
import model.response.{ErrorResponse, SupportedCountryCodes}
import play.api.Logging
import play.api.libs.json.{JsError, JsSuccess, JsValue, Json, Reads}
Expand All @@ -37,63 +38,73 @@ class AddressSearchController @Inject()(addressSearchService: AddressSearchServi
scheduler: CheckAddressDataScheduler,
val configHelper: ConfigHelper)(implicit ec: ExecutionContext)
extends BaseController with AccessChecker with Logging {

import ErrorResponse.Implicits._

scheduler.enable()

def search(): Action[String] = accessCheckedAction(parse.tolerantText) {
request =>
implicit val hc: HeaderCarrier = HeaderCarrierConverter.fromRequest(request)

withValidJson[LookupByPostcodeRequest](request) match {
case Left(err) => err
case Left(err) => err
case Right(lookupByPostcodeRequest: LookupByPostcodeRequest) =>
addressSearchService.searchByPostcode(request, lookupByPostcodeRequest)
doLookup[Postcode, LookupByPostcodeRequest](request, addressSearchService.searchByPostcode(_, _), lookupByPostcodeRequest)
}
}

def searchByUprn(): Action[String] = accessCheckedAction(parse.tolerantText) {
request =>
implicit val hc: HeaderCarrier = HeaderCarrierConverter.fromRequest(request)

withValidJson[LookupByUprnRequest](request) match {
case Left(err) => err
case Left(err) => err
case Right(lookupByUprnRequest: LookupByUprnRequest) =>
addressSearchService.searchByUprn(request, lookupByUprnRequest)
doLookup[String, LookupByUprnRequest](request, addressSearchService.searchByUprn(_, _), lookupByUprnRequest)
}
}

def searchByPostTown(): Action[String] = accessCheckedAction(parse.tolerantText) {
request =>
implicit val hc: HeaderCarrier = HeaderCarrierConverter.fromRequest(request)

withValidJson[LookupByPostTownRequest](request) match {
case Left(err) => err
case Left(err) => err
case Right(lookupByPostTownRequest: LookupByPostTownRequest) =>
addressSearchService.searchByTown(request, lookupByPostTownRequest)
doLookup[String, LookupByPostTownRequest](request, addressSearchService.searchByTown(_, _), lookupByPostTownRequest)
}
}

def searchByCountry(countryCode: String): Action[String] = accessCheckedAction(parse.tolerantText) {
request =>
implicit val hc: HeaderCarrier = HeaderCarrierConverter.fromRequest(request)

withValidJson[LookupByCountryRequestFilter](request, je => Json.toJson(ErrorResponse.invalidJson)) match {
withValidJson[LookupByCountryRequestFilter](request, _ => Json.toJson(ErrorResponse.invalidJson)) match {
case Left(err) =>
err
case Right(country: LookupByCountryRequestFilter) =>
val countryLookup = LookupByCountryRequest.fromLookupByCountryRequestFilter(countryCode.toLowerCase, country)
addressSearchService.searchByCountry(request, countryLookup)
doLookup[String, LookupByCountryRequest](request, addressSearchService.searchByCountry(_, _), countryLookup)
}
}

private def withValidJson[T: Reads](request: Request[String],
validateError: JsError => JsValue = err => JsError.toJson(err)): Either[Future[Result], Any] = {
Try(Json.parse(request.body)) match {
case Success(json) => json.validate[T] match {
case JsSuccess(value, _) =>
Try(Json.parse(request.body)).toEither match {
case Right(json) => json.validate[T].asEither match {
case Right(value) =>
Right(value)
case jse@JsError(_) =>
Left(Future.successful(BadRequest(validateError(jse))))
case Left(errs) =>
Left(Future.successful(BadRequest(validateError(JsError(errs)))))
}
case Failure(_) => Left(Future.successful(BadRequest(Json.toJson(ErrorResponse.invalidJson))))
case Left(_) => Left(Future.successful(BadRequest(Json.toJson(ErrorResponse.invalidJson))))
}
}

private def doLookup[T, B <: LookupRequest[T]](request: Request[String], lookup: (Request[String], B) => Future[Result], lookupRequest: B)(implicit hc: HeaderCarrier) =
lookup(request, lookupRequest)

def supportedCountries(): Action[AnyContent] = Action.async {
import model.response.SupportedCountryCodes._
Future.successful(Ok(Json.toJson(supportedCountryCodes)))
Expand Down
36 changes: 18 additions & 18 deletions app/model/request.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 HM Revenue & Customs
* Copyright 2024 HM Revenue & Customs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -23,9 +23,9 @@ import play.api.libs.json._


object request {
abstract class Filterable(filter: Option[String])
sealed abstract class LookupRequest[T](value: T, filter: Option[String])

case class LookupByPostcodeRequest(postcode: Postcode, filter: Option[String] = None) extends Filterable(filter)
case class LookupByPostcodeRequest(postcode: Postcode, filter: Option[String] = None) extends LookupRequest(postcode, filter)

object LookupByPostcodeRequest {
implicit val postcodeReads: Reads[Postcode] = Reads[Postcode] { json =>
Expand All @@ -39,45 +39,45 @@ object request {
}
}

implicit val postcodeWrites: Writes[Postcode] = new Writes[Postcode]{
implicit val postcodeWrites: Writes[Postcode] = new Writes[Postcode] {
override def writes(o: Postcode): JsValue =
JsString(o.toString)
}

implicit val reads: Reads[LookupByPostcodeRequest] = (
(JsPath \ "postcode").read[Postcode] and
(JsPath \ "filter").readNullable[String].map(fo =>
fo.flatMap(f => if(f.trim.isEmpty) None else Some(f))
)
) (
(JsPath \ "postcode").read[Postcode] and
(JsPath \ "filter").readNullable[String].map(fo =>
fo.flatMap(f => if (f.trim.isEmpty) None else Some(f))
)
)(
(pc, fo) => LookupByPostcodeRequest.apply(pc, fo))

implicit val writes: Writes[LookupByPostcodeRequest] = Json.writes[LookupByPostcodeRequest]
}

case class LookupByUprnRequest(uprn: String)
case class LookupByUprnRequest(uprn: String) extends LookupRequest(uprn, None)

object LookupByUprnRequest {
implicit val reads: Reads[LookupByUprnRequest] = Json.reads[LookupByUprnRequest]
implicit val writes: Writes[LookupByUprnRequest] = Json.writes[LookupByUprnRequest]
}

case class LookupByIdRequest(id: String)
case class LookupByIdRequest(id: String) extends LookupRequest(id, None)

object LookupByIdRequest {
implicit val reads: Reads[LookupByIdRequest] = Json.reads[LookupByIdRequest]
implicit val writes: Writes[LookupByIdRequest] = Json.writes[LookupByIdRequest]
}

case class LookupByPostTownRequest(posttown: String, filter: Option[String]) extends Filterable(filter)
case class LookupByPostTownRequest(posttown: String, filter: Option[String]) extends LookupRequest(posttown, filter)

object LookupByPostTownRequest {
implicit val reads: Reads[LookupByPostTownRequest] = (
(JsPath \ "posttown").read[String] and
(JsPath \ "filter").readNullable[String].map(fo =>
fo.flatMap(f => if(f.trim.isEmpty) None else Some(f))
)
) (
(JsPath \ "posttown").read[String] and
(JsPath \ "filter").readNullable[String].map(fo =>
fo.flatMap(f => if (f.trim.isEmpty) None else Some(f))
)
)(
(pt, fo) => LookupByPostTownRequest.apply(pt, fo))

implicit val writes: Writes[LookupByPostTownRequest] = Json.writes[LookupByPostTownRequest]
Expand All @@ -90,7 +90,7 @@ object request {
implicit val writes: Writes[LookupByCountryRequestFilter] = Json.writes[LookupByCountryRequestFilter]
}

case class LookupByCountryRequest(country: String, filter: Option[String])
case class LookupByCountryRequest(country: String, filter: Option[String]) extends LookupRequest(country, filter)

object LookupByCountryRequest {
def fromLookupByCountryRequestFilter(country: String, lookupByCountryRequestFilter: LookupByCountryRequestFilter) =
Expand Down

0 comments on commit 6c9442d

Please sign in to comment.