package com.constellio.model.services.records; import static com.constellio.sdk.tests.TestUtils.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verifyZeroInteractions; import org.joda.time.LocalDateTime; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import com.constellio.model.entities.records.Record; import com.constellio.model.entities.records.RecordUpdateOptions; import com.constellio.model.entities.records.Transaction; import com.constellio.model.entities.records.TransactionRecordsReindexation; import com.constellio.model.entities.schemas.Metadata; import com.constellio.model.services.schemas.MetadataList; import com.constellio.sdk.tests.ConstellioTest; import com.constellio.sdk.tests.TestRecord; import com.constellio.sdk.tests.schemas.DaysBetweenSingleLocalDateAndAnotherSchemaRequiredDateCalculator; import com.constellio.sdk.tests.schemas.TestsSchemasSetup; import com.constellio.sdk.tests.schemas.TestsSchemasSetup.AnotherSchemaMetadatas; import com.constellio.sdk.tests.schemas.TestsSchemasSetup.ZeSchemaMetadatas; public class RecordAutomaticMetadataServicesCalculationAcceptanceTest extends ConstellioTest { RecordUpdateOptions options = new RecordUpdateOptions(); RecordServicesImpl recordServices; RecordAutomaticMetadataServices services; RecordProvider recordProvider; String idReferencedRecordWithJan1DateValue, idReferencedRecordWithJan2DateValue, idReferencedRecordWithoutDateValue; RecordImpl record; LocalDateTime jan1 = new LocalDateTime(2014, 1, 1, 0, 0); LocalDateTime jan2 = new LocalDateTime(2014, 1, 2, 0, 0); LocalDateTime jan3 = new LocalDateTime(2014, 1, 3, 0, 0); TestsSchemasSetup schemas; ZeSchemaMetadatas zeSchema; AnotherSchemaMetadatas anotherSchema; @Mock Metadata firstReindexedMetadata, secondReindexedMetadata; TransactionRecordsReindexation reindexedMetadata; @Before public void setUp() { schemas = new TestsSchemasSetup(); zeSchema = schemas.new ZeSchemaMetadatas(); anotherSchema = schemas.new AnotherSchemaMetadatas(); record = new TestRecord(zeSchema); services = new RecordAutomaticMetadataServices(getModelLayerFactory().getMetadataSchemasManager(), getModelLayerFactory().getTaxonomiesManager(), getModelLayerFactory().getSystemConfigurationsManager(), getModelLayerFactory().getModelLayerLogger(), getModelLayerFactory().newSearchServices()); recordServices = spy((RecordServicesImpl) getModelLayerFactory().newCachelessRecordServices()); recordProvider = recordServices.newRecordProvider(null, new Transaction()); DaysBetweenSingleLocalDateAndAnotherSchemaRequiredDateCalculator.invokationCounter.set(0); reindexedMetadata = new TransactionRecordsReindexation( new MetadataList(firstReindexedMetadata, secondReindexedMetadata)); } @Test public void givenCalculatedMetadataOfNewRecordWhenUpdatingThenCalculateValue() throws Exception { givenCalculatedNumberBasedOnLocalDateAndAnotherSchemaReferenceDate(false); record.set(zeSchema.secondReferenceToAnotherSchema(), idReferencedRecordWithJan1DateValue); record.set(zeSchema.dateTimeMetadata(), jan3); services.updateAutomaticMetadatas(record, recordProvider, reindexedMetadata, options); assertThat(record.get(zeSchema.calculatedDaysBetween())).isEqualTo(2.0); } @Test public void givenCalculatedMetadataOfNewRecordWithMultivaluesWhenUpdatingThenCalculateValue() throws Exception { givenCalculatedNumberBasedOnLocalDateAndAnotherSchemaReferenceDate(true); record.set(zeSchema.secondReferenceToAnotherSchema(), asList(idReferencedRecordWithJan1DateValue)); record.set(zeSchema.dateTimeMetadata(), asList(jan1, jan2)); services.updateAutomaticMetadatas(record, recordProvider, reindexedMetadata, options); assertThat(record.get(zeSchema.calculatedDaysBetween())).isEqualTo(1.0); } @Test public void givenCalculatedMetadataOfNewRecordMissingRequiredReferenceDependencyWhenUpdatingThenCalculatedValueIsDefaultValue() throws Exception { givenCalculatedNumberBasedOnLocalDateAndAnotherSchemaReferenceDate(false); record.set(zeSchema.secondReferenceToAnotherSchema(), idReferencedRecordWithoutDateValue); record.set(zeSchema.dateTimeMetadata(), jan3); services.updateAutomaticMetadatas(record, recordProvider, reindexedMetadata, options); assertThat(record.get(zeSchema.calculatedDaysBetween())).isEqualTo(-1.0); } @Test public void givenCalculatedMetadataOfNewRecordMissingRequiredLocalDependencyWhenUpdatingThenCalculatedValueIsDefaultValue() throws Exception { givenCalculatedNumberBasedOnLocalDateAndAnotherSchemaReferenceDate(false); record.set(zeSchema.secondReferenceToAnotherSchema(), idReferencedRecordWithJan1DateValue); record.set(zeSchema.dateTimeMetadata(), null); services.updateAutomaticMetadatas(record, recordProvider, reindexedMetadata, options); assertThat(record.get(zeSchema.calculatedDaysBetween())).isEqualTo(-1.0); } @Test public void givenExistingRecordDependenciesOfCalculatedMetadataNotModifiedWhenUpdatingThenNotRecalculate() throws Exception { givenCalculatedNumberBasedOnLocalDateAndAnotherSchemaReferenceDate(false); record.set(zeSchema.secondReferenceToAnotherSchema(), idReferencedRecordWithJan1DateValue); record.set(zeSchema.dateTimeMetadata(), jan3); add(); services.updateAutomaticMetadatas(record, recordProvider, reindexedMetadata, options); assertThat(DaysBetweenSingleLocalDateAndAnotherSchemaRequiredDateCalculator.invokationCounter.get()).isEqualTo(1); assertThat(record.get(zeSchema.calculatedDaysBetween())).isEqualTo(2.0); verifyZeroInteractions(recordServices); } @Test public void givenExistingRecordReferenceDependencyOfCalculatedMetadataModifiedWhenUpdatingThenRecalculate() throws Exception { givenCalculatedNumberBasedOnLocalDateAndAnotherSchemaReferenceDate(false); record.set(zeSchema.secondReferenceToAnotherSchema(), idReferencedRecordWithJan1DateValue); record.set(zeSchema.dateTimeMetadata(), jan3); add(); record.set(zeSchema.secondReferenceToAnotherSchema(), idReferencedRecordWithJan2DateValue); services.updateAutomaticMetadatas(record, recordProvider, reindexedMetadata, options); assertThat(DaysBetweenSingleLocalDateAndAnotherSchemaRequiredDateCalculator.invokationCounter.get()).isEqualTo(2); assertThat(record.get(zeSchema.calculatedDaysBetween())).isEqualTo(1.0); } @Test public void givenExistingRecordLocalDependencyOfCalculatedMetadataModifiedWhenUpdatingThenRecalculate() throws Exception { givenCalculatedNumberBasedOnLocalDateAndAnotherSchemaReferenceDate(false); record.set(zeSchema.secondReferenceToAnotherSchema(), idReferencedRecordWithJan1DateValue); record.set(zeSchema.dateTimeMetadata(), jan3); add(); record.set(zeSchema.dateTimeMetadata(), jan2); services.updateAutomaticMetadatas(record, recordProvider, reindexedMetadata, options); assertThat(DaysBetweenSingleLocalDateAndAnotherSchemaRequiredDateCalculator.invokationCounter.get()).isEqualTo(2); assertThat(record.get(zeSchema.calculatedDaysBetween())).isEqualTo(1.0); } @Test public void givenExistingRecordReferenceDependencyOfCalculatedMetadataRemovedWhenUpdatingThenReplaceWithDefaultValue() throws Exception { givenCalculatedNumberBasedOnLocalDateAndAnotherSchemaReferenceDate(false); record.set(zeSchema.secondReferenceToAnotherSchema(), idReferencedRecordWithJan1DateValue); record.set(zeSchema.dateTimeMetadata(), jan3); add(); record.set(zeSchema.secondReferenceToAnotherSchema(), null); services.updateAutomaticMetadatas(record, recordProvider, reindexedMetadata, options); assertThat(DaysBetweenSingleLocalDateAndAnotherSchemaRequiredDateCalculator.invokationCounter.get()).isEqualTo(1); assertThat(record.get(zeSchema.calculatedDaysBetween())).isEqualTo(-1.0); verifyZeroInteractions(recordServices); } @Test public void givenExistingRecordLocalDependencyOfCalculatedMetadataRemovedWhenUpdatingThenReplaceWithDefaultValue() throws Exception { givenCalculatedNumberBasedOnLocalDateAndAnotherSchemaReferenceDate(false); record.set(zeSchema.secondReferenceToAnotherSchema(), idReferencedRecordWithJan1DateValue); record.set(zeSchema.dateTimeMetadata(), jan3); add(); record.set(zeSchema.dateTimeMetadata(), null); services.updateAutomaticMetadatas(record, recordProvider, reindexedMetadata, options); assertThat(DaysBetweenSingleLocalDateAndAnotherSchemaRequiredDateCalculator.invokationCounter.get()).isEqualTo(1); assertThat(record.get(zeSchema.calculatedDaysBetween())).isEqualTo(-1.0); } private void add() throws RecordServicesException { RecordServices recordServices = getModelLayerFactory().newRecordServices(); recordServices.add(record); } protected void givenCalculatedNumberBasedOnLocalDateAndAnotherSchemaReferenceDate(boolean multivalue) throws Exception { defineSchemasManager().using(schemas.withCalculatedDaysBetweenLocalDateAndAnotherSchemaRequiredDate(multivalue)); addRecords(); } private void addRecords() throws RecordServicesException { Record record = new TestRecord(anotherSchema); record.set(anotherSchema.dateMetadata(), jan1); recordServices.add(record); idReferencedRecordWithJan1DateValue = record.getId(); record = new TestRecord(anotherSchema); record.set(anotherSchema.dateMetadata(), jan2); recordServices.add(record); idReferencedRecordWithJan2DateValue = record.getId(); record = new TestRecord(anotherSchema); recordServices.add(record); idReferencedRecordWithoutDateValue = record.getId(); reset(recordServices); } }