1 package dst.ass2.service.courseplan.tests;
3 import static org.hamcrest.CoreMatchers.allOf;
4 import static org.hamcrest.CoreMatchers.hasItem;
5 import static org.hamcrest.CoreMatchers.is;
6 import static org.hamcrest.CoreMatchers.not;
7 import static org.hamcrest.CoreMatchers.notNullValue;
8 import static org.junit.Assert.assertThat;
10 import org.junit.Before;
11 import org.junit.Test;
12 import org.junit.runner.RunWith;
13 import org.springframework.beans.factory.annotation.Autowired;
14 import org.springframework.boot.context.embedded.LocalServerPort;
15 import org.springframework.boot.test.context.SpringBootTest;
16 import org.springframework.boot.test.web.client.TestRestTemplate;
17 import org.springframework.http.HttpEntity;
18 import org.springframework.http.HttpHeaders;
19 import org.springframework.http.HttpMethod;
20 import org.springframework.http.HttpStatus;
21 import org.springframework.http.MediaType;
22 import org.springframework.http.ResponseEntity;
23 import org.springframework.test.context.ActiveProfiles;
24 import org.springframework.test.context.junit4.SpringRunner;
25 import org.springframework.util.LinkedMultiValueMap;
26 import org.springframework.util.MultiValueMap;
28 import dst.ass1.jpa.tests.TestData;
29 import dst.ass2.service.api.courseplan.CoursePlan;
30 import dst.ass2.service.courseplan.CoursePlanApplication;
32 @RunWith(SpringRunner.class)
33 @SpringBootTest(classes = CoursePlanApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
34 @ActiveProfiles("testdata")
35 @org.springframework.transaction.annotation.Transactional
36 public class CoursePlanResourceTest {
39 private TestData testData;
44 private TestRestTemplate restTemplate;
45 private HttpHeaders headers;
49 headers = new HttpHeaders();
50 restTemplate = new TestRestTemplate();
54 public void createCoursePlan_withWrongHttpMethod_returnsError() {
55 String url = url("/courseplans");
56 ResponseEntity<String> response = restTemplate.getForEntity(url, String.class, body("membershipId", testData.membership1Id));
58 assertThat("Response was: " + response, response.getStatusCode().series(), is(HttpStatus.Series.CLIENT_ERROR));
62 public void createCoursePlan_withNonExistingMembershipKey_returnsNotFoundError() {
63 headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
64 String url = url("/courseplans");
65 MultiValueMap<String, String> body = body("membershipId", 123456789);
67 HttpEntity<?> request = new HttpEntity<>(body, headers);
68 ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
70 assertThat("Response was: " + response, response.getStatusCode(), is(HttpStatus.NOT_FOUND));
74 public void createCoursePlan_withExistingMembershipKey_returnsCourseplanId() {
75 headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
76 String url = url("/courseplans");
77 MultiValueMap<String, String> body = body("membershipId", testData.membership1Id);
79 HttpEntity<?> request = new HttpEntity<>(body, headers);
80 ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
82 assertThat(response.getStatusCode().series(), is(HttpStatus.Series.SUCCESSFUL));
83 assertThat(response.getBody(), notNullValue());
86 Long.parseLong(response.getBody());
87 } catch (NumberFormatException e) {
88 throw new AssertionError("Response body of " + url + " should be a Long value (the courseplan ID)", e);
93 public void getCoursePlan_onNonExistingPlan_returns404() {
94 String url = url("/courseplans/" + 12345678);
95 ResponseEntity<?> response = restTemplate.getForEntity(url, String.class);
96 assertThat("Response was: " + response, response.getStatusCode(), is(HttpStatus.NOT_FOUND));
100 public void getCoursePlan_onCreatedCoursePlan_returnsJsonEntity() {
101 Long id = createCoursePlan(testData.membership1Id);
103 String url = url("/courseplans/" + id);
104 ResponseEntity<CoursePlan> response = restTemplate.getForEntity(url, CoursePlan.class);
106 assertThat("Response was: " + response, response.getStatusCode().series(), is(HttpStatus.Series.SUCCESSFUL));
107 assertThat(response.getBody(), notNullValue());
108 assertThat(response.getBody().getId(), is(id));
109 assertThat(response.getBody().getMembershipId(), is(testData.membership1Id));
113 public void addCourse_onCreatedCoursePlan_returnsOk() {
114 Long id = createCoursePlan(testData.membership2Id);
115 ResponseEntity<String> response = addCourse(id, testData.course2Id);
116 assertThat("Response was: " + response, response.getStatusCode().series(), is(HttpStatus.Series.SUCCESSFUL));
120 public void addCourse_andThenGetCoursePlan_containsCourseInList() {
121 Long id = createCoursePlan(testData.membership2Id);
123 addCourse(id, testData.course2Id);
124 CoursePlan coursePlan = getCoursePlan(id);
126 assertThat(coursePlan.getCourses().size(), is(1));
127 assertThat(coursePlan.getCourses(), hasItem(testData.course2Id));
131 public void addCourse_onUnavailableCourse_returnsAppropriateError() {
132 Long id = createCoursePlan(testData.membership1Id);
133 ResponseEntity<String> response = addCourse(id, testData.course1Id);
135 assertThat("Make use of an appropriate HTTP status code", response.getStatusCode(), allOf(
136 is(not(HttpStatus.OK)),
137 is(not(HttpStatus.NOT_FOUND)),
138 is(not(HttpStatus.INTERNAL_SERVER_ERROR))
143 public void addCourse_onNonExistingCourse_returns404() {
144 Long id = createCoursePlan(testData.membership1Id);
145 ResponseEntity<String> response = addCourse(id, 123456789L);
146 assertThat("Response was: " + response, response.getStatusCode(), is(HttpStatus.NOT_FOUND));
150 public void submit_nonExistingCoursePlan_returns404() {
151 headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
152 String url = url("/courseplans/123456789/submit");
153 ResponseEntity<String> response = restTemplate.postForEntity(url, new LinkedMultiValueMap<>(), String.class);
154 assertThat("Response was: " + response, response.getStatusCode(), is(HttpStatus.NOT_FOUND));
158 public void submit_onExistingCoursePlan_returnsOk() {
159 Long id = createCoursePlan(testData.membership2Id);
160 addCourse(id, testData.course3Id);
162 headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
163 String url = url("/courseplans/" + id + "/submit");
164 ResponseEntity<String> response = restTemplate.postForEntity(url, new LinkedMultiValueMap<>(), String.class);
165 assertThat("Response was: " + response, response.getStatusCode().series(), is(HttpStatus.Series.SUCCESSFUL));
169 public void delete_existingCoursePlan_returnsSuccessful() {
170 Long id = createCoursePlan(testData.membership1Id);
171 String url = url("/courseplans/" + id);
173 HttpEntity<?> request = new HttpEntity<>(null, headers);
175 ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.DELETE, request, String.class);
176 assertThat("Response was: " + response, response.getStatusCode().series(), is(HttpStatus.Series.SUCCESSFUL));
180 public void delete_nonExistingCoursePlan_returns404() {
181 String url = url("/courseplans/12345678");
182 HttpEntity<?> request = new HttpEntity<>(null, headers);
184 ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.DELETE, request, String.class);
185 assertThat("Response was: " + response, response.getStatusCode(), is(HttpStatus.NOT_FOUND));
188 private CoursePlan getCoursePlan(Long id) {
189 String url = url("/courseplans/" + id);
190 ResponseEntity<CoursePlan> response = restTemplate.getForEntity(url, CoursePlan.class);
191 return response.getBody();
194 private Long createCoursePlan(Long membershipId) {
195 HttpHeaders headers = new HttpHeaders();
196 headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
197 String url = url("/courseplans");
198 MultiValueMap<String, String> body = body("membershipId", membershipId);
199 HttpEntity<?> request = new HttpEntity<>(body, headers);
200 ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
202 if(!response.getStatusCode().is2xxSuccessful()) {
203 throw new AssertionError("Expected createCoursePlan to return 2xx, instead got: " + response);
207 return Long.parseLong(response.getBody());
208 } catch (NumberFormatException e) {
209 throw new AssertionError("Expected createCoursePlan to return an id, instead got: " + response);
213 private ResponseEntity<String> addCourse(Long coursePlanId, Long courseId) {
214 HttpHeaders headers = new HttpHeaders();
215 headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
216 String url = url("/courseplans/" + coursePlanId + "/courses");
217 MultiValueMap<String, String> body = body("courseId", courseId);
218 return restTemplate.postForEntity(url, new HttpEntity<>(body, headers), String.class);
221 private String url(String uri) {
222 return "http://localhost:" + port + uri;
225 private MultiValueMap<String, String> body(String key, Object value) {
226 MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
227 map.add(key, String.valueOf(value));