@@ -12,7 +12,6 @@ import com.github.database.rider.core.api.dataset.ExpectedDataSet
12
12
import com.github.database.rider.junit5.api.DBRider
13
13
import org.assertj.core.api.Assertions.assertThat
14
14
import org.junit.jupiter.api.BeforeEach
15
- import org.junit.jupiter.api.Disabled
16
15
import org.junit.jupiter.api.Test
17
16
import org.junit.jupiter.api.TestInstance
18
17
import org.skyscreamer.jsonassert.Customization
@@ -22,8 +21,10 @@ import org.skyscreamer.jsonassert.comparator.CustomComparator
22
21
import org.springframework.beans.factory.annotation.Autowired
23
22
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
24
23
import org.springframework.boot.test.context.SpringBootTest
24
+ import org.springframework.http.HttpStatus
25
25
import org.springframework.http.MediaType
26
26
import org.springframework.test.web.servlet.MockMvc
27
+ import org.springframework.test.web.servlet.delete
27
28
import org.springframework.test.web.servlet.get
28
29
import org.springframework.test.web.servlet.post
29
30
import org.springframework.util.MultiValueMapAdapter
@@ -1761,28 +1762,226 @@ class ArticleTest {
1761
1762
@TestInstance(TestInstance .Lifecycle .PER_CLASS )
1762
1763
@DBRider
1763
1764
class DeleteArticle {
1764
- @Disabled
1765
+
1766
+ @Autowired
1767
+ lateinit var mockMvc: MockMvc
1768
+
1769
+ @BeforeEach
1770
+ fun reset () = DbConnection .resetSequence()
1771
+
1765
1772
@Test
1773
+ @DataSet(
1774
+ value = [
1775
+ " datasets/yml/given/users.yml" ,
1776
+ " datasets/yml/given/tags.yml" ,
1777
+ " datasets/yml/given/articles.yml" ,
1778
+ ]
1779
+ )
1780
+ @ExpectedDataSet(
1781
+ value = [" datasets/yml/then/api_integration/delete-success.yml" ],
1782
+ ignoreCols = [" id" , " created_at" , " updated_at" ],
1783
+ orderBy = [" id" ]
1784
+ )
1785
+ // NOTE: @ExportDataSetはgivenの@DataSetが変更された時用に残しておく
1786
+ // @ExportDataSet(
1787
+ // format = DataSetFormat.YML,
1788
+ // outputName = "src/test/resources/datasets/yml/then/api_integration/delete-success.yml",
1789
+ // includeTables = ["articles", "tags", "article_tags", "favorites", "article_comments"]
1790
+ // )
1766
1791
fun `正常系-自分が著者である記事のSlugを指定した場合、その作成済み記事を削除する` () {
1767
- TODO ()
1792
+ /* *
1793
+ * given:
1794
+ * - 存在する著者
1795
+ * - 著者が書いた作成済み記事のslug
1796
+ */
1797
+ val author = SeedData .users().first()
1798
+ val sessionToken = MySessionJwtImpl .encode(MySession (author.userId, author.email))
1799
+ .getOrHandle { throw UnsupportedOperationException (" セッションからJWTへの変換に失敗しました(前提条件であるため、元の実装を見直してください)" ) }
1800
+ val slug = " rust-vs-scala-vs-kotlin"
1801
+
1802
+ /* *
1803
+ * when:
1804
+ */
1805
+ val response = mockMvc.delete(" /articles/$slug " ) {
1806
+ contentType = MediaType .APPLICATION_JSON
1807
+ header(" Authorization" , sessionToken)
1808
+ }.andReturn().response
1809
+ val actualStatus = response.status
1810
+ val actualResponseBody = response.contentAsString
1811
+
1812
+ /* *
1813
+ * then:
1814
+ */
1815
+ val expectedStatus = HttpStatus .OK .value()
1816
+ val expectedResponseBody = " "
1817
+ assertThat(actualStatus).isEqualTo(expectedStatus)
1818
+ assertThat(actualResponseBody).isEqualTo(expectedResponseBody)
1768
1819
}
1769
1820
1770
- @Disabled
1771
1821
@Test
1822
+ @DataSet(
1823
+ value = [
1824
+ " datasets/yml/given/users.yml" ,
1825
+ " datasets/yml/given/tags.yml" ,
1826
+ " datasets/yml/given/articles.yml" ,
1827
+ ]
1828
+ )
1829
+ @ExpectedDataSet(
1830
+ value = [
1831
+ " datasets/yml/given/tags.yml" ,
1832
+ " datasets/yml/given/articles.yml" ,
1833
+ ],
1834
+ ignoreCols = [" id" , " created_at" , " updated_at" ],
1835
+ orderBy = [" id" ]
1836
+ )
1772
1837
fun `準正常系-自分が著者ではない記事のSlugを指定した場合、その作成済み記事は削除できない` () {
1773
- TODO ()
1838
+ /* *
1839
+ * given:
1840
+ * - 著者ではない存在する登録済みユーザー
1841
+ * - 登録済み記事のslug
1842
+ */
1843
+ val author = SeedData .users().toList()[1 ]
1844
+ val sessionToken = MySessionJwtImpl .encode(MySession (author.userId, author.email))
1845
+ .getOrHandle { throw UnsupportedOperationException (" セッションからJWTへの変換に失敗しました(前提条件であるため、元の実装を見直してください)" ) }
1846
+ val slug = " rust-vs-scala-vs-kotlin"
1847
+
1848
+ /* *
1849
+ * when:
1850
+ */
1851
+ val response = mockMvc.delete(" /articles/$slug " ) {
1852
+ contentType = MediaType .APPLICATION_JSON
1853
+ header(" Authorization" , sessionToken)
1854
+ }.andReturn().response
1855
+ val actualStatus = response.status
1856
+ val actualResponseBody = response.contentAsString
1857
+
1858
+ /* *
1859
+ * then:
1860
+ */
1861
+ val expectedStatus = HttpStatus .UNPROCESSABLE_ENTITY .value()
1862
+ val expectedResponseBody = """
1863
+ {"errors":{"body":["削除する権限がありません"]}}
1864
+ """ .trimIndent()
1865
+ assertThat(actualStatus).isEqualTo(expectedStatus)
1866
+ JSONAssert .assertEquals(
1867
+ expectedResponseBody,
1868
+ actualResponseBody,
1869
+ CustomComparator (JSONCompareMode .NON_EXTENSIBLE )
1870
+ )
1774
1871
}
1775
1872
1776
- @Disabled
1777
1873
@Test
1874
+ @DataSet(
1875
+ value = [
1876
+ " datasets/yml/given/users.yml" ,
1877
+ " datasets/yml/given/tags.yml" ,
1878
+ " datasets/yml/given/articles.yml" ,
1879
+ ]
1880
+ )
1881
+ @ExpectedDataSet(
1882
+ value = [
1883
+ " datasets/yml/given/tags.yml" ,
1884
+ " datasets/yml/given/articles.yml" ,
1885
+ ],
1886
+ ignoreCols = [" id" , " created_at" , " updated_at" ],
1887
+ orderBy = [" id" ]
1888
+ )
1778
1889
fun `準正常系-存在しないSlugを指定した場合、その作成済み記事は見つからなかった旨のエラーレスポンスが返る` () {
1779
- TODO ()
1890
+ /* *
1891
+ * given:
1892
+ * - 存在する登録済みユーザー
1893
+ * - 存在しないslug
1894
+ */
1895
+ val existedUser = SeedData .users().first()
1896
+ val sessionToken = MySessionJwtImpl .encode(MySession (existedUser.userId, existedUser.email))
1897
+ .getOrHandle { throw UnsupportedOperationException (" セッションからJWTへの変換に失敗しました(前提条件であるため、元の実装を見直してください)" ) }
1898
+ val slug = " not-existed-slug"
1899
+
1900
+ /* *
1901
+ * when:
1902
+ */
1903
+ val response = mockMvc.delete(" /articles/$slug " ) {
1904
+ contentType = MediaType .APPLICATION_JSON
1905
+ header(" Authorization" , sessionToken)
1906
+ }.andReturn().response
1907
+ val actualStatus = response.status
1908
+ val actualResponseBody = response.contentAsString
1909
+
1910
+ /* *
1911
+ * then:
1912
+ */
1913
+ val expectedStatus = HttpStatus .UNPROCESSABLE_ENTITY .value()
1914
+ val expectedResponseBody = """
1915
+ {"errors":{"body":["記事が見つかりませんでした"]}}
1916
+ """ .trimIndent()
1917
+ assertThat(actualStatus).isEqualTo(expectedStatus)
1918
+ JSONAssert .assertEquals(
1919
+ expectedResponseBody,
1920
+ actualResponseBody,
1921
+ CustomComparator (JSONCompareMode .NON_EXTENSIBLE )
1922
+ )
1780
1923
}
1781
1924
1782
- @Disabled
1783
1925
@Test
1784
- fun `準正常系-バリデーションエラーが起こるSlugを指定した場合、その作成済み記事は見つからなかった旨のエラーレスポンスが返る` () {
1785
- TODO ()
1926
+ @DataSet(
1927
+ value = [
1928
+ " datasets/yml/given/users.yml" ,
1929
+ " datasets/yml/given/tags.yml" ,
1930
+ " datasets/yml/given/articles.yml" ,
1931
+ ]
1932
+ )
1933
+ @ExpectedDataSet(
1934
+ value = [
1935
+ " datasets/yml/given/tags.yml" ,
1936
+ " datasets/yml/given/articles.yml" ,
1937
+ ],
1938
+ ignoreCols = [" id" , " created_at" , " updated_at" ],
1939
+ orderBy = [" id" ]
1940
+ )
1941
+ fun `準正常系-バリデーションエラーが起こるSlugを指定した場合、その旨のエラーレスポンスが返る` () {
1942
+ /* *
1943
+ * given:
1944
+ * - 存在する登録済みユーザー
1945
+ * - バリデーションエラーが起こるslug
1946
+ */
1947
+ val existedUser = SeedData .users().first()
1948
+ val sessionToken = MySessionJwtImpl .encode(MySession (existedUser.userId, existedUser.email))
1949
+ .getOrHandle { throw UnsupportedOperationException (" セッションからJWTへの変換に失敗しました(前提条件であるため、元の実装を見直してください)" ) }
1950
+ val slug = IntStream .range(0 , 10 ).mapToObj { " 長すぎるslug" }.toList().joinToString()
1951
+
1952
+ /* *
1953
+ * when:
1954
+ */
1955
+ val response = mockMvc.delete(" /articles/$slug " ) {
1956
+ contentType = MediaType .APPLICATION_JSON
1957
+ header(" Authorization" , sessionToken)
1958
+ }.andReturn().response
1959
+ val actualStatus = response.status
1960
+ val actualResponseBody = response.contentAsString
1961
+
1962
+ /* *
1963
+ * then:
1964
+ */
1965
+ val expectedStatus = HttpStatus .UNPROCESSABLE_ENTITY .value()
1966
+ val expectedResponseBody = """
1967
+ {
1968
+ "errors":{
1969
+ "body":[
1970
+ {
1971
+ "slug": "長すぎるslug, 長すぎるslug, 長すぎるslug, 長すぎるslug, 長すぎるslug, 長すぎるslug, 長すぎるslug, 長すぎるslug, 長すぎるslug, 長すぎるslug",
1972
+ "key":"Slug",
1973
+ "message":"slugは32文字以下にしてください。"
1974
+ }
1975
+ ]
1976
+ }
1977
+ }
1978
+ """ .trimIndent()
1979
+ assertThat(actualStatus).isEqualTo(expectedStatus)
1980
+ JSONAssert .assertEquals(
1981
+ expectedResponseBody,
1982
+ actualResponseBody,
1983
+ CustomComparator (JSONCompareMode .NON_EXTENSIBLE )
1984
+ )
1786
1985
}
1787
1986
}
1788
1987
}
0 commit comments