articles-backend-app
468 строк · 17.9 Кб
1package by.andd3dfx.controllers;
2
3import static org.hamcrest.CoreMatchers.containsString;
4import static org.hamcrest.CoreMatchers.is;
5import static org.hamcrest.CoreMatchers.notNullValue;
6import static org.hamcrest.MatcherAssert.assertThat;
7import static org.hamcrest.Matchers.hasSize;
8import static org.springframework.http.MediaType.APPLICATION_JSON;
9import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
10import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
11import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
12import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
13import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
14import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
15import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
16
17import by.andd3dfx.ArticlesBackendAppApplication;
18import by.andd3dfx.dto.ArticleDto;
19import by.andd3dfx.dto.ArticleUpdateDto;
20import by.andd3dfx.dto.AuthorDto;
21import com.fasterxml.jackson.databind.ObjectMapper;
22import java.io.IOException;
23import java.time.LocalDateTime;
24import org.junit.jupiter.api.BeforeEach;
25import org.junit.jupiter.api.Test;
26import org.springframework.beans.factory.annotation.Autowired;
27import org.springframework.boot.test.context.SpringBootTest;
28import org.springframework.test.context.web.WebAppConfiguration;
29import org.springframework.test.web.servlet.MockMvc;
30import org.springframework.web.context.WebApplicationContext;
31
32@SpringBootTest(classes = ArticlesBackendAppApplication.class)
33@WebAppConfiguration
34class ArticleControllerTest {
35
36private MockMvc mockMvc;
37
38@Autowired
39private WebApplicationContext webApplicationContext;
40
41@Autowired
42private ObjectMapper objectMapper;
43
44@BeforeEach
45public void setup() {
46mockMvc = webAppContextSetup(webApplicationContext)
47.build();
48}
49
50@Test
51public void createArticle() throws Exception {
52ArticleDto articleDto = new ArticleDto();
53articleDto.setTitle("Some tittle value");
54articleDto.setSummary("Some summary value");
55articleDto.setText("Some text");
56AuthorDto authorDto = new AuthorDto();
57authorDto.setId(1L);
58articleDto.setAuthor(authorDto);
59
60mockMvc.perform(post("/api/v1/articles")
61.contentType(APPLICATION_JSON)
62.content(json(articleDto))
63)
64.andExpect(status().isCreated())
65.andExpect(jsonPath("$.id", notNullValue()))
66.andExpect(jsonPath("$.title", is(articleDto.getTitle())))
67.andExpect(jsonPath("$.summary", is(articleDto.getSummary())))
68.andExpect(jsonPath("$.text", is(articleDto.getText())))
69.andExpect(jsonPath("$.author.id", is(1)))
70.andExpect(jsonPath("$.dateCreated", notNullValue()))
71.andExpect(jsonPath("$.dateUpdated", notNullValue()));
72}
73
74@Test
75public void createArticleWithIdPopulated() throws Exception {
76ArticleDto articleDto = new ArticleDto();
77articleDto.setId(123L);
78articleDto.setTitle("Some tittle value");
79articleDto.setSummary("Some summary value");
80articleDto.setText("Some text");
81AuthorDto authorDto = new AuthorDto();
82authorDto.setId(1L);
83articleDto.setAuthor(authorDto);
84
85final String message = mockMvc.perform(post("/api/v1/articles")
86.contentType(APPLICATION_JSON)
87.content(json(articleDto))
88)
89.andExpect(status().isBadRequest())
90.andReturn().getResolvedException().getMessage();
91assertThat(message, containsString("Article id shouldn't be present"));
92}
93
94@Test
95public void createArticleWithoutTitle() throws Exception {
96ArticleDto articleDto = new ArticleDto();
97articleDto.setSummary("Some summary value");
98articleDto.setText("Some text");
99AuthorDto authorDto = new AuthorDto();
100authorDto.setId(1L);
101articleDto.setAuthor(authorDto);
102
103final String message = mockMvc.perform(post("/api/v1/articles")
104.contentType(APPLICATION_JSON)
105.content(json(articleDto))
106)
107.andExpect(status().isBadRequest())
108.andReturn().getResolvedException().getMessage();
109assertThat(message, containsString("Title should be populated"));
110}
111
112@Test
113public void createArticleWithEmptyTitle() throws Exception {
114ArticleDto articleDto = new ArticleDto();
115articleDto.setTitle("");
116articleDto.setSummary("Some summary value");
117articleDto.setText("Some text");
118AuthorDto authorDto = new AuthorDto();
119authorDto.setId(1L);
120articleDto.setAuthor(authorDto);
121
122final String message = mockMvc.perform(post("/api/v1/articles")
123.contentType(APPLICATION_JSON)
124.content(json(articleDto))
125)
126.andExpect(status().isBadRequest())
127.andReturn().getResolvedException().getMessage();
128assertThat(message, containsString("Title length must be between 1 and 100"));
129}
130
131@Test
132public void createArticleWithTooLongTitle() throws Exception {
133ArticleDto articleDto = new ArticleDto();
134articleDto.setTitle(createStringWithLength(101));
135articleDto.setSummary("Some summary value");
136articleDto.setText("Some text");
137AuthorDto authorDto = new AuthorDto();
138authorDto.setId(1L);
139articleDto.setAuthor(authorDto);
140
141String message = mockMvc.perform(post("/api/v1/articles")
142.contentType(APPLICATION_JSON)
143.content(json(articleDto))
144)
145.andExpect(status().isBadRequest())
146.andReturn().getResolvedException().getMessage();
147assertThat(message, containsString("Title length must be between 1 and 100"));
148}
149
150@Test
151public void createArticleWithTooLongSummary() throws Exception {
152ArticleDto articleDto = new ArticleDto();
153articleDto.setTitle("Some title");
154articleDto.setSummary(createStringWithLength(260));
155articleDto.setText("Some text");
156AuthorDto authorDto = new AuthorDto();
157authorDto.setId(1L);
158articleDto.setAuthor(authorDto);
159
160String message = mockMvc.perform(post("/api/v1/articles")
161.contentType(APPLICATION_JSON)
162.content(json(articleDto))
163)
164.andExpect(status().isBadRequest())
165.andReturn().getResolvedException().getMessage();
166assertThat(message, containsString("Summary length shouldn't be greater than 255"));
167}
168
169@Test
170public void createArticleWithoutText() throws Exception {
171ArticleDto articleDto = new ArticleDto();
172articleDto.setTitle("Some title");
173articleDto.setSummary("Some summary value");
174AuthorDto authorDto = new AuthorDto();
175authorDto.setId(1L);
176articleDto.setAuthor(authorDto);
177
178String message = mockMvc.perform(post("/api/v1/articles")
179.contentType(APPLICATION_JSON)
180.content(json(articleDto))
181)
182.andExpect(status().isBadRequest())
183.andReturn().getResolvedException().getMessage();
184assertThat(message, containsString("Text should be populated"));
185}
186
187@Test
188public void createArticleWithEmptyText() throws Exception {
189ArticleDto articleDto = new ArticleDto();
190articleDto.setTitle("Some title");
191articleDto.setSummary("Some summary value");
192articleDto.setText("");
193AuthorDto authorDto = new AuthorDto();
194authorDto.setId(1L);
195articleDto.setAuthor(authorDto);
196
197String message = mockMvc.perform(post("/api/v1/articles")
198.contentType(APPLICATION_JSON)
199.content(json(articleDto))
200)
201.andExpect(status().isBadRequest())
202.andReturn().getResolvedException().getMessage();
203assertThat(message, containsString("Text length should be 1 at least"));
204}
205
206@Test
207public void createArticleWithoutAuthor() throws Exception {
208ArticleDto articleDto = new ArticleDto();
209articleDto.setTitle("Some title");
210articleDto.setSummary("Some summary value");
211articleDto.setText("Some text");
212
213String message = mockMvc.perform(post("/api/v1/articles")
214.contentType(APPLICATION_JSON)
215.content(json(articleDto))
216)
217.andExpect(status().isBadRequest())
218.andReturn().getResolvedException().getMessage();
219assertThat(message, containsString("Author should be populated"));
220}
221
222@Test
223public void createArticleWithWrongAuthor() throws Exception {
224ArticleDto articleDto = new ArticleDto();
225articleDto.setTitle("Some title");
226articleDto.setSummary("Some summary value");
227articleDto.setText("Some text");
228AuthorDto authorDto = new AuthorDto();
229authorDto.setId(100L);
230articleDto.setAuthor(authorDto);
231
232String message = mockMvc.perform(post("/api/v1/articles")
233.contentType(APPLICATION_JSON)
234.content(json(articleDto))
235)
236.andExpect(status().isBadRequest())
237.andReturn().getResolvedException().getMessage();
238assertThat(message, containsString("Unknown author"));
239}
240
241@Test
242public void createArticleWithDateCreatedPopulated() throws Exception {
243ArticleDto articleDto = new ArticleDto();
244articleDto.setTitle("Some tittle value");
245articleDto.setSummary("Some summary value");
246articleDto.setText("Some text");
247AuthorDto authorDto = new AuthorDto();
248authorDto.setId(1L);
249articleDto.setAuthor(authorDto);
250articleDto.setDateCreated(LocalDateTime.now());
251
252String message = mockMvc.perform(post("/api/v1/articles")
253.contentType(APPLICATION_JSON)
254.content(json(articleDto))
255)
256.andExpect(status().isBadRequest())
257.andReturn().getResolvedException().getMessage();
258assertThat(message, containsString("DateCreated shouldn't be populated"));
259}
260
261@Test
262public void createArticleWithDateUpdatedPopulated() throws Exception {
263ArticleDto articleDto = new ArticleDto();
264articleDto.setTitle("Some tittle value");
265articleDto.setSummary("Some summary value");
266articleDto.setText("Some text");
267AuthorDto authorDto = new AuthorDto();
268authorDto.setId(1L);
269articleDto.setAuthor(authorDto);
270articleDto.setDateUpdated(LocalDateTime.now());
271
272String message = mockMvc.perform(post("/api/v1/articles")
273.contentType(APPLICATION_JSON)
274.content(json(articleDto))
275)
276.andExpect(status().isBadRequest())
277.andReturn().getResolvedException().getMessage();
278assertThat(message, containsString("DateUpdated shouldn't be populated"));
279}
280
281@Test
282public void deleteArticle() throws Exception {
283mockMvc.perform(delete("/api/v1/articles/1")
284.contentType(APPLICATION_JSON)
285)
286.andExpect(status().isNoContent());
287}
288
289@Test
290public void deleteAbsentArticle() throws Exception {
291mockMvc.perform(delete("/api/v1/articles/9999")
292.contentType(APPLICATION_JSON))
293.andExpect(status().isNotFound());
294}
295
296@Test
297public void readArticle() throws Exception {
298mockMvc.perform(get("/api/v1/articles/1")
299.contentType(APPLICATION_JSON)
300)
301.andExpect(status().isOk())
302.andExpect(jsonPath("$.id", is(1)));
303}
304
305@Test
306public void readAbsentArticle() throws Exception {
307mockMvc.perform(get("/api/v1/articles/345")
308.contentType(APPLICATION_JSON))
309.andExpect(status().isNotFound());
310}
311
312@Test
313public void readArticles() throws Exception {
314mockMvc.perform(get("/api/v1/articles")
315.contentType(APPLICATION_JSON)
316)
317.andExpect(status().isOk())
318.andExpect(jsonPath("$.content", hasSize(10)))
319.andExpect(jsonPath("$.number", is(0)))
320.andExpect(jsonPath("$.size", is(50)))
321.andExpect(jsonPath("$.totalPages", is(1)))
322.andExpect(jsonPath("$.totalElements", is(10)));
323}
324
325@Test
326public void readArticlesWithPageSizeLimit() throws Exception {
327mockMvc.perform(get("/api/v1/articles")
328.param("size", "5")
329.contentType(APPLICATION_JSON)
330)
331.andExpect(status().isOk())
332.andExpect(jsonPath("$.content", hasSize(5)))
333.andExpect(jsonPath("$.number", is(0)))
334.andExpect(jsonPath("$.size", is(5)))
335.andExpect(jsonPath("$.totalPages", is(2)))
336.andExpect(jsonPath("$.totalElements", is(9)));
337}
338
339@Test
340public void updateArticleTitle() throws Exception {
341ArticleUpdateDto articleUpdateDto = new ArticleUpdateDto();
342articleUpdateDto.setTitle("Some tittle value");
343
344mockMvc.perform(patch("/api/v1/articles/2")
345.contentType(APPLICATION_JSON)
346.content(json(articleUpdateDto))
347)
348.andExpect(status().isOk());
349}
350
351@Test
352public void updateArticleSummary() throws Exception {
353ArticleUpdateDto articleUpdateDto = new ArticleUpdateDto();
354articleUpdateDto.setSummary("Some summary value");
355
356mockMvc.perform(patch("/api/v1/articles/2")
357.contentType(APPLICATION_JSON)
358.content(json(articleUpdateDto))
359)
360.andExpect(status().isOk());
361}
362
363@Test
364public void updateArticleText() throws Exception {
365ArticleUpdateDto articleUpdateDto = new ArticleUpdateDto();
366articleUpdateDto.setText("Some text value");
367
368mockMvc.perform(patch("/api/v1/articles/2")
369.contentType(APPLICATION_JSON)
370.content(json(articleUpdateDto))
371)
372.andExpect(status().isOk());
373}
374
375@Test
376public void updateArticleMultipleFields() throws Exception {
377ArticleUpdateDto articleUpdateDto = new ArticleUpdateDto();
378articleUpdateDto.setSummary("Some summary value");
379articleUpdateDto.setText("Some text value");
380
381String message = mockMvc.perform(patch("/api/v1/articles/2")
382.contentType(APPLICATION_JSON)
383.content(json(articleUpdateDto))
384)
385.andExpect(status().isBadRequest())
386.andReturn().getResolvedException().getMessage();
387assertThat(message, containsString("Only one field should be modified at once"));
388}
389
390@Test
391public void updateAbsentArticle() throws Exception {
392ArticleUpdateDto articleUpdateDto = new ArticleUpdateDto();
393articleUpdateDto.setTitle("q");
394
395mockMvc.perform(patch("/api/v1/articles/123")
396.contentType(APPLICATION_JSON)
397.content(json(articleUpdateDto)))
398.andExpect(status().isNotFound());
399}
400
401@Test
402public void updateArticleWithEmptyTitle() throws Exception {
403ArticleUpdateDto articleUpdateDto = new ArticleUpdateDto();
404articleUpdateDto.setTitle("");
405
406String message = mockMvc.perform(patch("/api/v1/articles/2")
407.contentType(APPLICATION_JSON)
408.content(json(articleUpdateDto))
409)
410.andExpect(status().isBadRequest())
411.andReturn().getResolvedException().getMessage();
412assertThat(message, containsString("Title length must be between 1 and 100"));
413}
414
415@Test
416public void updateArticleWithTooLongTitle() throws Exception {
417ArticleUpdateDto articleUpdateDto = new ArticleUpdateDto();
418articleUpdateDto.setTitle(createStringWithLength(101));
419
420String message = mockMvc.perform(patch("/api/v1/articles/2")
421.contentType(APPLICATION_JSON)
422.content(json(articleUpdateDto))
423)
424.andExpect(status().isBadRequest())
425.andReturn().getResolvedException().getMessage();
426assertThat(message, containsString("Title length must be between 1 and 100"));
427}
428
429@Test
430public void updateArticleWithTooLongSummary() throws Exception {
431ArticleUpdateDto articleUpdateDto = new ArticleUpdateDto();
432articleUpdateDto.setSummary(createStringWithLength(260));
433
434String message = mockMvc.perform(patch("/api/v1/articles/2")
435.contentType(APPLICATION_JSON)
436.content(json(articleUpdateDto))
437)
438.andExpect(status().isBadRequest())
439.andReturn().getResolvedException().getMessage();
440assertThat(message, containsString("Summary length shouldn't be greater than 255"));
441}
442
443@Test
444public void updateArticleWithEmptyText() throws Exception {
445ArticleUpdateDto articleUpdateDto = new ArticleUpdateDto();
446articleUpdateDto.setText("");
447
448String message = mockMvc.perform(patch("/api/v1/articles/2")
449.contentType(APPLICATION_JSON)
450.content(json(articleUpdateDto))
451)
452.andExpect(status().isBadRequest())
453.andReturn().getResolvedException().getMessage();
454assertThat(message, containsString("Text length should be 1 at least"));
455}
456
457private String json(Object o) throws IOException {
458return objectMapper.writeValueAsString(o);
459}
460
461private String createStringWithLength(int length) {
462StringBuilder builder = new StringBuilder();
463for (int index = 0; index < length; index++) {
464builder.append("a");
465}
466return builder.toString();
467}
468}
469