package com.hida.controller;
import com.hida.model.AutoIdGenerator;
import com.hida.model.BadParameterException;
import com.hida.model.CustomIdGenerator;
import com.hida.model.DefaultSetting;
import com.hida.model.IdGenerator;
import com.hida.model.Pid;
import com.hida.model.Token;
import com.hida.service.MinterService;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import junit.framework.Assert;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.testng.annotations.DataProvider;
/**
* Class that tests MinterController
*
* @author lruffin
*/
public class MinterControllerTest {
@Mock
private MinterService minterServiceDao_;
@InjectMocks
private MinterController controller_;
private final String PREPEND = "http://digitalarchives.hawaii.gov/70111/";
private final int AMOUNT = 5;
@BeforeClass
public void setUpClass() throws Exception {
MockitoAnnotations.initMocks(this);
}
/**
* Returns a data set. Each array contains attributes found in setting.html
*
* @return A data set
*/
@DataProvider(name = "request parameters")
private Object[][] requestParameters() {
return new Object[][]{
{PREPEND, "xyz", "auto", "random", "true", "1", "true", null, null, "mmm"},
{PREPEND, "xyz", "false", "false", null, "1", "true", "true", null, "mmm"},
{PREPEND, "xyz", "false", "false", null, "1", "true", "true", "true", "mmm"},
{PREPEND, "xyz", "false", "false", null, "1", null, "true", null, "mmm"},
{PREPEND, "xyz", "false", "false", null, "1", null, "true", "true", "mmm"},
{PREPEND, "xyz", "false", "false", null, "1", null, null, "true", "mmm"},
{PREPEND, "xyz", "false", "false", null, "1", "true", null, null, "mmm"},};
}
/**
* Returns a data set. Each array contains fields that can be exclusively
* held by a DefaultSetting.
*
* @return A dataset
*/
@DataProvider(name = "parameters")
private Object[][] parameters() {
return new Object[][]{
{PREPEND, "abc", Token.DIGIT, "d", 1, true, true, true},
{PREPEND, "abc", Token.LOWER_CONSONANTS, "d", 1, true, true, true},
{PREPEND, "abc", Token.UPPER_CONSONANTS, "d", 1, true, true, true},
{PREPEND, "abc", Token.MIXED_CONSONANTS, "d", 1, true, true, true},
{PREPEND, "abc", Token.LOWER_CONSONANTS_EXTENDED, "d", 1, true, true, true},
{PREPEND, "abc", Token.UPPER_CONSONANTS_EXTENDED, "d", 1, true, true, true},
{PREPEND, "abc", Token.MIXED_CONSONANTS_EXTENDED, "d", 1, true, true, true},
{PREPEND, "abc", Token.DIGIT, "d", 1, true, true, false},
{PREPEND, "abc", Token.LOWER_ALPHABET, "d", 1, true, true, false},
{PREPEND, "abc", Token.UPPER_ALPHABET, "d", 1, true, true, false},
{PREPEND, "abc", Token.MIXED_ALPHABET, "d", 1, true, true, false},
{PREPEND, "abc", Token.LOWER_ALPHABET_EXTENDED, "d", 1, true, true, false},
{PREPEND, "abc", Token.UPPER_ALPHABET_EXTENDED, "d", 1, true, true, false},
{PREPEND, "abc", Token.MIXED_ALPHABET_EXTENDED, "d", 1, true, true, false},
{PREPEND, "abc", Token.DIGIT, "d", 1, false, true, false},
{PREPEND, "abc", Token.DIGIT, "l", 1, false, true, false},
{PREPEND, "abc", Token.DIGIT, "u", 1, false, true, false},
{PREPEND, "abc", Token.DIGIT, "m", 1, false, true, false},
{PREPEND, "abc", Token.DIGIT, "e", 1, false, true, false},};
}
/**
* Returns a dataset that holds colloquially accepted values for booleans
* that automatically parses as false by the Boolean static methods.
*
* @return A data set
*/
@DataProvider(name = "bad booleans")
private Object[][] badBooleans() {
return new Object[][]{
{"auto", "t"},
//{"random", "f"},
{"sansVowels", "yes"},};
}
/**
* Tests data entry in the administration panel found at setting.html
*
* The following parameters are parameters that are contained in the request
* object
*
* @param prepend Primarily used to turn a Pid into a PURL
* @param idprefix A sequence of characters that appear in the beginning of
* PIDs
* @param mintType Determines which IdGenerator, auto or random, to use
* @param mintOrder Determines the order, randomly or sequentially, the Pids
* are minted
* @param vowels Boolean that determines whether or not the the Pids should
* contain vowels
* @param idLength Designates the length of the id's root
* @param digits Boolean that determines whether or not the Pids will
* contain numbers
* @param lowercase Boolean that determines whether or not the Pids will
* contain lowercase
* @param uppercase Boolean that determines whether or not the Pids will
* contain uppercase
* @param charMapping A sequence of characters used to configure PIDs
* @throws Exception
*/
@Test(dataProvider = "request parameters")
public void testHandleForm(String prepend, String idprefix, String mintType,
String mintOrder, String vowels, String idLength, String digits,
String lowercase, String uppercase, String charMapping) throws Exception {
// create a DefaultSetting object and create mock request and response object
DefaultSetting originalSetting = getSampleDefaultSetting();
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
// assign values to the mock request object
request.setParameter("prepend", prepend);
request.setParameter("idprefix", idprefix);
request.setParameter("mintType", mintType);
request.setParameter("mintOrder", mintOrder);
request.setParameter("vowels", vowels);
request.setParameter("idlength", idLength);
request.setParameter("digits", digits);
request.setParameter("lowercase", lowercase);
request.setParameter("uppercase", uppercase);
request.setParameter("charmapping", charMapping);
// return originalSetting whenever CurrentSetting is called
when(minterServiceDao_.getStoredSetting()).thenReturn(originalSetting);
doNothing().when(minterServiceDao_).
updateCurrentSetting(any(DefaultSetting.class));
// call the method to test
controller_.handleForm("prepend",
"idprefix",
"",
"mintType",
"mintOrder",
true,
5,
"charmapping",
false,
true,
true,
request, response);
// get and test the url of the destination
String viewName = response.getHeader("Location");
Assert.assertEquals("administration", viewName);
}
/**
* Tests the /mint endpoint by submitting parameters through it.
*
* @throws Exception
*/
@Test
public void testMintRequestedParameters() throws Exception {
// create a map to hold parameters
Map<String, String> map = getSampleMap();
// create DefaultSetting object to represent the original object
DefaultSetting originalSetting = getSampleDefaultSetting();
// create DefaultSetting object to represent the changes
DefaultSetting tempSetting = getSampleDefaultSetting();
// change the values of tempSetting to anticipate the changes done overrideSetting methods
tempSetting.setPrepend(map.get("prepend"));
tempSetting.setPrefix(map.get("prefix"));
tempSetting.setRootLength(Integer.parseInt(map.get("rootLength")));
tempSetting.setCharMap(map.get("charMap"));
tempSetting.setTokenType(Token.valueOf(map.get("tokenType")));
tempSetting.setAuto(Boolean.getBoolean(map.get("auto")));
tempSetting.setRandom(Boolean.getBoolean(map.get("random")));
tempSetting.setSansVowels(Boolean.getBoolean(map.get("sansVowels")));
Set<Pid> sampleSet = getSampleSet(tempSetting);
// return originalSetting when getStoredSetting is called and a sample Pid set
when(minterServiceDao_.getStoredSetting()).thenReturn(originalSetting);
when(minterServiceDao_.mint(anyInt(), any(DefaultSetting.class))).
thenReturn(getSampleSet(tempSetting));
Set<Pid> pidSet = controller_.mintPids(AMOUNT, map);
Assert.assertEquals(sampleSet.size(), pidSet.size());
}
/**
* Tests to see if the MinterController will call persisted settings
*
* @param prepend Primarily used to turn a Pid into a PURL
* @param prefix A sequence of characters that appear in the beginning of
* PIDs
* @param tokenType An enum used to configure PIDS
* @param charMap A sequence of characters used to configure PIDs
* @param rootLength Designates the length of the id's root
* @param isAuto Determines which generator, either Auto or Custom, will be
* used
* @param isRandom Determines if the PIDs are created randomly or
* sequentially
* @param sansVowel Dictates whether or not vowels are allowed
* @throws Exception
*/
@Test(dataProvider = "parameters")
public void testMintPersistedParameters(String prepend, String prefix, Token tokenType,
String charMap, int rootLength, boolean isAuto, boolean isRandom, boolean sansVowel)
throws Exception {
DefaultSetting setting = new DefaultSetting(prepend, prefix, 5, tokenType, charMap,
rootLength, isAuto, isRandom, sansVowel);
Set<Pid> sampleSet = getSampleSet(setting);
when(minterServiceDao_.getStoredSetting()).thenReturn(setting);
when(minterServiceDao_.mint(anyInt(), any(DefaultSetting.class))).
thenReturn(sampleSet);
Set<Pid> pidSet = controller_.mintPids(AMOUNT, new HashMap<String, String>());
Assert.assertEquals(sampleSet.size(), pidSet.size());
}
/**
* Tests to see if the MinterController will properly throw an error when a
* non-boolean is entered into the /mint endpoint
*
* @param key The boolean
* @param value The entered value of the boolean
* @throws Exception
*/
@Test(expectedExceptions = BadParameterException.class, dataProvider = "bad booleans")
public void testBadParameterExceptionBoolean(String key, String value) throws Exception {
Map<String, String> parameters = new HashMap<>();
parameters.put(key, value);
DefaultSetting setting = this.getSampleDefaultSetting();
when(minterServiceDao_.getStoredSetting()).thenReturn(setting);
controller_.mintPids(AMOUNT, parameters);
}
/**
* Tests to see if MinterController will properly throw an error when an
* invalid tokenType is entered into the /mint endpoint
*
* @throws Exception
*/
@Test(expectedExceptions = IllegalArgumentException.class)
public void testBadParameterExceptionTokenType() throws Exception {
Map<String, String> parameters = new HashMap<>();
parameters.put("tokenType", "digit");
DefaultSetting setting = this.getSampleDefaultSetting();
when(minterServiceDao_.getStoredSetting()).thenReturn(setting);
controller_.mintPids(AMOUNT, parameters);
}
/**
* Tests to see if MinterController will properly throw an error when an
* invalid charMap is entered into the /mint endpoint
*
* @throws Exception
*/
@Test(expectedExceptions = BadParameterException.class)
public void testBadParameterExceptionCharMap() throws Exception {
Map<String, String> parameters = new HashMap<>();
parameters.put("charMap", "dlumea");
DefaultSetting setting = this.getSampleDefaultSetting();
when(minterServiceDao_.getStoredSetting()).thenReturn(setting);
controller_.mintPids(AMOUNT, parameters);
}
/**
* Tests to see if MinterController will properly throw an error when an
* invalid amount is entered into the /mint endpoint
*
* @throws Exception
*/
@Test(expectedExceptions = BadParameterException.class)
public void testBadParameterExceptionAmount() throws Exception {
Map<String, String> parameters = new HashMap<>();
DefaultSetting setting = this.getSampleDefaultSetting();
when(minterServiceDao_.getStoredSetting()).thenReturn(setting);
controller_.mintPids(-1, parameters);
}
/**
* Tests to see if MinterController will properly throw an error when an
* invalid prefix is entered into the /mint endpoint
*
* @throws Exception
*/
@Test(expectedExceptions = BadParameterException.class)
public void testBadParameterExceptionPrefix() throws Exception {
Map<String, String> parameters = new HashMap<>();
parameters.put("prefix", " ");
DefaultSetting setting = this.getSampleDefaultSetting();
when(minterServiceDao_.getStoredSetting()).thenReturn(setting);
controller_.mintPids(AMOUNT, parameters);
}
/**
* Returns a sample DefaultSetting object
*
* @return
*/
private DefaultSetting getSampleDefaultSetting() {
DefaultSetting setting = new DefaultSetting("", // prepend
"", // prefix
5,
Token.MIXED_ALPHABET, // tokentype
"mmm", // charmap
3, // rootlength
true, // sansvowel
true, // auto
true); // random
return setting;
}
/**
* Returns a sample set of Pids
*
* @param setting
* @return
*/
private Set<Pid> getSampleSet(DefaultSetting setting) {
IdGenerator generator;
if (setting.isAuto()) {
generator = new AutoIdGenerator(setting.getPrefix(),
setting.getTokenType(),
setting.getRootLength());
}
else {
generator = new CustomIdGenerator(setting.getPrefix(),
setting.isSansVowels(),
setting.getCharMap());
}
Set<Pid> set;
if (setting.isRandom()) {
set = generator.randomMint(AMOUNT);
}
else {
set = generator.sequentialMint(AMOUNT);
}
return set;
}
/**
* Returns a sample map object
*
* @return
*/
private Map<String, String> getSampleMap() {
Map<String, String> map = new HashMap<>();
map.put("prepend", PREPEND);
map.put("prefix", "xyz");
map.put("tokenType", "LOWER_ALPHABET");
map.put("charMap", "m");
map.put("rootLength", "2");
map.put("auto", "false");
map.put("random", "false");
map.put("sansVowel", "false");
return map;
}
}