/*
* JBoss, Home of Professional Open Source
* Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @authors tag. All rights reserved.
*/
package org.searchisko.api.rest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import javax.enterprise.event.Event;
import javax.ws.rs.core.Response;
import org.elasticsearch.common.settings.SettingsException;
import org.hamcrest.CustomMatcher;
import org.json.JSONException;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;
import org.searchisko.api.ContentObjectFields;
import org.searchisko.api.events.ContentBeforeIndexedEvent;
import org.searchisko.api.events.ContentDeletedEvent;
import org.searchisko.api.events.ContentStoredEvent;
import org.searchisko.api.rest.exception.BadFieldException;
import org.searchisko.api.rest.exception.NotAuthenticatedException;
import org.searchisko.api.rest.exception.NotAuthorizedException;
import org.searchisko.api.rest.exception.OperationUnavailableException;
import org.searchisko.api.rest.exception.RequiredFieldException;
import org.searchisko.api.security.AuthenticatedUserType;
import org.searchisko.api.service.AuthenticationUtilService;
import org.searchisko.api.service.ContentManipulationLockService;
import org.searchisko.api.service.ProviderService;
import org.searchisko.api.service.ProviderService.ProviderContentTypeInfo;
import org.searchisko.api.service.ProviderServiceTest;
import org.searchisko.api.testtools.ESRealClientTestBase;
import org.searchisko.api.testtools.TestUtils;
import org.searchisko.persistence.service.ContentPersistenceService;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import static org.searchisko.api.testtools.TestUtils.assertResponseStatus;
import static org.searchisko.api.testtools.TestUtils.assetJsonStreamingOutputContent;
/**
* Unit test for {@link ContentRestService}
*
* @author Vlastimil Elias (velias at redhat dot com)
*/
public class ContentRestServiceTest extends ESRealClientTestBase {
private static final String TYPE_INVALID = "invalid";
private static final String TYPE_PERSIST = "persist";
private static final String TYPE_INVALID_CONTENT_TYPE = "invalid-content-type";
private static final String TYPE_UNKNOWN = "unknown";
private static final String TYPE_KNOWN = "known";
private static final String INDEX_TYPE = "index_type";
private static final String INDEX_NAME = "index_name";
private static final List<Map<String, Object>> PREPROCESSORS = new ArrayList<Map<String, Object>>();
@SuppressWarnings("unchecked")
@Test
public void processFieldSysVisibleForRoles() {
ContentRestService tested = getTested(false);
Map<String, Object> content = new HashMap<>();
// case - no given field present at all
tested.processFieldSysVisibleForRoles(content);
Assert.assertEquals(0, content.size());
// case - empty list is removed
{
content.put(ContentObjectFields.SYS_VISIBLE_FOR_ROLES, new ArrayList<>());
tested.processFieldSysVisibleForRoles(content);
Assert.assertEquals(0, content.size());
ArrayList<String> l = new ArrayList<>();
l.add("");
content.put(ContentObjectFields.SYS_VISIBLE_FOR_ROLES, l);
tested.processFieldSysVisibleForRoles(content);
Assert.assertEquals(0, content.size());
}
// case - list is preserved, empty strings removed, strings trimmed
{
List<String> l = new ArrayList<>();
l.add("role1");
l.add("");
l.add("role2 ");
content.put(ContentObjectFields.SYS_VISIBLE_FOR_ROLES, l);
tested.processFieldSysVisibleForRoles(content);
Assert.assertEquals(1, content.size());
List<String> ret = (List<String>) content.get(ContentObjectFields.SYS_VISIBLE_FOR_ROLES);
Assert.assertEquals(2, ret.size());
Assert.assertTrue(ret.contains("role1"));
Assert.assertTrue(ret.contains("role2"));
}
// case - one string is converted to list
content.put(ContentObjectFields.SYS_VISIBLE_FOR_ROLES, "role1");
tested.processFieldSysVisibleForRoles(content);
Assert.assertEquals(1, content.size());
List<String> ret = (List<String>) content.get(ContentObjectFields.SYS_VISIBLE_FOR_ROLES);
Assert.assertEquals(1, ret.size());
Assert.assertTrue(ret.contains("role1"));
// case - bad type in data throws exception
try {
content.put(ContentObjectFields.SYS_VISIBLE_FOR_ROLES, new Integer(1));
tested.processFieldSysVisibleForRoles(content);
Assert.fail("BadFieldException expected");
} catch (BadFieldException e) {
// OK
}
try {
content.put(ContentObjectFields.SYS_VISIBLE_FOR_ROLES, new HashMap<>());
tested.processFieldSysVisibleForRoles(content);
Assert.fail("BadFieldException expected");
} catch (BadFieldException e) {
// OK
}
}
@Test
public void getTypeInfoWithManagePermissionCheck() {
ContentRestService tested = getTested(false);
// case - field param required validation
try {
tested.getTypeInfoWithManagePermissionCheck(null);
Assert.fail("RequiredFieldException expected");
} catch (RequiredFieldException e) {
// OK
}
try {
tested.getTypeInfoWithManagePermissionCheck("");
Assert.fail("RequiredFieldException expected");
} catch (RequiredFieldException e) {
// OK
}
try {
tested.getTypeInfoWithManagePermissionCheck(" ");
Assert.fail("RequiredFieldException expected");
} catch (RequiredFieldException e) {
// OK
}
// case - unknown type
try {
tested.getTypeInfoWithManagePermissionCheck(TYPE_UNKNOWN);
Assert.fail("BadFieldException expected");
} catch (BadFieldException e) {
// OK
}
// known type, provider has permission
{
ProviderContentTypeInfo ret = tested.getTypeInfoWithManagePermissionCheck(TYPE_KNOWN);
Assert.assertNotNull(ret);
Assert.assertEquals(TYPE_KNOWN, ret.getTypeName());
Assert.assertEquals(ProviderServiceTest.TEST_PROVIDER_NAME, ret.getProviderName());
verify(tested.authenticationUtilService)
.checkProviderManagementPermission(ProviderServiceTest.TEST_PROVIDER_NAME);
}
// known type, provider has no permission
try {
Mockito.doThrow(new NotAuthorizedException("no perm")).when(tested.authenticationUtilService)
.checkProviderManagementPermission(ProviderServiceTest.TEST_PROVIDER_NAME);
tested.getTypeInfoWithManagePermissionCheck(TYPE_KNOWN);
Assert.fail("NotAuthorizedException expected");
} catch (NotAuthorizedException e) {
// OK
}
// known type, provider not authenticated
try {
Mockito.doThrow(new NotAuthenticatedException(AuthenticatedUserType.PROVIDER))
.when(tested.authenticationUtilService)
.checkProviderManagementPermission(ProviderServiceTest.TEST_PROVIDER_NAME);
tested.getTypeInfoWithManagePermissionCheck(TYPE_KNOWN);
Assert.fail("NotAuthenticatedException expected");
} catch (NotAuthenticatedException e) {
// OK
}
}
@Test(expected = RequiredFieldException.class)
public void pushContent_invalidParams_1() throws Exception {
Map<String, Object> content = new HashMap<String, Object>();
content.put("test", "test");
getTested(false).pushContent(null, "1", content);
}
@Test(expected = RequiredFieldException.class)
public void pushContent_invalidParams_2() throws Exception {
Map<String, Object> content = new HashMap<String, Object>();
content.put("test", "test");
getTested(false).pushContent("", "1", content);
}
@Test(expected = RequiredFieldException.class)
public void pushContent_invalidParams_3() throws Exception {
Map<String, Object> content = new HashMap<String, Object>();
content.put("test", "test");
getTested(false).pushContent(TYPE_KNOWN, null, content);
}
@Test(expected = RequiredFieldException.class)
public void pushContent_invalidParams_4() throws Exception {
Map<String, Object> content = new HashMap<String, Object>();
content.put("test", "test");
getTested(false).pushContent(TYPE_KNOWN, "", content);
}
@Test(expected = BadFieldException.class)
public void pushContent_invalidParams_id_1() throws Exception {
Map<String, Object> content = new HashMap<String, Object>();
content.put("test", "test");
getTested(false).pushContent("_id", "1", content);
}
@Test(expected = BadFieldException.class)
public void pushContent_invalidParams_id_2() throws Exception {
Map<String, Object> content = new HashMap<String, Object>();
content.put("test", "test");
getTested(false).pushContent("id,withcomma", "1", content);
}
@Test(expected = BadFieldException.class)
public void pushContent_invalidParams_id_3() throws Exception {
Map<String, Object> content = new HashMap<String, Object>();
content.put("test", "test");
getTested(false).pushContent("id*with*star", "1", content);
}
@Test(expected = BadFieldException.class)
public void pushContent_invalidParams_MissingContent1() throws Exception {
getTested(false).pushContent(TYPE_KNOWN, "1", null);
}
@Test(expected = BadFieldException.class)
public void pushContent_invalidParams_MissingContent2() throws Exception {
Map<String, Object> content = new HashMap<String, Object>();
getTested(false).pushContent(TYPE_KNOWN, "1", content);
}
@Test(expected = BadFieldException.class)
public void pushContent_invalidParams_UnknownType() throws Exception {
// case - type is unknown
Map<String, Object> content = new HashMap<String, Object>();
content.put("test", "test");
getTested(false).pushContent(TYPE_UNKNOWN, "1", content);
}
@Test(expected = Exception.class)
public void pushContent_invalidParams_TypeInvalid() throws Exception {
// case - type configuration is invalid - do not contains index name and/or index type
Map<String, Object> content = new HashMap<String, Object>();
content.put("test", "test");
getTested(false).pushContent(TYPE_INVALID, "1", content);
}
@Test(expected = Exception.class)
public void pushContent_invalidParams_TypeInvalid2() throws Exception {
// case - type configuration is invalid - do not contains sys_type definition
Map<String, Object> content = new HashMap<String, Object>();
content.put("test", "test");
getTested(false).pushContent("invalid_2", "1", content);
}
@Test(expected = Exception.class)
public void pushContent_invalidParams_1SCCTMandatory() throws Exception {
// case - sys_content_content-type not defined if input value contains sys_content
Map<String, Object> content = new HashMap<String, Object>();
content.put("test", "test");
content.put(ContentObjectFields.SYS_CONTENT, "some content");
getTested(false).pushContent(TYPE_INVALID_CONTENT_TYPE, "1", content);
}
@Test(expected = NotAuthorizedException.class)
public void pushContent_noPermission() throws Exception {
ContentRestService tested = getTested(false);
Map<String, Object> content = new HashMap<String, Object>();
content.put("test", "testvalue");
Mockito.doThrow(new NotAuthorizedException("no perm")).when(tested.authenticationUtilService)
.checkProviderManagementPermission(ProviderServiceTest.TEST_PROVIDER_NAME);
tested.pushContent(TYPE_KNOWN, "1", content);
}
@Test(expected = OperationUnavailableException.class)
public void pushContent_apiLockedDown() throws Exception {
ContentRestService tested = getTested(false);
Mockito.when(tested.contentManipulationLockService.isLockedForProvider(Mockito.anyString())).thenReturn(true);
Map<String, Object> content = new HashMap<String, Object>();
content.put("test", "testvalue");
tested.pushContent(TYPE_KNOWN, "1", content);
}
@SuppressWarnings("unchecked")
@Test
public void pushContent_noPersistence() throws Exception {
try {
ContentRestService tested = getTested(true);
Map<String, Object> content = new HashMap<String, Object>();
// case - insert when index is not found
String sys_content_type = TYPE_KNOWN;
{
reset(tested.contentPersistenceService, tested.eventContentStored);
indexDelete(INDEX_NAME);
content.clear();
content.put("test", "testvalue");
content.put(ContentObjectFields.SYS_VISIBLE_FOR_ROLES, "role1");
String sysId = tested.providerService.generateSysId(sys_content_type, "1");
Response r = assertResponseStatus(tested.pushContent(sys_content_type, "1", content), Response.Status.OK);
assertEquals("insert", ((Map<String, String>) r.getEntity()).get("status"));
verify(tested.providerService).runPreprocessors(sys_content_type, PREPROCESSORS, content);
// verify enhancements called
verify(tested.eventBeforeIndexed).fire(prepareContentBeforeIndexedEventMatcher(sysId, content));
indexFlushAndRefresh(INDEX_NAME);
Map<String, Object> doc = indexGetDocument(INDEX_NAME, INDEX_TYPE,
tested.providerService.generateSysId(sys_content_type, "1"));
assertNotNull(doc);
assertEquals("testvalue", doc.get("test"));
assertEquals("jbossorg", doc.get(ContentObjectFields.SYS_CONTENT_PROVIDER));
assertEquals("1", doc.get(ContentObjectFields.SYS_CONTENT_ID));
assertEquals(sys_content_type, doc.get(ContentObjectFields.SYS_CONTENT_TYPE));
assertEquals("my_sys_type", doc.get(ContentObjectFields.SYS_TYPE));
assertEquals(null, doc.get(ContentObjectFields.SYS_CONTENT_CONTENT_TYPE));
assertEquals(sysId, doc.get(ContentObjectFields.SYS_ID));
assertNotNull(doc.get(ContentObjectFields.SYS_UPDATED));
assertEquals(null, doc.get(ContentObjectFields.SYS_TAGS));
assertEquals(TestUtils.createListOfStrings("role1"), doc.get(ContentObjectFields.SYS_VISIBLE_FOR_ROLES));
verify(tested.eventContentStored).fire(prepareContentStoredEventMatcher(sysId));
verifyNoMoreInteractions(tested.contentPersistenceService);
}
// case - insert when index is found, fill sys_updated if not provided in content, process tags provided in
// content, fill sys_content_content-type because sys_content is present
{
reset(tested.providerService, tested.contentPersistenceService, tested.eventContentStored,
tested.eventBeforeIndexed);
setupProviderServiceMock(tested.providerService);
content.put("test2", "testvalue2");
content.put(ContentObjectFields.SYS_CONTENT, "sys content");
content.remove(ContentObjectFields.SYS_UPDATED);
String[] tags = new String[] { "tag_value" };
content.put("tags", tags);
Response r = assertResponseStatus(tested.pushContent(sys_content_type, "2", content), Response.Status.OK);
String sysId = tested.providerService.generateSysId(sys_content_type, "2");
verify(tested.eventBeforeIndexed).fire(prepareContentBeforeIndexedEventMatcher(sysId, content));
assertEquals("insert", ((Map<String, String>) r.getEntity()).get("status"));
verify(tested.providerService).runPreprocessors(sys_content_type, PREPROCESSORS, content);
indexFlushAndRefresh(INDEX_NAME);
Map<String, Object> doc = indexGetDocument(INDEX_NAME, INDEX_TYPE, sysId);
assertNotNull(doc);
assertEquals("testvalue", doc.get("test"));
assertEquals("testvalue2", doc.get("test2"));
assertEquals("jbossorg", doc.get(ContentObjectFields.SYS_CONTENT_PROVIDER));
assertEquals("2", doc.get(ContentObjectFields.SYS_CONTENT_ID));
assertEquals(sys_content_type, doc.get(ContentObjectFields.SYS_CONTENT_TYPE));
assertEquals("my_sys_type", doc.get(ContentObjectFields.SYS_TYPE));
assertEquals("text/plain", doc.get(ContentObjectFields.SYS_CONTENT_CONTENT_TYPE));
String expectedContentId = tested.providerService.generateSysId(sys_content_type, "2");
assertEquals(expectedContentId, doc.get(ContentObjectFields.SYS_ID));
assertNotNull(doc.get(ContentObjectFields.SYS_UPDATED));
assertEquals("tag_value", ((List<String>) doc.get(ContentObjectFields.SYS_TAGS)).get(0));
verify(tested.eventContentStored).fire(prepareContentStoredEventMatcher(expectedContentId));
verifyNoMoreInteractions(tested.contentPersistenceService);
}
// case - rewrite document in index
{
reset(tested.providerService, tested.contentPersistenceService, tested.eventContentStored,
tested.eventBeforeIndexed);
setupProviderServiceMock(tested.providerService);
content.clear();
content.put("test3", "testvalue3");
Response r = assertResponseStatus(tested.pushContent(sys_content_type, "1", content), Response.Status.OK);
String sysId = tested.providerService.generateSysId(sys_content_type, "1");
verify(tested.eventBeforeIndexed).fire(prepareContentBeforeIndexedEventMatcher(sysId, content));
assertEquals("update", ((Map<String, String>) r.getEntity()).get("status"));
verify(tested.providerService).runPreprocessors(sys_content_type, PREPROCESSORS, content);
indexFlushAndRefresh(INDEX_NAME);
Map<String, Object> doc = indexGetDocument(INDEX_NAME, INDEX_TYPE, sysId);
assertNotNull(doc);
assertEquals(null, doc.get("test"));
assertEquals("testvalue3", doc.get("test3"));
assertEquals("jbossorg", doc.get(ContentObjectFields.SYS_CONTENT_PROVIDER));
assertEquals("1", doc.get(ContentObjectFields.SYS_CONTENT_ID));
assertEquals(sys_content_type, doc.get(ContentObjectFields.SYS_CONTENT_TYPE));
assertEquals("my_sys_type", doc.get(ContentObjectFields.SYS_TYPE));
assertEquals(null, doc.get(ContentObjectFields.SYS_CONTENT_CONTENT_TYPE));
String expectedContentId = tested.providerService.generateSysId(sys_content_type, "1");
assertEquals(expectedContentId, doc.get(ContentObjectFields.SYS_ID));
assertNotNull(doc.get(ContentObjectFields.SYS_UPDATED));
assertEquals(null, doc.get(ContentObjectFields.SYS_TAGS));
verify(tested.eventContentStored).fire(prepareContentStoredEventMatcher(expectedContentId));
verifyNoMoreInteractions(tested.contentPersistenceService);
}
} finally {
indexDelete(INDEX_NAME);
finalizeESClientForUnitTest();
}
}
private ContentBeforeIndexedEvent prepareContentBeforeIndexedEventMatcher(final String expectedId,
final Map<String, Object> expectedContentObject) {
return Mockito.argThat(new CustomMatcher<ContentBeforeIndexedEvent>("ContentBeforeIndexedEvent [contentId="
+ expectedId + " data=" + expectedContentObject + "]") {
@Override
public boolean matches(Object paramObject) {
ContentBeforeIndexedEvent e = (ContentBeforeIndexedEvent) paramObject;
return e.getContentId().equals(expectedId) && e.getContentData() == expectedContentObject;
}
});
}
@SuppressWarnings("unchecked")
@Test
public void pushContent_persistence() throws Exception {
try {
ContentRestService tested = getTested(true);
Map<String, Object> content = new HashMap<String, Object>();
// case - insert when index is not found, remove sys_content_content-type because sys_content not present
String sys_content_type = TYPE_PERSIST;
{
Mockito.reset(tested.contentPersistenceService, tested.eventContentStored, tested.eventBeforeIndexed);
indexDelete(INDEX_NAME);
content.clear();
content.put("test", "testvalue");
content.put(ContentObjectFields.SYS_VISIBLE_FOR_ROLES, new ArrayList<String>());
content.put(ContentObjectFields.SYS_CONTENT_CONTENT_TYPE, "text/html");
Response r = assertResponseStatus(tested.pushContent(sys_content_type, "1", content), Response.Status.OK);
// verify enhancements called
String sysId = tested.providerService.generateSysId(sys_content_type, "1");
verify(tested.eventBeforeIndexed).fire(prepareContentBeforeIndexedEventMatcher(sysId, content));
assertEquals("insert", ((Map<String, String>) r.getEntity()).get("status"));
indexFlushAndRefresh(INDEX_NAME);
Map<String, Object> doc = indexGetDocument(INDEX_NAME, INDEX_TYPE,
tested.providerService.generateSysId(sys_content_type, "1"));
assertNotNull(doc);
assertEquals("testvalue", doc.get("test"));
assertEquals("jbossorg", doc.get(ContentObjectFields.SYS_CONTENT_PROVIDER));
assertEquals("1", doc.get(ContentObjectFields.SYS_CONTENT_ID));
assertEquals(sys_content_type, doc.get(ContentObjectFields.SYS_CONTENT_TYPE));
assertEquals("my_sys_type", doc.get(ContentObjectFields.SYS_TYPE));
assertEquals(null, doc.get(ContentObjectFields.SYS_CONTENT_CONTENT_TYPE));
String expectedContentId = tested.providerService.generateSysId(sys_content_type, "1");
assertEquals(expectedContentId, doc.get(ContentObjectFields.SYS_ID));
assertNotNull(doc.get(ContentObjectFields.SYS_UPDATED));
assertFalse(doc.containsKey(ContentObjectFields.SYS_VISIBLE_FOR_ROLES));
assertEquals(null, doc.get(ContentObjectFields.SYS_TAGS));
verify(tested.contentPersistenceService).store(tested.providerService.generateSysId(sys_content_type, "1"),
sys_content_type, content);
verify(tested.eventContentStored).fire(prepareContentStoredEventMatcher(expectedContentId));
verifyNoMoreInteractions(tested.contentPersistenceService);
}
// case - insert when index is found, fill sys_updated if not provided in content, process tags provided in
// content, rewrite sys_content_content-type because sys_content is present
{
reset(tested.providerService, tested.contentPersistenceService, tested.eventContentStored,
tested.eventBeforeIndexed);
setupProviderServiceMock(tested.providerService);
content.put("test2", "testvalue2");
content.put(ContentObjectFields.SYS_CONTENT, "sys content");
content.put(ContentObjectFields.SYS_CONTENT_CONTENT_TYPE, "text/html");
content.remove(ContentObjectFields.SYS_UPDATED);
String[] tags = new String[] { "tag_value" };
content.put("tags", tags);
Response r = assertResponseStatus(tested.pushContent(sys_content_type, "2", content), Response.Status.OK);
// verify enhancements called
String sysId = tested.providerService.generateSysId(sys_content_type, "2");
verify(tested.eventBeforeIndexed).fire(prepareContentBeforeIndexedEventMatcher(sysId, content));
assertEquals("insert", ((Map<String, String>) r.getEntity()).get("status"));
indexFlushAndRefresh(INDEX_NAME);
Map<String, Object> doc = indexGetDocument(INDEX_NAME, INDEX_TYPE, sysId);
assertNotNull(doc);
assertEquals("testvalue", doc.get("test"));
assertEquals("testvalue2", doc.get("test2"));
assertEquals("jbossorg", doc.get(ContentObjectFields.SYS_CONTENT_PROVIDER));
assertEquals("2", doc.get(ContentObjectFields.SYS_CONTENT_ID));
assertEquals(sys_content_type, doc.get(ContentObjectFields.SYS_CONTENT_TYPE));
assertEquals("my_sys_type", doc.get(ContentObjectFields.SYS_TYPE));
assertEquals("text/plain", doc.get(ContentObjectFields.SYS_CONTENT_CONTENT_TYPE));
String expectedContentId = tested.providerService.generateSysId(sys_content_type, "2");
assertEquals(expectedContentId, doc.get(ContentObjectFields.SYS_ID));
assertNotNull(doc.get(ContentObjectFields.SYS_UPDATED));
assertEquals("tag_value", ((List<String>) doc.get(ContentObjectFields.SYS_TAGS)).get(0));
verify(tested.contentPersistenceService).store(tested.providerService.generateSysId(sys_content_type, "2"),
sys_content_type, content);
verify(tested.eventContentStored).fire(prepareContentStoredEventMatcher(expectedContentId));
verifyNoMoreInteractions(tested.contentPersistenceService);
}
// case - rewrite document in index
{
reset(tested.providerService, tested.contentPersistenceService, tested.eventContentStored,
tested.eventBeforeIndexed);
setupProviderServiceMock(tested.providerService);
content.clear();
content.put("test3", "testvalue3");
Response r = assertResponseStatus(tested.pushContent(sys_content_type, "1", content), Response.Status.OK);
// verify enhancements called
String sysId = tested.providerService.generateSysId(sys_content_type, "1");
verify(tested.eventBeforeIndexed).fire(prepareContentBeforeIndexedEventMatcher(sysId, content));
assertEquals("update", ((Map<String, String>) r.getEntity()).get("status"));
indexFlushAndRefresh(INDEX_NAME);
Map<String, Object> doc = indexGetDocument(INDEX_NAME, INDEX_TYPE, sysId);
assertNotNull(doc);
assertEquals(null, doc.get("test"));
assertEquals("testvalue3", doc.get("test3"));
assertEquals("jbossorg", doc.get(ContentObjectFields.SYS_CONTENT_PROVIDER));
assertEquals("1", doc.get(ContentObjectFields.SYS_CONTENT_ID));
assertEquals(sys_content_type, doc.get(ContentObjectFields.SYS_CONTENT_TYPE));
assertEquals("my_sys_type", doc.get(ContentObjectFields.SYS_TYPE));
assertEquals(null, doc.get(ContentObjectFields.SYS_CONTENT_CONTENT_TYPE));
assertEquals(tested.providerService.generateSysId(sys_content_type, "1"), doc.get(ContentObjectFields.SYS_ID));
assertNotNull(doc.get(ContentObjectFields.SYS_UPDATED));
assertEquals(null, doc.get(ContentObjectFields.SYS_TAGS));
String expectedContentId = tested.providerService.generateSysId(sys_content_type, "1");
verify(tested.contentPersistenceService).store(expectedContentId, sys_content_type, content);
verify(tested.eventContentStored).fire(prepareContentStoredEventMatcher(expectedContentId));
verifyNoMoreInteractions(tested.contentPersistenceService);
}
} finally {
indexDelete(INDEX_NAME);
finalizeESClientForUnitTest();
}
}
@Test(expected = NotAuthorizedException.class)
public void pushContentBulk_noPermission() throws Exception {
ContentRestService tested = getTested(false);
Map<String, Object> content = new HashMap<String, Object>();
Map<String, Object> contentItem = new HashMap<String, Object>();
contentItem.put("title", "aaa");
content.put("1", contentItem);
Mockito.doThrow(new NotAuthorizedException("no perm")).when(tested.authenticationUtilService)
.checkProviderManagementPermission(ProviderServiceTest.TEST_PROVIDER_NAME);
tested.pushContentBulk(TYPE_KNOWN, content);
}
@Test(expected = OperationUnavailableException.class)
public void pushContentBulk_apiLockedDown() throws Exception {
ContentRestService tested = getTested(false);
Mockito.when(tested.contentManipulationLockService.isLockedForProvider(Mockito.anyString())).thenReturn(true);
Map<String, Object> content = new HashMap<String, Object>();
Map<String, Object> contentItem = new HashMap<String, Object>();
contentItem.put("title", "aaa");
content.put("1", contentItem);
tested.pushContentBulk(TYPE_KNOWN, content);
}
@SuppressWarnings("unchecked")
@Test
public void pushContentBulk_noPersistence() throws Exception {
try {
ContentRestService tested = getTested(true);
String sys_content_type = TYPE_KNOWN;
// case - insert/update, fill sys_updated if not provided in content, process tags provided in
// content, fill sys_content_content-type because sys_content is present
{
String sysId_1 = tested.providerService.generateSysId(sys_content_type, "1");
String sysId_2 = tested.providerService.generateSysId(sys_content_type, "2");
indexInsertDocument(INDEX_NAME, INDEX_TYPE, sysId_1, "{\"test\":\"old\"}");
indexFlushAndRefresh(INDEX_NAME);
reset(tested.providerService, tested.contentPersistenceService, tested.eventContentStored,
tested.eventBeforeIndexed);
setupProviderServiceMock(tested.providerService);
Map<String, Object> contentStructure = new LinkedHashMap<>();
// empty content means error
contentStructure.put("empty_content", new HashMap<>());
Map<String, Object> content_1 = new HashMap<>();
contentStructure.put("1", content_1);
content_1.put("test", "testvalue");
content_1.put(ContentObjectFields.SYS_CONTENT, "sys content");
content_1.remove(ContentObjectFields.SYS_UPDATED);
String[] tags = new String[] { "tag_value" };
content_1.put("tags", tags);
Map<String, Object> content_2 = new HashMap<>();
contentStructure.put("2", content_2);
content_2.put("test2", "testvalue2");
content_2.put(ContentObjectFields.SYS_CONTENT, "sys content");
content_2.remove(ContentObjectFields.SYS_UPDATED);
String[] tags2 = new String[] { "tag_value" };
content_2.put("tags", tags2);
// validation of id format
contentStructure.put("_bad_id_format", content_2);
contentStructure.put("bad_id,format", content_2);
contentStructure.put("bad_id*format", content_2);
Map<String, Map<String, Object>> ret = (Map<String, Map<String, Object>>) tested.pushContentBulk(
sys_content_type, contentStructure);
Assert.assertEquals(6, ret.size());
assertBulkPushRetItem(ret.get("empty_content"), "error",
"fieldName=content, description=Some content for pushing must be defined");
assertBulkPushRetItem(ret.get("_bad_id_format"), "error",
"fieldName=contentId, description=contentId can't start with underscore or contain comma, star");
assertBulkPushRetItem(ret.get("bad_id,format"), "error",
"fieldName=contentId, description=contentId can't start with underscore or contain comma, star");
assertBulkPushRetItem(ret.get("bad_id*format"), "error",
"fieldName=contentId, description=contentId can't start with underscore or contain comma, star");
assertBulkPushRetItem(ret.get("1"), "update", "Content updated successfully.");
assertBulkPushRetItem(ret.get("2"), "insert", "Content inserted successfully.");
verify(tested.eventBeforeIndexed).fire(prepareContentBeforeIndexedEventMatcher(sysId_1, content_1));
verify(tested.eventBeforeIndexed).fire(prepareContentBeforeIndexedEventMatcher(sysId_2, content_2));
verify(tested.providerService).runPreprocessors(sys_content_type, PREPROCESSORS, content_1);
verify(tested.providerService).runPreprocessors(sys_content_type, PREPROCESSORS, content_2);
verify(tested.eventContentStored).fire(prepareContentStoredEventMatcher(sysId_1));
verify(tested.eventContentStored).fire(prepareContentStoredEventMatcher(sysId_2));
verifyNoMoreInteractions(tested.contentPersistenceService, tested.eventBeforeIndexed,
tested.eventContentDeleted, tested.eventContentStored);
indexFlushAndRefresh(INDEX_NAME);
// assert documents in index
{
Map<String, Object> doc = indexGetDocument(INDEX_NAME, INDEX_TYPE, sysId_2);
assertNotNull(doc);
assertEquals("testvalue2", doc.get("test2"));
assertEquals("jbossorg", doc.get(ContentObjectFields.SYS_CONTENT_PROVIDER));
assertEquals("2", doc.get(ContentObjectFields.SYS_CONTENT_ID));
assertEquals(sys_content_type, doc.get(ContentObjectFields.SYS_CONTENT_TYPE));
assertEquals("my_sys_type", doc.get(ContentObjectFields.SYS_TYPE));
assertEquals("text/plain", doc.get(ContentObjectFields.SYS_CONTENT_CONTENT_TYPE));
assertEquals(sysId_2, doc.get(ContentObjectFields.SYS_ID));
assertNotNull(doc.get(ContentObjectFields.SYS_UPDATED));
assertEquals("tag_value", ((List<String>) doc.get(ContentObjectFields.SYS_TAGS)).get(0));
}
{
Map<String, Object> doc = indexGetDocument(INDEX_NAME, INDEX_TYPE, sysId_1);
assertNotNull(doc);
assertEquals("testvalue", doc.get("test"));
assertEquals("jbossorg", doc.get(ContentObjectFields.SYS_CONTENT_PROVIDER));
}
}
} finally {
indexDelete(INDEX_NAME);
finalizeESClientForUnitTest();
}
}
@SuppressWarnings("unchecked")
@Test
public void pushContentBulk_persistence() throws Exception {
try {
ContentRestService tested = getTested(true);
String sys_content_type = TYPE_PERSIST;
// case - insert/update, fill sys_updated if not provided in content, process tags provided in
// content, fill sys_content_content-type because sys_content is present
{
String sysId_1 = tested.providerService.generateSysId(sys_content_type, "1");
String sysId_2 = tested.providerService.generateSysId(sys_content_type, "2");
indexInsertDocument(INDEX_NAME, INDEX_TYPE, sysId_1, "{\"test\":\"old\"}");
indexFlushAndRefresh(INDEX_NAME);
reset(tested.providerService, tested.contentPersistenceService, tested.eventContentStored,
tested.eventBeforeIndexed);
setupProviderServiceMock(tested.providerService);
Map<String, Object> contentStructure = new LinkedHashMap<>();
// empty content means error
contentStructure.put("empty_content", new HashMap<>());
Map<String, Object> content_1 = new HashMap<>();
contentStructure.put("1", content_1);
content_1.put("test", "testvalue");
content_1.put(ContentObjectFields.SYS_CONTENT, "sys content");
content_1.remove(ContentObjectFields.SYS_UPDATED);
String[] tags = new String[] { "tag_value" };
content_1.put("tags", tags);
Map<String, Object> content_2 = new HashMap<>();
contentStructure.put("2", content_2);
content_2.put("test2", "testvalue2");
content_2.put(ContentObjectFields.SYS_CONTENT, "sys content");
content_2.remove(ContentObjectFields.SYS_UPDATED);
String[] tags2 = new String[] { "tag_value" };
content_2.put("tags", tags2);
// validation of id format
contentStructure.put("_bad_id_format", content_2);
contentStructure.put("bad_id,format", content_2);
contentStructure.put("bad_id*format", content_2);
Map<String, Map<String, Object>> ret = (Map<String, Map<String, Object>>) tested.pushContentBulk(
sys_content_type, contentStructure);
Assert.assertEquals(6, ret.size());
assertBulkPushRetItem(ret.get("empty_content"), "error",
"fieldName=content, description=Some content for pushing must be defined");
assertBulkPushRetItem(ret.get("_bad_id_format"), "error",
"fieldName=contentId, description=contentId can't start with underscore or contain comma, star");
assertBulkPushRetItem(ret.get("bad_id,format"), "error",
"fieldName=contentId, description=contentId can't start with underscore or contain comma, star");
assertBulkPushRetItem(ret.get("bad_id*format"), "error",
"fieldName=contentId, description=contentId can't start with underscore or contain comma, star");
assertBulkPushRetItem(ret.get("1"), "update", "Content updated successfully.");
assertBulkPushRetItem(ret.get("2"), "insert", "Content inserted successfully.");
verify(tested.eventBeforeIndexed).fire(prepareContentBeforeIndexedEventMatcher(sysId_1, content_1));
verify(tested.eventBeforeIndexed).fire(prepareContentBeforeIndexedEventMatcher(sysId_2, content_2));
verify(tested.providerService).runPreprocessors(sys_content_type, null, content_1);
verify(tested.providerService).runPreprocessors(sys_content_type, null, content_2);
verify(tested.contentPersistenceService).store(sysId_1, sys_content_type, content_1);
verify(tested.contentPersistenceService).store(sysId_2, sys_content_type, content_2);
verify(tested.eventContentStored).fire(prepareContentStoredEventMatcher(sysId_1));
verify(tested.eventContentStored).fire(prepareContentStoredEventMatcher(sysId_2));
verifyNoMoreInteractions(tested.contentPersistenceService, tested.eventBeforeIndexed,
tested.eventContentDeleted, tested.eventContentStored);
indexFlushAndRefresh(INDEX_NAME);
// assert documents in index
{
Map<String, Object> doc = indexGetDocument(INDEX_NAME, INDEX_TYPE, sysId_2);
assertNotNull(doc);
assertEquals("testvalue2", doc.get("test2"));
assertEquals("jbossorg", doc.get(ContentObjectFields.SYS_CONTENT_PROVIDER));
assertEquals("2", doc.get(ContentObjectFields.SYS_CONTENT_ID));
assertEquals(sys_content_type, doc.get(ContentObjectFields.SYS_CONTENT_TYPE));
assertEquals("my_sys_type", doc.get(ContentObjectFields.SYS_TYPE));
assertEquals("text/plain", doc.get(ContentObjectFields.SYS_CONTENT_CONTENT_TYPE));
assertEquals(sysId_2, doc.get(ContentObjectFields.SYS_ID));
assertNotNull(doc.get(ContentObjectFields.SYS_UPDATED));
assertEquals("tag_value", ((List<String>) doc.get(ContentObjectFields.SYS_TAGS)).get(0));
}
{
Map<String, Object> doc = indexGetDocument(INDEX_NAME, INDEX_TYPE, sysId_1);
assertNotNull(doc);
assertEquals("testvalue", doc.get("test"));
assertEquals("jbossorg", doc.get(ContentObjectFields.SYS_CONTENT_PROVIDER));
}
}
} finally {
indexDelete(INDEX_NAME);
finalizeESClientForUnitTest();
}
}
private void assertBulkPushRetItem(Map<String, Object> map, String expectedStatus, String expectedMessage) {
Assert.assertNotNull(map);
Assert.assertEquals(expectedStatus, map.get(ContentRestService.RETFIELD_STATUS));
Assert.assertEquals(expectedMessage, map.get(ContentRestService.RETFIELD_MESSAGE));
}
private ContentStoredEvent prepareContentStoredEventMatcher(final String expectedContentId) {
return Mockito.argThat(new CustomMatcher<ContentStoredEvent>("ContentStoredEvent [contributorId="
+ expectedContentId + "]") {
@Override
public boolean matches(Object paramObject) {
ContentStoredEvent e = (ContentStoredEvent) paramObject;
return e.getContentId().equals(expectedContentId) && e.getContentData() != null;
}
});
}
private ContentDeletedEvent prepareContentDeletedEventMatcher(final String expectedContentId) {
return Mockito.argThat(new CustomMatcher<ContentDeletedEvent>("ContentDeletedEvent [contributorId="
+ expectedContentId + "]") {
@Override
public boolean matches(Object paramObject) {
ContentDeletedEvent e = (ContentDeletedEvent) paramObject;
return e.getContentId().equals(expectedContentId);
}
});
}
@Test(expected = RequiredFieldException.class)
public void deleteContent_ParamValidation_1() throws Exception {
getTested(false).deleteContent(null, "1", null);
}
@Test(expected = RequiredFieldException.class)
public void deleteContent_ParamValidation_2() throws Exception {
getTested(false).deleteContent("", "1", null);
}
@Test(expected = RequiredFieldException.class)
public void deleteContent_ParamValidation_3() throws Exception {
getTested(false).deleteContent(TYPE_KNOWN, null, null);
}
@Test(expected = RequiredFieldException.class)
public void deleteContent_ParamValidation_4() throws Exception {
getTested(false).deleteContent(TYPE_KNOWN, "", null);
}
@Test(expected = BadFieldException.class)
public void deleteContent_ParamValidation_UnknownType() throws Exception {
// case - type is unknown
getTested(false).deleteContent(TYPE_UNKNOWN, "1", null);
}
@Test(expected = Exception.class)
public void deleteContent_ParamValidation_TypeInvalid() throws Exception {
// case - type configuration is invalid - do not contains index name and/or index type
getTested(false).deleteContent(TYPE_INVALID, "1", null);
}
@Test(expected = NotAuthorizedException.class)
public void deleteContent_noPermission() throws Exception {
ContentRestService tested = getTested(false);
Map<String, Object> content = new HashMap<String, Object>();
content.put("test", "testvalue");
Mockito.doThrow(new NotAuthorizedException("no perm")).when(tested.authenticationUtilService)
.checkProviderManagementPermission(ProviderServiceTest.TEST_PROVIDER_NAME);
tested.deleteContent(TYPE_KNOWN, "1", null);
}
@Test(expected = OperationUnavailableException.class)
public void deleteContent_apiLockedDown() throws Exception {
ContentRestService tested = getTested(false);
Map<String, Object> content = new HashMap<String, Object>();
content.put("test", "testvalue");
Mockito.when(tested.contentManipulationLockService.isLockedForProvider(Mockito.anyString())).thenReturn(true);
tested.deleteContent(TYPE_KNOWN, "1", null);
}
@Test
public void deleteContent() throws Exception {
try {
ContentRestService tested = getTested(true);
// case - delete when index is not found
{
reset(tested.contentPersistenceService, tested.eventContentDeleted);
indexDelete(INDEX_NAME);
assertResponseStatus(tested.deleteContent(TYPE_KNOWN, "1", null), Response.Status.NOT_FOUND);
assertResponseStatus(tested.deleteContent(TYPE_PERSIST, "1", null), Response.Status.NOT_FOUND);
verify(tested.contentPersistenceService).delete(tested.providerService.generateSysId(TYPE_PERSIST, "1"),
TYPE_PERSIST);
verifyZeroInteractions(tested.eventContentDeleted);
verifyNoMoreInteractions(tested.contentPersistenceService);
}
// case - delete when document doesn't exist in index
{
reset(tested.contentPersistenceService, tested.eventContentDeleted);
indexDelete(INDEX_NAME);
indexCreate(INDEX_NAME);
indexInsertDocument(INDEX_NAME, INDEX_TYPE, "known-2", "{\"test2\":\"test2\"}");
indexFlushAndRefresh(INDEX_NAME);
assertResponseStatus(tested.deleteContent(TYPE_KNOWN, "1", null), Response.Status.NOT_FOUND);
assertResponseStatus(tested.deleteContent(TYPE_PERSIST, "1", null), Response.Status.NOT_FOUND);
assertNotNull(indexGetDocument(INDEX_NAME, INDEX_TYPE, "known-2"));
verify(tested.contentPersistenceService).delete(tested.providerService.generateSysId(TYPE_PERSIST, "1"),
TYPE_PERSIST);
verifyZeroInteractions(tested.eventContentDeleted);
verifyNoMoreInteractions(tested.contentPersistenceService);
}
// case - delete when document exist in index
{
reset(tested.contentPersistenceService, tested.eventContentDeleted);
indexInsertDocument(INDEX_NAME, INDEX_TYPE, "known-1", "{\"test1\":\"test1\"}");
indexInsertDocument(INDEX_NAME, INDEX_TYPE, "persist-1", "{\"test1\":\"testper1\"}");
indexFlushAndRefresh(INDEX_NAME);
assertResponseStatus(tested.deleteContent(TYPE_KNOWN, "1", null), Response.Status.OK);
verify(tested.eventContentDeleted).fire(prepareContentDeletedEventMatcher("known-1"));
assertNull(indexGetDocument(INDEX_NAME, INDEX_TYPE, "known-1"));
assertResponseStatus(tested.deleteContent(TYPE_PERSIST, "1", null), Response.Status.OK);
assertNull(indexGetDocument(INDEX_NAME, INDEX_TYPE, "persist-1"));
assertNotNull(indexGetDocument(INDEX_NAME, INDEX_TYPE, "known-2"));
verify(tested.eventContentDeleted).fire(prepareContentDeletedEventMatcher("persist-1"));
// another subsequent deletes
assertResponseStatus(tested.deleteContent(TYPE_KNOWN, "1", null), Response.Status.NOT_FOUND);
assertResponseStatus(tested.deleteContent(TYPE_PERSIST, "1", null), Response.Status.NOT_FOUND);
assertResponseStatus(tested.deleteContent(TYPE_KNOWN, "2", null), Response.Status.OK);
verify(tested.eventContentDeleted).fire(prepareContentDeletedEventMatcher("known-2"));
assertNull(indexGetDocument(INDEX_NAME, INDEX_TYPE, "known-1"));
assertNull(indexGetDocument(INDEX_NAME, INDEX_TYPE, "known-2"));
// test ignore_missing parameter
assertResponseStatus(tested.deleteContent(TYPE_KNOWN, "1", null), Response.Status.NOT_FOUND);
assertResponseStatus(tested.deleteContent(TYPE_KNOWN, "1", "false"), Response.Status.NOT_FOUND);
assertResponseStatus(tested.deleteContent(TYPE_KNOWN, "1", "true"), Response.Status.OK);
verify(tested.contentPersistenceService, Mockito.times(2)).delete(
tested.providerService.generateSysId(TYPE_PERSIST, "1"), TYPE_PERSIST);
verifyNoMoreInteractions(tested.eventContentDeleted);
verifyNoMoreInteractions(tested.contentPersistenceService);
}
} finally {
indexDelete(INDEX_NAME);
finalizeESClientForUnitTest();
}
}
@Test(expected = RequiredFieldException.class)
public void deleteContentBulk_ParamValidation_1() throws Exception {
Map<String, Object> content = new HashMap<String, Object>();
content.put("id", new ArrayList<String>());
getTested(false).deleteContentBulk(null, content);
}
@Test(expected = RequiredFieldException.class)
public void deleteContentBulk_ParamValidation_2() throws Exception {
Map<String, Object> content = new HashMap<String, Object>();
content.put("id", new ArrayList<String>());
getTested(false).deleteContentBulk("", content);
}
@Test
public void deleteContentBulk_invalidRequestContent() throws Exception {
TestUtils.assertResponseStatus(getTested(false).deleteContentBulk(TYPE_KNOWN, null), Response.Status.BAD_REQUEST);
Map<String, Object> content = new HashMap<String, Object>();
TestUtils
.assertResponseStatus(getTested(false).deleteContentBulk(TYPE_KNOWN, content), Response.Status.BAD_REQUEST);
content.put("id", new Object());
TestUtils
.assertResponseStatus(getTested(false).deleteContentBulk(TYPE_KNOWN, content), Response.Status.BAD_REQUEST);
}
@Test(expected = NotAuthorizedException.class)
public void deleteContentBulk_noPermission() throws Exception {
ContentRestService tested = getTested(false);
Map<String, Object> content = new HashMap<String, Object>();
content.put("id", new ArrayList<String>());
Mockito.doThrow(new NotAuthorizedException("no perm")).when(tested.authenticationUtilService)
.checkProviderManagementPermission(ProviderServiceTest.TEST_PROVIDER_NAME);
tested.deleteContentBulk(TYPE_KNOWN, content);
}
@Test(expected = OperationUnavailableException.class)
public void deleteContentBulk_apiLockedDown() throws Exception {
ContentRestService tested = getTested(false);
Mockito.when(tested.contentManipulationLockService.isLockedForProvider(Mockito.anyString())).thenReturn(true);
Map<String, Object> content = new HashMap<String, Object>();
content.put("id", new ArrayList<String>());
tested.deleteContentBulk(TYPE_KNOWN, content);
}
@SuppressWarnings("unchecked")
@Test
public void deleteContentBulk() {
try {
ContentRestService tested = getTested(true);
Map<String, Object> content = new HashMap<String, Object>();
List<String> ids = new ArrayList<String>();
content.put("id", ids);
// case - delete when index is not found
{
ids.add("1");
ids.add("2");
reset(tested.contentPersistenceService, tested.eventContentDeleted);
indexDelete(INDEX_NAME);
// without persistence
Map<String, String> ret = (Map<String, String>) tested.deleteContentBulk(TYPE_KNOWN, content);
Assert.assertEquals(2, ret.size());
Assert.assertEquals("not_found", ret.get("1"));
Assert.assertEquals("not_found", ret.get("2"));
// persistently stored content
ret = (Map<String, String>) tested.deleteContentBulk(TYPE_PERSIST, content);
Assert.assertEquals(2, ret.size());
Assert.assertEquals("not_found", ret.get("1"));
Assert.assertEquals("not_found", ret.get("2"));
verify(tested.contentPersistenceService).delete(tested.providerService.generateSysId(TYPE_PERSIST, "1"),
TYPE_PERSIST);
verify(tested.contentPersistenceService).delete(tested.providerService.generateSysId(TYPE_PERSIST, "2"),
TYPE_PERSIST);
verifyZeroInteractions(tested.eventContentDeleted);
verifyNoMoreInteractions(tested.contentPersistenceService);
}
// case - delete when no any of documents exist in index
{
reset(tested.contentPersistenceService, tested.eventContentDeleted);
indexDelete(INDEX_NAME);
indexCreate(INDEX_NAME);
indexInsertDocument(INDEX_NAME, INDEX_TYPE, "known-3", "{\"test3\":\"test3\"}");
indexFlushAndRefresh(INDEX_NAME);
// without persistence
Map<String, String> ret = (Map<String, String>) tested.deleteContentBulk(TYPE_KNOWN, content);
Assert.assertEquals(2, ret.size());
Assert.assertEquals("not_found", ret.get("1"));
Assert.assertEquals("not_found", ret.get("2"));
assertNotNull(indexGetDocument(INDEX_NAME, INDEX_TYPE, "known-3"));
// persistently stored content
ret = (Map<String, String>) tested.deleteContentBulk(TYPE_PERSIST, content);
Assert.assertEquals(2, ret.size());
Assert.assertEquals("not_found", ret.get("1"));
Assert.assertEquals("not_found", ret.get("2"));
verify(tested.contentPersistenceService).delete(tested.providerService.generateSysId(TYPE_PERSIST, "1"),
TYPE_PERSIST);
verify(tested.contentPersistenceService).delete(tested.providerService.generateSysId(TYPE_PERSIST, "2"),
TYPE_PERSIST);
verifyZeroInteractions(tested.eventContentDeleted);
verifyNoMoreInteractions(tested.contentPersistenceService);
}
// case - delete when part of documents exist in index
{
ids.add("10");
reset(tested.contentPersistenceService, tested.eventContentDeleted);
indexInsertDocument(INDEX_NAME, INDEX_TYPE, "known-1", "{\"test1\":\"test1\"}");
indexInsertDocument(INDEX_NAME, INDEX_TYPE, "persist-1", "{\"test1\":\"testper1\"}");
indexInsertDocument(INDEX_NAME, INDEX_TYPE, "known-2", "{\"test1\":\"test1\"}");
indexInsertDocument(INDEX_NAME, INDEX_TYPE, "persist-2", "{\"test1\":\"testper1\"}");
indexInsertDocument(INDEX_NAME, INDEX_TYPE, "known-3", "{\"test1\":\"test1\"}");
indexInsertDocument(INDEX_NAME, INDEX_TYPE, "persist-3", "{\"test1\":\"testper1\"}");
indexInsertDocument(INDEX_NAME, INDEX_TYPE, "known-4", "{\"test1\":\"test1\"}");
indexInsertDocument(INDEX_NAME, INDEX_TYPE, "persist-4", "{\"test1\":\"testper1\"}");
indexFlushAndRefresh(INDEX_NAME);
// without persistence
Map<String, String> ret = (Map<String, String>) tested.deleteContentBulk(TYPE_KNOWN, content);
Assert.assertEquals(3, ret.size());
Assert.assertEquals("ok", ret.get("1"));
Assert.assertEquals("ok", ret.get("2"));
Assert.assertEquals("not_found", ret.get("10"));
verify(tested.eventContentDeleted).fire(prepareContentDeletedEventMatcher("known-1"));
verify(tested.eventContentDeleted).fire(prepareContentDeletedEventMatcher("known-2"));
assertNull(indexGetDocument(INDEX_NAME, INDEX_TYPE, "known-1"));
assertNull(indexGetDocument(INDEX_NAME, INDEX_TYPE, "known-2"));
assertNotNull(indexGetDocument(INDEX_NAME, INDEX_TYPE, "known-3"));
assertNotNull(indexGetDocument(INDEX_NAME, INDEX_TYPE, "known-4"));
assertNotNull(indexGetDocument(INDEX_NAME, INDEX_TYPE, "persist-1"));
assertNotNull(indexGetDocument(INDEX_NAME, INDEX_TYPE, "persist-2"));
assertNotNull(indexGetDocument(INDEX_NAME, INDEX_TYPE, "persist-3"));
assertNotNull(indexGetDocument(INDEX_NAME, INDEX_TYPE, "persist-4"));
// persistently stored content
ret = (Map<String, String>) tested.deleteContentBulk(TYPE_PERSIST, content);
Assert.assertEquals(3, ret.size());
Assert.assertEquals("ok", ret.get("1"));
Assert.assertEquals("ok", ret.get("2"));
Assert.assertEquals("not_found", ret.get("10"));
assertNull(indexGetDocument(INDEX_NAME, INDEX_TYPE, "persist-1"));
assertNull(indexGetDocument(INDEX_NAME, INDEX_TYPE, "persist-2"));
assertNotNull(indexGetDocument(INDEX_NAME, INDEX_TYPE, "persist-3"));
assertNotNull(indexGetDocument(INDEX_NAME, INDEX_TYPE, "persist-4"));
assertNotNull(indexGetDocument(INDEX_NAME, INDEX_TYPE, "known-3"));
assertNotNull(indexGetDocument(INDEX_NAME, INDEX_TYPE, "known-4"));
verify(tested.contentPersistenceService).delete(tested.providerService.generateSysId(TYPE_PERSIST, "1"),
TYPE_PERSIST);
verify(tested.contentPersistenceService).delete(tested.providerService.generateSysId(TYPE_PERSIST, "2"),
TYPE_PERSIST);
verify(tested.contentPersistenceService).delete(tested.providerService.generateSysId(TYPE_PERSIST, "10"),
TYPE_PERSIST);
verify(tested.eventContentDeleted).fire(prepareContentDeletedEventMatcher("persist-1"));
verify(tested.eventContentDeleted).fire(prepareContentDeletedEventMatcher("persist-2"));
// event is not fired for 10 as it is not deleted actually because doesn't exist
verifyNoMoreInteractions(tested.eventContentDeleted);
verifyNoMoreInteractions(tested.contentPersistenceService);
}
} finally {
indexDelete(INDEX_NAME);
finalizeESClientForUnitTest();
}
}
@Test(expected = RequiredFieldException.class)
public void getAllContent_ParamValidation_1() throws IOException, InterruptedException {
getTested(false).getAllContent(null, null, null, null);
}
@Test(expected = RequiredFieldException.class)
public void getAllContent_ParamValidation_2() throws IOException, InterruptedException {
getTested(false).getAllContent("", null, null, null);
}
@Test(expected = BadFieldException.class)
public void getAllContent_ParamValidation_UnknownType() throws IOException, InterruptedException {
// case - type is unknown
getTested(false).getAllContent(TYPE_UNKNOWN, null, null, null);
}
@Test(expected = SettingsException.class)
public void getAllContent_ParamValidation_TypeConfigInvalid() throws IOException, InterruptedException {
// case - type configuration is invalid (do not contains index name and type)
getTested(false).getAllContent(TYPE_INVALID, null, null, null);
}
@Test
public void getAllContent() throws IOException, InterruptedException, JSONException {
try {
ContentRestService tested = getTested(true);
// case - type is valid, but nothing is found because index is missing
indexDelete(INDEX_NAME);
assertResponseStatus(tested.getAllContent(TYPE_KNOWN, null, null, null), Response.Status.NOT_FOUND);
// case - nothing found because index is empty
indexCreate(INDEX_NAME);
assetJsonStreamingOutputContent("{\"total\":0,\"hits\":[]}", tested.getAllContent(TYPE_KNOWN, null, null, null));
// case - something found, no from and size param used
indexInsertDocument(INDEX_NAME, INDEX_TYPE, "known-1",
"{\"name\":\"test1\", \"sys_updated\" : 0,\"sys_content_id\":\"1\"}");
indexInsertDocument(INDEX_NAME, INDEX_TYPE, "known-2",
"{\"name\":\"test2\",\"sys_updated\":1,\"sys_content_id\":\"2\"}");
indexInsertDocument(INDEX_NAME, INDEX_TYPE, "known-3",
"{\"name\":\"test3\",\"sys_updated\":2,\"sys_content_id\":\"3\"}");
indexInsertDocument(INDEX_NAME, INDEX_TYPE, "known-4",
"{\"name\":\"test4\",\"sys_updated\":3,\"sys_content_id\":\"4\"}");
indexFlushAndRefresh(INDEX_NAME);
assetJsonStreamingOutputContent("{\"total\":4,\"hits\":["
+ "{\"id\":\"1\",\"data\":{\"sys_updated\":0,\"sys_content_id\":\"1\",\"name\":\"test1\"}},"
+ "{\"id\":\"2\",\"data\":{\"sys_updated\":1,\"sys_content_id\":\"2\",\"name\":\"test2\"}},"
+ "{\"id\":\"3\",\"data\":{\"sys_updated\":2,\"sys_content_id\":\"3\",\"name\":\"test3\"}},"
+ "{\"id\":\"4\",\"data\":{\"sys_updated\":3,\"sys_content_id\":\"4\",\"name\":\"test4\"}}" + "]}",
tested.getAllContent(TYPE_KNOWN, null, null, null));
// case - something found, from and size param used
assetJsonStreamingOutputContent("{\"total\":4,\"hits\":["
+ "{\"id\":\"2\",\"data\":{\"sys_updated\":1,\"sys_content_id\":\"2\",\"name\":\"test2\"}},"
+ "{\"id\":\"3\",\"data\":{\"sys_updated\":2,\"sys_content_id\":\"3\",\"name\":\"test3\"}}" + "]}",
tested.getAllContent(TYPE_KNOWN, 1, 2, null));
// case - sort param used
indexInsertDocument(INDEX_NAME, INDEX_TYPE, "known-5",
"{\"name\":\"test5\", \"sys_updated\" : 4,\"sys_content_id\":\"5\"}");
indexFlushAndRefresh(INDEX_NAME);
// on ASC our record with id 5 is last, so we set from=4
assetJsonStreamingOutputContent(
"{\"total\":5,\"hits\":[{\"id\":\"5\",\"data\":{\"sys_updated\":4,\"sys_content_id\":\"5\",\"name\":\"test5\"}}]}",
tested.getAllContent(TYPE_KNOWN, 4, 1, "asc"));
// on DESC our record with id 5 is first, so we set from=0
assetJsonStreamingOutputContent(
"{\"total\":5,\"hits\":[{\"id\":\"5\",\"data\":{\"sys_updated\":4,\"sys_content_id\":\"5\",\"name\":\"test5\"}}]}",
tested.getAllContent(TYPE_KNOWN, 0, 1, "DESC"));
} finally {
indexDelete(INDEX_NAME);
finalizeESClientForUnitTest();
}
}
@Test(expected = RequiredFieldException.class)
public void getContent_ParamValidation_1() {
// case - invalid input parameters
getTested(true).getContent(null, "1");
}
@Test(expected = RequiredFieldException.class)
public void getContent_ParamValidation_2() {
getTested(true).getContent("", "1");
}
@Test(expected = RequiredFieldException.class)
public void getContent_ParamValidation_3() {
getTested(true).getContent("testtype", null);
}
@Test(expected = RequiredFieldException.class)
public void getContent_ParamVvalidation_4() {
getTested(true).getContent("testtype", "");
}
@Test(expected = BadFieldException.class)
public void getContent_ParamVvalidation_UnknownType() {
// case - type is unknown
getTested(true).getContent(TYPE_UNKNOWN, "12");
}
@Test(expected = Exception.class)
public void getContent_ParamVvalidation_TypeConfigInvalid() {
// case - type configuration is invalid (do not contains index name and type)
getTested(true).getContent(TYPE_INVALID, "12");
}
@Test
public void getContent() {
try {
ContentRestService tested = getTested(true);
// case - type is valid, but nothing is found for passed id because index is missing
indexDelete(INDEX_NAME);
assertResponseStatus(tested.getContent(TYPE_KNOWN, "12"), Response.Status.NOT_FOUND);
// case - index is present bud document is not found
indexCreate(INDEX_NAME);
indexInsertDocument(INDEX_NAME, INDEX_TYPE, "known-1", "{\"name\":\"test\"}");
assertResponseStatus(tested.getContent(TYPE_KNOWN, "2"), Response.Status.NOT_FOUND);
// case - document found
@SuppressWarnings("unchecked")
Map<String, Object> ret = (Map<String, Object>) tested.getContent(TYPE_KNOWN, "1");
assertEquals("test", ret.get("name"));
} finally {
indexDelete(INDEX_NAME);
finalizeESClientForUnitTest();
}
}
/**
* Prepare tested instance with injected mocks.
*
* @param initEsClient - searchClientService is initialized from
* {@link ESRealClientTestBase#prepareSearchClientServiceMock(String clusterName)} if this is true, so do not forget to clean
* up client in finally!
* @return instance for test
*/
@SuppressWarnings("unchecked")
protected ContentRestService getTested(boolean initEsClient) {
ContentRestService tested = new ContentRestService();
if (initEsClient)
tested.searchClientService = prepareSearchClientServiceMock("ContentRestServiceTest");
tested.providerService = mock(ProviderService.class);
setupProviderServiceMock(tested.providerService);
tested.contentPersistenceService = mock(ContentPersistenceService.class);
tested.log = Logger.getLogger("testlogger");
tested.authenticationUtilService = mock(AuthenticationUtilService.class);
tested.contentManipulationLockService = Mockito.mock(ContentManipulationLockService.class);
tested.eventContentDeleted = mock(Event.class);
tested.eventContentStored = mock(Event.class);
tested.eventBeforeIndexed = mock(Event.class);
when(tested.authenticationUtilService.getAuthenticatedProvider())
.thenReturn(ProviderServiceTest.TEST_PROVIDER_NAME);
return tested;
}
private void setupProviderServiceMock(ProviderService providerServiceMock) {
Mockito.when(providerServiceMock.findContentType(TYPE_INVALID)).thenReturn(
ProviderServiceTest.createProviderContentTypeInfo(new HashMap<String, Object>()));
Mockito.when(providerServiceMock.findContentType(TYPE_UNKNOWN)).thenReturn(null);
Mockito.when(providerServiceMock.generateSysId(Mockito.anyString(), Mockito.anyString())).thenCallRealMethod();
Map<String, Object> typeDefKnown = new HashMap<String, Object>();
Map<String, Object> typeDefKnownIndex = new HashMap<String, Object>();
typeDefKnown.put(ProviderService.INDEX, typeDefKnownIndex);
typeDefKnownIndex.put("name", INDEX_NAME);
typeDefKnownIndex.put("type", INDEX_TYPE);
typeDefKnown.put("input_preprocessors", PREPROCESSORS);
typeDefKnown.put(ProviderService.SYS_TYPE, "my_sys_type");
typeDefKnown.put(ProviderService.SYS_CONTENT_CONTENT_TYPE, "text/plain");
Mockito.when(providerServiceMock.findContentType(TYPE_KNOWN)).thenReturn(
ProviderServiceTest.createProviderContentTypeInfo(typeDefKnown, TYPE_KNOWN));
Map<String, Object> typeDefPersist = new HashMap<String, Object>();
Map<String, Object> typeDefPersistIndex = new HashMap<String, Object>();
typeDefPersist.put(ProviderService.INDEX, typeDefPersistIndex);
typeDefPersistIndex.put("name", INDEX_NAME);
typeDefPersistIndex.put("type", INDEX_TYPE);
typeDefPersist.put(ProviderService.SYS_TYPE, "my_sys_type");
typeDefPersist.put(ProviderService.PERSIST, "true");
typeDefPersist.put(ProviderService.SYS_CONTENT_CONTENT_TYPE, "text/plain");
when(providerServiceMock.findContentType(TYPE_PERSIST)).thenReturn(
ProviderServiceTest.createProviderContentTypeInfo(typeDefPersist, TYPE_PERSIST));
Map<String, Object> typeDefSysContent = new HashMap<String, Object>();
Map<String, Object> typeDefSysContentIndex = new HashMap<String, Object>();
typeDefSysContent.put(ProviderService.INDEX, typeDefPersistIndex);
typeDefSysContentIndex.put("name", INDEX_NAME);
typeDefSysContentIndex.put("type", INDEX_TYPE);
typeDefSysContent.put(ProviderService.SYS_TYPE, "my_sys_type");
when(providerServiceMock.findContentType(TYPE_INVALID_CONTENT_TYPE)).thenReturn(
ProviderServiceTest.createProviderContentTypeInfo(typeDefSysContent, TYPE_INVALID_CONTENT_TYPE));
Map<String, Object> providerDef = new HashMap<String, Object>();
providerDef.put(ProviderService.NAME, ProviderServiceTest.TEST_PROVIDER_NAME);
when(providerServiceMock.findProvider(ProviderServiceTest.TEST_PROVIDER_NAME)).thenReturn(providerDef);
Map<String, Object> typesDef = new HashMap<String, Object>();
providerDef.put(ProviderService.TYPE, typesDef);
typesDef.put(TYPE_INVALID, new HashMap<String, Object>());
Map<String, Object> typeDefInvalid2 = new HashMap<String, Object>();
typeDefInvalid2.put(ProviderService.INDEX, typeDefKnownIndex);
typesDef.put("invalid_2", typeDefInvalid2);
typesDef.put(TYPE_KNOWN, typeDefKnown);
typesDef.put(TYPE_PERSIST, typeDefPersist);
typesDef.put(TYPE_INVALID_CONTENT_TYPE, typeDefSysContent);
}
}