Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

- added Spring Test MVC unit and integration tests #23

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions assignments/Asgn1-VideoUp/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ dependencies {
compile(":mobilecloud.handin:1.0.0")

testCompile("junit:junit")
testCompile("com.jayway.jsonpath:json-path:0.9.1")
testCompile("com.jayway.jsonpath:json-path-assert:0.9.1")
testCompile("commons-fileupload:commons-fileupload:1.3.1")
}

task wrapper(type: Wrapper) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package org.magnum.dataup;

import com.jayway.jsonassert.JsonAssert;
import com.jayway.jsonpath.JsonPath;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.Matchers.greaterThan;
import static org.junit.Assert.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

/**
* Created by vigi on 8/10/2014.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class VideoControllerTest {

@Autowired
private WebApplicationContext wac;

private MockMvc mockMvc;

private final File testVideoFile = new File("src/test/resources/test.mp4");

@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}

@AfterClass
public static void cleanup() throws IOException {
FileUtils.deleteDirectory(new File("videos"));
}

@Test
public void should_add_a_video_metadata() throws Exception {
ResultActions resultActions = performAddVideo("lotr", "fantasy", 567);
int videoId = parseVideoId(resultActions);

resultActions.andExpect(status().isOk())
.andExpect(content().contentType("application/json;charset=UTF-8"))
.andExpect(jsonPath("$.id").value(videoId))
.andExpect(jsonPath("$.title").value("lotr"))
.andExpect(jsonPath("$.subject").value("fantasy"))
.andExpect(jsonPath("$.duration").value(567))
.andExpect(jsonPath("$.dataUrl")
.value(String.format("http://localhost/video/%s/data", videoId)));
}

@Test
public void should_get_all_videos() throws Exception {
int videoId1 = parseVideoId(performAddVideo("title1", "subject1", 111));
int videoId2 = parseVideoId(performAddVideo("title2", "subject2", 222));

MvcResult resultActions = mockMvc.perform(get("/video")).andReturn();
String json = resultActions.getResponse().getContentAsString();

JsonAssert.with(json)
.assertThat("$", is(JsonAssert.collectionWithSize(greaterThan(2))))
.assertThat("$..id", hasItems(videoId1, videoId2))
.assertThat("$..title", hasItems("title1", "title2"))
.assertThat("$..duration", hasItems(111, 222))
.assertThat("$..subject", hasItems("subject1", "subject2"));
}

@Test
public void should_upload_video_data() throws Exception {
int videoId = parseVideoId(performAddVideo());

mockMvc.perform(fileUpload("/video/{id}/data", videoId)
.file(fileToUpload()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.state").value("READY"));

byte[] originalFile = IOUtils.toByteArray(new FileInputStream(testVideoFile));
MvcResult downloadResult = mockMvc.perform(get("/video/{id}/data", videoId)).andReturn();
byte[] downloadedFile = downloadResult.getResponse().getContentAsByteArray();

assertThat(originalFile, equalTo(downloadedFile));
}

@Test
public void should_not_be_able_to_add_video_data_for_a_nonexistent_video() throws Exception {
mockMvc.perform(fileUpload("/video/{id}/data", -1)
.file(fileToUpload()))
.andExpect(status().is(404));
}

private MockMultipartFile fileToUpload() throws IOException {
return new MockMultipartFile("data", "test.mp4", "video/mp4",
new FileInputStream(testVideoFile));
}

@Test
public void get_non_existent_video_data_should_return_a_404_not_found() throws Exception {
mockMvc.perform(get("/video/{id}/data", -2))
.andExpect(status().is(404));
}

private ResultActions performAddVideo(String title, String subject, int duration) throws Exception {
String jsonTemplate = "{\"id\":0,\"title\":\"%s\",\"duration\":%s,\"location\":null,\"subject\":\"%s\",\"contentType\":\"video/mp4\"}";
return mockMvc.perform(post("/video")
.content(String.format(jsonTemplate, title, duration, subject))
.contentType(MediaType.APPLICATION_JSON));
}

private ResultActions performAddVideo() throws Exception {
// use some default values for video metadata
return performAddVideo("test_title", "test_subject", 123);
}

private int parseVideoId(ResultActions addedVideoAction) throws Exception {
String json = addedVideoAction.andReturn().getResponse().getContentAsString();
return JsonPath.read(json, "$.id");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package org.magnum.dataup;

import com.jayway.jsonpath.JsonPath;
import org.apache.commons.io.FileUtils;
import org.junit.AfterClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.magnum.dataup.model.Video;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.*;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
import static org.junit.Assert.assertThat;

/**
* Created by vigi on 8/10/2014.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@IntegrationTest
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class VideoControllerTestIT {

private final RestTemplate restTemplate = new TestRestTemplate();

@AfterClass
public static void cleanup() throws IOException {
FileUtils.deleteDirectory(new File("videos"));
}

@Test
public void should_add_a_video() throws Exception {
// even though it is not a good practice, for this class we assume that the test methods
// will be executed in the ascending order of their lexicographic names
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
String videoJson = "{\"id\":0,\"title\":\"hodor\",\"duration\":123,\"location\":null,\"subject\":\"hodor hodor\",\"contentType\":\"video/mp4\"}";
HttpEntity<String> entity = new HttpEntity<>(videoJson, headers);
Video added = restTemplate.postForObject("http://localhost:8080/video", entity, Video.class);

assertThat(added.getId(), is(1L));
}

@Test
public void should_get_all_videos_and_read_them_as_Strings() {
String json = restTemplate.getForObject("http://localhost:8080/video", String.class);
List<Video> videos = JsonPath.read(json, "$");

assertThat(videos, hasSize(1));
assertThat((Integer) JsonPath.read(json, "$.[0].id"), is(1));
assertThat((String) JsonPath.read(json, "$.[0].title"), is("hodor"));
assertThat((Integer) JsonPath.read(json, "$.[0].duration"), is(123));
assertThat((String) JsonPath.read(json, "$.[0].subject"), is("hodor hodor"));
assertThat((String) JsonPath.read(json, "$.[0].contentType"), is("video/mp4"));
}

@Test
public void should_get_all_videos_and_read_them_as_objects() {
List<Map<String, Object>> videos = restTemplate.getForObject("http://localhost:8080/video", List.class);

assertThat(videos, hasSize(1));
assertThat((Integer) videos.get(0).get("id"), is(1));
assertThat((String) videos.get(0).get("title"), is("hodor"));
assertThat((Integer) videos.get(0).get("duration"), is(123));
assertThat((String) videos.get(0).get("subject"), is("hodor hodor"));
assertThat((String) videos.get(0).get("contentType"), is("video/mp4"));
}

@Test
public void get_video_data_for_nonexistent_video_should_give_a_404() {
ResponseEntity<String> entity = restTemplate.getForEntity("http://localhost:8080/video/-1/data", String.class);
assertThat(entity.getStatusCode(), is(HttpStatus.NOT_FOUND));
}

@Test
public void should_upload_video_data() throws IOException {
ResponseEntity<String> noDataEntity = restTemplate.getForEntity("http://localhost:8080/video/1/data", String.class);
assertThat(noDataEntity.getStatusCode(), is(HttpStatus.NOT_FOUND));

ResponseEntity<String> uploadResult = uploadDataForVideo(1L);
assertThat(uploadResult.getStatusCode(), is(HttpStatus.OK));
assertThat((String) JsonPath.read(uploadResult.getBody(), "$.state"), is("READY"));

ResponseEntity<String> entity = restTemplate.getForEntity("http://localhost:8080/video/1/data", String.class);
assertThat(entity.getStatusCode(), is(HttpStatus.OK));
}

@Test
public void upload_video_data_for_non_existent_video_should_return_a_404() {
ResponseEntity<String> uploadResult = uploadDataForVideo(-1L);
assertThat(uploadResult.getStatusCode(), is(HttpStatus.NOT_FOUND));
}

private ResponseEntity<String> uploadDataForVideo(Long videoId) {
Resource resource = new FileSystemResource("src/test/resources/test.mp4");
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
parts.add("Content-Type", "video/mp4");
parts.add("data", resource);
return restTemplate.postForEntity("http://localhost:8080/video/{id}/data", parts, String.class, videoId);
}

}