Skip to content

Commit 5f84981

Browse files
authored
Merge pull request #145 from hmrc/MTDSA-30457
[MTDSA-30457] Hip migration for api#1640
2 parents baaf068 + c2de9fd commit 5f84981

17 files changed

+426
-51
lines changed

app/v1/connectors/DeleteDisclosuresConnector.scala

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616

1717
package v1.connectors
1818

19-
import api.connectors.DownstreamUri.Ifs1Uri
19+
import api.connectors.DownstreamUri.{HipUri, Ifs1Uri}
2020
import api.connectors.httpparsers.StandardDownstreamHttpParser._
2121
import api.connectors.{BaseDownstreamConnector, DownstreamOutcome}
22-
import config.AppConfig
22+
import config.{AppConfig, ConfigFeatureSwitches}
2323
import uk.gov.hmrc.http.HeaderCarrier
2424
import uk.gov.hmrc.http.client.HttpClientV2
2525
import v1.models.request.delete.DeleteDisclosuresRequestData
@@ -37,7 +37,11 @@ class DeleteDisclosuresConnector @Inject() (val http: HttpClientV2, val appConfi
3737

3838
import request._
3939

40-
val downstreamUri = Ifs1Uri[Unit](s"income-tax/disclosures/$nino/${taxYear.asMtd}")
40+
val downstreamUri = if(ConfigFeatureSwitches().isEnabled("ifs_hip_migration_1640")) {
41+
HipUri[Unit](s"itsd/disclosures/$nino/${taxYear.asMtd}")
42+
} else {
43+
Ifs1Uri[Unit](s"income-tax/disclosures/$nino/${taxYear.asMtd}")
44+
}
4145

4246
delete(downstreamUri)
4347
}

app/v1/services/DeleteDisclosuresService.scala

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,22 @@ class DeleteDisclosuresService @Inject() (connector: DeleteDisclosuresConnector)
3535
.map(_.leftMap(mapDownstreamErrors(downstreamErrorMap)))
3636
}
3737

38-
private val downstreamErrorMap: Map[String, MtdError] = Map(
39-
"INVALID_TAXABLE_ENTITY_ID" -> NinoFormatError,
40-
"INVALID_TAX_YEAR" -> TaxYearFormatError,
41-
"INVALID_CORRELATIONID" -> InternalError,
42-
"NO_DATA_FOUND" -> NotFoundError,
43-
"VOLUNTARY_CLASS2_CANNOT_BE_CHANGED" -> RuleVoluntaryClass2CannotBeChangedError,
44-
"SERVER_ERROR" -> InternalError,
45-
"SERVICE_UNAVAILABLE" -> InternalError
46-
)
38+
private val downstreamErrorMap: Map[String, MtdError] = {
39+
val ifsErrors = Map(
40+
"INVALID_TAXABLE_ENTITY_ID" -> NinoFormatError,
41+
"INVALID_TAX_YEAR" -> TaxYearFormatError,
42+
"INVALID_CORRELATIONID" -> InternalError,
43+
"NO_DATA_FOUND" -> NotFoundError,
44+
"SERVER_ERROR" -> InternalError,
45+
"SERVICE_UNAVAILABLE" -> InternalError
46+
)
47+
val hipErrors = Map(
48+
"1215" -> NinoFormatError,
49+
"1117" -> TaxYearFormatError,
50+
"5010" -> NotFoundError,
51+
"5000" -> RuleTaxYearNotSupportedError
52+
)
53+
ifsErrors ++ hipErrors
54+
}
4755

4856
}

app/v2/connectors/DeleteDisclosuresConnector.scala

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616

1717
package v2.connectors
1818

19-
import api.connectors.DownstreamUri.Ifs1Uri
19+
import api.connectors.DownstreamUri.{HipUri, Ifs1Uri}
2020
import api.connectors.httpparsers.StandardDownstreamHttpParser._
2121
import api.connectors.{BaseDownstreamConnector, DownstreamOutcome}
22-
import config.AppConfig
22+
import config.{AppConfig, ConfigFeatureSwitches}
2323
import uk.gov.hmrc.http.HeaderCarrier
2424
import uk.gov.hmrc.http.client.HttpClientV2
2525
import v2.models.request.delete.DeleteDisclosuresRequestData
@@ -37,7 +37,12 @@ class DeleteDisclosuresConnector @Inject() (val http: HttpClientV2, val appConfi
3737

3838
import request._
3939

40-
val downstreamUri = Ifs1Uri[Unit](s"income-tax/disclosures/$nino/${taxYear.asMtd}")
40+
val downstreamUri = if(ConfigFeatureSwitches().isEnabled("ifs_hip_migration_1640")) {
41+
HipUri[Unit](s"itsd/disclosures/$nino/${taxYear.asMtd}")
42+
} else {
43+
Ifs1Uri[Unit](s"income-tax/disclosures/$nino/${taxYear.asMtd}")
44+
}
45+
4146

4247
delete(downstreamUri)
4348
}

app/v2/services/DeleteDisclosuresService.scala

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,24 @@ class DeleteDisclosuresService @Inject() (connector: DeleteDisclosuresConnector)
3535
.map(_.leftMap(mapDownstreamErrors(downstreamErrorMap)))
3636
}
3737

38-
private val downstreamErrorMap: Map[String, MtdError] = Map(
39-
"INVALID_TAXABLE_ENTITY_ID" -> NinoFormatError,
40-
"INVALID_TAX_YEAR" -> TaxYearFormatError,
41-
"INVALID_CORRELATIONID" -> InternalError,
42-
"NO_DATA_FOUND" -> NotFoundError,
43-
"VOLUNTARY_CLASS2_CANNOT_BE_CHANGED" -> RuleVoluntaryClass2CannotBeChangedError,
44-
"OUTSIDE_AMENDMENT_WINDOW" -> RuleOutsideAmendmentWindowError,
45-
"SERVER_ERROR" -> InternalError,
46-
"SERVICE_UNAVAILABLE" -> InternalError
47-
)
38+
private val downstreamErrorMap: Map[String, MtdError] = {
39+
val ifsErrors = Map(
40+
"INVALID_TAXABLE_ENTITY_ID" -> NinoFormatError,
41+
"INVALID_TAX_YEAR" -> TaxYearFormatError,
42+
"INVALID_CORRELATIONID" -> InternalError,
43+
"NO_DATA_FOUND" -> NotFoundError,
44+
"OUTSIDE_AMENDMENT_WINDOW" -> RuleOutsideAmendmentWindowError,
45+
"SERVER_ERROR" -> InternalError,
46+
"SERVICE_UNAVAILABLE" -> InternalError
47+
)
48+
val hipErrors = Map(
49+
"1215" -> NinoFormatError,
50+
"1117" -> TaxYearFormatError,
51+
"5010" -> NotFoundError,
52+
"4200" -> RuleOutsideAmendmentWindowError,
53+
"5000" -> RuleTaxYearNotSupportedError
54+
)
55+
ifsErrors ++ hipErrors
56+
}
4857

4958
}

it/test/auth/DisclosuresAPIAuthMainAgentsOnlyISpec.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ import play.api.libs.ws.{WSRequest, WSResponse}
2525

2626
class DisclosuresAPIAuthMainAgentsOnlyISpec extends AuthMainAgentsOnlyISpec {
2727

28+
override def servicesConfig: Map[String, Any] =
29+
Map("feature-switch.ifs_hip_migration_1640.enabled" -> false) ++ super.servicesConfig
30+
2831
val callingApiVersion = "2.0"
2932

3033
val supportingAgentsNotAllowedEndpoint = "delete-disclosures"

it/test/auth/DisclosuresAPIAuthSupportingAgentsOnlyISpec.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ import play.api.libs.ws.{WSRequest, WSResponse}
2525

2626
class DisclosuresAPIAuthSupportingAgentsOnlyISpec extends AuthSupportingAgentsAllowedISpec {
2727

28+
override def servicesConfig: Map[String, Any] =
29+
Map("feature-switch.ifs_hip_migration_1640.enabled" -> false) ++ super.servicesConfig
30+
2831
val callingApiVersion = "2.0"
2932

3033
val supportingAgentsAllowedEndpoint = "delete-disclosures"
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/*
2+
* Copyright 2025 HM Revenue & Customs
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package v1
18+
19+
import api.models.errors.{MtdError, NinoFormatError, NotFoundError, RuleTaxYearNotSupportedError, RuleTaxYearRangeInvalidError, TaxYearFormatError}
20+
import api.services.{AuditStub, AuthStub, DownstreamStub, MtdIdLookupStub}
21+
import api.support.IntegrationBaseSpec
22+
import com.github.tomakehurst.wiremock.stubbing.StubMapping
23+
import play.api.libs.json.Json
24+
import play.api.libs.ws.{WSRequest, WSResponse}
25+
import play.api.test.Helpers.{ACCEPT, AUTHORIZATION, BAD_REQUEST, NOT_FOUND, NO_CONTENT, UNPROCESSABLE_ENTITY}
26+
27+
class DeleteDisclosuresControllerHipISpec extends IntegrationBaseSpec {
28+
29+
private trait Test {
30+
31+
val nino: String = "AA123456A"
32+
val taxYear: String = "2021-22"
33+
34+
private def uri: String = s"/$nino/$taxYear"
35+
36+
def HipUri: String = s"/itsd/disclosures/$nino/$taxYear"
37+
38+
def setupStubs(): StubMapping
39+
40+
def request(): WSRequest = {
41+
setupStubs()
42+
buildRequest(uri)
43+
.withHttpHeaders(
44+
(ACCEPT, "application/vnd.hmrc.1.0+json"),
45+
(AUTHORIZATION, "Bearer 123") // some bearer token
46+
)
47+
}
48+
49+
}
50+
51+
"Calling the 'delete disclosures' endpoint" should {
52+
"return a 204 status code" when {
53+
"any valid request is made" in new Test {
54+
55+
override def setupStubs(): StubMapping = {
56+
AuditStub.audit()
57+
AuthStub.authorised()
58+
MtdIdLookupStub.ninoFound(nino)
59+
DownstreamStub.onSuccess(DownstreamStub.DELETE, HipUri, NO_CONTENT)
60+
}
61+
62+
val response: WSResponse = await(request().delete())
63+
response.status shouldBe NO_CONTENT
64+
response.header("X-CorrelationId").nonEmpty shouldBe true
65+
}
66+
}
67+
68+
"return error according to spec" when {
69+
70+
"validation error" when {
71+
def validationErrorTest(requestNino: String, requestTaxYear: String, expectedStatus: Int, expectedBody: MtdError): Unit = {
72+
s"validation fails with ${expectedBody.code} error" in new Test {
73+
74+
override val nino: String = requestNino
75+
override val taxYear: String = requestTaxYear
76+
77+
override def setupStubs(): StubMapping = {
78+
AuditStub.audit()
79+
AuthStub.authorised()
80+
MtdIdLookupStub.ninoFound(nino)
81+
}
82+
83+
val response: WSResponse = await(request().delete())
84+
response.status shouldBe expectedStatus
85+
response.json shouldBe Json.toJson(expectedBody)
86+
response.header("Content-Type") shouldBe Some("application/json")
87+
}
88+
}
89+
90+
val input = Seq(
91+
("AA1123A", "2021-22", BAD_REQUEST, NinoFormatError),
92+
("AA123456A", "2017-18", BAD_REQUEST, RuleTaxYearNotSupportedError),
93+
("AA123456A", "20177", BAD_REQUEST, TaxYearFormatError),
94+
("AA123456A", "2015-17", BAD_REQUEST, RuleTaxYearRangeInvalidError)
95+
)
96+
input.foreach(args => (validationErrorTest _).tupled(args))
97+
}
98+
99+
"hip service error" when {
100+
def serviceErrorTest(hipStatus: Int, hipCode: String, expectedStatus: Int, expectedBody: MtdError): Unit = {
101+
s"ifs returns an $hipCode error and status $hipStatus" in new Test {
102+
103+
override def setupStubs(): StubMapping = {
104+
AuditStub.audit()
105+
AuthStub.authorised()
106+
MtdIdLookupStub.ninoFound(nino)
107+
DownstreamStub.onError(DownstreamStub.DELETE, HipUri, hipStatus, errorBody(hipCode))
108+
}
109+
110+
val response: WSResponse = await(request().delete())
111+
response.status shouldBe expectedStatus
112+
response.json shouldBe Json.toJson(expectedBody)
113+
response.header("Content-Type") shouldBe Some("application/json")
114+
}
115+
}
116+
117+
def errorBody(code: String): String =
118+
s"""
119+
|[
120+
| {
121+
| "errorCode": "$code",
122+
| "errorDescription": "error message"
123+
| }
124+
|]
125+
""".stripMargin
126+
127+
val input = Seq(
128+
(BAD_REQUEST, "1215", BAD_REQUEST, NinoFormatError),
129+
(BAD_REQUEST, "1117", BAD_REQUEST, TaxYearFormatError),
130+
(NOT_FOUND, "5010", NOT_FOUND, NotFoundError),
131+
(UNPROCESSABLE_ENTITY, "5000", BAD_REQUEST, RuleTaxYearNotSupportedError)
132+
)
133+
input.foreach(args => (serviceErrorTest _).tupled(args))
134+
}
135+
}
136+
}
137+
138+
}

it/test/v1/DeleteDisclosuresControllerISpec.scala renamed to it/test/v1/DeleteDisclosuresControllerIfsISpec.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ import play.api.libs.json.Json
2525
import play.api.libs.ws.{WSRequest, WSResponse}
2626
import play.api.test.Helpers._
2727

28-
class DeleteDisclosuresControllerISpec extends IntegrationBaseSpec {
28+
class DeleteDisclosuresControllerIfsISpec extends IntegrationBaseSpec {
29+
30+
override def servicesConfig: Map[String, Any] =
31+
Map("feature-switch.ifs_hip_migration_1640.enabled" -> false) ++ super.servicesConfig
2932

3033
private trait Test {
3134

@@ -128,7 +131,6 @@ class DeleteDisclosuresControllerISpec extends IntegrationBaseSpec {
128131
(BAD_REQUEST, "INVALID_TAX_YEAR", BAD_REQUEST, TaxYearFormatError),
129132
(BAD_REQUEST, "INVALID_CORRELATIONID", INTERNAL_SERVER_ERROR, errors.InternalError),
130133
(NOT_FOUND, "NO_DATA_FOUND", NOT_FOUND, NotFoundError),
131-
(UNPROCESSABLE_ENTITY, "VOLUNTARY_CLASS2_CANNOT_BE_CHANGED", BAD_REQUEST, RuleVoluntaryClass2CannotBeChangedError),
132134
(INTERNAL_SERVER_ERROR, "SERVER_ERROR", INTERNAL_SERVER_ERROR, errors.InternalError),
133135
(SERVICE_UNAVAILABLE, "SERVICE_UNAVAILABLE", INTERNAL_SERVER_ERROR, errors.InternalError)
134136
)

0 commit comments

Comments
 (0)