Skip to content

Commit

Permalink
Improve repository tests
Browse files Browse the repository at this point in the history
  • Loading branch information
KapStorm committed Sep 30, 2023
1 parent 6a3bcd0 commit 7ab20b3
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 333 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import org.scalatest.wordspec.AnyWordSpec
import utils.Executors

import java.time.Clock
import scala.concurrent.ExecutionContext
import scala.concurrent.duration.DurationInt

trait RepositorySpec extends AnyWordSpec with PostgresSpec {
implicit val patienceConfig: PatienceConfig = PatienceConfig(30.seconds, 1.second)
implicit val executionContext: ExecutionContext = Executors.globalEC

def withRepositories[T](clock: Clock = Clock.systemUTC)(runTest: RepositoryComponents => T): T = withDatabase { db =>
val users = new UsersRepository(db, UserTokensConfig(1.hour, 1.hour, "secret"))(Executors.databaseEC, clock)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@ import akka.stream.scaladsl.*
import net.wiringbits.common.models.Email
import net.wiringbits.core.RepositorySpec
import net.wiringbits.models.jobs.{BackgroundJobPayload, BackgroundJobStatus, BackgroundJobType}
import net.wiringbits.repositories.daos.BackgroundJobDAO
import net.wiringbits.repositories.daos.{BackgroundJobDAO, backgroundJobParser}
import net.wiringbits.repositories.models.BackgroundJobData
import org.scalatest.BeforeAndAfterAll
import org.scalatest.OptionValues.*
import org.scalatest.concurrent.ScalaFutures.*
import org.scalatest.matchers.must.Matchers.*
import play.api.libs.json.Json
import utils.RepositoryUtils

import java.time.Instant
import java.util.UUID

class BackgroundJobsRepositorySpec extends RepositorySpec with BeforeAndAfterAll {
class BackgroundJobsRepositorySpec extends RepositorySpec with BeforeAndAfterAll with RepositoryUtils {

// required to test the streaming operations
private implicit lazy val system: ActorSystem = ActorSystem("BackgroundJobsRepositorySpec")
Expand All @@ -26,24 +27,10 @@ class BackgroundJobsRepositorySpec extends RepositorySpec with BeforeAndAfterAll
super.afterAll()
}

private val backgroundJobPayload =
BackgroundJobPayload.SendEmail(Email.trusted("[email protected]"), subject = "Test message", body = "it works")
"streamPendingJobs" should {

"work (simple case)" in withRepositories() { repositories =>
val createRequest = BackgroundJobData.Create(
id = UUID.randomUUID(),
`type` = BackgroundJobType.SendEmail,
payload = backgroundJobPayload,
status = BackgroundJobStatus.Pending,
executeAt = Instant.now(),
createdAt = Instant.now(),
updatedAt = Instant.now()
)

repositories.database.withConnection { implicit conn =>
BackgroundJobDAO.create(createRequest)
}
"work (simple case)" in withRepositories() { implicit repositories =>
val createRequest = createBackgroundJobData()

val result = repositories.backgroundJobs.streamPendingJobs.futureValue
.runWith(Sink.seq)
Expand All @@ -56,36 +43,25 @@ class BackgroundJobsRepositorySpec extends RepositorySpec with BeforeAndAfterAll
item.payload must be(Json.toJson(createRequest.payload))
}

"only return pending jobs" in withRepositories() { repositories =>
val createRequestBase = BackgroundJobData.Create(
id = UUID.randomUUID(),
`type` = BackgroundJobType.SendEmail,
payload = backgroundJobPayload,
status = BackgroundJobStatus.Pending,
executeAt = Instant.now(),
createdAt = Instant.now(),
updatedAt = Instant.now()
)

"only return pending jobs" in withRepositories() { implicit repositories =>
val backgroundJobType = BackgroundJobType.SendEmail
val payload = backgroundJobPayload
val limit = 6
for (i <- 1 to limit) {
repositories.database.withConnection { implicit conn =>
BackgroundJobDAO.create(
createRequestBase.copy(
id = UUID.randomUUID(),
status = if ((i % 2) == 0) BackgroundJobStatus.Success else BackgroundJobStatus.Pending
)
)
}
createBackgroundJobData(
backgroundJobType = backgroundJobType,
payload = payload,
status = if (i % 2) == 0 then BackgroundJobStatus.Success else BackgroundJobStatus.Pending
)
}
val response = repositories.backgroundJobs.streamPendingJobs.futureValue
.runWith(Sink.seq)
.futureValue
response.length must be(limit / 2)
response.foreach { x =>
x.status must be(BackgroundJobStatus.Pending)
x.`type` must be(createRequestBase.`type`)
x.payload must be(Json.toJson(createRequestBase.payload))
x.`type` must be(backgroundJobType)
x.payload must be(Json.toJson(payload))
}
}

Expand All @@ -98,20 +74,9 @@ class BackgroundJobsRepositorySpec extends RepositorySpec with BeforeAndAfterAll
}

"setStatusToFailed" should {
"work" in withRepositories() { repositories =>
val createRequest = BackgroundJobData.Create(
id = UUID.randomUUID(),
`type` = BackgroundJobType.SendEmail,
payload = backgroundJobPayload,
status = BackgroundJobStatus.Pending,
executeAt = Instant.now(),
createdAt = Instant.now(),
updatedAt = Instant.now()
)

repositories.database.withConnection { implicit conn =>
BackgroundJobDAO.create(createRequest)
}
"work" in withRepositories() { implicit repositories =>
val createRequest = createBackgroundJobData()

val failReason = "test"
repositories.backgroundJobs
.setStatusToFailed(createRequest.id, executeAt = Instant.now(), failReason = failReason)
Expand All @@ -137,20 +102,9 @@ class BackgroundJobsRepositorySpec extends RepositorySpec with BeforeAndAfterAll
}

"setStatusToSuccess" should {
"work" in withRepositories() { repositories =>
val createRequest = BackgroundJobData.Create(
id = UUID.randomUUID(),
`type` = BackgroundJobType.SendEmail,
payload = backgroundJobPayload,
status = BackgroundJobStatus.Pending,
executeAt = Instant.now(),
createdAt = Instant.now(),
updatedAt = Instant.now()
)

repositories.database.withConnection { implicit conn =>
BackgroundJobDAO.create(createRequest)
}
"work" in withRepositories() { implicit repositories =>
val createRequest = createBackgroundJobData()

repositories.backgroundJobs.setStatusToSuccess(createRequest.id).futureValue

val result = repositories.backgroundJobs.streamPendingJobs.futureValue
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,23 @@
package net.wiringbits.repositories

import net.wiringbits.common.models.{Email, Name}
import net.wiringbits.core.RepositorySpec
import net.wiringbits.repositories.models.{User, UserLog}
import org.scalatest.concurrent.ScalaFutures.*
import org.scalatest.matchers.must.Matchers.*
import utils.RepositoryUtils

import java.util.UUID

class UserLogsRepositorySpec extends RepositorySpec {
class UserLogsRepositorySpec extends RepositorySpec with RepositoryUtils {
"create" should {
"work" in withRepositories() { repositories =>
val request = User.CreateUser(
id = UUID.randomUUID(),
email = Email.trusted("[email protected]"),
name = Name.trusted("Sample"),
hashedPassword = "password",
verifyEmailToken = "token"
)
repositories.users.create(request).futureValue
"work" in withRepositories() { implicit repositories =>
val request = createUser().futureValue

val logsRequest = UserLog.CreateUserLog(userLogId = UUID.randomUUID(), userId = request.id, message = "test")
repositories.userLogs.create(logsRequest).futureValue
createUserLog(request.id).futureValue
}

"fail if the user doesn't exists" in withRepositories() { repositories =>
val logsRequest =
UserLog.CreateUserLog(userLogId = UUID.randomUUID(), userId = UUID.randomUUID(), message = "test")
"fail if the user doesn't exists" in withRepositories() { implicit repositories =>
val ex = intercept[RuntimeException] {
repositories.userLogs.create(logsRequest).futureValue
createUserLog(UUID.randomUUID()).futureValue
}
ex.getCause.getMessage must startWith(
s"""ERROR: insert or update on table "user_logs" violates foreign key constraint "user_logs_users_fk""""
Expand All @@ -37,22 +26,15 @@ class UserLogsRepositorySpec extends RepositorySpec {
}

"create(userId, message)" should {
"work" in withRepositories() { repositories =>
val request = User.CreateUser(
id = UUID.randomUUID(),
email = Email.trusted("[email protected]"),
name = Name.trusted("Sample"),
hashedPassword = "password",
verifyEmailToken = "token"
)
repositories.users.create(request).futureValue
"work" in withRepositories() { implicit repositories =>
val request = createUser().futureValue

repositories.userLogs.create(request.id, "test").futureValue
createUserLog(request.id, "test").futureValue
}

"fail if the user doesn't exists" in withRepositories() { repositories =>
"fail if the user doesn't exists" in withRepositories() { implicit repositories =>
val ex = intercept[RuntimeException] {
repositories.userLogs.create(UUID.randomUUID(), "test").futureValue
createUserLog(UUID.randomUUID(), "test").futureValue
}
ex.getCause.getMessage must startWith(
s"""ERROR: insert or update on table "user_logs" violates foreign key constraint "user_logs_users_fk""""
Expand All @@ -61,24 +43,18 @@ class UserLogsRepositorySpec extends RepositorySpec {
}

"logs" should {
"return every log" in withRepositories() { repositories =>
val request = User.CreateUser(
id = UUID.randomUUID(),
email = Email.trusted("[email protected]"),
name = Name.trusted("Sample"),
hashedPassword = "password",
verifyEmailToken = "token"
)
repositories.users.create(request).futureValue
"return every log" in withRepositories() { implicit repositories =>
val request = createUser().futureValue

val message = "test"
for (_ <- 1 to 3) {
repositories.userLogs.create(request.id, message).futureValue
val expected = 3
(1 to expected).foreach { _ =>
createUserLog(request.id, message).futureValue
}

val response = repositories.userLogs.logs(request.id).futureValue
// Creating a user generates a user log. 3 + 1
response.length must be(4)
response.length must be(expected + 1)
}

"return no results" in withRepositories() { repositories =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,52 +1,24 @@
package net.wiringbits.repositories

import net.wiringbits.common.models.{Email, Name}
import net.wiringbits.core.RepositorySpec
import net.wiringbits.repositories.models.{User, UserToken, UserTokenType}
import org.scalatest.OptionValues.convertOptionToValuable
import org.scalatest.concurrent.ScalaFutures.*
import org.scalatest.matchers.must.Matchers.*
import utils.RepositoryUtils

import java.time.Instant
import java.time.temporal.ChronoUnit
import java.util.UUID

class UserTokensRepositorySpec extends RepositorySpec {
class UserTokensRepositorySpec extends RepositorySpec with RepositoryUtils {
"create" should {
"work" in withRepositories() { repositories =>
val request = User.CreateUser(
id = UUID.randomUUID(),
email = Email.trusted("[email protected]"),
name = Name.trusted("Sample"),
hashedPassword = "password",
verifyEmailToken = "token"
)
repositories.users.create(request).futureValue

val tokenRequest =
UserToken.Create(
id = UUID.randomUUID(),
token = "test",
tokenType = UserTokenType.ResetPassword,
createdAt = Instant.now(),
expiresAt = Instant.now.plus(2, ChronoUnit.DAYS),
userId = request.id
)
repositories.userTokens.create(tokenRequest).futureValue
"work" in withRepositories() { implicit repositories =>
val request = createUser().futureValue

createToken(request.id).futureValue
}

"fail when the user doesn't exists" in withRepositories() { repositories =>
val tokenRequest =
UserToken.Create(
id = UUID.randomUUID(),
token = "test",
tokenType = UserTokenType.ResetPassword,
createdAt = Instant.now(),
expiresAt = Instant.now.plus(2, ChronoUnit.DAYS),
userId = UUID.randomUUID()
)
"fail when the user doesn't exists" in withRepositories() { implicit repositories =>
val ex = intercept[RuntimeException] {
repositories.userTokens.create(tokenRequest).futureValue
createToken(UUID.randomUUID()).futureValue
}
ex.getCause.getMessage must startWith(
s"""ERROR: insert or update on table "user_tokens" violates foreign key constraint "user_tokens_user_id_fk""""
Expand All @@ -55,26 +27,10 @@ class UserTokensRepositorySpec extends RepositorySpec {
}

"find(userId)" should {
"return the user token" in withRepositories() { repositories =>
val request = User.CreateUser(
id = UUID.randomUUID(),
email = Email.trusted("[email protected]"),
name = Name.trusted("Sample"),
hashedPassword = "password",
verifyEmailToken = "token"
)
repositories.users.create(request).futureValue

val tokenRequest =
UserToken.Create(
id = UUID.randomUUID(),
token = "test",
tokenType = UserTokenType.ResetPassword,
createdAt = Instant.now(),
expiresAt = Instant.now.plus(2, ChronoUnit.DAYS),
userId = request.id
)
repositories.userTokens.create(tokenRequest).futureValue
"return the user token" in withRepositories() { implicit repositories =>
val request = createUser().futureValue

val tokenRequest = createToken(request.id).futureValue

val maybe = repositories.userTokens.find(request.id).futureValue
val response = maybe.headOption.value
Expand All @@ -90,26 +46,10 @@ class UserTokensRepositorySpec extends RepositorySpec {
}

"find(userId, token)" should {
"return the user token" in withRepositories() { repositories =>
val request = User.CreateUser(
id = UUID.randomUUID(),
email = Email.trusted("[email protected]"),
name = Name.trusted("Sample"),
hashedPassword = "password",
verifyEmailToken = "token"
)
repositories.users.create(request).futureValue

val tokenRequest =
UserToken.Create(
id = UUID.randomUUID(),
token = "test",
tokenType = UserTokenType.ResetPassword,
createdAt = Instant.now(),
expiresAt = Instant.now.plus(2, ChronoUnit.DAYS),
userId = request.id
)
repositories.userTokens.create(tokenRequest).futureValue
"return the user token" in withRepositories() { implicit repositories =>
val request = createUser().futureValue

val tokenRequest = createToken(request.id).futureValue

val response = repositories.userTokens.find(request.id, tokenRequest.token).futureValue
response.isDefined must be(true)
Expand All @@ -122,15 +62,8 @@ class UserTokensRepositorySpec extends RepositorySpec {
}

"delete" should {
"work" in withRepositories() { repositories =>
val request = User.CreateUser(
id = UUID.randomUUID(),
email = Email.trusted("[email protected]"),
name = Name.trusted("Sample"),
hashedPassword = "password",
verifyEmailToken = "token"
)
repositories.users.create(request).futureValue
"work" in withRepositories() { implicit repositories =>
val request = createUser().futureValue

val maybe = repositories.userTokens.find(request.id).futureValue
val tokenId = maybe.headOption.value.id
Expand Down
Loading

0 comments on commit 7ab20b3

Please sign in to comment.