Skip to content

Commit

Permalink
test: add suport for security on tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Lukinhasssss committed May 30, 2024
1 parent cd7b227 commit 02f3fbb
Show file tree
Hide file tree
Showing 6 changed files with 484 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@ class IntegrationTestConfiguration {

@Bean
fun videoRepository() = mockk<VideoRepository>()

@Bean
fun webGraphQlSecurityInterceptor() = WebGraphQlSecurityInterceptor()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.lukinhasssss.catalogo

import org.springframework.graphql.server.WebGraphQlInterceptor
import org.springframework.graphql.server.WebGraphQlRequest
import org.springframework.graphql.server.WebGraphQlResponse
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.core.context.ReactiveSecurityContextHolder
import org.springframework.security.core.context.SecurityContextHolder
import reactor.core.publisher.Mono

class WebGraphQlSecurityInterceptor(
private val authorities: MutableList<SimpleGrantedAuthority> = mutableListOf()
) : WebGraphQlInterceptor {

override fun intercept(request: WebGraphQlRequest, chain: WebGraphQlInterceptor.Chain): Mono<WebGraphQlResponse> {
if (authorities.isEmpty()) { return chain.next(request) }

val user = UsernamePasswordAuthenticationToken.authenticated("JohnDoe", "123456", authorities)
val context = SecurityContextHolder.getContext()
context.authentication = user

return chain.next(request).contextWrite(ReactiveSecurityContextHolder.withSecurityContext(Mono.just(context)))
}

fun setAuthorities(
vararg authorities: String
) {
this.authorities.clear()

if (authorities.isNotEmpty()) {
this.authorities.addAll(authorities.map { SimpleGrantedAuthority(it) })
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package com.lukinhasssss.catalogo.infrastructure.graphql

import com.lukinhasssss.catalogo.IntegrationTest
import com.lukinhasssss.catalogo.WebGraphQlSecurityInterceptor
import com.lukinhasssss.catalogo.application.castmember.list.ListCastMemberOutput
import com.lukinhasssss.catalogo.application.castmember.list.ListCastMemberUseCase
import com.lukinhasssss.catalogo.domain.Fixture
import com.lukinhasssss.catalogo.domain.pagination.Pagination
import com.lukinhasssss.catalogo.infrastructure.configuration.security.Roles
import com.ninjasquad.springmockk.MockkBean
import io.mockk.every
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.graphql.server.WebGraphQlHandler
import org.springframework.graphql.test.tester.GraphQlTester
import org.springframework.graphql.test.tester.WebGraphQlTester

@IntegrationTest
class CastMemberGraphQLIT {

@MockkBean
private lateinit var listCastMemberUseCase: ListCastMemberUseCase

@Autowired
private lateinit var graphqlHandler: WebGraphQlHandler

@Autowired
private lateinit var interceptor: WebGraphQlSecurityInterceptor

@Test
fun givenAnonymousUser_whenQueries_shouldReturnUnauthorized() {
interceptor.setAuthorities()

val document = "query { castMembers { id } }"

val graphQlTester = WebGraphQlTester.create(graphqlHandler)

graphQlTester.document(document).execute()
.errors()
.expect { it.path == "castMembers" && it.message == "Unauthorized" }
.verify()
}

@Test
fun givenUserWithAdminRole_whenQueries_shouldReturnCastMembers() {
interceptor.setAuthorities(Roles.ADMIN)

val castMembers = listOf(
ListCastMemberOutput.from(Fixture.CastMembers.luffy()),
ListCastMemberOutput.from(Fixture.CastMembers.zoro())
)

val expectedIds = castMembers.map { it.id }

every {
listCastMemberUseCase.execute(any())
} returns Pagination(0, 10, castMembers.size.toLong(), castMembers)

val document = "query { castMembers { id } }"

val graphQlTester = WebGraphQlTester.create(graphqlHandler)

graphQlTester.document(document).execute().errors().verify()
.path("castMembers[*].id").entityList(String::class.java).isEqualTo<GraphQlTester.EntityList<String>>(expectedIds)
}

@Test
fun givenUserWithSubscriberRole_whenQueries_shouldReturnCastMembers() {
interceptor.setAuthorities(Roles.SUBSCRIBER)

val castMembers = listOf(
ListCastMemberOutput.from(Fixture.CastMembers.luffy()),
ListCastMemberOutput.from(Fixture.CastMembers.zoro())
)

val expectedIds = castMembers.map { it.id }

every {
listCastMemberUseCase.execute(any())
} returns Pagination(0, 10, castMembers.size.toLong(), castMembers)

val document = "query { castMembers { id } }"

val graphQlTester = WebGraphQlTester.create(graphqlHandler)

graphQlTester.document(document).execute().errors().verify()
.path("castMembers[*].id").entityList(String::class.java).isEqualTo<GraphQlTester.EntityList<String>>(expectedIds)
}

@Test
fun givenUserWithCastMembersRole_whenQueries_shouldReturnCastMembers() {
interceptor.setAuthorities(Roles.CAST_MEMBERS)

val castMembers = listOf(
ListCastMemberOutput.from(Fixture.CastMembers.luffy()),
ListCastMemberOutput.from(Fixture.CastMembers.zoro())
)

val expectedIds = castMembers.map { it.id }

every {
listCastMemberUseCase.execute(any())
} returns Pagination(0, 10, castMembers.size.toLong(), castMembers)

val document = "query { castMembers { id } }"

val graphQlTester = WebGraphQlTester.create(graphqlHandler)

graphQlTester.document(document).execute().errors().verify()
.path("castMembers[*].id").entityList(String::class.java).isEqualTo<GraphQlTester.EntityList<String>>(expectedIds)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package com.lukinhasssss.catalogo.infrastructure.graphql

import com.lukinhasssss.catalogo.IntegrationTest
import com.lukinhasssss.catalogo.WebGraphQlSecurityInterceptor
import com.lukinhasssss.catalogo.application.category.list.ListCategoryOutput
import com.lukinhasssss.catalogo.application.category.list.ListCategoryUseCase
import com.lukinhasssss.catalogo.domain.Fixture
import com.lukinhasssss.catalogo.domain.pagination.Pagination
import com.lukinhasssss.catalogo.infrastructure.configuration.security.Roles
import com.ninjasquad.springmockk.MockkBean
import io.mockk.every
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.graphql.server.WebGraphQlHandler
import org.springframework.graphql.test.tester.GraphQlTester
import org.springframework.graphql.test.tester.WebGraphQlTester

@IntegrationTest
class CategoryGraphQLIT {

@MockkBean
private lateinit var listCategoryUseCase: ListCategoryUseCase

@Autowired
private lateinit var graphqlHandler: WebGraphQlHandler

@Autowired
private lateinit var interceptor: WebGraphQlSecurityInterceptor

@Test
fun givenAnonymousUser_whenQueries_shouldReturnUnauthorized() {
interceptor.setAuthorities()

val document = "query { categories { id } }"

val graphQlTester = WebGraphQlTester.create(graphqlHandler)

graphQlTester.document(document).execute()
.errors()
.expect { it.path == "categories" && it.message == "Unauthorized" }
.verify()
}

@Test
fun givenUserWithAdminRole_whenQueries_shouldReturnCategories() {
interceptor.setAuthorities(Roles.ADMIN)

val categories = listOf(
ListCategoryOutput.from(Fixture.Categories.aulas),
ListCategoryOutput.from(Fixture.Categories.lives)
)

val expectedIds = categories.map { it.id }

every {
listCategoryUseCase.execute(any())
} returns Pagination(0, 10, categories.size.toLong(), categories)

val document = "query { categories { id } }"

val graphQlTester = WebGraphQlTester.create(graphqlHandler)

graphQlTester.document(document).execute().errors().verify()
.path("categories[*].id").entityList(String::class.java).isEqualTo<GraphQlTester.EntityList<String>>(expectedIds)
}

@Test
fun givenUserWithSubscriberRole_whenQueries_shouldReturnCategories() {
interceptor.setAuthorities(Roles.SUBSCRIBER)

val categories = listOf(
ListCategoryOutput.from(Fixture.Categories.aulas),
ListCategoryOutput.from(Fixture.Categories.lives)
)

val expectedIds = categories.map { it.id }

every {
listCategoryUseCase.execute(any())
} returns Pagination(0, 10, categories.size.toLong(), categories)

val document = "query { categories { id } }"

val graphQlTester = WebGraphQlTester.create(graphqlHandler)

graphQlTester.document(document).execute().errors().verify()
.path("categories[*].id").entityList(String::class.java).isEqualTo<GraphQlTester.EntityList<String>>(expectedIds)
}

@Test
fun givenUserWithCategoriesRole_whenQueries_shouldReturnCategories() {
interceptor.setAuthorities(Roles.CATEGORIES)

val categories = listOf(
ListCategoryOutput.from(Fixture.Categories.aulas),
ListCategoryOutput.from(Fixture.Categories.lives)
)

val expectedIds = categories.map { it.id }

every {
listCategoryUseCase.execute(any())
} returns Pagination(0, 10, categories.size.toLong(), categories)

val document = "query { categories { id } }"

val graphQlTester = WebGraphQlTester.create(graphqlHandler)

graphQlTester.document(document).execute().errors().verify()
.path("categories[*].id").entityList(String::class.java).isEqualTo<GraphQlTester.EntityList<String>>(expectedIds)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package com.lukinhasssss.catalogo.infrastructure.graphql

import com.lukinhasssss.catalogo.IntegrationTest
import com.lukinhasssss.catalogo.WebGraphQlSecurityInterceptor
import com.lukinhasssss.catalogo.application.genre.list.ListGenreUseCase
import com.lukinhasssss.catalogo.domain.Fixture
import com.lukinhasssss.catalogo.domain.pagination.Pagination
import com.lukinhasssss.catalogo.infrastructure.configuration.security.Roles
import com.ninjasquad.springmockk.MockkBean
import io.mockk.every
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.graphql.server.WebGraphQlHandler
import org.springframework.graphql.test.tester.GraphQlTester
import org.springframework.graphql.test.tester.WebGraphQlTester

@IntegrationTest
class GenreGraphQLIT {

@MockkBean
private lateinit var listGenreUseCase: ListGenreUseCase

@Autowired
private lateinit var graphqlHandler: WebGraphQlHandler

@Autowired
private lateinit var interceptor: WebGraphQlSecurityInterceptor

@Test
fun givenAnonymousUser_whenQueries_shouldReturnUnauthorized() {
interceptor.setAuthorities()

val document = "query { genres { id } }"

val graphQlTester = WebGraphQlTester.create(graphqlHandler)

graphQlTester.document(document).execute()
.errors()
.expect { it.path == "genres" && it.message == "Unauthorized" }
.verify()
}

@Test
fun givenUserWithAdminRole_whenQueries_shouldReturnGenres() {
interceptor.setAuthorities(Roles.ADMIN)

val genres = listOf(
ListGenreUseCase.Output.from(Fixture.Genres.tech()),
ListGenreUseCase.Output.from(Fixture.Genres.business())
)

val expectedIds = genres.map { it.id }

every {
listGenreUseCase.execute(any())
} returns Pagination(0, 10, genres.size.toLong(), genres)

val document = "query { genres { id } }"

val graphQlTester = WebGraphQlTester.create(graphqlHandler)

graphQlTester.document(document).execute().errors().verify()
.path("genres[*].id").entityList(String::class.java).isEqualTo<GraphQlTester.EntityList<String>>(expectedIds)
}

@Test
fun givenUserWithSubscriberRole_whenQueries_shouldReturnGenres() {
interceptor.setAuthorities(Roles.SUBSCRIBER)

val genres = listOf(
ListGenreUseCase.Output.from(Fixture.Genres.tech()),
ListGenreUseCase.Output.from(Fixture.Genres.business())
)

val expectedIds = genres.map { it.id }

every {
listGenreUseCase.execute(any())
} returns Pagination(0, 10, genres.size.toLong(), genres)

val document = "query { genres { id } }"

val graphQlTester = WebGraphQlTester.create(graphqlHandler)

graphQlTester.document(document).execute().errors().verify()
.path("genres[*].id").entityList(String::class.java).isEqualTo<GraphQlTester.EntityList<String>>(expectedIds)
}

@Test
fun givenUserWithGenresRole_whenQueries_shouldReturnGenres() {
interceptor.setAuthorities(Roles.GENRES)

val genres = listOf(
ListGenreUseCase.Output.from(Fixture.Genres.tech()),
ListGenreUseCase.Output.from(Fixture.Genres.business())
)

val expectedIds = genres.map { it.id }

every {
listGenreUseCase.execute(any())
} returns Pagination(0, 10, genres.size.toLong(), genres)

val document = "query { genres { id } }"

val graphQlTester = WebGraphQlTester.create(graphqlHandler)

graphQlTester.document(document).execute().errors().verify()
.path("genres[*].id").entityList(String::class.java).isEqualTo<GraphQlTester.EntityList<String>>(expectedIds)
}
}
Loading

0 comments on commit 02f3fbb

Please sign in to comment.