diff --git a/app/uk/gov/hmrc/vatapi/auth/AuthContext.scala b/app/uk/gov/hmrc/vatapi/auth/AuthContext.scala index d154ba41..865fa894 100644 --- a/app/uk/gov/hmrc/vatapi/auth/AuthContext.scala +++ b/app/uk/gov/hmrc/vatapi/auth/AuthContext.scala @@ -18,28 +18,35 @@ package uk.gov.hmrc.vatapi.auth import uk.gov.hmrc.auth.core.AffinityGroup import AuthConstants._ +import nrs.models.IdentityData + sealed trait AuthContext { val affinityGroup: String val agentCode: Option[String] val agentReference: Option[String] val userType: String + + val identityData: Option[IdentityData] } -case object Organisation extends AuthContext { +case class Organisation(override val identityData: Option[IdentityData] = None) extends AuthContext { override val affinityGroup: String = ORGANISATION override val agentCode: Option[String] = None override val agentReference: Option[String] = None override val userType = "OrgVatPayer" } -case object Individual extends AuthContext { +case class Individual(override val identityData: Option[IdentityData]) extends AuthContext { override val affinityGroup: String = INDIVIDUAL override val agentCode: Option[String] = None override val agentReference: Option[String] = None override val userType = "IndVatPayer" } -case class Agent(override val agentCode: Option[String], override val agentReference: Option[String]) extends AuthContext { +case class Agent(override val agentCode: Option[String], + override val agentReference: Option[String], + override val identityData: Option[IdentityData] = None + ) extends AuthContext { override val affinityGroup: String = "agent" override val userType = "Agent" } @@ -47,10 +54,10 @@ case class Agent(override val agentCode: Option[String], override val agentRefer case class VATAuthEnrolments(enrolmentToken: String, identifier: String, authRule: Option[String] = None) object AffinityGroupToAuthContext { - def authContext(affinityGroup: AffinityGroup) = { + def authContext(affinityGroup: AffinityGroup, identityData: Option[IdentityData]) = { affinityGroup.getClass.getSimpleName.dropRight(1) match { - case ORGANISATION => Organisation - case INDIVIDUAL => Individual + case ORGANISATION => Organisation(identityData) + case INDIVIDUAL => Individual(identityData) } } } diff --git a/app/uk/gov/hmrc/vatapi/connectors/NRSConnector.scala b/app/uk/gov/hmrc/vatapi/connectors/NRSConnector.scala index ea8d2813..c81cf602 100644 --- a/app/uk/gov/hmrc/vatapi/connectors/NRSConnector.scala +++ b/app/uk/gov/hmrc/vatapi/connectors/NRSConnector.scala @@ -53,7 +53,7 @@ trait NRSConnector extends BaseConnector { private val xApiKeyHeader = "X-API-Key" - val nrsSubmissionUrl: String => String = vrn => s"${AppContext.nrsServiceUrl}/submission/$vrn" + val nrsSubmissionUrl: String => String = vrn => s"${AppContext.nrsServiceUrl}/submission" def submit(vrn: Vrn, nrsSubmission: NRSSubmission)(implicit hc: HeaderCarrier, ec: ExecutionContext): Future[NrsSubmissionOutcome] = { diff --git a/app/uk/gov/hmrc/vatapi/models/NRSSubmission.scala b/app/uk/gov/hmrc/vatapi/models/NRSSubmission.scala index 7a1259a2..da1d2c6e 100644 --- a/app/uk/gov/hmrc/vatapi/models/NRSSubmission.scala +++ b/app/uk/gov/hmrc/vatapi/models/NRSSubmission.scala @@ -17,165 +17,78 @@ package nrs.models import org.joda.time.{DateTime, LocalDate} -import play.api.libs.functional.syntax._ -import play.api.libs.json.{Writes, __, _} -import uk.gov.hmrc.auth.core.ConfidenceLevel -import uk.gov.hmrc.domain.{Nino, SaUtr, Vrn} +import play.api.libs.json._ +import uk.gov.hmrc.auth.core.retrieve._ +import uk.gov.hmrc.auth.core.{AffinityGroup, ConfidenceLevel, CredentialRole} +import uk.gov.hmrc.domain.Vrn import uk.gov.hmrc.http.controllers.RestFormats +import uk.gov.hmrc.vatapi.models.isoInstantDateFormat -case class NRSSubmission(payload: String, - metadata: Metadata) +case class NRSSubmission( payload: String, + metadata: Metadata ) object NRSSubmission{ implicit val mdFormat: OFormat[Metadata] = Metadata.format implicit val format: OFormat[NRSSubmission] = Json.format[NRSSubmission] } +//Identity Data should always be populated, but allow it to be optional for when the authEnabled flag is disabled case class Metadata(businessId: String, notableEvent: String, payloadContentType: String, payloadSha256Checksum: Option[String], userSubmissionTimestamp: DateTime, - identityData: IdentityData, + identityData: Option[IdentityData], userAuthToken: String, - headerData: HeaderData, + headerData: JsValue, searchKeys: SearchKeys) object Metadata{ - implicit val dateTimeFormat: Format[DateTime] = RestFormats.dateTimeFormats implicit val idformat: OFormat[IdentityData] = IdentityData.format - implicit val hdWrts: Writes[HeaderData] = HeaderData.writes - implicit val hdRds: Reads[HeaderData] = HeaderData.reads implicit val format: OFormat[Metadata] = Json.format[Metadata] } +//Todo: match against NRS mandatory fields with what may not be returned from auth. Appropriate error handling case class IdentityData(internalId: Option[String] = None, externalId: Option[String] = None, agentCode: Option[String] = None, - credentials: Option[Credentials] = None, - confidenceLevel: Option[ConfidenceLevel] = None, - nino: Option[Nino] = None, - saUtr: Option[SaUtr] = None, - name: Option[Name] = None, + credentials: Credentials, + confidenceLevel: ConfidenceLevel, + nino: Option[String] = None, + saUtr: Option[String] = None, + name: Name, dateOfBirth: Option[LocalDate] = None, email: Option[String] = None, - agentInformation: Option[AgentInformation] = None, + agentInformation: AgentInformation, groupIdentifier: Option[String] = None, - credentialRole: Option[String] = None, + credentialRole: Option[CredentialRole], mdtpInformation: Option[MdtpInformation] = None, - itmpName: Option[ItmpName] = None, + itmpName: ItmpName, itmpDateOfBirth: Option[LocalDate] = None, - itmpAddress: Option[ItmpAddress] = None, - affinityGroup: Option[String] = None, + itmpAddress: ItmpAddress, + affinityGroup: Option[AffinityGroup], credentialStrength: Option[String] = None, - loginTimes: Option[LoginTimes] = None) + loginTimes: LoginTimes) object IdentityData { implicit val localDateFormat: Format[LocalDate] = RestFormats.localDateFormats - implicit val dateTimeReads: Format[DateTime] = RestFormats.dateTimeFormats + implicit val credFormat: OFormat[Credentials] = Json.format[Credentials] + implicit val nameFormat: OFormat[Name] = Json.format[Name] + implicit val agentInfoFormat: OFormat[AgentInformation] = Json.format[AgentInformation] + implicit val mdtpInfoFormat: OFormat[MdtpInformation] = Json.format[MdtpInformation] + implicit val itmpNameFormat: OFormat[ItmpName] = Json.format[ItmpName] + implicit val itmpAddressFormat: OFormat[ItmpAddress] = Json.format[ItmpAddress] + implicit val loginTimesFormat: OFormat[LoginTimes] = Json.format[LoginTimes] implicit val format: OFormat[IdentityData] = Json.format[IdentityData] } -case class HeaderData(publicIp: Option[String] = None, - port: Option[String] = None, - deviceId: Option[String] = None, - userId: Option[String] = None, - timeZone: Option[String] = None, - localIp: Option[String] = None, - screenResolution: Option[String] = None, - windowSize: Option[String] = None, - colourDepth: Option[String] = None) - -object HeaderData { - implicit val writes: Writes[HeaderData] = ( - (__ \ "Gov-Client-Public-IP").writeNullable[String] and - (__ \ "Gov-Client-Public-Port").writeNullable[String] and - (__ \ "Gov-Client-Device-ID").writeNullable[String] and - (__ \ "Gov-Client-User-ID").writeNullable[String] and - (__ \ "Gov-Client-Timezone").writeNullable[String] and - (__ \ "Gov-Client-Local-IP").writeNullable[String] and - (__ \ "Gov-Client-Screen-Resolution").writeNullable[String] and - (__ \ "Gov-Client-Window-Size").writeNullable[String] and - (__ \ "Gov-Client-Colour-Depth").writeNullable[String] - )(unlift(HeaderData.unapply)) - - implicit val reads: Reads[HeaderData] = ( - (__ \ "Gov-Client-Public-IP").readNullable[String] and - (__ \ "Gov-Client-Public-Port").readNullable[String] and - (__ \ "Gov-Client-Device-ID").readNullable[String] and - (__ \ "Gov-Client-User-ID").readNullable[String] and - (__ \ "Gov-Client-Timezone").readNullable[String] and - (__ \ "Gov-Client-Local-IP").readNullable[String] and - (__ \ "Gov-Client-Screen-Resolution").readNullable[String] and - (__ \ "Gov-Client-Window-Size").readNullable[String] and - (__ \ "Gov-Client-Colour-Depth").readNullable[String] - )(HeaderData.apply _) -} - -case class SearchKeys(vrn: Vrn, - companyName: String, - taxPeriodEndDate: LocalDate) +case class SearchKeys(vrn: Option[Vrn] = None, + companyName: Option[String] = None, + taxPeriodEndDate: Option[LocalDate] = None, + periodKey: Option[String] = None + ) object SearchKeys{ implicit val localDateFormat: Format[LocalDate] = RestFormats.localDateFormats implicit val format: OFormat[SearchKeys] = Json.format[SearchKeys] -} - -case class Credentials(providerId: String, providerType: String) - -object Credentials { - implicit val format: Format[Credentials] = Json.format[Credentials] -} - -case class Name(name: Option[String], lastName: Option[String]) - -object Name { - implicit val format: Format[Name] = Json.format[Name] -} - -case class PostCode(value: String) - -object PostCode { - implicit val format: Format[PostCode] = Json.format[PostCode] -} - -case class ItmpName(givenName: Option[String], - middleName: Option[String], - familyName: Option[String]) - -object ItmpName { - implicit val format: Format[ItmpName] = Json.format[ItmpName] -} - -case class ItmpAddress(line1: Option[String], - line2: Option[String], - line3: Option[String], - line4: Option[String], - line5: Option[String], - postCode: Option[String], - countryName: Option[String], - countryCode: Option[String]) - -object ItmpAddress { - implicit val format: Format[ItmpAddress] = Json.format[ItmpAddress] -} - -case class MdtpInformation(deviceId: String, sessionId: String) -object MdtpInformation { - implicit val format: Format[MdtpInformation] = Json.format[MdtpInformation] -} - -case class AgentInformation(agentId: Option[String], - agentCode: Option[String], - agentFriendlyName: Option[String]) - -object AgentInformation { - implicit val format: Format[AgentInformation] = Json.format[AgentInformation] -} - -case class LoginTimes(currentLogin: DateTime, previousLogin: Option[DateTime]) - -object LoginTimes { - implicit val dateTimeReads: Format[DateTime] = RestFormats.dateTimeFormats - implicit val format: Format[LoginTimes] = Json.format[LoginTimes] -} +} \ No newline at end of file diff --git a/app/uk/gov/hmrc/vatapi/models/models.scala b/app/uk/gov/hmrc/vatapi/models/models.scala index 21462549..fc889f2e 100644 --- a/app/uk/gov/hmrc/vatapi/models/models.scala +++ b/app/uk/gov/hmrc/vatapi/models/models.scala @@ -101,6 +101,13 @@ package object models { def trimNullable: Reads[Option[String]] = reads.map(_.map(_.trim)) } + val isoInstantDatePattern = "yyyy-MM-dd'T'HH:mm:ss'Z'" + + implicit val isoInstantDateFormat: Format[DateTime] = Format[DateTime]( + JodaReads.jodaDateReads(isoInstantDatePattern), + JodaWrites.jodaDateWrites(isoInstantDatePattern) + ) + val dateTimePattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" implicit val dateTimeFormat: Format[DateTime] = Format[DateTime]( diff --git a/app/uk/gov/hmrc/vatapi/orchestrators/VatReturnsOrchestrator.scala b/app/uk/gov/hmrc/vatapi/orchestrators/VatReturnsOrchestrator.scala index 6ce09a96..e721e573 100644 --- a/app/uk/gov/hmrc/vatapi/orchestrators/VatReturnsOrchestrator.scala +++ b/app/uk/gov/hmrc/vatapi/orchestrators/VatReturnsOrchestrator.scala @@ -22,6 +22,7 @@ import uk.gov.hmrc.domain.Vrn import uk.gov.hmrc.http.HeaderCarrier import uk.gov.hmrc.vatapi.httpparsers.NRSData import uk.gov.hmrc.vatapi.models.{ErrorResult, Errors, InternalServerErrorResult, VatReturnDeclaration} +import uk.gov.hmrc.vatapi.resources.AuthRequest import uk.gov.hmrc.vatapi.resources.wrappers.VatReturnResponse import uk.gov.hmrc.vatapi.services.{NRSService, VatReturnsService} @@ -42,7 +43,7 @@ trait VatReturnsOrchestrator { def submitVatReturn(vrn: Vrn, vatReturn: VatReturnDeclaration - )(implicit hc: HeaderCarrier): Future[Either[ErrorResult, VatReturnResponse]] = { + )(implicit hc: HeaderCarrier, request: AuthRequest[_]): Future[Either[ErrorResult, VatReturnResponse]] = { logger.debug(s"[VatReturnsOrchestrator][submitVatReturn] - Orchestrating calls to NRS and Vat Returns") nrsService.submit(vrn, vatReturn) map { diff --git a/app/uk/gov/hmrc/vatapi/resources/BaseResource.scala b/app/uk/gov/hmrc/vatapi/resources/BaseResource.scala index a2fd6cfe..e53badc0 100644 --- a/app/uk/gov/hmrc/vatapi/resources/BaseResource.scala +++ b/app/uk/gov/hmrc/vatapi/resources/BaseResource.scala @@ -45,7 +45,7 @@ trait BaseResource extends BaseController { case Left(authError) => Left(authError) } } else - Future.successful(Right(new AuthRequest(Organisation, request))) + Future.successful(Right(new AuthRequest(Organisation(), request))) } def APIAction(vrn: Vrn, summary: Option[String] = None): ActionBuilder[AuthRequest] = diff --git a/app/uk/gov/hmrc/vatapi/resources/VatReturnsResource.scala b/app/uk/gov/hmrc/vatapi/resources/VatReturnsResource.scala index ab5dc690..0a642f88 100644 --- a/app/uk/gov/hmrc/vatapi/resources/VatReturnsResource.scala +++ b/app/uk/gov/hmrc/vatapi/resources/VatReturnsResource.scala @@ -17,12 +17,9 @@ package uk.gov.hmrc.vatapi.resources import cats.implicits._ -import play.api.Logger - import play.api.libs.json.{JsNull, JsValue, Json, OFormat} import play.api.mvc.{Action, AnyContent, Request} import uk.gov.hmrc.domain.Vrn -import uk.gov.hmrc.play.microservice.controller.BaseController import uk.gov.hmrc.vatapi.audit.AuditEvent import uk.gov.hmrc.vatapi.audit.AuditService.audit import uk.gov.hmrc.vatapi.connectors.VatReturnsConnector @@ -38,7 +35,6 @@ object VatReturnsResource extends BaseResource { private val orchestrator = VatReturnsOrchestrator def submitVatReturn(vrn: Vrn): Action[JsValue] = APIAction(vrn).async(parse.json) { implicit request => - val receiptId = "Receipt-ID" val receiptTimestamp = "Receipt-Timestamp" val receiptSignature = "Receipt-Signature" diff --git a/app/uk/gov/hmrc/vatapi/services/AuthorisationService.scala b/app/uk/gov/hmrc/vatapi/services/AuthorisationService.scala index c44c149e..7678c32e 100644 --- a/app/uk/gov/hmrc/vatapi/services/AuthorisationService.scala +++ b/app/uk/gov/hmrc/vatapi/services/AuthorisationService.scala @@ -16,9 +16,10 @@ package uk.gov.hmrc.vatapi.services +import nrs.models.IdentityData import play.api.Logger import play.api.libs.json.Json.toJson -import play.api.libs.json.{JsArray, Json} +import play.api.libs.json.{JsArray, JsResultException, Json} import play.api.mvc.Results._ import play.api.mvc.{RequestHeader, Result} import uk.gov.hmrc.auth.core.authorise.RawJsonPredicate @@ -27,7 +28,7 @@ import uk.gov.hmrc.auth.core.{Enrolment, Enrolments, _} import uk.gov.hmrc.domain.Vrn import uk.gov.hmrc.http.HeaderCarrier import uk.gov.hmrc.vatapi.auth.AffinityGroupToAuthContext._ -import uk.gov.hmrc.vatapi.auth.{APIAuthorisedFunctions, AffinityGroupToAuthContext, AuthContext} +import uk.gov.hmrc.vatapi.auth.{APIAuthorisedFunctions, AuthContext} import uk.gov.hmrc.vatapi.config.AppContext import uk.gov.hmrc.vatapi.models.Errors import uk.gov.hmrc.vatapi.models.Errors.ClientOrAgentNotAuthorized @@ -35,13 +36,13 @@ import uk.gov.hmrc.vatapi.models.Errors.ClientOrAgentNotAuthorized import scala.concurrent.{ExecutionContext, Future} object AuthorisationService extends AuthorisationService{ - override val aPIAuthorisedFunctions = APIAuthorisedFunctions + override val apiAuthorisedFunctions: APIAuthorisedFunctions.type = APIAuthorisedFunctions } trait AuthorisationService { type AuthResult = Either[Result, AuthContext] - val aPIAuthorisedFunctions : APIAuthorisedFunctions + val apiAuthorisedFunctions: APIAuthorisedFunctions private lazy val vatAuthEnrolments = AppContext.vatAuthEnrolments private val logger = Logger(AuthorisationService.getClass) @@ -56,17 +57,39 @@ trait AuthorisationService { .map(_.value) private def authoriseAsClient(vrn: Vrn)(implicit hc: HeaderCarrier, - requestHeader: RequestHeader, - ec: ExecutionContext): Future[AuthResult] = { - logger.debug(s"[AuthorisationService] [authoriseAsClient] Check user authorisation for MTD VAT based on VRN ${vrn}.") - aPIAuthorisedFunctions.authorised( + requestHeader: RequestHeader, + ec: ExecutionContext): Future[AuthResult] = { + import Retrievals._ + + logger.debug(s"[AuthorisationService] [authoriseAsClient] Check user authorisation for MTD VAT based on VRN $vrn.") + apiAuthorisedFunctions.authorised( RawJsonPredicate(JsArray.apply(Seq(Json.toJson(Enrolment(vatAuthEnrolments.enrolmentToken).withIdentifier(vatAuthEnrolments.identifier, vrn.vrn)))))) - .retrieve(Retrievals.affinityGroup and Retrievals.authorisedEnrolments) { - case retrieval@Some(AffinityGroup.Organisation|AffinityGroup.Individual) ~ enrolments => - val authAffinityGroup = retrieval.a.get - logger.debug(s"[AuthorisationService] [authoriseAsClient] Authorisation succeeded as fully-authorised ${authContext(authAffinityGroup).affinityGroup} " + + .retrieve( + affinityGroup and authorisedEnrolments + and internalId and externalId and agentCode and credentials + and confidenceLevel and nino and saUtr and name and dateOfBirth + and email and agentInformation and groupIdentifier and credentialRole + and mdtpInformation and itmpName and itmpDateOfBirth and itmpAddress + and credentialStrength and loginTimes + ){ + case affGroup ~ enrolments ~ inId ~ exId ~ agCode ~ creds + ~ confLevel ~ ni ~ saRef ~ nme ~ dob + ~ eml ~ agInfo ~ groupId ~ credRole + ~ mdtpInfo ~ iname ~ idob ~ iaddress + ~ credStrength ~ logins + if affGroup.contains(AffinityGroup.Organisation) | affGroup.contains(AffinityGroup.Individual) => + + val identityData = + IdentityData( + inId, exId, agCode, creds, + confLevel, ni, saRef, nme, dob, + eml, agInfo, groupId, + credRole, mdtpInfo, iname, idob, + iaddress, affGroup, credStrength, logins) + val afGroup = affGroup.get + logger.debug(s"[AuthorisationService] [authoriseAsClient] Authorisation succeeded as fully-authorised organisation " + s"for VRN ${getClientReference(enrolments).getOrElse("")}.") - Future.successful(Right(authContext(authAffinityGroup))) + Future.successful(Right(authContext(afGroup,Some(identityData)))) case _ => logger.error(s"[AuthorisationService] [authoriseAsClient] Authorisation failed due to unsupported affinity group.") Future.successful(Left(Forbidden(toJson(ClientOrAgentNotAuthorized)))) } recoverWith unauthorisedError @@ -74,14 +97,17 @@ trait AuthorisationService { private def unauthorisedError: PartialFunction[Throwable, Future[AuthResult]] = { case _: InsufficientEnrolments => - logger.error(s"[AuthorisationService] [unauthorisedError] Client authorisation failed due to unsupported insufficient enrolments.") + logger.warn(s"[AuthorisationService] [unauthorisedError] Client authorisation failed due to unsupported insufficient enrolments.") Future.successful(Left(Forbidden(toJson(Errors.ClientOrAgentNotAuthorized)))) case _: InsufficientConfidenceLevel => - logger.error(s"[AuthorisationService] [unauthorisedError] Client authorisation failed due to unsupported insufficient confidenceLevels.") + logger.warn(s"[AuthorisationService] [unauthorisedError] Client authorisation failed due to unsupported insufficient confidenceLevels.") Future.successful(Left(Forbidden(toJson(Errors.ClientOrAgentNotAuthorized)))) + case _: JsResultException => + logger.warn(s"[AuthorisationService] [unauthorisedError] - Did not receive minimum data from Auth required for NRS Submission") + Future.successful(Left(Forbidden(toJson(Errors.InternalServerError)))) case exception@_ => - logger.error(s"[AuthorisationService] [unauthorisedError] Client authorisation failed due to internal server error. auth-client exception was ${exception.getClass.getSimpleName}") + logger.warn(s"[AuthorisationService] [unauthorisedError] Client authorisation failed due to internal server error. auth-client exception was ${exception.getClass.getSimpleName}") Future.successful(Left(InternalServerError(toJson( - Errors.InternalServerError("An internal server error occurred"))))) + Errors.InternalServerError("An internal server error occurred"))))) } } diff --git a/app/uk/gov/hmrc/vatapi/services/NRSService.scala b/app/uk/gov/hmrc/vatapi/services/NRSService.scala index 357428b2..210fb825 100644 --- a/app/uk/gov/hmrc/vatapi/services/NRSService.scala +++ b/app/uk/gov/hmrc/vatapi/services/NRSService.scala @@ -20,7 +20,7 @@ import java.nio.charset.StandardCharsets import java.util.Base64 import nrs.models._ -import org.joda.time.{DateTime, LocalDate} +import org.joda.time.DateTime import play.api.Logger import play.api.libs.json.Json import uk.gov.hmrc.domain.Vrn @@ -28,6 +28,7 @@ import uk.gov.hmrc.http.HeaderCarrier import uk.gov.hmrc.vatapi.connectors.NRSConnector import uk.gov.hmrc.vatapi.httpparsers.NrsSubmissionHttpParser.NrsSubmissionOutcome import uk.gov.hmrc.vatapi.models.VatReturnDeclaration +import uk.gov.hmrc.vatapi.resources.AuthRequest import scala.concurrent.{ExecutionContext, Future} @@ -40,33 +41,29 @@ trait NRSService { val nrsConnector: NRSConnector - def submit(vrn: Vrn, payload: VatReturnDeclaration)(implicit hc: HeaderCarrier, ec: ExecutionContext): Future[NrsSubmissionOutcome] = { + def submit(vrn: Vrn, payload: VatReturnDeclaration)(implicit hc: HeaderCarrier, ec: ExecutionContext, request: AuthRequest[_]): Future[NrsSubmissionOutcome] = { logger.debug(s"[NRSService][submit] - Submitting payload to NRS") - nrsConnector.submit(vrn, convertToNrsSubmission(payload)) + nrsConnector.submit(vrn, convertToNrsSubmission(vrn, payload)) } - private def convertToNrsSubmission(payload: VatReturnDeclaration): NRSSubmission = { + private def convertToNrsSubmission(vrn: Vrn, payload: VatReturnDeclaration)(implicit request: AuthRequest[_]): NRSSubmission = { + // TODO - Add in validation to get rid of .get val encoder = Base64.getEncoder NRSSubmission( payload = encoder.encodeToString(Json.toJson(payload).toString.getBytes(StandardCharsets.UTF_8)), metadata = Metadata( - businessId = "", - notableEvent = "", - payloadContentType = "", - payloadSha256Checksum = Some(""), - userSubmissionTimestamp = DateTime.parse("2018-06-30T01:20"), - identityData = IdentityData( - - ), - userAuthToken = "", - headerData = HeaderData( - - ), + businessId = "vat", + notableEvent = "vat-return", + payloadContentType = "application/json", + payloadSha256Checksum = None, + userSubmissionTimestamp = DateTime.now(), + identityData = request.authContext.identityData, + userAuthToken = request.headers.get("Authorization").get, + headerData = Json.toJson(request.headers.toMap.map { h => h._1 -> h._2.head}), searchKeys = SearchKeys( - vrn = Vrn("123456789"), - companyName = "", - taxPeriodEndDate = LocalDate.parse("2018-06-30") + vrn = Some(vrn), + periodKey = Some(payload.periodKey) ) ) ) diff --git a/func/uk/gov/hmrc/support/BaseFunctionalSpec.scala b/func/uk/gov/hmrc/support/BaseFunctionalSpec.scala index 14011bb2..40cf91bf 100644 --- a/func/uk/gov/hmrc/support/BaseFunctionalSpec.scala +++ b/func/uk/gov/hmrc/support/BaseFunctionalSpec.scala @@ -503,6 +503,32 @@ trait BaseFunctionalSpec extends TestApplication { .withBody(""" |{ | "internalId": "some-id", + | "externalId": "some-id", + | "credentials" : {"providerId":"8124873381064832", "providerType":"GovernmentGateway"}, + | "confidenceLevel": 200, + | "name": { "name": "test", "lastName": "test" }, + | "dateOfBirth": "1985-01-01", + | "postCode":"NW94HD", + | "description" : "description", + | "agentInformation": { + | "agentCode" : "TZRXXV", + | "agentFriendlyName" : "Bodgitt & Legget LLP", + | "agentId": "BDGL" + | }, + | "groupIdentifier" : "GroupId", + | "credentialRole": "admin", + | "itmpName" : { "givenName": "test", "middleName": "test", "familyName": "test" }, + | "itmpDateOfBirth" : "1985-01-01", + | "itmpAddress" : { + | "line1" : "Line 1", + | "line2" : "", + | "line3" : "", + | "line4" : "", + | "line5" : "", + | "postCode" :"NW94HD", + | "countryName" : "United Kingdom", + | "countryCode" : "UK" + | }, | "affinityGroup": "Organisation", | "loginTimes": { | "currentLogin": "2016-11-27T09:00:00.000Z", @@ -522,7 +548,6 @@ trait BaseFunctionalSpec extends TestApplication { | ] |} """.stripMargin))) - this } @@ -799,7 +824,7 @@ trait BaseFunctionalSpec extends TestApplication { class Nrs(givens: Givens) { def nrsVatReturnSuccessFor(vrn: Vrn): Givens = { - stubFor(any(urlMatching(s".*/submission/$vrn.*")) + stubFor(any(urlMatching(s".*/submission.*")) .willReturn( aResponse() .withStatus(Status.ACCEPTED) diff --git a/func/uk/gov/hmrc/vatapi/resources/ValueAddedTaxReturnsSpec.scala b/func/uk/gov/hmrc/vatapi/resources/ValueAddedTaxReturnsSpec.scala index c458ccce..e5b178da 100644 --- a/func/uk/gov/hmrc/vatapi/resources/ValueAddedTaxReturnsSpec.scala +++ b/func/uk/gov/hmrc/vatapi/resources/ValueAddedTaxReturnsSpec.scala @@ -42,6 +42,7 @@ class ValueAddedTaxReturnsSpec extends BaseFunctionalSpec { .des().vatReturns.expectVatReturnSubmissionFor(vrn) .when() .post(s"/$vrn/returns", Some(Json.parse(body()))) + .withHeaders("Authorization", "Bearer testtoken") .thenAssertThat() .statusIs(201) .bodyHasPath("\\paymentIndicator", "BANK") @@ -59,6 +60,7 @@ class ValueAddedTaxReturnsSpec extends BaseFunctionalSpec { .des().vatReturns.expectVatReturnSubmissionFor(vrn) .when() .post(s"/$vrn/returns", Some(Json.parse(requestWithNegativeAmounts()))) + .withHeaders("Authorization", "Bearer testtoken") .thenAssertThat() .statusIs(201) .bodyHasPath("\\paymentIndicator", "BANK") @@ -99,6 +101,7 @@ class ValueAddedTaxReturnsSpec extends BaseFunctionalSpec { .des().vatReturns.expectVatReturnToFail(vrn, "INVALID_PERIODKEY") .when() .post(s"/$vrn/returns", Some(Json.parse(body()))) + .withHeaders("Authorization", "Bearer testtoken") .thenAssertThat() .statusIs(400) .bodyHasPath("\\code", "PERIOD_KEY_INVALID") @@ -111,6 +114,7 @@ class ValueAddedTaxReturnsSpec extends BaseFunctionalSpec { .des().vatReturns.expectVatReturnToFail(vrn, "INVALID_ARN") .when() .post(s"/$vrn/returns", Some(Json.parse(body()))) + .withHeaders("Authorization", "Bearer testtoken") .thenAssertThat() .statusIs(500) .bodyHasPath("\\code", "INTERNAL_SERVER_ERROR") @@ -123,6 +127,7 @@ class ValueAddedTaxReturnsSpec extends BaseFunctionalSpec { .des().vatReturns.expectVatReturnToFail(vrn, "INVALID_VRN") .when() .post(s"/$vrn/returns", Some(Json.parse(body()))) + .withHeaders("Authorization", "Bearer testtoken") .thenAssertThat() .statusIs(400) .bodyHasPath("\\code", "VRN_INVALID") @@ -135,6 +140,7 @@ class ValueAddedTaxReturnsSpec extends BaseFunctionalSpec { .des().vatReturns.expectVatReturnToFail(vrn, "INVALID_PAYLOAD") .when() .post(s"/$vrn/returns", Some(Json.parse(body()))) + .withHeaders("Authorization", "Bearer testtoken") .thenAssertThat() .statusIs(400) .bodyHasPath("\\code", "INVALID_REQUEST") @@ -147,6 +153,7 @@ class ValueAddedTaxReturnsSpec extends BaseFunctionalSpec { .des().vatReturns.expectVatReturnToFail(vrn, "DUPLICATE_SUBMISSION") .when() .post(s"/$vrn/returns", Some(Json.parse(body()))) + .withHeaders("Authorization", "Bearer testtoken") .thenAssertThat() .statusIs(403) .bodyHasPath("\\errors(0)\\code", "DUPLICATE_SUBMISSION") @@ -158,6 +165,7 @@ class ValueAddedTaxReturnsSpec extends BaseFunctionalSpec { .nrs().nrsFailurefor(vrn) .when() .post(s"/$vrn/returns", Some(Json.parse(body()))) + .withHeaders("Authorization", "Bearer testtoken") .thenAssertThat() .statusIs(500) .bodyHasPath("\\code", "INTERNAL_SERVER_ERROR") diff --git a/test/uk/gov/hmrc/vatapi/assets/TestConstants.scala b/test/uk/gov/hmrc/vatapi/assets/TestConstants.scala index 19c67c7a..2885f83c 100644 --- a/test/uk/gov/hmrc/vatapi/assets/TestConstants.scala +++ b/test/uk/gov/hmrc/vatapi/assets/TestConstants.scala @@ -17,14 +17,70 @@ package uk.gov.hmrc.vatapi.assets import nrs.models._ -import org.joda.time.{DateTime, LocalDate} +import org.joda.time.DateTime +import play.api.libs.json.Json +import uk.gov.hmrc.auth.core._ +import uk.gov.hmrc.auth.core.retrieve._ import uk.gov.hmrc.domain.Vrn +import uk.gov.hmrc.vatapi.auth.{AuthContext, Individual, Organisation} import uk.gov.hmrc.vatapi.httpparsers.NRSData import uk.gov.hmrc.vatapi.models.des.PaymentIndicator import uk.gov.hmrc.vatapi.models.{VatReturnDeclaration, des} object TestConstants { + object Auth { + + val orgIdentityData = IdentityData( + internalId = Some("Int-a7688cda-d983-472d-9971-ddca5f124641"), + externalId = Some("Ext-c4ebc935-ac7a-4cc2-950a-19e6fac91f2a"), + agentCode = None, + credentials = retrieve.Credentials( + providerId = "8124873381064832", + providerType = "GovernmentGateway" + ), + confidenceLevel = ConfidenceLevel.L200, + name = Name( + name = Some("TestUser"), + lastName = None + ), + email = Some("user@test.com"), + agentInformation = AgentInformation( + agentCode = None, + agentFriendlyName = None, + agentId = None + ), + groupIdentifier = Some("testGroupId-840cf4e3-c8ad-48f4-80fd-ea267f916be5"), + credentialRole = Some(User), + itmpName = ItmpName( + givenName = Some("a"), + middleName = Some("b"), + familyName = Some("c") + ), + itmpAddress = ItmpAddress( + line1 = Some("1"), + line2 = Some("2"), + line3 = Some("3"), + line4 = Some("4"), + line5 = Some("5"), + postCode = Some("cw93nm"), + countryName = Some("uk"), + countryCode = Some("uk") + ), + affinityGroup = Some(AffinityGroup.Organisation), + credentialStrength = Some("strong"), + loginTimes = LoginTimes( + currentLogin = DateTime.parse("2018-04-16T11:00:55Z"), + previousLogin = None + ) + ) + + val indIdentityData: IdentityData = orgIdentityData.copy(affinityGroup = Some(AffinityGroup.Individual)) + + val orgAuthContext: AuthContext = Organisation(Some(orgIdentityData)) + val indAuthContext: AuthContext = Individual(Some(indIdentityData)) + } + object VatReturn { val vatReturnDeclaration = VatReturnDeclaration( periodKey = "#001", @@ -58,22 +114,30 @@ object TestConstants { val nrsSubmission: NRSSubmission = NRSSubmission( payload = "payload", metadata = Metadata( - businessId = "", - notableEvent = "", - payloadContentType = "", - payloadSha256Checksum = Some(""), - userSubmissionTimestamp = DateTime.parse("2018-06-30T01:20"), - identityData = IdentityData( - - ), + businessId = "vat", + notableEvent = "vat-return", + payloadContentType = "application/json", + payloadSha256Checksum = None, + userSubmissionTimestamp = timestamp, + identityData = Some(Auth.orgIdentityData), userAuthToken = "", - headerData = HeaderData( - - ), + headerData = Json.toJson( + s""" + |{ + |"Gov-Client-Public-IP":"198.51.100.0", + |"Gov-Client-Public-Port":"12345", + |"Gov-Client-Device-ID":"beec798b-b366-47fa-b1f8-92cede14a1ce", + |"Gov-Client-User-ID":"alice_desktop", + |"Gov-Client-Timezone":"GMT+3", + |"Gov-Client-Local-IP":"10.1.2.3", + |"Gov-Client-Screen-Resolution":"1920x1080", + |"Gov-Client-Window-Size":"1256x803", + |"Gov-Client-Colour-Depth":"24" + |} + """.stripMargin), searchKeys = SearchKeys( - vrn = Vrn("123456789"), - companyName = "", - taxPeriodEndDate = LocalDate.parse("2018-06-30") + vrn = Some(Vrn("123456789")), + periodKey = Some("AA34") ) ) ) diff --git a/test/uk/gov/hmrc/vatapi/mocks/auth/MockAPIAuthorisedFunctions.scala b/test/uk/gov/hmrc/vatapi/mocks/auth/MockAPIAuthorisedFunctions.scala index ea8179dc..9f10b730 100644 --- a/test/uk/gov/hmrc/vatapi/mocks/auth/MockAPIAuthorisedFunctions.scala +++ b/test/uk/gov/hmrc/vatapi/mocks/auth/MockAPIAuthorisedFunctions.scala @@ -20,12 +20,13 @@ import org.mockito.Matchers import org.mockito.Mockito.{reset, when} import org.scalatest.mockito.MockitoSugar import org.scalatest.{BeforeAndAfterEach, Suite} -import play.api.libs.json.{JsArray, Json} +import play.api.libs.json.JsArray import uk.gov.hmrc.auth.core._ import uk.gov.hmrc.auth.core.authorise.RawJsonPredicate -import uk.gov.hmrc.auth.core.retrieve.{Retrieval, ~} +import uk.gov.hmrc.auth.core.retrieve._ import uk.gov.hmrc.http.HeaderCarrier import uk.gov.hmrc.play.test.UnitSpec +import uk.gov.hmrc.vatapi.assets.TestConstants.Auth._ import uk.gov.hmrc.vatapi.auth.APIAuthorisedFunctions import scala.concurrent.{ExecutionContext, Future} @@ -34,7 +35,7 @@ trait MockAPIAuthorisedFunctions extends UnitSpec with MockitoSugar with BeforeA self: Suite => - val mockAPIAuthorisedFunctions = mock[APIAuthorisedFunctions] + val mockAPIAuthorisedFunctions: APIAuthorisedFunctions = mock[APIAuthorisedFunctions] override def beforeEach(): Unit = { super.beforeEach() @@ -42,13 +43,59 @@ trait MockAPIAuthorisedFunctions extends UnitSpec with MockitoSugar with BeforeA setupMockAuthRetrievalSuccess(testAuthOrganisationSuccessResponse) } - val testAuthOrganisationSuccessResponse = new ~(Option(AffinityGroup.Organisation), Enrolments(Set( - Enrolment("HMRC-MTD-VAT", Seq(EnrolmentIdentifier("VRN", "134567890")), "activated") - ))) + val testAuthOrganisationSuccessResponse = + new~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~( + Option(AffinityGroup.Organisation), + Enrolments(Set( + Enrolment("HMRC-MTD-VAT",List(EnrolmentIdentifier("VRN", "666350722")),"activated")))), + orgIdentityData.internalId), + orgIdentityData.externalId), + None), + orgIdentityData.credentials), + orgIdentityData.confidenceLevel), + None), + None), + orgIdentityData.name) + ,None), + orgIdentityData.email), + orgIdentityData.agentInformation), + orgIdentityData.groupIdentifier), + orgIdentityData.credentialRole), + None), + orgIdentityData.itmpName), + None), + orgIdentityData.itmpAddress) + , + orgIdentityData.credentialStrength), + orgIdentityData.loginTimes + ) - val testAuthIndividualSuccessResponse = new ~(Option(AffinityGroup.Individual), Enrolments(Set( - Enrolment("HMRC-MTD-VAT", Seq(EnrolmentIdentifier("VRN", "123456789")), "activated") - ))) + val testAuthIndividualSuccessResponse = + new~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~(new ~( + Option(AffinityGroup.Individual), + Enrolments(Set( + Enrolment("HMRC-MTD-VAT",List(EnrolmentIdentifier("VRN", "666350722")),"activated")))), + orgIdentityData.internalId), + orgIdentityData.externalId), + None), + orgIdentityData.credentials), + orgIdentityData.confidenceLevel), + None), + None), + orgIdentityData.name) + ,None), + orgIdentityData.email), + orgIdentityData.agentInformation), + orgIdentityData.groupIdentifier), + orgIdentityData.credentialRole), + None), + orgIdentityData.itmpName), + None), + orgIdentityData.itmpAddress) + , + orgIdentityData.credentialStrength), + orgIdentityData.loginTimes + ) def setupMockAuthRetrievalSuccess[X,Y](retrievalValue: X~Y): Unit = { when(mockAPIAuthorisedFunctions.authorised(Matchers.any())) @@ -60,7 +107,7 @@ trait MockAPIAuthorisedFunctions extends UnitSpec with MockitoSugar with BeforeA }) } - def setupMockAuthorisationException(exception: AuthorisationException = new InsufficientEnrolments()): Unit = + def setupMockAuthorisationException(exception: Exception = new InsufficientEnrolments()): Unit = when(mockAPIAuthorisedFunctions.authorised(Matchers.any())) .thenReturn( new mockAPIAuthorisedFunctions.AuthorisedFunction(RawJsonPredicate(JsArray.empty)) { diff --git a/test/uk/gov/hmrc/vatapi/mocks/services/MockNRSService.scala b/test/uk/gov/hmrc/vatapi/mocks/services/MockNRSService.scala index ea87492d..9e3fffc0 100644 --- a/test/uk/gov/hmrc/vatapi/mocks/services/MockNRSService.scala +++ b/test/uk/gov/hmrc/vatapi/mocks/services/MockNRSService.scala @@ -25,6 +25,7 @@ import uk.gov.hmrc.http.HeaderCarrier import uk.gov.hmrc.play.test.UnitSpec import uk.gov.hmrc.vatapi.httpparsers.NrsSubmissionHttpParser.NrsSubmissionOutcome import uk.gov.hmrc.vatapi.models.VatReturnDeclaration +import uk.gov.hmrc.vatapi.resources.AuthRequest import uk.gov.hmrc.vatapi.services.NRSService import scala.concurrent.{ExecutionContext, Future} @@ -42,6 +43,6 @@ trait MockNRSService extends UnitSpec with MockitoSugar with BeforeAndAfterEach when(mockNrsService .submit( Matchers.eq(vrn), - Matchers.any[VatReturnDeclaration]())(Matchers.any[HeaderCarrier](), Matchers.any[ExecutionContext]())) + Matchers.any[VatReturnDeclaration]())(Matchers.any[HeaderCarrier](), Matchers.any[ExecutionContext](), Matchers.any[AuthRequest[_]]())) .thenReturn(Future.successful(response)) } diff --git a/test/uk/gov/hmrc/vatapi/orchestrators/VatReturnsOrchestratorSpec.scala b/test/uk/gov/hmrc/vatapi/orchestrators/VatReturnsOrchestratorSpec.scala index 3952c52d..2436999b 100644 --- a/test/uk/gov/hmrc/vatapi/orchestrators/VatReturnsOrchestratorSpec.scala +++ b/test/uk/gov/hmrc/vatapi/orchestrators/VatReturnsOrchestratorSpec.scala @@ -22,15 +22,18 @@ import org.scalatest.mockito.MockitoSugar import org.scalatestplus.play.OneAppPerSuite import play.api.http.Status.{BAD_REQUEST, OK} import play.api.libs.json.Json +import play.api.test.FakeRequest import uk.gov.hmrc.domain.Vrn import uk.gov.hmrc.http.{HeaderCarrier, HttpResponse} import uk.gov.hmrc.vatapi.UnitSpec +import uk.gov.hmrc.vatapi.assets.TestConstants.Auth._ import uk.gov.hmrc.vatapi.assets.TestConstants.NRSResponse._ import uk.gov.hmrc.vatapi.assets.TestConstants.VatReturn._ import uk.gov.hmrc.vatapi.httpparsers.NrsError import uk.gov.hmrc.vatapi.mocks.services.{MockNRSService, MockVatReturnsService} import uk.gov.hmrc.vatapi.models.des.{DesError, DesErrorCode} import uk.gov.hmrc.vatapi.models.{ErrorResult, Errors, InternalServerErrorResult, VatReturnDeclaration} +import uk.gov.hmrc.vatapi.resources.AuthRequest import uk.gov.hmrc.vatapi.resources.wrappers.VatReturnResponse import uk.gov.hmrc.vatapi.services.{NRSService, VatReturnsService} @@ -46,6 +49,7 @@ class VatReturnsOrchestratorSpec extends UnitSpec with OneAppPerSuite with Mocki } implicit val hc: HeaderCarrier = HeaderCarrier() + implicit val req: AuthRequest[_] = new AuthRequest(orgAuthContext, FakeRequest().withHeaders(("Authorization", "Bearer test-bearer-token"))) val vatReturnSuccessResponse = VatReturnResponse(HttpResponse(OK, responseJson = Some(Json.toJson(vatReturnsDes)))) val vatReturninvalidPayloadResponse = diff --git a/test/uk/gov/hmrc/vatapi/services/AuthorisationServiceSpec.scala b/test/uk/gov/hmrc/vatapi/services/AuthorisationServiceSpec.scala index c0f1bfac..bd02d82b 100644 --- a/test/uk/gov/hmrc/vatapi/services/AuthorisationServiceSpec.scala +++ b/test/uk/gov/hmrc/vatapi/services/AuthorisationServiceSpec.scala @@ -21,6 +21,7 @@ import org.scalatest.concurrent.ScalaFutures import org.scalatest.mockito.MockitoSugar import org.scalatestplus.play.OneAppPerSuite import play.api.http.HeaderNames +import play.api.libs.json.JsResultException import play.api.libs.json.Json.toJson import play.api.mvc.Results import play.api.mvc.Results.Forbidden @@ -29,7 +30,8 @@ import uk.gov.hmrc.auth.core.{InsufficientConfidenceLevel, UnsupportedAuthProvid import uk.gov.hmrc.domain.Vrn import uk.gov.hmrc.http.{HeaderCarrier, SessionKeys} import uk.gov.hmrc.vatapi.UnitSpec -import uk.gov.hmrc.vatapi.auth.{Individual, Organisation} +import uk.gov.hmrc.vatapi.assets.TestConstants.Auth._ +import uk.gov.hmrc.vatapi.auth.APIAuthorisedFunctions import uk.gov.hmrc.vatapi.mocks.auth.MockAPIAuthorisedFunctions import uk.gov.hmrc.vatapi.models.Errors @@ -40,13 +42,13 @@ import scala.util.Right class AuthorisationServiceSpec extends UnitSpec with OneAppPerSuite with MockitoSugar with ScalaFutures with MockAPIAuthorisedFunctions { object TestAuthorisationService extends AuthorisationService { - override val aPIAuthorisedFunctions = mockAPIAuthorisedFunctions + override val apiAuthorisedFunctions: APIAuthorisedFunctions = mockAPIAuthorisedFunctions } implicit val hc: HeaderCarrier = HeaderCarrier() val testDateTime: DateTime = DateTime.now() - lazy val fakeRequestWithActiveSession = FakeRequest().withSession( + lazy val fakeRequestWithActiveSession: FakeRequest[_] = FakeRequest().withSession( SessionKeys.lastRequestTimestamp -> "1498236506662", SessionKeys.authToken -> "Bearer Token" ).withHeaders( @@ -63,14 +65,14 @@ class AuthorisationServiceSpec extends UnitSpec with OneAppPerSuite with Mockito "verify the auth with valid organisation client details" should { "should return valid auth enrolments " in { setupMockAuthRetrievalSuccess(testAuthOrganisationSuccessResponse) - extractAwait(TestAuthorisationService.authCheck(testVrn)(hc, fakeRequestWithActiveSession, ec)) shouldBe Right(Organisation) + extractAwait(TestAuthorisationService.authCheck(testVrn)(hc, fakeRequestWithActiveSession, ec)) shouldBe Right(orgAuthContext) } } "verify the auth with valid individual client details" should { "should return valid auth enrolments" in { setupMockAuthRetrievalSuccess(testAuthIndividualSuccessResponse) - extractAwait(TestAuthorisationService.authCheck(testVrn)(hc, fakeRequestWithActiveSession, ec)) shouldBe Right(Individual) + extractAwait(TestAuthorisationService.authCheck(testVrn)(hc, fakeRequestWithActiveSession, ec)) shouldBe Right(indAuthContext) } } @@ -89,6 +91,14 @@ class AuthorisationServiceSpec extends UnitSpec with OneAppPerSuite with Mockito } } + "verify auth when JSON response from auth.authorise has insufficient data for creating NRS data" should { + "reject the client" in { + setupMockAuthorisationException(new JsResultException(errors = Seq())) + extractAwait(TestAuthorisationService.authCheck(testVrn)(hc, fakeRequestWithActiveSession, ec)) shouldBe + Left(Forbidden(toJson(Errors.InternalServerError))) + } + } + "verify the auth with unexpected auth error" should { "should reject the client " in { setupMockAuthorisationException(new UnsupportedAuthProvider) @@ -97,4 +107,4 @@ class AuthorisationServiceSpec extends UnitSpec with OneAppPerSuite with Mockito } } } -} +} \ No newline at end of file diff --git a/test/uk/gov/hmrc/vatapi/services/NRSServiceSpec.scala b/test/uk/gov/hmrc/vatapi/services/NRSServiceSpec.scala index b4b9e3c4..0c285b8e 100644 --- a/test/uk/gov/hmrc/vatapi/services/NRSServiceSpec.scala +++ b/test/uk/gov/hmrc/vatapi/services/NRSServiceSpec.scala @@ -19,9 +19,11 @@ import org.joda.time.DateTime import org.scalatest.concurrent.ScalaFutures import org.scalatest.mockito.MockitoSugar import org.scalatestplus.play.OneAppPerSuite +import play.api.test.FakeRequest import uk.gov.hmrc.domain.Vrn import uk.gov.hmrc.http.HeaderCarrier import uk.gov.hmrc.vatapi.UnitSpec +import uk.gov.hmrc.vatapi.assets.TestConstants.Auth.orgAuthContext import uk.gov.hmrc.vatapi.assets.TestConstants.NRSResponse._ import uk.gov.hmrc.vatapi.assets.TestConstants.VatReturn._ import uk.gov.hmrc.vatapi.connectors.NRSConnector @@ -29,6 +31,7 @@ import uk.gov.hmrc.vatapi.httpparsers.NrsError import uk.gov.hmrc.vatapi.httpparsers.NrsSubmissionHttpParser.NrsSubmissionOutcome import uk.gov.hmrc.vatapi.mocks.connectors.MockNRSConnector import uk.gov.hmrc.vatapi.models.VatReturnDeclaration +import uk.gov.hmrc.vatapi.resources.AuthRequest import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.Future @@ -40,8 +43,9 @@ class NRSServiceSpec extends UnitSpec with OneAppPerSuite with MockitoSugar with } implicit val hc: HeaderCarrier = HeaderCarrier() - val testDateTime: DateTime = DateTime.now() + implicit val req: AuthRequest[_] = new AuthRequest(orgAuthContext, FakeRequest().withHeaders(("Authorization", "Bearer test-bearer-token"))) + val testDateTime: DateTime = DateTime.now() "NRSService.submit" when {