package com.constellio.model.services.schemas.builders;
import static com.constellio.sdk.tests.TestUtils.asList;
import static com.constellio.sdk.tests.TestUtils.onlyElementsOfClass;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Map;
import java.util.Set;
import com.constellio.model.entities.schemas.entries.CalculatedDataEntry;
import com.constellio.model.entities.schemas.entries.DataEntry;
import com.constellio.model.services.schemas.testimpl.TestMetadataValueCalculator;
import org.junit.Before;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import org.mockito.Mock;
import com.constellio.data.dao.services.DataStoreTypesFactory;
import com.constellio.model.entities.Language;
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.services.factories.ModelLayerFactory;
import com.constellio.model.services.schemas.MetadataList;
import com.constellio.model.services.schemas.SchemaUtils;
import com.constellio.model.services.schemas.builders.MetadataSchemaTypesBuilderRuntimeException.NoSuchSchemaType;
import com.constellio.model.services.schemas.testimpl.TestRecordValidator1;
import com.constellio.model.services.schemas.testimpl.TestRecordValidator2;
import com.constellio.model.services.taxonomies.TaxonomiesManager;
import com.constellio.model.utils.DefaultClassProvider;
import com.constellio.model.utils.DependencyUtils;
import com.constellio.model.utils.DependencyUtilsRuntimeException;
import com.constellio.sdk.tests.ConstellioTest;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class MetadataSchemaBuilderTest extends ConstellioTest {
@Mock MetadataSchemaTypesBuilder typesBuilder;
@Mock DataStoreTypesFactory typesFactory;
MetadataSchemaTypeBuilder metadataSchemaTypeBuilder;
MetadataSchemaBuilder defaultSchemaBuilder;
MetadataSchemaBuilder customSchemaBuilder;
MetadataSchema defaultSchema;
MetadataSchema customSchema;
@Mock ModelLayerFactory modelLayerFactory;
@Mock TaxonomiesManager taxonomiesManager;
@Mock Comparator<Metadata> metadataComparator;
@Before
public void setUp() {
when(modelLayerFactory.getTaxonomiesManager()).thenReturn(taxonomiesManager);
when(typesBuilder.getSchemaType(anyString())).thenThrow(NoSuchSchemaType.class);
when(typesBuilder.getLanguages()).thenReturn(Arrays.asList(Language.French));
when(typesBuilder.getClassProvider()).thenReturn(new DefaultClassProvider());
metadataSchemaTypeBuilder = MetadataSchemaTypeBuilder
.createNewSchemaType("zeUltimateCollection", "aSchemaType", typesBuilder);
defaultSchemaBuilder = spy(metadataSchemaTypeBuilder.getDefaultSchema());
customSchemaBuilder = metadataSchemaTypeBuilder.createCustomSchema("custom");
}
@Test
public void whenNewSchemaCreatedThenHasIdMetadata()
throws Exception {
MetadataBuilder metadataBuilder = defaultSchemaBuilder.get("id");
assertThat(metadataBuilder.isUndeletable()).isTrue();
assertThat(metadataBuilder.isSystemReserved()).isTrue();
assertThat(metadataBuilder.isUnmodifiable()).isTrue();
assertThat(metadataBuilder.isMultivalue()).isFalse();
assertThat(metadataBuilder.getType()).isSameAs(MetadataValueType.STRING);
assertThat(metadataBuilder.getLocalCode()).isEqualTo("id");
assertThat(metadataBuilder.getCode()).isEqualTo("aSchemaType_default_id");
assertThat(metadataBuilder.getEnabled()).isTrue();
assertThat(metadataBuilder.getDefaultRequirement()).isTrue();
}
@Test
public void whenNewSchemaCreatedThenHasSchemaMetadata()
throws Exception {
MetadataBuilder metadataBuilder = defaultSchemaBuilder.get("schema");
assertThat(metadataBuilder.isUndeletable()).isTrue();
assertThat(metadataBuilder.isSystemReserved()).isTrue();
assertThat(metadataBuilder.isUnmodifiable()).isFalse();
assertThat(metadataBuilder.isMultivalue()).isFalse();
assertThat(metadataBuilder.getType()).isSameAs(MetadataValueType.STRING);
assertThat(metadataBuilder.getLocalCode()).isEqualTo("schema");
assertThat(metadataBuilder.getCode()).isEqualTo("aSchemaType_default_schema");
assertThat(metadataBuilder.getEnabled()).isTrue();
assertThat(metadataBuilder.getDefaultRequirement()).isTrue();
}
@Test
public void whenNewSchemaCreatedThenHasPreviousSystemIdentifierMetadata()
throws Exception {
MetadataBuilder metadataBuilder = defaultSchemaBuilder.get("legacyIdentifier");
assertThat(metadataBuilder.isUndeletable()).isTrue();
assertThat(metadataBuilder.isSystemReserved()).isTrue();
assertThat(metadataBuilder.isUnmodifiable()).isTrue();
assertThat(metadataBuilder.isMultivalue()).isFalse();
assertThat(metadataBuilder.getType()).isSameAs(MetadataValueType.STRING);
assertThat(metadataBuilder.getLocalCode()).isEqualTo("legacyIdentifier");
assertThat(metadataBuilder.getCode()).isEqualTo("aSchemaType_default_legacyIdentifier");
assertThat(metadataBuilder.getEnabled()).isTrue();
assertThat(metadataBuilder.getDefaultRequirement()).isTrue();
}
@Test
public void givenCodeOfDefaultSchemaWhenBuildingThenSetToCorrectValue()
throws Exception {
build();
assertThat(defaultSchema.getLocalCode()).isEqualTo("default");
}
@Test
public void givenCodeOfDefaultSchemaWhenModifyingThenSetToCorrectValue()
throws Exception {
buildAndModify();
assertThat(defaultSchemaBuilder.getLocalCode()).isEqualTo("default");
}
@Test
public void givenCollectionOfDefaultSchemaWhenBuildingThenSetToCorrectValue()
throws Exception {
build();
assertThat(defaultSchema.getCollection()).isEqualTo("zeUltimateCollection");
}
@Test
public void givenCollectionOfDefaultSchemaWhenModifyingThenSetToCorrectValue()
throws Exception {
buildAndModify();
assertThat(defaultSchemaBuilder.getCollection()).isEqualTo("zeUltimateCollection");
}
@Test
public void givenCompleteCodeOfDefaultSchemaWhenBuildingThenSetToCorrectValue()
throws Exception {
build();
assertThat(defaultSchema.getCode()).isEqualTo("aSchemaType_default");
}
@Test
public void givenCompleteCodeOfDefaultSchemaWhenModifyingThenSetToCorrectValue()
throws Exception {
buildAndModify();
assertThat(defaultSchemaBuilder.getCode()).isEqualTo("aSchemaType_default");
}
@Test
public void givenCodeOfCustomSchemaWhenBuildingThenSetToCorrectValue()
throws Exception {
build();
assertThat(customSchema.getLocalCode()).isEqualTo("custom");
}
@Test
public void givenCodeOfCustomSchemaWhenModifyingThenSetToCorrectValue()
throws Exception {
buildAndModify();
assertThat(customSchemaBuilder.getLocalCode()).isEqualTo("custom");
}
@Test
public void givenCollectionOfCustomSchemaWhenBuildingThenSetToCorrectValue()
throws Exception {
build();
assertThat(customSchema.getCollection()).isEqualTo("zeUltimateCollection");
}
@Test
public void givenCollectionOfCustomSchemaWhenModifyingThenSetToCorrectValue()
throws Exception {
buildAndModify();
assertThat(customSchemaBuilder.getCollection()).isEqualTo("zeUltimateCollection");
}
@Test
public void givenCompleteCodeOfCustomSchemaWhenBuildingThenSetToCorrectValue()
throws Exception {
build();
assertThat(customSchema.getCode()).isEqualTo("aSchemaType_custom");
}
@Test
public void givenCompleteCodeOfCustomSchemaWhenModifyingThenSetToCorrectValue()
throws Exception {
build();
assertThat(customSchemaBuilder.getCode()).isEqualTo("aSchemaType_custom");
}
@Test
public void givenLabelOfDefaultSchemaIsNullAndLabelOfSchemaTypeIsDefinedWhenBuildingThenSetToSchemaTypeLabel() {
defaultSchemaBuilder.addLabel(Language.French, null);
metadataSchemaTypeBuilder.addLabel(Language.French, "Type");
build();
assertThat(defaultSchema.getLabel(Language.French)).isEqualTo("Type");
}
@Test
public void givenLabelOfDefaultSchemaIsNullAndLabelOfSchemaTypeIsNullWhenBuildingThenSetToSchemaTypeCode() {
defaultSchemaBuilder.addLabel(Language.French, null);
build();
assertThat(defaultSchema.getLabel(Language.French)).isEqualTo("aSchemaType");
}
@Test
public void givenLabelOfCustomSchemaIsNullWhenBuildingThenSetToSchemaCode() {
customSchemaBuilder.addLabel(Language.French, null);
build();
assertThat(customSchema.getLabel(Language.French)).isEqualTo("custom");
}
@Test
public void givenLabelOfDefaultSchemaIsDefinedWhenBuildingThenSetToDefinedValue() {
defaultSchemaBuilder.addLabel(Language.French, "aName");
build();
assertThat(defaultSchema.getLabel(Language.French)).isEqualTo("aName");
}
@Test
public void givenLabelOfDefaultSchemaIsDefinedWhenModifyingThenSetToDefinedValue() {
defaultSchemaBuilder.addLabel(Language.French, "aName");
buildAndModify();
assertThat(defaultSchemaBuilder.getLabel(Language.French)).isEqualTo("aName");
}
@Test
public void givenLabelOfCustomSchemaIsDefinedWhenBuildingThenSetToDefinedValue() {
defaultSchemaBuilder.addLabel(Language.French, "zeDefaultSchemaName");
customSchemaBuilder.addLabel(Language.French, "aName");
build();
assertThat(customSchema.getLabel(Language.French)).isEqualTo("aName");
}
@Test
public void givenLabelOfCustomSchemaIsDefinedWhenModifyingThenSetToDefinedValue() {
defaultSchemaBuilder.addLabel(Language.French, "zeDefaultSchemaName");
customSchemaBuilder.addLabel(Language.French, "aName");
buildAndModify();
assertThat(customSchemaBuilder.getLabel(Language.French)).isEqualTo("aName");
}
@Test(expected = MetadataSchemaBuilderRuntimeException.InvalidAttribute.class)
public void whenCreatingCustomSchemaWithNullCodeThenException() {
customSchemaBuilder.create(null);
}
@Test(expected = MetadataSchemaBuilderRuntimeException.InvalidAttribute.class)
public void whenCreatingCustomSchemaWithEmptyCodeThenException() {
customSchemaBuilder.create("");
}
@Test
public void givenUndeletableStatusOfCustomSchemaUndefinedWhenBuildingThenDeletable()
throws Exception {
build();
assertThat(customSchema.isUndeletable()).isFalse();
}
@Test
public void givenUndeletableStatusOfCustomSchemaUndefinedWhenModifyingThenDeletable()
throws Exception {
buildAndModify();
assertThat(customSchemaBuilder.isUndeletable()).isFalse();
}
@Test
public void givenUndeletableStatusOfCustomSchemaSetToTrueWhenBuildingThenUndeletable()
throws Exception {
customSchemaBuilder.setUndeletable(true);
build();
assertThat(customSchema.isUndeletable()).isTrue();
}
@Test
public void givenUndeletableStatusOfCustomSchemaSetToTrueWhenModifyingThenUndeletable()
throws Exception {
customSchemaBuilder.setUndeletable(true);
buildAndModify();
assertThat(customSchemaBuilder.isUndeletable()).isTrue();
}
@Test
public void givenUndeletableStatusOfCustomSchemaSetToFalseWhenBuildingThenDeletable()
throws Exception {
customSchemaBuilder.setUndeletable(false);
build();
assertThat(customSchema.isUndeletable()).isFalse();
}
@Test
public void givenUndeletableStatusOfCustomSchemaSetToFalseWhenModifyingThenDeletable()
throws Exception {
customSchemaBuilder.setUndeletable(false);
buildAndModify();
assertThat(customSchemaBuilder.isUndeletable()).isFalse();
}
@SuppressWarnings("unchecked")
@Test
public void givenRecordValidatorsOfDefaultMetadataWhenBuildingThenHasDefinedValidators()
throws Exception {
defaultSchemaBuilder.defineValidators().add(TestRecordValidator1.class).add(TestRecordValidator2.class);
build();
assertThat(defaultSchema.getValidators()).has(
onlyElementsOfClass(TestRecordValidator1.class, TestRecordValidator2.class)).hasSize(2);
}
@Test
public void givenRecordValidatorsOfDefaultMetadataWhenModifyingThenHasDefinedValidators()
throws Exception {
defaultSchemaBuilder.defineValidators().add(TestRecordValidator1.class).add(TestRecordValidator2.class);
buildAndModify();
assertThat(defaultSchemaBuilder.defineValidators().implementationsClassname).containsOnly(
TestRecordValidator1.class.getName(), TestRecordValidator2.class.getName()).hasSize(2);
}
@SuppressWarnings("unchecked")
@Test
public void givenRecordValidatorsOfCustomMetadataWhenBuildingThenHasDefinedValidatorsAndDefaultValidators()
throws Exception {
defaultSchemaBuilder.defineValidators().add(TestRecordValidator1.class);
customSchemaBuilder.defineValidators().add(TestRecordValidator2.class);
build();
assertThat(defaultSchema.getValidators()).has(onlyElementsOfClass(TestRecordValidator1.class)).hasSize(1);
assertThat(customSchema.getValidators())
.has(onlyElementsOfClass(TestRecordValidator1.class, TestRecordValidator2.class)).hasSize(2);
}
@Test
public void givenRecordValidatorsOfCustomMetadataWhenModifyingThenHasOnlyCustomValidators()
throws Exception {
defaultSchemaBuilder.defineValidators().add(TestRecordValidator1.class);
customSchemaBuilder.defineValidators().add(TestRecordValidator2.class);
buildAndModify();
assertThat(defaultSchemaBuilder.defineValidators().implementationsClassname).containsOnly(
TestRecordValidator1.class.getName()).hasSize(1);
assertThat(customSchemaBuilder.defineValidators().implementationsClassname).containsOnly(
TestRecordValidator2.class.getName()).hasSize(1);
}
@SuppressWarnings("unchecked")
@Test
public void givenRecordValidatorsOfCustomMetadataHasSameValidatorsThanTheDefaultSchemaWhenBuildingThenNoDuplication()
throws Exception {
defaultSchemaBuilder.defineValidators().add(TestRecordValidator1.class);
customSchemaBuilder.defineValidators().add(TestRecordValidator1.class);
build();
assertThat(customSchema.getValidators()).has(onlyElementsOfClass(TestRecordValidator1.class)).hasSize(1);
}
@Test
public void givenRecordValidatorsOfCustomMetadataHasSameValidatorsThanTheDefaultSchemaWhenModifyingThenDuplicatedValidatorRemovedInCustom()
throws Exception {
defaultSchemaBuilder.defineValidators().add(TestRecordValidator1.class);
customSchemaBuilder.defineValidators().add(TestRecordValidator1.class);
buildAndModify();
assertThat(customSchemaBuilder.defineValidators().implementationsClassname).isEmpty();
}
@Test(expected = MetadataSchemaBuilderRuntimeException.InvalidAttribute.class)
public void givenInvalidCodeFormatWhenValidateThenThrowExcpetion()
throws Exception {
customSchemaBuilder.validateLocalCode("te_st");
}
@Test
public void givenValidCodeFormatWhenValidateThenItIsValid()
throws Exception {
customSchemaBuilder.validateLocalCode("test");
}
@Test(expected = MetadataSchemaBuilderRuntimeException.InvalidAttribute.class)
public void givenInvalidMetadataCodeFormatWhenValidateThenThrowExcpetion()
throws Exception {
customSchemaBuilder.validateLocalCode("tes_t");
}
private Metadata newMockedMetadataWithCode(String code) {
Metadata secondMetadata = mock(Metadata.class);
when(secondMetadata.getLocalCode()).thenReturn(code);
return secondMetadata;
}
@Test
public void whenAddingCustomSchemaThenInheritModifiedDefaultSchemaFlags()
throws Exception {
buildAndModify();
defaultSchemaBuilder.create("zeMetadata").setMultivalue(true).setUndeletable(true).setEnabled(false)
.setSystemReserved(true).setDefaultRequirement(true).addLabel(Language.French, "zeLabel")
.setType(MetadataValueType.BOOLEAN)
.setUnmodifiable(true);
MetadataSchemaBuilder builder = MetadataSchemaBuilder.createSchema(defaultSchemaBuilder, "zeCustom2", true);
MetadataBuilder metadataBuilder = builder.getMetadata("zeMetadata");
assertThat(metadataBuilder.isMultivalue()).isTrue();
assertThat(metadataBuilder.isUndeletable()).isTrue();
assertThat(metadataBuilder.isSystemReserved()).isTrue();
assertThat(metadataBuilder.isUnmodifiable()).isTrue();
}
@Test
public void whenAddingCustomSchemaThenInheritModifiedDefaultSchemaUniqueFlags()
throws Exception {
buildAndModify();
defaultSchemaBuilder.create("zeMetadata").setUniqueValue(true);
MetadataSchemaBuilder builder = MetadataSchemaBuilder.createSchema(defaultSchemaBuilder, "zeCustom2", true);
MetadataBuilder metadataBuilder = builder.getMetadata("zeMetadata");
assertThat(metadataBuilder.isUniqueValue()).isTrue();
}
private void build() {
defaultSchema = defaultSchemaBuilder.buildDefault(typesFactory, modelLayerFactory);
customSchema = customSchemaBuilder.buildCustom(defaultSchema, typesFactory, modelLayerFactory);
}
private void buildAndModify() {
MetadataSchema defaultSchema = defaultSchemaBuilder.buildDefault(typesFactory, modelLayerFactory);
MetadataSchema customSchema = customSchemaBuilder.buildCustom(defaultSchema, typesFactory, modelLayerFactory);
defaultSchemaBuilder = MetadataSchemaBuilder.modifyDefaultSchema(defaultSchema, metadataSchemaTypeBuilder);
customSchemaBuilder = MetadataSchemaBuilder.modifySchema(customSchema, metadataSchemaTypeBuilder);
}
}