/** * Copyright (c) Codice Foundation * <p> * This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser * General Public License as published by the Free Software Foundation, either version 3 of the * License, or any later version. * </p> * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. A copy of the GNU Lesser General Public License * is distributed along with this program and can be found at * <http://www.gnu.org/licenses/lgpl.html>. */ package org.codice.ddf.validator.metacard.duplication; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsCollectionContaining.hasItems; import static org.hamcrest.core.IsNot.not; import static org.hamcrest.core.StringContains.containsString; import static org.junit.Assert.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.opengis.filter.Filter; import ddf.catalog.CatalogFramework; import ddf.catalog.data.Metacard; import ddf.catalog.data.Result; import ddf.catalog.data.impl.AttributeImpl; import ddf.catalog.data.impl.MetacardImpl; import ddf.catalog.data.impl.ResultImpl; import ddf.catalog.federation.FederationException; import ddf.catalog.filter.FilterBuilder; import ddf.catalog.operation.QueryRequest; import ddf.catalog.operation.QueryResponse; import ddf.catalog.plugin.PluginExecutionException; import ddf.catalog.plugin.StopProcessingException; import ddf.catalog.source.SourceUnavailableException; import ddf.catalog.source.UnsupportedQueryException; import ddf.catalog.validation.ValidationException; import ddf.catalog.validation.report.MetacardValidationReport; import ddf.catalog.validation.violation.ValidationViolation; @RunWith(MockitoJUnitRunner.class) public class TestDuplicationValidator { @Mock(answer = Answers.RETURNS_DEEP_STUBS) private FilterBuilder mockFilterBuilder; @Mock private CatalogFramework mockFramework; private DuplicationValidator validator; private MetacardImpl matchingMetacard; private MetacardImpl testMetacard; private static final String ID = "matching metacard id"; private static final String TAG1 = "1"; private static final String TAG2 = "2"; private Set tags = new HashSet<>(Arrays.asList(TAG1, TAG2)); @Before public void setup() throws UnsupportedQueryException, SourceUnavailableException, FederationException { QueryResponse response = mock(QueryResponse.class); when(mockFramework.query(any(QueryRequest.class))).thenReturn(response); testMetacard = new MetacardImpl(); matchingMetacard = new MetacardImpl(); matchingMetacard.setId(ID); testMetacard.setId("test metacard ID"); matchingMetacard.setAttribute(new AttributeImpl(Metacard.CHECKSUM, "checksum-value")); testMetacard.setAttribute(new AttributeImpl(Metacard.CHECKSUM, "checksum-value")); matchingMetacard.setTags(tags); testMetacard.setTags(tags); List<Result> results = Arrays.asList(new ResultImpl(matchingMetacard)); when(response.getResults()).thenReturn(results); validator = new DuplicationValidator(mockFramework, mockFilterBuilder); } @Test(expected = IllegalArgumentException.class) public void testValidateMetacardNullInput() { validator.validateMetacard(null); } @Test(expected = IllegalArgumentException.class) public void testValidateNullInput() throws ValidationException { validator.validate(null); } @Test public void testValidateMetacardNullConfiguration() throws ValidationException { validator.setWarnOnDuplicateAttributes(null); validator.setErrorOnDuplicateAttributes(null); Optional<MetacardValidationReport> report = validator.validateMetacard(testMetacard); assertThat(report.isPresent(), is(false)); } @Test public void testValidateNullConfiguration() throws ValidationException { validator.setWarnOnDuplicateAttributes(null); validator.setErrorOnDuplicateAttributes(null); // verify no exception thrown validator.validate(testMetacard); } @Test public void testValidateMetacardBlankConfiguration() throws ValidationException { validator.setWarnOnDuplicateAttributes(new String[0]); validator.setErrorOnDuplicateAttributes(new String[0]); Optional<MetacardValidationReport> report = validator.validateMetacard(testMetacard); assertThat(report.isPresent(), is(false)); } @Test public void testValidateBlankConfiguration() throws ValidationException { validator.setWarnOnDuplicateAttributes(new String[0]); validator.setErrorOnDuplicateAttributes(new String[0]); // verify no exception thrown validator.validate(testMetacard); } @Test public void testValidateMetacardWithValidationErrorAndWarning() { String[] checksumAttribute = {Metacard.CHECKSUM}; String[] idAttribute = {Metacard.ID}; validator.setWarnOnDuplicateAttributes(checksumAttribute); validator.setErrorOnDuplicateAttributes(idAttribute); Optional<MetacardValidationReport> report = validator.validateMetacard(testMetacard); assertThat(report.isPresent(), is(true)); assertThat(report.get() .getMetacardValidationViolations(), hasSize(2)); Map<ValidationViolation.Severity, ValidationViolation> violations = report.get() .getMetacardValidationViolations() .stream() .collect(Collectors.toMap(ValidationViolation::getSeverity, Function.identity())); ValidationViolation warnViolation = violations.get(ValidationViolation.Severity.WARNING); ValidationViolation errorViolation = violations.get(ValidationViolation.Severity.ERROR); assertThat(warnViolation.getAttributes(), is(new HashSet<>(Arrays.asList(checksumAttribute)))); assertThat(warnViolation.getMessage(), containsString(Metacard.CHECKSUM)); assertThat(errorViolation.getAttributes(), is(new HashSet<>(Arrays.asList(idAttribute)))); assertThat(errorViolation.getMessage(), containsString(Metacard.ID)); } @Test public void testValidateWithValidationErrorAndWarning() throws ValidationException { String[] checksumAttribute = {Metacard.CHECKSUM}; String[] idAttribute = {Metacard.ID}; ValidationException expectedException = null; validator.setWarnOnDuplicateAttributes(checksumAttribute); validator.setErrorOnDuplicateAttributes(idAttribute); try { validator.validate(testMetacard); } catch (ValidationException e) { expectedException = e; } assertThat(expectedException, is(not(nullValue()))); assertThat(expectedException.getMessage(), is(not(nullValue()))); assertThat(expectedException.getErrors() .size(), is(1)); assertThat(expectedException.getWarnings() .size(), is(1)); expectedException.getWarnings() .forEach(warning -> assertThat(warning, containsString(Metacard.CHECKSUM))); expectedException.getErrors() .forEach(error -> assertThat(error, containsString(Metacard.ID))); } @Test public void testValidateMetacardWithMultiValuedAttribute() throws StopProcessingException, PluginExecutionException, FederationException, UnsupportedQueryException, SourceUnavailableException { String[] tagAttributes = {Metacard.TAGS}; ArgumentCaptor<String> attributeValueCaptor = ArgumentCaptor.forClass(String.class); ArgumentCaptor<QueryRequest> queryRequestCaptor = ArgumentCaptor.forClass(QueryRequest.class); when(mockFilterBuilder.attribute(anyString()) .equalTo() .text(attributeValueCaptor.capture())).thenReturn(mock(Filter.class)); String[] attributes = {Metacard.TAGS}; validator.setWarnOnDuplicateAttributes(attributes); Optional<MetacardValidationReport> report = validator.validateMetacard(testMetacard); assertThat(report.isPresent(), is(true)); assertThat(report.get() .getMetacardValidationViolations() .size(), is(1)); verify(mockFramework).query(queryRequestCaptor.capture()); assertThat(attributeValueCaptor.getAllValues(), hasItems(TAG1, TAG2)); report.get() .getMetacardValidationViolations() .forEach(violation -> { assertThat(violation.getAttributes(), is(new HashSet<>(Arrays.asList( tagAttributes)))); assertThat(violation.getMessage(), containsString(Metacard.TAGS)); }); } }