package org.cbir.retrieval.web.rest;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import org.cbir.retrieval.Application;
import org.cbir.retrieval.service.RetrievalService;
import org.cbir.retrieval.service.StoreImageService;
import org.cbir.retrieval.service.exception.ResourceNotFoundException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
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.util.ReflectionTestUtils;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.util.NestedServletException;
import retrieval.server.RetrievalServer;
import javax.imageio.ImageIO;
import javax.inject.Inject;
import java.awt.image.BufferedImage;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
/**
* Test class for the UserResource REST controller.
*
* @see UserResource
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class ImageResourceTest {
public static String DEFAULT_STORAGE = "default";
public static long NUMBER_OF_PICTURES_AT_BEGINNING = 4;
public static String[] IMAGE_PATHS = {
"testdata/images/crop1.jpg",
"testdata/images/crop2.jpg",
"testdata/images/crop3.jpg",
"testdata/images/crop4.jpg",
"testdata/images/crop5.jpg",
"testdata/images/crop6.jpg",
"testdata/images/crop7.jpg",
"testdata/images/crop8.jpg",
"testdata/images/crop1.jpg",
"testdata/images/crop1.jpg"
};
@Inject
private RetrievalService retrievalService;
@Inject
private StoreImageService storeImageService;
private RetrievalServer retrievalServer;
private MockMvc restStorageMockMvc;
@Before
public void setup() throws Exception {
ImageResource imageResource = new ImageResource();
ReflectionTestUtils.setField(imageResource, "retrievalService", retrievalService);
ReflectionTestUtils.setField(imageResource, "storeImageService", storeImageService);
this.restStorageMockMvc = MockMvcBuilders.standaloneSetup(imageResource).build();
retrievalService.reset();
this.retrievalServer = retrievalService.getRetrievalServer();
for (int i = 1; i < 5; i++) {
Long id = (long) i;
BufferedImage img = ImageIO.read(new File(IMAGE_PATHS[i - 1]));
Map<String, String> properties = new TreeMap<>();
properties.put("path", IMAGE_PATHS[i - 1]);
properties.put("date", new Date().toString());
retrievalServer
.getStorage(DEFAULT_STORAGE)
.indexPicture(img, id, properties);
}
}
@Test
public void testGetImage() throws Exception {
restStorageMockMvc.perform(get("/api/images/{id}", 1L).accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$.id").value("1"));
}
@Test
public void testGetImageNotExists() throws Exception {
try {
restStorageMockMvc.perform(get("/api/images/{id}", 0L).accept(MediaType.APPLICATION_JSON))
.andExpect(status().isNotFound());
} catch (NestedServletException e) {
assertThat(e.getCause().getClass()).isEqualTo(ResourceNotFoundException.class);
}
}
@Test
public void testGetImageByStorage() throws Exception {
restStorageMockMvc.perform(get("/api/storages/{storage}/images/{id}", DEFAULT_STORAGE, 1L)
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$.id").value("1"));
}
@Test
public void testGetImageByStorageNotExists() throws Exception {
try {
restStorageMockMvc.perform(get("/api/storages/{storage}/images/{id}", "unknown", 0L).accept(MediaType.APPLICATION_JSON))
.andReturn();
assert false;
} catch (NestedServletException e) {
assertThat(e.getCause().getClass()).isEqualTo(ResourceNotFoundException.class);
}
}
@Test
public void testGetAllimages() throws Exception {
restStorageMockMvc.perform(get("/api/images").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$[0].id").value("1"))
.andExpect(jsonPath("$[1].id").value("2"))
.andExpect(jsonPath("$[2].id").value("3"))
.andExpect(jsonPath("$[3].id").value("4"));
}
@Test
public void testGetAllimagesByStorage() throws Exception {
restStorageMockMvc.perform(get("/api/storages/{storage}/images", DEFAULT_STORAGE).accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$[0].id").value("1"))
.andExpect(jsonPath("$[1].id").value("2"))
.andExpect(jsonPath("$[2].id").value("3"))
.andExpect(jsonPath("$[3].id").value("4"));
}
@Test
public void testGetAllimagesByStorageNotExist() throws Exception {
try {
restStorageMockMvc.perform(get("/api/storages/{storage}/images", "unknown").accept(MediaType.APPLICATION_JSON))
.andReturn();
assert false;
} catch (NestedServletException e) {
assertThat(e.getCause().getClass()).isEqualTo(ResourceNotFoundException.class);
}
}
@Test
public void testAddImage() throws Exception {
// Validate the database is empty (only default storage)
assertThat(retrievalServer.getSize()).isEqualTo(NUMBER_OF_PICTURES_AT_BEGINNING);
String storage = DEFAULT_STORAGE;
Long id = 5l;
File file = new File(IMAGE_PATHS[(int) (id - 1)]);
MockMultipartFile firstFile = new MockMultipartFile("file", file.getName(), "image/png", Files.readAllBytes(Paths.get(IMAGE_PATHS[(int) (id - 1)])));
MockMultipartFile file1 = new MockMultipartFile(file.getName(), Files.readAllBytes(Paths.get(IMAGE_PATHS[(int) (id - 1)])));
MvcResult result = restStorageMockMvc.perform(
fileUpload("/api/images")
.file(firstFile)
.param("id", id + "")
.param("storage", storage)
.param("keys", "date;test")
.param("values", "2015;test")
.param("async", "false")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(id + ""))
.andExpect(jsonPath("$.test").value("test"))
.andReturn();
assertThat(retrievalServer.getStorage(storage).getProperties(id)).isNotNull();
assertThat(retrievalServer.getStorage(storage).getProperties(id)).containsEntry("id", id + "");
}
@Test
public void testAddImageNoProperties() throws Exception {
// Validate the database is empty (only default storage)
assertThat(retrievalServer.getSize()).isEqualTo(NUMBER_OF_PICTURES_AT_BEGINNING);
String storage = DEFAULT_STORAGE;
Long id = 6l;
File file = new File(IMAGE_PATHS[(int) (id - 1)]);
MockMultipartFile firstFile = new MockMultipartFile("file", file.getName(), "image/png", Files.readAllBytes(Paths.get(IMAGE_PATHS[(int) (id - 1)])));
MockMultipartFile file1 = new MockMultipartFile(file.getName(), Files.readAllBytes(Paths.get(IMAGE_PATHS[(int) (id - 1)])));
MvcResult result = restStorageMockMvc.perform(
fileUpload("/api/images")
.file(firstFile)
.param("id", id + "")
.param("storage", storage)
.param("async", "false")
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(id + ""))
.andReturn();
assertThat(retrievalServer.getStorage(storage).getProperties(id)).isNotNull();
assertThat(retrievalServer.getStorage(storage).getProperties(id)).containsEntry("id", id + "");
}
@Test
public void testAddImagStorageNotExist() throws Exception {
// Validate the database is empty (only default storage)
assertThat(retrievalServer.getSize()).isEqualTo(NUMBER_OF_PICTURES_AT_BEGINNING);
String storage = "STORAGE_testAddImagStorageNotExist";
Long id = 7l;
assertThat(retrievalServer.getStorage(storage)).isNull();
File file = new File(IMAGE_PATHS[(int) (id - 1)]);
MockMultipartFile firstFile = new MockMultipartFile("file", file.getName(), "image/png", Files.readAllBytes(Paths.get(IMAGE_PATHS[(int) (id - 1)])));
MockMultipartFile file1 = new MockMultipartFile(file.getName(), Files.readAllBytes(Paths.get(IMAGE_PATHS[(int) (id - 1)])));
MvcResult result = restStorageMockMvc.perform(
fileUpload("/api/images")
.file(firstFile)
.param("id", id + "")
.param("storage", storage)
.param("async", "false")
)
.andReturn();
printIfError(result);
assertThat(result.getResponse().getStatus()).isEqualTo(200);
Map<String, Object> map = parseStringToMap(result);
assertThat(map.get("id")).isEqualTo(id + "");
assertThat(retrievalServer.getStorage(storage)).isNotNull();
assertThat(retrievalServer.getStorage(storage).getProperties(id)).isNotNull();
assertThat(retrievalServer.getStorage(storage).getProperties(id)).containsEntry("id", id + "");
}
@Test
public void testAddImageWithNoStorage() throws Exception {
// Validate the database is empty (only default storage)
assertThat(retrievalServer.getSize()).isEqualTo(NUMBER_OF_PICTURES_AT_BEGINNING);
Long id = 8l;
File file = new File(IMAGE_PATHS[(int) (id - 1)]);
MockMultipartFile firstFile = new MockMultipartFile("file", file.getName(), "image/png", Files.readAllBytes(Paths.get(IMAGE_PATHS[(int) (id - 1)])));
MockMultipartFile file1 = new MockMultipartFile(file.getName(), Files.readAllBytes(Paths.get(IMAGE_PATHS[(int) (id - 1)])));
MvcResult result = restStorageMockMvc.perform(
fileUpload("/api/images")
.file(firstFile)
.param("id", id + "")
.param("async", "false")
)
.andReturn();
printIfError(result);
assertThat(result.getResponse().getStatus()).isEqualTo(200);
Map<String, Object> map = parseStringToMap(result);
String storage = (String) map.get("storage");
assertThat(retrievalServer.getStorage(storage)).isNotNull();
assertThat(retrievalServer.getStorage(storage).getProperties(id)).isNotNull();
assertThat(retrievalServer.getStorage(storage).getProperties(id)).containsEntry("id", id + "");
}
@Test
public void testAddImageNoID() throws Exception {
// Validate the database is empty (only default storage)
assertThat(retrievalServer.getSize()).isEqualTo(NUMBER_OF_PICTURES_AT_BEGINNING);
String storage = DEFAULT_STORAGE;
File file = new File(IMAGE_PATHS[(int) (8)]);
MockMultipartFile firstFile = new MockMultipartFile("file", file.getName(), "image/png", Files.readAllBytes(Paths.get(IMAGE_PATHS[(int) (8)])));
MockMultipartFile file1 = new MockMultipartFile(file.getName(), Files.readAllBytes(Paths.get(IMAGE_PATHS[(int) (8)])));
MvcResult result = restStorageMockMvc.perform(
fileUpload("/api/images")
.file(firstFile)
//.param("id", id + "")
.param("storage", storage)
)
.andReturn();
printIfError(result);
assertThat(result.getResponse().getStatus()).isEqualTo(200);
Map<String, Object> map = parseStringToMap(result);
Long id = Long.parseLong((String) map.get("id"));
assertThat(retrievalServer.getStorage(storage).getProperties(id)).isNotNull();
assertThat(retrievalServer.getStorage(storage).getProperties(id)).containsEntry("id", id + "");
}
@Test
@Transactional
public void deleteStorage() throws Exception {
Long id = (long) 99;
BufferedImage img = ImageIO.read(new File(IMAGE_PATHS[0]));
Map<String, String> properties = new TreeMap<>();
properties.put("path", IMAGE_PATHS[0]);
properties.put("date", new Date().toString());
retrievalServer.getStorage(DEFAULT_STORAGE).indexPicture(img, id, properties);
System.out.println("TEST");
System.out.println(retrievalServer.getInfos());
assertThat(retrievalServer.getStorage(DEFAULT_STORAGE).getProperties(id)).isNotNull();
restStorageMockMvc.perform(delete("/api/storages/{storage}/images/{id}", DEFAULT_STORAGE, id)
.accept(TestUtil.APPLICATION_JSON_UTF8))
.andExpect(status().isOk());
assertThat(retrievalServer.getStorage(DEFAULT_STORAGE).isPictureInIndex(id)).isFalse();
}
@Test
@Transactional
public void deleteStorageNotExist() throws Exception {
try {
MvcResult result = restStorageMockMvc.perform(delete("/api/storages/{storage}/images/{id}", DEFAULT_STORAGE, 999)
.accept(TestUtil.APPLICATION_JSON_UTF8)).andReturn();
assert false;
} catch (NestedServletException e) {
assertThat(e.getCause().getClass()).isEqualTo(ResourceNotFoundException.class);
}
}
@Test
@Transactional
public void indexFullImage() throws Exception {
// Validate the database is empty (only default storage)
String storage = retrievalServer.getStorageList().get(0).getStorageName();
Long sizeBegin = retrievalServer.getStorage(storage).getNumberOfItem();
// Create the Storage
System.out.println("***********************");
// try {
MvcResult result = restStorageMockMvc.perform(post("/api/index/full")
.contentType(TestUtil.APPLICATION_JSON_UTF8)
.content(String.format("[{\"id\":\"%s\", \"storage\":\"%s\",\"url\":\"%s\"}]",
new Date().getTime()+"",
storage,
"https://www.google.be/images/srpr/logo11w.png"))).andReturn();
printIfError(result);
assertThat(result.getResponse().getStatus()).isEqualTo(200);
assertThat(retrievalServer.getStorage(storage).getNumberOfItem()).isEqualTo(sizeBegin+1);
// } catch (NestedServletException e) {
// assertThat(e.getCause().getClass()).isEqualTo(ResourceAlreadyExistException.class);
// }
}
private void printIfError(MvcResult result) {
if (result.getResolvedException() != null) {
System.out.println(result.getResolvedException().getMessage());
System.out.println(result.getResolvedException().toString());
}
}
public static Map<String, Object> parseStringToMap(MvcResult result) throws java.io.IOException {
String response = result.getResponse().getContentAsString();
System.out.println("response=" + response);
ObjectReader reader = new ObjectMapper().reader(Map.class);
return reader.readValue(response);
}
public static List<Map> parseStringToList(MvcResult result) throws java.io.IOException {
String response = result.getResponse().getContentAsString();
System.out.println("response=" + response);
ObjectReader reader = new ObjectMapper().reader(List.class);
return reader.readValue(response);
}
}