~jan0sch/smederee

Showing details for patch 51bc3db0e4ecdfa9cbda428e488013d6420346c3.
2023-06-16 (Fri), 2:37 PM - Jens Grassel - 51bc3db0e4ecdfa9cbda428e488013d6420346c3

Add `allAccounts()` method to AuthenticationRepository.

This method returns all accounts defined in the database.
Summary of changes
4 files modified with 38 lines added and 0 lines removed
  • modules/hub/src/main/scala/de/smederee/hub/AuthenticationRepository.scala with 8 added and 0 removed lines
  • modules/hub/src/main/scala/de/smederee/hub/DoobieAuthenticationRepository.scala with 6 added and 0 removed lines
  • modules/hub/src/test/scala/de/smederee/hub/DoobieAuthenticationRepositoryTest.scala with 21 added and 0 removed lines
  • modules/hub/src/test/scala/de/smederee/hub/TestAuthenticationRepository.scala with 3 added and 0 removed lines
diff -rN -u old-smederee/modules/hub/src/main/scala/de/smederee/hub/AuthenticationRepository.scala new-smederee/modules/hub/src/main/scala/de/smederee/hub/AuthenticationRepository.scala
--- old-smederee/modules/hub/src/main/scala/de/smederee/hub/AuthenticationRepository.scala	2025-01-16 03:02:56.663787463 +0000
+++ new-smederee/modules/hub/src/main/scala/de/smederee/hub/AuthenticationRepository.scala	2025-01-16 03:02:56.663787463 +0000
@@ -19,6 +19,7 @@
 
 import de.smederee.email.EmailAddress
 import de.smederee.security._
+import fs2.Stream
 
 /** A base class for database functionality related to the authentication process.
   *
@@ -36,6 +37,13 @@
   */
 abstract class AuthenticationRepository[F[_]] {
 
+  /** Return all accounts found in the database sorted ascending by username.
+    *
+    * @return
+    *   A stream containing all accounts sorted ascending by username which may be empty.
+    */
+  def allAccounts(): Stream[F, Account]
+
   /** Create a user session in the database.
     *
     * @param session
diff -rN -u old-smederee/modules/hub/src/main/scala/de/smederee/hub/DoobieAuthenticationRepository.scala new-smederee/modules/hub/src/main/scala/de/smederee/hub/DoobieAuthenticationRepository.scala
--- old-smederee/modules/hub/src/main/scala/de/smederee/hub/DoobieAuthenticationRepository.scala	2025-01-16 03:02:56.663787463 +0000
+++ new-smederee/modules/hub/src/main/scala/de/smederee/hub/DoobieAuthenticationRepository.scala	2025-01-16 03:02:56.663787463 +0000
@@ -27,6 +27,7 @@
 import doobie._
 import doobie.implicits._
 import doobie.postgres.implicits._
+import fs2.Stream
 
 final class DoobieAuthenticationRepository[F[_]: Sync](tx: Transactor[F]) extends AuthenticationRepository[F] {
   given Meta[EmailAddress] = Meta[String].timap(EmailAddress.apply)(_.toString)
@@ -41,6 +42,11 @@
   private val notLockedFilter      = fr"""locked_at IS NULL"""
   private val selectAccountColumns = fr"""SELECT uid, name, email, validated_email, language FROM "hub"."accounts""""
 
+  override def allAccounts(): Stream[F, Account] = {
+    val query = selectAccountColumns ++ fr"""ORDER BY "name" ASC"""
+    query.query[Account].stream.transact(tx)
+  }
+
   override def createUserSession(session: Session): F[Int] =
     sql"""INSERT INTO "hub"."sessions" (id, uid, created_at, updated_at) VALUES (${session.id}, ${session.uid}, ${session.createdAt}, ${session.updatedAt})""".update.run
       .transact(tx)
diff -rN -u old-smederee/modules/hub/src/test/scala/de/smederee/hub/DoobieAuthenticationRepositoryTest.scala new-smederee/modules/hub/src/test/scala/de/smederee/hub/DoobieAuthenticationRepositoryTest.scala
--- old-smederee/modules/hub/src/test/scala/de/smederee/hub/DoobieAuthenticationRepositoryTest.scala	2025-01-16 03:02:56.663787463 +0000
+++ new-smederee/modules/hub/src/test/scala/de/smederee/hub/DoobieAuthenticationRepositoryTest.scala	2025-01-16 03:02:56.663787463 +0000
@@ -43,6 +43,27 @@
     val _ = flyway.clean()
   }
 
+  test("allAccounts must return all accounts from the database".tag(NeedsDatabase)) {
+    genValidAccounts.sample match {
+      case Some(accounts) =>
+        val expected = accounts.map(_.copy(language = None))
+        val dbConfig = configuration.database
+        val tx       = Transactor.fromDriverManager[IO](dbConfig.driver, dbConfig.url, dbConfig.user, dbConfig.pass)
+        val repo     = new DoobieAuthenticationRepository[IO](tx)
+        val test = for {
+          _ <- accounts.traverse(account =>
+            createAccount(account, PasswordHash("I am not a password hash!"), None, None)
+          )
+          result <- repo.allAccounts().compile.toList
+        } yield result
+        test.map { result =>
+          assertEquals(result.size, expected.size)
+          assertEquals(result, expected.sortBy(_.name))
+        }
+      case _ => fail("Could not generate data samples!")
+    }
+  }
+
   test("createUserSession must create the user session".tag(NeedsDatabase)) {
     (genValidSession.sample, genValidAccount.sample) match {
       case (Some(s), Some(account)) =>
diff -rN -u old-smederee/modules/hub/src/test/scala/de/smederee/hub/TestAuthenticationRepository.scala new-smederee/modules/hub/src/test/scala/de/smederee/hub/TestAuthenticationRepository.scala
--- old-smederee/modules/hub/src/test/scala/de/smederee/hub/TestAuthenticationRepository.scala	2025-01-16 03:02:56.663787463 +0000
+++ new-smederee/modules/hub/src/test/scala/de/smederee/hub/TestAuthenticationRepository.scala	2025-01-16 03:02:56.663787463 +0000
@@ -24,6 +24,7 @@
 import de.smederee.email.EmailAddress
 import de.smederee.hub._
 import de.smederee.security._
+import fs2.Stream
 
 /** An implementation of a [[AuthenticationRepository]] for testing purposes.
   *
@@ -56,6 +57,8 @@
     */
   def getLocked: F[List[UserId]] = Sync[F].delay(locked)
 
+  override def allAccounts(): Stream[F, Account] = Stream.emits(accounts)
+
   override def lockAccount(uid: UserId)(token: Option[UnlockToken]): F[Int] = {
     locked = uid :: locked
     Sync[F].pure(1)