Skip to content

Commit

Permalink
Add Projects Route tests (#324)
Browse files Browse the repository at this point in the history
  • Loading branch information
Wavesonics authored Jun 30, 2024
1 parent 59f901b commit 7091c4a
Show file tree
Hide file tree
Showing 9 changed files with 525 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ import com.darkrockstudios.apps.hammer.plugins.ServerUserIdPrincipal
import com.darkrockstudios.apps.hammer.plugins.USER_AUTH
import com.darkrockstudios.apps.hammer.project.InvalidSyncIdException
import com.darkrockstudios.apps.hammer.utilities.isSuccess
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.auth.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.http.HttpStatusCode
import io.ktor.server.application.call
import io.ktor.server.auth.authenticate
import io.ktor.server.auth.principal
import io.ktor.server.response.respond
import io.ktor.server.routing.Route
import io.ktor.server.routing.get
import io.ktor.server.routing.route
import org.koin.ktor.ext.get

fun Route.projectsRoutes() {
Expand Down Expand Up @@ -46,7 +49,7 @@ private fun Route.beginProjectsSync() {
call.respond(
status = HttpStatusCode.BadRequest,
HttpResponseError(
error = "Missing Header",
error = "Begin Project Sync Failed",
displayMessage = message?.text(call) ?: "Unknown Error"
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,40 @@ import com.darkrockstudios.apps.hammer.utils.setupKtorTestKoin
import io.ktor.client.request.post
import io.ktor.http.isSuccess
import io.ktor.server.testing.testApplication
import io.mockk.mockk
import io.mockk.MockKAnnotations
import io.mockk.impl.annotations.MockK
import kotlinx.serialization.json.Json
import org.junit.Before
import org.koin.dsl.module
import kotlin.test.Test
import kotlin.test.assertFalse

class AccountRoutesTest : BaseTest() {
@MockK
private lateinit var accountsRepository: AccountsRepository

@MockK
private lateinit var projectRepository: ProjectRepository

@MockK
private lateinit var projectsRepository: ProjectsRepository

@MockK
private lateinit var accountsComponent: AccountsComponent

@MockK
private lateinit var adminComponent: AdminComponent

@MockK
private lateinit var json: Json

private lateinit var testModule: org.koin.core.module.Module

@Before
override fun setup() {
super.setup()

accountsRepository = mockk()
projectRepository = mockk()
projectsRepository = mockk()
accountsComponent = mockk()
adminComponent = mockk()
json = mockk()
MockKAnnotations.init(this)

testModule = module {
single { accountsRepository }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package com.darkrockstudios.apps.hammer.projects.routes

import com.darkrockstudios.apps.hammer.account.AccountsComponent
import com.darkrockstudios.apps.hammer.account.AccountsRepository
import com.darkrockstudios.apps.hammer.admin.AdminComponent
import com.darkrockstudios.apps.hammer.admin.WhiteListRepository
import com.darkrockstudios.apps.hammer.plugins.configureRouting
import com.darkrockstudios.apps.hammer.plugins.configureSecurity
import com.darkrockstudios.apps.hammer.plugins.configureSerialization
import com.darkrockstudios.apps.hammer.project.ProjectRepository
import com.darkrockstudios.apps.hammer.projects.ProjectsRepository
import com.darkrockstudios.apps.hammer.utils.BaseTest
import com.darkrockstudios.apps.hammer.utils.setupKtorTestKoin
import io.ktor.server.application.Application
import io.ktor.server.testing.ApplicationTestBuilder
import io.mockk.MockKAnnotations
import io.mockk.impl.annotations.MockK
import kotlinx.serialization.json.Json
import org.junit.Before
import org.koin.dsl.module

abstract class ProjectsRoutesBaseTest : BaseTest() {

@MockK(relaxed = true)
protected lateinit var accountsRepository: AccountsRepository

@MockK(relaxed = true)
protected lateinit var whiteListRepository: WhiteListRepository

@MockK(relaxed = true)
protected lateinit var projectRepository: ProjectRepository

@MockK(relaxed = true)
protected lateinit var projectsRepository: ProjectsRepository

@MockK(relaxed = true)
protected lateinit var accountsComponent: AccountsComponent

@MockK(relaxed = true)
protected lateinit var adminComponent: AdminComponent

@MockK(relaxed = true)
protected lateinit var json: Json

protected lateinit var testModule: org.koin.core.module.Module

protected val BEARER_TOKEN = "token-test"

@Before
override fun setup() {
super.setup()

MockKAnnotations.init(this, relaxUnitFun = true)

testModule = module {
single { accountsRepository }
single { whiteListRepository }
single { projectRepository }
single { projectsRepository }
single { accountsComponent }
single { adminComponent }
single { json }
}
}

protected fun ApplicationTestBuilder.defaultApplication(moreSetup: (Application.() -> Unit)? = null) {
application {
setupKtorTestKoin(this@ProjectsRoutesBaseTest, testModule)

configureSerialization()
configureSecurity()
configureRouting()

if (moreSetup != null) moreSetup()
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package com.darkrockstudios.apps.hammer.projects.routes

import com.darkrockstudios.apps.hammer.base.http.HEADER_SYNC_ID
import com.darkrockstudios.apps.hammer.project.InvalidSyncIdException
import com.darkrockstudios.apps.hammer.utilities.SResult
import io.ktor.client.request.get
import io.ktor.client.request.header
import io.ktor.http.HttpStatusCode
import io.ktor.http.isSuccess
import io.ktor.server.testing.testApplication
import io.mockk.coEvery
import io.mockk.coVerify
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue

class ProjectsRoutesCreateProjectTest : ProjectsRoutesBaseTest() {

@Test
fun `Projects - Create Project - Success`() = testApplication {
val projectName = "TestProject"
val syncId = "syncId-test"
val userId = 0L

coEvery { accountsRepository.checkToken(userId, BEARER_TOKEN) } returns SResult.success(0L)
coEvery { whiteListRepository.useWhiteList() } returns false
coEvery {
projectsRepository.createProject(
userId = userId,
syncId = syncId,
projectName = projectName,
)
} returns Result.success(Unit)

defaultApplication()

client.get("api/projects/0/TestProject/create") {
header("Authorization", "Bearer $BEARER_TOKEN")
header(HEADER_SYNC_ID, syncId)
}.apply {
assertTrue(status.isSuccess())
coVerify {
projectsRepository.createProject(
userId = userId,
syncId = syncId,
projectName = projectName,
)
}
}
}

@Test
fun `Projects - Create Project - Invalid Request`() = testApplication {
coEvery { accountsRepository.checkToken(any(), any()) } returns SResult.success(0L)
coEvery { whiteListRepository.useWhiteList() } returns false

defaultApplication()

client.get("api/projects/0/TestProject/create") {
header("Authorization", "Bearer $BEARER_TOKEN")
}.apply {
assertEquals(HttpStatusCode.BadRequest, status)
}
}

@Test
fun `Projects - Create Project - Failure - Bad SyncId`() = testApplication {
val projectName = "TestProject"
val syncId = "syncId-test"
val userId = 0L

coEvery { accountsRepository.checkToken(userId, BEARER_TOKEN) } returns SResult.success(0L)
coEvery { whiteListRepository.useWhiteList() } returns false
coEvery {
projectsRepository.createProject(
userId = userId,
syncId = syncId,
projectName = projectName,
)
} returns Result.failure(InvalidSyncIdException())

defaultApplication()

client.get("api/projects/0/TestProject/create") {
header("Authorization", "Bearer $BEARER_TOKEN")
header(HEADER_SYNC_ID, syncId)
}.apply {
assertEquals(HttpStatusCode.BadRequest, status)
}
}

@Test
fun `Projects - Create Project - Failure - Repository Exception`() = testApplication {
val projectName = "TestProject"
val syncId = "syncId-test"
val userId = 0L

coEvery { accountsRepository.checkToken(userId, BEARER_TOKEN) } returns SResult.success(0L)
coEvery { whiteListRepository.useWhiteList() } returns false
coEvery {
projectsRepository.createProject(
userId = userId,
syncId = syncId,
projectName = projectName,
)
} returns Result.failure(Exception())

defaultApplication()

client.get("api/projects/0/TestProject/create") {
header("Authorization", "Bearer $BEARER_TOKEN")
header(HEADER_SYNC_ID, syncId)
}.apply {
assertEquals(HttpStatusCode.InternalServerError, status)
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package com.darkrockstudios.apps.hammer.projects.routes

import com.darkrockstudios.apps.hammer.base.http.HEADER_SYNC_ID
import com.darkrockstudios.apps.hammer.utilities.SResult
import io.ktor.client.request.get
import io.ktor.client.request.header
import io.ktor.http.HttpStatusCode
import io.ktor.server.testing.testApplication
import io.mockk.coEvery
import io.mockk.coVerify
import kotlin.test.Test
import kotlin.test.assertEquals

class ProjectsRoutesDeleteProjectTest : ProjectsRoutesBaseTest() {

@Test
fun `Projects - Delete Project - Success`() = testApplication {
val projectName = "TestProject"
val syncId = "syncId-test"
val userId = 0L

coEvery { accountsRepository.checkToken(userId, BEARER_TOKEN) } returns SResult.success(0L)
coEvery { whiteListRepository.useWhiteList() } returns false
coEvery {
projectsRepository.deleteProject(
userId = userId,
syncId = syncId,
projectName = projectName,
)
} returns Result.success(Unit)

defaultApplication()

client.get("api/projects/0/TestProject/delete") {
header("Authorization", "Bearer $BEARER_TOKEN")
header(HEADER_SYNC_ID, syncId)
}.apply {
assertEquals(HttpStatusCode.OK, status)
coVerify {
projectsRepository.deleteProject(
userId = userId,
syncId = syncId,
projectName = projectName,
)
}
}
}

@Test
fun `Projects - Delete Project - Invalid Request`() = testApplication {
coEvery { accountsRepository.checkToken(any(), any()) } returns SResult.success(0L)
coEvery { whiteListRepository.useWhiteList() } returns false

defaultApplication()

client.get("api/projects/0/TestProject/delete") {
header("Authorization", "Bearer $BEARER_TOKEN")
}.apply {
assertEquals(HttpStatusCode.BadRequest, status)
}
}

@Test
fun `Projects - Delete Project - Failure - Repository Exception`() = testApplication {
val projectName = "TestProject"
val syncId = "syncId-test"
val userId = 0L

coEvery { accountsRepository.checkToken(userId, BEARER_TOKEN) } returns SResult.success(0L)
coEvery { whiteListRepository.useWhiteList() } returns false
coEvery {
projectsRepository.deleteProject(
userId = userId,
syncId = syncId,
projectName = projectName,
)
} returns Result.failure(Exception())

defaultApplication()

client.get("api/projects/0/TestProject/delete") {
header("Authorization", "Bearer $BEARER_TOKEN")
header(HEADER_SYNC_ID, syncId)
}.apply {
assertEquals(HttpStatusCode.InternalServerError, status)
}
}
}
Loading

0 comments on commit 7091c4a

Please sign in to comment.