~jan0sch/smederee
Showing details for patch f60e4679d9bae7f39bd0b8a124180a96454477a1.
diff -rN -u old-smederee/modules/hub/src/test/scala/de/smederee/tickets/DoobieProjectRepositoryTest.scala new-smederee/modules/hub/src/test/scala/de/smederee/tickets/DoobieProjectRepositoryTest.scala --- old-smederee/modules/hub/src/test/scala/de/smederee/tickets/DoobieProjectRepositoryTest.scala 2025-01-10 20:55:32.837211385 +0000 +++ new-smederee/modules/hub/src/test/scala/de/smederee/tickets/DoobieProjectRepositoryTest.scala 2025-01-10 20:55:32.837211385 +0000 @@ -6,211 +6,203 @@ package de.smederee.tickets +import cats.data.NonEmptyList import cats.effect.* import cats.syntax.all.* import de.smederee.TestTags.* -import de.smederee.tickets.Generators.* +import de.smederee.tickets.Generators.given import doobie.* +import org.scalacheck.effect.PropF + final class DoobieProjectRepositoryTest extends BaseSpec { + override def scalaCheckTestParameters = super.scalaCheckTestParameters.withMinSuccessfulTests(1) + test("createProject must create a project".tag(NeedsDatabase)) { - (genProjectOwner.sample, genProject.sample) match { - case (Some(owner), Some(generatedProject)) => - val project = generatedProject.copy(owner = owner) - val dbConfig = configuration.database - val tx = Transactor.fromDriverManager[IO]( - driver = dbConfig.driver, - url = dbConfig.url, - user = dbConfig.user, - password = dbConfig.pass, - logHandler = None - ) - val projectRepo = new DoobieProjectRepository[IO](tx) - val test = for { - _ <- createProjectOwner(owner) - _ <- projectRepo.createProject(project) - foundProject <- projectRepo.findProject(owner, project.name) - } yield foundProject - test.map { foundProject => - assertEquals(foundProject, Some(project)) - } - case _ => fail("Could not generate data samples!") + PropF.forAllF { (owner: ProjectOwner, generatedProject: Project) => + val project = generatedProject.copy(owner = owner) + val dbConfig = configuration.database + val tx = Transactor.fromDriverManager[IO]( + driver = dbConfig.driver, + url = dbConfig.url, + user = dbConfig.user, + password = dbConfig.pass, + logHandler = None + ) + val projectRepo = new DoobieProjectRepository[IO](tx) + val test = for { + _ <- createProjectOwner(owner) + _ <- projectRepo.createProject(project) + foundProject <- projectRepo.findProject(owner, project.name) + } yield foundProject + test.start.flatMap(_.joinWithNever).map { foundProject => + assertEquals(foundProject, Some(project)) + } } } test("deleteProject must delete a project".tag(NeedsDatabase)) { - (genProjectOwner.sample, genProject.sample) match { - case (Some(owner), Some(generatedProject)) => - val project = generatedProject.copy(owner = owner) - val dbConfig = configuration.database - val tx = Transactor.fromDriverManager[IO]( - driver = dbConfig.driver, - url = dbConfig.url, - user = dbConfig.user, - password = dbConfig.pass, - logHandler = None - ) - val projectRepo = new DoobieProjectRepository[IO](tx) - val test = for { - _ <- createProjectOwner(owner) - _ <- createTicketsProject(project) - deleted <- projectRepo.deleteProject(project) - foundProject <- projectRepo.findProject(owner, project.name) - } yield (deleted, foundProject) - test.map { result => - val (deleted, foundProject) = result - assert(deleted > 0, "Rows not deleted from database!") - assert(foundProject.isEmpty, "Project not deleted from database!") - } - case _ => fail("Could not generate data samples!") + PropF.forAllF { (owner: ProjectOwner, generatedProject: Project) => + val project = generatedProject.copy(owner = owner) + val dbConfig = configuration.database + val tx = Transactor.fromDriverManager[IO]( + driver = dbConfig.driver, + url = dbConfig.url, + user = dbConfig.user, + password = dbConfig.pass, + logHandler = None + ) + val projectRepo = new DoobieProjectRepository[IO](tx) + val test = for { + _ <- createProjectOwner(owner) + _ <- createTicketsProject(project) + deleted <- projectRepo.deleteProject(project) + foundProject <- projectRepo.findProject(owner, project.name) + } yield (deleted, foundProject) + test.start.flatMap(_.joinWithNever).map { result => + val (deleted, foundProject) = result + assert(deleted > 0, "Rows not deleted from database!") + assert(foundProject.isEmpty, "Project not deleted from database!") + } } } test("findProject must return the matching project".tag(NeedsDatabase)) { - (genProjectOwner.sample, genProjects.sample) match { - case (Some(owner), Some(generatedProject :: projects)) => - val project = generatedProject.copy(owner = owner) - val dbConfig = configuration.database - val tx = Transactor.fromDriverManager[IO]( - driver = dbConfig.driver, - url = dbConfig.url, - user = dbConfig.user, - password = dbConfig.pass, - logHandler = None - ) - val projectRepo = new DoobieProjectRepository[IO](tx) - val test = for { - _ <- createProjectOwner(owner) - _ <- createTicketsProject(project) - _ <- projects - .filterNot(_.name === project.name) - .traverse(p => createTicketsProject(p.copy(owner = owner))) - foundProject <- projectRepo.findProject(owner, project.name) - } yield foundProject - test.map { foundProject => - assertEquals(foundProject, Some(project)) - } - case _ => fail("Could not generate data samples!") + PropF.forAllF { (owner: ProjectOwner, projects: NonEmptyList[Project]) => + val project = projects.head.copy(owner = owner) + val dbConfig = configuration.database + val tx = Transactor.fromDriverManager[IO]( + driver = dbConfig.driver, + url = dbConfig.url, + user = dbConfig.user, + password = dbConfig.pass, + logHandler = None + ) + val projectRepo = new DoobieProjectRepository[IO](tx) + val test = for { + _ <- createProjectOwner(owner) + _ <- createTicketsProject(project) + _ <- projects + .filterNot(_.name === project.name) + .traverse(p => createTicketsProject(p.copy(owner = owner))) + foundProject <- projectRepo.findProject(owner, project.name) + } yield foundProject + test.start.flatMap(_.joinWithNever).map { foundProject => + assertEquals(foundProject, Some(project)) + } } } test("findProjectId must return the matching id".tag(NeedsDatabase)) { - (genProjectOwner.sample, genProjects.sample) match { - case (Some(owner), Some(generatedProject :: projects)) => - val project = generatedProject.copy(owner = owner) - val dbConfig = configuration.database - val tx = Transactor.fromDriverManager[IO]( - driver = dbConfig.driver, - url = dbConfig.url, - user = dbConfig.user, - password = dbConfig.pass, - logHandler = None - ) - val projectRepo = new DoobieProjectRepository[IO](tx) - val test = for { - _ <- createProjectOwner(owner) - _ <- createTicketsProject(project) - _ <- projects - .filterNot(_.name === project.name) - .traverse(p => createTicketsProject(p.copy(owner = owner))) - foundProjectId <- projectRepo.findProjectId(owner, project.name) - projectId <- loadProjectId(owner.uid, project.name) - } yield (foundProjectId, projectId) - test.map { result => - val (foundProjectId, projectId) = result - assertEquals(foundProjectId, projectId) - } - case _ => fail("Could not generate data samples!") + PropF.forAllF { (owner: ProjectOwner, projects: NonEmptyList[Project]) => + val project = projects.head.copy(owner = owner) + val dbConfig = configuration.database + val tx = Transactor.fromDriverManager[IO]( + driver = dbConfig.driver, + url = dbConfig.url, + user = dbConfig.user, + password = dbConfig.pass, + logHandler = None + ) + val projectRepo = new DoobieProjectRepository[IO](tx) + val test = for { + _ <- createProjectOwner(owner) + _ <- createTicketsProject(project) + _ <- projects + .filterNot(_.name === project.name) + .traverse(p => createTicketsProject(p.copy(owner = owner))) + foundProjectId <- projectRepo.findProjectId(owner, project.name) + projectId <- loadProjectId(owner.uid, project.name) + } yield (foundProjectId, projectId) + test.start.flatMap(_.joinWithNever).map { result => + val (foundProjectId, projectId) = result + assertEquals(foundProjectId, projectId) + } } } test("findProjectOwner must return the matching project owner".tag(NeedsDatabase)) { - genProjectOwners.sample match { - case Some(owner :: owners) => - val dbConfig = configuration.database - val tx = Transactor.fromDriverManager[IO]( - driver = dbConfig.driver, - url = dbConfig.url, - user = dbConfig.user, - password = dbConfig.pass, - logHandler = None - ) - val projectRepo = new DoobieProjectRepository[IO](tx) - val test = for { - _ <- createProjectOwner(owner) - _ <- owners.filterNot(_.name === owner.name).traverse(createProjectOwner) - foundOwner <- projectRepo.findProjectOwner(owner.name) - } yield foundOwner - test.map { foundOwner => - assert(foundOwner.exists(_ === owner)) - } - case _ => fail("Could not generate data samples!") + PropF.forAllF { (owners: NonEmptyList[ProjectOwner]) => + val owner = owners.head + val dbConfig = configuration.database + val tx = Transactor.fromDriverManager[IO]( + driver = dbConfig.driver, + url = dbConfig.url, + user = dbConfig.user, + password = dbConfig.pass, + logHandler = None + ) + val projectRepo = new DoobieProjectRepository[IO](tx) + val test = for { + _ <- createProjectOwner(owner) + _ <- owners.filterNot(_.name === owner.name).traverse(createProjectOwner) + foundOwner <- projectRepo.findProjectOwner(owner.name) + } yield foundOwner + test.start.flatMap(_.joinWithNever).map { foundOwner => + assert(foundOwner.exists(_ === owner)) + } } } test("incrementNextTicketNumber must return and increment the old value".tag(NeedsDatabase)) { - (genProjectOwner.sample, genProject.sample) match { - case (Some(owner), Some(firstProject)) => - val project = firstProject.copy(owner = owner) - val dbConfig = configuration.database - val tx = Transactor.fromDriverManager[IO]( - driver = dbConfig.driver, - url = dbConfig.url, - user = dbConfig.user, - password = dbConfig.pass, - logHandler = None - ) - val projectRepo = new DoobieProjectRepository[IO](tx) - val test = for { - _ <- createProjectOwner(owner) - _ <- projectRepo.createProject(project) - projectId <- loadProjectId(owner.uid, project.name) - result <- projectId match { - case None => fail("Project was not created!") - case Some(projectId) => - for { - before <- loadNextTicketNumber(projectId) - number <- projectRepo.incrementNextTicketNumber(projectId) - after <- loadNextTicketNumber(projectId) - } yield (TicketNumber(before), number, TicketNumber(after)) - } - } yield result - test.map { result => - val (before, number, after) = result - assertEquals(before, number) - assertEquals(after, TicketNumber(number.toInt + 1)) - } - case _ => fail("Could not generate data samples!") + PropF.forAllF { (owner: ProjectOwner, firstProject: Project) => + val project = firstProject.copy(owner = owner) + val dbConfig = configuration.database + val tx = Transactor.fromDriverManager[IO]( + driver = dbConfig.driver, + url = dbConfig.url, + user = dbConfig.user, + password = dbConfig.pass, + logHandler = None + ) + val projectRepo = new DoobieProjectRepository[IO](tx) + val test = for { + _ <- createProjectOwner(owner) + _ <- projectRepo.createProject(project) + projectId <- loadProjectId(owner.uid, project.name) + result <- projectId match { + case None => fail("Project was not created!") + case Some(projectId) => + for { + before <- loadNextTicketNumber(projectId) + number <- projectRepo.incrementNextTicketNumber(projectId) + after <- loadNextTicketNumber(projectId) + } yield (TicketNumber(before), number, TicketNumber(after)) + } + } yield result + test.start.flatMap(_.joinWithNever).map { result => + val (before, number, after) = result + assertEquals(before, number) + assertEquals(after, TicketNumber(number.toInt + 1)) + } } } test("updateProject must update a project".tag(NeedsDatabase)) { - (genProjectOwner.sample, genProject.sample, genProject.sample) match { - case (Some(owner), Some(firstProject), Some(secondProject)) => - val project = firstProject.copy(owner = owner) - val updatedProject = - project.copy(description = secondProject.description, isPrivate = secondProject.isPrivate) - val dbConfig = configuration.database - val tx = Transactor.fromDriverManager[IO]( - driver = dbConfig.driver, - url = dbConfig.url, - user = dbConfig.user, - password = dbConfig.pass, - logHandler = None - ) - val projectRepo = new DoobieProjectRepository[IO](tx) - val test = for { - _ <- createProjectOwner(owner) - _ <- projectRepo.createProject(project) - written <- projectRepo.updateProject(updatedProject) - foundProject <- projectRepo.findProject(owner, project.name) - } yield (written, foundProject) - test.map { result => - val (written, foundProject) = result - assert(written > 0, "Rows not updated in database!") - assertEquals(foundProject, Some(updatedProject)) - } - case _ => fail("Could not generate data samples!") + PropF.forAllF { (owner: ProjectOwner, firstProject: Project, secondProject: Project) => + val project = firstProject.copy(owner = owner) + val updatedProject = + project.copy(description = secondProject.description, isPrivate = secondProject.isPrivate) + val dbConfig = configuration.database + val tx = Transactor.fromDriverManager[IO]( + driver = dbConfig.driver, + url = dbConfig.url, + user = dbConfig.user, + password = dbConfig.pass, + logHandler = None + ) + val projectRepo = new DoobieProjectRepository[IO](tx) + val test = for { + _ <- createProjectOwner(owner) + _ <- projectRepo.createProject(project) + written <- projectRepo.updateProject(updatedProject) + foundProject <- projectRepo.findProject(owner, project.name) + } yield (written, foundProject) + test.start.flatMap(_.joinWithNever).map { result => + val (written, foundProject) = result + assert(written > 0, "Rows not updated in database!") + assertEquals(foundProject, Some(updatedProject)) + } } } }