Skip to content

Commit

Permalink
Fixed NPE when underlying data was null, added few tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sparkhi committed Mar 20, 2024
1 parent 30cbd34 commit 3e5f3f1
Show file tree
Hide file tree
Showing 8 changed files with 267 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,6 @@ public ColumnType getColumnType() {
*/
@Override
public String getOperatedValue(String input) {
return input;
return input == null ? "" : input;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ public ColumnType getColumnType() {
*/
@Override
public String getOperatedValue(String input) {
if ((input == null) || (input.length() == 0)) {
return "";
}
switch(operation) {
case LCASE:
return input.toLowerCase();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@

import uk.gov.nationalarchives.droid.export.interfaces.ExportTemplate;
import uk.gov.nationalarchives.droid.export.interfaces.ExportTemplateColumnDef;
import uk.gov.nationalarchives.droid.profile.CsvWriterConstants;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -119,8 +121,12 @@ private ExportTemplateColumnDef createDataModifierDef(String header, String para
String column = tokens[1].trim().substring(0, tokens[1].trim().length() - 1);
ProfileResourceNodeColumnDef inner = createProfileNodeDef(header, column);

ExportTemplateColumnDef.DataModification operation = ExportTemplateColumnDef.DataModification.valueOf(operationName);
return new DataModifierColumnDef(inner, operation);
try {
ExportTemplateColumnDef.DataModification operation = ExportTemplateColumnDef.DataModification.valueOf(operationName);
return new DataModifierColumnDef(inner, operation);
} catch (IllegalArgumentException iae) {
throw new ExportTemplateParseException("Undefined operation '" + operationName + "' encountered in export template");
}
}

private ExportTemplateColumnDef createConstantStringDef(String header, String param2) {
Expand All @@ -136,6 +142,9 @@ private ExportTemplateColumnDef createConstantStringDef(String header, String pa

private ProfileResourceNodeColumnDef createProfileNodeDef(String header, String param2) {
String originalColumnName = param2.substring(1);
if (!(Arrays.stream(CsvWriterConstants.HEADERS).collect(Collectors.toList()).contains(originalColumnName))) {
throw new ExportTemplateParseException("Invalid column name. " + originalColumnName + " does not exist in profile results");
}
return new ProfileResourceNodeColumnDef(originalColumnName, header);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,6 @@ public ColumnType getColumnType() {
*/
@Override
public String getOperatedValue(String input) {
return input;
return input == null ? "" : input;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright (c) 2016, The National Archives <[email protected]>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the The National Archives nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package uk.gov.nationalarchives.droid.export.template;

import org.junit.Test;
import uk.gov.nationalarchives.droid.export.interfaces.ExportTemplateColumnDef;

import static org.junit.Assert.*;

public class ConstantStringColumnDefTest {
@Test
public void should_operate_on_null_value_and_return_empty_string() {
ConstantStringColumnDef def = new ConstantStringColumnDef("English (UK)", "Language");
assertEquals("", def.getOperatedValue(null));
}

@Test
public void should_return_input_as_it_is_when_asked_for_operated_value() {
ConstantStringColumnDef def = new ConstantStringColumnDef("English (UK)", "Language");
assertEquals("FoRMat", def.getOperatedValue("FoRMat"));
}

@Test
public void should_return_header_label_as_set_when_defining_the_column_definition() {
ConstantStringColumnDef def = new ConstantStringColumnDef("English (UK)", "Language");
assertEquals("Language", def.getHeaderLabel());
}
@Test
public void should_throw_exception_when_asking_for_original_column_name() {
ConstantStringColumnDef def = new ConstantStringColumnDef("English (UK)", "Language");
RuntimeException ex = assertThrows(RuntimeException.class, () -> def.getOriginalColumnName());
assertEquals("Constant String Columns do not have an associated original column name", ex.getMessage());
}

@Test
public void should_return_data_as_set_in_the_definition() {
ConstantStringColumnDef def = new ConstantStringColumnDef("English (UK)", "Language");
assertEquals("English (UK)", def.getDataValue());
}

@Test
public void should_return_column_type_as_data_modifier_column_def() {
ConstantStringColumnDef def = new ConstantStringColumnDef("English (UK)", "Language");
assertEquals(ExportTemplateColumnDef.ColumnType.ConstantString, def.getColumnType());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2016, The National Archives <[email protected]>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the The National Archives nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package uk.gov.nationalarchives.droid.export.template;

import org.junit.Test;
import uk.gov.nationalarchives.droid.export.interfaces.ExportTemplateColumnDef;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class DataModifierColumnDefTest {
@Test
public void should_operate_on_null_value_and_return_empty_string() {
ProfileResourceNodeColumnDef innerDef = mock(ProfileResourceNodeColumnDef.class);
DataModifierColumnDef def = new DataModifierColumnDef(innerDef, ExportTemplateColumnDef.DataModification.LCASE);
assertEquals("", def.getOperatedValue(null));
}

@Test
public void should_return_header_label_as_set_on_the_inner_profile_def() {
ProfileResourceNodeColumnDef innerDef = mock(ProfileResourceNodeColumnDef.class);
when(innerDef.getHeaderLabel()).thenReturn("InnerHeader");
DataModifierColumnDef def = new DataModifierColumnDef(innerDef, ExportTemplateColumnDef.DataModification.LCASE);
assertEquals("InnerHeader", def.getHeaderLabel());
}
@Test
public void should_return_original_column_name_as_set_on_the_inner_profile_def() {
ProfileResourceNodeColumnDef innerDef = mock(ProfileResourceNodeColumnDef.class);
when(innerDef.getOriginalColumnName()).thenReturn("FORMAT_NAME");
DataModifierColumnDef def = new DataModifierColumnDef(innerDef, ExportTemplateColumnDef.DataModification.LCASE);
assertEquals("FORMAT_NAME", def.getOriginalColumnName());
}

@Test
public void should_return_column_type_as_data_modifier_column_def() {
ProfileResourceNodeColumnDef innerDef = mock(ProfileResourceNodeColumnDef.class);
DataModifierColumnDef def = new DataModifierColumnDef(innerDef, ExportTemplateColumnDef.DataModification.LCASE);
assertEquals(ExportTemplateColumnDef.ColumnType.DataModifier, def.getColumnType());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,34 @@ public void should_throw_an_exception_if_the_constant_string_value_does_not_have
ExportTemplateParseException ex = assertThrows(ExportTemplateParseException.class, () -> builder.buildExportTemplate(tempFile.getAbsolutePath()));
assertEquals("The line with a constant value ('\"English') in template definition does not have closing quotes", ex.getMessage());
}

@Test
public void should_throw_an_exception_if_the_column_name_given_for_profile_resource_column_is_not_a_well_known_header() throws IOException {
ExportTemplateBuilder builder = new ExportTemplateBuilder();
File tempFile = temporaryFolder.newFile("export-task-test-default-encoding");
List<String> data = Arrays.asList(
"version 1.0",
"",
"Identifier: $UUID",
"");
Files.write(tempFile.toPath(), data, StandardOpenOption.WRITE);

ExportTemplateParseException ex = assertThrows(ExportTemplateParseException.class, () -> builder.buildExportTemplate(tempFile.getAbsolutePath()));
assertEquals("Invalid column name. UUID does not exist in profile results", ex.getMessage());
}

@Test
public void should_throw_an_exception_when_the_operation_is_unknown() throws IOException {
ExportTemplateBuilder builder = new ExportTemplateBuilder();
File tempFile = temporaryFolder.newFile("export-task-test-default-encoding");
List<String> data = Arrays.asList(
"version 1.0",
"",
"Identifier: Lower($ID)",
"");
Files.write(tempFile.toPath(), data, StandardOpenOption.WRITE);

ExportTemplateParseException ex = assertThrows(ExportTemplateParseException.class, () -> builder.buildExportTemplate(tempFile.getAbsolutePath()));
assertEquals("Undefined operation 'Lower' encountered in export template", ex.getMessage());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright (c) 2016, The National Archives <[email protected]>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the The National Archives nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package uk.gov.nationalarchives.droid.export.template;

import org.junit.Test;
import uk.gov.nationalarchives.droid.export.interfaces.ExportTemplateColumnDef;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;

public class ProfileResourceNodeColumnDefTest {
@Test
public void should_operate_on_null_value_and_return_empty_string() {
ProfileResourceNodeColumnDef def = new ProfileResourceNodeColumnDef("FORMAT_NAME", "Format");
assertEquals("", def.getOperatedValue(null));
}

@Test
public void should_return_input_as_it_is_when_asked_for_operated_value() {
ProfileResourceNodeColumnDef def = new ProfileResourceNodeColumnDef("FORMAT_NAME", "Format");
assertEquals("FoRMat", def.getOperatedValue("FoRMat"));
}

@Test
public void should_return_header_label_as_set_when_defining_the_column_definition() {
ProfileResourceNodeColumnDef def = new ProfileResourceNodeColumnDef("FORMAT_NAME", "Format");
assertEquals("Format", def.getHeaderLabel());
}
@Test
public void should_return_original_column_name_as_set_when_defining_the_column_definition() {
ProfileResourceNodeColumnDef def = new ProfileResourceNodeColumnDef("FORMAT_NAME", "Format");
assertEquals("FORMAT_NAME", def.getOriginalColumnName());
}

@Test
public void should_throw_exception_when_asking_for_data_from_the_definition() {
ProfileResourceNodeColumnDef def = new ProfileResourceNodeColumnDef("FORMAT_NAME", "Format");
RuntimeException ex = assertThrows(RuntimeException.class, () -> def.getDataValue());
assertEquals("Profile resource node column uses data from the profile results", ex.getMessage());
}

@Test
public void should_return_column_type_as_data_modifier_column_def() {
ProfileResourceNodeColumnDef def = new ProfileResourceNodeColumnDef("FORMAT_NAME", "Format");
assertEquals(ExportTemplateColumnDef.ColumnType.ProfileResourceNode, def.getColumnType());
}
}

0 comments on commit 3e5f3f1

Please sign in to comment.