package org.iri_research.renkan.test.rest;

import java.io.IOException;
import java.net.URI;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response.Status;

import junit.framework.Assert;

import org.iri_research.renkan.models.Space;
import org.iri_research.renkan.repositories.SpacesRepository;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.context.ContextLoaderListener;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.jersey.api.client.ClientHandlerException;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.UniformInterfaceException;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.spi.spring.container.servlet.SpringServlet;
import com.sun.jersey.test.framework.AppDescriptor;
import com.sun.jersey.test.framework.JerseyTest;
import com.sun.jersey.test.framework.WebAppDescriptor;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("rest-context.xml")
public class SpaceRestTest extends JerseyTest {
	
	private Logger logger = LoggerFactory.getLogger(SpaceRestTest.class);
	
	@Autowired
	private SpacesRepository spacesRepository;
		
	private Map<String,Space> spacesList = new HashMap<String, Space>();
	private String firstSpaceUUID = null;
		

	public SpaceRestTest() {
	}
	
	@Override
	protected AppDescriptor configure() {
		return new WebAppDescriptor.Builder("org.iri_research.renkan.rest")
			.contextPath("rest")
			.contextParam("contextConfigLocation", "classpath:/org/iri_research/renkan/test/rest/rest-context.xml")
			.initParam("com.sun.jersey.config.property.packages", "org.iri_research.renkan.rest;com.fasterxml.jackson.jaxrs")
			.servletClass(SpringServlet.class)
			.contextListenerClass(ContextLoaderListener.class)
			.build();
	};
	
	@Before
	public void setup() {
		
		logger.debug("Setup");
		spacesRepository.deleteAll();
		Date creationDate = new Date();
		this.firstSpaceUUID = UUID.randomUUID().toString();
		Space testSpace = new Space(firstSpaceUUID, "test", "Test space", "{}", "http://ldt.iri.centrepompidou.fr", "#ababab", "test_user", "http://ldt.iri.centrepompidou.fr", creationDate);
		testSpace = spacesRepository.save(testSpace);
		this.spacesList.put(firstSpaceUUID, testSpace);
	}
	
	@After
	public void teardown() {
		spacesRepository.deleteAll();
	}

	
	@Test
	public void testSetup() throws JsonProcessingException, IOException {

		WebResource webResource = this.resource();
		String respString = webResource.path("spaces").get(String.class);
		
		Assert.assertNotNull("The response string for the list of spaces must not be null", respString);
		
		logger.debug("RESPONSE : " + respString);
		
		Assert.assertTrue("The length of the space list resp. string must be > 0", respString.length() > 0);
		
		
		ObjectMapper mapper = new ObjectMapper();
		JsonNode spacesList = mapper.readTree(respString);
		
		Assert.assertTrue("The spaceList must be an array", spacesList.isArray());
		Assert.assertEquals("The spaceList length must be = " + this.spacesList.size(), this.spacesList.size(), spacesList.size());
		
		for (JsonNode jsonNode : spacesList) {
			Assert.assertTrue("the space must have an id", jsonNode.hasNonNull("id"));
			String id = jsonNode.get("id").asText();
			Assert.assertTrue("The id must be in the spacesList", this.spacesList.containsKey(id));
			Space space = this.spacesList.get(id);
			Assert.assertNotNull("The object must in the spacesList must not be null", space);
								
		}
		
	}
	
	@Test
	public void testTitle() throws JsonProcessingException, IOException {
		
		WebResource webResource = this.resource();
		String respString = webResource.path("spaces").get(String.class);
		logger.debug("RESPONSE : " + respString);
		ObjectMapper mapper = new ObjectMapper();
		JsonNode spacesList = mapper.readTree(respString);
		
		for (JsonNode jsonNode : spacesList) {
			String id = jsonNode.get("_id").asText();
			Space space = this.spacesList.get(id);
			
			Assert.assertTrue("the space must have a title", jsonNode.hasNonNull("title"));
			String title = jsonNode.get("title").asText();
			Assert.assertEquals("space title must be equals to " + space.getTitle(), space.getTitle(), title);
		}

	}

	@Test
	public void testDescription() throws JsonProcessingException, IOException {
		
		WebResource webResource = this.resource();
		String respString = webResource.path("spaces").get(String.class);
		logger.debug("RESPONSE : " + respString);
		ObjectMapper mapper = new ObjectMapper();
		JsonNode spacesList = mapper.readTree(respString);
		
		for (JsonNode jsonNode : spacesList) {
			String id = jsonNode.get("id").asText();
			Space space = this.spacesList.get(id);
			
			Assert.assertTrue("the space must have a description", jsonNode.hasNonNull("description"));
			String description = jsonNode.get("description").asText();
			Assert.assertEquals("space description must be equals to " + space.getDescription(), space.getDescription(), description);
		}

	}

	@Test
	public void testUri() throws JsonProcessingException, IOException {
		
		WebResource webResource = this.resource();
		String respString = webResource.path("spaces").get(String.class);
		logger.debug("RESPONSE : " + respString);
		ObjectMapper mapper = new ObjectMapper();
		JsonNode spacesList = mapper.readTree(respString);
		
		for (JsonNode jsonNode : spacesList) {
			String id = jsonNode.get("id").asText();
			Space space = this.spacesList.get(id);
			
			Assert.assertTrue("the space must have a uri", jsonNode.hasNonNull("uri"));
			String uri = jsonNode.get("uri").asText();
			Assert.assertEquals("space uri must be equals to " + space.getUri(), space.getUri(), uri);
		}

	}

	@Test
	public void testColor() throws JsonProcessingException, IOException {
		
		WebResource webResource = this.resource();
		String respString = webResource.path("spaces").get(String.class);
		logger.debug("RESPONSE : " + respString);
		ObjectMapper mapper = new ObjectMapper();
		JsonNode spacesList = mapper.readTree(respString);
		
		for (JsonNode jsonNode : spacesList) {
			String id = jsonNode.get("id").asText();
			Space space = this.spacesList.get(id);
			
			Assert.assertTrue("the space must have a color", jsonNode.hasNonNull("color"));
			String color = jsonNode.get("color").asText();
			Assert.assertEquals("space color must be equals to " + space.getColor(), space.getColor(), color);
		}

	}

	
	
	@Test
	public void testBinConfig() throws JsonProcessingException, IOException {
		
		WebResource webResource = this.resource();
		String respString = webResource.path("spaces").get(String.class);
		logger.debug("RESPONSE : " + respString);
		ObjectMapper mapper = new ObjectMapper();
		JsonNode spacesList = mapper.readTree(respString);
		
		for (JsonNode jsonNode : spacesList) {
			String id = jsonNode.get("id").asText();
			Space space = this.spacesList.get(id);
			
			Assert.assertTrue("the space must have a bin_config", jsonNode.hasNonNull("bin_config"));
			String binConfig = jsonNode.get("bin_config").asText();
			Assert.assertEquals("space bin_config must be equals to " + space.getBinConfig(), space.getBinConfig(), binConfig);
		}

	}
	
	@Test
	public void testCreatedBy() throws JsonProcessingException, IOException {
		
		WebResource webResource = this.resource();
		String respString = webResource.path("spaces").get(String.class);
		logger.debug("RESPONSE : " + respString);
		ObjectMapper mapper = new ObjectMapper();
		JsonNode spacesList = mapper.readTree(respString);
		
		for (JsonNode jsonNode : spacesList) {
			String id = jsonNode.get("id").asText();
			Space space = this.spacesList.get(id);
			
			Assert.assertTrue("the space must have a created_by", jsonNode.hasNonNull("created_by"));
			String createdBy = jsonNode.get("created_by").asText();
			Assert.assertEquals("space created_by must be equals to " + space.getCreatedBy(), space.getCreatedBy(), createdBy);
		}

	}
	
	
	@Test
	public void testCreated() throws JsonProcessingException, IOException {
		
		WebResource webResource = this.resource();
		String respString = webResource.path("spaces").get(String.class);
		logger.debug("RESPONSE : " + respString);
		ObjectMapper mapper = new ObjectMapper();
		JsonNode spacesList = mapper.readTree(respString);
		
		for (JsonNode jsonNode : spacesList) {
			String id = jsonNode.get("id").asText();
			Space space = this.spacesList.get(id);
			
			Assert.assertTrue("the space must have a created", jsonNode.hasNonNull("created"));
			
			String dateStr = jsonNode.get("created").asText();
			
			DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
			DateTime date = fmt.parseDateTime(dateStr);
			
			Assert.assertEquals("Created date must be the same", space.getCreated(), date.toDate());				
			
		}

	}
	
	@Test
	public void testImage() throws JsonProcessingException, IOException {
		
		WebResource webResource = this.resource();
		String respString = webResource.path("spaces").get(String.class);
		logger.debug("RESPONSE : " + respString);
		ObjectMapper mapper = new ObjectMapper();
		JsonNode spacesList = mapper.readTree(respString);
		
		for (JsonNode jsonNode : spacesList) {
			String id = jsonNode.get("id").asText();
			Space space = this.spacesList.get(id);
			
			Assert.assertTrue("the space must have a image", jsonNode.hasNonNull("image"));
			String image = jsonNode.get("image").asText();
			Assert.assertEquals("space image must be equals to " + space.getImage(), space.getImage(), image);
		}

	}
	
	@Test
	public void testSingleCreated() throws JsonProcessingException, IOException {
		
		Space space = this.spacesList.get(this.firstSpaceUUID);
		WebResource webResource = this.resource();
		String respString = webResource.path("spaces").path(this.firstSpaceUUID).get(String.class);
		logger.debug("RESPONSE : " + respString);
		ObjectMapper mapper = new ObjectMapper();
		JsonNode jsonNode = mapper.readTree(respString);
		
		String id = jsonNode.get("id").asText();
		Assert.assertEquals("id must be equals", space.getId(), id);
		
		Assert.assertTrue("the space must have a created", jsonNode.hasNonNull("created"));
		
		String dateStr = jsonNode.get("created").asText();
		
		DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
		DateTime date = fmt.parseDateTime(dateStr);
		
		Assert.assertEquals("Created date must be the same", space.getCreated(), date.toDate());				

	}
	
	@Test
	public void testSingleTitle() throws JsonProcessingException, IOException {
		
		Space space = this.spacesList.get(this.firstSpaceUUID);
		WebResource webResource = this.resource();
		String respString = webResource.path("spaces").path(this.firstSpaceUUID).get(String.class);
		logger.debug("RESPONSE : " + respString);
		ObjectMapper mapper = new ObjectMapper();
		JsonNode jsonNode = mapper.readTree(respString);
					
		Assert.assertTrue("the space must have a title", jsonNode.hasNonNull("title"));
		String title = jsonNode.get("title").asText();
		Assert.assertEquals("space title must be equals to " + space.getTitle(), space.getTitle(), title);
	}

	@Test
	public void testSingleDescription() throws JsonProcessingException, IOException {
		
		Space space = this.spacesList.get(this.firstSpaceUUID);
		WebResource webResource = this.resource();
		String respString = webResource.path("spaces").path(this.firstSpaceUUID).get(String.class);
		logger.debug("RESPONSE : " + respString);
		ObjectMapper mapper = new ObjectMapper();
		JsonNode jsonNode = mapper.readTree(respString);
					
		Assert.assertTrue("the space must have a description", jsonNode.hasNonNull("description"));
		String description = jsonNode.get("description").asText();
		Assert.assertEquals("space description must be equals to " + space.getDescription(), space.getDescription(), description);
	}

	@Test
	public void testSingleUri() throws JsonProcessingException, IOException {
		
		Space space = this.spacesList.get(this.firstSpaceUUID);
		WebResource webResource = this.resource();
		String respString = webResource.path("spaces").path(this.firstSpaceUUID).get(String.class);
		logger.debug("RESPONSE : " + respString);
		ObjectMapper mapper = new ObjectMapper();
		JsonNode jsonNode = mapper.readTree(respString);
		
		Assert.assertTrue("the space must have a uri", jsonNode.hasNonNull("uri"));
		String uri = jsonNode.get("uri").asText();
		Assert.assertEquals("space uri must be equals to " + space.getUri(), space.getUri(), uri);
	}

	@Test
	public void testSingleColor() throws JsonProcessingException, IOException {
		
		Space space = this.spacesList.get(this.firstSpaceUUID);
		WebResource webResource = this.resource();
		String respString = webResource.path("spaces").path(this.firstSpaceUUID).get(String.class);
		logger.debug("RESPONSE : " + respString);
		ObjectMapper mapper = new ObjectMapper();
		JsonNode jsonNode = mapper.readTree(respString);
					
		Assert.assertTrue("the space must have a color", jsonNode.hasNonNull("color"));
		String color = jsonNode.get("color").asText();
		Assert.assertEquals("space color must be equals to " + space.getColor(), space.getColor(), color);
	}

	
	
	@Test
	public void testSingleBinConfig() throws JsonProcessingException, IOException {
		
		Space space = this.spacesList.get(this.firstSpaceUUID);
		WebResource webResource = this.resource();
		String respString = webResource.path("spaces").path(this.firstSpaceUUID).get(String.class);
		logger.debug("RESPONSE : " + respString);
		ObjectMapper mapper = new ObjectMapper();
		JsonNode jsonNode = mapper.readTree(respString);
		
		Assert.assertTrue("the space must have a bin_config", jsonNode.hasNonNull("bin_config"));
		String binConfig = jsonNode.get("bin_config").asText();
		Assert.assertEquals("space bin_config must be equals to " + space.getBinConfig(), space.getBinConfig(), binConfig);
	}
	
	@Test
	public void testSingleCreatedBy() throws JsonProcessingException, IOException {
		
		Space space = this.spacesList.get(this.firstSpaceUUID);
		WebResource webResource = this.resource();
		String respString = webResource.path("spaces").path(this.firstSpaceUUID).get(String.class);
		logger.debug("RESPONSE : " + respString);
		ObjectMapper mapper = new ObjectMapper();
		JsonNode jsonNode = mapper.readTree(respString);
		
		Assert.assertTrue("the space must have a created_by", jsonNode.hasNonNull("created_by"));
		String createdBy = jsonNode.get("created_by").asText();
		Assert.assertEquals("space created_by must be equals to " + space.getCreatedBy(), space.getCreatedBy(), createdBy);
	}
	
		
	@Test
	public void testSingleImage() throws JsonProcessingException, IOException {
	
		Space space = this.spacesList.get(this.firstSpaceUUID);
		WebResource webResource = this.resource();
		String respString = webResource.path("spaces").path(this.firstSpaceUUID).get(String.class);
		logger.debug("RESPONSE : " + respString);
		ObjectMapper mapper = new ObjectMapper();
		JsonNode jsonNode = mapper.readTree(respString);
					
		Assert.assertTrue("the space must have a image", jsonNode.hasNonNull("image"));
		String image = jsonNode.get("image").asText();
		Assert.assertEquals("space image must be equals to " + space.getImage(), space.getImage(), image);
	}
	
	
	@Test
	public void testPost() throws JsonProcessingException, ClientHandlerException, UniformInterfaceException, IOException {
		
		String title = "test_post";
		String description = "test space post";
		String uri = "http://ldt.iri.centrepompidou.fr/test_post";
		String color = "#bcbcbc";
		String image = "http://ldt.iri.centrepompidou.fr/test_post/image";
		String created = "2013-01-01T01:01:01.001+0000";
		String bin_config = "{name: 'test_post_config'}";
		String created_by = "test_user_post";
		
		String spaceJson = String.format("{" +
				"\"title\":\"%s\"," +
				"\"description\":\"%s\"," +
				"\"uri\":\"%s\"," +
				"\"color\":\"%s\"," +
				"\"image\":\"%s\"," +
				"\"created\":\"%s\"," +
				"\"bin_config\":\"%s\"," +
				"\"created_by\":\"%s\"" +
				"}",
				title,
				description,
				uri,
				color,
				image,
				created,
				bin_config,
				created_by);
		
		WebResource webResource = this.resource();
		ClientResponse resp = webResource.path("spaces").type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).entity(spaceJson).post(ClientResponse.class);
		
		String respStr = resp.getEntity(String.class);
		
		Assert.assertEquals("Resp status = created : " + respStr, Status.CREATED.getStatusCode(), resp.getStatus());
		Assert.assertTrue("Resp must be application/json", resp.getType().isCompatible(MediaType.APPLICATION_JSON_TYPE));		
		
		ObjectMapper mapper = new ObjectMapper();
		JsonNode objNode = mapper.readTree(respStr);

		Assert.assertTrue("the space must have an id", objNode.hasNonNull("id"));
		String idStr = objNode.get("id").asText();
		Assert.assertFalse("The id str must not be empty", idStr.length()==0);
		
		Assert.assertTrue("the space must have a title", objNode.hasNonNull("title"));
		String titleStr = objNode.get("title").asText();
		Assert.assertEquals("space title must be equals to " + title, title, titleStr);

		Assert.assertTrue("the space must have a description", objNode.hasNonNull("description"));
		String descriptionStr = objNode.get("description").asText();
		Assert.assertEquals("space description must be equals to " + description, description, descriptionStr);

		Assert.assertTrue("the space must have a uri", objNode.hasNonNull("uri"));
		String uriStr = objNode.get("uri").asText();
		Assert.assertEquals("space uri must be equals to " + uri, uri, uriStr);

		Assert.assertTrue("the space must have a color", objNode.hasNonNull("color"));
		String colorStr = objNode.get("color").asText();
		Assert.assertEquals("space color must be equals to " + color, color, colorStr);

		Assert.assertTrue("the space must have a bin_config", objNode.hasNonNull("bin_config"));
		String bin_configStr = objNode.get("bin_config").asText();
		Assert.assertEquals("space bin_config must be equals to " + bin_config, bin_config, bin_configStr);

		Assert.assertTrue("the space must have a created_by", objNode.hasNonNull("created_by"));
		String created_byStr = objNode.get("created_by").asText();
		Assert.assertEquals("space created_by must be equals to " + created_by, created_by, created_byStr);
		
		Assert.assertTrue("the space must have a created", objNode.hasNonNull("created"));
		String createdStr = objNode.get("created").asText();
		Assert.assertEquals("space created must be equals to " + created, created, createdStr);
		
		// object must be created
		Space sp = this.spacesRepository.findOne(idStr);
		
		Assert.assertNotNull("Space object must be in rep", sp);
		
		Assert.assertEquals("space title must be equals to " + title, title, sp.getTitle());
		Assert.assertEquals("space description must be equals to " + description, description, sp.getDescription());
		Assert.assertEquals("space uri must be equals to " + uri, uri, sp.getUri());
		Assert.assertEquals("space color must be equals to " + color, color, sp.getColor());
		Assert.assertEquals("space bin_config must be equals to " + bin_config, bin_config, sp.getBinConfig());
		Assert.assertEquals("space created_by must be equals to " + created_by, created_by, sp.getCreatedBy());
		DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
		DateTime created_date = fmt.parseDateTime(created);
		Assert.assertEquals("space created must be equals to " + created, created_date.toDate(), sp.getCreated());
		
	}

	
	@Test
	public void testPostWithId() {
		
		String id = UUID.randomUUID().toString();
		String title = "test_post";
		String description = "test space post";
		String uri = "http://ldt.iri.centrepompidou.fr/test_post";
		String color = "#bcbcbc";
		String image = "http://ldt.iri.centrepompidou.fr/test_post/image";
		String created = "2013-01-01T01:01:01.001+0000";
		String bin_config = "{name: 'test_post_config'}";
		String created_by = "test_user_post";
		
		String spaceJson = String.format("{" +
		        "\"id\":\"%s\"," +
				"\"title\":\"%s\"," +
				"\"description\":\"%s\"," +
				"\"uri\":\"%s\"," +
				"\"color\":\"%s\"," +
				"\"image\":\"%s\"," +
				"\"created\":\"%s\"," +
				"\"bin_config\":\"%s\"," +
				"\"created_by\":\"%s\"" +
				"}",
				id,
				title,
				description,
				uri,
				color,
				image,
				created,
				bin_config,
				created_by);
		
		WebResource webResource = this.resource();
		ClientResponse resp = webResource.path("spaces").type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).entity(spaceJson).post(ClientResponse.class);
		
		String respStr = resp.getEntity(String.class);
		
		Assert.assertEquals("Resp status = Bad Request : " + respStr, Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
		Assert.assertEquals("Error message", "Id in JSON must be null", respStr);
		
	}
		
	@Test
	public void testPut() throws JsonProcessingException, IOException {
		
		String id = this.firstSpaceUUID;
		String title = "test_post";
		String description = "test space put";
		String uri = "http://ldt.iri.centrepompidou.fr/test_put";
		String color = "#bcbcbc";
		String image = "http://ldt.iri.centrepompidou.fr/test_put/image";
		String created = "2013-01-01T01:01:01.001+0000";
		String bin_config = "{name: 'test_put_config'}";
		String created_by = "test_user_put";
		
		String spaceJson = String.format("{" +
		        "\"id\":\"%s\"," +
				"\"title\":\"%s\"," +
				"\"description\":\"%s\"," +
				"\"uri\":\"%s\"," +
				"\"color\":\"%s\"," +
				"\"image\":\"%s\"," +
				"\"created\":\"%s\"," +
				"\"bin_config\":\"%s\"," +
				"\"created_by\":\"%s\"" +
				"}",
				id,
				title,
				description,
				uri,
				color,
				image,
				created,
				bin_config,
				created_by);
		
		WebResource webResource = this.resource();
		ClientResponse resp = webResource.path("spaces").path(this.firstSpaceUUID).type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).entity(spaceJson).put(ClientResponse.class);
		
		String respStr = "";
		
		if(resp.getStatus() != 204) {
			respStr = resp.getEntity(String.class);
		}
		
		Assert.assertEquals("Resp status = created : " + respStr, Status.NO_CONTENT.getStatusCode(), resp.getStatus());
		Assert.assertNull("Resp type must be null", resp.getType());		

		
		// object must be updated
		Space sp = this.spacesRepository.findOne(id);
		
		Assert.assertNotNull("Space object must be in rep", sp);
		
		Assert.assertEquals("space title must be equals to " + title, title, sp.getTitle());
		Assert.assertEquals("space description must be equals to " + description, description, sp.getDescription());
		Assert.assertEquals("space uri must be equals to " + uri, uri, sp.getUri());
		Assert.assertEquals("space color must be equals to " + color, color, sp.getColor());
		Assert.assertEquals("space bin_config must be equals to " + bin_config, bin_config, sp.getBinConfig());
		Assert.assertEquals("space created_by must be equals to " + created_by, created_by, sp.getCreatedBy());
		DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
		DateTime created_date = fmt.parseDateTime(created);
		Assert.assertEquals("space created must be equals to " + created, created_date.toDate(), sp.getCreated());

	}
	
	@Test
	public void testPutWithoutId() {

		String title = "test_put";
		String description = "test space put";
		String uri = "http://ldt.iri.centrepompidou.fr/test_put";
		String color = "#bcbcbc";
		String image = "http://ldt.iri.centrepompidou.fr/test_put/image";
		String created = "2013-01-01T01:01:01.001+0000";
		String bin_config = "{name: 'test_put_config'}";
		String created_by = "test_user_put";
		
		String spaceJson = String.format("{" +
				"\"title\":\"%s\"," +
				"\"description\":\"%s\"," +
				"\"uri\":\"%s\"," +
				"\"color\":\"%s\"," +
				"\"image\":\"%s\"," +
				"\"created\":\"%s\"," +
				"\"bin_config\":\"%s\"," +
				"\"created_by\":\"%s\"" +
				"}",
				title,
				description,
				uri,
				color,
				image,
				created,
				bin_config,
				created_by);
		
		WebResource webResource = this.resource();
		ClientResponse resp = webResource.path("spaces").path(this.firstSpaceUUID).type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).entity(spaceJson).put(ClientResponse.class);
		
		String respStr = resp.getEntity(String.class);
		
		Assert.assertEquals("Resp status = Bad Request : " + respStr, Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
		Assert.assertEquals("Error message", "Id parameter and id in JSON do not match", respStr);		
	}
	
	@Test
	public void testPutBadId() {
		
		String id = UUID.randomUUID().toString();
		String title = "test_post";
		String description = "test space put";
		String uri = "http://ldt.iri.centrepompidou.fr/test_put";
		String color = "#bcbcbc";
		String image = "http://ldt.iri.centrepompidou.fr/test_put/image";
		String created = "2013-01-01T01:01:01.001+0000";
		String bin_config = "{name: 'test_put_config'}";
		String created_by = "test_user_put";
		
		String spaceJson = String.format("{" +
		        "\"id\":\"%s\"," +
				"\"title\":\"%s\"," +
				"\"description\":\"%s\"," +
				"\"uri\":\"%s\"," +
				"\"color\":\"%s\"," +
				"\"image\":\"%s\"," +
				"\"created\":\"%s\"," +
				"\"bin_config\":\"%s\"," +
				"\"created_by\":\"%s\"" +
				"}",
				id,
				title,
				description,
				uri,
				color,
				image,
				created,
				bin_config,
				created_by);
		
		WebResource webResource = this.resource();
		ClientResponse resp = webResource.path("spaces").path(id).type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).entity(spaceJson).put(ClientResponse.class);
		
		String respStr = resp.getEntity(String.class);
		
		Assert.assertEquals("Resp status = Bad Request : " + respStr, Status.NOT_FOUND.getStatusCode(), resp.getStatus());
		
	}
	
	@Test
	public void testDelete() {

		WebResource webResource = this.resource();
		ClientResponse resp = webResource.path("spaces").path(this.firstSpaceUUID).accept(MediaType.TEXT_PLAIN).delete(ClientResponse.class);
		
		String respStr = resp.getEntity(String.class);
		URI reqUri = webResource.getUriBuilder().path("spaces").path(this.firstSpaceUUID).build();

		Assert.assertEquals("Status must be deleted : " + respStr, Status.OK.getStatusCode(), resp.getStatus());
		Assert.assertEquals(String.format("Message must be \"%s deleted\"", reqUri), String.format("%s deleted",reqUri) , respStr);
		
		// object must be updated
		Space sp = this.spacesRepository.findOne(this.firstSpaceUUID);
		
		Assert.assertNull("Space object must be in rep", sp);

	}
}
