Skip to content

Commit 165c5e9

Browse files
Merge pull request #149 from hmrc/MTDSA-31559
MTDSA-31559 - Raised coverage to 95%
2 parents c4df0cd + 611018a commit 165c5e9

File tree

11 files changed

+209
-24
lines changed

11 files changed

+209
-24
lines changed

app/api/controllers/AuditHandler.scala

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,21 +55,6 @@ object AuditHandler {
5555
responseBodyMap = if (includeResponse) identity else const(None)
5656
)
5757

58-
def custom[A: Writes](auditService: AuditService,
59-
auditType: String,
60-
transactionName: String,
61-
auditDetailCreator: AuditDetailCreator[A],
62-
requestBody: Option[JsValue] = None,
63-
responseBodyMap: Option[JsValue] => Option[JsValue]): AuditHandler =
64-
new AuditHandlerImpl[A](
65-
auditService = auditService,
66-
auditType = auditType,
67-
transactionName = transactionName,
68-
auditDetailCreator,
69-
requestBody = requestBody,
70-
responseBodyMap = responseBodyMap
71-
)
72-
7358
private class AuditHandlerImpl[A: Writes](auditService: AuditService,
7459
auditType: String,
7560
transactionName: String,

app/definition/ApiDefinition.scala

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,6 @@ import play.api.libs.json.{Format, Json, OFormat}
2020
import routing.Version
2121
import utils.enums.Enums
2222

23-
case class Parameter(name: String, required: Boolean = false)
24-
25-
object Parameter {
26-
implicit val formatParameter: OFormat[Parameter] = Json.format[Parameter]
27-
}
28-
2923
case class PublishingException(message: String) extends Exception(message)
3024

3125
enum APIStatus {

project/CodeCoverageSettings.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ object CodeCoverageSettings {
3434

3535
val settings: Seq[Setting[?]] = Seq(
3636
ScoverageKeys.coverageExcludedPackages := excludedPackages.mkString(";"),
37-
ScoverageKeys.coverageMinimumStmtTotal := 88,
37+
ScoverageKeys.coverageMinimumStmtTotal := 95,
3838
ScoverageKeys.coverageFailOnMinimum := true,
3939
ScoverageKeys.coverageHighlighting := true
4040
)

test/api/connectors/parsers/StandardDownstreamHttpParserSpec.scala

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,48 @@ class StandardDownstreamHttpParserSpec extends UnitSpec {
115115
}
116116
}
117117

118+
"validateJson" when {
119+
implicit val reads: Reads[SomeModel] = Json.reads[SomeModel]
120+
121+
"the JSON is valid" should {
122+
"return the parsed model" in {
123+
val validJsonResponse: HttpResponse = HttpResponse(
124+
OK,
125+
desExpectedJson,
126+
Map("CorrelationId" -> Seq(correlationId))
127+
)
128+
129+
val result: Option[SomeModel] = validJsonResponse.validateJson[SomeModel]
130+
131+
result shouldBe Some(desModel)
132+
}
133+
}
134+
135+
"the JSON is invalid" should {
136+
"return None" in {
137+
val invalidJsonResponse: HttpResponse = HttpResponse(
138+
OK,
139+
Json.obj("data" -> 1234),
140+
Map("CorrelationId" -> Seq(correlationId))
141+
)
142+
143+
val result: Option[SomeModel] = invalidJsonResponse.validateJson[SomeModel]
144+
145+
result shouldBe None
146+
}
147+
}
148+
149+
"the response contains no JSON" should {
150+
"return None" in {
151+
val emptyResponse: HttpResponse = HttpResponse(OK, "", Map("CorrelationId" -> Seq(correlationId)))
152+
153+
val result: Option[SomeModel] = emptyResponse.validateJson[SomeModel]
154+
155+
result shouldBe None
156+
}
157+
}
158+
}
159+
118160
val singleErrorJson: JsValue = Json.parse(
119161
"""
120162
|{

test/api/models/domain/TaxYearRangeSpec.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package api.models.domain
1818

19+
import api.models.domain.TaxYear.currentTaxYear
1920
import support.UnitSpec
2021

2122
import java.time.LocalDate
@@ -53,6 +54,14 @@ class TaxYearRangeSpec extends UnitSpec {
5354
val result: TaxYearRange = TaxYearRange.todayMinus(years = 4)
5455
result shouldBe TaxYearRange(expectedFrom, TaxYear.fromMtd(currentTaxYear))
5556
}
57+
58+
"return a TaxYearRange using the default systemUTC clock when no implicit clock is provided" in {
59+
val expectedRange: TaxYearRange = TaxYearRange(TaxYear.fromDownstreamInt(currentTaxYear().year - 1), currentTaxYear())
60+
61+
val actualRange: TaxYearRange = TaxYearRange.todayMinus(1)
62+
63+
actualRange shouldBe expectedRange
64+
}
5665
}
5766

5867
}

test/api/models/domain/TimestampSpec.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ class TimestampSpec extends UnitSpec {
7474
}
7575
}
7676

77+
"Timestamp.toString" should {
78+
"return the string value" in {
79+
Timestamp("2023-01-20T01:20:30.000Z").toString shouldBe "2023-01-20T01:20:30.000Z"
80+
}
81+
}
82+
7783
"Timestamp serialised to a JSON string field" should {
7884
"serialise correctly" in {
7985
val result = Json.toJson(response)

test/api/models/errors/MtdErrorSpec.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ class MtdErrorSpec extends UnitSpec {
3838
}
3939
}
4040

41+
"maybeWithPath" should {
42+
"add a path to the error" when {
43+
"a path is provided" in {
44+
val result = error.maybeWithPath(Some("path")).paths
45+
result shouldBe Some(List("path"))
46+
}
47+
}
48+
}
49+
4150
"maybeWithExtraPath" should {
4251
"add an extra path to the error" when {
4352
"a path is provided" in {

test/api/services/EnrolmentsAuthServiceSpec.scala

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,10 @@ class EnrolmentsAuthServiceSpec extends ServiceSpec with MockAppConfig {
7474
behave like authorisedSupportingAgent(authValidationEnabled, initialPredicate, primaryAgentPredicate, supportingAgentPredicate)
7575

7676
behave like disallowSupportingAgentForPrimaryOnlyEndpoint(authValidationEnabled, initialPredicate, primaryAgentPredicate)
77-
77+
behave like disallowInvalidAffinityGroup(authValidationEnabled, initialPredicate)
7878
behave like disallowUsersWithoutEnrolments(authValidationEnabled, initialPredicate)
7979
behave like disallowWhenNotLoggedIn(authValidationEnabled, initialPredicate)
80+
behave like handleUnexpectedError(authValidationEnabled, initialPredicate)
8081
}
8182

8283
def authorisedIndividual(authValidationEnabled: Boolean, initialPredicate: Predicate): Unit =
@@ -237,6 +238,21 @@ class EnrolmentsAuthServiceSpec extends ServiceSpec with MockAppConfig {
237238
result shouldBe Left(ClientOrAgentNotAuthorisedError)
238239
}
239240

241+
def disallowInvalidAffinityGroup(authValidationEnabled: Boolean, initialPredicate: Predicate): Unit =
242+
"disallow users with an invalid affinity group" in new Test {
243+
mockConfidenceLevelCheckConfig(authValidationEnabled = authValidationEnabled)
244+
245+
val retrievalsResult = new ~(None, Enrolments(Set.empty))
246+
247+
MockedAuthConnector
248+
.authorised(initialPredicate, affinityGroup and authorisedEnrolments)
249+
.once()
250+
.returns(Future.successful(retrievalsResult))
251+
252+
val result: AuthOutcome = await(enrolmentsAuthService.authorised(mtdId))
253+
result shouldBe Left(ClientOrAgentNotAuthorisedError)
254+
}
255+
240256
def disallowWhenNotLoggedIn(authValidationEnabled: Boolean, initialPredicate: Predicate): Unit =
241257
"disallow users that are not logged in" in new Test {
242258
mockConfidenceLevelCheckConfig(authValidationEnabled = authValidationEnabled)
@@ -264,6 +280,22 @@ class EnrolmentsAuthServiceSpec extends ServiceSpec with MockAppConfig {
264280
}
265281
}
266282

283+
def handleUnexpectedError(authValidationEnabled: Boolean, initialPredicate: Predicate): Unit =
284+
"return InternalError on unexpected error" in new Test {
285+
val exception = new RuntimeException("Unexpected error")
286+
287+
mockConfidenceLevelCheckConfig(authValidationEnabled = authValidationEnabled)
288+
289+
MockedAuthConnector
290+
.authorised(initialPredicate, affinityGroup and authorisedEnrolments)
291+
.once()
292+
.returns(Future.failed(exception))
293+
294+
val result: AuthOutcome = await(enrolmentsAuthService.authorised(mtdId))
295+
result shouldBe Left(InternalError)
296+
297+
}
298+
267299
trait Test {
268300
val mockAuthConnector: AuthConnector = mock[AuthConnector]
269301

test/definition/ApiDefinitionSpec.scala

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package definition
1818

19+
import play.api.libs.json.*
1920
import definition.APIStatus.BETA
2021
import routing.Version1
2122
import support.UnitSpec
@@ -25,6 +26,50 @@ class ApiDefinitionSpec extends UnitSpec {
2526
val apiVersion: APIVersion = APIVersion(Version1, BETA, endpointsEnabled = false)
2627
val apiDefinition: APIDefinition = APIDefinition("b", "c", "d", Seq("e"), Seq(apiVersion), Some(false))
2728

29+
private val apiVersionJson = Json.parse("""
30+
{
31+
"version": "1.0",
32+
"status": "BETA",
33+
"endpointsEnabled": false
34+
}
35+
""")
36+
37+
private val apiDefinitionJson = Json.parse("""
38+
{
39+
"name": "b",
40+
"description": "c",
41+
"context": "d",
42+
"categories": ["e"],
43+
"versions": [
44+
{
45+
"version": "1.0",
46+
"status": "BETA",
47+
"endpointsEnabled": false
48+
}
49+
],
50+
"requiresTrust": false
51+
}
52+
""")
53+
54+
private val definitionJson = Json.parse("""
55+
{
56+
"api": {
57+
"name": "b",
58+
"description": "c",
59+
"context": "d",
60+
"categories": ["e"],
61+
"versions": [
62+
{
63+
"version": "1.0",
64+
"status": "BETA",
65+
"endpointsEnabled": false
66+
}
67+
],
68+
"requiresTrust": false
69+
}
70+
}
71+
""")
72+
2873
"APIDefinition" when {
2974
"the 'name' parameter is empty" should {
3075
"throw an 'IllegalArgumentException'" in {
@@ -75,4 +120,36 @@ class ApiDefinitionSpec extends UnitSpec {
75120
}
76121
}
77122

123+
"APIVersion" should {
124+
"deserialise to model" in {
125+
apiVersionJson.as[APIVersion] shouldBe apiVersion
126+
}
127+
128+
"serialise to JSON" in {
129+
Json.toJson(apiVersion) shouldBe apiVersionJson
130+
}
131+
}
132+
133+
"APIDefinition" should {
134+
"deserialise to model" in {
135+
apiDefinitionJson.as[APIDefinition] shouldBe apiDefinition
136+
}
137+
138+
"serialise to JSON" in {
139+
Json.toJson(apiDefinition) shouldBe apiDefinitionJson
140+
}
141+
}
142+
143+
"Definition" should {
144+
val definition = Definition(apiDefinition)
145+
146+
"deserialise to model" in {
147+
definitionJson.as[Definition] shouldBe definition
148+
}
149+
150+
"serialise to JSON" in {
151+
Json.toJson(definition) shouldBe definitionJson
152+
}
153+
}
154+
78155
}

test/utils/EmptinessCheckerSpec.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,19 @@ class EmptinessCheckerSpec extends UnitSpec {
101101
}
102102
}
103103

104+
"given primitives, Options, Seq and List with no emptiness" must {
105+
"return NoEmptyPaths" in {
106+
EmptinessChecker[String].findEmptyPaths("test") shouldBe NoEmptyPaths
107+
EmptinessChecker[Int].findEmptyPaths(1) shouldBe NoEmptyPaths
108+
EmptinessChecker[Double].findEmptyPaths(1.00) shouldBe NoEmptyPaths
109+
EmptinessChecker[Boolean].findEmptyPaths(true) shouldBe NoEmptyPaths
110+
EmptinessChecker[BigInt].findEmptyPaths(BigInt(1)) shouldBe NoEmptyPaths
111+
EmptinessChecker[BigDecimal].findEmptyPaths(BigDecimal(1)) shouldBe NoEmptyPaths
112+
EmptinessChecker[Option[String]].findEmptyPaths(Some("test")) shouldBe NoEmptyPaths
113+
EmptinessChecker[Option[String]].findEmptyPaths(None) shouldBe NoEmptyPaths
114+
EmptinessChecker[List[Int]].findEmptyPaths(List(1, 2)) shouldBe NoEmptyPaths
115+
EmptinessChecker[Seq[String]].findEmptyPaths(Vector("test", "test")) shouldBe NoEmptyPaths
116+
}
117+
}
118+
104119
}

0 commit comments

Comments
 (0)