package com.constellio.model.services.records;
import static com.constellio.sdk.tests.TestUtils.asMap;
import static com.constellio.sdk.tests.TestUtils.mockManualMetadata;
import static com.constellio.sdk.tests.TestUtils.mockMetadata;
import static com.constellio.sdk.tests.TestUtils.unmodifiableCollection;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.data.MapEntry.entry;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.SerializationUtils;
import org.joda.time.LocalDate;
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.data.dao.dto.records.RecordDeltaDTO;
import com.constellio.data.utils.Factory;
import com.constellio.model.entities.records.Record;
import com.constellio.model.entities.records.RecordRuntimeException;
import com.constellio.model.entities.records.RecordRuntimeException.CannotMerge;
import com.constellio.model.entities.schemas.Metadata;
import com.constellio.model.entities.schemas.MetadataSchema;
import com.constellio.model.entities.schemas.MetadataValueType;
import com.constellio.model.entities.schemas.Schemas;
import com.constellio.model.entities.schemas.StructureFactory;
import com.constellio.model.entities.schemas.entries.CalculatedDataEntry;
import com.constellio.model.entities.schemas.entries.CopiedDataEntry;
import com.constellio.model.entities.schemas.entries.ManualDataEntry;
import com.constellio.model.services.encrypt.EncryptionServices;
import com.constellio.model.services.records.RecordImplRuntimeException.RecordImplException_UnsupportedOperationOnUnsavedRecord;
import com.constellio.model.services.schemas.MetadataList;
import com.constellio.model.services.schemas.testimpl.ZeModifiableStructure;
import com.constellio.sdk.tests.ConstellioTest;
import com.constellio.sdk.tests.TestRecord;
import com.constellio.sdk.tests.TestUtils;
public class RecordImplTest extends ConstellioTest {
LocalDateTime shishOClock;
String zeStringValue = "zeStringValue";
String theSchemaCode = "a_b";
String multipleTextMetadataCode = "multipleText";
String multipleTextMetadataCodeAndType = multipleTextMetadataCode + "_ss";
String numberMetadataCode = "number";
String numberMetadataCodeAndType = numberMetadataCode + "_d";
String otherNumberMetadataCode = "otherNumber";
String otherNumberMetadataCodeAndType = otherNumberMetadataCode + "_d";
String textMetadataCode = "text";
String textMetadataCodeAndType = textMetadataCode + "_s";
String dateMetadataCode = "date";
String dateMetadataCodeAndType = dateMetadataCode + "_dt";
String multipleBooleanMetadataCode = "multipleBoolean";
String multipleBooleanMetadataCodeAndType = multipleBooleanMetadataCode + "_bs";
String copyMetadataCode = "copy";
String copyMetadataCodeAndType = copyMetadataCode + "_s";
String calculatedMetadataCode = "calculated";
String calculatedMetadataCodeAndType = calculatedMetadataCode + "_s";
String factoredMetadataCode = "factoredMetadata";
String factoredMetadataCodeAndType = factoredMetadataCode + "_s";
String factoredListMetadataCode = "factoredListMetadata";
String factoredListMetadataCodeAndType = factoredListMetadataCode + "_ss";
@Mock Metadata textMetadata, numberMetadata, otherNumberMetadata, multipleTextMetadata, dateMetadata,
multipleBooleanMetadata, copyMetadata, calculatedMetadata, factoredMetadata, factoredListMetadata;
@Mock RecordDTO initialState, currentState;
@Mock MetadataSchema zeSchema;
String zeStructureInitialValue = "zeStructureInitialValue";
String zeStructureModifiedValue = "zeStructureModifiedValue";
String anotherStructureInitialValue = "anotherStructureInitialValue";
String aThirdStructureInitialValue = "aThirdStructureInitialValue";
@Mock ZeModifiableStructure zeStructure;
@Mock ZeModifiableStructure anotherStructure;
@Mock ZeModifiableStructure aThirdStructure;
@Mock StructureFactory stringStructureFactory;
@Mock FieldsPopulator copyfieldsPopulator, copyfieldsPopulator2;
@Mock Factory<EncryptionServices> encryptionServicesFactory;
@Before
public void setUp()
throws Exception {
when(initialState.getFields()).thenReturn(newSchemaFields());
when(currentState.getFields()).thenReturn(newSchemaFields());
MetadataList zeSchemaMetadatas = new MetadataList(
asList(multipleTextMetadata, dateMetadata, multipleBooleanMetadata, numberMetadata, otherNumberMetadata,
textMetadata, copyMetadata, calculatedMetadata, factoredMetadata, factoredListMetadata));
when(zeSchema.getMetadatas()).thenReturn(zeSchemaMetadatas);
when(zeSchema.getMetadata(multipleTextMetadataCode)).thenReturn(multipleTextMetadata);
when(multipleTextMetadata.getLocalCode()).thenReturn(multipleTextMetadataCode);
when(multipleTextMetadata.getCode()).thenReturn(theSchemaCode + "_" + multipleTextMetadataCode);
when(multipleTextMetadata.isMultivalue()).thenReturn(true);
when(multipleTextMetadata.getDataStoreType()).thenReturn("ss");
when(multipleTextMetadata.getDataStoreCode()).thenReturn(multipleTextMetadataCodeAndType);
when(multipleTextMetadata.getDataEntry()).thenReturn(new ManualDataEntry());
when(zeSchema.getMetadata(dateMetadataCode)).thenReturn(dateMetadata);
when(dateMetadata.getLocalCode()).thenReturn(dateMetadataCode);
when(dateMetadata.getCode()).thenReturn(theSchemaCode + "_" + dateMetadataCode);
when(dateMetadata.getDataStoreType()).thenReturn("dt");
when(dateMetadata.getDataStoreCode()).thenReturn(dateMetadataCodeAndType);
when(dateMetadata.getDataEntry()).thenReturn(new ManualDataEntry());
when(zeSchema.getMetadata(multipleBooleanMetadataCode)).thenReturn(multipleBooleanMetadata);
when(multipleBooleanMetadata.getLocalCode()).thenReturn(multipleBooleanMetadataCode);
when(multipleBooleanMetadata.getCode()).thenReturn(theSchemaCode + "_" + multipleBooleanMetadataCode);
when(multipleBooleanMetadata.isMultivalue()).thenReturn(true);
when(multipleBooleanMetadata.getDataStoreType()).thenReturn("bs");
when(multipleBooleanMetadata.getDataStoreCode()).thenReturn(multipleBooleanMetadataCodeAndType);
when(multipleBooleanMetadata.getDataEntry()).thenReturn(new ManualDataEntry());
when(zeSchema.getMetadata(numberMetadataCode)).thenReturn(numberMetadata);
when(numberMetadata.getLocalCode()).thenReturn(numberMetadataCode);
when(numberMetadata.getCode()).thenReturn(theSchemaCode + "_" + numberMetadataCode);
when(numberMetadata.getDataStoreType()).thenReturn("d");
when(numberMetadata.getDataStoreCode()).thenReturn(numberMetadataCodeAndType);
when(numberMetadata.getDataEntry()).thenReturn(new ManualDataEntry());
when(zeSchema.getMetadata(otherNumberMetadataCode)).thenReturn(otherNumberMetadata);
when(otherNumberMetadata.getLocalCode()).thenReturn(otherNumberMetadataCode);
when(otherNumberMetadata.getCode()).thenReturn(theSchemaCode + "_" + otherNumberMetadataCode);
when(otherNumberMetadata.getDataStoreType()).thenReturn("d");
when(otherNumberMetadata.getDataStoreCode()).thenReturn(otherNumberMetadataCodeAndType);
when(otherNumberMetadata.getDataEntry()).thenReturn(new ManualDataEntry());
when(zeSchema.getMetadata(textMetadataCode)).thenReturn(textMetadata);
when(textMetadata.getLocalCode()).thenReturn(textMetadataCode);
when(textMetadata.getCode()).thenReturn(theSchemaCode + "_" + textMetadataCode);
when(textMetadata.getDataStoreType()).thenReturn("s");
when(textMetadata.getDataStoreCode()).thenReturn(textMetadataCodeAndType);
when(textMetadata.getDataEntry()).thenReturn(new ManualDataEntry());
when(zeSchema.getMetadata(copyMetadataCode)).thenReturn(copyMetadata);
when(copyMetadata.getLocalCode()).thenReturn(copyMetadataCode);
when(copyMetadata.getCode()).thenReturn(theSchemaCode + "_" + copyMetadataCode);
when(copyMetadata.getDataStoreType()).thenReturn("s");
when(copyMetadata.getDataStoreCode()).thenReturn(copyMetadataCodeAndType);
when(copyMetadata.getDataEntry()).thenReturn(new CopiedDataEntry(aString(), aString()));
when(zeSchema.getMetadata(calculatedMetadataCode)).thenReturn(calculatedMetadata);
when(calculatedMetadata.getLocalCode()).thenReturn(calculatedMetadataCode);
when(calculatedMetadata.getCode()).thenReturn(theSchemaCode + "_" + calculatedMetadataCode);
when(calculatedMetadata.getDataStoreType()).thenReturn("s");
when(calculatedMetadata.getDataStoreCode()).thenReturn(calculatedMetadataCodeAndType);
when(calculatedMetadata.getDataEntry()).thenReturn(new CalculatedDataEntry(null));
when(zeSchema.getMetadata(factoredMetadataCode)).thenReturn(factoredMetadata);
when(factoredMetadata.getLocalCode()).thenReturn(factoredMetadataCode);
when(factoredMetadata.getCode()).thenReturn(theSchemaCode + "_" + factoredMetadataCode);
when(factoredMetadata.getDataStoreType()).thenReturn("s");
when(factoredMetadata.getDataStoreCode()).thenReturn(factoredMetadataCodeAndType);
when(factoredMetadata.getType()).thenReturn(MetadataValueType.STRING);
when(factoredMetadata.getStructureFactory()).thenReturn((StructureFactory) stringStructureFactory);
when(factoredMetadata.getDataEntry()).thenReturn(new ManualDataEntry());
when(zeSchema.getMetadata(factoredListMetadataCode)).thenReturn(factoredListMetadata);
when(factoredListMetadata.getLocalCode()).thenReturn(factoredListMetadataCode);
when(factoredListMetadata.getCode()).thenReturn(theSchemaCode + "_" + factoredListMetadataCode);
when(factoredListMetadata.getDataStoreType()).thenReturn("s");
when(factoredListMetadata.getDataStoreCode()).thenReturn(factoredListMetadataCodeAndType);
when(factoredListMetadata.getType()).thenReturn(MetadataValueType.STRING);
when(factoredListMetadata.isMultivalue()).thenReturn(true);
when(factoredListMetadata.getStructureFactory()).thenReturn((StructureFactory) stringStructureFactory);
when(factoredListMetadata.getDataEntry()).thenReturn(new ManualDataEntry());
}
@Test(expected = IllegalArgumentException.class)
public void cannotInstanciateRecordWithoutCode()
throws Exception {
new TestRecord((String) null, "zeCollection");
}
@Test(expected = UnsupportedOperationException.class)
public void cannotAddRemoveFieldValuesUsingGetModifiedValues()
throws Exception {
RecordImpl record = new TestRecord(theSchemaCode, "zeCollection");
record.getModifiedValues().clear();
}
@Test(expected = RecordRuntimeException.CannotModifyADisconnectedRecord.class)
public void givenDisconnectedRecordWhenSetMetadataValueThenException()
throws Exception {
RecordImpl record = new TestRecord(theSchemaCode, "zeCollection");
record.set(textMetadata, "theValue");
record.markAsDisconnected();
try {
record.set(textMetadata, "thisValueCannotBeSet");
} finally {
assertThat(record.get(textMetadata)).isEqualTo("theValue");
}
}
@Test(expected = RecordRuntimeException.RecordDTORequired.class)
public void cannotRefreshWithNullRecordDTO()
throws Exception {
RecordImpl record = new TestRecord(theSchemaCode, "zeCollection");
record.refresh(2, null);
}
@Test
public void whenRefreshingThenVersionAndDTOSet()
throws Exception {
RecordImpl record = new TestRecord(theSchemaCode, "zeCollection");
when(initialState.getId()).thenReturn(record.getId());
when(currentState.getId()).thenReturn(record.getId());
record.refresh(1, initialState);
assertThat(record.getVersion()).isEqualTo(1);
assertThat(record.getRecordDTO()).isEqualTo(initialState);
record.refresh(2, currentState);
assertThat(record.getVersion()).isEqualTo(2);
assertThat(record.getRecordDTO()).isEqualTo(currentState);
}
@Test
public void whenRefreshingThenClearChanges()
throws Exception {
RecordImpl record = new TestRecord(theSchemaCode, "zeCollection");
when(initialState.getId()).thenReturn(record.getId());
record.set(textMetadata, "value");
assertThat(record.get(textMetadata)).isEqualTo("value");
assertThat(record.isDirty()).isTrue();
record.refresh(1, initialState);
assertThat(record.get(textMetadata)).isNull();
assertThat(record.isDirty()).isFalse();
}
@Test
public void givenNewRecordWhenProducingRecordDTOThenProducedWithFieldValues() {
RecordImpl record = new TestRecord(theSchemaCode, "zeCollection");
record.set(multipleTextMetadata, asList("firstValue"));
record.set(dateMetadata, "secondValue");
when(copyfieldsPopulator.populateCopyfields(zeSchema, record))
.thenReturn(TestUtils.asMap("copiedField1", (Object) "copiedValue1", "copiedField2", "copiedValue2"));
when(copyfieldsPopulator2.populateCopyfields(zeSchema, record))
.thenReturn(TestUtils.asMap("copiedField3", (Object) "copiedValue3"));
MetadataList metadatas = new MetadataList(textMetadata, multipleTextMetadata, dateMetadata);
when(zeSchema.getMetadatas()).thenReturn(metadatas);
RecordDTO recordDTO = record
.toNewDocumentDTO(zeSchema, asList(copyfieldsPopulator, copyfieldsPopulator2));
assertThat(recordDTO.getId()).isNotNull();
assertThat(recordDTO.getLoadedFields()).isNull();
assertThat(recordDTO.getVersion()).isEqualTo(-1L);
assertThat(recordDTO.getFields()).containsOnly(
entry(multipleTextMetadataCodeAndType, asList("firstValue")),
entry(dateMetadataCodeAndType, "secondValue"),
entry("collection_s", "zeCollection"),
entry("schema_s", "a_b"));
assertThat(recordDTO.getCopyFields()).containsOnly(
entry("copiedField1", "copiedValue1"),
entry("copiedField2", "copiedValue2"),
entry("copiedField3", "copiedValue3"));
}
@Test
public void givenRecordWithModifiedValuesWhenVerifyingMetadataModifiedThenReturnsTrue() {
RecordImpl record = new TestRecord(theSchemaCode, "zeCollection");
record.set(dateMetadata, "secondValue");
assertThat(record.isModified(dateMetadata));
}
@Test
public void givenRecordWithoutModifiedValuesWhenVerifyingMetadataModifiedThenReturnsFalse() {
RecordImpl record = new TestRecord(theSchemaCode, "zeCollection");
assertThat(record.isModified(dateMetadata)).isFalse();
}
@Test(expected = RecordRuntimeException.RecordIsAlreadySaved.class)
public void givenSavedRecordWhenProducingRecordDTOThenProducedWithFieldValuesAndCurrentDTO() {
Map<String, Object> fields = newSchemaFields();
fields.put(multipleTextMetadataCodeAndType, asList("thisValueWillBeReplaced"));
fields.put(multipleBooleanMetadataCodeAndType, asList("thirdValue"));
RecordDTO savedRecordDTO = new RecordDTO("zeOldId", 1L, null, fields);
RecordImpl record = new TestRecord(theSchemaCode, "zeCollection");
record.refresh(1L, savedRecordDTO);
record.set(multipleTextMetadata, asList("firstValue"));
record.set(dateMetadata, "secondValue");
MetadataList metadatas = new MetadataList(textMetadata, multipleTextMetadata, dateMetadata);
when(zeSchema.getMetadatas()).thenReturn(metadatas);
record.toNewDocumentDTO(zeSchema, asList(copyfieldsPopulator, copyfieldsPopulator2));
}
@Test
public void givenValueEqualToRecordDTOWhenSettingMetadataThenNotAddedToModifiedValuesNotDirty()
throws Exception {
Map<String, Object> fields = newSchemaFields();
fields.put(multipleTextMetadataCodeAndType, asList("firstValue"));
RecordImpl record = new TestRecord(theSchemaCode, "zeCollection");
RecordDTO savedRecordDTO = new RecordDTO(record.getId(), 1L, null, fields);
record.refresh(1L, savedRecordDTO);
record.set(multipleTextMetadata, asList("firstValue"));
assertThat(record.isDirty()).isFalse();
assertThat(record.getModifiedValues()).isEmpty();
assertThat(record.get(multipleTextMetadata)).isEqualTo(asList("firstValue"));
}
@Test
public void whenSettingDifferentValueThenAddedToModifiedValueAndRecordBecomeDirty()
throws Exception {
Map<String, Object> fields = newSchemaFields();
fields.put(multipleTextMetadataCodeAndType, asList("firstValue"));
RecordImpl record = new TestRecord(theSchemaCode, "zeCollection");
RecordDTO savedRecordDTO = new RecordDTO(record.getId(), 1L, null, fields);
record.refresh(1L, savedRecordDTO);
record.set(multipleTextMetadata, asList("otherValueValue"));
assertThat(record.isDirty()).isTrue();
assertThat(record.getModifiedValues()).hasSize(1);
assertThat(record.get(multipleTextMetadata)).isEqualTo(asList("otherValueValue"));
}
@Test
public void givenMetadataModifiedWhenSettingOriginalValueThenModifiedValueRemovedNotDirtyAnymore()
throws Exception {
Map<String, Object> fields = newSchemaFields();
fields.put(multipleTextMetadataCodeAndType, asList("firstValue"));
RecordImpl record = new TestRecord(theSchemaCode, "zeCollection");
RecordDTO savedRecordDTO = new RecordDTO(record.getId(), 1L, null, fields);
record.refresh(1L, savedRecordDTO);
record.set(multipleTextMetadata, asList("otherValueValue"));
record.set(multipleTextMetadata, asList("firstValue"));
assertThat(record.isDirty()).isFalse();
assertThat(record.getModifiedValues()).isEmpty();
assertThat(record.get(multipleTextMetadata)).isEqualTo(asList("firstValue"));
}
@Test
public void whenProducingDeltaRecordDTOThenReturnModifications()
throws Exception {
RecordImpl record = new TestRecord(theSchemaCode, "zeCollection");
Map<String, Object> fields = newSchemaFields();
fields.put(multipleTextMetadataCodeAndType, asList("firstValue"));
fields.put(multipleBooleanMetadataCodeAndType, asList("thirdValue"));
when(copyfieldsPopulator.populateCopyfields(zeSchema, record))
.thenReturn(TestUtils.asMap("copiedField1", (Object) "copiedValue1", "copiedField2", "copiedValue2"));
when(copyfieldsPopulator2.populateCopyfields(zeSchema, record))
.thenReturn(TestUtils.asMap("copiedField3", (Object) "copiedValue3"));
RecordDTO savedRecordDTO = new RecordDTO(record.getId(), 1L, null, fields);
record.refresh(1L, savedRecordDTO);
record.set(multipleTextMetadata, asList("firstValue"));
record.set(dateMetadata, "secondValue");
record.set(multipleBooleanMetadata, null);
RecordDeltaDTO deltaDTO = record
.toRecordDeltaDTO(zeSchema, asList(copyfieldsPopulator, copyfieldsPopulator2));
assertThat(deltaDTO.getId()).isEqualTo(record.getId());
assertThat(deltaDTO.getFromVersion()).isEqualTo(1L);
assertThat(deltaDTO.getModifiedFields()).hasSize(2).containsEntry(dateMetadataCodeAndType, "secondValue")
.containsEntry(multipleBooleanMetadataCodeAndType, null);
assertThat(deltaDTO.getCopyfields()).hasSize(3).containsEntry("copiedField1",
"copiedValue1").containsEntry("copiedField2", "copiedValue2").containsEntry("copiedField3", "copiedValue3");
}
@Test
public void whenCreatingRecordWithSchemaCodeThenCanBeObtainedWithGetSchemaCode()
throws Exception {
Record record = new TestRecord("a_b", "zeCollection");
assertThat(record.getSchemaCode()).isEqualTo("a_b");
}
@Test(expected = RecordRuntimeException.RequiredMetadataArgument.class)
public void whenSettingWithNullMetadataThenException()
throws Exception {
Record record = new TestRecord("a_b", "zeCollection");
record.set(null, "zeValue");
}
@Test(expected = RecordRuntimeException.CannotSetCollectionInSingleValueMetadata.class)
public void whenSettingAListValueInSingleValueMetadataThenException()
throws Exception {
Record record = new TestRecord("a_b", "zeCollection");
record.set(textMetadata, asList("a", "b"));
}
@Test(expected = RecordRuntimeException.CannotSetNonListValueInMultivalueMetadata.class)
public void whenSettingASingleValueInMultivalueMetadataThenException()
throws Exception {
Record record = new TestRecord("a_b", "zeCollection");
record.set(multipleTextMetadata, "aValue");
}
@Test(expected = RecordRuntimeException.RequiredMetadataArgument.class)
public void whenGettingWithNullMetadataThenException()
throws Exception {
Record record = new TestRecord("a_b", "zeCollection");
record.get(null);
}
@Test(expected = RecordRuntimeException.CannotSetManualValueInAutomaticField.class)
public void whenSettingValueInCopiedMetadataThenException()
throws Exception {
Record record = new TestRecord("a_b", "zeCollection");
record.set(copyMetadata, "manualValue");
}
@Test(expected = RecordRuntimeException.CannotSetManualValueInAutomaticField.class)
public void whenSettingValueInCalculatedMetadataThenException()
throws Exception {
Record record = new TestRecord("a_b", "zeCollection");
record.set(calculatedMetadata, "manualValue");
}
@Test
public void givenNullWasSetToMultivalueMetadataWhenCallingGetterThenReturnUnmodifiableEmptyList()
throws Exception {
Record record = new TestRecord("a_b", "zeCollection");
record.set(multipleTextMetadata, null);
assertThat(record.get(multipleTextMetadata)).isEqualTo(new ArrayList<>());
assertThat(record.get(multipleTextMetadata)).is(unmodifiableCollection());
assertThat(record.getList(multipleTextMetadata)).isEqualTo(new ArrayList<>());
assertThat(record.getList(multipleTextMetadata)).is(unmodifiableCollection());
}
@Test
public void givenModifiableListWasSetToMultivalueMetadataWhenCallingGetterThenReturnUnmodifiableEmptyList()
throws Exception {
Record record = new TestRecord("a_b", "zeCollection");
record.set(multipleTextMetadata, new ArrayList<>(asList("a", "b")));
assertThat(record.get(multipleTextMetadata)).isEqualTo(asList("a", "b"));
assertThat(record.get(multipleTextMetadata)).is(unmodifiableCollection());
assertThat(record.getList(multipleTextMetadata)).isEqualTo(asList("a", "b"));
assertThat(record.getList(multipleTextMetadata)).is(unmodifiableCollection());
}
@Test
public void givenNullWasSetToMultivalueMetadataWhenCallingGetterThenReturnEmptyList()
throws Exception {
Record record = new TestRecord("a_b", "zeCollection");
record.set(multipleTextMetadata, new ArrayList<>());
assertThat(record.get(multipleTextMetadata));
assertThat(record.getList(multipleTextMetadata)).isEqualTo(new ArrayList<>());
}
@Test
public void givenRecordModifiedWhenMergingThenMergeSuccessful()
throws Exception {
Map<String, Object> initialStateFields = new HashMap<>();
initialStateFields.put("schema_s", "zeSchemaType_default");
initialStateFields.put("collection_s", "zeCollection");
when(initialState.getFields()).thenReturn(initialStateFields);
RecordImpl record = new TestRecord(initialState);
Map<String, Object> currentStateFields = new HashMap<>();
currentStateFields.put(textMetadataCodeAndType, "differentValue");
currentStateFields.put("schema_s", "zeSchemaType_default");
currentStateFields.put("collection_s", "zeCollection");
when(currentState.getFields()).thenReturn(currentStateFields);
RecordImpl newRecord = new TestRecord(currentState);
record.merge(newRecord, zeSchema);
assertThat(record.getVersion()).isEqualTo(newRecord.getVersion());
assertThat(record.getRecordDTO()).isEqualTo(currentState);
assertThat(record.isDirty()).isFalse();
assertThat(record.getModifiedValues()).doesNotContainKey(textMetadataCodeAndType);
assertThat(record.get(textMetadata)).isEqualTo("differentValue");
}
@Test(expected = CannotMerge.class)
public void givenRecordsConflictingWhenMergingThenExceptionThrown()
throws Exception {
Map<String, Object> initialStateFields = new HashMap<>();
initialStateFields.put("collection_s", "zeCollection");
initialStateFields.put(textMetadataCodeAndType, "aValue");
initialStateFields.put("schema_s", theSchemaCode);
when(initialState.getFields()).thenReturn(initialStateFields);
RecordImpl record = new TestRecord(initialState);
Map<String, Object> currentStateFields = new HashMap<>();
currentStateFields.put("collection_s", "zeCollection");
currentStateFields.put(textMetadataCodeAndType, "differentValue");
currentStateFields.put("schema_s", theSchemaCode);
when(currentState.getFields()).thenReturn(currentStateFields);
RecordImpl newRecord = new TestRecord(currentState);
record.set(textMetadata, "changedValue");
record.merge(newRecord, zeSchema);
}
@Test
public void whenMergingRecordWithTwoModifiedFieldsThenMerged()
throws Exception {
Map<String, Object> initialStateFields = new HashMap<>();
initialStateFields.put("schema_s", "zeSchemaType_default");
initialStateFields.put("collection_s", "zeCollection");
when(initialState.getFields()).thenReturn(initialStateFields);
RecordImpl record = new TestRecord(initialState);
Map<String, Object> currentStateFields = new HashMap<>();
currentStateFields.put("schema_s", "zeSchemaType_default");
currentStateFields.put("collection_s", "zeCollection");
currentStateFields.put(textMetadataCodeAndType, "differentValue");
currentStateFields.put(dateMetadataCodeAndType, new LocalDateTime(2014, 8, 15, 11, 2));
when(currentState.getFields()).thenReturn(currentStateFields);
RecordImpl newRecord = new TestRecord(currentState);
record.merge(newRecord, zeSchema);
assertThat(record.getVersion()).isEqualTo(newRecord.getVersion());
assertThat(record.getRecordDTO()).isEqualTo(currentState);
assertThat(record.getModifiedValues()).doesNotContainKey(textMetadataCodeAndType);
assertThat(record.getModifiedValues()).doesNotContainKey(dateMetadataCodeAndType);
assertThat(record.isDirty()).isFalse();
assertThat(record.get(textMetadata)).isEqualTo("differentValue");
assertThat(record.get(dateMetadata)).isEqualTo(new LocalDateTime(2014, 8, 15, 11, 2));
}
@Test
public void whenMergingRecordWithThenMergeFieldsCorrectly()
throws Exception {
Map<String, Object> initialStateFields = new HashMap<>();
initialStateFields.put("schema_s", theSchemaCode);
initialStateFields.put("collection_s", "zeCollection");
when(initialState.getFields()).thenReturn(initialStateFields);
RecordImpl record = new TestRecord(initialState);
Map<String, Object> currentStateFields = new HashMap<>();
currentStateFields.put("schema_s", theSchemaCode);
currentStateFields.put("collection_s", "zeCollection");
currentStateFields.put(textMetadataCodeAndType, "modifiedValue");
currentStateFields.put(dateMetadataCodeAndType, new LocalDateTime(2013, 8, 15, 11, 2));
when(currentState.getFields()).thenReturn(currentStateFields);
RecordImpl newRecord = new TestRecord(currentState);
record.set(textMetadata, "modifiedValue");
record.set(numberMetadata, 42.0);
record.merge(newRecord, zeSchema);
assertThat(record.getVersion()).isEqualTo(newRecord.getVersion());
assertThat(record.getRecordDTO()).isEqualTo(currentState);
assertThat(record.getModifiedValues()).doesNotContainKey(textMetadataCodeAndType);
assertThat(record.getModifiedValues()).doesNotContainKey(dateMetadataCodeAndType);
assertThat(record.getModifiedValues()).containsEntry(numberMetadataCodeAndType, 42.0);
assertThat(record.isDirty()).isTrue();
assertThat(record.get(textMetadata)).isEqualTo("modifiedValue");
assertThat(record.get(dateMetadata)).isEqualTo(new LocalDateTime(2013, 8, 15, 11, 2));
}
@Test(expected = CannotMerge.class)
public void givenRecordsWithTwoFieldsConflictingOnOneWhenMergingThenExceptionThrown()
throws Exception {
Map<String, Object> initialStateFields = new HashMap<>();
initialStateFields.put(textMetadataCodeAndType, "aValue");
initialStateFields.put(dateMetadataCodeAndType, new LocalDateTime(2014, 8, 15, 11, 2));
initialStateFields.put("schema_s", "a_b");
initialStateFields.put("collection_s", "zeCollection");
when(initialState.getFields()).thenReturn(initialStateFields);
RecordImpl record = new TestRecord(initialState);
Map<String, Object> currentStateFields = new HashMap<>();
currentStateFields.put(textMetadataCodeAndType, "differentValue");
currentStateFields.put(dateMetadataCodeAndType, new LocalDateTime(2014, 8, 15, 11, 2));
currentStateFields.put("schema_s", "a_b");
currentStateFields.put("collection_s", "zeCollection");
when(currentState.getFields()).thenReturn(currentStateFields);
RecordImpl newRecord = new TestRecord(currentState);
record.set(textMetadata, "changedValue");
record.merge(newRecord, zeSchema);
}
@Test(expected = RecordRuntimeException.InvalidMetadata.class)
public void givenRecordOfSchemaTypeA_CustomWhenSetB_CustomMetadataThenException()
throws Exception {
Metadata metadata = mockMetadata("b_custom_m");
RecordImpl record = new TestRecord("a_custom", "zeCollection");
record.set(metadata, "1");
}
@Test(expected = RecordRuntimeException.InvalidMetadata.class)
public void givenRecordOfSchemaTypeA_DefaultWhenSetA_CustomMetadataThenException()
throws Exception {
Metadata metadata = mockMetadata("b_custom_m");
RecordImpl record = new TestRecord("a_default", "zeCollection");
record.set(metadata, "1");
}
@Test(expected = RecordRuntimeException.InvalidMetadata.class)
public void givenRecordOfSchemaTypeA_CustomWhenSetWithNullCodeThenException()
throws Exception {
Metadata metadata = mock(Metadata.class);
when(metadata.getCode()).thenReturn(null);
RecordImpl record = new TestRecord("a_custom", "zeCollection");
record.set(metadata, "1");
}
@Test
public void givenARecordsWithTwoEqualFieldsWhenMergingThenDoNottNeedToMerge()
throws Exception {
Map<String, Object> initialStateFields = new HashMap<>();
initialStateFields.put("schema_s", "zeSchemaType_default");
initialStateFields.put("collection_s", "zeCollection");
initialStateFields.put(textMetadataCodeAndType, "aValue");
initialStateFields.put(dateMetadataCodeAndType, new LocalDateTime(2014, 8, 15, 11, 2));
when(initialState.getFields()).thenReturn(initialStateFields);
RecordImpl record = new TestRecord(initialState);
assertThat(record.get(textMetadata)).isEqualTo("aValue");
Map<String, Object> currentStateFields = new HashMap<>();
currentStateFields.put("schema_s", "zeSchemaType_default");
currentStateFields.put("collection_s", "zeCollection");
currentStateFields.put(textMetadataCodeAndType, "aValue");
currentStateFields.put(dateMetadataCodeAndType, new LocalDateTime(2014, 8, 15, 11, 2));
when(currentState.getFields()).thenReturn(currentStateFields);
RecordImpl newRecord = new TestRecord(currentState);
record.merge(newRecord, zeSchema);
assertThat(record.getRecordDTO()).isEqualTo(currentState);
assertThat(record.get(textMetadata)).isEqualTo("aValue");
assertThat(record.isDirty()).isFalse();
assertThat(record.getModifiedValues()).hasSize(0);
}
@Test
public void givenRecordsWithSameValuesAndNumberTypesWhenMergingThenDoNotNeedToMerge()
throws Exception {
Map<String, Object> initialStateFields = new HashMap<>();
initialStateFields.put("schema_s", "zeSchemaType_default");
initialStateFields.put("collection_s", "zeCollection");
initialStateFields.put(numberMetadataCodeAndType, 20);
initialStateFields.put(otherNumberMetadataCodeAndType, 10.0);
when(initialState.getFields()).thenReturn(initialStateFields);
RecordImpl record = new TestRecord(initialState);
Map<String, Object> currentStateFields = new HashMap<>();
currentStateFields.put("schema_s", "zeSchemaType_default");
currentStateFields.put("collection_s", "zeCollection");
currentStateFields.put(numberMetadataCodeAndType, 20);
currentStateFields.put(otherNumberMetadataCodeAndType, 10.0);
when(currentState.getFields()).thenReturn(currentStateFields);
RecordImpl newRecord = new TestRecord(currentState);
record.merge(newRecord, zeSchema);
assertThat(record.getRecordDTO()).isEqualTo(currentState);
assertThat(record.get(numberMetadata)).isEqualTo(20);
assertThat(record.get(otherNumberMetadata)).isEqualTo(10.0);
assertThat(record.isDirty()).isFalse();
assertThat(record.getModifiedValues()).hasSize(0);
}
@Test
public void givenRecordsWithSameValuesAndDifferentNumberTypesWhenMergingThenDoNotNeedToMerge()
throws Exception {
Map<String, Object> initialStateFields = new HashMap<>();
initialStateFields.put("schema_s", "zeSchemaType_default");
initialStateFields.put("collection_s", "zeCollection");
initialStateFields.put(numberMetadataCodeAndType, 20);
initialStateFields.put(otherNumberMetadataCodeAndType, 10.0);
when(initialState.getFields()).thenReturn(initialStateFields);
RecordImpl record = new TestRecord(initialState);
Map<String, Object> currentStateFields = new HashMap<>();
currentStateFields.put("schema_s", "zeSchemaType_default");
currentStateFields.put("collection_s", "zeCollection");
currentStateFields.put(numberMetadataCodeAndType, 20.0);
currentStateFields.put(otherNumberMetadataCodeAndType, 10.0);
when(currentState.getFields()).thenReturn(currentStateFields);
RecordImpl newRecord = new TestRecord(currentState);
record.merge(newRecord, zeSchema);
assertThat(record.getRecordDTO()).isEqualTo(currentState);
assertThat(record.get(numberMetadata)).isEqualTo(20.0);
assertThat(record.get(otherNumberMetadata)).isEqualTo(10.0);
assertThat(record.isDirty()).isFalse();
assertThat(record.getModifiedValues()).hasSize(0);
}
@Test
public void givenRecordsWithSameValuesAndDifferentNumberTypesWhenSetAndMergingThenDoNotNeedToMerge()
throws Exception {
Map<String, Object> initialStateFields = new HashMap<>();
initialStateFields.put(numberMetadataCodeAndType, 20.0);
initialStateFields.put("schema_s", "a_b");
initialStateFields.put("collection_s", "zeCollection");
when(initialState.getFields()).thenReturn(initialStateFields);
RecordImpl record = new TestRecord(initialState);
record.set(numberMetadata, 20);
Map<String, Object> currentStateFields = new HashMap<>();
currentStateFields.put(numberMetadataCodeAndType, 20.0);
currentStateFields.put("schema_s", "a_b");
currentStateFields.put("collection_s", "zeCollection");
when(currentState.getFields()).thenReturn(currentStateFields);
RecordImpl newRecord = new TestRecord(currentState);
record.merge(newRecord, zeSchema);
assertThat(record.getRecordDTO()).isEqualTo(currentState);
assertThat(record.get(numberMetadata)).isEqualTo(20.0);
assertThat(record.isDirty()).isFalse();
assertThat(record.getModifiedValues()).hasSize(0);
}
@Test()
public void givenOnlyOneNonNullValueInListWhenGettingNonNullValueThenRightValueReturned()
throws Exception {
RecordImpl record = new TestRecord(theSchemaCode, "zeCollection");
record.set(textMetadata, null);
record.set(dateMetadata, null);
record.set(numberMetadata, 5.0);
assertThat(record.getNonNullValueIn(asList(textMetadata, dateMetadata, numberMetadata))).isEqualTo(5.0);
}
@Test(expected = RuntimeException.class)
public void givenMultipleNonNullValuesInListWhenGettingNonNullValueThenRightValueReturned()
throws Exception {
RecordImpl record = new TestRecord(theSchemaCode, "zeCollection");
record.set(textMetadata, "aValue");
record.set(dateMetadata, null);
record.set(numberMetadata, 5.0);
assertThat(record.getNonNullValueIn(asList(textMetadata, dateMetadata, numberMetadata))).isEqualTo(5.0);
}
@Test
public void givenAllNullValuesInListWhenGettingNonNullValueThenNullReturned()
throws Exception {
RecordImpl record = new TestRecord(theSchemaCode, "zeCollection");
record.set(textMetadata, null);
record.set(dateMetadata, null);
record.set(numberMetadata, null);
assertThat(record.getNonNullValueIn(asList(textMetadata, dateMetadata, numberMetadata))).isNull();
}
@Test
public void whenGettingListForMetadataThenCorrectValueReturned() {
RecordImpl record = new TestRecord(theSchemaCode, "zeCollection");
record.set(multipleTextMetadata, asList("value1", "value2", "value3"));
assertThat(record.getList(multipleTextMetadata)).containsOnly("value1", "value2", "value3");
}
@Test
public void whenGettingListForNullMetadataThenEmptyListReturned() {
RecordImpl record = new TestRecord(theSchemaCode, "zeCollection");
record.set(multipleTextMetadata, null);
assertThat(record.getList(multipleTextMetadata)).isEmpty();
}
@Test(expected = RecordImplRuntimeException.CannotGetListForSingleValue.class)
public void whenGettingListForSingleValueMetadataThenWhat() {
RecordImpl record = new TestRecord(theSchemaCode, "zeCollection");
record.set(textMetadata, "value");
record.getList(textMetadata);
}
@Test
public void givenNewRecordSavedWhenSetNewVersionThenSetNewDocumentDTOWithVersion() {
RecordImpl record = new TestRecord(theSchemaCode, "zeCollection");
record.set(multipleTextMetadata, asList("value1", "value2", "value3"));
record.set(numberMetadata, 123);
assertThat(record.isModified(multipleTextMetadata)).isTrue();
assertThat(record.isModified(numberMetadata)).isTrue();
record.markAsSaved(42, zeSchema);
assertThat(record.isModified(multipleTextMetadata)).isFalse();
assertThat(record.isModified(numberMetadata)).isFalse();
assertThat(record.getVersion()).isEqualTo(42L);
assertThat(record.get(multipleTextMetadata)).isEqualTo(asList("value1", "value2", "value3"));
assertThat(record.get(numberMetadata)).isEqualTo(123.0);
assertThat(record.getModifiedValues()).isEmpty();
}
@Test
public void givenModifiedRecordSavedWhenSetNewVersionThenSetNewDocumentDTOWithVersion() {
LocalDate date = new LocalDate();
List<String> loadedFields = asList(multipleTextMetadataCodeAndType, numberMetadataCodeAndType);
Map<String, Object> fieldValues = new HashMap<>();
fieldValues.put(multipleTextMetadata.getDataStoreCode(), asList("value1", "value2", "value3"));
fieldValues.put(numberMetadata.getDataStoreCode(), 123.0);
fieldValues.put(dateMetadata.getDataStoreCode(), date);
fieldValues.put("schema_s", theSchemaCode);
fieldValues.put("collection_s", "zeCollection");
RecordDTO recordDTO = new RecordDTO("id", 4, loadedFields, fieldValues);
RecordImpl record = new TestRecord(recordDTO);
record.set(multipleTextMetadata, asList("value4", "value5", "value6"));
record.set(numberMetadata, 456);
assertThat(record.isModified(multipleTextMetadata)).isTrue();
assertThat(record.isModified(numberMetadata)).isTrue();
record.markAsSaved(42, zeSchema);
assertThat(record.isModified(multipleTextMetadata)).isFalse();
assertThat(record.isModified(numberMetadata)).isFalse();
assertThat(record.getVersion()).isEqualTo(42L);
assertThat(record.get(multipleTextMetadata)).isEqualTo(asList("value4", "value5", "value6"));
assertThat(record.get(numberMetadata)).isEqualTo(456.0);
assertThat(record.get(dateMetadata)).isEqualTo(date);
assertThat(record.getModifiedValues()).isEmpty();
assertThat(record.getRecordDTO().getLoadedFields()).isEqualTo(loadedFields);
}
@Test
public void givenSingleValueMetadataWithStructureFactoryWhenGetValueThenBuildObjectUsingStructure()
throws Exception {
when(stringStructureFactory.build(zeStructureInitialValue)).thenReturn(zeStructure);
Map<String, Object> fieldValues = newMap("zeCollection", theSchemaCode);
fieldValues.put(factoredMetadataCodeAndType, zeStructureInitialValue);
RecordImpl record = new TestRecord(new RecordDTO("id", 4, null, fieldValues));
assertThat(record.isDirty()).isFalse();
assertThat(record.getModifiedValues()).isEmpty();
verify(stringStructureFactory, never()).build(zeStructureInitialValue);
assertThat(record.get(factoredMetadata)).isSameAs(zeStructure);
assertThat(record.get(factoredMetadata)).isSameAs(zeStructure);
verify(stringStructureFactory, times(1)).build(zeStructureInitialValue);
}
@Test
public void givenMultivalueMetadataWithStructureFactoryWhenGetValueThenBuildObjectUsingStructure()
throws Exception {
when(stringStructureFactory.build(zeStructureInitialValue)).thenReturn(zeStructure);
when(stringStructureFactory.build(anotherStructureInitialValue)).thenReturn(anotherStructure);
Map<String, Object> fieldValues = newMap("zeCollection", theSchemaCode);
fieldValues.put(factoredMetadataCodeAndType, asList(zeStructureInitialValue, anotherStructureInitialValue));
RecordImpl record = new TestRecord(new RecordDTO("id", 4, null, fieldValues));
assertThat(record.isDirty()).isFalse();
assertThat(record.getModifiedValues()).isEmpty();
verify(stringStructureFactory, never()).build(zeStructureInitialValue);
verify(stringStructureFactory, never()).build(anotherStructureInitialValue);
assertThat(record.get(factoredMetadata)).isSameAs(record.get(factoredMetadata))
.isEqualTo(asList(zeStructure, anotherStructure));
verify(stringStructureFactory, times(1)).build(zeStructureInitialValue);
verify(stringStructureFactory, times(1)).build(anotherStructureInitialValue);
}
@Test
public void givenFactoredSingleValueMetadataModifiedThenRecordIsDirtyAndValueInModifiedValues()
throws Exception {
when(stringStructureFactory.build(zeStructureInitialValue)).thenReturn(zeStructure);
when(stringStructureFactory.toString(zeStructure)).thenReturn(zeStructureModifiedValue);
Map<String, Object> fieldValues = newMap("zeCollection", theSchemaCode);
fieldValues.put(factoredMetadataCodeAndType, zeStructureInitialValue);
RecordImpl record = new TestRecord(new RecordDTO("id", 4, null, fieldValues));
assertThat(record.get(factoredMetadata)).isSameAs(zeStructure);
when(zeStructure.isDirty()).thenReturn(true);
assertThat(record.isDirty()).isTrue();
assertThat(record.getModifiedValues()).containsEntry(factoredMetadataCodeAndType, zeStructure).hasSize(1);
assertThat(
record.toRecordDeltaDTO(zeSchema, asList(copyfieldsPopulator)).getModifiedFields())
.containsEntry(factoredMetadataCodeAndType, zeStructureModifiedValue).hasSize(1);
verify(copyfieldsPopulator).populateCopyfields(zeSchema, record);
}
@Test
public void givenNewFactoredSingleValueMetadataThenRecordIsDirtyAndValueInModifiedValues()
throws Exception {
when(stringStructureFactory.build(zeStructureInitialValue)).thenReturn(zeStructure);
when(stringStructureFactory.toString(zeStructure)).thenReturn(zeStructureModifiedValue);
when(stringStructureFactory.toString(anotherStructure)).thenReturn(anotherStructureInitialValue);
Map<String, Object> fieldValues = newMap("zeCollection", theSchemaCode);
fieldValues.put(factoredMetadataCodeAndType, zeStructureInitialValue);
RecordImpl record = new TestRecord(new RecordDTO("id", 4, null, fieldValues));
when(anotherStructure.isDirty()).thenReturn(true);
record.set(factoredMetadata, anotherStructure);
assertThat(record.get(factoredMetadata)).isSameAs(anotherStructure);
assertThat(record.isDirty()).isTrue();
assertThat(record.getModifiedValues()).containsEntry(factoredMetadataCodeAndType, anotherStructure).hasSize(1);
assertThat(record.toRecordDeltaDTO(zeSchema, asList(copyfieldsPopulator)).getModifiedFields())
.containsEntry(factoredMetadataCodeAndType, anotherStructureInitialValue).hasSize(1);
verify(copyfieldsPopulator).populateCopyfields(zeSchema, record);
}
@Test
public void givenFactoredSinglevalueInNewRecordWhenCreatingDtoThenStructureConvertedToString()
throws Exception {
when(stringStructureFactory.build(zeStructureInitialValue)).thenReturn(zeStructure);
when(stringStructureFactory.toString(zeStructure)).thenReturn(zeStructureModifiedValue);
when(stringStructureFactory.toString(anotherStructure)).thenReturn(anotherStructureInitialValue);
RecordImpl record = new TestRecord("a_b", "zeCollection");
when(anotherStructure.isDirty()).thenReturn(true);
record.set(factoredMetadata, anotherStructure);
assertThat(record.get(factoredMetadata)).isSameAs(anotherStructure);
assertThat(record.isDirty()).isTrue();
assertThat(record.getModifiedValues()).containsEntry(factoredMetadataCodeAndType, anotherStructure).hasSize(1);
assertThat(record.toNewDocumentDTO(zeSchema, asList(copyfieldsPopulator))
.getFields()).containsEntry(factoredMetadataCodeAndType, anotherStructureInitialValue);
verify(copyfieldsPopulator).populateCopyfields(zeSchema, record);
}
@Test
public void givenFactoredMultivalueMetadataModifiedThenRecordIsDirtyAndValueInModifiedValues()
throws Exception {
when(stringStructureFactory.build(zeStructureInitialValue)).thenReturn(zeStructure);
when(stringStructureFactory.build(anotherStructureInitialValue)).thenReturn(anotherStructure);
when(stringStructureFactory.toString(zeStructure)).thenReturn(zeStructureModifiedValue);
when(stringStructureFactory.toString(anotherStructure)).thenReturn(anotherStructureInitialValue);
when(stringStructureFactory.toString(aThirdStructure)).thenReturn(aThirdStructureInitialValue);
Map<String, Object> fieldValues = newMap("zeCollection", theSchemaCode);
fieldValues.put(factoredListMetadataCodeAndType, asList(zeStructureInitialValue, anotherStructureInitialValue));
RecordImpl record = new TestRecord(new RecordDTO("id", 4, null, fieldValues));
List<Object> values = record.get(factoredListMetadata);
assertThat(values).isEqualTo(asList(zeStructure, anotherStructure));
when(zeStructure.isDirty()).thenReturn(true);
assertThat(record.isDirty()).isTrue();
assertThat(record.getModifiedValues())
.containsEntry(factoredListMetadataCodeAndType, asList(zeStructure, anotherStructure)).hasSize(1);
assertThat(record.toRecordDeltaDTO(zeSchema, asList(copyfieldsPopulator)).getModifiedFields())
.containsEntry(factoredListMetadataCodeAndType,
asList(zeStructureModifiedValue, anotherStructureInitialValue)).hasSize(1);
verify(copyfieldsPopulator).populateCopyfields(zeSchema, record);
}
@Test
public void givenFactoredMultivalueInNewRecordWhenCreatingDtoThenStructureConvertedToString()
throws Exception {
when(stringStructureFactory.build(zeStructureInitialValue)).thenReturn(zeStructure);
when(stringStructureFactory.build(anotherStructureInitialValue)).thenReturn(anotherStructure);
when(stringStructureFactory.toString(zeStructure)).thenReturn(zeStructureInitialValue);
when(stringStructureFactory.toString(anotherStructure)).thenReturn(anotherStructureInitialValue);
when(stringStructureFactory.toString(aThirdStructure)).thenReturn(aThirdStructureInitialValue);
RecordImpl record = new TestRecord("a_b", "zeCollection");
record.set(factoredListMetadata, asList(zeStructure, anotherStructure));
List<Object> values = record.get(factoredListMetadata);
assertThat(values).isEqualTo(asList(zeStructure, anotherStructure));
when(zeStructure.isDirty()).thenReturn(true);
assertThat(record.toNewDocumentDTO(zeSchema, asList(copyfieldsPopulator))
.getFields())
.containsEntry(factoredListMetadataCodeAndType,
asList(zeStructureInitialValue, anotherStructureInitialValue));
verify(copyfieldsPopulator).populateCopyfields(zeSchema, record);
}
@Test
public void givenFactoredMultivalueMetadataAddRemovedThenRecordIsDirtyAndValueInModifiedValues()
throws Exception {
when(stringStructureFactory.build(zeStructureInitialValue)).thenReturn(zeStructure);
when(stringStructureFactory.build(anotherStructureInitialValue)).thenReturn(anotherStructure);
when(stringStructureFactory.toString(zeStructure)).thenReturn(zeStructureInitialValue);
when(stringStructureFactory.toString(anotherStructure)).thenReturn(anotherStructureInitialValue);
when(stringStructureFactory.toString(aThirdStructure)).thenReturn(aThirdStructureInitialValue);
Map<String, Object> fieldValues = newMap("zeCollection", theSchemaCode);
fieldValues.put(factoredListMetadataCodeAndType, asList(zeStructureInitialValue, anotherStructureInitialValue));
RecordImpl record = new TestRecord(new RecordDTO("id", 4, null, fieldValues));
record.set(factoredListMetadata, asList(zeStructure, aThirdStructure));
when(zeStructure.isDirty()).thenReturn(true);
assertThat(record.isDirty()).isTrue();
assertThat(record.getModifiedValues())
.containsEntry(factoredListMetadataCodeAndType, asList(zeStructure, aThirdStructure)).hasSize(1);
assertThat(record.toRecordDeltaDTO(zeSchema, asList(copyfieldsPopulator)).getModifiedFields())
.containsEntry(factoredListMetadataCodeAndType,
asList(zeStructureInitialValue, aThirdStructureInitialValue)).hasSize(1);
verify(copyfieldsPopulator).populateCopyfields(zeSchema, record);
}
private Map<String, Object> newMap(String collection, String theSchemaCode) {
Map<String, Object> fieldValues = new HashMap<>();
fieldValues.put("schema_s", theSchemaCode);
fieldValues.put("collection_s", "zeCollection");
return fieldValues;
}
@Test
public void givenNewRecordWithoutParentThenReturnNullParentId()
throws Exception {
RecordImpl record = new RecordImpl("a_b", "zeCollection", "zeId");
assertThat(record.getParentId()).isNull();
}
@Test
public void givenNewRecordWithParentThenReturnParentId()
throws Exception {
RecordImpl record = new RecordImpl("a_b", "zeCollection", "zeId");
record.modifiedValues.put("zeParentPId_s", "modifiedParentId");
assertThat(record.getParentId()).isEqualTo("modifiedParentId");
}
@Test
public void givenSavedRecordWithoutParentThenReturnNullParentId()
throws Exception {
RecordDTO recordDTO = new RecordDTO("id", 4, new ArrayList<String>(),
asMap("refId_s", (Object) 123, "collection_s", "zeCollection"));
RecordImpl record = new RecordImpl(recordDTO);
assertThat(record.getParentId()).isNull();
}
@Test
public void givenSavedRecordWithParentThenReturnParentId()
throws Exception {
RecordDTO recordDTO = new RecordDTO("id", 4, new ArrayList<String>(),
asMap("refId_s", (Object) 123, "collection_s", "zeCollection", "zeParentPId_s", "initialParentId"));
RecordImpl record = new RecordImpl(recordDTO);
assertThat(record.getParentId()).isEqualTo("initialParentId");
}
@Test
public void givenSavedRecordWithModifiedParentThenReturnModifiedParentId()
throws Exception {
RecordDTO recordDTO = new RecordDTO("id", 4, new ArrayList<String>(),
asMap("refId_s", (Object) 123, "collection_s", "zeCollection", "zeParentPId_s", "initialParentId"));
RecordImpl record = new RecordImpl(recordDTO);
record.modifiedValues.put("zeParentPId_s", "modifiedParentId");
assertThat(record.getParentId()).isEqualTo("modifiedParentId");
}
@Test
public void givenModifiedRecordWhenGetCopyOfOriginalRecordThenHasValuesFetchedFromServerAndNoModifications()
throws Exception {
RecordDTO recordDTO = new RecordDTO("id", 4, new ArrayList<String>(),
asMap("refId_s", (Object) 123, "collection_s", "zeCollection", "zeParentPId_s", "initialParentId"));
RecordImpl record = new RecordImpl(recordDTO);
record.modifiedValues.put("zeParentPId_s", "modifiedParentId");
assertThat(record.getParentId()).isEqualTo("modifiedParentId");
assertThat(record.getCopyOfOriginalRecord().getParentId()).isEqualTo("initialParentId");
}
@Test(expected = RecordImplException_UnsupportedOperationOnUnsavedRecord.class)
public void givenUnsavedRecordWhenGetCopyOfOriginalRecordThenException()
throws Exception {
RecordImpl record = new RecordImpl("folder_default", "zeUltimateCollection", "42");
record.getCopyOfOriginalRecord();
}
@Test
public void whenSerializingNewRecordThenCorrectlySerializedAndUnserialized() {
RecordImpl record = new RecordImpl("folder_default", "zeUltimateCollection", "42");
record.set(Schemas.TITLE, "zeTitle");
record.set(Schemas.MODIFIED_BY, shishOClock);
byte[] bytes = SerializationUtils.serialize(record);
RecordImpl unserializedRecord = (RecordImpl) SerializationUtils.deserialize(bytes);
assertThat(unserializedRecord.get(Schemas.TITLE)).isEqualTo("zeTitle");
assertThat(unserializedRecord.get(Schemas.MODIFIED_BY)).isEqualTo(shishOClock);
assertThat(unserializedRecord.getSchemaCode()).isEqualTo("folder_default");
assertThat(unserializedRecord.getCollection()).isEqualTo("zeUltimateCollection");
assertThat(unserializedRecord.getId()).isEqualTo("42");
assertThat(unserializedRecord.getVersion()).isEqualTo(-1);
assertThat(unserializedRecord.getRecordDTO()).isNull();
assertThat(unserializedRecord.getLoadedStructuredValues()).isNull();
}
@Test
public void whenSerializingModifiedRecordThenCorrectlySerializedAndUnserialized() {
List<String> loadedFields = TestUtils.asList("1", "2");
Map<String, Object> fields = new HashMap<>();
fields.put("schema_s", "folder_default");
fields.put("collection_s", "zeUltimateCollection");
fields.put("key1", "value1");
fields.put("key2", "value2");
Map<String, Object> copyFields = asMap("key3", (Object) "value3", "key4", "value4");
RecordDTO recordDTO = new RecordDTO("id42", 42, loadedFields, fields, copyFields);
RecordImpl record = new RecordImpl(recordDTO);
record.set(Schemas.TITLE, "zeTitle");
record.set(Schemas.MODIFIED_BY, shishOClock);
byte[] bytes = SerializationUtils.serialize(record);
RecordImpl unserializedRecord = (RecordImpl) SerializationUtils.deserialize(bytes);
assertThat(unserializedRecord.get(Schemas.TITLE)).isEqualTo("zeTitle");
assertThat(unserializedRecord.get(Schemas.MODIFIED_BY)).isEqualTo(shishOClock);
assertThat(unserializedRecord.getSchemaCode()).isEqualTo("folder_default");
assertThat(unserializedRecord.getCollection()).isEqualTo("zeUltimateCollection");
assertThat(unserializedRecord.getId()).isEqualTo("id42");
assertThat(unserializedRecord.getVersion()).isEqualTo(42);
assertThat(unserializedRecord.getRecordDTO().getId()).isEqualTo("id42");
assertThat(unserializedRecord.getRecordDTO().getVersion()).isEqualTo(42);
assertThat(unserializedRecord.getRecordDTO().getLoadedFields()).isEqualTo(loadedFields);
assertThat(unserializedRecord.getRecordDTO().getFields()).isEqualTo(fields);
assertThat(unserializedRecord.getRecordDTO().getCopyFields()).isEqualTo(copyFields);
assertThat(unserializedRecord.getLoadedStructuredValues()).isNull();
}
//TODO @Test
public void whenSettingCompatibleRawValueInMetadataWithInputMaskThenConvertIt()
throws Exception {
Metadata telephoneNumber = mockManualMetadata("zeType_default_telephoneNumber", MetadataValueType.STRING);
Metadata postalCode = mockManualMetadata("zeType_default_postalCode", MetadataValueType.STRING);
when(telephoneNumber.getDataStoreCode()).thenReturn("telephoneNumber_s");
when(telephoneNumber.getInputMask()).thenReturn("(###) ###-####");
when(postalCode.getDataStoreCode()).thenReturn("postalCode_s");
when(postalCode.getInputMask()).thenReturn("U#U #U#");
RecordImpl record = new RecordImpl("zeType_default", "zeCollection", "zeId");
record.set(telephoneNumber, "4183533390");
record.set(postalCode, "G1N2C9");
assertThat(record.get(telephoneNumber)).isEqualTo("(418) 353-3390");
assertThat(record.get(postalCode)).isEqualTo("G1N 2C9");
record.set(telephoneNumber, "4186664242");
record.set(postalCode, "H0H0H0");
assertThat(record.get(telephoneNumber)).isEqualTo("(418) 666-4242");
assertThat(record.get(postalCode)).isEqualTo("H0H 0H0");
}
@Test
public void whenSettingIncompatibleRawValueInMetadataWithInputMaskThenSetTheRawValue()
throws Exception {
Metadata telephoneNumber = mockManualMetadata("zeType_default_telephoneNumber", MetadataValueType.STRING);
Metadata postalCode = mockManualMetadata("zeType_default_postalCode", MetadataValueType.STRING);
when(telephoneNumber.getDataStoreCode()).thenReturn("telephoneNumber_s");
when(telephoneNumber.getInputMask()).thenReturn("(###) ###-####");
when(postalCode.getDataStoreCode()).thenReturn("postalCode_s");
when(postalCode.getInputMask()).thenReturn("U#U #U#");
RecordImpl record = new RecordImpl("zeType_default", "zeCollection", "zeId");
record.set(telephoneNumber, "418-353-3390");
record.set(postalCode, "G1Nyyy2C9");
assertThat(record.get(telephoneNumber)).isEqualTo("418-353-3390");
assertThat(record.get(postalCode)).isEqualTo("G1Nyyy2C9");
record.set(telephoneNumber, "(418y 666-4242");
record.set(postalCode, "H0H:0H0");
assertThat(record.get(telephoneNumber)).isEqualTo("(418y 666-4242");
assertThat(record.get(postalCode)).isEqualTo("H0H:0H0");
}
@Test
public void whenSettingFormattedValueInMetadataWithInputMaskThenSetTheValue()
throws Exception {
Metadata telephoneNumber = mockManualMetadata("zeType_default_telephoneNumber", MetadataValueType.STRING);
Metadata postalCode = mockManualMetadata("zeType_default_postalCode", MetadataValueType.STRING);
when(telephoneNumber.getDataStoreCode()).thenReturn("telephoneNumber_s");
when(telephoneNumber.getInputMask()).thenReturn("(###) ###-####");
when(postalCode.getDataStoreCode()).thenReturn("postalCode_s");
when(postalCode.getInputMask()).thenReturn("U#U #U#");
RecordImpl record = new RecordImpl("zeType_default", "zeCollection", "zeId");
record.set(telephoneNumber, "(418) 353-3390");
record.set(postalCode, "G1N 2C9");
assertThat(record.get(telephoneNumber)).isEqualTo("(418) 353-3390");
assertThat(record.get(postalCode)).isEqualTo("G1N 2C9");
record.set(telephoneNumber, "(418) 666-4242");
record.set(postalCode, "H0H 0H0");
assertThat(record.get(telephoneNumber)).isEqualTo("(418) 666-4242");
assertThat(record.get(postalCode)).isEqualTo("H0H 0H0");
}
Map<String, Object> newSchemaFields() {
Map<String, Object> fields = new HashMap<>();
fields.put("schema_s", theSchemaCode);
fields.put("collection_s", zeCollection);
return fields;
}
}