From 8ed5caa41b04e3d15f3c381ec9c0ddf5fc5a7ee1 Mon Sep 17 00:00:00 2001 From: Tristan Garwood Date: Fri, 13 Oct 2023 12:42:29 -0400 Subject: [PATCH] Add test cases and modify test conf. --- .../sam/dataAccess/DirectoryDAO.scala | 3 +- .../sam/dataAccess/PostgresDirectoryDAO.scala | 2 +- .../workbench/sam/service/TosService.scala | 4 +- src/test/resources/reference.conf | 2 + .../workbench/sam/api/TestSamRoutes.scala | 5 +- .../sam/dataAccess/MockDirectoryDAO.scala | 9 +- .../dataAccess/PostgresDirectoryDAOSpec.scala | 10 +- .../sam/service/TosServiceSpec.scala | 163 ++++++++++++++++-- 8 files changed, 171 insertions(+), 27 deletions(-) diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/DirectoryDAO.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/DirectoryDAO.scala index d62cd34ac..d1581a7a0 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/DirectoryDAO.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/DirectoryDAO.scala @@ -75,9 +75,8 @@ trait DirectoryDAO { def acceptTermsOfService(userId: WorkbenchUserId, tosVersion: String, samRequestContext: SamRequestContext): IO[Boolean] def rejectTermsOfService(userId: WorkbenchUserId, tosVersion: String, samRequestContext: SamRequestContext): IO[Boolean] - def getLatestUserTos(userId: WorkbenchUserId, samRequestContext: SamRequestContext): IO[Option[SamUserTos]] + def getUserTos(userId: WorkbenchUserId, samRequestContext: SamRequestContext): IO[Option[SamUserTos]] def getUserTos(userId: WorkbenchUserId, tosVersion: String, samRequestContext: SamRequestContext): IO[Option[SamUserTos]] - def createPetManagedIdentity(petManagedIdentity: PetManagedIdentity, samRequestContext: SamRequestContext): IO[PetManagedIdentity] def loadPetManagedIdentity(petManagedIdentityId: PetManagedIdentityId, samRequestContext: SamRequestContext): IO[Option[PetManagedIdentity]] def getUserFromPetManagedIdentity(petManagedIdentityObjectId: ManagedIdentityObjectId, samRequestContext: SamRequestContext): IO[Option[SamUser]] diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/PostgresDirectoryDAO.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/PostgresDirectoryDAO.scala index 5d0e57aa3..34715ce8a 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/PostgresDirectoryDAO.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/PostgresDirectoryDAO.scala @@ -647,7 +647,7 @@ class PostgresDirectoryDAO(protected val writeDbRef: DbReference, protected val } } - override def getLatestUserTos(userId: WorkbenchUserId, samRequestContext: SamRequestContext): IO[Option[SamUserTos]] = + override def getUserTos(userId: WorkbenchUserId, samRequestContext: SamRequestContext): IO[Option[SamUserTos]] = readOnlyTransaction("getLatestUserTos", samRequestContext) { implicit session => val tosTable = TosTable.syntax val column = TosTable.column diff --git a/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/TosService.scala b/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/TosService.scala index 5dc199843..b1e0d84e4 100644 --- a/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/TosService.scala +++ b/src/main/scala/org/broadinstitute/dsde/workbench/sam/service/TosService.scala @@ -47,12 +47,12 @@ class TosService(val directoryDao: DirectoryDAO, val tosConfig: TermsOfServiceCo @Deprecated def getTosDetails(samUser: SamUser, samRequestContext: SamRequestContext): IO[TermsOfServiceDetails] = - directoryDao.getLatestUserTos(samUser.id, samRequestContext).map { tos => + directoryDao.getUserTos(samUser.id, samRequestContext).map { tos => TermsOfServiceDetails(isEnabled = true, tosConfig.isGracePeriodEnabled, tosConfig.version, tos.map(_.version)) } def getTosComplianceStatus(samUser: SamUser, samRequestContext: SamRequestContext): IO[TermsOfServiceComplianceStatus] = for { - latestUserTos <- directoryDao.getLatestUserTos(samUser.id, samRequestContext) + latestUserTos <- directoryDao.getUserTos(samUser.id, samRequestContext) previousUserTos <- directoryDao.getUserTos(samUser.id, tosConfig.rollingAcceptanceWindowPreviousTosVersion, samRequestContext) userHasAcceptedLatestVersion = userHasAcceptedLatestTosVersion(latestUserTos) permitsSystemUsage = tosAcceptancePermitsSystemUsage(samUser, latestUserTos, previousUserTos) diff --git a/src/test/resources/reference.conf b/src/test/resources/reference.conf index 4d95e02b2..d0963f957 100644 --- a/src/test/resources/reference.conf +++ b/src/test/resources/reference.conf @@ -62,6 +62,8 @@ termsOfService { enabled = false version = 1 url = "app.terra.bio/#terms-of-service" + rollingAcceptanceWindowExpirationDatetime = "2019-01-01T00:00:00Z" + rollingAcceptanceWindowPreviousTosVersion = 0 } petServiceAccount { diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/TestSamRoutes.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/TestSamRoutes.scala index 9ad9e0af7..b5badfaf1 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/TestSamRoutes.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/api/TestSamRoutes.scala @@ -24,6 +24,7 @@ import org.broadinstitute.dsde.workbench.sam.util.SamRequestContext import org.broadinstitute.dsde.workbench.sam.{Generator, TestSupport} import org.scalatest.concurrent.ScalaFutures +import java.time.Instant import scala.concurrent.ExecutionContext /** Created by dvoet on 7/14/17. @@ -49,7 +50,7 @@ class TestSamRoutes( userService, statusService, managedGroupService, - TermsOfServiceConfig(true, false, "0", "app.terra.bio/#terms-of-service"), + TermsOfServiceConfig(true, false, "0", "app.terra.bio/#terms-of-service", Instant.now(), "0"), policyEvaluatorService, tosService, LiquibaseConfig("", false), @@ -91,7 +92,7 @@ class TestSamTosEnabledRoutes( userService, statusService, managedGroupService, - TermsOfServiceConfig(true, false, "0", "app.terra.bio/#terms-of-service"), + TermsOfServiceConfig(true, false, "0", "app.terra.bio/#terms-of-service", Instant.now(), "0"), policyEvaluatorService, tosService, LiquibaseConfig("", false), diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/MockDirectoryDAO.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/MockDirectoryDAO.scala index 3472df795..a50b7020e 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/MockDirectoryDAO.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/MockDirectoryDAO.scala @@ -340,7 +340,14 @@ class MockDirectoryDAO(val groups: mutable.Map[WorkbenchGroupIdentity, Workbench true } - override def getLatestUserTos(userId: WorkbenchUserId, samRequestContext: SamRequestContext): IO[Option[SamUserTos]] = + override def getUserTos(userId: WorkbenchUserId, samRequestContext: SamRequestContext): IO[Option[SamUserTos]] = + loadUser(userId, samRequestContext).map { + case None => None + case Some(_) => + userTos.get(userId) + } + + override def getUserTos(userId: WorkbenchUserId, tosVersion: String, samRequestContext: SamRequestContext): IO[Option[SamUserTos]] = loadUser(userId, samRequestContext).map { case None => None case Some(_) => diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/PostgresDirectoryDAOSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/PostgresDirectoryDAOSpec.scala index da09d7617..123b12003 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/PostgresDirectoryDAOSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/dataAccess/PostgresDirectoryDAOSpec.scala @@ -1486,7 +1486,7 @@ class PostgresDirectoryDAOSpec extends RetryableAnyFreeSpec with Matchers with B dao.acceptTermsOfService(defaultUser.id, tosConfig.version, samRequestContext).unsafeRunSync() shouldBe true // Assert - val userTos = dao.getLatestUserTos(defaultUser.id, samRequestContext).unsafeRunSync() + val userTos = dao.getUserTos(defaultUser.id, samRequestContext).unsafeRunSync() userTos should not be empty userTos.get.createdAt should beAround(Instant.now()) userTos.get.action shouldBe TosTable.ACCEPT @@ -1501,7 +1501,7 @@ class PostgresDirectoryDAOSpec extends RetryableAnyFreeSpec with Matchers with B dao.acceptTermsOfService(defaultUser.id, "2", samRequestContext).unsafeRunSync() shouldBe true // Assert - val userTos = dao.getLatestUserTos(defaultUser.id, samRequestContext).unsafeRunSync() + val userTos = dao.getUserTos(defaultUser.id, samRequestContext).unsafeRunSync() userTos should not be empty userTos.get.createdAt should beAround(Instant.now()) userTos.get.action shouldBe TosTable.ACCEPT @@ -1516,7 +1516,7 @@ class PostgresDirectoryDAOSpec extends RetryableAnyFreeSpec with Matchers with B dao.rejectTermsOfService(user.id, tosConfig.version, samRequestContext).unsafeRunSync() shouldBe true // Assert - val userTos = dao.getLatestUserTos(user.id, samRequestContext).unsafeRunSync() + val userTos = dao.getUserTos(user.id, samRequestContext).unsafeRunSync() userTos should not be empty userTos.get.createdAt should beAround(Instant.now()) userTos.get.action shouldBe TosTable.REJECT @@ -1530,7 +1530,7 @@ class PostgresDirectoryDAOSpec extends RetryableAnyFreeSpec with Matchers with B dao.rejectTermsOfService(user.id, tosConfig.version, samRequestContext).unsafeRunSync() shouldBe true // Assert - val userTos = dao.getLatestUserTos(user.id, samRequestContext).unsafeRunSync() + val userTos = dao.getUserTos(user.id, samRequestContext).unsafeRunSync() userTos should not be empty userTos.get.createdAt should beAround(Instant.now()) userTos.get.action shouldBe TosTable.REJECT @@ -1544,7 +1544,7 @@ class PostgresDirectoryDAOSpec extends RetryableAnyFreeSpec with Matchers with B dao.createUser(user, samRequestContext).unsafeRunSync() // Assert - val userTos = dao.getLatestUserTos(user.id, samRequestContext).unsafeRunSync() + val userTos = dao.getUserTos(user.id, samRequestContext).unsafeRunSync() userTos should be(None) } } diff --git a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/TosServiceSpec.scala b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/TosServiceSpec.scala index 7f6b56828..7a9d2c26c 100644 --- a/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/TosServiceSpec.scala +++ b/src/test/scala/org/broadinstitute/dsde/workbench/sam/service/TosServiceSpec.scala @@ -87,8 +87,12 @@ class TosServiceSpec(_system: ActorSystem) val tosVersion = "2" val tosService = new TosService(dirDAO, TestSupport.tosConfig.copy(version = tosVersion)) - when(dirDAO.getLatestUserTos(serviceAccountUser.id, samRequestContext)) + when(dirDAO.getUserTos(serviceAccountUser.id, samRequestContext)) .thenReturn(IO.pure(Some(SamUserTos(serviceAccountUser.id, tosVersion, TosTable.ACCEPT, Instant.now())))) + + when(dirDAO.getUserTos(serviceAccountUser.id, "0", samRequestContext)) + .thenReturn(IO.pure(Some(SamUserTos(serviceAccountUser.id, tosVersion, TosTable.ACCEPT, Instant.now())))) + val complianceStatus = tosService.getTosComplianceStatus(serviceAccountUser, samRequestContext).unsafeRunSync() complianceStatus.permitsSystemUsage shouldBe true } @@ -100,13 +104,18 @@ class TosServiceSpec(_system: ActorSystem) } val tosVersion = "2" + val rollingAcceptanceWindowPreviousTosVersion = "0" val withoutGracePeriod = "without the grace period enabled" val withGracePeriod = " with the grace period enabled" + val withoutRollingAcceptanceWindow = "outside of the rolling acceptance window" + val withRollingAcceptanceWindow = " inside of the rolling acceptance window" val cannotUseTheSystem = "says the user cannot use the system" val canUseTheSystem = "says the user can use the system" val tosServiceV2 = new TosService(dirDAO, TestSupport.tosConfig.copy(version = tosVersion)) val tosServiceV2GracePeriodEnabled = new TosService(dirDAO, TestSupport.tosConfig.copy(version = tosVersion, isGracePeriodEnabled = true)) + val tosServiceV2AcceptanceWindowEnabled = new TosService(dirDAO, TestSupport.tosConfig.copy(isTosEnabled=true, isGracePeriodEnabled=false, version = tosVersion, rollingAcceptanceWindowExpiration = Instant.now().plusSeconds(3600), rollingAcceptanceWindowPreviousTosVersion = rollingAcceptanceWindowPreviousTosVersion)) + /** | Case | Grace Period Enabled | Accepted Version | Current Version | User accepted latest | Permits system usage | * |:-----|:---------------------|:-----------------|:----------------|:---------------------|:---------------------| @@ -120,14 +129,19 @@ class TosServiceSpec(_system: ActorSystem) "when the user has not accepted any ToS version" - { "says the user has not accepted the latest version" in { - when(dirDAO.getLatestUserTos(defaultUser.id, samRequestContext)) + when(dirDAO.getUserTos(defaultUser.id, samRequestContext)) + .thenReturn(IO.pure(None)) + when(dirDAO.getUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, samRequestContext)) .thenReturn(IO.pure(None)) + val complianceStatus = tosServiceV2.getTosComplianceStatus(defaultUser, samRequestContext).unsafeRunSync() complianceStatus.userHasAcceptedLatestTos shouldBe false } withoutGracePeriod - { cannotUseTheSystem in { - when(dirDAO.getLatestUserTos(defaultUser.id, samRequestContext)) + when(dirDAO.getUserTos(defaultUser.id, samRequestContext)) + .thenReturn(IO.pure(None)) + when(dirDAO.getUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, samRequestContext)) .thenReturn(IO.pure(None)) // CASE 1 val complianceStatus = tosServiceV2.getTosComplianceStatus(defaultUser, samRequestContext).unsafeRunSync() @@ -136,25 +150,53 @@ class TosServiceSpec(_system: ActorSystem) } withGracePeriod - { cannotUseTheSystem in { - when(dirDAO.getLatestUserTos(defaultUser.id, samRequestContext)) + when(dirDAO.getUserTos(defaultUser.id, samRequestContext)) + .thenReturn(IO.pure(None)) + when(dirDAO.getUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, samRequestContext)) .thenReturn(IO.pure(None)) // CASE 4 val complianceStatus = tosServiceV2GracePeriodEnabled.getTosComplianceStatus(defaultUser, samRequestContext).unsafeRunSync() complianceStatus.permitsSystemUsage shouldBe false } } + withRollingAcceptanceWindow - { + cannotUseTheSystem in { + when(dirDAO.getUserTos(defaultUser.id, samRequestContext)) + .thenReturn(IO.pure(None)) + when(dirDAO.getUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, samRequestContext)) + .thenReturn(IO.pure(None)) + // CASE 1 + val complianceStatus = tosServiceV2AcceptanceWindowEnabled.getTosComplianceStatus(defaultUser, samRequestContext).unsafeRunSync() + complianceStatus.permitsSystemUsage shouldBe false + } + } + withoutRollingAcceptanceWindow - { + cannotUseTheSystem in { + when(dirDAO.getUserTos(defaultUser.id, samRequestContext)) + .thenReturn(IO.pure(None)) + when(dirDAO.getUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, samRequestContext)) + .thenReturn(IO.pure(None)) + // CASE 4 + val complianceStatus = tosServiceV2.getTosComplianceStatus(defaultUser, samRequestContext).unsafeRunSync() + complianceStatus.permitsSystemUsage shouldBe false + } + } } "when the user has accepted a non-current ToS version" - { "says the user has not accepted the latest version" in { - when(dirDAO.getLatestUserTos(defaultUser.id, samRequestContext)) + when(dirDAO.getUserTos(defaultUser.id, samRequestContext)) .thenReturn(IO.pure(None)) + when(dirDAO.getUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, TosTable.ACCEPT, Instant.now())))) val complianceStatus = tosServiceV2.getTosComplianceStatus(defaultUser, samRequestContext).unsafeRunSync() complianceStatus.userHasAcceptedLatestTos shouldBe false } withoutGracePeriod - { cannotUseTheSystem in { - when(dirDAO.getLatestUserTos(defaultUser.id, samRequestContext)) + when(dirDAO.getUserTos(defaultUser.id, samRequestContext)) .thenReturn(IO.pure(None)) + when(dirDAO.getUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, TosTable.ACCEPT, Instant.now())))) // CASE 2 val complianceStatus = tosServiceV2.getTosComplianceStatus(defaultUser, samRequestContext).unsafeRunSync() complianceStatus.permitsSystemUsage shouldBe false @@ -162,25 +204,64 @@ class TosServiceSpec(_system: ActorSystem) } withGracePeriod - { canUseTheSystem in { - when(dirDAO.getLatestUserTos(defaultUser.id, samRequestContext)) + when(dirDAO.getUserTos(defaultUser.id, samRequestContext)) .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, tosVersion, TosTable.ACCEPT, Instant.now())))) + when(dirDAO.getUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, TosTable.ACCEPT, Instant.now())))) // CASE 5 val complianceStatus = tosServiceV2GracePeriodEnabled.getTosComplianceStatus(defaultUser, samRequestContext).unsafeRunSync() complianceStatus.permitsSystemUsage shouldBe true } } + withRollingAcceptanceWindow - { + canUseTheSystem in { + when(dirDAO.getUserTos(defaultUser.id, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, TosTable.ACCEPT, Instant.now())))) + when(dirDAO.getUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, TosTable.ACCEPT, Instant.now())))) + // CASE 1 + val complianceStatus = tosServiceV2AcceptanceWindowEnabled.getTosComplianceStatus(defaultUser, samRequestContext).unsafeRunSync() + complianceStatus.permitsSystemUsage shouldBe true + } + } + withRollingAcceptanceWindow - { + cannotUseTheSystem in { + when(dirDAO.getUserTos(defaultUser.id, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, TosTable.ACCEPT, Instant.now())))) + when(dirDAO.getUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, TosTable.ACCEPT, Instant.now())))) + // CASE 1 + val complianceStatus = tosServiceV2AcceptanceWindowEnabled.getTosComplianceStatus(defaultUser, samRequestContext).unsafeRunSync() + complianceStatus.permitsSystemUsage shouldBe true + } + } + withoutRollingAcceptanceWindow - { + cannotUseTheSystem in { + when(dirDAO.getUserTos(defaultUser.id, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, TosTable.ACCEPT, Instant.now())))) + when(dirDAO.getUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, TosTable.ACCEPT, Instant.now())))) + // CASE 4 + val complianceStatus = tosServiceV2.getTosComplianceStatus(defaultUser, samRequestContext).unsafeRunSync() + complianceStatus.permitsSystemUsage shouldBe false + } + } } "when the user has accepted the current ToS version" - { "says the user has accepted the latest version" in { - when(dirDAO.getLatestUserTos(defaultUser.id, samRequestContext)) + when(dirDAO.getUserTos(defaultUser.id, samRequestContext)) .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, tosVersion, TosTable.ACCEPT, Instant.now())))) + when(dirDAO.getUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, TosTable.ACCEPT, Instant.now())))) val complianceStatus = tosServiceV2.getTosComplianceStatus(defaultUser, samRequestContext).unsafeRunSync() complianceStatus.userHasAcceptedLatestTos shouldBe true } withoutGracePeriod - { canUseTheSystem in { - when(dirDAO.getLatestUserTos(defaultUser.id, samRequestContext)) + when(dirDAO.getUserTos(defaultUser.id, samRequestContext)) .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, tosVersion, TosTable.ACCEPT, Instant.now())))) + when(dirDAO.getUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, TosTable.ACCEPT, Instant.now())))) // CASE 3 val complianceStatus = tosServiceV2.getTosComplianceStatus(defaultUser, samRequestContext).unsafeRunSync() complianceStatus.permitsSystemUsage shouldBe true @@ -188,26 +269,54 @@ class TosServiceSpec(_system: ActorSystem) } withGracePeriod - { canUseTheSystem in { - when(dirDAO.getLatestUserTos(defaultUser.id, samRequestContext)) + when(dirDAO.getUserTos(defaultUser.id, samRequestContext)) .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, tosVersion, TosTable.ACCEPT, Instant.now())))) + when(dirDAO.getUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, TosTable.ACCEPT, Instant.now())))) // CASE 6 val complianceStatus = tosServiceV2GracePeriodEnabled.getTosComplianceStatus(defaultUser, samRequestContext).unsafeRunSync() complianceStatus.permitsSystemUsage shouldBe true } } + withRollingAcceptanceWindow - { + canUseTheSystem in { + when(dirDAO.getUserTos(defaultUser.id, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, tosVersion, TosTable.ACCEPT, Instant.now())))) + when(dirDAO.getUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, TosTable.ACCEPT, Instant.now())))) + // CASE 1 + val complianceStatus = tosServiceV2AcceptanceWindowEnabled.getTosComplianceStatus(defaultUser, samRequestContext).unsafeRunSync() + complianceStatus.permitsSystemUsage shouldBe true + } + } + withoutRollingAcceptanceWindow - { + canUseTheSystem in { + when(dirDAO.getUserTos(defaultUser.id, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, tosVersion, TosTable.ACCEPT, Instant.now())))) + when(dirDAO.getUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, TosTable.ACCEPT, Instant.now())))) + // CASE 4 + val complianceStatus = tosServiceV2.getTosComplianceStatus(defaultUser, samRequestContext).unsafeRunSync() + complianceStatus.permitsSystemUsage shouldBe true + } + } } "when the user has rejected the latest ToS version" - { "says the user has rejected the latest version" in { - when(dirDAO.getLatestUserTos(defaultUser.id, samRequestContext)) + when(dirDAO.getUserTos(defaultUser.id, samRequestContext)) .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, tosVersion, TosTable.REJECT, Instant.now())))) + when(dirDAO.getUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, TosTable.ACCEPT, Instant.now())))) val complianceStatus = tosServiceV2.getTosComplianceStatus(defaultUser, samRequestContext).unsafeRunSync() complianceStatus.userHasAcceptedLatestTos shouldBe false } withoutGracePeriod - { cannotUseTheSystem in { - when(dirDAO.getLatestUserTos(defaultUser.id, samRequestContext)) + when(dirDAO.getUserTos(defaultUser.id, samRequestContext)) .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, tosVersion, TosTable.REJECT, Instant.now())))) + when(dirDAO.getUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, TosTable.ACCEPT, Instant.now())))) // CASE 1 val complianceStatus = tosServiceV2.getTosComplianceStatus(defaultUser, samRequestContext).unsafeRunSync() complianceStatus.permitsSystemUsage shouldBe false @@ -215,17 +324,43 @@ class TosServiceSpec(_system: ActorSystem) } withGracePeriod - { cannotUseTheSystem in { - when(dirDAO.getLatestUserTos(defaultUser.id, samRequestContext)) + when(dirDAO.getUserTos(defaultUser.id, samRequestContext)) .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, tosVersion, TosTable.REJECT, Instant.now())))) + when(dirDAO.getUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, TosTable.ACCEPT, Instant.now())))) // CASE 4 val complianceStatus = tosServiceV2GracePeriodEnabled.getTosComplianceStatus(defaultUser, samRequestContext).unsafeRunSync() complianceStatus.permitsSystemUsage shouldBe false } } + withRollingAcceptanceWindow - { + canUseTheSystem in { + when(dirDAO.getUserTos(defaultUser.id, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, tosVersion, TosTable.REJECT, Instant.now())))) + when(dirDAO.getUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, TosTable.ACCEPT, Instant.now())))) + // CASE 1 + val complianceStatus = tosServiceV2AcceptanceWindowEnabled.getTosComplianceStatus(defaultUser, samRequestContext).unsafeRunSync() + complianceStatus.permitsSystemUsage shouldBe true + } + } + withoutRollingAcceptanceWindow - { + cannotUseTheSystem in { + when(dirDAO.getUserTos(defaultUser.id, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, tosVersion, TosTable.REJECT, Instant.now())))) + when(dirDAO.getUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, samRequestContext)) + .thenReturn(IO.pure(Option(SamUserTos(defaultUser.id, rollingAcceptanceWindowPreviousTosVersion, TosTable.ACCEPT, Instant.now())))) + // CASE 4 + val complianceStatus = tosServiceV2.getTosComplianceStatus(defaultUser, samRequestContext).unsafeRunSync() + complianceStatus.permitsSystemUsage shouldBe false + } + } } "when a service account is using the api" - { "let it use the api regardless of tos status" in { - when(dirDAO.getLatestUserTos(serviceAccountUser.id, samRequestContext)) + when(dirDAO.getUserTos(serviceAccountUser.id, samRequestContext)) + .thenReturn(IO.pure(None)) + when(dirDAO.getUserTos(serviceAccountUser.id, rollingAcceptanceWindowPreviousTosVersion, samRequestContext)) .thenReturn(IO.pure(None)) val complianceStatus = tosServiceV2.getTosComplianceStatus(serviceAccountUser, samRequestContext).unsafeRunSync() complianceStatus.permitsSystemUsage shouldBe true