1 package org.imageconverter.controller.imagetype;
2
3 import static org.hamcrest.CoreMatchers.containsString;
4 import static org.hamcrest.Matchers.containsInAnyOrder;
5 import static org.imageconverter.util.controllers.imagetype.ImageTypeConst.REST_URL;
6 import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
7 import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
8 import static org.springframework.test.context.jdbc.SqlConfig.ErrorMode.CONTINUE_ON_ERROR;
9 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
10 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
11 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
12 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
13 import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
14 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
15 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
16
17 import java.util.Map;
18
19 import org.imageconverter.TestConstants;
20 import org.imageconverter.controller.ImageTypeRestController;
21 import org.imageconverter.util.controllers.imagetype.CreateImageTypeRequest;
22 import org.imageconverter.util.controllers.imagetype.UpdateImageTypeRequest;
23 import org.junit.jupiter.api.DisplayName;
24 import org.junit.jupiter.api.MethodOrderer;
25 import org.junit.jupiter.api.Order;
26 import org.junit.jupiter.api.Tag;
27 import org.junit.jupiter.api.Test;
28 import org.junit.jupiter.api.TestInstance;
29 import org.junit.jupiter.api.TestMethodOrder;
30 import org.springframework.beans.factory.annotation.Autowired;
31 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
32 import org.springframework.boot.test.context.SpringBootTest;
33 import org.springframework.http.MediaType;
34 import org.springframework.security.test.context.support.WithMockUser;
35 import org.springframework.test.context.ActiveProfiles;
36 import org.springframework.test.context.jdbc.Sql;
37 import org.springframework.test.context.jdbc.SqlConfig;
38 import org.springframework.test.web.servlet.MockMvc;
39
40 import com.fasterxml.jackson.databind.ObjectMapper;
41
42
43
44
45
46
47 @ActiveProfiles("test")
48 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
49 @AutoConfigureMockMvc
50 @WithMockUser(username = "user")
51 @Sql(scripts = "classpath:db/db-data-test.sql", config = @SqlConfig(errorMode = CONTINUE_ON_ERROR))
52 @Sql(statements = "DELETE FROM image_type WHERE IMT_EXTENSION = 'BMP' ")
53
54 @Tag("acceptance")
55 @DisplayName("Test the image type controller, unhappy path :( 𝅘𝅥𝅮 Hello, darkness, my old friend ")
56 @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
57 @TestInstance(PER_CLASS)
58 class ImageTypeRestControllerUnHappyPathMovTest extends ImageTypeRestControllerUnHappyPathBaseTest {
59
60 private final CreateImageTypeRequest createImageTypeRequest;
61
62 @Autowired
63 ImageTypeRestControllerUnHappyPathMovTest(final ObjectMapper mapper, final MockMvc mvc) {
64 super(mapper, mvc);
65 this.createImageTypeRequest = new CreateImageTypeRequest("BMP", "BitMap", "Device independent bitmap");
66 }
67
68 @Test
69 @Order(4)
70 @DisplayName("Create twice the same image type")
71 void createSameImageTypeTest() throws Exception {
72
73
74
75 final var content = asJsonString(createImageTypeRequest);
76
77 final var request = post(REST_URL)
78 .content(content)
79 .contentType(MediaType.APPLICATION_JSON)
80 .accept(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON)
81 .with(csrf());
82
83 mvc.perform(request)
84 .andDo(print())
85 .andExpect(status().isCreated())
86 ;
87
88
89 mvc.perform(request)
90
91
92 .andDo(print())
93
94
95 .andExpect(status().isConflict())
96 .andExpect(jsonPath(TestConstants.JSON_MESSAGE).value(containsString("The ImageType with field(s) extension '" + createImageTypeRequest.extension() + "' already exists")))
97
98 ;
99
100 }
101
102 @Test
103 @Order(5)
104 @DisplayName("Try to create image type with invalid json")
105 void createInvalidImageTypeTest() throws Exception {
106
107
108
109 final var json = """
110 {
111 "blabla": "BMP",
112 "name": "BitMap",
113 "description": "Device independent bitmap"
114 }
115 """;
116
117 final var request = post(REST_URL)
118 .content(json)
119 .contentType(MediaType.APPLICATION_JSON)
120 .accept(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON)
121 .with(csrf());
122
123
124 mvc.perform(request)
125
126
127 .andDo(print())
128
129
130 .andExpect(status().isBadRequest())
131 .andExpect(jsonPath(TestConstants.JSON_MESSAGE).value(containsString("Missing required creator property 'extension'")))
132 ;
133 }
134
135 @Test
136 @Order(6)
137 @DisplayName("Try to create image type with invalid value")
138 void createInvalidImageTypeTest2() throws Exception {
139
140
141
142 final var json = """
143 {
144 "extension": "BMP",
145 "name": "",
146 "description": "Device independent bitmap"
147 } """;
148
149 final var request = post(REST_URL)
150 .content(json)
151 .contentType(MediaType.APPLICATION_JSON)
152 .accept(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON)
153 .with(csrf());
154
155
156 mvc.perform(request)
157
158
159 .andDo(print())
160
161
162 .andExpect(status().isBadRequest())
163 .andExpect(jsonPath(TestConstants.JSON_MESSAGE).value(containsString("Validation error")))
164 .andExpect(jsonPath("$.subErrors", containsInAnyOrder(
165 Map.of("field", "name", "error", "The 'name' cannot be empty", "object", "createImageTypeRequest"))));
166
167 ;
168
169 }
170
171 @Test
172 @Order(7)
173 @DisplayName("Try to update a image type that doesn't exist")
174 void updateImageTypeDoesNotExistTest() throws Exception {
175
176
177 final var id = "12345";
178
179
180 final var newTypeRequest = new UpdateImageTypeRequest(null, "BitmapNew", null);
181
182 final var request = put(REST_URL + TestConstants.ID_PARAM_VALUE, id)
183 .content(asJsonString(newTypeRequest))
184 .contentType(MediaType.APPLICATION_JSON)
185 .accept(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON)
186 .with(csrf());
187
188
189 mvc.perform(request)
190
191
192 .andDo(print())
193
194
195 .andExpect(status().isNotFound())
196 .andExpect(jsonPath(TestConstants.JSON_MESSAGE).value(containsString("ImageType with id '" + id + "' not found")))
197 ;
198 }
199
200 @Test
201 @Order(8)
202 @DisplayName("Try to delete a image type that doesn't exist")
203 void deleteImageTypeDoesNotExistTest() throws Exception {
204
205
206 final var id = "12356";
207
208 final var request = delete(REST_URL + TestConstants.ID_PARAM_VALUE, id)
209 .accept(MediaType.APPLICATION_JSON)
210 .with(csrf());
211
212
213 mvc.perform(request)
214
215
216 .andDo(print())
217
218
219 .andExpect(status().isNotFound())
220 .andExpect(jsonPath(TestConstants.JSON_MESSAGE).value(containsString("ImageType with id '" + id + "' not found")))
221 ;
222 }
223
224 @Test
225 @Order(9)
226 @DisplayName("Try to delete a image type that has a relation with other record")
227 void deleteImageTypeRestrictionTest() throws Exception {
228
229
230 final var id = "1001";
231
232 final var request = delete(REST_URL + TestConstants.ID_PARAM_VALUE, id)
233 .accept(MediaType.APPLICATION_JSON)
234 .with(csrf());
235
236
237 mvc.perform(request)
238
239
240 .andDo(print())
241
242
243 .andExpect(status().isConflict())
244 .andExpect(jsonPath(TestConstants.JSON_MESSAGE).value(containsString("You cannot delete the image type '1001' because it is already used")))
245 ;
246 }
247
248 @Test
249 @Order(10)
250 @DisplayName("Try to access a invalid url")
251 void invalidUrlTest() throws Exception {
252
253
254 final var request = get(REST_URL + "/blablabla")
255 .accept(MediaType.ALL, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN)
256 .with(csrf());
257
258 mvc.perform(request)
259
260
261 .andDo(print())
262
263
264 .andExpect(status().isNotFound())
265 .andExpect(jsonPath(TestConstants.JSON_MESSAGE)
266 .value(containsString("Resource not found. Please check the /swagger-ui/index.html?configUrl=/v3/api-docs/swagger-config for more information")))
267 ;
268
269 }
270 }