package com.constellio.model.services.contents;
import static com.constellio.data.conf.HashingEncoding.BASE64_URL_ENCODED;
import static com.constellio.model.services.contents.ContentFactory.isCheckedOutBy;
import static com.constellio.model.services.migrations.ConstellioEIMConfigs.PARSED_CONTENT_MAX_LENGTH_IN_KILOOCTETS;
import static com.constellio.model.services.search.query.logical.LogicalSearchQueryOperators.from;
import static com.constellio.model.services.search.query.logical.LogicalSearchQueryOperators.fromAllSchemasIn;
import static com.constellio.sdk.tests.schemas.TestsSchemasSetup.whichIsSearchable;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import static org.assertj.core.api.Assertions.tuple;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.io.IOUtils;
import org.assertj.core.api.Condition;
import org.joda.time.LocalDateTime;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import com.constellio.data.dao.services.records.RecordDao;
import com.constellio.data.utils.LangUtils;
import com.constellio.model.conf.PropertiesModelLayerConfiguration.InMemoryModelLayerConfiguration;
import com.constellio.model.entities.CorePermissions;
import com.constellio.model.entities.Taxonomy;
import com.constellio.model.entities.records.Content;
import com.constellio.model.entities.records.ContentVersion;
import com.constellio.model.entities.records.ParsedContent;
import com.constellio.model.entities.records.Record;
import com.constellio.model.entities.records.wrappers.User;
import com.constellio.model.entities.records.wrappers.UserPermissionsChecker;
import com.constellio.model.entities.schemas.Schemas;
import com.constellio.model.entities.security.global.UserCredentialStatus;
import com.constellio.model.services.configs.SystemConfigurationsManager;
import com.constellio.model.services.contents.ContentImplRuntimeException.ContentImplRuntimeException_CannotDeleteLastVersion;
import com.constellio.model.services.contents.ContentImplRuntimeException.ContentImplRuntimeException_ContentMustBeCheckedOut;
import com.constellio.model.services.contents.ContentImplRuntimeException.ContentImplRuntimeException_ContentMustNotBeCheckedOut;
import com.constellio.model.services.contents.ContentImplRuntimeException.ContentImplRuntimeException_InvalidArgument;
import com.constellio.model.services.contents.ContentImplRuntimeException.ContentImplRuntimeException_UserHasNoDeleteVersionPermission;
import com.constellio.model.services.contents.ContentImplRuntimeException.ContentImplRuntimeException_VersionMustBeHigherThanPreviousVersion;
import com.constellio.model.services.contents.ContentManagerRuntimeException.ContentManagerRuntimeException_ContentHasNoPreview;
import com.constellio.model.services.contents.ContentManagerRuntimeException.ContentManagerRuntimeException_NoSuchContent;
import com.constellio.model.services.records.RecordServices;
import com.constellio.model.services.records.RecordServicesException;
import com.constellio.model.services.schemas.MetadataSchemaTypesAlteration;
import com.constellio.model.services.schemas.MetadataSchemasManager;
import com.constellio.model.services.schemas.builders.MetadataSchemaTypesBuilder;
import com.constellio.model.services.search.SearchServices;
import com.constellio.model.services.search.query.logical.LogicalSearchQuery;
import com.constellio.model.services.taxonomies.TaxonomiesManager;
import com.constellio.model.services.users.UserServices;
import com.constellio.sdk.tests.ConstellioTest;
import com.constellio.sdk.tests.ModelLayerConfigurationAlteration;
import com.constellio.sdk.tests.TestRecord;
import com.constellio.sdk.tests.schemas.TestsSchemasSetup;
import com.constellio.sdk.tests.schemas.TestsSchemasSetup.ZeSchemaMetadatas;
public class ContentManagementAcceptTest extends ConstellioTest {
private AtomicInteger threadCalls = new AtomicInteger();
private final String OCTET_STREAM_MIMETYPE = "application/octet-stream";
private final String PDF_MIMETYPE = "application/pdf";
private final String DOCX_MIMETYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
LocalDateTime smashOClock = new LocalDateTime();
LocalDateTime shishOClock = new LocalDateTime().plusHours(1);
LocalDateTime teaOClock = new LocalDateTime().plusHours(2);
ContentManager contentManager;
RecordServices recordServices;
TestsSchemasSetup schemas = new TestsSchemasSetup(zeCollection);
TestsSchemasSetup anotherCollectionSchemas = new TestsSchemasSetup("anotherCollection");
ZeSchemaMetadatas zeSchema = schemas.new ZeSchemaMetadatas();
ZeSchemaMetadatas anotherCollectionSchema = anotherCollectionSchemas.new ZeSchemaMetadatas();
User bob, bobInAnotherCollection;
User alice;
String bobId;
String aliceId;
private long pdf1Length = 170039L;
private long pdf2Length = 167347L;
private long pdf3Length = 141667L;
private long docx1Length = 27055L;
private long docx2Length = 27325L;
private String pdf1Hash = "KN8RjbrnBgq1EDDV2U71a6_6gd4=";
private String pdf2Hash = "T-4zq4cGP_tXkdJp_qz1WVWYhoQ=";
private String pdf3Hash = "2O9RyZlxNUL3asxk2yGDT6VIlbs=";
private String docx1Hash = "Fss7pKBafi8ok5KaOwEpmNdeGCE=";
private String docx2Hash = "TIKwSvHOXHOOtRd1K9t2fm4TQ4I=";
@Mock UserPermissionsChecker userPermissionsChecker;
@Before
public void setUp()
throws Exception {
givenHashingEncodingIs(BASE64_URL_ENCODED);
withSpiedServices(ContentManager.class);
configure(new ModelLayerConfigurationAlteration() {
@Override
public void alter(InMemoryModelLayerConfiguration configuration) {
configuration.setDelayBeforeDeletingUnreferencedContents(org.joda.time.Duration.standardMinutes(42));
configuration.setUnreferencedContentsThreadDelayBetweenChecks(org.joda.time.Duration.standardHours(10));
}
});
customSystemPreparation(new CustomSystemPreparation() {
@Override
public void prepare() {
try {
defineSchemasManager()
.using(schemas.withAContentMetadata(whichIsSearchable).withAContentListMetadata()
.withAParentReferenceFromZeSchemaToZeSchema());
defineSchemasManager().using(anotherCollectionSchemas.withAContentMetadata());
recordServices = getModelLayerFactory().newRecordServices();
contentManager = getModelLayerFactory().getContentManager();
MetadataSchemasManager metadataSchemasManager = getModelLayerFactory().getMetadataSchemasManager();
TaxonomiesManager taxonomiesManager = getModelLayerFactory().getTaxonomiesManager();
Taxonomy taxonomy = Taxonomy.createPublic("taxo", "taxo", zeCollection, asList("zeSchemaType"));
taxonomiesManager.addTaxonomy(taxonomy, metadataSchemasManager);
taxonomiesManager.setPrincipalTaxonomy(taxonomy, metadataSchemasManager);
UserServices userServices = getModelLayerFactory().newUserServices();
userServices.addUpdateUserCredential(userServices.createUserCredential(
"bob", "bob", "gratton", "bob@doculibre.com", new ArrayList<String>(),
asList(zeCollection, "anotherCollection"), UserCredentialStatus.ACTIVE, "domain", Arrays.asList(""),
null));
userServices.addUpdateUserCredential(userServices.createUserCredential(
"alice", "alice", "wonderland", "alice@doculibre.com", new ArrayList<String>(),
asList(zeCollection), UserCredentialStatus.ACTIVE, "domain", Arrays.asList(""), null));
bob = spy(userServices.getUserInCollection("bob", zeCollection));
bob.setCollectionDeleteAccess(true);
recordServices.update(bob.getWrappedRecord());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void initializeFromCache() {
recordServices = getModelLayerFactory().newRecordServices();
contentManager = getModelLayerFactory().getContentManager();
schemas.refresh(getModelLayerFactory().getMetadataSchemasManager());
anotherCollectionSchemas.refresh(getModelLayerFactory().getMetadataSchemasManager());
}
});
givenTimeIs(smashOClock);
alice = getModelLayerFactory().newUserServices().getUserInCollection("alice", zeCollection);
bob = spy(getModelLayerFactory().newUserServices().getUserInCollection("bob", zeCollection));
bobInAnotherCollection = getModelLayerFactory().newUserServices().getUserInCollection("bob", "anotherCollection");
aliceId = alice.getId();
bobId = bob.getId();
Mockito.doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation)
throws Throwable {
Object value = invocation.callRealMethod();
threadCalls.incrementAndGet();
return value;
}
}).when(contentManager).deleteUnreferencedContents();
}
@Test
public void whenAddingContentToSinglevalueContentMetadataThenContentRetreivable()
throws Exception {
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
assertThat(theRecordContent()).isNot(emptyVersion);
assertThat(theRecordContent().getCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf1HashAndLength())
.is(version("0.1")).is(modifiedBy(bob)).has(modificationDatetime(smashOClock));
assertThatVaultOnlyContains(pdf1Hash);
}
@Test
public void whenAddingMinorEmptyContentThenContentRetreivable()
throws Exception {
givenRecord().withSingleValueContent(contentManager.createEmptyMinor(bob, "ZePdf.pdf", uploadPdf1InputStream()))
.isSaved();
assertThat(theRecordContent()).is(emptyVersion);
assertThat(theRecordContent().getCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf1HashAndLength())
.is(version("0.1")).is(modifiedBy(bob)).has(modificationDatetime(smashOClock));
assertThatVaultOnlyContains(pdf1Hash);
}
@Test
public void whenSearchingByBorrowedContentThenFindDocuments()
throws Exception {
Content minorContentAddedByBob = contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream()).checkOut(bob);
Content contentAddedByAliceThenBorrowedByBob = contentManager.createMinor(alice, "ZePdf.pdf", uploadPdf1InputStream())
.checkOut(bob);
Content returnedContent = contentManager.createMajor(alice, "ZePdf.pdf", uploadPdf1InputStream());
Content minorContentAddedByAlice = contentManager.createMinor(alice, "ZePdf.pdf", uploadPdf1InputStream())
.checkOut(alice);
Content minorContentAddedByBobThenBorrowedByAlice = contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())
.checkOut(bob).checkIn().checkOut(alice);
givenRecordWithId("bobDoc1").withSingleValueContent(minorContentAddedByBob).isSaved();
givenRecordWithId("bobDoc2").withSingleValueContent(contentAddedByAliceThenBorrowedByBob).isSaved();
givenRecordWithId("aliceDoc1").withSingleValueContent(minorContentAddedByAlice).isSaved();
givenRecordWithId("aliceDoc2").withSingleValueContent(minorContentAddedByAlice).isSaved();
givenRecordWithId("notBorrowedDoc").withSingleValueContent(returnedContent).isSaved();
SearchServices searchServices = getModelLayerFactory().newSearchServices();
LogicalSearchQuery bobBorrowerdDocumentsQuery = new LogicalSearchQuery()
.setCondition(from(zeSchema.instance()).where(zeSchema.contentMetadata()).is(isCheckedOutBy(bob)));
LogicalSearchQuery aliceBorrowerdDocumentsQuery = new LogicalSearchQuery()
.setCondition(from(zeSchema.instance()).where(zeSchema.contentMetadata()).is(isCheckedOutBy(alice)));
assertThat(searchServices.searchRecordIds(bobBorrowerdDocumentsQuery)).containsOnly("bobDoc1", "bobDoc2");
assertThat(searchServices.searchRecordIds(aliceBorrowerdDocumentsQuery)).containsOnly("aliceDoc1", "aliceDoc2");
}
@Test
public void whenReplacingSingleValueContentThenNewContentRetreivableAndPreviousDeleted()
throws Exception {
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
when(theRecord()).withSingleValueContent(contentManager.createMinor(bob, "ZeDocx.docx", uploadDocx1InputStream()))
.isSaved();
assertThat(theRecordContent().getCurrentVersion()).has(docsMimetype()).has(filename("ZeDocx.docx")).has(
docx1HashAndLength())
.has(version("0.1")).has(modifiedBy(bob)).has(modificationDatetime(smashOClock));
assertThatVaultOnlyContains(docx1Hash);
}
@Test
public void whenAddingContentToMultivalueContentMetadataThenNewContentRetreivable()
throws Exception {
givenRecord().addMultiValueContent(contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
assertThat(theRecordFirstMultivalueContent().getCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf"))
.has(pdf1HashAndLength()).has(version("0.1")).has(modifiedBy(bob)).has(modificationDatetime(smashOClock));
assertThatVaultOnlyContains(pdf1Hash);
}
@Test
public void whenAddingAContentWithMultipleVersionsWithDifferentNamesThenNamesCorrectlySaved()
throws Exception {
Content content = contentManager.createMinor(alice, "ZePdf1.pdf", uploadPdf1InputStream());
content.updateContentWithName(bob, uploadPdf2InputStream(), true, "ZePdf2.pdf");
content.updateContentWithName(alice, uploadPdf3InputStream(), false, "ZePdf3.pdf");
content.updateContentWithName(alice, uploadDocx1InputStream(), false, "ZeDocx1.docx");
content.updateContentWithName(bob, uploadDocx2InputStream(), true, "ZeDocx2.docx");
givenRecord().withSingleValueContent(content).isSaved();
assertThat(theRecordContent().getVersions()).extracting("version", "filename", "lastModifiedBy").isEqualTo(asList(
tuple("0.1", "ZePdf1.pdf", aliceId),
tuple("1.0", "ZePdf2.pdf", bobId),
tuple("1.1", "ZePdf3.pdf", aliceId),
tuple("1.2", "ZeDocx1.docx", aliceId),
tuple("2.0", "ZeDocx2.docx", bobId)
));
}
@Test
public void whenAddingAContentThenUpdateNameWithMultipleVersionsWithDifferentNamesThenNamesCorrectlySaved()
throws Exception {
Content content = contentManager.createMinor(alice, "ZePdf1.pdf", uploadPdf1InputStream());
content.updateContent(bob, uploadPdf2InputStream(), true);
content.renameCurrentVersion("ZePdf2.pdf");
content.updateContentWithName(alice, uploadPdf3InputStream(), false, "test.txt");
content.renameCurrentVersion("ZePdf3.pdf");
content.updateContent(alice, uploadDocx1InputStream(), false);
content.renameCurrentVersion("ZeDocx1.docx");
content.updateContentWithName(bob, uploadDocx2InputStream(), true, "test.txt");
content.renameCurrentVersion("ZeDocx2.docx");
givenRecord().withSingleValueContent(content).isSaved();
assertThat(theRecordContent().getVersions()).extracting("version", "filename", "lastModifiedBy").isEqualTo(asList(
tuple("0.1", "ZePdf1.pdf", aliceId),
tuple("1.0", "ZePdf2.pdf", bobId),
tuple("1.1", "ZePdf3.pdf", aliceId),
tuple("1.2", "ZeDocx1.docx", aliceId),
tuple("2.0", "ZeDocx2.docx", bobId)
));
}
@Test
public void whenAddingContentWithoutParsingHistoryVersionsThenMimetypeCorrectlySet()
throws Exception {
Content content = contentManager.createMinor(alice, "ZePdf.pdf", uploadPdf1InputStreamWithoutParsing());
content.updateContent(bob, uploadPdf2InputStreamWithoutParsing(), true);
content.updateContent(alice, uploadPdf3InputStreamWithoutParsing(), false);
content.updateContentWithName(alice, uploadDocx1InputStreamWithoutParsing(), false, "ZeDocx.docx");
content.updateContent(bob, uploadDocx2InputStreamWithoutParsing(), true);
givenRecord().withSingleValueContent(content).isSaved();
assertThat(theRecordContent().getVersions())
.extracting("version", "filename", "lastModifiedBy", "mimetype", "hash", "length").isEqualTo(asList(
tuple("0.1", "ZePdf.pdf", aliceId, PDF_MIMETYPE, pdf1Hash, pdf1Length),
tuple("1.0", "ZePdf.pdf", bobId, PDF_MIMETYPE, pdf2Hash, pdf2Length),
tuple("1.1", "ZePdf.pdf", aliceId, PDF_MIMETYPE, pdf3Hash, pdf3Length),
tuple("1.2", "ZeDocx.docx", aliceId, DOCX_MIMETYPE, docx1Hash, docx1Length),
tuple("2.0", "ZeDocx.docx", bobId, DOCX_MIMETYPE, docx2Hash, docx2Length)
));
assertThat(contentManager.isParsed(pdf1Hash)).isFalse();
assertThat(contentManager.isParsed(pdf2Hash)).isFalse();
assertThat(contentManager.isParsed(pdf3Hash)).isFalse();
assertThat(contentManager.isParsed(docx1Hash)).isFalse();
assertThat(contentManager.isParsed(docx2Hash)).isTrue();
}
@Test
public void givenHistoryVersionsAreNotParsedWhenRemovingCurrentVersionThenParseLastHistoryVersion()
throws Exception {
doReturn(true).when(userPermissionsChecker).globally();
doReturn(userPermissionsChecker).when(bob).has(CorePermissions.DELETE_CONTENT_VERSION);
Content content = contentManager.createMinor(alice, "ZePdf.pdf", uploadPdf1InputStreamWithoutParsing());
content.updateContent(bob, uploadPdf2InputStreamWithoutParsing(), true);
content.updateContent(alice, uploadPdf3InputStreamWithoutParsing(), false);
content.updateContentWithName(alice, uploadDocx1InputStreamWithoutParsing(), false, "ZeDocx.docx");
content.updateContent(bob, uploadDocx2InputStreamWithoutParsing(), true);
givenRecord().withSingleValueContent(content).isSaved();
when(theRecord()).deleteVersion("2.0", bob).and().isSaved();
assertThat(theRecordContent().getVersions())
.extracting("version", "filename", "lastModifiedBy", "mimetype", "hash", "length").isEqualTo(asList(
tuple("0.1", "ZePdf.pdf", aliceId, PDF_MIMETYPE, pdf1Hash, pdf1Length),
tuple("1.0", "ZePdf.pdf", bobId, PDF_MIMETYPE, pdf2Hash, pdf2Length),
tuple("1.1", "ZePdf.pdf", aliceId, PDF_MIMETYPE, pdf3Hash, pdf3Length),
tuple("1.2", "ZeDocx.docx", aliceId, DOCX_MIMETYPE, docx1Hash, docx1Length)
));
assertThat(contentManager.isParsed(pdf1Hash)).isFalse();
assertThat(contentManager.isParsed(pdf2Hash)).isFalse();
assertThat(contentManager.isParsed(pdf3Hash)).isFalse();
assertThat(contentManager.isParsed(docx1Hash)).isTrue();
}
@Test
public void givenHistoryVersionsAreNotParsedWhenAddingAPreviousVersionHasANewVersionThenParsed()
throws Exception {
Content content = contentManager.createMinor(alice, "ZePdf.pdf", uploadPdf1InputStreamWithoutParsing());
content.updateContent(bob, uploadPdf2InputStreamWithoutParsing(), true);
content.updateContent(alice, uploadPdf3InputStream(), false);
content.updateContentWithName(alice, uploadDocx1InputStreamWithoutParsing(), false, "ZeDocx.docx");
content.updateContent(bob, uploadDocx2InputStream(), true);
givenRecord().withSingleValueContent(content).isSaved();
when(theRecord()).hasItsContentUpdated(alice, uploadPdf1InputStream()).and().isSaved();
assertThat(theRecordContent().getVersions())
.extracting("version", "filename", "lastModifiedBy", "mimetype", "hash", "length").isEqualTo(asList(
tuple("0.1", "ZePdf.pdf", aliceId, PDF_MIMETYPE, pdf1Hash, pdf1Length),
tuple("1.0", "ZePdf.pdf", bobId, PDF_MIMETYPE, pdf2Hash, pdf2Length),
tuple("1.1", "ZePdf.pdf", aliceId, PDF_MIMETYPE, pdf3Hash, pdf3Length),
tuple("1.2", "ZeDocx.docx", aliceId, DOCX_MIMETYPE, docx1Hash, docx1Length),
tuple("2.0", "ZeDocx.docx", bobId, DOCX_MIMETYPE, docx2Hash, docx2Length),
tuple("2.1", "ZeDocx.docx", aliceId, PDF_MIMETYPE, pdf1Hash, pdf1Length)
));
assertThat(contentManager.isParsed(pdf1Hash)).isTrue();
assertThat(contentManager.isParsed(pdf2Hash)).isFalse();
assertThat(contentManager.isParsed(pdf3Hash)).isTrue();
assertThat(contentManager.isParsed(docx1Hash)).isFalse();
assertThat(contentManager.isParsed(docx2Hash)).isTrue();
}
@Test
public void whenAddingAContentThenUpdateNameAndCommentWithMultipleVersionsWithDifferentNamesThenNamesCorrectlySaved()
throws Exception {
Content content = contentManager.createMinor(alice, "zetest.pdf", uploadPdf1InputStream());
content.setVersionComment("version comment 1");
content.updateContent(bob, uploadPdf2InputStream(), true);
content.setVersionComment("version comment 2");
content.updateContent(alice, uploadPdf3InputStream(), false);
content.setVersionComment("version comment 3");
content.updateContentWithName(alice, uploadDocx1InputStream(), false, "zetest.docx");
content.setVersionComment("version comment 4");
content.updateContent(bob, uploadDocx2InputStream(), true);
content.setVersionComment("version comment 5");
givenRecord().withSingleValueContent(content).isSaved();
assertThat(theRecordContent().getVersions()).extracting("version", "filename", "lastModifiedBy", "comment")
.isEqualTo(asList(
tuple("0.1", "zetest.pdf", aliceId, "version comment 1"),
tuple("1.0", "zetest.pdf", bobId, "version comment 2"),
tuple("1.1", "zetest.pdf", aliceId, "version comment 3"),
tuple("1.2", "zetest.docx", aliceId, "version comment 4"),
tuple("2.0", "zetest.docx", bobId, "version comment 5")
));
}
@Test
public void givenEmptyCommentThenSavedAsAnEmptyComment()
throws Exception {
Content content = contentManager.createMinor(alice, "zetest.pdf", uploadPdf1InputStream());
content.setVersionComment("");
givenRecord().withSingleValueContent(content).isSaved();
assertThat(theRecordContent().getVersions()).extracting("version", "filename", "lastModifiedBy", "comment")
.isEqualTo(asList(
tuple("0.1", "zetest.pdf", aliceId, null)
));
when(theRecord()).hasItsContentCommentChangedTo("Ze comment").and().isSaved();
assertThat(theRecordContent().getVersions()).extracting("version", "filename", "lastModifiedBy", "comment")
.isEqualTo(asList(
tuple("0.1", "zetest.pdf", aliceId, "Ze comment")
));
}
@Test
public void whenModifyingContentOfMultivalueContentMetadataThenNewContentRetreivableAndOldRemoved()
throws Exception {
givenRecord().addMultiValueContent(contentManager.createMinor(alice, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
givenTimeIs(shishOClock);
given(theRecord()).clearAllMultiValueContents().addMultiValueContent(contentManager.createMinor(bob, "ZePdf2.pdf",
uploadPdf2InputStream())).addMultiValueContent(
contentManager.createMajor(bob, "ZeDocx.docx", uploadDocx1InputStream())).isSaved();
assertThat(theRecordFirstMultivalueContent().getCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf2.pdf"))
.has(pdf2HashAndLength()).has(version("0.1")).is(modifiedBy(bob)).has(modificationDatetime(shishOClock));
assertThat(theRecordSecondAndLastMultivalueContent().getCurrentVersion()).has(docsMimetype()).has(filename("ZeDocx.docx"))
.has(docx1HashAndLength()).has(version("1.0")).has(modifiedBy(bob)).has(modificationDatetime(shishOClock));
assertThatVaultOnlyContains(docx1Hash, pdf2Hash);
}
@Test
public void whenRenamingContentThenNameModified()
throws Exception {
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
when(theRecord()).hasItsContentRenamedTo("ZeUltimatePdf.pdf").and().isSaved();
assertThat(theRecordContent().getCurrentVersion()).has(pdfMimetype()).has(filename("ZeUltimatePdf.pdf")).has(
pdf1HashAndLength())
.has(version("0.1")).has(modifiedBy(bob)).has(modificationDatetime(smashOClock));
}
@Test
public void whenCommentingAVersionThenCommentModified()
throws Exception {
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
when(theRecord()).hasItsContentCommentChangedTo("comment 1").and().isSaved();
assertThat(theRecordContent().getCurrentVersion()).has(pdfMimetype()).has(comment("comment 1")).has(
pdf1HashAndLength()).has(version("0.1")).has(modifiedBy(bob)).has(modificationDatetime(smashOClock));
when(theRecord()).hasItsContentCommentChangedTo("comment 2").and().isSaved();
assertThat(theRecordContent().getCurrentVersion()).has(pdfMimetype()).has(comment("comment 2")).has(
pdf1HashAndLength()).has(version("0.1")).has(modifiedBy(bob)).has(modificationDatetime(smashOClock));
}
@Test
public void givenaACheckedOutContentWhenCommentingAVersionThenCommentModified()
throws Exception {
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream()))
.contentCheckedOutBy(alice).isSaved();
givenTimeIs(shishOClock);
when(theRecord()).hasItsCheckedOutContentUpdatedWith(uploadPdf2InputStream()).hasItsContentCommentChangedTo("comment 1")
.and().isSaved();
assertThat(theRecordContent().getCurrentVersion()).has(pdfMimetype()).has(
pdf1HashAndLength()).has(version("0.1")).has(modifiedBy(bob)).has(comment(null))
.has(modificationDatetime(smashOClock));
assertThat(theRecordContent().getCurrentCheckedOutVersion()).has(pdfMimetype()).has(comment("comment 1")).has(
pdf2HashAndLength()).has(version("0.2")).has(modifiedBy(alice)).has(modificationDatetime(shishOClock));
givenTimeIs(teaOClock);
when(theRecord()).hasItsContentCommentChangedTo("comment 2").and().isSaved();
assertThat(theRecordContent().getCurrentVersion()).has(pdfMimetype()).has(
pdf1HashAndLength()).has(version("0.1")).has(modifiedBy(bob)).has(comment(null))
.has(modificationDatetime(smashOClock));
assertThat(theRecordContent().getCurrentCheckedOutVersion()).has(pdfMimetype()).has(comment("comment 2")).has(
pdf2HashAndLength()).has(version("0.2")).has(modifiedBy(alice)).has(modificationDatetime(shishOClock));
}
@Test
public void whenModifyingContentThenContentHashModifiedAndVersionIncremented()
throws Exception {
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
assertThat(theRecordContent().getCurrentVersion()).is(modifiedBy(bob)).has(modificationDatetime(smashOClock));
givenTimeIs(shishOClock);
when(theRecord()).hasItsContentUpdated(alice, uploadPdf2InputStream()).and().isSaved();
assertThat(theRecordContent().getCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf2HashAndLength())
.has(
version("0.2")).has(modifiedBy(alice)).has(modificationDatetime(shishOClock));
assertThat(theRecordContent()).is(notCheckedOut());
assertThatVaultOnlyContains(pdf1Hash, pdf2Hash);
}
@Test
public void whenModifyingContentMultipleTimesThenContentHashModifiedAndVersionIncrementedEachTime()
throws Exception {
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
assertThat(theRecordContent().getCurrentVersion()).is(modifiedBy(bob)).has(modificationDatetime(smashOClock));
givenTimeIs(shishOClock);
when(theRecord()).hasItsContentUpdated(alice, uploadPdf2InputStream()).and().isSaved();
givenTimeIs(teaOClock);
when(theRecord()).hasItsContentUpdated(bob, uploadPdf3InputStream()).and().isSaved();
assertThat(theRecordContent().getCurrentVersion()).has(pdf3HashAndLength()).has(version("0.3")).has(modifiedBy(bob))
.has(modificationDatetime(teaOClock));
assertThat(theRecordContentHistory()).hasSize(2);
assertThat(theRecordContentHistory().get(0)).has(pdf1HashAndLength()).has(version("0.1")).has(modifiedBy(bob))
.has(modificationDatetime(smashOClock));
assertThat(theRecordContentHistory().get(1)).has(pdf2HashAndLength()).has(version("0.2")).has(modifiedBy(alice))
.has(modificationDatetime(shishOClock));
assertThatVaultOnlyContains(pdf1Hash, pdf2Hash, pdf3Hash);
}
@Test(expected = ContentImplRuntimeException_UserHasNoDeleteVersionPermission.class)
public void givenUserHasNoDeletePermissionThenExceptionWhenDeleteingVersion()
throws Exception {
doReturn(false).when(userPermissionsChecker).globally();
doReturn(userPermissionsChecker).when(bob).has(CorePermissions.DELETE_CONTENT_VERSION);
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
assertThat(theRecordContent().getCurrentVersion()).is(modifiedBy(bob)).has(modificationDatetime(smashOClock));
givenTimeIs(shishOClock);
when(theRecord()).hasItsContentUpdated(alice, uploadPdf2InputStream()).and().isSaved();
givenTimeIs(teaOClock);
when(theRecord()).hasItsContentUpdated(bob, uploadPdf3InputStream()).and().isSaved();
when(theRecord()).deleteVersion("0.1", bob);
}
@Test
public void whenDeletingTheOldestHistoryVersionThenDeleted()
throws Exception {
doReturn(true).when(userPermissionsChecker).globally();
doReturn(userPermissionsChecker).when(bob).has(CorePermissions.DELETE_CONTENT_VERSION);
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
assertThat(theRecordContent().getCurrentVersion()).is(modifiedBy(bob)).has(modificationDatetime(smashOClock));
givenTimeIs(shishOClock);
when(theRecord()).hasItsContentUpdated(alice, uploadPdf2InputStream()).and().isSaved();
givenTimeIs(teaOClock);
when(theRecord()).hasItsContentUpdated(bob, uploadPdf3InputStream()).and().isSaved();
when(theRecord()).deleteVersion("0.1", bob).isSaved();
assertThat(theRecordContent().getCurrentVersion()).has(pdf3HashAndLength()).has(version("0.3")).has(modifiedBy(bob))
.has(modificationDatetime(teaOClock));
assertThat(theRecordContentHistory()).hasSize(1);
assertThat(theRecordContentHistory().get(0)).has(pdf2HashAndLength()).has(version("0.2")).has(modifiedBy(alice))
.has(modificationDatetime(shishOClock));
assertThatVaultOnlyContains(pdf2Hash, pdf3Hash);
}
@Test
public void whenDeletingCurrentVersionThenPreviousVersionIsMovedFromHistoryToCurrentVersion()
throws Exception {
doReturn(true).when(userPermissionsChecker).globally();
doReturn(userPermissionsChecker).when(bob).has(CorePermissions.DELETE_CONTENT_VERSION);
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
assertThat(theRecordContent().getCurrentVersion()).is(modifiedBy(bob)).has(modificationDatetime(smashOClock));
givenTimeIs(shishOClock);
when(theRecord()).hasItsContentUpdated(alice, uploadPdf2InputStream()).and().isSaved();
givenTimeIs(teaOClock);
when(theRecord()).hasItsContentUpdated(bob, uploadPdf3InputStream()).and().isSaved();
when(theRecord()).deleteVersion("0.3", bob).isSaved();
assertThat(theRecordContent().getCurrentVersion()).has(pdf2HashAndLength()).has(version("0.2")).has(modifiedBy(alice))
.has(modificationDatetime(shishOClock));
assertThat(theRecordContentHistory()).hasSize(1);
assertThat(theRecordContentHistory().get(0)).has(pdf1HashAndLength()).has(version("0.1")).has(modifiedBy(bob))
.has(modificationDatetime(smashOClock));
assertThatVaultOnlyContains(pdf1Hash, pdf2Hash);
}
@Test(expected = ContentImplRuntimeException_CannotDeleteLastVersion.class)
public void whenDeletingTheOnlyVersionThenException()
throws Exception {
doReturn(true).when(userPermissionsChecker).globally();
doReturn(userPermissionsChecker).when(bob).has(CorePermissions.DELETE_CONTENT_VERSION);
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
assertThat(theRecordContent().getCurrentVersion()).is(modifiedBy(bob)).has(modificationDatetime(smashOClock));
when(theRecord()).deleteVersion("0.1", bob);
}
@Test
public void whenDeletingTheNewestHistoryVersionThenDeleted()
throws Exception {
doReturn(true).when(userPermissionsChecker).globally();
doReturn(userPermissionsChecker).when(bob).has(CorePermissions.DELETE_CONTENT_VERSION);
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
assertThat(theRecordContent().getCurrentVersion()).is(modifiedBy(bob)).has(modificationDatetime(smashOClock));
givenTimeIs(shishOClock);
when(theRecord()).hasItsContentUpdated(alice, uploadPdf2InputStream()).and().isSaved();
givenTimeIs(teaOClock);
when(theRecord()).hasItsContentUpdated(bob, uploadPdf3InputStream()).and().isSaved();
when(theRecord()).deleteVersion("0.2", bob).isSaved();
assertThat(theRecordContent().getCurrentVersion()).has(pdf3HashAndLength()).has(version("0.3")).has(modifiedBy(bob))
.has(modificationDatetime(teaOClock));
assertThat(theRecordContentHistory()).hasSize(1);
assertThat(theRecordContentHistory().get(0)).has(pdf1HashAndLength()).has(version("0.1")).has(modifiedBy(bob))
.has(modificationDatetime(smashOClock));
assertThatVaultOnlyContains(pdf1Hash, pdf3Hash);
}
@Test
public void givenContentNonCheckedOutWhenFinalizingThenVersionLabelOfLastVersionModified()
throws Exception {
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
assertThat(theRecordContent().getCurrentVersion()).is(modifiedBy(bob)).has(modificationDatetime(smashOClock));
givenTimeIs(shishOClock);
when(theRecord()).hasItsContentUpdated(alice, uploadPdf2InputStream()).and().isSaved();
givenTimeIs(teaOClock);
when(theRecord()).hasItsContentUpdated(bob, uploadPdf3InputStream()).and().isSaved();
when(theRecord()).hasItsContentFinalized().and().isSaved();
assertThat(theRecordContent().getCurrentVersion()).has(pdf3HashAndLength()).has(version("1.0")).has(modifiedBy(bob))
.has(modificationDatetime(teaOClock));
assertThat(theRecordContentHistory()).hasSize(2);
assertThat(theRecordContentHistory().get(0)).has(pdf1HashAndLength()).has(version("0.1")).has(modifiedBy(bob))
.has(modificationDatetime(smashOClock));
assertThat(theRecordContentHistory().get(1)).has(pdf2HashAndLength()).has(version("0.2")).has(modifiedBy(alice))
.has(modificationDatetime(shishOClock));
assertThatVaultOnlyContains(pdf1Hash, pdf2Hash, pdf3Hash);
}
@Test
public void givenFileNameAndDocumentTypeModifiedMultipleTimes()
throws Exception {
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "1.pdf", uploadPdf1InputStream())).isSaved();
givenTimeIs(shishOClock);
when(theRecord()).hasItsContentUpdatedWithName(alice, uploadDocx1InputStream(), "2.docx").and().isSaved();
givenTimeIs(teaOClock);
when(theRecord()).hasItsContentUpdatedWithName(alice, uploadPdf2InputStream(), "3.pdf").and().isSaved();
Content c = theRecordContent();
c.getHistoryVersions();
assertThat(c.getCurrentVersion()).has(pdf2HashAndLength()).has(filename("3.pdf")).has(pdfMimetype());
assertThat(theRecordContentHistory()).hasSize(2);
assertThat(theRecordContentHistory().get(0)).has(pdf1HashAndLength()).has(filename("1.pdf")).has(pdfMimetype());
assertThat(theRecordContentHistory().get(1)).has(docx1HashAndLength()).has(filename("2.docx")).has(docsMimetype());
assertThatVaultOnlyContains(pdf1Hash, docx1Hash, pdf2Hash);
}
@Test
public void givenAContentIsReplacedWithAVersionConcentThenAllVersionsAreDeletedExceptTheGivenVersion()
throws Exception {
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "1.pdf", uploadPdf1InputStream())).isSaved();
givenTimeIs(shishOClock);
when(theRecord()).hasItsContentRenamedTo("2.docx").hasItsContentUpdated(alice, uploadDocx1InputStream()).and().isSaved();
givenTimeIs(teaOClock);
when(theRecord()).hasItsContentRenamedTo("3.pdf").hasItsContentUpdated(alice, uploadPdf2InputStream()).and().isSaved();
when(theRecord()).withSingleValueContent(contentManager.createMinor(bob, "ze.pdf", uploadPdf2InputStream())).isSaved();
assertThatVaultOnlyContains(pdf2Hash);
}
@Test
public void givenAContentIsDeletedThenAllVersionsDeletedExceptThoseInOtherRecords()
throws Exception {
givenAnotherRecord().withSingleValueContent(contentManager.createMinor(bob, "1.pdf", uploadPdf2InputStream())).isSaved();
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "1.pdf", uploadPdf1InputStream())).isSaved();
givenTimeIs(shishOClock);
when(theRecord()).hasItsContentRenamedTo("2.pdf").hasItsContentUpdated(alice, uploadPdf2InputStream()).and().isSaved();
givenTimeIs(teaOClock);
when(theRecord()).hasItsContentRenamedTo("3.docx").hasItsContentUpdated(alice, uploadDocx1InputStream()).and().isSaved();
when(theRecord()).withSingleValueContent(null).isSaved();
assertThatVaultOnlyContains(pdf2Hash);
}
@Test
public void givenARecordIsLogicallyDeletedThenPhysicallyDeletedThenAllContentVersionsAreAvailableBeforePhysicalDelete()
throws Exception {
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "1.pdf", uploadPdf1InputStream())).isSaved();
givenTimeIs(shishOClock);
when(theRecord()).hasItsContentRenamedTo("2.pdf").hasItsContentUpdated(alice, uploadPdf2InputStream()).and().isSaved();
givenTimeIs(teaOClock);
when(theRecord()).hasItsContentRenamedTo("3.docx").hasItsContentUpdated(alice, uploadDocx1InputStream()).and().isSaved();
givenAnotherRecord().withSingleValueContent(contentManager.createMinor(bob, "2.docx", uploadDocx2InputStream()))
.withParent(theRecord()).isSaved();
recordServices.logicallyDelete(theRecord(), bob);
assertThatVaultOnlyContains(pdf1Hash, pdf2Hash, docx1Hash, docx2Hash);
givenTimeIs(shishOClock);
recordServices.physicallyDelete(theRecord(), bob);
assertThatVaultOnlyContains();
}
@Test
public void whenModifyingContentAsFinalizedThenContentHashModifiedAndVersionFinalized()
throws Exception {
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
givenTimeIs(shishOClock);
when(theRecord()).hasItsContentRenamedTo("ZeDoc.docx").and().
hasItsContentUpdatedAndFinalized(alice, uploadDocx1InputStream()).and().isSaved();
assertThat(theRecordContent().getCurrentVersion()).has(docsMimetype()).has(filename("ZeDoc.docx")).has(
docx1HashAndLength()).has(
version("1.0")).has(modifiedBy(alice)).has(modificationDatetime(shishOClock));
assertThat(theRecordContent()).is(notCheckedOut());
assertThatVaultOnlyContains(docx1Hash, pdf1Hash);
}
@Test
public void whenCheckoutContentThenUserIsCheckoutUser()
throws RecordServicesException {
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
givenTimeIs(shishOClock);
when(theRecord()).contentCheckedOutBy(alice).and().isSaved();
assertThat(theRecordContent().getCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf1HashAndLength())
.has(version("0.1")).has(modifiedBy(bob)).has(modificationDatetime(smashOClock));
assertThat(theRecordContent()).is(checkedOutBy(alice, shishOClock));
}
@Test
public void givenCheckedOutContentWhenCheckinThenNothingHasChanged()
throws Exception {
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).and()
.contentCheckedOutBy(alice).isSaved();
givenTimeIs(shishOClock);
when(theRecord()).contentCheckedIn().and().isSaved();
assertThat(theRecordContent().getCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf1HashAndLength())
.has(
version("0.1")).has(modifiedBy(bob)).has(modificationDatetime(smashOClock));
assertThat(theRecordContent()).is(notCheckedOut());
assertThatVaultOnlyContains(pdf1Hash);
}
@Test
public void givenCheckedOutContentWhenCancelCheckinThenNothingHasChanged()
throws Exception {
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).and()
.contentCheckedOutBy(alice).isSaved();
givenTimeIs(shishOClock);
when(theRecord()).contentCheckedInCancelled().and().isSaved();
assertThat(theRecordContent().getCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf1HashAndLength())
.has(
version("0.1")).has(modifiedBy(bob)).has(modificationDatetime(smashOClock));
assertThat(theRecordContent()).is(notCheckedOut());
assertThatVaultOnlyContains(pdf1Hash);
}
@Test
public void givenMutlipleCollectionsWhenDeleteUnreferencedThenOnlyDeleteUnreferencedInBothCollections()
throws Exception {
givenTimeIs(shishOClock);
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
givenAnotherCollectionRecord()
.withSingleValueContent(contentManager.createMinor(bobInAnotherCollection, "ZePdf.pdf", uploadPdf2InputStream()))
.isSaved();
uploadPdf3InputStream();
assertThatVaultOnlyContains(pdf1Hash, pdf2Hash);
}
@Test
public void givenCheckedOutContentWhenCheckinInAsMinorVersionThenVersionIsNotFinalized()
throws Exception {
Record record = givenRecord().withSingleValueContent(
contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).contentCheckedOutBy(alice).isSaved();
givenTimeIs(shishOClock);
when(theRecord()).contentCheckedInAsMinor(uploadPdf2InputStream()).and().isSaved();
assertThat(theRecordContentCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf2HashAndLength())
.has(version("0.2")).has(modifiedBy(alice)).has(modificationDatetime(shishOClock));
assertThat(theRecordContentHistory()).hasSize(1);
assertThat(theRecordContentHistory().get(0)).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf1HashAndLength())
.has(version("0.1")).has(modifiedBy(bob)).has(modificationDatetime(smashOClock));
assertThat(theRecordContent()).is(notCheckedOut());
assertThatVaultOnlyContains(pdf1Hash, pdf2Hash);
}
@Test
public void givenMinorEmptyVersionCheckedOutContentWhenCheckinInAsMinorVersionThenVersionHas0_1Version()
throws Exception {
Record record = givenRecord().withSingleValueContent(
contentManager.createEmptyMinor(alice, "ZePdf.pdf", uploadPdf1InputStream())).contentCheckedOutBy(alice)
.isSaved();
givenTimeIs(shishOClock);
when(theRecord()).contentCheckedInAsMinor(uploadPdf2InputStream()).and().isSaved();
assertThat(theRecordContentCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf2HashAndLength())
.has(version("0.1")).has(modifiedBy(alice)).has(modificationDatetime(shishOClock));
assertThat(theRecordContentHistory()).isEmpty();
assertThat(theRecordContent()).is(notCheckedOut());
assertThat(theRecordContent()).isNot(emptyVersion);
assertThatVaultOnlyContains(pdf2Hash);
}
@Test
public void givenMinorEmptyVersionCheckedOutContentWhenUpdatingTwiceThenCheckinInAsMinorVersionThenVersionHas0_1Version()
throws Exception {
Record record = givenRecord().withSingleValueContent(
contentManager.createEmptyMinor(alice, "ZePdf.pdf", uploadPdf1InputStream())).contentCheckedOutBy(alice)
.isSaved();
givenTimeIs(shishOClock);
when(theRecord()).hasItsCheckedOutContentUpdatedWith(uploadPdf2InputStream()).and().isSaved();
assertThat(theRecordContentHistory()).isEmpty();
assertThat(theRecordContent()).is(checkedOutBy(alice, smashOClock));
assertThat(theRecordContent()).is(emptyVersion);
givenTimeIs(teaOClock);
when(theRecord()).hasItsCheckedOutContentUpdatedWith(uploadPdf3InputStream()).and().isSaved();
assertThat(theRecordContentHistory()).isEmpty();
assertThat(theRecordContent()).is(checkedOutBy(alice, smashOClock));
assertThat(theRecordContent()).is(emptyVersion);
givenTimeIs(teaOClock.plusDays(1));
when(theRecord()).contentCheckedIn().and().isSaved();
assertThat(theRecordContentCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf3HashAndLength())
.has(version("0.1")).has(modifiedBy(alice)).has(modificationDatetime(teaOClock));
assertThat(theRecordContentHistory()).isEmpty();
assertThat(theRecordContent()).is(notCheckedOut());
assertThat(theRecordContent()).isNot(emptyVersion);
assertThatVaultOnlyContains(pdf3Hash);
}
@Test
public void givenMinorEmptyContentWhenUpdatingThen0_1Version()
throws Exception {
Record record = givenRecord().withSingleValueContent(
contentManager.createEmptyMinor(alice, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
givenTimeIs(shishOClock);
when(theRecord()).hasItsContentUpdated(bob, uploadPdf2InputStream()).and().isSaved();
assertThat(theRecordContentCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf2HashAndLength())
.has(version("0.1")).has(modifiedBy(bob)).has(modificationDatetime(shishOClock));
assertThat(theRecordContentHistory()).isEmpty();
assertThat(theRecordContent()).is(notCheckedOut());
assertThat(theRecordContent()).isNot(emptyVersion);
}
@Test
public void givenMinorEmptyVersionCheckedOutContentWhenCheckinInAsMajorVersionThenVersionHas1_0Version()
throws Exception {
Record record = givenRecord().withSingleValueContent(
contentManager.createEmptyMinor(alice, "ZePdf.pdf", uploadPdf1InputStream())).contentCheckedOutBy(alice)
.isSaved();
givenTimeIs(shishOClock);
when(theRecord()).contentCheckedInAsMajor(uploadPdf2InputStream()).and().isSaved();
assertThat(theRecordContentCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf2HashAndLength())
.has(version("1.0")).has(modifiedBy(alice)).has(modificationDatetime(shishOClock));
assertThat(theRecordContentHistory()).isEmpty();
assertThat(theRecordContent()).is(notCheckedOut());
assertThat(theRecordContent()).isNot(emptyVersion);
assertThatVaultOnlyContains(pdf2Hash);
}
@Test
public void givenMinorEmptyVersionCheckedOutContentWhenSavingModifiedVersionVersionThenHas0_1Version()
throws Exception {
Record record = givenRecord().withSingleValueContent(
contentManager.createEmptyMinor(alice, "ZePdf.pdf", uploadPdf1InputStream())).contentCheckedOutBy(alice)
.isSaved();
givenTimeIs(shishOClock);
when(theRecord()).hasItsCheckedOutContentUpdatedWith(uploadPdf2InputStream()).and().isSaved();
assertThat(theRecordContentCurrentCheckedOutVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf"))
.has(pdf2HashAndLength()).has(version("0.1")).has(modifiedBy(alice)).has(modificationDatetime(shishOClock));
assertThat(theRecordContentHistory()).isEmpty();
assertThat(theRecordContent()).is(checkedOutBy(alice, smashOClock));
assertThat(theRecordContent()).is(emptyVersion);
assertThatVaultOnlyContains(pdf1Hash, pdf2Hash);
}
@Test
public void givenCheckedOutContentWhenCheckinInAsMajorVersionThenVersionIsFinalized()
throws Exception {
Record record = givenRecord().withSingleValueContent(
contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).contentCheckedOutBy(alice).isSaved();
givenTimeIs(shishOClock);
when(theRecord()).contentCheckedInAsMajor(uploadPdf2InputStream()).and().isSaved();
assertThat(theRecordContentCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf2HashAndLength())
.has(version("1.0")).has(modifiedBy(alice)).has(modificationDatetime(shishOClock));
assertThat(theRecordContentHistory()).hasSize(1);
assertThat(theRecordContentHistory().get(0)).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf1HashAndLength())
.has(version("0.1")).has(modifiedBy(bob)).has(modificationDatetime(smashOClock));
assertThat(theRecordContent()).is(notCheckedOut());
assertThatVaultOnlyContains(pdf1Hash, pdf2Hash);
}
@Test
public void givenCheckedOutContentWhenUpdatingContentThenVersionIsIncrementedAndStillCheckedOut()
throws Exception {
givenTimeIs(teaOClock);
Record record = givenRecord().withSingleValueContent(
contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).contentCheckedOutBy(alice).isSaved();
givenTimeIs(shishOClock);
when(theRecord()).hasItsCheckedOutContentUpdatedWith(uploadPdf2InputStream()).and().isSaved();
assertThat(theRecordContentCurrentCheckedOutVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(
pdf2HashAndLength())
.has(version("0.2")).has(modifiedBy(alice)).has(modificationDatetime(shishOClock));
assertThat(theRecordContentCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf1HashAndLength())
.has(version("0.1")).has(modifiedBy(bob)).has(modificationDatetime(teaOClock));
assertThat(theRecordContent()).is(checkedOutBy(alice, teaOClock));
assertThatVaultOnlyContains(pdf1Hash, pdf2Hash);
assertThat(theRecordContentHistory()).isEmpty();
}
@Test
public void givenCheckedOutContentWhenUpdatingContentMultipleTimeThenVersionIsIncrementedOnlyOnceAndOnlyLastConcentIsConserved()
throws Exception {
Record record = givenRecord().withSingleValueContent(
contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).contentCheckedOutBy(alice).isSaved();
givenTimeIs(shishOClock);
when(theRecord()).hasItsCheckedOutContentUpdatedWith(uploadPdf2InputStream()).and().isSaved();
assertThat(theRecordContentCurrentCheckedOutVersion()).has(pdf2HashAndLength()).has(version("0.2"))
.has(modificationDatetime(shishOClock));
givenTimeIs(teaOClock);
when(theRecord()).hasItsCheckedOutContentUpdatedWith(uploadPdf3InputStream()).and().isSaved();
assertThat(theRecordContentCurrentCheckedOutVersion()).has(pdf3HashAndLength()).has(version("0.2"))
.has(modificationDatetime(teaOClock));
assertThat(theRecordContentHistory()).isEmpty();
assertThat(theRecordContentCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf1HashAndLength())
.has(version("0.1")).has(modifiedBy(bob)).has(modificationDatetime(smashOClock));
assertThat(theRecordContent()).is(checkedOutBy(alice, smashOClock));
assertThatVaultOnlyContains(pdf1Hash, pdf3Hash);
}
@Test
public void givenCheckedOutContentWhenUpdatingContentAndCheckinThenUpdatedContentAndMinorVersion()
throws Exception {
Record record = givenRecord().withSingleValueContent(
contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).contentCheckedOutBy(alice).isSaved();
givenTimeIs(shishOClock);
when(theRecord()).hasItsCheckedOutContentUpdatedWith(uploadPdf2InputStream()).and().isSaved();
when(theRecord()).contentCheckedIn().isSaved();
assertThat(theRecordContentCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf2HashAndLength())
.has(version("0.2")).has(modifiedBy(alice)).has(modificationDatetime(shishOClock));
assertThat(theRecordContentHistory()).hasSize(1);
assertThat(theRecordContentHistory().get(0)).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf1HashAndLength())
.has(version("0.1")).has(modifiedBy(bob)).has(modificationDatetime(smashOClock));
assertThat(theRecordContent()).is(notCheckedOut());
assertThatVaultOnlyContains(pdf1Hash, pdf2Hash);
}
@Test
public void givenCheckedOutContentWhenUpdatingContentAndCancelCheckinThenNothingChanged()
throws Exception {
Record record = givenRecord().withSingleValueContent(
contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).contentCheckedOutBy(alice).isSaved();
givenTimeIs(shishOClock);
when(theRecord()).hasItsCheckedOutContentUpdatedWith(uploadPdf2InputStream()).and().isSaved();
when(theRecord()).contentCheckedInCancelled().isSaved();
assertThat(theRecordContentCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf1HashAndLength())
.has(version("0.1")).has(modifiedBy(bob)).has(modificationDatetime(smashOClock));
assertThat(theRecordContentHistory()).isEmpty();
assertThat(theRecordContent()).is(notCheckedOut());
assertThatVaultOnlyContains(pdf1Hash);
}
@Test
public void givenCheckedOutContentWhenUpdatingContentAndFinalisingThenUpdatedContentAndMinorVersion()
throws Exception {
Record record = givenRecord().withSingleValueContent(
contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).contentCheckedOutBy(alice).isSaved();
givenTimeIs(shishOClock);
when(theRecord()).hasItsCheckedOutContentUpdatedWith(uploadPdf2InputStream()).and().isSaved();
when(theRecord()).finalizeVersion().isSaved();
assertThat(theRecordContentCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf2HashAndLength())
.has(version("1.0")).has(modifiedBy(alice)).has(modificationDatetime(shishOClock));
assertThat(theRecordContentHistory()).hasSize(1);
assertThat(theRecordContentHistory().get(0)).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf1HashAndLength())
.has(version("0.1")).has(modifiedBy(bob)).has(modificationDatetime(smashOClock));
assertThat(theRecordContent()).is(notCheckedOut());
assertThatVaultOnlyContains(pdf1Hash, pdf2Hash);
}
@Test
public void givenCheckedOutContentWhenUpdatingContentAndCheckinWithNewContentAsMajorThenMajorAndFirstUpdatedVersionDeleted()
throws Exception {
Record record = givenRecord().withSingleValueContent(
contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).contentCheckedOutBy(alice).isSaved();
givenTimeIs(shishOClock);
when(theRecord()).hasItsCheckedOutContentUpdatedWith(uploadPdf2InputStream()).and().isSaved();
when(theRecord()).contentCheckedInAsMajor(uploadPdf3InputStream()).isSaved();
assertThat(theRecordContentCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf3HashAndLength())
.has(version("1.0")).has(modifiedBy(alice)).has(modificationDatetime(shishOClock));
assertThat(theRecordContentHistory()).hasSize(1);
assertThat(theRecordContentHistory().get(0)).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf1HashAndLength())
.has(version("0.1")).has(modifiedBy(bob)).has(modificationDatetime(smashOClock));
assertThat(theRecordContent()).is(notCheckedOut());
assertThatVaultOnlyContains(pdf1Hash, pdf3Hash);
}
@Test
public void givenCheckedOutContentWhenUpdatingContentAndCheckinWithNewContentAsMinorThenMajorAndFirstUpdatedVersionDeleted()
throws Exception {
Record record = givenRecord().withSingleValueContent(
contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).contentCheckedOutBy(alice).isSaved();
givenTimeIs(shishOClock);
when(theRecord()).hasItsCheckedOutContentUpdatedWith(uploadPdf2InputStream()).and().isSaved();
when(theRecord()).contentCheckedInAsMinor(uploadPdf3InputStream()).isSaved();
assertThat(theRecordContentCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf3HashAndLength())
.has(version("0.2")).has(modifiedBy(alice)).has(modificationDatetime(shishOClock));
assertThat(theRecordContentHistory()).hasSize(1);
assertThat(theRecordContentHistory().get(0)).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf1HashAndLength())
.has(version("0.1")).has(modifiedBy(bob)).has(modificationDatetime(smashOClock));
assertThat(theRecordContent()).is(notCheckedOut());
assertThatVaultOnlyContains(pdf1Hash, pdf3Hash);
}
@Test
public void givenCheckedOutContentWhenUpdatingContentWithIncorrectMethodThenExceptionAndNothingIsChanged()
throws Exception {
Record record = givenRecord().withSingleValueContent(
contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).contentCheckedOutBy(alice).isSaved();
givenTimeIs(shishOClock);
when(theRecord()).hasItsCheckedOutContentUpdatedWith(uploadPdf2InputStream()).and().isSaved();
assertThat(theRecordContentCurrentCheckedOutVersion()).has(pdf2HashAndLength()).has(version("0.2"))
.has(modificationDatetime(shishOClock));
givenTimeIs(teaOClock);
RecordPreparation recordPreparation = when(theRecord());
try {
recordPreparation.hasItsContentUpdated(alice, uploadPdf3InputStream());
fail("ContentImplRuntimeException_ContentMustNotBeCheckedOut expected");
} catch (ContentImplRuntimeException_ContentMustNotBeCheckedOut e) {
//OK
}
recordPreparation.isSaved();
try {
recordPreparation.hasItsContentUpdatedAndFinalized(alice, uploadPdf3InputStream());
fail("ContentImplRuntimeException_ContentMustNotBeCheckedOut expected");
} catch (ContentImplRuntimeException_ContentMustNotBeCheckedOut e) {
//OK
}
recordPreparation.isSaved();
assertThat(theRecordContentCurrentCheckedOutVersion()).has(pdf2HashAndLength()).has(version("0.2"))
.has(modificationDatetime(shishOClock));
assertThatVaultOnlyContains(pdf1Hash, pdf2Hash);
}
@Test
public void whenUploadingNeverUsedContentWhenCleaningVaultThenContentRemoved()
throws Exception {
givenTimeIs(shishOClock);
assertThat(getModelLayerFactory().getConfiguration().getDelayBeforeDeletingUnreferencedContents()).isEqualTo(
org.joda.time.Duration.standardMinutes(42)
);
assertThat(getModelLayerFactory().getConfiguration().getUnreferencedContentsThreadDelayBetweenChecks()).isEqualTo(
org.joda.time.Duration.standardHours(10)
);
uploadPdf1InputStream();
uploadPdf2InputStream();
uploadDocx1InputStream();
givenTimeIs(shishOClock.plusMinutes(41));
contentManager.deleteUnreferencedContents();
assertThatVaultOnlyContainsWithoutAdvancingTime(pdf1Hash, pdf2Hash, docx1Hash);
givenTimeIs(shishOClock.plusMinutes(42));
assertThatVaultOnlyContainsWithoutAdvancingTime();
}
@Test
public void givenAContentIsNotCheckedOutThenCannotCheckinAsMajor()
throws Exception {
Record record = givenRecord().withSingleValueContent(
contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
givenTimeIs(shishOClock);
RecordPreparation recordPreparation = when(theRecord());
try {
recordPreparation.contentCheckedInAsMajor(uploadPdf3InputStream());
fail("ContentImplRuntimeException_ContentMustBeCheckedOut expected");
} catch (ContentImplRuntimeException_ContentMustBeCheckedOut e) {
//OK
}
recordPreparation.isSaved();
assertThat(theRecordContentCurrentVersion()).has(pdf1HashAndLength()).has(modificationDatetime(smashOClock));
}
@Test
public void givenAContentIsNotCheckedOutThenCannotCheckinAsMinor()
throws Exception {
Record record = givenRecord().withSingleValueContent(
contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
givenTimeIs(shishOClock);
RecordPreparation recordPreparation = when(theRecord());
try {
recordPreparation.contentCheckedInAsMinor(uploadPdf3InputStream());
fail("ContentImplRuntimeException_ContentMustBeCheckedOut expected");
} catch (ContentImplRuntimeException_ContentMustBeCheckedOut e) {
//OK
}
recordPreparation.isSaved();
assertThat(theRecordContentCurrentVersion()).has(pdf1HashAndLength()).has(modificationDatetime(smashOClock));
}
@Test
public void givenAContentIsNotCheckedOutThenCannotCheckinAsMinorWithNewFilename()
throws Exception {
Record record = givenRecord().withSingleValueContent(
contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
givenTimeIs(shishOClock);
RecordPreparation recordPreparation = when(theRecord());
try {
recordPreparation.contentCheckedInAsMinorWithNewName(uploadPdf3InputStream(), "newFile.pdf");
fail("ContentImplRuntimeException_ContentMustBeCheckedOut expected");
} catch (ContentImplRuntimeException_ContentMustBeCheckedOut e) {
//OK
}
recordPreparation.isSaved();
assertThat(theRecordContentCurrentVersion()).has(pdf1HashAndLength()).has(modificationDatetime(smashOClock));
}
@Test
public void givenAContentIsNotCheckedOutThenCannotCheckin()
throws Exception {
Record record = givenRecord().withSingleValueContent(
contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
givenTimeIs(shishOClock);
RecordPreparation recordPreparation = when(theRecord());
try {
recordPreparation.contentCheckedIn().isSaved();
fail("ContentImplRuntimeException_ContentMustBeCheckedOut expected");
} catch (ContentImplRuntimeException_ContentMustBeCheckedOut e) {
//OK
}
recordPreparation.isSaved();
assertThat(theRecordContentCurrentVersion()).has(pdf1HashAndLength()).has(modificationDatetime(smashOClock));
}
@Test
public void givenAContentIsNotCheckedOutThenCannotCancelCheckin()
throws Exception {
Record record = givenRecord().withSingleValueContent(
contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream())).isSaved();
givenTimeIs(shishOClock);
RecordPreparation recordPreparation = when(theRecord());
try {
recordPreparation.contentCheckedInCancelled();
fail("ContentImplRuntimeException_ContentMustBeCheckedOut expected");
} catch (ContentImplRuntimeException_ContentMustBeCheckedOut e) {
//OK
}
recordPreparation.isSaved();
assertThat(theRecordContentCurrentVersion()).has(pdf1HashAndLength()).has(modificationDatetime(smashOClock));
}
@Test
public void givenAContentIsAlreadyCheckedOutThenCannotCheck()
throws Exception {
givenRecord().withSingleValueContent(contentManager.createMinor(bob, "ZePdf.pdf", uploadPdf1InputStream()))
.contentCheckedOutBy(alice).isSaved();
givenTimeIs(shishOClock);
RecordPreparation recordPreparation = when(theRecord());
try {
recordPreparation.contentCheckedOutBy(alice);
fail("ContentImplRuntimeException_ContentMustNotBeCheckedOut expected");
} catch (ContentImplRuntimeException_ContentMustNotBeCheckedOut e) {
//OK
}
recordPreparation.isSaved();
assertThat(theRecordContentCurrentVersion()).has(pdf1HashAndLength()).has(modificationDatetime(smashOClock));
}
@Test
public void givenARecordHasAParsedContentHigherThanTheLimitThenTrimmed()
throws Exception {
SystemConfigurationsManager manager = getModelLayerFactory().getSystemConfigurationsManager();
givenSingleValueContentMetadataIsSearchable();
//default limit is 3mo
ContentVersionDataSummary zeContent = contentManager.upload(getTestResourceInputStream("fileWith4MoOfParsedContent.txt"));
ParsedContent parsedContent = contentManager.getParsedContent(zeContent.getHash());
givenRecord().withSingleValueContent(contentManager.createMajor(alice, "file.txt", zeContent)).isSaved();
assertThat(parsedContent.getParsedContent()).contains("Allo", "Hola", "Test").doesNotContain("Cafe");
assertThatRecordCanBeObtainedWithKeywords("Allo", "Hola", "Test");
assertThatRecordCannotBeObtainedWithKeywords("Cafe");
manager.setValue(PARSED_CONTENT_MAX_LENGTH_IN_KILOOCTETS, 4000);
contentManager.reparse(zeContent.getHash());
parsedContent = contentManager.getParsedContent(zeContent.getHash());
assertThat(parsedContent.getParsedContent()).contains("Allo", "Hola", "Cafe", "Test");
assertThatRecordCanBeObtainedWithKeywords("Allo", "Hola", "Cafe", "Test");
manager.setValue(PARSED_CONTENT_MAX_LENGTH_IN_KILOOCTETS, 2000);
contentManager.reparse(zeContent.getHash());
parsedContent = contentManager.getParsedContent(zeContent.getHash());
assertThat(parsedContent.getParsedContent()).contains("Allo", "Test").doesNotContain("Cafe").doesNotContain("Hola");
assertThatRecordCanBeObtainedWithKeywords("Allo", "Test");
assertThatRecordCannotBeObtainedWithKeywords("Cafe", "Hola");
}
@Test
public void givenTheRequireConversionFlagIsActivatedWhenCheckContentsToConvertThenConvert()
throws Exception {
ContentVersionDataSummary zeContent = uploadDocx1InputStream();
givenRecord().withSingleValueContent(contentManager.createMajor(alice, "file.docx", zeContent))
.withRequireConversionFlag(true).isSaved();
assertThat(theRecord().get(Schemas.MARKED_FOR_PREVIEW_CONVERSION)).isEqualTo(Boolean.TRUE);
assertThat(contentManager.hasContentPreview(zeContent.getHash())).isFalse();
try {
contentManager.getContentPreviewInputStream(zeContent.getHash(), SDK_STREAM);
fail("Exception expected");
} catch (ContentManagerRuntimeException_ContentHasNoPreview e) {
//OK
}
contentManager.convertPendingContentForPreview();
assertThat(theRecord().get(Schemas.MARKED_FOR_PREVIEW_CONVERSION)).isNull();
assertThat(contentManager.hasContentPreview(zeContent.getHash())).isTrue();
InputStream in = contentManager.getContentPreviewInputStream(zeContent.getHash(), SDK_STREAM);
ByteArrayOutputStream out = new ByteArrayOutputStream();
IOUtils.copy(in, out);
assertThat(out.toByteArray().length == 42);
}
@Test
public void givenARecordCannotBeConvertedThenFlagRemovedAndStillNotAvailableForePreview()
throws Exception {
ContentVersionDataSummary zeContent = uploadACorruptedDocx();
givenRecord().withSingleValueContent(contentManager.createMajor(alice, "file.docx", zeContent))
.withRequireConversionFlag(true).isSaved();
assertThat(theRecord().get(Schemas.MARKED_FOR_PREVIEW_CONVERSION)).isEqualTo(Boolean.TRUE);
assertThat(contentManager.hasContentPreview(zeContent.getHash())).isFalse();
try {
contentManager.getContentPreviewInputStream(zeContent.getHash(), SDK_STREAM);
fail("Exception expected");
} catch (ContentManagerRuntimeException_ContentHasNoPreview e) {
//OK
}
contentManager.convertPendingContentForPreview();
assertThat(theRecord().get(Schemas.MARKED_FOR_PREVIEW_CONVERSION)).isNull();
assertThat(contentManager.hasContentPreview(zeContent.getHash())).isFalse();
try {
contentManager.getContentPreviewInputStream(zeContent.getHash(), SDK_STREAM);
fail("Exception expected");
} catch (ContentManagerRuntimeException_ContentHasNoPreview e) {
//OK
}
}
@Test
public void givenOnlyAMinorVersionWhenGetLatestMajorThenReturnNull()
throws Exception {
doReturn(true).when(userPermissionsChecker).globally();
doReturn(userPermissionsChecker).when(bob).has(CorePermissions.DELETE_CONTENT_VERSION);
Content content = contentManager.createMinor(alice, "ZePdf.pdf", uploadPdf1InputStreamWithoutParsing());
givenRecord().withSingleValueContent(content).isSaved();
assertThat(content.getLastMajorContentVersion()).isNull();
assertThat(content.getCurrentVersion().getVersion()).isEqualTo("0.1");
when(theRecord()).hasItsContentUpdated(alice, uploadPdf2InputStream()).and().isSaved();
assertThat(theRecordContent().getLastMajorContentVersion()).isNull();
assertThat(theRecordContent().getCurrentVersion().getVersion()).isEqualTo("0.2");
when(theRecord()).hasItsContentFinalized().isSaved();
assertThat(theRecordContent().getLastMajorContentVersion().getVersion()).isEqualTo("1.0");
assertThat(theRecordContent().getCurrentVersion().getVersion()).isEqualTo("1.0");
when(theRecord()).hasItsContentUpdated(alice, uploadPdf3InputStream()).and().isSaved();
assertThat(theRecordContent().getLastMajorContentVersion().getVersion()).isEqualTo("1.0");
assertThat(theRecordContent().getCurrentVersion().getVersion()).isEqualTo("1.1");
when(theRecord()).hasItsContentFinalized().isSaved();
assertThat(theRecordContent().getLastMajorContentVersion().getVersion()).isEqualTo("2.0");
assertThat(theRecordContent().getCurrentVersion().getVersion()).isEqualTo("2.0");
when(theRecord()).hasItsContentUpdated(alice, uploadDocx1InputStream()).and().isSaved();
assertThat(theRecordContent().getLastMajorContentVersion().getVersion()).isEqualTo("2.0");
assertThat(theRecordContent().getCurrentVersion().getVersion()).isEqualTo("2.1");
when(theRecord()).hasItsContentFinalized().isSaved();
assertThat(theRecordContent().getLastMajorContentVersion().getVersion()).isEqualTo("3.0");
assertThat(theRecordContent().getCurrentVersion().getVersion()).isEqualTo("3.0");
}
@Test
public void whenCreateAndUpdateContentWithCustomVersionLabelThenUsed()
throws Exception {
givenRecord().withSingleValueContent(contentManager.createWithVersion(bob, "ZePdf.pdf", uploadPdf1InputStream(), "3.5"))
.isSaved();
assertThat(theRecordContent()).isNot(emptyVersion);
assertThat(theRecordContent().getCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf1HashAndLength())
.is(version("3.5")).is(modifiedBy(bob)).has(modificationDatetime(smashOClock));
when(theRecord()).hasItsContentUpdatedWithVersionAndName(alice, uploadPdf2InputStream(), "42", "ZeNewPdf.pdf")
.isSaved();
when(theRecord()).hasItsContentUpdatedWithVersionAndName(alice, uploadPdf2InputStream(), "66.6", "ZeNewPdf.pdf")
.isSaved();
assertThat(theRecordContent().getCurrentVersion().getVersion()).isEqualTo("66.6");
assertThat(theRecordContent().getHistoryVersions().get(1).getVersion()).isEqualTo("42.0");
assertThat(theRecordContent().getHistoryVersions().get(0).getVersion()).isEqualTo("3.5");
}
@Test
public void whenCreateAndUpdateContentWithBadCustomVersionThenException()
throws Exception {
try {
givenRecord()
.withSingleValueContent(contentManager.createWithVersion(bob, "ZePdf.pdf", uploadPdf1InputStream(), "3.5a"));
fail("Invalid argument exception expected");
} catch (ContentImplRuntimeException_InvalidArgument e) {
//oK
}
givenRecord().withSingleValueContent(contentManager.createWithVersion(bob, "ZePdf.pdf", uploadPdf1InputStream(), "3.5"))
.isSaved();
try {
when(theRecord()).hasItsContentUpdatedWithVersionAndName(alice, uploadPdf2InputStream(), "42b", "ZeNewPdf.pdf");
fail("Invalid argument exception expected");
} catch (ContentImplRuntimeException_InvalidArgument e) {
//oK
}
}
@Test
public void whenCreateAndUpdateContentWithInferiorCustomVersionThenException()
throws Exception {
givenRecord().withSingleValueContent(contentManager.createWithVersion(bob, "ZePdf.pdf", uploadPdf1InputStream(), "3"))
.isSaved();
assertThat(theRecordContent().getCurrentVersion()).has(pdfMimetype()).has(filename("ZePdf.pdf")).has(pdf1HashAndLength())
.is(version("3.0")).is(modifiedBy(bob)).has(modificationDatetime(smashOClock));
try {
when(theRecord()).hasItsContentUpdatedWithVersionAndName(alice, uploadPdf2InputStream(), "2.4", "ZeNewPdf.pdf");
fail("Invalid argument exception expected");
} catch (ContentImplRuntimeException_VersionMustBeHigherThanPreviousVersion e) {
//oK
}
}
//------------------------------------------------------------------
private void assertThatRecordCanBeObtainedWithKeywords(String... keywords) {
SearchServices searchServices = getModelLayerFactory().newSearchServices();
for (String keyword : keywords) {
assertThat(searchServices.search(new LogicalSearchQuery(fromAllSchemasIn(zeCollection).returnAll())
.setFreeTextQuery(keyword))).isNotEmpty();
}
}
private void assertThatRecordCannotBeObtainedWithKeywords(String... keywords) {
SearchServices searchServices = getModelLayerFactory().newSearchServices();
for (String keyword : keywords) {
assertThat(searchServices.search(new LogicalSearchQuery(fromAllSchemasIn(zeCollection).returnAll())
.setFreeTextQuery(keyword))).isEmpty();
}
}
private void givenSingleValueContentMetadataIsSearchable() {
schemas.modify(new MetadataSchemaTypesAlteration() {
@Override
public void alter(MetadataSchemaTypesBuilder types) {
types.getMetadata(zeSchema.contentMetadata().getCode()).setSearchable(true);
}
});
zeSchema = schemas.new ZeSchemaMetadatas();
}
private Condition<? super Content> notCheckedOut() {
return new Condition<Content>() {
@Override
public boolean matches(Content value) {
return value.getCheckoutUserId() == null && value.getCheckoutDateTime() == null
&& value.getCurrentCheckedOutVersion() == null;
}
}.describedAs("notCheckedOut()");
}
private Condition<? super Content> checkedOutBy(final User user, final LocalDateTime localDateTime) {
return new Condition<Content>() {
@Override
public boolean matches(Content value) {
String userId = user == null ? null : user.getId();
return localDateTime.equals(value.getCheckoutDateTime()) && LangUtils
.areNullableEqual(userId, value.getCheckoutUserId());
}
}.describedAs("checkedOutBy(" + user + ", " + localDateTime + ")");
}
private Condition<? super ContentVersion> modifiedBy(final User user) {
return new Condition<ContentVersion>() {
@Override
public boolean matches(ContentVersion value) {
String userId = user == null ? null : user.getId();
return LangUtils.areNullableEqual(userId, value.getModifiedBy());
}
}.describedAs("modifiedBy(" + user + ")");
}
private Condition<? super ContentVersion> modificationDatetime(final LocalDateTime dateTime) {
return new Condition<ContentVersion>() {
@Override
public boolean matches(ContentVersion value) {
return dateTime.equals(value.getLastModificationDateTime());
}
}.describedAs("modificationDatetime(" + dateTime + ")");
}
private Condition<? super ContentVersion> version(final String version) {
return new Condition<ContentVersion>() {
@Override
public boolean matches(ContentVersion value) {
return version.equals(value.getVersion());
}
}.describedAs("version(" + version + ")");
}
private Condition<? super ContentVersion> pdfMimetype() {
return mimetype(PDF_MIMETYPE);
}
private Condition<? super ContentVersion> docsMimetype() {
return mimetype(DOCX_MIMETYPE);
}
private Condition<? super ContentVersion> mimetype(final String mimetype) {
return new Condition<ContentVersion>() {
@Override
public boolean matches(ContentVersion value) {
return mimetype.equals(value.getMimetype());
}
}.describedAs("mimetype(" + mimetype + ")");
}
private Condition<? super ContentVersion> filename(final String filename) {
return new Condition<ContentVersion>() {
@Override
public boolean matches(ContentVersion value) {
return filename.equals(value.getFilename());
}
}.describedAs("filename(" + filename + ")");
}
private Condition<? super ContentVersion> comment(final String comment) {
return new Condition<ContentVersion>() {
@Override
public boolean matches(ContentVersion value) {
if (comment == null) {
return value.getComment() == null || value.getComment().equals("");
} else {
return comment.equals(value.getComment());
}
}
}.describedAs("comment(" + comment + ")");
}
private Condition<? super ContentVersion> pdf1HashAndLength() {
return hash(pdf1Hash, pdf1Length);
}
private Condition<? super ContentVersion> pdf2HashAndLength() {
return hash(pdf2Hash, pdf2Length);
}
private Condition<? super ContentVersion> pdf3HashAndLength() {
return hash(pdf3Hash, pdf3Length);
}
private Condition<? super ContentVersion> docx1HashAndLength() {
return hash(docx1Hash, docx1Length);
}
private Condition<? super ContentVersion> docx2HashAndLength() {
return hash(docx2Hash, docx2Length);
}
private Condition<? super ContentVersion> hash(final String hash, final long length) {
return new Condition<ContentVersion>() {
@Override
public boolean matches(ContentVersion value) {
return hash.equals(value.getHash()) && length == value.getLength();
}
}.describedAs("hash(" + hash + ")");
}
private RecordPreparation givenRecord() {
Record record = new TestRecord(zeSchema, "zeRecord");
return new RecordPreparation(record);
}
private RecordPreparation givenRecordWithId(String id) {
Record record = new TestRecord(zeSchema, id);
return new RecordPreparation(record);
}
private RecordPreparation givenAnotherCollectionRecord() {
Record record = new TestRecord(anotherCollectionSchema, "anotherCollectionRecord");
return new RecordPreparation(record);
}
private Record theRecord() {
return recordServices.getDocumentById("zeRecord");
}
private Content theRecordContent() {
return theRecord().get(zeSchema.contentMetadata());
}
private List<ContentVersion> theRecordContentHistory() {
return theRecordContent().getHistoryVersions();
}
private ContentVersion theRecordContentCurrentVersion() {
return theRecordContent().getCurrentVersion();
}
private ContentVersion theRecordContentCurrentCheckedOutVersion() {
return theRecordContent().getCurrentCheckedOutVersion();
}
private Content theRecordFirstMultivalueContent() {
List<Content> contents = theRecord().getList(zeSchema.contentListMetadata());
return contents.get(0);
}
private Content theRecordSecondAndLastMultivalueContent() {
List<Content> contents = theRecord().getList(zeSchema.contentListMetadata());
assertThat(contents).hasSize(2);
return contents.get(1);
}
private RecordPreparation givenAnotherRecord() {
Record record = new TestRecord(zeSchema, "anotherRecord");
return new RecordPreparation(record);
}
private RecordPreparation given(Record record) {
return new RecordPreparation(record);
}
private RecordPreparation when(Record record) {
return new RecordPreparation(record);
}
private Record createZeRecord() {
return new TestRecord(zeSchema, "zeRecord");
}
private ContentVersionDataSummary getPdf1InputStream() {
return new ContentVersionDataSummary(pdf1Hash, "application/pdf", 170039);
}
private ContentVersionDataSummary getPdf2InputStream() {
return new ContentVersionDataSummary(pdf2Hash, "application/pdf", 167347);
}
private ContentVersionDataSummary getPdf3InputStream() {
return new ContentVersionDataSummary(pdf3Hash, "application/pdf", 141667);
}
private ContentVersionDataSummary getDocx1InputStream() {
return new ContentVersionDataSummary(docx1Hash,
"application/vnd.openxmlformats-officedocument.wordprocessingml.document", 27055);
}
private ContentVersionDataSummary getDocx2InputStream() {
return new ContentVersionDataSummary(docx2Hash,
"application/vnd.openxmlformats-officedocument.wordprocessingml.document", 27325);
}
private ContentVersionDataSummary uploadACorruptedDocx() {
return contentManager.upload(getTestResourceInputStream("corrupted.docx"));
}
private ContentVersionDataSummary uploadPdf1InputStream() {
return contentManager.upload(getTestResourceInputStream("pdf1.pdf"));
}
private ContentVersionDataSummary uploadPdf2InputStream() {
return contentManager.upload(getTestResourceInputStream("pdf2.pdf"));
}
private ContentVersionDataSummary uploadPdf3InputStream() {
return contentManager.upload(getTestResourceInputStream("pdf3.pdf"));
}
private ContentVersionDataSummary uploadDocx1InputStream() {
return contentManager.upload(getTestResourceInputStream("docx1.docx"));
}
private ContentVersionDataSummary uploadDocx2InputStream() {
return contentManager.upload(getTestResourceInputStream("docx2.docx"));
}
private ContentVersionDataSummary uploadPdf1InputStreamWithoutParsing() {
return contentManager.upload(getTestResourceInputStream("pdf1.pdf"), false, false, "pd1.pdf");
}
private ContentVersionDataSummary uploadPdf2InputStreamWithoutParsing() {
return contentManager.upload(getTestResourceInputStream("pdf2.pdf"), false, false, "pd2.docx.pdf");
}
private ContentVersionDataSummary uploadPdf3InputStreamWithoutParsing() {
return contentManager.upload(getTestResourceInputStream("pdf3.pdf"), false, false, "pd3.pdf.pdf");
}
private ContentVersionDataSummary uploadDocx1InputStreamWithoutParsing() {
return contentManager.upload(getTestResourceInputStream("docx1.docx"), false, false, "doc1.docx");
}
private ContentVersionDataSummary uploadDocx2InputStreamWithoutParsing() {
return contentManager.upload(getTestResourceInputStream("docx2.docx"), false, false, "doc2.doc.docx");
}
private void assertThatVaultOnlyContains(String... hashes)
throws Exception {
RecordDao recordDao = getDataLayerFactory().newRecordDao();
recordDao.flush();
givenTimeIs(shishOClock.plusDays(1));
assertThatVaultOnlyContainsWithoutAdvancingTime(hashes);
}
private void assertThatVaultOnlyContainsWithoutAdvancingTime(String... hashes)
throws Exception {
RecordDao recordDao = getDataLayerFactory().newRecordDao();
recordDao.flush();
getModelLayerFactory().getContentManager().deleteUnreferencedContents();
List<String> hashList = asList(hashes);
if (hashList.contains(pdf1Hash)) {
assertThatContentIsAvailable(getPdf1InputStream());
} else {
assertThatContentIsNotAvailable(pdf1Hash);
}
if (hashList.contains(pdf2Hash)) {
assertThatContentIsAvailable(getPdf2InputStream());
} else {
assertThatContentIsNotAvailable(pdf2Hash);
}
if (hashList.contains(pdf3Hash)) {
assertThatContentIsAvailable(getPdf3InputStream());
} else {
assertThatContentIsNotAvailable(pdf3Hash);
}
if (hashList.contains(docx1Hash)) {
assertThatContentIsAvailable(getDocx1InputStream());
} else {
assertThatContentIsNotAvailable(docx1Hash);
}
if (hashList.contains(docx2Hash)) {
assertThatContentIsAvailable(getDocx2InputStream());
} else {
assertThatContentIsNotAvailable(docx2Hash);
}
}
private void assertThatContentIsAvailable(ContentVersionDataSummary dataSummary)
throws Exception {
ContentVersionDataSummary retrievedDataSummary = contentManager.getContentVersionSummary(dataSummary.getHash());
assertThat(retrievedDataSummary).isEqualTo(dataSummary);
InputStream contentStream = contentManager.getContentInputStream(dataSummary.getHash(), SDK_STREAM);
if (dataSummary.getHash().equals(pdf1Hash)) {
assertThat(contentStream).hasContentEqualTo(getTestResourceInputStream("pdf1.pdf"));
} else if (dataSummary.getHash().equals(pdf2Hash)) {
assertThat(contentStream).hasContentEqualTo(getTestResourceInputStream("pdf2.pdf"));
} else if (dataSummary.getHash().equals(pdf3Hash)) {
assertThat(contentStream).hasContentEqualTo(getTestResourceInputStream("pdf3.pdf"));
} else if (dataSummary.getHash().equals(docx1Hash)) {
assertThat(contentStream).hasContentEqualTo(getTestResourceInputStream("docx1.docx"));
} else if (dataSummary.getHash().equals(docx2Hash)) {
assertThat(contentStream).hasContentEqualTo(getTestResourceInputStream("docx2.docx"));
}
}
private void assertThatContentIsNotAvailable(String hash) {
try {
contentManager.getContentInputStream(hash, SDK_STREAM);
fail("Content with " + hash + " is available");
} catch (ContentManagerRuntimeException_NoSuchContent noSuchContent) {
//OK
}
try {
contentManager.getContentVersionSummary(hash);
fail("Content with " + hash + " is available");
} catch (ContentManagerRuntimeException_NoSuchContent noSuchContent) {
//OK
}
}
private class RecordPreparation {
private Record record;
private RecordPreparation(Record record) {
this.record = record;
}
public RecordPreparation withSingleValueContent(Content content) {
record.set(zeSchema.contentMetadata(), content);
return this;
}
public RecordPreparation addMultiValueContent(Content content) {
List<Content> currentContends = record.getList(zeSchema.contentListMetadata());
List<Content> contents = new ArrayList<>(currentContends);
contents.add(content);
record.set(zeSchema.contentListMetadata(), contents);
return this;
}
public RecordPreparation clearAllMultiValueContents() {
List<Content> contents = new ArrayList<>();
record.set(zeSchema.contentListMetadata(), contents);
return this;
}
public Record isSaved()
throws RecordServicesException {
String id = record.getId();
if (record.isSaved()) {
recordServices.update(record);
} else {
recordServices.add(record);
}
return recordServices.getDocumentById(id);
}
public RecordPreparation contentCheckedOutBy(User alice) {
Content content = record.get(zeSchema.contentMetadata());
content.checkOut(alice);
return this;
}
public RecordPreparation and() {
return this;
}
public RecordPreparation hasItsContentUpdatedAndFinalized(User alice,
ContentVersionDataSummary contentVersionDataSummary) {
Content content = record.get(zeSchema.contentMetadata());
content.updateContent(alice, contentVersionDataSummary, true);
return this;
}
public RecordPreparation hasItsContentUpdated(User alice, ContentVersionDataSummary contentVersionDataSummary) {
Content content = record.get(zeSchema.contentMetadata());
content.updateContent(alice, contentVersionDataSummary, false);
return this;
}
public RecordPreparation hasItsContentUpdatedWithName(User alice, ContentVersionDataSummary contentVersionDataSummary,
String name) {
Content content = record.get(zeSchema.contentMetadata());
content.updateContentWithName(alice, contentVersionDataSummary, false, name);
return this;
}
public RecordPreparation hasItsContentUpdatedWithVersionAndName(User alice,
ContentVersionDataSummary contentVersionDataSummary, String version, String name) {
Content content = record.get(zeSchema.contentMetadata());
content.updateContentWithVersionAndName(alice, contentVersionDataSummary, version, name);
return this;
}
public RecordPreparation hasItsCheckedOutContentUpdatedWith(ContentVersionDataSummary contentVersionDataSummary) {
Content content = record.get(zeSchema.contentMetadata());
content.updateCheckedOutContent(contentVersionDataSummary);
return this;
}
public RecordPreparation hasItsContentRenamedTo(String newName) {
Content content = record.get(zeSchema.contentMetadata());
content.renameCurrentVersion(newName);
return this;
}
public RecordPreparation hasItsContentCommentChangedTo(String newComment) {
Content content = record.get(zeSchema.contentMetadata());
content.setVersionComment(newComment);
return this;
}
public RecordPreparation contentCheckedIn() {
Content content = record.get(zeSchema.contentMetadata());
content.checkIn();
return this;
}
public RecordPreparation contentCheckedInCancelled() {
Content content = record.get(zeSchema.contentMetadata());
content.cancelCheckOut();
return this;
}
public RecordPreparation finalizeVersion() {
Content content = record.get(zeSchema.contentMetadata());
content.finalizeVersion();
return this;
}
public RecordPreparation contentCheckedInAsMinor(ContentVersionDataSummary contentVersionDataSummary) {
Content content = record.get(zeSchema.contentMetadata());
content.checkInWithModification(contentVersionDataSummary, false);
return this;
}
public RecordPreparation contentCheckedInAsMinorWithNewName(ContentVersionDataSummary contentVersionDataSummary,
String newName) {
Content content = record.get(zeSchema.contentMetadata());
content.checkInWithModificationAndName(contentVersionDataSummary, false, newName);
return this;
}
public RecordPreparation contentCheckedInAsMajor(ContentVersionDataSummary contentVersionDataSummary) {
Content content = record.get(zeSchema.contentMetadata());
content.checkInWithModification(contentVersionDataSummary, true);
return this;
}
public RecordPreparation withParent(Record parent) {
record.set(zeSchema.parentReferenceFromZeSchemaToZeSchema(), parent);
return this;
}
public RecordPreparation hasItsContentFinalized() {
Content content = record.get(zeSchema.contentMetadata());
content.finalizeVersion();
return this;
}
public RecordPreparation deleteVersion(String versionLabel, User user) {
Content content = record.get(zeSchema.contentMetadata());
content.deleteVersion(versionLabel, user);
return this;
}
public RecordPreparation withRequireConversionFlag(boolean value) {
record.set(Schemas.MARKED_FOR_PREVIEW_CONVERSION, value);
return this;
}
}
Condition<? super Content> emptyVersion = new Condition<Content>() {
@Override
public boolean matches(Content value) {
return value.isEmptyVersion();
}
};
}