package com.constellio.model.services.records.validators;
import static com.constellio.model.services.search.query.logical.LogicalSearchQueryOperators.from;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import com.constellio.model.entities.records.Record;
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.schemas.validators.MetadataUniqueValidator;
import com.constellio.model.services.search.SearchServices;
import com.constellio.model.services.search.query.logical.LogicalSearchQuery;
import com.constellio.sdk.tests.ConstellioTest;
public class MetadataUniqueValidatorTest extends ConstellioTest {
public static final String NON_UNIQUE_METADATA = MetadataUniqueValidator.class.getName() + "_nonUniqueMetadata";
String zeId;
String zeValue = "zeValue";
@Mock Metadata metadata;
@Mock MetadataSchemaTypes schemaTypes;
@Mock MetadataSchema schema;
@Mock Record record;
@Mock SearchServices searchServices;
MetadataUniqueValidator validator;
ValidationErrors validationErrors;
@Before
public void setUp() {
List<Metadata> metadatas = new ArrayList<>();
metadatas.add(metadata);
when(metadata.isUniqueValue()).thenReturn(true);
when(metadata.getCode()).thenReturn("type_default_zeCompleteCode");
when(schemaTypes.getSchema("type_default")).thenReturn(schema);
when(schema.getCode()).thenReturn("type_default");
when(metadata.getType()).thenReturn(MetadataValueType.STRING);
validator = new MetadataUniqueValidator(metadatas, schemaTypes, searchServices);
validationErrors = new ValidationErrors();
when(record.getId()).thenReturn(zeId);
when(record.isActive()).thenReturn(true);
}
@Test
public void givenNonUniqueMetadataThenNotValidated() {
when(metadata.isUniqueValue()).thenReturn(false);
validator.validate(record, validationErrors);
verify(record, never()).isModified(metadata);
verify(searchServices, never()).hasResults(any(LogicalSearchQuery.class));
assertThat(validationErrors.getValidationErrors()).isEmpty();
}
@Test
public void givenUniqueMetadataIsNotModifiedThenNotValidated() {
when(record.isModified(metadata)).thenReturn(false);
when(record.get(metadata)).thenReturn(zeValue);
validator.validate(record, validationErrors);
verify(searchServices, never()).hasResults(any(LogicalSearchQuery.class));
assertThat(validationErrors.getValidationErrors()).isEmpty();
}
@Test
public void givenUniqueMetadataIsModifiedButIsNullThenNotValidated() {
when(record.isModified(metadata)).thenReturn(false);
when(record.get(metadata)).thenReturn(null);
validator.validate(record, validationErrors);
verify(searchServices, never()).hasResults(any(LogicalSearchQuery.class));
assertThat(validationErrors.getValidationErrors()).isEmpty();
}
@Test
public void givenUniqueMetadataAndNoExistingRecordsNoThenError() {
ArgumentCaptor<LogicalSearchQuery> query = ArgumentCaptor.forClass(LogicalSearchQuery.class);
when(searchServices.hasResults(query.capture())).thenReturn(false);
when(record.isModified(metadata)).thenReturn(true);
when(record.get(metadata)).thenReturn(zeValue);
validator.validate(record, validationErrors);
assertThat(validationErrors.getValidationErrors()).isEmpty();
assertThat(query.getValue().getCondition()).isEqualTo(
from(schema).where(metadata).isEqualTo(zeValue).andWhere(Schemas.IDENTIFIER).isNotEqual(zeId));
}
@Test
public void givenUniqueMetadataAndExistingRecordsThenError() {
ArgumentCaptor<LogicalSearchQuery> query = ArgumentCaptor.forClass(LogicalSearchQuery.class);
when(searchServices.hasResults(query.capture())).thenReturn(true);
when(record.isModified(metadata)).thenReturn(true);
when(record.get(metadata)).thenReturn(zeValue);
validator.validate(record, validationErrors);
assertThat(validationErrors.getValidationErrors()).hasSize(1);
assertThat(validationErrors.getValidationErrors().get(0).getCode()).isEqualTo(NON_UNIQUE_METADATA);
assertThat(query.getValue().getCondition()).isEqualTo(
from(schema).where(metadata).isEqualTo(zeValue).andWhere(Schemas.IDENTIFIER).isNotEqual(zeId));
}
}