diff --git a/README.md b/README.md index b82016fbc76..7461213bde7 100644 --- a/README.md +++ b/README.md @@ -34,3 +34,31 @@ Dataverse is a trademark of President and Fellows of Harvard College and is regi [chat.dataverse.org]: http://chat.dataverse.org [Dataverse Community Meeting]: https://dataverse.org/events [open source]: LICENSE.md + + +# Running integration tests + +All tests: + +```bash +./mvnw verify +``` + +Single test: + +```bash +./mvnw verify -Dit.test=UserNotificationRepositoryIT -pl dataverse-persistence +``` + + +Integration test dependencies can be started manually in order to execute integration tests through the IDE: + +```bash +./mvnw docker:start -Dtest.solr.port=8984 -pl dataverse-webapp +``` + +Once started, all the integration tests can be run through the IDE. When finished, containers can be stopped with: + +```bash +./mvnw docker:stop -pl dataverse-webapp +``` diff --git a/dataverse-persistence/src/main/resources/Bundle_en.properties b/dataverse-persistence/src/main/resources/Bundle_en.properties index a23cf91eb7f..361350bbe3d 100755 --- a/dataverse-persistence/src/main/resources/Bundle_en.properties +++ b/dataverse-persistence/src/main/resources/Bundle_en.properties @@ -3108,4 +3108,5 @@ geobox.invalid.longitude=The longitude must be a number between -180 and 180. geobox.invalid.latitude=The latitude must be a number between -90 and 90. geobox.invalid.latitude.relation=The north latitude must be greater or equal to the south latitude. -validation.nonunique=The field must have a unique value. \ No newline at end of file +validation.nonunique=The field must have a unique value. +validation.value.not.allowed.in.controlled.vocabulary=Value "{0}" is not allowed. Please select one from the list. \ No newline at end of file diff --git a/dataverse-persistence/src/main/resources/Bundle_pl.properties b/dataverse-persistence/src/main/resources/Bundle_pl.properties index 8aa488a3456..ebcc3df764c 100644 --- a/dataverse-persistence/src/main/resources/Bundle_pl.properties +++ b/dataverse-persistence/src/main/resources/Bundle_pl.properties @@ -3059,4 +3059,5 @@ geobox.invalid.longitude=D\u0142ugo\u015B\u0107 geograficzna musi zawiera\u0107 geobox.invalid.latitude=Szeroko\u015B\u0107 geograficzna musi zawiera\u0107 si\u0119 mi\u0119dzy -90 a 90. geobox.invalid.latitude.relation=Szeroko\u015B\u0107 p\u00F3\u0142nocna musi by\u0107 nie mniejsza od po\u0142udniowej. -validation.nonunique=Pole musi mie\u0107 tylko jedn\u0105 warto\u015B\u0107. \ No newline at end of file +validation.nonunique=Pole musi mie\u0107 tylko jedn\u0105 warto\u015B\u0107. +validation.value.not.allowed.in.controlled.vocabulary=Warto\u015B\u0107 "{0}" jest niedozwolona. Wybierz jedn\u0105 z listy. \ No newline at end of file diff --git a/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/ControlledVocabularyValueServiceBean.java b/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/ControlledVocabularyValueServiceBean.java index 4094d954a63..cd21cdb060a 100644 --- a/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/ControlledVocabularyValueServiceBean.java +++ b/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/ControlledVocabularyValueServiceBean.java @@ -30,4 +30,16 @@ public List findByDatasetFieldTypeId(Long dsftId) { return query.getResultList(); } + public List findByDatasetFieldTypeNameAndValueLike(String datasetFieldTypeName, String suggestionSourceFieldValue, int queryLimit) { + + String queryString = "select DISTINCT v from ControlledVocabularyValue as v " + + "where UPPER(v.strValue) LIKE CONCAT('%', UPPER(:suggestionSourceFieldValue), '%') " + + "and v.datasetFieldType.id = (select d.id from DatasetFieldType as d where d.name = :datasetFieldTypeName)"; + TypedQuery query = em.createQuery(queryString, ControlledVocabularyValue.class); + query.setParameter("suggestionSourceFieldValue", suggestionSourceFieldValue); + query.setParameter("datasetFieldTypeName", datasetFieldTypeName); + query.setMaxResults(queryLimit); + query.setHint("eclipselink.QUERY_RESULTS_CACHE", "TRUE"); + return query.getResultList(); + } } diff --git a/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/SuggestionInputFieldRenderer.java b/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/SuggestionInputFieldRenderer.java index c691998f671..dedaf46c706 100644 --- a/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/SuggestionInputFieldRenderer.java +++ b/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/SuggestionInputFieldRenderer.java @@ -120,8 +120,11 @@ public List createSuggestions(DatasetField datasetField, String quer Map suggestionFilteredFields = new HashMap<>(); if (!datasetFieldTypeToSuggestionFilterMapping.isEmpty()) { - - suggestionFilteredFields = findFilterValues(datasetField, datasetFieldTypeToSuggestionFilterMapping); + if(suggestionHandler.isDependentOnSiblings()) { + suggestionFilteredFields = findFilterValuesInSiblings(datasetField, datasetFieldTypeToSuggestionFilterMapping); + } else { + suggestionFilteredFields = getFilterValue(datasetField, datasetFieldTypeToSuggestionFilterMapping); + } if (suggestionFilteredFields.isEmpty()){ return new ArrayList<>(); @@ -133,7 +136,15 @@ public List createSuggestions(DatasetField datasetField, String quer // -------------------- PRIVATE -------------------- - private Map findFilterValues(DatasetField datasetField, Map datasetFieldTypeToSuggestionFilterMapping) { + /** + * In this scenario we are using indirectly value from datasetFieldTypeToSuggestionFilterMapping + * which comes from datasetField configuration. + * This value is used indirectly to filter out suggestions. + * This value is the name of other siblings datasetField in datasetField group, + * that shares common parent. Method loops over all siblings to find out + * the one that have corresponding name, then its value is used to filter out suggestions. + */ + private Map findFilterValuesInSiblings(DatasetField datasetField, Map datasetFieldTypeToSuggestionFilterMapping) { Map filteredValues = datasetField.getDatasetFieldParent() .getOrElseThrow(() -> new NullPointerException("datasetfield with type: " + datasetField.getTypeName() + " didn't have any parent required to generate suggestions")) .getDatasetFieldsChildren().stream() @@ -146,4 +157,22 @@ private Map findFilterValues(DatasetField datasetField, Map() : filteredValues; } + /** + * In this scenario we are using directly value from datasetFieldTypeToSuggestionFilterMapping + * which comes from datasetField configuration. + * This value is used directly to filter out suggestions. + */ + private Map getFilterValue(DatasetField datasetField, Map datasetFieldTypeToSuggestionFilterMapping) { + return datasetFieldTypeToSuggestionFilterMapping + .entrySet() + .stream() + .filter(entry -> entry.getKey().equalsIgnoreCase(datasetField.getTypeName())) + .findFirst() + .map(entry -> { + Map filterValues = new HashMap<>(); + filterValues.put(entry.getValue(), entry.getKey()); + return filterValues; + }) + .orElseGet(HashMap::new); + } } diff --git a/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/ControlledVocabularySuggestionHandler.java b/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/ControlledVocabularySuggestionHandler.java new file mode 100644 index 00000000000..baff6abf8b9 --- /dev/null +++ b/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/ControlledVocabularySuggestionHandler.java @@ -0,0 +1,74 @@ +package edu.harvard.iq.dataverse.dataset.metadata.inputRenderer.suggestion; + +import com.google.common.collect.Lists; +import edu.harvard.iq.dataverse.ControlledVocabularyValueServiceBean; +import edu.harvard.iq.dataverse.dataset.metadata.inputRenderer.Suggestion; + +import javax.ejb.Stateless; +import javax.inject.Inject; +import java.util.List; +import java.util.Map; + +import static java.util.stream.Collectors.toList; + +/** + * This suggestion handler provides suggestions based on controlled vocabulary values. + */ +@Stateless +public class ControlledVocabularySuggestionHandler implements SuggestionHandler { + + public static final String CONTROLLED_VOCABULARY_NAME_COLUMN = "controlledVocabularyName"; + private ControlledVocabularyValueServiceBean controlledVocabularyValueServiceBean; + + // -------------------- CONSTRUCTORS -------------------- + + @Deprecated + public ControlledVocabularySuggestionHandler() { + } + + @Inject + public ControlledVocabularySuggestionHandler(ControlledVocabularyValueServiceBean controlledVocabularyValueServiceBean) { + this.controlledVocabularyValueServiceBean = controlledVocabularyValueServiceBean; + } + + // -------------------- LOGIC -------------------- + + /** + * {@inheritDoc} + *

+ * This implementation always returns class name. + */ + @Override + public String getName() { + return getClass().getSimpleName(); + } + + + /** + * This is not dependent on siblings input values. All values will be taken + * to build matching suggestions list. + */ + @Override + public boolean isDependentOnSiblings() { + return false; + } + + /** + * {@inheritDoc} + *

+ * This implementation filers out base on controlled vocabulary (input) name, + * a.k.a. dictionary name + */ + @Override + public List getAllowedFilters() { + return Lists.newArrayList(CONTROLLED_VOCABULARY_NAME_COLUMN); + } + + @Override + public List generateSuggestions(Map filters, String suggestionSourceFieldValue) { + return controlledVocabularyValueServiceBean + .findByDatasetFieldTypeNameAndValueLike(filters.get(CONTROLLED_VOCABULARY_NAME_COLUMN), suggestionSourceFieldValue, 10) + .stream().map(vocabulary -> new Suggestion(vocabulary.getStrValue(), vocabulary.getIdentifier())) + .collect(toList()); + } +} diff --git a/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/GrantAgencyAcronymSuggestionHandler.java b/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/GrantAgencyAcronymSuggestionHandler.java index 67f7335db9d..e612e93995b 100644 --- a/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/GrantAgencyAcronymSuggestionHandler.java +++ b/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/GrantAgencyAcronymSuggestionHandler.java @@ -40,6 +40,17 @@ public String getName() { return getClass().getSimpleName(); } + /** + * This suggestion is dependent on sibling input value. + * Only values that match pointed out sibling input value will be taken + * to create suggestion. + * @see this#getAllowedFilters() + */ + @Override + public boolean isDependentOnSiblings() { + return !getAllowedFilters().isEmpty(); + } + /** * {@inheritDoc} *

diff --git a/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/GrantAgencySuggestionHandler.java b/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/GrantAgencySuggestionHandler.java index 3a44ff10b35..72a13d732cd 100644 --- a/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/GrantAgencySuggestionHandler.java +++ b/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/GrantAgencySuggestionHandler.java @@ -40,6 +40,15 @@ public String getName() { return getClass().getSimpleName(); } + /** + * This suggestion is not dependent on siblings. + * All values will be taken to mach the suggestion string. + */ + @Override + public boolean isDependentOnSiblings() { + return !getAllowedFilters().isEmpty(); + } + /** * {@inheritDoc} *

diff --git a/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/GrantProgramSuggestionHandler.java b/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/GrantProgramSuggestionHandler.java index b02c5edd341..137019e1925 100644 --- a/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/GrantProgramSuggestionHandler.java +++ b/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/GrantProgramSuggestionHandler.java @@ -3,12 +3,10 @@ import com.google.common.collect.Lists; import edu.harvard.iq.dataverse.dataset.metadata.inputRenderer.Suggestion; import edu.harvard.iq.dataverse.persistence.dataset.suggestion.GrantSuggestion; -import edu.harvard.iq.dataverse.persistence.dataset.suggestion.GrantSuggestions; import javax.ejb.Stateless; import javax.inject.Inject; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -42,6 +40,17 @@ public String getName() { return getClass().getSimpleName(); } + /** + * This suggestion is dependent on sibling input value. + * Only values that match pointed out sibling input value will be taken + * to create suggestion. + * @see this#getAllowedFilters() + */ + @Override + public boolean isDependentOnSiblings() { + return !getAllowedFilters().isEmpty(); + } + /** * {@inheritDoc} *

diff --git a/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/RorSuggestionHandler.java b/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/RorSuggestionHandler.java index 20ebbff87c7..851f6529b1f 100644 --- a/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/RorSuggestionHandler.java +++ b/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/RorSuggestionHandler.java @@ -35,6 +35,17 @@ public String getName() { return getClass().getSimpleName(); } + /** + * This suggestion is dependent on sibling input value. + * Only values that match pointed out sibling input value will be taken + * to create suggestion. + * @see this#getAllowedFilters() + */ + @Override + public boolean isDependentOnSiblings() { + return !getAllowedFilters().isEmpty(); + } + /** * {@inheritDoc} *

diff --git a/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/SuggestionHandler.java b/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/SuggestionHandler.java index 0a00061c2cd..e7449f6d8b0 100644 --- a/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/SuggestionHandler.java +++ b/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/SuggestionHandler.java @@ -12,6 +12,20 @@ public interface SuggestionHandler { */ String getName(); + /** + * @return true if this handler is dependent on siblings input values. + * If it is dependant it will use other input values + * to filter out while generating suggestions. + * Sibling means the group of inputs that shares common parent input. + * F.e.: when input grant is parent and have children as follow: grantAgency, + * grantRor, grantAcronym it means that whenever one of its children will have value + * it will be taken to filter out values during generating suggestions. + * Of course its need to be configured via getAllowedFilters() method + * + * @see this#getAllowedFilters() + */ + boolean isDependentOnSiblings(); + /** * Returns name of filters that this handler understands * and can handle. diff --git a/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/validation/field/validators/ControlledVocabularyValidator.java b/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/validation/field/validators/ControlledVocabularyValidator.java new file mode 100644 index 00000000000..c3578ca3811 --- /dev/null +++ b/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/validation/field/validators/ControlledVocabularyValidator.java @@ -0,0 +1,53 @@ +package edu.harvard.iq.dataverse.validation.field.validators; + +import edu.harvard.iq.dataverse.ControlledVocabularyValueServiceBean; +import edu.harvard.iq.dataverse.common.BundleUtil; +import edu.harvard.iq.dataverse.persistence.dataset.ControlledVocabularyValue; +import edu.harvard.iq.dataverse.persistence.dataset.ValidatableField; +import edu.harvard.iq.dataverse.validation.field.FieldValidationResult; +import org.omnifaces.cdi.Eager; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import java.util.List; +import java.util.Map; + +/** + * Validator for fields that should only contain values from a controlled vocabulary. + * The vocabulary is passed in through the parameters. + */ +@Eager +@ApplicationScoped +public class ControlledVocabularyValidator extends MultiValueValidatorBase { + + @Inject + private ControlledVocabularyValueServiceBean vocabularyDao; + + // -------------------- LOGIC -------------------- + + @Override + public String getName() { + return "controlled_vocabulary_validator"; + } + + @Override + public FieldValidationResult validateValue + (String value, + ValidatableField field, + Map params, + Map> fieldIndex) { + + List matchesFromDb = + vocabularyDao.findByDatasetFieldTypeNameAndValueLike( + field.getDatasetFieldType().getName(), value, 1 + ); + if(matchesFromDb.size() == 1 && matchesFromDb.get(0).getStrValue().equalsIgnoreCase(value)) { + return FieldValidationResult.ok(); + } else { + return FieldValidationResult.invalid( + field, + BundleUtil.getStringFromBundle("validation.value.not.allowed.in.controlled.vocabulary", value) + ); + } + } +} \ No newline at end of file diff --git a/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/validation/field/validators/RequiredByValueDependantFieldValidator.java b/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/validation/field/validators/RequiredByValueDependantFieldValidator.java index 6053f9495e6..a41035a0013 100644 --- a/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/validation/field/validators/RequiredByValueDependantFieldValidator.java +++ b/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/validation/field/validators/RequiredByValueDependantFieldValidator.java @@ -26,8 +26,6 @@ * @see edu.harvard.iq.dataverse.persistence.dataset.ValidatableField * @see edu.harvard.iq.dataverse.persistence.dataset.DatasetField * @see edu.harvard.iq.dataverse.persistence.dataset.DatasetFieldType#getValidation() - * - * @author Filipe Dias Lewandowski, Krzysztof Mądry, Daniel Korbel, Sylwester Niewczas */ @Eager @ApplicationScoped diff --git a/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/validation/field/validators/RequiredDependantFieldValidator.java b/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/validation/field/validators/RequiredDependantFieldValidator.java index 61bb3178785..be94184e7d4 100644 --- a/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/validation/field/validators/RequiredDependantFieldValidator.java +++ b/dataverse-webapp/src/main/java/edu/harvard/iq/dataverse/validation/field/validators/RequiredDependantFieldValidator.java @@ -28,8 +28,6 @@ * @see edu.harvard.iq.dataverse.persistence.dataset.ValidatableField * @see edu.harvard.iq.dataverse.persistence.dataset.DatasetField * @see edu.harvard.iq.dataverse.persistence.dataset.DatasetFieldType#getValidation() - * - * @author Filipe Dias Lewandowski, Krzysztof Mądry, Daniel Korbel, Sylwester Niewczas */ @Eager @ApplicationScoped diff --git a/dataverse-webapp/src/test/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/SuggestionInputFieldRendererTest.java b/dataverse-webapp/src/test/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/SuggestionInputFieldRendererTest.java index f07d7042555..4aaf36160f2 100644 --- a/dataverse-webapp/src/test/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/SuggestionInputFieldRendererTest.java +++ b/dataverse-webapp/src/test/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/SuggestionInputFieldRendererTest.java @@ -26,7 +26,7 @@ @ExtendWith(MockitoExtension.class) @MockitoSettings(strictness = Strictness.LENIENT) -public class SuggestionInputFieldRendererTest { +class SuggestionInputFieldRendererTest { private SuggestionInputFieldRenderer suggestionInputFieldRenderer; @@ -36,7 +36,7 @@ public class SuggestionInputFieldRendererTest { // -------------------- TESTS -------------------- @Test - public void createSuggestions_WithoutFilters() { + void createSuggestions_WithoutFilters() { //given suggestionInputFieldRenderer = new SuggestionInputFieldRenderer(suggestionHandler, new HashMap<>(), @@ -58,10 +58,11 @@ public void createSuggestions_WithoutFilters() { } @Test - public void createSuggestions_WithFilters() { + void createSuggestions_WithFilters() { //given String dsftName = "grantNumber"; String suggestionFilterName = "grantNumberSuggestionFilter"; + when(suggestionHandler.isDependentOnSiblings()).thenReturn(true); suggestionInputFieldRenderer = new SuggestionInputFieldRenderer(suggestionHandler, ImmutableMap.of(dsftName, suggestionFilterName), SuggestionDisplayType.SIMPLE, diff --git a/dataverse-webapp/src/test/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/ControlledVocabularySuggestionHandlerTest.java b/dataverse-webapp/src/test/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/ControlledVocabularySuggestionHandlerTest.java new file mode 100644 index 00000000000..1de074f9d57 --- /dev/null +++ b/dataverse-webapp/src/test/java/edu/harvard/iq/dataverse/dataset/metadata/inputRenderer/suggestion/ControlledVocabularySuggestionHandlerTest.java @@ -0,0 +1,66 @@ +package edu.harvard.iq.dataverse.dataset.metadata.inputRenderer.suggestion; + +import com.google.common.collect.ImmutableMap; +import edu.harvard.iq.dataverse.ControlledVocabularyValueServiceBean; +import edu.harvard.iq.dataverse.dataset.metadata.inputRenderer.Suggestion; +import edu.harvard.iq.dataverse.persistence.dataset.ControlledVocabularyValue; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static java.util.Collections.singletonList; + +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) +class ControlledVocabularySuggestionHandlerTest { + + @InjectMocks + private ControlledVocabularySuggestionHandler controlledVocabularySuggestionHandler; + + @Mock + private ControlledVocabularyValueServiceBean controlledVocabularyValueServiceBean; + + // -------------------- TESTS -------------------- + + @Test + void generateSuggestions() { + // given + ControlledVocabularyValue vocabularyValue = new ControlledVocabularyValue(); + vocabularyValue.setStrValue("suggestion1"); + vocabularyValue.setIdentifier("123"); + + when(controlledVocabularyValueServiceBean.findByDatasetFieldTypeNameAndValueLike( + anyString(), anyString(), eq(10)) + ) + .thenReturn(singletonList(vocabularyValue)); + + // when + List suggestions = controlledVocabularySuggestionHandler + .generateSuggestions( + ImmutableMap.of(ControlledVocabularySuggestionHandler.CONTROLLED_VOCABULARY_NAME_COLUMN, + "testVocabulary"), "query"); + + // then + assertThat(suggestions) + .extracting(Suggestion::getValue) + .containsExactly("suggestion1"); + + assertThat(suggestions) + .extracting(Suggestion::getDetails) + .containsExactly("123"); + + verify(controlledVocabularyValueServiceBean).findByDatasetFieldTypeNameAndValueLike( + "testVocabulary", "query", 10); + } +} diff --git a/dataverse-webapp/src/test/java/edu/harvard/iq/dataverse/validation/field/validators/ControlledVocabularyValidatorTest.java b/dataverse-webapp/src/test/java/edu/harvard/iq/dataverse/validation/field/validators/ControlledVocabularyValidatorTest.java new file mode 100644 index 00000000000..e68471dd6d9 --- /dev/null +++ b/dataverse-webapp/src/test/java/edu/harvard/iq/dataverse/validation/field/validators/ControlledVocabularyValidatorTest.java @@ -0,0 +1,73 @@ +package edu.harvard.iq.dataverse.validation.field.validators; + +import edu.harvard.iq.dataverse.ControlledVocabularyValueServiceBean; +import edu.harvard.iq.dataverse.persistence.dataset.ControlledVocabularyValue; +import edu.harvard.iq.dataverse.persistence.dataset.DatasetFieldType; +import edu.harvard.iq.dataverse.persistence.dataset.ValidatableField; +import edu.harvard.iq.dataverse.validation.field.FieldValidationResult; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.Collections; +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class ControlledVocabularyValidatorTest { + + @Mock + private ControlledVocabularyValueServiceBean vocabularyDao; + + @InjectMocks + private ControlledVocabularyValidator validator; + + @BeforeEach + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Test + void testValidateValue_success() { + String testValue = "TestValue"; + ValidatableField testField = mock(ValidatableField.class); + DatasetFieldType testFieldType = mock(DatasetFieldType.class); + + when(testField.getDatasetFieldType()).thenReturn(testFieldType); + when(testFieldType.getName()).thenReturn("TestFieldType"); + + ControlledVocabularyValue vocabularyValue = mock(ControlledVocabularyValue.class); + when(vocabularyValue.getStrValue()).thenReturn(testValue); + + when(vocabularyDao.findByDatasetFieldTypeNameAndValueLike("TestFieldType", testValue, 1)) + .thenReturn(Collections.singletonList(vocabularyValue)); + + FieldValidationResult result = validator.validateValue( + testValue, testField, new HashMap<>(), new HashMap<>()); + + assertTrue(result.isOk()); + } + + @Test + void testValidateValue_failure() { + String testValue = "InvalidValue"; + ValidatableField testField = mock(ValidatableField.class); + DatasetFieldType testFieldType = mock(DatasetFieldType.class); + + when(testField.getDatasetFieldType()).thenReturn(testFieldType); + when(testFieldType.getName()).thenReturn("TestFieldType"); + + when(vocabularyDao.findByDatasetFieldTypeNameAndValueLike("TestFieldType", testValue, 1)) + .thenReturn(Collections.emptyList()); + + FieldValidationResult result = validator.validateValue( + testValue, testField, new HashMap<>(), new HashMap<>()); + + assertFalse(result.isOk()); + assertEquals("Value \"InvalidValue\" is not allowed. Please select one from the list.", result.getMessage()); + } +} \ No newline at end of file diff --git a/dataverse-webapp/src/test/java/edu/harvard/iq/dataverse/validation/field/validators/RequiredByValueDependantFieldValidatorTest.java b/dataverse-webapp/src/test/java/edu/harvard/iq/dataverse/validation/field/validators/RequiredByValueDependantFieldValidatorTest.java index 9ed46116a64..9a092f361d5 100644 --- a/dataverse-webapp/src/test/java/edu/harvard/iq/dataverse/validation/field/validators/RequiredByValueDependantFieldValidatorTest.java +++ b/dataverse-webapp/src/test/java/edu/harvard/iq/dataverse/validation/field/validators/RequiredByValueDependantFieldValidatorTest.java @@ -21,9 +21,6 @@ import org.mockito.MockedStatic; import org.mockito.junit.MockitoJUnitRunner; -/** - * @author Filipe Dias Lewandowski, Krzysztof Mądry, Daniel Korbel, Sylwester Niewczas - */ @RunWith(MockitoJUnitRunner.class) public class RequiredByValueDependantFieldValidatorTest { diff --git a/dataverse-webapp/src/test/java/edu/harvard/iq/dataverse/validation/field/validators/RequiredDependantFieldValidatorTest.java b/dataverse-webapp/src/test/java/edu/harvard/iq/dataverse/validation/field/validators/RequiredDependantFieldValidatorTest.java index f3e311b2048..98e01ad33e9 100644 --- a/dataverse-webapp/src/test/java/edu/harvard/iq/dataverse/validation/field/validators/RequiredDependantFieldValidatorTest.java +++ b/dataverse-webapp/src/test/java/edu/harvard/iq/dataverse/validation/field/validators/RequiredDependantFieldValidatorTest.java @@ -12,9 +12,6 @@ import static org.assertj.core.api.Assertions.assertThat; -/** - * @author Filipe Dias Lewandowski, Krzysztof Mądry, Daniel Korbel, Sylwester Niewczas - */ public class RequiredDependantFieldValidatorTest { private final RequiredDependantFieldValidator validator = new RequiredDependantFieldValidator();