From 032342262cd69aaa90c34ecf4cf5003ea9fc6c1f Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 29 Nov 2023 16:23:59 +0900 Subject: [PATCH] =?UTF-8?q?test:=20Status=E3=81=AE=E3=83=86=E3=82=B9?= =?UTF-8?q?=E3=83=88=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/mastodon/status/StatusTest.kt | 145 ++++++++++++++++++ src/intTest/resources/logback.xml | 1 + src/intTest/resources/sql/test-post.sql | 3 + 3 files changed, 149 insertions(+) create mode 100644 src/intTest/kotlin/mastodon/status/StatusTest.kt create mode 100644 src/intTest/resources/sql/test-post.sql diff --git a/src/intTest/kotlin/mastodon/status/StatusTest.kt b/src/intTest/kotlin/mastodon/status/StatusTest.kt new file mode 100644 index 00000000..2272895a --- /dev/null +++ b/src/intTest/kotlin/mastodon/status/StatusTest.kt @@ -0,0 +1,145 @@ +package mastodon.status + +import dev.usbharu.hideout.SpringApplication +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.http.MediaType +import org.springframework.security.core.authority.SimpleGrantedAuthority +import org.springframework.security.test.context.support.WithAnonymousUser +import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors +import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf +import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers +import org.springframework.test.context.jdbc.Sql +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.post +import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder +import org.springframework.test.web.servlet.setup.MockMvcBuilders +import org.springframework.transaction.annotation.Transactional +import org.springframework.web.context.WebApplicationContext + +@SpringBootTest(classes = [SpringApplication::class]) +@AutoConfigureMockMvc +@Transactional +@Sql("/sql/test-user.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) +class StatusTest { + + @Autowired + private lateinit var context: WebApplicationContext + + private lateinit var mockMvc: MockMvc + + + @BeforeEach + fun setUp() { + mockMvc = MockMvcBuilders.webAppContextSetup(context) + .apply(SecurityMockMvcConfigurers.springSecurity()) + .build() + } + + @Test + fun 投稿できる() { + mockMvc + .post("/api/v1/statuses") { + contentType = MediaType.APPLICATION_JSON + content = """{"status":"hello"}""" + with( + SecurityMockMvcRequestPostProcessors.jwt() + .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write")) + ) + } + .asyncDispatch() + .andExpect { status { isOk() } } + } + + @Test + fun write_statusesスコープで投稿できる() { + mockMvc + .post("/api/v1/statuses") { + contentType = MediaType.APPLICATION_JSON + content = """{"status":"hello"}""" + with( + SecurityMockMvcRequestPostProcessors.jwt() + .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write:statuses")) + ) + } + .asyncDispatch() + .andExpect { status { isOk() } } + } + + @Test + fun 権限がないと403() { + mockMvc + .post("/api/v1/statuses") { + contentType = MediaType.APPLICATION_JSON + content = """{"status":"hello"}""" + with( + SecurityMockMvcRequestPostProcessors.jwt() + .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_read")) + ) + } + .andExpect { status { isForbidden() } } + } + + @Test + @WithAnonymousUser + fun 匿名だと401() { + mockMvc + .post("/api/v1/statuses") { + contentType = MediaType.APPLICATION_JSON + content = """{"status":"hello"}""" + with(csrf()) + } + .andExpect { status { isUnauthorized() } } + } + + @Test + @WithAnonymousUser + fun 匿名の場合通常はcsrfが無いので403() { + mockMvc + .post("/api/v1/statuses") { + contentType = MediaType.APPLICATION_JSON + content = """{"status":"hello"}""" + } + .andExpect { status { isForbidden() } } + } + + @Test + fun formでも投稿できる() { + mockMvc + .post("/api/v1/statuses") { + contentType = MediaType.APPLICATION_FORM_URLENCODED + param("status", "hello") + with( + SecurityMockMvcRequestPostProcessors.jwt() + .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write:statuses")) + ) + } + .asyncDispatch() + .andExpect { status { isOk() } } + } + + @Test + @Sql("/sql/test-post.sql") + fun in_reply_to_idを指定したら返信として処理される() { + mockMvc + .post("/api/v1/statuses") { + contentType = MediaType.APPLICATION_JSON + //language=JSON + content = """{ + "status": "hello", + "in_reply_to_id": "1" +}""" + with( + SecurityMockMvcRequestPostProcessors.jwt() + .jwt { it.claim("uid", "1") }.authorities(SimpleGrantedAuthority("SCOPE_write")) + ) + } + .asyncDispatch() + .andDo { print() } + .andExpect { status { isOk() } } + .andExpect { jsonPath("\$.in_reply_to_id") { value("1") } } + } +} diff --git a/src/intTest/resources/logback.xml b/src/intTest/resources/logback.xml index 54cfd39a..a8bb21c4 100644 --- a/src/intTest/resources/logback.xml +++ b/src/intTest/resources/logback.xml @@ -7,4 +7,5 @@ + diff --git a/src/intTest/resources/sql/test-post.sql b/src/intTest/resources/sql/test-post.sql new file mode 100644 index 00000000..01bcb2dd --- /dev/null +++ b/src/intTest/resources/sql/test-post.sql @@ -0,0 +1,3 @@ +insert into posts (id, user_id, overview, text, created_at, visibility, url, repost_id, reply_id, sensitive, ap_id) +VALUES (1, 1, null, 'hello', 1234455, 0, 'https://localhost/users/1/posts/1', null, null, false, + 'https://users/1/posts/1');