Skip to content

Commit

Permalink
Merge pull request #142 from hmrc/MTDSA-1578
Browse files Browse the repository at this point in the history
Started on unit test framework
  • Loading branch information
narendravijayarao authored May 1, 2018
2 parents 87d071a + 34e8a6e commit 4e2173e
Show file tree
Hide file tree
Showing 27 changed files with 574 additions and 43 deletions.
8 changes: 6 additions & 2 deletions app/uk/gov/hmrc/vatapi/config/AppContext.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,12 @@ import play.api.Play._
import uk.gov.hmrc.play.config.ServicesConfig
import uk.gov.hmrc.vatapi.auth.VATAuthEnrolments

object AppContext extends ServicesConfig {
private lazy val config = current.configuration
object AppContext extends AppContext with ServicesConfig {
lazy val config: Configuration = current.configuration
}

trait AppContext extends ServicesConfig {
val config: Configuration

lazy val desEnv: String = config.getString(s"$env.microservice.services.des.env").getOrElse(throw new RuntimeException("desEnv is not configured"))
lazy val desToken: String = config.getString(s"$env.microservice.services.des.token").getOrElse(throw new RuntimeException("desEnv is not configured"))
Expand Down
1 change: 1 addition & 0 deletions app/uk/gov/hmrc/vatapi/connectors/BaseConnector.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import scala.concurrent.{ExecutionContext, Future}
trait BaseConnector {

val http: WSHttp
val appContext: AppContext

private val logger = Logger("connectors")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ object FinancialDataConnector extends BaseConnector {

val logger: Logger = Logger(this.getClass)
override val http: WSHttp = WSHttp
override val appContext = AppContext

private lazy val baseUrl: String = s"${AppContext.desUrl}/enterprise/financial-data"

Expand Down
1 change: 1 addition & 0 deletions app/uk/gov/hmrc/vatapi/connectors/NRSConnector.scala
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import scala.concurrent.{ExecutionContext, Future}

object NRSConnector extends NRSConnector {
override val http: WSHttp = WSHttp
override val appContext = AppContext
}

trait NRSConnector extends BaseConnector {
Expand Down
12 changes: 7 additions & 5 deletions app/uk/gov/hmrc/vatapi/connectors/ObligationsConnector.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,21 @@ import uk.gov.hmrc.vatapi.resources.wrappers.ObligationsResponse
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

object ObligationsConnector extends BaseConnector {
object ObligationsConnector extends ObligationsConnector {
override val http: WSHttp = WSHttp
override val appContext = AppContext
}

val logger: Logger = Logger(this.getClass)
trait ObligationsConnector extends BaseConnector {
val http: WSHttp

private lazy val baseUrl: String = AppContext.desUrl
private lazy val baseUrl = appContext.desUrl
private val logger: Logger = Logger(this.getClass)

def get(vrn: Vrn, queryParams: ObligationsQueryParams)(implicit hc: HeaderCarrier): Future[ObligationsResponse] = {

logger.debug(s"[ObligationsConnector][get] Retrieve obligations for VRN $vrn with the given query parameters.")

val queryString = s"from=${queryParams.from}&to=${queryParams.to}&status=${queryParams.status}"
httpGet[ObligationsResponse](baseUrl + s"/enterprise/obligation-data/vrn/$vrn/VATC?$queryString", ObligationsResponse)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import scala.concurrent.{ExecutionContext, Future}

object VatReturnsConnector extends VatReturnsConnector {
override val http: WSHttp = WSHttp
override val appContext = AppContext
}

trait VatReturnsConnector extends BaseConnector {
Expand Down
6 changes: 4 additions & 2 deletions app/uk/gov/hmrc/vatapi/resources/BaseResource.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@ import scala.concurrent.Future
import scala.util.Right

trait BaseResource extends BaseController {
val authService: AuthorisationService
val appContext: AppContext

val logger: Logger = Logger(this.getClass)

private val authService = AuthorisationService
private lazy val featureSwitch = FeatureSwitch(AppContext.featureSwitch)
lazy val featureSwitch = FeatureSwitch(appContext.featureSwitch)

def AuthAction(vrn: Vrn) = new ActionRefiner[Request, AuthRequest] {
logger.debug(s"[BaseResource][AuthAction] Check MTD VAT authorisation for the VRN : $vrn")
Expand Down
4 changes: 4 additions & 0 deletions app/uk/gov/hmrc/vatapi/resources/FinancialDataResource.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,18 @@ import play.api.libs.json.Json
import play.api.mvc.{Action, AnyContent}
import uk.gov.hmrc.domain.Vrn
import uk.gov.hmrc.play.microservice.controller.BaseController
import uk.gov.hmrc.vatapi.config.AppContext
import uk.gov.hmrc.vatapi.connectors.FinancialDataConnector
import uk.gov.hmrc.vatapi.models.{Errors, FinancialDataQueryParams, Liabilities, Payments}
import uk.gov.hmrc.vatapi.services.AuthorisationService

import scala.concurrent.ExecutionContext.Implicits.global

object FinancialDataResource extends BaseResource {

private val connector = FinancialDataConnector
override val authService = AuthorisationService
override val appContext = AppContext

def retrieveLiabilities(vrn: Vrn, params: FinancialDataQueryParams): Action[AnyContent] = APIAction(vrn).async { implicit request =>
logger.debug(s"[FinancialDataResource][retrieveLiabilities] Retrieving Liabilities from DES")
Expand Down
21 changes: 15 additions & 6 deletions app/uk/gov/hmrc/vatapi/resources/ObligationsResource.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,39 @@ import cats.implicits._
import play.api.libs.json.{JsNull, JsValue, Json}
import play.api.mvc.{Action, AnyContent}
import uk.gov.hmrc.domain.Vrn
import uk.gov.hmrc.vatapi.audit.AuditEvent
import uk.gov.hmrc.vatapi.audit.AuditService.audit
import uk.gov.hmrc.vatapi.audit.{AuditEvent, AuditService}
import uk.gov.hmrc.vatapi.config.AppContext
import uk.gov.hmrc.vatapi.connectors.ObligationsConnector
import uk.gov.hmrc.vatapi.models.{Errors, ObligationsQueryParams}
import uk.gov.hmrc.vatapi.resources.wrappers.ObligationsResponse
import uk.gov.hmrc.vatapi.services.AuthorisationService

import scala.concurrent.ExecutionContext.Implicits.global

object ObligationsResource extends BaseResource {
object ObligationsResource extends ObligationsResource {
override val connector = ObligationsConnector
override val authService = AuthorisationService
override val appContext = AppContext
override val auditService = AuditService
}

private val connector = ObligationsConnector
trait ObligationsResource extends BaseResource {
val connector: ObligationsConnector
val auditService: AuditService

def retrieveObligations(vrn: Vrn, params: ObligationsQueryParams): Action[AnyContent] = APIAction(vrn).async { implicit request =>
logger.debug(s"[ObligationsResource][retrieveObligations] - Retrieve Obligations for VRN : $vrn")
fromDes {
for {
response <- execute { _ => connector.get(vrn, params) }
_ <- audit(RetrieveVatObligationsEvent(vrn, response))
_ <- auditService.audit(RetrieveVatObligationsEvent(vrn, response))
} yield response
} onSuccess { response =>
response.filter {
case 200 =>
response.obligations(vrn) match {
case Right(obj) => obj.map(x => Ok(Json.toJson(x))).getOrElse(NotFound)
case Right(Some(obligations)) => Ok(Json.toJson(obligations))
case Right(None) => NotFound
case Left(ex) =>
logger.error(s"[ObligationsResource][retrieveObligations] Json format from DES doesn't match the Obligations model: ${ex.msg}")
InternalServerError(Json.toJson(Errors.InternalServerError))
Expand Down
5 changes: 4 additions & 1 deletion app/uk/gov/hmrc/vatapi/resources/VatReturnsResource.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,21 @@ import play.api.mvc.{Action, AnyContent, Request}
import uk.gov.hmrc.domain.Vrn
import uk.gov.hmrc.vatapi.audit.AuditEvent
import uk.gov.hmrc.vatapi.audit.AuditService.audit
import uk.gov.hmrc.vatapi.config.AppContext
import uk.gov.hmrc.vatapi.connectors.VatReturnsConnector
import uk.gov.hmrc.vatapi.models.{Errors, VatReturnDeclaration}
import uk.gov.hmrc.vatapi.orchestrators.VatReturnsOrchestrator
import uk.gov.hmrc.vatapi.resources.wrappers.VatReturnResponse
import uk.gov.hmrc.vatapi.services.AuthorisationService

import scala.concurrent.ExecutionContext.Implicits.global

object VatReturnsResource extends BaseResource {

private val connector = VatReturnsConnector
private val orchestrator = VatReturnsOrchestrator
override val authService = AuthorisationService
override val appContext = AppContext

def submitVatReturn(vrn: Vrn): Action[JsValue] = APIAction(vrn, nrsRequired = true).async(parse.json) { implicit request =>
val receiptId = "Receipt-ID"
Expand Down Expand Up @@ -103,5 +107,4 @@ object VatReturnsResource extends BaseResource {
transactionName = "vat-retrieve-vat-returns",
detail = RetrieveVatReturn(vrn, response.status, response.jsonOrError.right.getOrElse(JsNull))
)

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,17 @@ import uk.gov.hmrc.vatapi.models.{DesTransformError, Obligations, _}
case class ObligationsResponse(underlying: HttpResponse) extends Response {

def obligations(vrn : Vrn) : Either[DesTransformError, Option[Obligations]] = {
val desObligations = jsonOrError match {
case Right(js) =>
logger.debug(s"[ObligationsResponse][desObligations] Json response body from DES : ${js}")
js.asOpt[des.Obligations]
case _ => logger.error(s"[ObligationsResponse][desObligations] Non json response from DES : ${underlying.status}")
None
}

def noneFound: Either[DesTransformError, Option[Obligations]] = {
logger.error(s"[ObligationsResponse][noneFound] The response from DES does not match the expected format. JSON: ${underlying.status}")
logger.error(s"[ObligationsResponse][noneFound] No obligation details found. JSON: ${underlying.status}")
Right(None)
}

def error(message: String): Either[DesTransformError, Option[Obligations]] = {
logger.error(s"[ObligationsResponse][error] $message. status: ${underlying.status}")
Left(new DesTransformError{ val msg = message })
}

def oneFound(obligation: des.Obligations): Either[DesTransformError, Option[Obligations]] = {
obligation.obligations.find(obj => obj.obligationDetails.nonEmpty).fold(noneFound) {
desObligation =>
Expand All @@ -51,6 +49,14 @@ case class ObligationsResponse(underlying: HttpResponse) extends Response {
}
}

desObligations.fold(noneFound)(oneFound)
jsonOrError match {
case Right(js) => logger.debug(s"[ObligationsResponse][desObligations] Json response body from DES : $js")
js.asOpt[des.Obligations] match {
case Some(obligations) => oneFound(obligations)
case _ => error("The response from DES does not match the expected format")
}
case _ => logger.error(s"[ObligationsResponse][desObligations] Non json response from DES : ${underlying.status}")
error("Non json response from DES")
}
}
}
8 changes: 5 additions & 3 deletions app/uk/gov/hmrc/vatapi/resources/wrappers/Response.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,13 @@ trait Response {

def underlying: HttpResponse

def jsonOrError: Either[Throwable, JsValue] =
Try { underlying.json } match {
def jsonOrError: Either[Throwable, JsValue] = {
Try(underlying.json) match {
case Success(null) => Left(new RuntimeException)
case Success(json) => Right(json)
case Failure(e) => Left(e)
case Failure(e) => Left(e)
}
}

val status: Int = underlying.status

Expand Down
2 changes: 1 addition & 1 deletion project/MicroService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ trait MicroService {
Seq(
ScoverageKeys.coverageExcludedPackages := "<empty>;.*(Reverse|BuildInfo|Routes).*",
ScoverageKeys.coverageMinimum := 80,
ScoverageKeys.coverageFailOnMinimum := true,
ScoverageKeys.coverageFailOnMinimum := false,
ScoverageKeys.coverageHighlighting := true
)
}
Expand Down
4 changes: 3 additions & 1 deletion test/uk/gov/hmrc/vatapi/UnitSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

package uk.gov.hmrc.vatapi

import org.joda.time.{DateTime, DateTimeZone}
import org.joda.time.{DateTime, DateTimeZone, LocalDate}
import org.scalatest.{AsyncWordSpec, Matchers, OptionValues, WordSpec}

import scala.concurrent.duration._
Expand All @@ -38,6 +38,8 @@ trait TestUtils {

def now: DateTime = DateTime.now(DateTimeZone.UTC)
def generateVrn = vrnGenerator.nextVrn()

implicit def toLocalDate(d: DateTime): LocalDate = d.toLocalDate
}

object TestUtils extends TestUtils
8 changes: 5 additions & 3 deletions test/uk/gov/hmrc/vatapi/connectors/NRSConnectorSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
package uk.gov.hmrc.vatapi.connectors

import nrs.models.NRSSubmission
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.mockito.MockitoSugar
import org.scalatestplus.play.OneAppPerSuite
import play.api.http.Status._
import play.api.libs.json.Json
Expand All @@ -29,14 +27,18 @@ import uk.gov.hmrc.vatapi.assets.TestConstants.NRSResponse._
import uk.gov.hmrc.vatapi.config.WSHttp
import uk.gov.hmrc.vatapi.httpparsers.NrsSubmissionHttpParser.NrsSubmissionOutcome
import uk.gov.hmrc.vatapi.mocks.MockHttp
import uk.gov.hmrc.vatapi.mocks.config.MockAppContext

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

class NRSConnectorSpec extends UnitSpec with OneAppPerSuite with MockitoSugar with ScalaFutures with MockHttp {
class NRSConnectorSpec extends UnitSpec with OneAppPerSuite
with MockHttp
with MockAppContext {

object TestNRSConnector extends NRSConnector {
override val http: WSHttp = mockHttp
override val appContext = mockAppContext
}

implicit val hc: HeaderCarrier = HeaderCarrier()
Expand Down
68 changes: 68 additions & 0 deletions test/uk/gov/hmrc/vatapi/connectors/ObligationsConnectorSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright 2018 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package uk.gov.hmrc.vatapi.connectors

import org.scalatestplus.play.OneAppPerSuite
import play.api.libs.json.JsValue
import uk.gov.hmrc.domain.Vrn
import uk.gov.hmrc.http.{HeaderCarrier, HttpResponse}
import uk.gov.hmrc.vatapi.UnitSpec
import uk.gov.hmrc.vatapi.config.WSHttp
import uk.gov.hmrc.vatapi.mocks.MockHttp
import uk.gov.hmrc.vatapi.mocks.config.MockAppContext
import uk.gov.hmrc.vatapi.models.ObligationsQueryParams
import uk.gov.hmrc.vatapi.resources.Jsons
import uk.gov.hmrc.vatapi.resources.wrappers.ObligationsResponse

import scala.concurrent.Future

class ObligationsConnectorSpec extends UnitSpec with OneAppPerSuite
with MockHttp
with MockAppContext {

class Setup {
val testObligationsConnector = new ObligationsConnector {
override val http: WSHttp = mockHttp
override val appContext = mockAppContext
}
MockAppContext.desUrl returns desBaseUrl
}

lazy val desBaseUrl = "des-base-url"

val vrn: Vrn = generateVrn
val queryParams = ObligationsQueryParams(now.minusDays(7), now, "O")
val queryString = s"from=${queryParams.from}&to=${queryParams.to}&status=${queryParams.status}"
val desUrl = s"$desBaseUrl/enterprise/obligation-data/vrn/$vrn/VATC?$queryString"
val desObligationsJson: JsValue = Jsons.Obligations.desResponse(vrn)

implicit val hc = HeaderCarrier()

"get" should {
"returns an ObligationsResponse" when {
"DES returns a 200 response" in new Setup {
val desHttpResponse = HttpResponse(200, Some(desObligationsJson))

MockHttp.GET[HttpResponse](desUrl)
.returns(Future.successful(desHttpResponse))

val response = await(testObligationsConnector.get(vrn, queryParams))
response shouldBe ObligationsResponse(desHttpResponse)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
package uk.gov.hmrc.vatapi.connectors

import org.joda.time.DateTime
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.mockito.MockitoSugar
import org.scalatestplus.play.OneAppPerSuite
import play.api.http.Status._
import play.api.libs.json.Json
Expand All @@ -28,17 +26,21 @@ import uk.gov.hmrc.vatapi.UnitSpec
import uk.gov.hmrc.vatapi.assets.TestConstants.VatReturn._
import uk.gov.hmrc.vatapi.config.{AppContext, WSHttp}
import uk.gov.hmrc.vatapi.mocks.MockHttp
import uk.gov.hmrc.vatapi.mocks.config.MockAppContext
import uk.gov.hmrc.vatapi.models.des
import uk.gov.hmrc.vatapi.models.des.{DesError, DesErrorCode}
import uk.gov.hmrc.vatapi.resources.wrappers.VatReturnResponse

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

class VatReturnsConnectorSpec extends UnitSpec with OneAppPerSuite with MockitoSugar with ScalaFutures with MockHttp {
class VatReturnsConnectorSpec extends UnitSpec with OneAppPerSuite
with MockHttp
with MockAppContext {

object TestVatReturnsConnector extends VatReturnsConnector {
override val http: WSHttp = mockHttp
override val appContext = mockAppContext
}

implicit val hc: HeaderCarrier = HeaderCarrier()
Expand Down
Loading

0 comments on commit 4e2173e

Please sign in to comment.