~jan0sch/smederee
Showing details for patch 6093191a3eabd73f47364101273aacd8168399e5.
diff -rN -u old-smederee/modules/hub/src/test/scala/de/smederee/hub/DoobieResetPasswordRepositoryTest.scala new-smederee/modules/hub/src/test/scala/de/smederee/hub/DoobieResetPasswordRepositoryTest.scala --- old-smederee/modules/hub/src/test/scala/de/smederee/hub/DoobieResetPasswordRepositoryTest.scala 2025-01-11 00:11:03.798376581 +0000 +++ new-smederee/modules/hub/src/test/scala/de/smederee/hub/DoobieResetPasswordRepositoryTest.scala 2025-01-11 00:11:03.798376581 +0000 @@ -13,12 +13,16 @@ import cats.effect.* import cats.syntax.all.* import de.smederee.TestTags.* -import de.smederee.hub.Generators.* +import de.smederee.hub.Generators.given import de.smederee.security.* import doobie.* import org.flywaydb.core.Flyway +import org.scalacheck.effect.PropF + final class DoobieResetPasswordRepositoryTest extends BaseSpec { + override def scalaCheckTestParameters = super.scalaCheckTestParameters.withMinSuccessfulTests(1) + override def beforeEach(context: BeforeEach): Unit = { val dbConfig = configuration.database val flyway: Flyway = @@ -37,248 +41,230 @@ } test("findByNameAndResetPasswordToken must find a matching account".tag(NeedsDatabase)) { - genValidAccount.sample match { - case Some(user) => - val token = ResetToken.generate - val tokenExpiration = OffsetDateTime.now(ZoneOffset.UTC).plusDays(3L) - val expected = user.copy(language = None) - val dbConfig = configuration.database - val tx = Transactor.fromDriverManager[IO]( - driver = dbConfig.driver, - url = dbConfig.url, - user = dbConfig.user, - password = dbConfig.pass, - logHandler = None - ) - val repo = new DoobieResetPasswordRepository[IO](tx) - val test = for { - _ <- createAccount(user, PasswordHash("I am not a password hash!"), None, None) - _ <- repo.setResetPasswordToken(user.uid)(token, tokenExpiration) - _ <- repo.removeResetPasswordExpirationDate(user.uid) - result <- repo.findByNameAndResetPasswordToken(user.name, token) - } yield result - test.map { result => - assertEquals(result, Option(expected)) - } - case _ => fail("Could not generate data samples!") + PropF.forAllF { (user: Account) => + val token = ResetToken.generate + val tokenExpiration = OffsetDateTime.now(ZoneOffset.UTC).plusDays(3L) + val expected = user.copy(language = None) + val dbConfig = configuration.database + val tx = Transactor.fromDriverManager[IO]( + driver = dbConfig.driver, + url = dbConfig.url, + user = dbConfig.user, + password = dbConfig.pass, + logHandler = None + ) + val repo = new DoobieResetPasswordRepository[IO](tx) + val test = for { + _ <- createAccount(user, PasswordHash("I am not a password hash!"), None, None) + _ <- repo.setResetPasswordToken(user.uid)(token, tokenExpiration) + _ <- repo.removeResetPasswordExpirationDate(user.uid) + result <- repo.findByNameAndResetPasswordToken(user.name, token) + } yield result + test.start.flatMap(_.joinWithNever).map { result => + assertEquals(result, Option(expected)) + } } } test("findByNameAndResetPasswordToken must not respect tokens with expiration date".tag(NeedsDatabase)) { - genValidAccount.sample match { - case Some(user) => - val token = ResetToken.generate - val tokenExpiration = OffsetDateTime.now(ZoneOffset.UTC).plusDays(3L) - val dbConfig = configuration.database - val tx = Transactor.fromDriverManager[IO]( - driver = dbConfig.driver, - url = dbConfig.url, - user = dbConfig.user, - password = dbConfig.pass, - logHandler = None - ) - val repo = new DoobieResetPasswordRepository[IO](tx) - val test = for { - _ <- createAccount(user, PasswordHash("I am not a password hash!"), None, None) - _ <- repo.setResetPasswordToken(user.uid)(token, tokenExpiration) - result <- repo.findByNameAndResetPasswordToken(user.name, token) - } yield result - test.map { result => - assertEquals(result, None) - } - case _ => fail("Could not generate data samples!") + PropF.forAllF { (user: Account) => + val token = ResetToken.generate + val tokenExpiration = OffsetDateTime.now(ZoneOffset.UTC).plusDays(3L) + val dbConfig = configuration.database + val tx = Transactor.fromDriverManager[IO]( + driver = dbConfig.driver, + url = dbConfig.url, + user = dbConfig.user, + password = dbConfig.pass, + logHandler = None + ) + val repo = new DoobieResetPasswordRepository[IO](tx) + val test = for { + _ <- createAccount(user, PasswordHash("I am not a password hash!"), None, None) + _ <- repo.setResetPasswordToken(user.uid)(token, tokenExpiration) + result <- repo.findByNameAndResetPasswordToken(user.name, token) + } yield result + test.start.flatMap(_.joinWithNever).map { result => + assertEquals(result, None) + } } } test("findByResetPasswordToken must find a matching account".tag(NeedsDatabase)) { - genValidAccount.sample match { - case Some(user) => - val token = ResetToken.generate - val tokenExpiration = OffsetDateTime.now(ZoneOffset.UTC).plusDays(3L) - val expected = user.copy(language = None) - val dbConfig = configuration.database - val tx = Transactor.fromDriverManager[IO]( - driver = dbConfig.driver, - url = dbConfig.url, - user = dbConfig.user, - password = dbConfig.pass, - logHandler = None - ) - val repo = new DoobieResetPasswordRepository[IO](tx) - val test = for { - _ <- createAccount(user, PasswordHash("I am not a password hash!"), None, None) - _ <- repo.setResetPasswordToken(user.uid)(token, tokenExpiration) - result <- repo.findByResetPasswordToken(token) - } yield result - test.map { result => - assertEquals(result, Option(expected)) - } - case _ => fail("Could not generate data samples!") + PropF.forAllF { (user: Account) => + val token = ResetToken.generate + val tokenExpiration = OffsetDateTime.now(ZoneOffset.UTC).plusDays(3L) + val expected = user.copy(language = None) + val dbConfig = configuration.database + val tx = Transactor.fromDriverManager[IO]( + driver = dbConfig.driver, + url = dbConfig.url, + user = dbConfig.user, + password = dbConfig.pass, + logHandler = None + ) + val repo = new DoobieResetPasswordRepository[IO](tx) + val test = for { + _ <- createAccount(user, PasswordHash("I am not a password hash!"), None, None) + _ <- repo.setResetPasswordToken(user.uid)(token, tokenExpiration) + result <- repo.findByResetPasswordToken(token) + } yield result + test.start.flatMap(_.joinWithNever).map { result => + assertEquals(result, Option(expected)) + } } } test("findByResetPasswordToken must not return accounts with expired tokens".tag(NeedsDatabase)) { - genValidAccount.sample match { - case Some(user) => - val token = ResetToken.generate - val tokenExpiration = OffsetDateTime.now(ZoneOffset.UTC).minusDays(3L) - val dbConfig = configuration.database - val tx = Transactor.fromDriverManager[IO]( - driver = dbConfig.driver, - url = dbConfig.url, - user = dbConfig.user, - password = dbConfig.pass, - logHandler = None - ) - val repo = new DoobieResetPasswordRepository[IO](tx) - val test = for { - _ <- createAccount(user, PasswordHash("I am not a password hash!"), None, None) - _ <- repo.setResetPasswordToken(user.uid)(token, tokenExpiration) - result <- repo.findByResetPasswordToken(token) - } yield result - test.map { result => - assertEquals(result, None) - } - case _ => fail("Could not generate data samples!") + PropF.forAllF { (user: Account) => + val token = ResetToken.generate + val tokenExpiration = OffsetDateTime.now(ZoneOffset.UTC).minusDays(3L) + val dbConfig = configuration.database + val tx = Transactor.fromDriverManager[IO]( + driver = dbConfig.driver, + url = dbConfig.url, + user = dbConfig.user, + password = dbConfig.pass, + logHandler = None + ) + val repo = new DoobieResetPasswordRepository[IO](tx) + val test = for { + _ <- createAccount(user, PasswordHash("I am not a password hash!"), None, None) + _ <- repo.setResetPasswordToken(user.uid)(token, tokenExpiration) + result <- repo.findByResetPasswordToken(token) + } yield result + test.start.flatMap(_.joinWithNever).map { result => + assertEquals(result, None) + } } } test("findByResetPasswordToken must not return accounts without expiration date".tag(NeedsDatabase)) { - genValidAccount.sample match { - case Some(user) => - val token = ResetToken.generate - val tokenExpiration = OffsetDateTime.now(ZoneOffset.UTC).minusDays(3L) - val dbConfig = configuration.database - val tx = Transactor.fromDriverManager[IO]( - driver = dbConfig.driver, - url = dbConfig.url, - user = dbConfig.user, - password = dbConfig.pass, - logHandler = None - ) - val repo = new DoobieResetPasswordRepository[IO](tx) - val test = for { - _ <- createAccount(user, PasswordHash("I am not a password hash!"), None, None) - _ <- repo.setResetPasswordToken(user.uid)(token, tokenExpiration) - _ <- repo.removeResetPasswordExpirationDate(user.uid) - result <- repo.findByResetPasswordToken(token) - } yield result - test.map { result => - assertEquals(result, None) - } - case _ => fail("Could not generate data samples!") + PropF.forAllF { (user: Account) => + val token = ResetToken.generate + val tokenExpiration = OffsetDateTime.now(ZoneOffset.UTC).minusDays(3L) + val dbConfig = configuration.database + val tx = Transactor.fromDriverManager[IO]( + driver = dbConfig.driver, + url = dbConfig.url, + user = dbConfig.user, + password = dbConfig.pass, + logHandler = None + ) + val repo = new DoobieResetPasswordRepository[IO](tx) + val test = for { + _ <- createAccount(user, PasswordHash("I am not a password hash!"), None, None) + _ <- repo.setResetPasswordToken(user.uid)(token, tokenExpiration) + _ <- repo.removeResetPasswordExpirationDate(user.uid) + result <- repo.findByResetPasswordToken(token) + } yield result + test.start.flatMap(_.joinWithNever).map { result => + assertEquals(result, None) + } } } test("removeResetPasswordExpirationDate must remove the expiration date".tag(NeedsDatabase)) { - genValidAccount.sample match { - case Some(user) => - val token = ResetToken.generate - val tokenExpiration = - OffsetDateTime.now(ZoneOffset.UTC).plusDays(3L).withNano(0) // Nanos are troublesome! - val expected = ((None, token.some)).some - val dbConfig = configuration.database - val tx = Transactor.fromDriverManager[IO]( - driver = dbConfig.driver, - url = dbConfig.url, - user = dbConfig.user, - password = dbConfig.pass, - logHandler = None - ) - val repo = new DoobieResetPasswordRepository[IO](tx) - val test = for { - _ <- createAccount(user, PasswordHash("I am not a password hash!"), None, None) - _ <- repo.setResetPasswordToken(user.uid)(token, tokenExpiration) - _ <- repo.removeResetPasswordExpirationDate(user.uid) - result <- loadResetColumns(user.uid) - } yield result - test.map { result => - assertEquals(result, expected) - } - case _ => fail("Could not generate data samples!") + PropF.forAllF { (user: Account) => + val token = ResetToken.generate + val tokenExpiration = + OffsetDateTime.now(ZoneOffset.UTC).plusDays(3L).withNano(0) // Nanos are troublesome! + val expected = ((None, token.some)).some + val dbConfig = configuration.database + val tx = Transactor.fromDriverManager[IO]( + driver = dbConfig.driver, + url = dbConfig.url, + user = dbConfig.user, + password = dbConfig.pass, + logHandler = None + ) + val repo = new DoobieResetPasswordRepository[IO](tx) + val test = for { + _ <- createAccount(user, PasswordHash("I am not a password hash!"), None, None) + _ <- repo.setResetPasswordToken(user.uid)(token, tokenExpiration) + _ <- repo.removeResetPasswordExpirationDate(user.uid) + result <- loadResetColumns(user.uid) + } yield result + test.start.flatMap(_.joinWithNever).map { result => + assertEquals(result, expected) + } } } test("removeResetPasswordToken must remove the token and the expiration date".tag(NeedsDatabase)) { - genValidAccount.sample match { - case Some(user) => - val token = ResetToken.generate - val tokenExpiration = - OffsetDateTime.now(ZoneOffset.UTC).plusDays(3L).withNano(0) // Nanos are troublesome! - val expected = ((None, None)).some - val dbConfig = configuration.database - val tx = Transactor.fromDriverManager[IO]( - driver = dbConfig.driver, - url = dbConfig.url, - user = dbConfig.user, - password = dbConfig.pass, - logHandler = None - ) - val repo = new DoobieResetPasswordRepository[IO](tx) - val test = for { - _ <- createAccount(user, PasswordHash("I am not a password hash!"), None, None) - _ <- repo.setResetPasswordToken(user.uid)(token, tokenExpiration) - _ <- repo.removeResetPasswordToken(user.uid) - result <- loadResetColumns(user.uid) - } yield result - test.map { result => - assertEquals(result, expected) - } - case _ => fail("Could not generate data samples!") + PropF.forAllF { (user: Account) => + val token = ResetToken.generate + val tokenExpiration = + OffsetDateTime.now(ZoneOffset.UTC).plusDays(3L).withNano(0) // Nanos are troublesome! + val expected = ((None, None)).some + val dbConfig = configuration.database + val tx = Transactor.fromDriverManager[IO]( + driver = dbConfig.driver, + url = dbConfig.url, + user = dbConfig.user, + password = dbConfig.pass, + logHandler = None + ) + val repo = new DoobieResetPasswordRepository[IO](tx) + val test = for { + _ <- createAccount(user, PasswordHash("I am not a password hash!"), None, None) + _ <- repo.setResetPasswordToken(user.uid)(token, tokenExpiration) + _ <- repo.removeResetPasswordToken(user.uid) + result <- loadResetColumns(user.uid) + } yield result + test.start.flatMap(_.joinWithNever).map { result => + assertEquals(result, expected) + } } } test("setPassword must set the password correctly".tag(NeedsDatabase)) { - genValidAccount.sample match { - case Some(user) => - val expected = - Password("This is not the password you're looking for!".getBytes(StandardCharsets.UTF_8)).encode - val dbConfig = configuration.database - val tx = Transactor.fromDriverManager[IO]( - driver = dbConfig.driver, - url = dbConfig.url, - user = dbConfig.user, - password = dbConfig.pass, - logHandler = None - ) - val repo = new DoobieResetPasswordRepository[IO](tx) - val test = for { - _ <- createAccount(user, PasswordHash("I am not a password hash!"), None, None) - _ <- repo.setPassword(user.uid)(expected) - result <- loadPasswordHash(user.uid) - } yield result - test.map { result => - assertEquals(result, expected.some) - } - case _ => fail("Could not generate data samples!") + PropF.forAllF { (user: Account) => + val expected = + Password("This is not the password you're looking for!".getBytes(StandardCharsets.UTF_8)).encode + val dbConfig = configuration.database + val tx = Transactor.fromDriverManager[IO]( + driver = dbConfig.driver, + url = dbConfig.url, + user = dbConfig.user, + password = dbConfig.pass, + logHandler = None + ) + val repo = new DoobieResetPasswordRepository[IO](tx) + val test = for { + _ <- createAccount(user, PasswordHash("I am not a password hash!"), None, None) + _ <- repo.setPassword(user.uid)(expected) + result <- loadPasswordHash(user.uid) + } yield result + test.start.flatMap(_.joinWithNever).map { result => + assertEquals(result, expected.some) + } } } test("setResetPasswordToken must set token and expiry date correctly".tag(NeedsDatabase)) { - genValidAccount.sample match { - case Some(user) => - val token = ResetToken.generate - val tokenExpiration = - OffsetDateTime.now(ZoneOffset.UTC).plusDays(3L).withNano(0) // Nanos are troublesome! - val expected = ((tokenExpiration.some, token.some)).some - val dbConfig = configuration.database - val tx = Transactor.fromDriverManager[IO]( - driver = dbConfig.driver, - url = dbConfig.url, - user = dbConfig.user, - password = dbConfig.pass, - logHandler = None - ) - val repo = new DoobieResetPasswordRepository[IO](tx) - val test = for { - _ <- createAccount(user, PasswordHash("I am not a password hash!"), None, None) - _ <- repo.setResetPasswordToken(user.uid)(token, tokenExpiration) - result <- loadResetColumns(user.uid) - } yield result - test.map { result => - assertEquals(result, expected) - } - case _ => fail("Could not generate data samples!") + PropF.forAllF { (user: Account) => + val token = ResetToken.generate + val tokenExpiration = + OffsetDateTime.now(ZoneOffset.UTC).plusDays(3L).withNano(0) // Nanos are troublesome! + val expected = ((tokenExpiration.some, token.some)).some + val dbConfig = configuration.database + val tx = Transactor.fromDriverManager[IO]( + driver = dbConfig.driver, + url = dbConfig.url, + user = dbConfig.user, + password = dbConfig.pass, + logHandler = None + ) + val repo = new DoobieResetPasswordRepository[IO](tx) + val test = for { + _ <- createAccount(user, PasswordHash("I am not a password hash!"), None, None) + _ <- repo.setResetPasswordToken(user.uid)(token, tokenExpiration) + result <- loadResetColumns(user.uid) + } yield result + test.start.flatMap(_.joinWithNever).map { result => + assertEquals(result, expected) + } } } }