package com.constellio.model.services.records.validators;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import com.constellio.model.entities.records.Record;
import com.constellio.model.entities.schemas.AllowedReferences;
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.entities.schemas.Schemas;
import com.constellio.model.frameworks.validation.ValidationErrors;
import com.constellio.model.services.records.RecordProvider;
import com.constellio.model.services.schemas.validators.CyclicHierarchyValidator;
import com.constellio.sdk.tests.ConstellioTest;
public class CyclicHierarchyValidatorTest extends ConstellioTest {
@Mock MetadataSchemaTypes schemaTypes;
@Mock Metadata metadataWithoutReferences;
@Mock Metadata metadataWithAReference;
@Mock Metadata metadataWithAChildOfReference;
@Mock Metadata metadataWithTwoReferences;
@Mock Metadata metadataWithAlistOfReference;
@Mock AllowedReferences oneAllowedReferences;
@Mock AllowedReferences twoAllowedReferences;
@Mock MetadataSchema nonAllowedSchema;
@Mock MetadataSchema anAllowedSchema;
@Mock MetadataSchema anotherAllowedSchema;
@Mock Record record;
CyclicHierarchyValidator validator;
@Mock RecordProvider recordProvider;
@Mock Record anAllowedRecord;
@Mock Record anUnallowedRecord;
@Mock Record descendantRecord;
String theRecordId = "theRecordId";
List<String> aListOfAllowedReferencesCodes = new ArrayList<String>();
@Before
public void setUp() {
when(record.getId()).thenReturn(theRecordId);
aListOfAllowedReferencesCodes.add("anAllowedRecordId");
when(record.getSchemaCode()).thenReturn("anAllowedSchemaCode");
when(descendantRecord.getSchemaCode()).thenReturn("anAllowedSchemaCode");
when(anAllowedRecord.getSchemaCode()).thenReturn("anAllowedSchemaCode");
when(anUnallowedRecord.getSchemaCode()).thenReturn("nonAllowedSchemaCode");
when(recordProvider.getRecord("theRecordId")).thenReturn(record);
when(recordProvider.getRecord("aDescendantId")).thenReturn(descendantRecord);
when(recordProvider.getRecord("anAllowedRecordId")).thenReturn(anAllowedRecord);
when(recordProvider.getRecord("anUnallowedRecordId")).thenReturn(anUnallowedRecord);
when(anAllowedRecord.get(Schemas.PRINCIPAL_PATH)).thenReturn("/concept/anAllowedRecordId");
when(descendantRecord.get(Schemas.PRINCIPAL_PATH)).thenReturn("/concept/theRecordId/aDescendantId");
when(metadataWithoutReferences.getType()).thenReturn(MetadataValueType.STRING);
when(metadataWithAReference.getType()).thenReturn(MetadataValueType.REFERENCE);
when(metadataWithTwoReferences.getType()).thenReturn(MetadataValueType.REFERENCE);
when(metadataWithAChildOfReference.getType()).thenReturn(MetadataValueType.REFERENCE);
when(metadataWithAlistOfReference.getType()).thenReturn(MetadataValueType.REFERENCE);
when(record.isModified(metadataWithoutReferences)).thenReturn(true);
when(record.isModified(metadataWithAReference)).thenReturn(true);
when(record.isModified(metadataWithTwoReferences)).thenReturn(true);
when(record.isModified(metadataWithAChildOfReference)).thenReturn(true);
when(record.isModified(metadataWithAlistOfReference)).thenReturn(true);
when(metadataWithAlistOfReference.isMultivalue()).thenReturn(true);
when(metadataWithAChildOfReference.isChildOfRelationship()).thenReturn(true);
List<Metadata> metadatas = new ArrayList<>();
metadatas.add(metadataWithoutReferences);
metadatas.add(metadataWithAReference);
metadatas.add(metadataWithAChildOfReference);
metadatas.add(metadataWithTwoReferences);
metadatas.add(metadataWithAlistOfReference);
when(schemaTypes.getSchema("nonAllowedSchemaCode")).thenReturn(nonAllowedSchema);
when(schemaTypes.getSchema("anAllowedSchemaCode")).thenReturn(anAllowedSchema);
when(schemaTypes.getSchema("anotherAllowedSchemaCode")).thenReturn(anotherAllowedSchema);
when(oneAllowedReferences.isAllowed(anAllowedSchema)).thenReturn(true);
when(twoAllowedReferences.isAllowed(anAllowedSchema)).thenReturn(true);
when(twoAllowedReferences.isAllowed(anotherAllowedSchema)).thenReturn(true);
when(metadataWithAReference.getAllowedReferences()).thenReturn(oneAllowedReferences);
when(metadataWithTwoReferences.getAllowedReferences()).thenReturn(twoAllowedReferences);
when(metadataWithTwoReferences.getAllowedReferences()).thenReturn(oneAllowedReferences);
when(metadataWithAlistOfReference.getAllowedReferences()).thenReturn(oneAllowedReferences);
when(metadataWithAChildOfReference.getAllowedReferences()).thenReturn(oneAllowedReferences);
validator = new CyclicHierarchyValidator(schemaTypes, metadatas, recordProvider);
}
@Test
public void givenARecordIsReferencingADescendantInAReferenceMetadataThenNoError() {
when(record.get(metadataWithAlistOfReference)).thenReturn(Arrays.asList("aDescendantId"));
ValidationErrors validationErrors = new ValidationErrors();
validator.validate(record, validationErrors);
assertThat(validationErrors.getValidationErrors()).isEmpty();
}
@Test
public void givenARecordIsReferencingADescendantInAChildOfReferenceMetadataThenError() {
when(record.get(metadataWithAChildOfReference)).thenReturn("aDescendantId");
ValidationErrors validationErrors = new ValidationErrors();
validator.validate(record, validationErrors);
assertThat(validationErrors.getValidationErrors()).hasSize(1);
assertThat(validationErrors.getValidationErrors().get(0).getCode())
.endsWith(CyclicHierarchyValidator.CANNOT_REFERENCE_A_DESCENDANT_IN_A_CHILD_OF_REFERENCE);
}
@Test
public void givenARecordIsReferencingAnotherRecordInAChildOfReferenceMetadataThenOk() {
when(record.get(metadataWithAChildOfReference)).thenReturn("anAllowedRecordId");
ValidationErrors validationErrors = new ValidationErrors();
validator.validate(record, validationErrors);
assertThat(validationErrors.getValidationErrors()).isEmpty();
}
@Test
public void givenARecordWithIdInSubstringOfPrincipalPathThenNoError() {
when(record.get(metadataWithAChildOfReference)).thenReturn("anAllowedRecordId");
when(anAllowedRecord.get(Schemas.PRINCIPAL_PATH)).thenReturn("/anAllowedRecordIdanAllowedRecordId");
ValidationErrors validationErrors = new ValidationErrors();
validator.validate(record, validationErrors);
assertThat(validationErrors.getValidationErrors()).isEmpty();
}
}