Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1618: Add tests for api token feature #1694

Merged
merged 15 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
package app.ehrenamtskarte.backend.auth.webservice

import app.ehrenamtskarte.backend.IntegrationTest
ztefanie marked this conversation as resolved.
Show resolved Hide resolved
import app.ehrenamtskarte.backend.auth.database.AdministratorEntity
import app.ehrenamtskarte.backend.auth.database.Administrators
import app.ehrenamtskarte.backend.auth.database.ApiTokens
import app.ehrenamtskarte.backend.auth.service.Authorizer
import app.ehrenamtskarte.backend.auth.webservice.schema.ApiTokenQueryService
import app.ehrenamtskarte.backend.auth.webservice.schema.ApiTokenService
import app.ehrenamtskarte.backend.common.webservice.GraphQLContext
import app.ehrenamtskarte.backend.exception.service.ForbiddenException
import app.ehrenamtskarte.backend.helper.TestAdministrators
import app.ehrenamtskarte.backend.helper.TestData
import graphql.schema.DataFetchingEnvironment
import io.mockk.every
import io.mockk.mockk
import org.jetbrains.exposed.sql.deleteAll
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.selectAll
import org.jetbrains.exposed.sql.transactions.transaction
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Assert.assertThrows
import org.junit.Assert.assertTrue
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import java.time.LocalDate

internal class ApiTokenServiceTest : IntegrationTest() {

private val mockDfe = mockk<DataFetchingEnvironment>()
private val mockContext = mockk<GraphQLContext>()
private val mockJwtPayload = mockk<JwtPayload>()

@BeforeEach
fun setUp() {
every { mockDfe.getContext<GraphQLContext>() } returns mockContext
every { mockContext.enforceSignedIn() } returns mockJwtPayload
transaction {
ApiTokens.deleteAll()
}
}

@Test
fun createApiToken_createsTokenSuccessfully() {
every { mockJwtPayload.adminId } returns TestAdministrators.KOBLENZ_PROJECT_ADMIN.id

transaction {
val numberOfTokensBefore = ApiTokens.selectAll().count()
ApiTokenService().createApiToken(3, mockDfe)
val numberOfTokensAfter = ApiTokens.selectAll().count()
assertEquals(numberOfTokensBefore + 1, numberOfTokensAfter)
}
}

@Test
fun createApiToken_throwsForbiddenExceptionWhenNotAuthorized() {
every { mockJwtPayload.adminId } returns TestAdministrators.NUERNBERG_PROJECT_STORE_MANAGER.id

transaction {
assertThrows(ForbiddenException::class.java) {
ApiTokenService().createApiToken(1, mockDfe)
}
assertFalse(
Authorizer.mayAddApiTokensInProject(
AdministratorEntity.find { Administrators.id eq mockJwtPayload.adminId }.single()
)
)
}
}

@Test
fun createApiToken_throwsExceptionWhenAdminNotFound() {
every { mockJwtPayload.adminId } returns 1234

transaction {
assertThrows(ForbiddenException::class.java) {
ApiTokenService().createApiToken(1, mockDfe)
}
}
}

@Test
fun deleteApiToken_deletesTokenSuccessfully() {
every { mockJwtPayload.adminId } returns TestAdministrators.KOBLENZ_PROJECT_ADMIN.id

transaction {
val tokenId = TestData.createApiToken(creatorId = TestAdministrators.KOBLENZ_PROJECT_ADMIN.id)
val tokenExists = ApiTokens.select { ApiTokens.id eq tokenId }.count() > 0
assertTrue(tokenExists)

ApiTokenService().deleteApiToken(tokenId, mockDfe)

val tokenNoLongerExists = ApiTokens.select { ApiTokens.id eq tokenId }.singleOrNull() == null
assertTrue(tokenNoLongerExists)
}
}

@Test
fun deleteApiToken_deletesFromOtherAdminTokenSuccessfully() {
ztefanie marked this conversation as resolved.
Show resolved Hide resolved
every { mockJwtPayload.adminId } returns TestAdministrators.KOBLENZ_PROJECT_ADMIN.id
TestData.createApiToken(creatorId = TestAdministrators.KOBLENZ_PROJECT_ADMIN_2.id)

transaction {
val tokenBefore = ApiTokens.select { ApiTokens.creatorId eq TestAdministrators.KOBLENZ_PROJECT_ADMIN_2.id }.singleOrNull()
assertNotNull(tokenBefore)
ztefanie marked this conversation as resolved.
Show resolved Hide resolved

ApiTokenService().deleteApiToken(tokenBefore!![ApiTokens.id].value, mockDfe)

val tokenAfter = ApiTokens.select { ApiTokens.creatorId eq TestAdministrators.KOBLENZ_PROJECT_ADMIN_2.id }.singleOrNull()
assertNull(tokenAfter)
}
}

@Test
fun deleteApiToken_deletesNoTokenFormOtherProject() {
every { mockJwtPayload.adminId } returns TestAdministrators.KOBLENZ_PROJECT_ADMIN.id
transaction {
val tokenId = TestData.createApiToken(creatorId = TestAdministrators.NUERNBERG_PROJECT_ADMIN.id)

val numberOfTokensBefore = ApiTokens.selectAll().count()
ApiTokenService().deleteApiToken(tokenId, mockDfe)
val numberOfTokensAfter = ApiTokens.selectAll().count()
assert(numberOfTokensBefore == numberOfTokensAfter)
}
}

@Test
fun deleteApiToken_throwsForbiddenExceptionWhenNotAuthorized() {
every { mockJwtPayload.adminId } returns TestAdministrators.NUERNBERG_PROJECT_STORE_MANAGER.id

transaction {
assertThrows(ForbiddenException::class.java) {
ApiTokenService().deleteApiToken(1, mockDfe)
}
assertFalse(
Authorizer.mayAddApiTokensInProject(
AdministratorEntity.find { Administrators.id eq mockJwtPayload.adminId }.single()
)
)
}
}

@Test
fun deleteApiToken_throwsExceptionWhenAdminNotFound() {
every { mockJwtPayload.adminId } returns 1234

transaction {
assertThrows(ForbiddenException::class.java) {
ApiTokenService().deleteApiToken(1, mockDfe)
}
}
}

@Test
fun getApiTokenMetaData_returnsMetaDataSuccessfully() {
every { mockJwtPayload.adminId } returns TestAdministrators.KOBLENZ_PROJECT_ADMIN.id

transaction {
val tokenId = TestData.createApiToken(creatorId = TestAdministrators.KOBLENZ_PROJECT_ADMIN.id)

val metaData = ApiTokenQueryService().getApiTokenMetaData(mockDfe)
assertEquals(1, metaData.size)
assertEquals(tokenId, metaData[0].id)
assertEquals(TestAdministrators.KOBLENZ_PROJECT_ADMIN.email, metaData[0].creatorEmail)
assertEquals(LocalDate.now().plusYears(1).toString(), metaData[0].expirationDate)
}
}

@Test
fun getApiTokenMetaData_throwsForbiddenExceptionWhenNotAuthorized() {
every { mockJwtPayload.adminId } returns TestAdministrators.NUERNBERG_PROJECT_STORE_MANAGER.id

transaction {
assertThrows(ForbiddenException::class.java) {
ApiTokenQueryService().getApiTokenMetaData(mockDfe)
}
assertFalse(
Authorizer.mayViewApiMetadataInProject(
AdministratorEntity.find { Administrators.id eq mockJwtPayload.adminId }.single()
)
)
}
}

@Test
fun getApiTokenMetaData_throwsExceptionWhenAdminNotFound() {
every { mockJwtPayload.adminId } returns 1234

transaction {
assertThrows(ForbiddenException::class.java) {
ApiTokenQueryService().getApiTokenMetaData(mockDfe)
}
}
}

@Test
fun getApiTokenMetaData_returnsNoTokensOfOtherProjects() {
every { mockJwtPayload.adminId } returns TestAdministrators.KOBLENZ_PROJECT_ADMIN.id

transaction {
TestData.createApiToken(creatorId = TestAdministrators.NUERNBERG_PROJECT_ADMIN.id)

val metaData = ApiTokenQueryService().getApiTokenMetaData(mockDfe)
assertEquals(0, metaData.size)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ enum class TestAdministrators(
project = "koblenz.sozialpass.app",
email = "[email protected]",
role = Role.PROJECT_ADMIN
),
KOBLENZ_PROJECT_ADMIN_2(
id = 6,
project = "koblenz.sozialpass.app",
email = "[email protected]",
role = Role.PROJECT_ADMIN
);

fun getJwtToken(): String {
Expand Down