Skip to content

Commit 3cae26c

Browse files
committed
Allow resuming traversal after a 204 no content
1 parent e1b4295 commit 3cae26c

File tree

6 files changed

+85
-0
lines changed

6 files changed

+85
-0
lines changed

core/src/main/java/com/cosium/hal_mock_mvc/Form.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ public HalMockMvc createAndShift() throws Exception {
128128
return requestExecutor.assertCreatedAndShift(submit());
129129
}
130130

131+
/** Submit the form by expecting 204 No Content then resume the traversal. */
132+
public HalMockMvc submitAndExpectNoContent() throws Exception {
133+
return requestExecutor.assert204NoContentAndResume(submit());
134+
}
135+
131136
/** Submits the form */
132137
public ResultActions submit() throws Exception {
133138
String contentType = template.representation().contentType();

core/src/main/java/com/cosium/hal_mock_mvc/RequestExecutor.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ public HalMockMvc assertCreatedAndShift(ResultActions resultActions) throws Exce
4545
return shiftTo(location);
4646
}
4747

48+
public HalMockMvc assert204NoContentAndResume(ResultActions resultActions) throws Exception {
49+
resultActions.andExpect(status().isNoContent());
50+
String requestURI = resultActions.andReturn().getRequest().getRequestURI();
51+
return shiftTo(requestURI);
52+
}
53+
4854
private HalMockMvc shiftTo(String location) {
4955
return HalMockMvc.builder(mockMvc)
5056
.baseUri(location)

core/src/main/java/com/cosium/hal_mock_mvc/SubmittableTemplate.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,7 @@ public interface SubmittableTemplate {
1515
* at the returned Location header.
1616
*/
1717
HalMockMvc createAndShift() throws Exception;
18+
19+
/** Submit the template by expecting 204 No Content then resume the traversal. */
20+
HalMockMvc submitAndExpect204NoContent() throws Exception;
1821
}

core/src/main/java/com/cosium/hal_mock_mvc/Template.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ public HalMockMvc createAndShift() throws Exception {
4545
return createAndShift(null);
4646
}
4747

48+
@Override
49+
public HalMockMvc submitAndExpect204NoContent() throws Exception {
50+
return submitAndExpect204NoContent(null);
51+
}
52+
4853
/**
4954
* Submits the template by expecting a 201 Created response then begins a new traversal starting
5055
* at the returned Location header.
@@ -55,6 +60,15 @@ public HalMockMvc createAndShift(String content) throws Exception {
5560
return requestExecutor.assertCreatedAndShift(submit(content));
5661
}
5762

63+
/**
64+
* Submit the template by expecting 204 No Content then resume the traversal.
65+
*
66+
* @param content The content to submit
67+
*/
68+
public HalMockMvc submitAndExpect204NoContent(String content) throws Exception {
69+
return requestExecutor.assert204NoContentAndResume(submit(content));
70+
}
71+
5872
@Override
5973
public ResultActions submit() throws Exception {
6074
return submit(null);

core/src/main/java/com/cosium/hal_mock_mvc/TemplateMultipartRequest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,9 @@ public ResultActions submit() throws Exception {
5151
public HalMockMvc createAndShift() throws Exception {
5252
return requestExecutor.assertCreatedAndShift(submit());
5353
}
54+
55+
@Override
56+
public HalMockMvc submitAndExpect204NoContent() throws Exception {
57+
return requestExecutor.assert204NoContentAndResume(submit());
58+
}
5459
}

core/src/test/java/com/cosium/hal_mock_mvc/HalMockMvcFormsTest.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.cosium.hal_mock_mvc;
22

33
import static org.assertj.core.api.Assertions.assertThat;
4+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
45
import static org.assertj.core.api.Assertions.tuple;
56
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.afford;
67
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
@@ -204,6 +205,48 @@ void test8() throws Exception {
204205
assertThat(myController.personByName).containsKey("john");
205206
}
206207

208+
@Test
209+
@DisplayName("PUT template then GET updated resource")
210+
void test9() throws Exception {
211+
212+
HalMockMvc.builder(mockMvc)
213+
.baseUri(linkTo(methodOn(MyController.class).list()).toUri())
214+
.build()
215+
.follow()
216+
.templates()
217+
.byKey("create")
218+
.createAndShift(JSON.std.composeString().startObject().put("name", "john").end().finish())
219+
.follow()
220+
.templates()
221+
.byKey("changeCity")
222+
.submitAndExpect204NoContent(
223+
JSON.std.composeString().startObject().put("city", "Casablanca").end().finish())
224+
.follow()
225+
.get()
226+
.andExpect(status().isOk())
227+
.andExpect(jsonPath("$.value").value("Casablanca"));
228+
}
229+
230+
@Test
231+
@DisplayName("submitAndExpect204NoContent fails if the response status is not 204")
232+
void test10() throws Exception {
233+
234+
Template template =
235+
HalMockMvc.builder(mockMvc)
236+
.baseUri(linkTo(methodOn(MyController.class).list()).toUri())
237+
.build()
238+
.follow()
239+
.templates()
240+
.byKey("create");
241+
242+
String createCommand =
243+
JSON.std.composeString().startObject().put("name", "john").end().finish();
244+
245+
assertThatThrownBy(() -> template.submitAndExpect204NoContent(createCommand))
246+
.isInstanceOf(AssertionError.class)
247+
.hasMessageContaining("Status expected:<204> but was:<201>");
248+
}
249+
207250
@Controller
208251
@RequestMapping("/HalMockMvcFormsTest")
209252
public static class MyController {
@@ -269,6 +312,15 @@ public ResponseEntity<?> changeCity(
269312
return ResponseEntity.noContent().build();
270313
}
271314

315+
@GetMapping("/{name}/city")
316+
public ResponseEntity<?> getCity(@PathVariable("name") String name) {
317+
PersonResource resource = personByName.get(name);
318+
if (resource == null) {
319+
return ResponseEntity.notFound().build();
320+
}
321+
return ResponseEntity.ok(Map.of("value", resource.city));
322+
}
323+
272324
@DeleteMapping("/{name}")
273325
public ResponseEntity<?> deleteByName(@PathVariable("name") String name) {
274326
personByName.remove(name);

0 commit comments

Comments
 (0)