~jan0sch/smederee
Showing details for patch f15299aad27aeaa47f23fc0371b191779a40fa6a.
diff -rN -u old-smederee/modules/tickets/src/it/scala/de/smederee/tickets/DoobieProjectRepositoryTest.scala new-smederee/modules/tickets/src/it/scala/de/smederee/tickets/DoobieProjectRepositoryTest.scala --- old-smederee/modules/tickets/src/it/scala/de/smederee/tickets/DoobieProjectRepositoryTest.scala 1970-01-01 00:00:00.000000000 +0000 +++ new-smederee/modules/tickets/src/it/scala/de/smederee/tickets/DoobieProjectRepositoryTest.scala 2025-01-31 04:54:13.899274092 +0000 @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2022 Contributors as noted in the AUTHORS.md file + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.smederee.tickets + +import cats.effect._ +import cats.syntax.all._ +import de.smederee.tickets.Generators._ +import doobie._ + +final class DoobieProjectRepositoryTest extends BaseSpec { + test("findProject must return the matching project") { + (genValidProjectOwner.sample, genValidProjects.sample) match { + case (Some(owner), Some(generatedProject :: projects)) => + val project = generatedProject.copy(owner = owner) + val dbConfig = configuration.database + val tx = Transactor.fromDriverManager[IO](dbConfig.driver, dbConfig.url, dbConfig.user, dbConfig.pass) + val projectRepo = new DoobieProjectRepository[IO](tx) + val test = for { + _ <- createTicketsUser(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!") + } + } + + test("findProjectId must return the matching id") { + (genValidProjectOwner.sample, genValidProjects.sample) match { + case (Some(owner), Some(generatedProject :: projects)) => + val project = generatedProject.copy(owner = owner) + val dbConfig = configuration.database + val tx = Transactor.fromDriverManager[IO](dbConfig.driver, dbConfig.url, dbConfig.user, dbConfig.pass) + val projectRepo = new DoobieProjectRepository[IO](tx) + val test = for { + _ <- createTicketsUser(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!") + } + } + + test("findProjectOwner must return the matching project owner") { + genValidProjectOwners.sample match { + case Some(owner :: owners) => + val dbConfig = configuration.database + val tx = Transactor.fromDriverManager[IO](dbConfig.driver, dbConfig.url, dbConfig.user, dbConfig.pass) + val projectRepo = new DoobieProjectRepository[IO](tx) + val test = for { + _ <- createTicketsUser(owner) + _ <- owners.filterNot(_.name === owner.name).traverse(createTicketsUser) + foundOwner <- projectRepo.findProjectOwner(owner.name) + } yield foundOwner + test.map { foundOwner => + assert(foundOwner.exists(_ === owner)) + } + case _ => fail("Could not generate data samples!") + } + } +} diff -rN -u old-smederee/modules/tickets/src/main/scala/de/smederee/tickets/DoobieProjectRepository.scala new-smederee/modules/tickets/src/main/scala/de/smederee/tickets/DoobieProjectRepository.scala --- old-smederee/modules/tickets/src/main/scala/de/smederee/tickets/DoobieProjectRepository.scala 1970-01-01 00:00:00.000000000 +0000 +++ new-smederee/modules/tickets/src/main/scala/de/smederee/tickets/DoobieProjectRepository.scala 2025-01-31 04:54:13.899274092 +0000 @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2022 Contributors as noted in the AUTHORS.md file + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.smederee.tickets + +import java.util.UUID + +import cats.effect._ +import de.smederee.email.EmailAddress +import doobie._ +import doobie.implicits._ +import doobie.postgres.implicits._ + +final class DoobieProjectRepository[F[_]: Sync](tx: Transactor[F]) extends ProjectRepository[F] { + + given Meta[EmailAddress] = Meta[String].timap(EmailAddress.apply)(_.toString) + given Meta[ProjectDescription] = Meta[String].timap(ProjectDescription.apply)(_.toString) + given Meta[ProjectName] = Meta[String].timap(ProjectName.apply)(_.toString) + given Meta[ProjectOwnerId] = Meta[UUID].timap(ProjectOwnerId.apply)(_.toUUID) + given Meta[ProjectOwnerName] = Meta[String].timap(ProjectOwnerName.apply)(_.toString) + + override def findProject(owner: ProjectOwner, name: ProjectName): F[Option[Project]] = + sql"""SELECT + "users".uid AS owner_id, + "users".name AS owner_name, + "users".email AS owner_email, + "projects".name, + "projects".description, + "projects".is_private + FROM "tickets"."projects" AS "projects" + JOIN "tickets"."users" AS "users" + ON "projects".owner = "users".uid + WHERE + "projects".owner = ${owner.uid} + AND + "projects".name = $name""".query[Project].option.transact(tx) + + override def findProjectId(owner: ProjectOwner, name: ProjectName): F[Option[Long]] = + sql"""SELECT + "projects".id + FROM "tickets"."projects" AS "projects" + JOIN "tickets"."users" AS "users" + ON "projects".owner = "users".uid + WHERE + "projects".owner = ${owner.uid} + AND + "projects".name = $name""".query[Long].option.transact(tx) + + override def findProjectOwner(name: ProjectOwnerName): F[Option[ProjectOwner]] = + sql"""SELECT + "users".uid, + "users".name, + "users".email + FROM "tickets"."users" + WHERE name = $name""".query[ProjectOwner].option.transact(tx) + +}