Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

ITSASU-3206: Create delete all session backend route #269

Merged
merged 2 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions app/controllers/SessionDataController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,10 @@ class SessionDataController @Inject()(authService: AuthService,
).map(_ => Ok)
}
}

def deleteAllSessionData(): Action[AnyContent] = Action.async { implicit request =>
authService.authorised() {
sessionDataService.deleteAllSessionData.map(_ => Ok)
}
}
}
10 changes: 9 additions & 1 deletion app/repositories/SessionDataRepository.scala
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,22 @@ class SessionDataRepository @Inject()(config: SessionDataRepositoryConfig)(impli
findAndUpdate(selector, update)
}


private def findAndUpdate(selector: JsObject, update: JsObject, fetchNewObject: Boolean = false, upsert: Boolean = false) = {
collection
.findOneAndUpdate(selector, update, findOneAndUpdateOptions(upsert))
.toFuture()
.map(asOption)
}

def deleteDataBySessionId(sessionId: String): Future[Option[JsValue]] = {
val selector: JsObject = Json.obj("session-id" -> sessionId)
findAndDelete(selector)
}
private def findAndDelete(selector: JsObject): Future[Option[JsValue]] = {
collection.findOneAndDelete(selector)
.toFutureOption()
}

def insert(document: JsObject): Future[InsertOneResult] = {
collection
.insertOne(document)
Expand Down
4 changes: 4 additions & 0 deletions app/services/SessionDataService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ class SessionDataService @Inject()(sessionDataRepository: SessionDataRepository,
dataId = dataId
)

def deleteAllSessionData(implicit hc: HeaderCarrier): Future[Option[JsValue]] =
sessionDataRepository.deleteDataBySessionId(sessionId = sessionIdFromHC)


private[services] def sessionIdFromHC(implicit hc: HeaderCarrier): String = {
hc.sessionId.fold(
throw new InternalServerException("[SessionDataService][sessionIdFromHC] - No session id in header carrier")
Expand Down
1 change: 1 addition & 0 deletions conf/subscription.routes
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ GET /session-data/all controllers.SessionDataCont
GET /session-data/id/:id controllers.SessionDataController.retrieveSessionData(id: String)
POST /session-data/id/:id controllers.SessionDataController.insertSessionData(id: String)
DELETE /session-data/id/:id controllers.SessionDataController.deleteSessionData(id: String)
DELETE /session-data/id controllers.SessionDataController.deleteAllSessionData

POST /mis/sign-up/:nino/:taxYear controllers.#Controller.#(nino: String, taxYear: String)

Expand Down
10 changes: 10 additions & 0 deletions it/test/controllers/SessionDataControllerISpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -177,4 +177,14 @@ class SessionDataControllerISpec extends ComponentSpecBase with FeatureSwitching
}
}
}

s"DELETE ${controllers.routes.SessionDataController.deleteAllSessionData.url}" should {
"return OK and remove the entire document related to the user in mongo" when {
"the sessionId exists in mongo for the user" in {
AuthStub.stubAuthSuccess()
await(repository.insert(testDocumentAll))
IncomeTaxSubscription.deleteAllSessionData should have(httpStatus(OK))
}
}
}
}
3 changes: 3 additions & 0 deletions it/test/helpers/ComponentSpecBase.scala
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ trait ComponentSpecBase extends AnyWordSpecLike
def deleteSessionData(id:String): WSResponse =
authorisedClient(s"/session-data/id/$id").delete().futureValue

def deleteAllSessionData(): WSResponse =
authorisedClient(s"/session-data/id").delete().futureValue

def insertSessionData(id:String, body: JsObject): WSResponse =
authorisedClient(s"/session-data/id/$id", "Content-Type" -> "application/json").post(body.toString()).futureValue

Expand Down
21 changes: 21 additions & 0 deletions it/test/repositories/SessionDataRepositorySpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package repositories

import helpers.IntegrationTestConstants.testArn
import org.scalatest.concurrent.ScalaFutures.convertScalaFuture
import org.scalatest.matchers.must.Matchers.convertToAnyMustWrapper
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpecLike
import org.scalatest.{BeforeAndAfterEach, OptionValues}
Expand Down Expand Up @@ -154,6 +155,26 @@ class SessionDataRepositorySpec extends AnyWordSpecLike with Matchers with Optio
}
}

"deleteDataBySessionId" when {
"the document was found" should {
"delete the entire document" in new Setup(testDocument()) {
testSessionDataRepository.deleteDataBySessionId(testSessionId).futureValue.map(_ \ "session-id").flatMap(_.asOpt[String]) shouldBe Some(testSessionId)

val optionalData: Option[JsValue] = testSessionDataRepository.getSessionData(testSessionId).futureValue
optionalData shouldBe None
}
}

"the document is not found" should {
"return no document" in new Setup(testDocument("testSessionIdTwo")) {
testSessionDataRepository.deleteDataBySessionId(testSessionId).futureValue shouldBe None

val optionalData: Option[JsValue] = testSessionDataRepository.getSessionData("testSessionIdTwo").futureValue
optionalData.isDefined shouldBe true
}
}
}

"the document is not found" should {
"return no document" in new Setup(testDocument()) {
testSessionDataRepository.deleteDataWithSession(testSessionId + "-2", "testDataIdOne").futureValue shouldBe None
Expand Down
15 changes: 15 additions & 0 deletions test/services/SessionDataServiceSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,19 @@ class SessionDataServiceSpec extends CommonSpec with MockitoSugar with FeatureSw
}
}

"deleteAllSessionData" should {
"delete session using sessionId" in new Setup {

when(mockSessionDataRepository.deleteDataBySessionId(ArgumentMatchers.eq(testSessionId)))
.thenReturn(Future.successful(Some(testJson)))

await(service.deleteAllSessionData(headerCarrier)) shouldBe Some(testJson)
}
"throw an internal server exception when no session id exists" in new Setup {
intercept[InternalServerException](
await(service.deleteAllSessionData(headerCarrierWithOutSessionId))
).message shouldBe errorMessage
}
}

}