package com.constellio.model.services.contents;
import static com.constellio.sdk.tests.TestUtils.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.joda.time.LocalDateTime;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import com.constellio.data.dao.dto.records.RecordDTO;
import com.constellio.model.entities.records.Content;
import com.constellio.model.entities.records.ContentVersion;
import com.constellio.model.entities.records.Record;
import com.constellio.model.entities.records.wrappers.User;
import com.constellio.model.entities.schemas.Metadata;
import com.constellio.model.entities.schemas.MetadataSchema;
import com.constellio.model.entities.schemas.MetadataSchemaTypes;
import com.constellio.model.entities.schemas.MetadataValueType;
import com.constellio.model.services.records.RecordImpl;
import com.constellio.model.services.schemas.MetadataList;
import com.constellio.sdk.tests.ConstellioTest;
import com.constellio.sdk.tests.TestRecord;
import com.constellio.sdk.tests.TestUtils;
public class ContentModificationsBuilderTest extends ConstellioTest {
String schemaCode = "type_default";
String id1 = "1";
String id2 = "2";
String id3 = "3";
long length1 = 1;
long length2 = 2;
String username;
@Mock User user;
@Mock InputStream inputStream;
@Mock MetadataSchemaTypes types;
@Mock MetadataSchema schema;
RecordImpl record;
Metadata singleValueContentMetadata;
Metadata multiValueContentMetadata;
ContentModificationsBuilder builder;
String firstHash = "firstHash";
String secondHash = "secondHash";
String thirdHash = "thirdHash";
String fourthHash = "fourthHash";
String fifthHash = "fifthHash";
@Before
public void setUp()
throws Exception {
builder = new ContentModificationsBuilder(types);
Metadata textMetadata = TestUtils.mockManualMetadata("type_default_text", MetadataValueType.STRING);
singleValueContentMetadata = TestUtils.mockManualMetadata("type_default_singleValue", MetadataValueType.CONTENT);
multiValueContentMetadata = TestUtils
.mockManualMultivalueMetadata("type_default_multivalueValue", MetadataValueType.CONTENT);
when(singleValueContentMetadata.getDataStoreCode()).thenReturn("singleValue_s");
when(multiValueContentMetadata.getDataStoreCode()).thenReturn("multivalueValue_ss");
when(types.getSchema(schemaCode)).thenReturn(schema);
MetadataList metadatas = new MetadataList(textMetadata, singleValueContentMetadata, multiValueContentMetadata);
when(schema.getMetadatas()).thenReturn(
metadatas);
when(types.getMetadata("type_default_singleValue")).thenReturn(singleValueContentMetadata);
when(types.getMetadata("type_default_multivalueValue")).thenReturn(multiValueContentMetadata);
when(user.getUsername()).thenReturn(username);
}
@Test
public void givenARecordWithANewSingleValueContentWhenBuildingContentModificationThenInNewContentList() {
Content newContent = createMajor(id1, user, "file.pdf", contentVersionDataSummary(firstHash));
record = newRecord();
record.set(singleValueContentMetadata, newContent);
assertThatNewHashListOfBuildForModifiedRecords(record).containsOnly(firstHash);
assertThatDeleteListOfBuildForModifiedRecords(record).isEmpty();
assertThatBuildForDeletedRecords(record).containsOnly(firstHash);
}
@Test
public void givenARecordWithANewSingleValueContentReplacingAPreviousWhenBuildingContentModificationThenInNewContentListAndPreviousVersionsOfRemovedContentInDeletedList() {
ContentImpl oldContent
= createMajor(id1, user, "file.pdf", new ContentVersionDataSummary(firstHash, "mime1", length1));
oldContent.updateContent(user, new ContentVersionDataSummary(secondHash, "mime1", length1), true);
Content newContent = createMajor(id2, user, "file.pdf", contentVersionDataSummary(thirdHash));
record = newExistingRecordWith(singleValueContentMetadata, toStr(oldContent));
record.set(singleValueContentMetadata, newContent);
assertThatNewHashListOfBuildForModifiedRecords(record).containsOnly(thirdHash);
assertThatDeleteListOfBuildForModifiedRecords(record).containsOnly(firstHash, secondHash);
assertThatBuildForDeletedRecords(record).containsOnly(firstHash, secondHash, thirdHash);
}
@Test
public void givenARecordWithARemovedSingleValueContentWhenBuildingContentModificationThenInInDeletedList() {
ContentImpl oldContent
= createMajor(id1, user, "file.pdf", new ContentVersionDataSummary(firstHash, "mime1", length1));
oldContent.updateContent(user, new ContentVersionDataSummary(secondHash, "mime1", length1), true);
record = newExistingRecordWith(singleValueContentMetadata, toStr(oldContent));
record.set(singleValueContentMetadata, null);
assertThatNewHashListOfBuildForModifiedRecords(record).isEmpty();
assertThatDeleteListOfBuildForModifiedRecords(record).containsOnly(firstHash, secondHash);
assertThatBuildForDeletedRecords(record).containsOnly(firstHash, secondHash);
}
@Test
public void givenARecordWithANewMultiValueContentWhenBuildingContentModificationThenInNewContentList() {
Content newContent1 = createMajor(id1, user, "file.pdf", contentVersionDataSummary(firstHash));
Content newContent2 = createMajor(id2, user, "file.pdf", contentVersionDataSummary(secondHash));
record = newRecord();
record.set(multiValueContentMetadata, Arrays.asList(newContent1, newContent2));
assertThatNewHashListOfBuildForModifiedRecords(record).containsOnly(firstHash, secondHash);
assertThatDeleteListOfBuildForModifiedRecords(record).isEmpty();
assertThatBuildForDeletedRecords(record).containsOnly(firstHash, secondHash);
}
@Test
public void givenARecordWithANewMultiValueContentReplacingAPreviousWhenBuildingContentModificationThenInNewContentListAndPreviousVersionsOfRemovedContentInDeletedList() {
ContentImpl oldContent1
= createMajor(id1, user, "file.pdf", new ContentVersionDataSummary(firstHash, "mime1", length1));
oldContent1.updateContent(user, new ContentVersionDataSummary(secondHash, "mime1", length1), true);
ContentImpl oldContent2
= createMajor(id2, user, "file.pdf", new ContentVersionDataSummary(thirdHash, "mime1", length1));
ContentImpl newContent = createMajor(id3, user, "file.pdf", contentVersionDataSummary(fourthHash));
record = newExistingRecordWith(multiValueContentMetadata, Arrays.asList(toStr(oldContent1), toStr(oldContent2)));
oldContent2 = (ContentImpl) record.getList(multiValueContentMetadata).get(1);
record.set(multiValueContentMetadata, Arrays.asList(newContent, oldContent2));
assertThatNewHashListOfBuildForModifiedRecords(record).containsOnly(fourthHash);
assertThatDeleteListOfBuildForModifiedRecords(record).containsOnly(firstHash, secondHash);
assertThatBuildForDeletedRecords(record).containsOnly(firstHash, secondHash, thirdHash, fourthHash);
}
@Test
public void givenARecordWithARemovedMultiValueContentWhenBuildingContentModificationThenInInDeletedList() {
ContentImpl oldContent1
= createMajor(id1, user, "file.pdf", new ContentVersionDataSummary(firstHash, "mime1", length1));
oldContent1.updateContent(user, new ContentVersionDataSummary(secondHash, "mime1", length1), true);
ContentImpl oldContent2
= createMajor(id2, user, "file.pdf", new ContentVersionDataSummary(thirdHash, "mime1", length1));
record = newExistingRecordWith(multiValueContentMetadata, Arrays.asList(toStr(oldContent1), toStr(oldContent2)));
record.set(multiValueContentMetadata, null);
assertThatNewHashListOfBuildForModifiedRecords(record).isEmpty();
assertThatDeleteListOfBuildForModifiedRecords(record).containsOnly(firstHash, secondHash, thirdHash);
assertThatBuildForDeletedRecords(record).containsOnly(firstHash, secondHash, thirdHash);
}
@Test
public void givenAContentWithNewVersionWhenBuildingContentModificationThenInNewVersionList() {
ContentImpl content
= createMajor(id1, user, "file.pdf", new ContentVersionDataSummary(firstHash, "mime1", length1));
content.updateContent(user, new ContentVersionDataSummary(secondHash, "mime1", length1), true);
record = newExistingRecordWith(singleValueContentMetadata, toStr(content));
content = record.get(singleValueContentMetadata);
content.updateContent(user, contentVersionDataSummary(thirdHash), true);
assertThatNewHashListOfBuildForModifiedRecords(record).containsOnly(thirdHash);
assertThatDeleteListOfBuildForModifiedRecords(record).isEmpty();
assertThatBuildForDeletedRecords(record).containsOnly(firstHash, secondHash, thirdHash);
}
@Test
public void givenACheckedOutContentWithNewVersionWhenBuildingContentModificationThenInNewVersionList() {
ContentImpl content
= createMajor(id1, user, "file.pdf", new ContentVersionDataSummary(firstHash, "mime1", length1));
content.updateContent(user, new ContentVersionDataSummary(secondHash, "mime1", length1), true);
record = newExistingRecordWith(singleValueContentMetadata, toStr(content));
content = record.get(singleValueContentMetadata);
content.checkOut(user).updateCheckedOutContent(contentVersionDataSummary(thirdHash));
assertThatNewHashListOfBuildForModifiedRecords(record).containsOnly(thirdHash);
assertThatDeleteListOfBuildForModifiedRecords(record).isEmpty();
assertThatBuildForDeletedRecords(record).containsOnly(firstHash, secondHash, thirdHash);
}
@Test
public void givenACheckedOutContentWithNewVersionWhenBuildingContentModificationThenInNewVersionListAndPreviousWorkContentInDeleteList() {
ContentImpl content
= createMajor(id1, user, "file.pdf", new ContentVersionDataSummary(firstHash, "mime1", length1));
content.updateContent(user, new ContentVersionDataSummary(secondHash, "mime1", length1), true);
content.checkOut(user).updateCheckedOutContent(new ContentVersionDataSummary(thirdHash, "mime2", length2));
record = newExistingRecordWith(singleValueContentMetadata, toStr(content));
content = record.get(singleValueContentMetadata);
content.updateCheckedOutContent(contentVersionDataSummary(fourthHash));
assertThatNewHashListOfBuildForModifiedRecords(record).containsOnly(fourthHash);
assertThatDeleteListOfBuildForModifiedRecords(record).containsOnly(thirdHash);
assertThatBuildForDeletedRecords(record).containsOnly(firstHash, secondHash, thirdHash, fourthHash);
}
@Test
public void givenACheckedOutRecordThenCurrentCheckedOutVersionCurrentVersionAndHistoryVersionAreInDeleteList() {
ContentImpl content
= createMajor(id1, user, "file.pdf", new ContentVersionDataSummary(firstHash, "mime1", length1));
content.updateContent(user, new ContentVersionDataSummary(secondHash, "mime1", length1), true);
content.checkOut(user).updateCheckedOutContent(new ContentVersionDataSummary(thirdHash, "mime2", length2));
record = newExistingRecordWith(singleValueContentMetadata, toStr(content));
assertThatNewHashListOfBuildForModifiedRecords(record).isEmpty();
assertThatDeleteListOfBuildForModifiedRecords(record).isEmpty();
assertThatBuildForDeletedRecords(record).containsOnly(firstHash, secondHash, thirdHash);
}
@Test
public void givenMultivalueContentThenAllVersionInDeleteList() {
ContentImpl content
= createMajor(id1, user, "file.pdf", new ContentVersionDataSummary(firstHash, "mime1", length1));
content.updateContent(user, new ContentVersionDataSummary(secondHash, "mime1", length1), true);
content.checkOut(user).updateCheckedOutContent(new ContentVersionDataSummary(thirdHash, "mime2", length2));
ContentImpl content2
= createMajor(id1, user, "file2.pdf", new ContentVersionDataSummary(fourthHash, "mime1", length1));
record = newExistingRecordWith(multiValueContentMetadata, Arrays.asList(toStr(content), toStr(content2)));
assertThatNewHashListOfBuildForModifiedRecords(record).isEmpty();
assertThatDeleteListOfBuildForModifiedRecords(record).isEmpty();
assertThatBuildForDeletedRecords(record).containsOnly(firstHash, secondHash, thirdHash, fourthHash);
}
@Test
public void givenRecordWithTwoContentHashesInMultivalueMetadataWhenReplacingOneContentHashByAnotherOneThenInDelteList() {
ContentImpl content
= createMajor(id1, user, "file.pdf", new ContentVersionDataSummary(firstHash, "mime1", length1));
content.updateContent(user, new ContentVersionDataSummary(secondHash, "mime1", length1), true);
content.checkOut(user).updateCheckedOutContent(new ContentVersionDataSummary(thirdHash, "mime2", length2));
ContentImpl content2
= createMajor(id1, user, "file2.pdf", new ContentVersionDataSummary(fourthHash, "mime1", length1));
record = newExistingRecordWith(multiValueContentMetadata, Arrays.asList(toStr(content), toStr(content2)));
ContentImpl content3
= createMajor(id1, user, "file3.pdf", new ContentVersionDataSummary(fifthHash, "mime1", length1));
record.set(multiValueContentMetadata, Arrays.asList(content2, content3));
assertThatNewHashListOfBuildForModifiedRecords(record).containsOnly(fifthHash);
assertThatDeleteListOfBuildForModifiedRecords(record).containsOnly(firstHash, secondHash, thirdHash);
assertThatBuildForDeletedRecords(record).containsOnly(firstHash, secondHash, thirdHash, fourthHash, fifthHash);
}
@Test
public void givenRecordWithTwoContentHashesInsingleValueMetadataWhenReplacingOneContentHashByAnotherOneThenInDelteList() {
ContentImpl content = createMajor(id1, user, "file.pdf", new ContentVersionDataSummary(firstHash, "mime1", length1));
content.updateContent(user, new ContentVersionDataSummary(secondHash, "mime1", length1), true);
content.checkOut(user).updateCheckedOutContent(new ContentVersionDataSummary(thirdHash, "mime2", length2));
ContentImpl content2 = createMajor(id1, user, "file2.pdf", new ContentVersionDataSummary(fourthHash, "mime1", length1));
record = newExistingRecordWith(singleValueContentMetadata, toStr(content));
record.set(singleValueContentMetadata, content2);
assertThatNewHashListOfBuildForModifiedRecords(record).containsOnly(fourthHash);
assertThatDeleteListOfBuildForModifiedRecords(record).containsOnly(firstHash, secondHash, thirdHash);
assertThatBuildForDeletedRecords(record).containsOnly(firstHash, secondHash, thirdHash, fourthHash);
}
private org.assertj.core.api.ListAssert<String> assertThatBuildForDeletedRecords(Record record) {
return assertThat(builder.buildForDeletedRecords(asList(record)));
}
private org.assertj.core.api.ListAssert<String> assertThatDeleteListOfBuildForModifiedRecords(Record record) {
return assertThat(builder.buildForModifiedRecords(asList(record)).getDeletedContentsVersionsHashes());
}
private org.assertj.core.api.ListAssert<String> assertThatNewHashListOfBuildForModifiedRecords(Record record) {
return assertThat(builder.buildForModifiedRecords(asList(record)).getContentsWithNewVersion());
}
private ContentVersion version(String hash) {
return new ContentVersion(contentVersionDataSummary(hash), "test.pdf", "zeVersion", "bob", new LocalDateTime(), null);
}
private ContentVersionDataSummary contentVersionDataSummary(String hash) {
return new ContentVersionDataSummary(hash, aString(), aLong());
}
private RecordImpl newRecord() {
return new TestRecord(schemaCode, zeCollection);
}
private String toStr(Content content) {
return new ContentFactory().toString(content);
}
private RecordImpl newExistingRecordWith(Metadata metadata, Object value) {
Map<String, Object> params = new HashMap<>();
params.put(metadata.getDataStoreCode(), value);
params.put("schema_s", schemaCode);
params.put("collection_s", zeCollection);
RecordDTO recordDTO = new RecordDTO("zeId", 3L, null, params);
return new TestRecord(recordDTO);
}
private ContentImpl createMajor(String id, User user, String filename, ContentVersionDataSummary newVersion) {
return ContentImpl.create(id, user, filename, newVersion, true, false);
}
private ContentImpl createMinor(String id, User user, String filename, ContentVersionDataSummary newVersion) {
return ContentImpl.create(id, user, filename, newVersion, false, false);
}
}