Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
162b153
[DC-7967] Update lib versions, rename test class to align with its co…
tyagikumarvineet Oct 28, 2025
a0b886f
[DC-7967] Add test class and relevant tests
tyagikumarvineet Oct 30, 2025
1d82560
[DC-7967] Add test class for Letter and refactor test suite order for…
tyagikumarvineet Oct 30, 2025
5634f48
[DC-7967] Add tests
tyagikumarvineet Oct 30, 2025
0876e8f
[DC-7967] Add further tests for Letter and rename the vals
tyagikumarvineet Oct 31, 2025
a9ed075
[DC-7967] Add common TestData object and test class for MessageHeader
tyagikumarvineet Oct 31, 2025
54b883a
[DC-7967] Add test class for MessageListItem
tyagikumarvineet Nov 1, 2025
ea861db
[DC-7967] Add test classes and relevant tests
tyagikumarvineet Nov 1, 2025
57218c4
[DC-7967] Add Test classes and add tests
tyagikumarvineet Nov 3, 2025
d63eaee
[DC-7967] Update minimum test coverage to 81 %
tyagikumarvineet Nov 3, 2025
2947d2a
[DC-7967] Add test classes and Update minimum test coverage to 86%
tyagikumarvineet Nov 4, 2025
6a3e5f9
[DC-7967] Refactored the Integration tests to avoid the future timing…
tyagikumarvineet Nov 5, 2025
85f1b83
[DC-7967] Move TestData to helpers and replace the values with the co…
tyagikumarvineet Nov 5, 2025
d16eda0
[DC-7967] Make use of common constants
tyagikumarvineet Nov 5, 2025
70d2330
[DC-7967] Comment assertion in Integration tests as it is not consistent
tyagikumarvineet Nov 5, 2025
c1cea18
[DC-7967] Update the libraries' version to latest
tyagikumarvineet Nov 5, 2025
6bdd9a9
[DC-7967] Update the method name
tyagikumarvineet Nov 5, 2025
2db02f1
[DC-7967] Update secure message test-only routes
tyagikumarvineet Nov 6, 2025
5c9e6ef
[DC-7967] Incorporate Review Comments
tyagikumarvineet Nov 7, 2025
c088897
[DC-7967] Incorporate Review Comments, remove redundant message url a…
tyagikumarvineet Nov 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 13 additions & 10 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@
* limitations under the License.
*/

import uk.gov.hmrc.DefaultBuildSettings.{defaultSettings, scalaSettings}
import uk.gov.hmrc.DefaultBuildSettings.{ defaultSettings, scalaSettings }
import play.twirl.sbt.Import.TwirlKeys
import play.sbt.routes.RoutesKeys
import scoverage.ScoverageKeys

val appName = "secure-message-frontend"

Global / majorVersion := 1
Global / scalaVersion := "3.3.4"
Global / scalaVersion := "3.3.6"

val excludedPackages: Seq[String] = Seq(
"<empty>",
Expand All @@ -32,13 +32,12 @@ val excludedPackages: Seq[String] = Seq(
".*\\$anon.*",
"testOnlyDoNotUseInAppConf.*",
"views.viewmodels.*"

)

lazy val scoverageSettings =
Seq(
ScoverageKeys.coverageExcludedPackages := excludedPackages.mkString(","),
ScoverageKeys.coverageMinimumStmtTotal := 67.90,
ScoverageKeys.coverageMinimumStmtTotal := 86,
ScoverageKeys.coverageFailOnMinimum := true,
ScoverageKeys.coverageHighlighting := true
)
Expand All @@ -49,7 +48,12 @@ lazy val microservice = Project(appName, file("."))
.settings(defaultSettings() *)
.settings(
name := appName,
RoutesKeys.routesImport ++= Seq("models._", "controllers.generic.models._", "controllers.binders._","uk.gov.hmrc.play.bootstrap.binders.RedirectUrl"),
RoutesKeys.routesImport ++= Seq(
"models._",
"controllers.generic.models._",
"controllers.binders._",
"uk.gov.hmrc.play.bootstrap.binders.RedirectUrl"
),
libraryDependencies ++= AppDependencies.compile ++ AppDependencies.test,
TwirlKeys.templateImports ++= Seq(
"config.AppConfig",
Expand All @@ -65,18 +69,18 @@ lazy val microservice = Project(appName, file("."))
buildInfoKeys := Seq[BuildInfoKey](name, version, scalaVersion, sbtVersion)
)
.settings(
scalacOptions := scalacOptions.value.diff(Seq("-Wunused:all")),
scalacOptions ++= Seq(
// Silence unused imports in template files
"-Wconf:msg=unused import&src=.*:s",
// Silence "Flag -XXX set repeatedly"
"-Wconf:msg=Flag.*repeatedly:s",
// Silence unused warnings on Play `routes` files
"-Wconf:src=routes/.*:s")

"-Wconf:src=routes/.*:s"
)
)
.settings(scoverageSettings.settings *)


lazy val it = (project in file("it"))
.enablePlugins(PlayScala)
.dependsOn(`microservice` % "test->test")
Expand All @@ -92,6 +96,5 @@ Test / test := (Test / test)
.value

it / test := (it / Test / test)
.dependsOn(scalafmtCheckAll, it/scalafmtCheckAll)
.dependsOn(scalafmtCheckAll, it / scalafmtCheckAll)
.value

4 changes: 3 additions & 1 deletion it/test/ConversationPartialISpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ import views.helpers.HtmlUtil.encodeBase64String
import play.api.libs.ws.JsonBodyWritables.writeableOf_JsValue

class ConversationPartialISpec extends PlaySpec with ServiceSpec with MockitoSugar with BeforeAndAfterEach {
override def externalServices: Seq[String] = Seq.empty

val secureMessagePort: Int = 9051
val overCharacterLimit: Int = 4001
val id = "909d1359aa0220d12c73160a"

override def externalServices: Seq[String] = Seq.empty
override protected def beforeEach(): Unit = {
wsClient
.url(s"http://localhost:$secureMessagePort/test-only/delete/conversation/$id")
Expand Down
53 changes: 25 additions & 28 deletions it/test/MessageFrontendISpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import play.api.http.{ HeaderNames, Status }
import play.api.inject.guice.GuiceApplicationBuilder
import play.api.libs.json.*
import play.api.libs.ws.JsonBodyWritables.writeableOf_JsValue
import play.api.libs.ws.{ WSClient, WSResponse }
import play.api.libs.ws.WSClient
import play.api.mvc.AnyContentAsEmpty
import play.api.test.FakeRequest
import play.api.test.Helpers.*
Expand All @@ -39,15 +39,16 @@ import uk.gov.hmrc.crypto.{ PlainText, SymmetricCryptoFactory }
import uk.gov.hmrc.domain.*
import uk.gov.hmrc.http.{ HeaderCarrier, SessionKeys }

import java.time.LocalDate
import java.util.Base64
import java.util.concurrent.TimeUnit
import scala.concurrent.duration.{ Duration, FiniteDuration }
import scala.jdk.CollectionConverters.*
import scala.util.Random
import play.api.http.ContentTypes

class MessageFrontendISpec
extends PlaySpec with GuiceOneServerPerSuite with ScalaFutures with BeforeAndAfterEach with Eventually {

val duration15: Int = 15
implicit val defaultTimeout: FiniteDuration = Duration(duration15, TimeUnit.SECONDS)

Expand All @@ -60,24 +61,25 @@ class MessageFrontendISpec
)
.build()

lazy val ws = app.injector.instanceOf[WSClient]
lazy val testAuthorisationProvider = app.injector.instanceOf[TestAuthorisationProvider]
val messageResource = "http://localhost:8910/"
val secureMessageResource = "http://localhost:9051/secure-messaging/"
lazy val ws: WSClient = app.injector.instanceOf[WSClient]
lazy val testAuthorisationProvider: TestAuthorisationProvider = app.injector.instanceOf[TestAuthorisationProvider]

override protected def beforeEach() = {
ws.url(s"${messageResource}test-only/messages").delete().futureValue
ws.url(s"${messageResource}test-only/qmessages").delete().futureValue
}
val secureMessageResource = "http://localhost:9051/"

override protected def beforeEach(): Unit =
ws.url(s"${secureMessageResource}test-only/delete/secure-messages")
.withHttpHeaders((HeaderNames.CONTENT_TYPE, ContentTypes.JSON))
.delete()
.futureValue

trait TestCase {

def httpClient: WSClient = ws

implicit val hc: HeaderCarrier = HeaderCarrier()

lazy val authBuilder = testAuthorisationProvider.governmentGatewayAuthority().withSaUtr(utr)
lazy val ggAuthorisationHeader = authBuilder.bearerTokenHeader()(Duration(1, TimeUnit.MINUTES))
lazy val authBuilder: AuthorityBuilder = testAuthorisationProvider.governmentGatewayAuthority().withSaUtr(utr)
lazy val ggAuthorisationHeader: (String, String) = authBuilder.bearerTokenHeader()(Duration(1, TimeUnit.MINUTES))
lazy val cookie: (String, String) = authBuilder.sessionCookie(ggAuthorisationHeader._2)

def authResource(path: String): String = s"http://localhost:8585/$path"
Expand All @@ -87,9 +89,7 @@ class MessageFrontendISpec
val duration16: Int = 16
def randomDetailsId: String = "C" + Random.alphanumeric.filter(_.isDigit).take(duration16).mkString

val now = LocalDate.now

lazy val atsMessage = Json
lazy val atsMessage: JsObject = Json
.parse(s"""
| {
| "externalRef":{
Expand Down Expand Up @@ -123,9 +123,10 @@ class MessageFrontendISpec
""".stripMargin)
.as[JsObject]

lazy val statementMessage = createMessageJson("mdtp", "SA300", TaxEntity("sa", utr), Some("user@email.com"))
lazy val statementMessage: JsObject =
createMessageJson("mdtp", "SA300", TaxEntity("sa", utr), Some("user@email.com"))

lazy val refundMessage = createMessageJson("mdtp", "R002A", TaxEntity("sa", utr), Some("user@email.com"))
lazy val refundMessage: JsObject = createMessageJson("mdtp", "R002A", TaxEntity("sa", utr), Some("user@email.com"))

def ninoMessage(nino: Nino): JsObject =
createMessageJson("mdtp", "SA300", TaxEntity("paye", nino), Some("user@email.com"))
Expand Down Expand Up @@ -347,21 +348,15 @@ class MessageFrontendISpec
def messagesPost(body: JsObject): String = {
val response =
httpClient
.url(s"${messageResource}messages")
.url(s"${secureMessageResource}messages")
.withHttpHeaders(SessionKeys.authToken -> ggAuthorisationHeader._2)
.post(body)
.futureValue

response.status must be(Status.CREATED)
(response.json \\ "id").map(_.as[JsString].value).head
}

def externalMessagesPost(body: JsObject): WSResponse =
httpClient
.url(s"${messageResource}external/messages")
.withHttpHeaders(SessionKeys.authToken -> ggAuthorisationHeader._2)
.post(body)
.futureValue

def messages(
taxIdentifiers: List[String] = List(),
regimes: List[String] = List()
Expand Down Expand Up @@ -407,7 +402,10 @@ class MessageFrontendISpec
val bt = authBuilder.bearerTokenHeader()

val response =
ws.url(s"${secureMessageResource}messages").withHttpHeaders(HeaderNames.AUTHORIZATION -> bt._2).get()
ws.url(s"${secureMessageResource}secure-messaging/messages")
.withHttpHeaders(HeaderNames.AUTHORIZATION -> bt._2)
.get()

val responseValue = response.futureValue
responseValue.status must be(Status.OK)
val alerts = Jsoup.parse(responseValue.body).getElementById("unreadMessages")
Expand Down Expand Up @@ -454,7 +452,6 @@ class MessageFrontendISpec
messagesPost(fhddsMessage(fhdds))
messagesPost(pptMessage(ppt))
messagesPost(vatMessage(vat))
externalMessagesPost(podsMessage("HMRC-PODS-ORG.PSAID", pods.value))
messagesPost(epayeMessage(epaye))

(authProvider, nino.value, ctUtr.value, fhdds.value, vat.value, ppt.value, pods.value, epaye.value)
Expand All @@ -480,8 +477,8 @@ class MessageFrontendISpec
}

def emailMessagesSubject(responseBody: String): List[String] = {

val parsedMessages = Jsoup.parse(responseBody)

parsedMessages
.getElementsByClass("table--borderless")
.first()
Expand Down
4 changes: 0 additions & 4 deletions it/test/MessagesISpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ class MessagesISpec extends MessageFrontendISpec with Inspectors {

status(result) must be(Status.OK)
expectedMessages(contentAsString(result), 1)

}

"return no messages for ct-utr user" in new TestCase {
Expand Down Expand Up @@ -322,9 +321,6 @@ class MessagesISpec extends MessageFrontendISpec with Inspectors {
.withNino(Nino("NH123456D"))
.withPodsPp(HmrcPodsPpOrg("A12345678"))

externalMessagesPost(podsMessage("HMRC-PODS-ORG.PSAID", "A1234567"))
externalMessagesPost(podsMessage("HMRC-PODSPP-ORG.PSPID", "A12345678"))

val request = messagesBta(List("PSPID"), List("pods"))
.withSession(
authContext.bearerTokenHeader(),
Expand Down
30 changes: 17 additions & 13 deletions it/test/MessagesPartialsISpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,44 +20,48 @@
*/
import org.scalatest.concurrent.IntegrationPatience
import org.scalatest.{ BeforeAndAfterEach, Inspectors }
import play.api.Logger
import play.api.Logging
import play.api.http.Status
import play.api.test.FakeRequest
import play.api.test.Helpers.{ route, * }
import uk.gov.hmrc.auth.core.MissingBearerToken
import uk.gov.hmrc.domain.SaUtr
import uk.gov.hmrc.http.SessionKeys
import play.api.http.{ ContentTypes, HeaderNames }
import play.api.mvc.{ AnyContentAsEmpty, Result }
import test.utils.AuthorityBuilder

import scala.concurrent.Future
import scala.concurrent.duration.*
import scala.language.postfixOps

class MessagesPartialsISpec
extends MessageFrontendISpec with IntegrationPatience with Inspectors with BeforeAndAfterEach {
extends MessageFrontendISpec with IntegrationPatience with Inspectors with BeforeAndAfterEach with Logging {

val logger = Logger(getClass)
implicit override val patienceConfig: PatienceConfig =
PatienceConfig(timeout = scaled(30 seconds), interval = scaled(200 millis))

override protected def beforeEach() = {
ws.url(s"${messageResource}test-only/messages").delete()
ws.url(s"${messageResource}test-only/qmessages").delete()
}
override protected def beforeEach(): Unit =
ws.url(s"${secureMessageResource}test-only/delete/secure-messages")
.withHttpHeaders((HeaderNames.CONTENT_TYPE, ContentTypes.JSON))
.delete()
.futureValue

"Message link" must {
"successfully view message when step and returnUrl are missing" in new TestCase {

val utr = SaUtr("1555369043")
val utr: SaUtr = SaUtr("1555369043")

val authProvider = testAuthorisationProvider.governmentGatewayAuthority().withSaUtr(utr)
val authProvider: AuthorityBuilder = testAuthorisationProvider.governmentGatewayAuthority().withSaUtr(utr)

val bt = authProvider.bearerTokenHeader()
val bt: (String, String) = authProvider.bearerTokenHeader()

val messageId = messagesPost(statementMessage)
val request =
val messageId: String = messagesPost(statementMessage)
val request: FakeRequest[AnyContentAsEmpty.type] =
getMessageForEncryptedUrl(encryptSaMessageRendererReadUrl(messageId))
.withSession(SessionKeys.authToken -> bt._2)

val result = route(app, request).get
val result: Future[Result] = route(app, request).get
status(result) must be(Status.OK)

}
Expand Down
22 changes: 10 additions & 12 deletions project/AppDependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,25 @@
* limitations under the License.
*/


import sbt._
import sbt.*

object AppDependencies {

private val bootstrapVersion = "9.19.0"
private val bootstrapVersion = "10.4.0"

val compile = Seq(
val compile: Seq[ModuleID] = Seq(
"uk.gov.hmrc" %% "bootstrap-frontend-play-30" % bootstrapVersion,
"uk.gov.hmrc" %% "play-frontend-hmrc-play-30" % "12.12.0",
"uk.gov.hmrc" %% "domain-play-30" % "10.0.0",
"uk.gov.hmrc" %% "play-frontend-hmrc-play-30" % "12.20.0",
"uk.gov.hmrc" %% "domain-play-30" % "13.0.0",
"org.typelevel" %% "cats-core" % "2.13.0",
"net.codingwell" %% "scala-guice" % "6.0.0",
"uk.gov.hmrc" %% "play-partials-play-30" % "10.1.0",
"uk.gov.hmrc" %% "play-partials-play-30" % "10.2.0",
"org.jsoup" % "jsoup" % "1.21.1"
)

val test = Seq(
"uk.gov.hmrc" %% "bootstrap-test-play-30" % bootstrapVersion % Test,
"org.scalatestplus.play" %% "scalatestplus-play" % "7.0.2" % Test,
"org.scalatestplus" %% "mockito-3-4" % "3.2.10.0" % Test,
"org.mockito" % "mockito-core" % "5.18.0" % Test
val test: Seq[ModuleID] = Seq(
"uk.gov.hmrc" %% "bootstrap-test-play-30" % bootstrapVersion % Test,
"org.scalatestplus" %% "mockito-3-4" % "3.2.10.0" % Test,
"org.mockito" % "mockito-core" % "5.18.0" % Test
)
}
13 changes: 7 additions & 6 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@

resolvers += MavenRepository("HMRC-open-artefacts-maven2", "https://open.artefacts.tax.service.gov.uk/maven2")
resolvers += Resolver.url("HMRC-open-artefacts-ivy", url("https://open.artefacts.tax.service.gov.uk/ivy2"))(
Resolver.ivyStylePatterns)
Resolver.ivyStylePatterns
)

addSbtPlugin("uk.gov.hmrc" % "sbt-auto-build" % "3.24.0")
addSbtPlugin("uk.gov.hmrc" % "sbt-distributables" % "2.6.0")
addSbtPlugin("org.playframework" % "sbt-plugin" % "3.0.8")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2")
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.2.2")
addSbtPlugin("uk.gov.hmrc" % "sbt-auto-build" % "3.24.0")
addSbtPlugin("uk.gov.hmrc" % "sbt-distributables" % "2.6.0")
addSbtPlugin("org.playframework" % "sbt-plugin" % "3.0.9")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2")
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.2.2")
Loading