package com.collabinate.server.resources; import static org.hamcrest.CoreMatchers.containsString; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.junit.Test; import org.restlet.Request; import org.restlet.Response; import org.restlet.data.Conditions; import org.restlet.data.MediaType; import org.restlet.data.Method; import org.restlet.data.Status; import org.restlet.data.Tag; import com.collabinate.server.activitystreams.Activity; import com.collabinate.server.activitystreams.ActivityStreamsCollection; import com.collabinate.server.activitystreams.ActivityStreamsObject; import com.google.gson.JsonParser; /** * Tests for the Comments Resource * * @author mafuba * */ public class CommentsResourceTest extends GraphResourceTest { @Test public void get_comments_for_nonexistent_activity_should_return_404() { assertEquals(Status.CLIENT_ERROR_NOT_FOUND, get().getStatus()); } @Test public void get_comments_for_existing_activity_should_return_200() { addActivity(); assertEquals(Status.SUCCESS_OK, get().getStatus()); } @Test public void get_should_return_json_content_type() { addActivity(); assertEquals(MediaType.APPLICATION_JSON, get().getEntity().getMediaType()); } @Test public void get_response_should_contain_etag_header() { addActivity(); assertTrue(null != get().getEntity().getTag()); } @Test public void etag_should_change_when_comments_change() { addActivity(); Tag tag1 = get().getEntity().getTag(); post("TEST", MediaType.TEXT_PLAIN); Tag tag2 = get().getEntity().getTag(); assertNotEquals(tag1, tag2); } @Test public void matching_etag_should_return_304() { addActivity(); Tag etag = get().getEntity().getTag(); Request request = getRequest(Method.GET, null); Conditions conditions = new Conditions(); conditions.getNoneMatch().add(etag); request.setConditions(conditions); assertEquals(Status.REDIRECTION_NOT_MODIFIED, getResponse(request).getStatus()); } @Test public void non_matching_etag_should_return_200() { addActivity(); Request request = getRequest(Method.GET, null); Conditions conditions = new Conditions(); conditions.getNoneMatch().add(new Tag("abc")); request.setConditions(conditions); assertEquals(Status.SUCCESS_OK, getResponse(request).getStatus()); } @Test public void post_to_missing_activity_should_return_404() { assertEquals(Status.CLIENT_ERROR_NOT_FOUND, post().getStatus()); } @Test public void item_added_to_comments_should_return_201() { addActivity(); assertEquals(Status.SUCCESS_CREATED, post().getStatus()); } @Test public void item_added_to_comments_should_create_and_return_child_location() { addActivity(); assertEquals( getRequest(Method.POST, null).getResourceRef().getPath() + "/", post().getLocationRef().getParentRef().getPath()); } @Test public void item_added_to_comments_should_have_text_in_post_response_body() { addActivity(); String entityBody = "TEST"; Response response = post(entityBody, MediaType.TEXT_PLAIN); assertThat(response.getEntityAsText(), containsString(entityBody)); } @Test public void post_response_body_should_be_json() { addActivity(); String entityBody = "TEST,"; Response response = post(entityBody, MediaType.TEXT_PLAIN); new JsonParser().parse(response.getEntityAsText()); } @Test public void post_response_body_should_contain_added_fields() { addActivity(); String entityBody = "TEST"; Response response = post(entityBody, MediaType.TEXT_PLAIN); assertThat(response.getEntityAsText(), containsString("\"id\"")); } @Test public void comment_should_be_json_object() { addActivity(); post("TEST", MediaType.TEXT_PLAIN); // parser will throw if result is not json new JsonParser().parse(get().getEntityAsText()); } @Test public void item_added_to_comments_should_appear_in_comments() { addActivity(); String entityBody = "TEST"; post(entityBody, MediaType.TEXT_PLAIN); assertThat(get().getEntityAsText(), containsString(entityBody)); } @Test public void comment_should_not_use_given_id() { addActivity(); String entityBody = "{\"id\":\"TEST\"}"; post(entityBody, MediaType.TEXT_PLAIN); ActivityStreamsCollection comments = new ActivityStreamsCollection(get().getEntityAsText()); assertNotEquals("TEST", comments.get(0).getId()); } @Test public void individual_comment_should_be_retrievable_via_generated_id() { addActivity(); String entityBody = "{\"id\":\"test\",\"content\":\"TEST\"}"; Activity posted = new Activity( post(entityBody, MediaType.TEXT_PLAIN).getEntityAsText()); Request request = new Request(Method.GET, "riap://application/1/tenant/entities/entity" + "/stream/activity/comments/" + posted.getId()); ActivityStreamsObject comment = new ActivityStreamsObject( component.handle(request).getEntityAsText()); assertEquals("TEST", comment.getContent()); } @Test public void original_id_should_be_preserved() { addActivity(); String entityBody = "{\"id\":\"original\",\"actor\":{\"id\":\"foo\"}}"; ActivityStreamsObject posted = new ActivityStreamsObject( post(entityBody, MediaType.TEXT_PLAIN).getEntityAsText()); assertEquals("original", posted.getCollabinateValue("originalId")); } @Test public void posted_raw_text_should_have_id_in_comment_when_retrieved() { addActivity(); post("test", MediaType.TEXT_PLAIN); ActivityStreamsCollection comments = new ActivityStreamsCollection(get().getEntityAsText()); assertNotNull(comments.get(0).getId()); } @Test public void comment_should_always_use_comment_object_type() { addActivity(); String entityBody = "{\"objectType\":\"TEST\"}"; post(entityBody, MediaType.TEXT_PLAIN); ActivityStreamsCollection comments = new ActivityStreamsCollection(get().getEntityAsText()); assertEquals("comment", comments.get(0).getObjectType()); } @Test public void original_object_type_should_be_preserved() { addActivity(); String entityBody = "{\"objectType\":\"original\"}"; ActivityStreamsObject posted = new ActivityStreamsObject( post(entityBody, MediaType.TEXT_PLAIN).getEntityAsText()); assertEquals("original", posted.getCollabinateValue("originalObjectType")); } @Test public void user_id_should_be_preserved() { addActivity(); post("?userId=user"); ActivityStreamsCollection comments = new ActivityStreamsCollection(get().getEntityAsText()); assertEquals("user", comments.get(0).getCollabinateValue("userId")); } @Test public void comment_date_in_post_should_be_used_in_comments() { addActivity(); DateTime dateTime = new DateTime(1977, 5, 13, 5, 13, DateTimeZone.UTC); ActivityStreamsObject comment = new ActivityStreamsObject(); comment.setPublished(dateTime); String entityBody = comment.toString(); post(entityBody, MediaType.APPLICATION_JSON); ActivityStreamsCollection comments = new ActivityStreamsCollection(get().getEntityAsText()); assertEquals(dateTime, comments.get(0).getPublished()); } @Test public void comments_should_appear_in_correct_date_order() { addActivity(); DateTime dateTime1 = new DateTime(1977, 5, 13, 5, 13, DateTimeZone.UTC); ActivityStreamsObject comment1 = new ActivityStreamsObject(); comment1.setPublished(dateTime1); DateTime dateTime2 = new DateTime(1973, 6, 28, 6, 28, DateTimeZone.UTC); ActivityStreamsObject comment2 = new ActivityStreamsObject(); comment2.setPublished(dateTime2); post(comment1.toString(), MediaType.APPLICATION_JSON); post(comment2.toString(), MediaType.APPLICATION_JSON); ActivityStreamsCollection comments = new ActivityStreamsCollection(get().getEntityAsText()); assertEquals(dateTime1, comments.get(0).getPublished()); } @Test public void collection_should_include_total_items_property() { addActivity(); assertThat(get().getEntityAsText(), containsString("totalItems")); } @Test public void collection_should_include_zero_count_for_empty_comments() { addActivity(); ActivityStreamsCollection comments = new ActivityStreamsCollection(get().getEntityAsText()); assertEquals(0, comments.getTotalItems()); } @Test public void collection_should_include_count_that_matches_comments() { addActivity(); post(); post(); ActivityStreamsCollection comments = new ActivityStreamsCollection(get().getEntityAsText()); assertEquals(2, comments.getTotalItems()); } @Test public void collection_count_should_account_for_deleted_comments() { addActivity(); post(); post(); ActivityStreamsObject deleted = new ActivityStreamsObject(post().getEntityAsText()); Request request = new Request(Method.DELETE, "riap://application/1/tenant/entities/entity/" + "stream/activity/comments/" + deleted.getId()); component.handle(request); ActivityStreamsCollection comments = new ActivityStreamsCollection(get().getEntityAsText()); assertEquals(2, comments.getTotalItems()); } /** * Prepares for comment work by creating an activity. */ private void addActivity() { component.handle(new Request(Method.PUT, "riap://application/1/tenant/entities/entity/stream/activity")); } @Override protected String getResourcePath() { return "/1/tenant/entities/entity/stream/activity/comments"; } }