VIVO-12 NIHVIVO-4011 Provide config and GUI for selecting Locale

This commit is contained in:
j2blake 2013-01-24 16:21:36 -05:00
parent 1ba6204815
commit bb6b2fa970
19 changed files with 1346 additions and 10 deletions

View file

@ -0,0 +1,314 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.i18n.selection;
import static edu.cornell.mannlib.vitro.webapp.i18n.selection.LocaleSelectionSetup.PROPERTY_FORCE_LOCALE;
import static edu.cornell.mannlib.vitro.webapp.i18n.selection.LocaleSelectionSetup.PROPERTY_SELECTABLE_LOCALES;
import static edu.cornell.mannlib.vitro.webapp.i18n.selection.SelectedLocale.ATTRIBUTE_NAME;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import javax.servlet.ServletContextEvent;
import org.apache.commons.lang.LocaleUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.log4j.Level;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import stubs.edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesStub;
import stubs.edu.cornell.mannlib.vitro.webapp.startup.StartupStatusStub;
import stubs.javax.servlet.ServletContextStub;
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.i18n.selection.SelectedLocale.ContextSelectedLocale;
/**
* TODO
*/
public class LocaleSelectionSetupTest extends AbstractTestClass {
// ----------------------------------------------------------------------
// Infrastructure
// ----------------------------------------------------------------------
private LocaleSelectionSetup lss;
private ServletContextStub ctx;
private ServletContextEvent sce;
private ConfigurationPropertiesStub props;
private StartupStatusStub ss;
private int[] expectedMessageCounts;
private Locale expectedForcedLocale;
private List<Locale> expectedSelectableLocales;
@Before
public void setup() {
// setLoggerLevel(LocaleSelectionSetup.class, Level.DEBUG);
// setLoggerLevel(StartupStatusStub.class, Level.DEBUG);
setLoggerLevel(ConfigurationProperties.class, Level.WARN);
ctx = new ServletContextStub();
sce = new ServletContextEvent(ctx);
props = new ConfigurationPropertiesStub();
props.setBean(ctx);
ss = new StartupStatusStub(ctx);
lss = new LocaleSelectionSetup();
}
@After
public void checkExpectations() {
if (expectedMessageCounts == null) {
fail("expecteMessages() was not called");
}
String message = compareMessageCount("info", ss.getInfoCount(),
expectedMessageCounts[0])
+ compareMessageCount("warning", ss.getWarningCount(),
expectedMessageCounts[1])
+ compareMessageCount("fatal", ss.getFatalCount(),
expectedMessageCounts[2])
+ checkForced()
+ checkSelectable();
if (!message.isEmpty()) {
fail(message);
}
}
private String compareMessageCount(String label, int actual, int expected) {
if (expected == actual) {
return "";
} else {
return "expecting " + expected + " " + label
+ " messages, but received " + actual + "; ";
}
}
private String checkForced() {
Locale actual = null;
Object o = ctx.getAttribute(ATTRIBUTE_NAME);
if (o instanceof ContextSelectedLocale) {
actual = ((ContextSelectedLocale) o).getForcedLocale();
}
Locale expected = expectedForcedLocale;
if (ObjectUtils.equals(expected, actual)) {
return "";
} else {
return "expected forced locale of " + expectedForcedLocale
+ ", but was " + actual + "; ";
}
}
private String checkSelectable() {
List<Locale> actual = Collections.emptyList();
Object o = ctx.getAttribute(ATTRIBUTE_NAME);
if (o instanceof ContextSelectedLocale) {
actual = ((ContextSelectedLocale) o).getSelectableLocales();
}
List<Locale> expected = expectedSelectableLocales;
if (expected == null) {
expected = Collections.emptyList();
}
if (ObjectUtils.equals(expected, actual)) {
return "";
} else {
return "expected selectable locales of " + expected + ", but was "
+ actual + "; ";
}
}
// ----------------------------------------------------------------------
// The tests
// ----------------------------------------------------------------------
// General functionality
@Test
public void neitherPropertyIsSpecified() {
lss.contextInitialized(sce);
expectMessages(1, 0, 0);
}
@Test
public void forceSuccessL() {
props.setProperty(PROPERTY_FORCE_LOCALE, "es");
lss.contextInitialized(sce);
expectForced("es");
expectMessages(1, 0, 0);
}
@Test
public void forceSuccessL_C() {
props.setProperty(PROPERTY_FORCE_LOCALE, "es_ES");
lss.contextInitialized(sce);
expectForced("es_ES");
expectMessages(1, 0, 0);
}
@Test
public void forceSuccessL_C_V() {
props.setProperty(PROPERTY_FORCE_LOCALE, "no_NO_NY");
lss.contextInitialized(sce);
expectForced("no_NO_NY");
expectMessages(1, 0, 0);
}
@Test
public void oneSelectable() {
props.setProperty(PROPERTY_SELECTABLE_LOCALES, "fr_FR");
lss.contextInitialized(sce);
expectSelectable("fr_FR");
expectMessages(1, 0, 0);
}
@Test
public void twoSelectables() {
props.setProperty(PROPERTY_SELECTABLE_LOCALES, "fr_FR, es_PE");
lss.contextInitialized(sce);
expectSelectable("fr_FR", "es_PE");
expectMessages(1, 0, 0);
}
@Test
public void bothPropertiesAreSpecified() {
props.setProperty(PROPERTY_FORCE_LOCALE, "es_ES");
props.setProperty(PROPERTY_SELECTABLE_LOCALES, "fr_FR");
lss.contextInitialized(sce);
expectForced("es_ES");
expectMessages(1, 1, 0);
}
// Locale string syntax (common to both force and selectable)
@Test
public void langaugeIsEmpty() {
props.setProperty(PROPERTY_FORCE_LOCALE, "_ES");
lss.contextInitialized(sce);
expectMessages(0, 1, 0);
}
@Test
public void languageWrongLength() {
props.setProperty(PROPERTY_FORCE_LOCALE, "e_ES");
lss.contextInitialized(sce);
expectMessages(0, 1, 0);
}
@Test
public void languageNotAlphabetic() {
props.setProperty(PROPERTY_FORCE_LOCALE, "e4_ES");
lss.contextInitialized(sce);
expectMessages(0, 1, 0);
}
@Test
public void languageNotLowerCase() {
props.setProperty(PROPERTY_FORCE_LOCALE, "eS_ES");
lss.contextInitialized(sce);
expectMessages(0, 1, 0);
}
@Test
public void countryIsEmpty() {
props.setProperty(PROPERTY_FORCE_LOCALE, "es_ _13");
lss.contextInitialized(sce);
expectMessages(0, 1, 0);
}
@Test
public void countryWrongLength() {
props.setProperty(PROPERTY_FORCE_LOCALE, "es_ESS");
lss.contextInitialized(sce);
expectMessages(0, 1, 0);
}
@Test
public void countryNotAlphabetic() {
props.setProperty(PROPERTY_FORCE_LOCALE, "es_E@");
lss.contextInitialized(sce);
expectMessages(0, 1, 0);
}
@Test
public void countryNotUpperCase() {
props.setProperty(PROPERTY_FORCE_LOCALE, "es_es");
lss.contextInitialized(sce);
expectMessages(0, 1, 0);
}
@Test
public void variantIsEmpty() {
props.setProperty(PROPERTY_FORCE_LOCALE, "es_ES_");
lss.contextInitialized(sce);
expectMessages(0, 1, 0);
}
@Test
public void funkyVariantIsAcceptable() {
props.setProperty(PROPERTY_FORCE_LOCALE, "es_ES_123_aa");
lss.contextInitialized(sce);
expectForced("es_ES_123_aa");
expectMessages(1, 1, 0);
}
@Test
public void localeNotRecognizedProducesWarning() {
props.setProperty(PROPERTY_FORCE_LOCALE, "es_FR");
lss.contextInitialized(sce);
expectForced("es_FR");
expectMessages(1, 1, 0);
}
// Syntax of selectable property
@Test
public void emptySelectableLocaleProducesWarning() {
props.setProperty(PROPERTY_SELECTABLE_LOCALES, "es_ES, , fr_FR");
lss.contextInitialized(sce);
expectSelectable("es_ES", "fr_FR");
expectMessages(1, 1, 0);
}
@Test
public void blanksAroundCommasAreIgnored() {
props.setProperty(PROPERTY_SELECTABLE_LOCALES, "es_ES,en_US \t , fr_FR");
lss.contextInitialized(sce);
expectSelectable("es_ES", "en_US", "fr_FR");
expectMessages(1, 0, 0);
}
// ----------------------------------------------------------------------
// helper methods
// ----------------------------------------------------------------------
private void expectMessages(int infoCount, int warningCount, int fatalCount) {
this.expectedMessageCounts = new int[] { infoCount, warningCount,
fatalCount };
}
private void expectForced(String localeString) {
this.expectedForcedLocale = stringToLocale(localeString);
}
private void expectSelectable(String... strings) {
List<Locale> list = new ArrayList<Locale>();
for (String string : strings) {
list.add(stringToLocale(string));
}
this.expectedSelectableLocales = list;
}
private Locale stringToLocale(String string) {
return LocaleUtils.toLocale(string);
}
}

View file

@ -0,0 +1,140 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package stubs.edu.cornell.mannlib.vitro.webapp.startup;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
/**
* Keep track of how many messages come in.
*/
public class StartupStatusStub extends StartupStatus {
private static final Log log = LogFactory.getLog(StartupStatusStub.class);
// ----------------------------------------------------------------------
// Stub infrastructure
// ----------------------------------------------------------------------
private int infoCount = 0;
private int warningCount = 0;
private int fatalCount = 0;
public StartupStatusStub(ServletContext ctx) {
ctx.setAttribute(ATTRIBUTE_NAME, this);
}
public int getInfoCount() {
return infoCount;
}
public int getWarningCount() {
return warningCount;
}
public int getFatalCount() {
return fatalCount;
}
// ----------------------------------------------------------------------
// Stub methods
// ----------------------------------------------------------------------
@Override
public void info(ServletContextListener listener, String message) {
log.debug("INFO: " + message);
infoCount++;
}
@Override
public void info(ServletContextListener listener, String message,
Throwable cause) {
log.debug("INFO: " + message + " " + cause);
infoCount++;
}
@Override
public void warning(ServletContextListener listener, String message) {
log.debug("WARNING: " + message);
warningCount++;
}
@Override
public void warning(ServletContextListener listener, String message,
Throwable cause) {
log.debug("WARNING: " + message + " " + cause);
warningCount++;
}
@Override
public void fatal(ServletContextListener listener, String message) {
log.debug("FATAL: " + message);
fatalCount++;
}
@Override
public void fatal(ServletContextListener listener, String message,
Throwable cause) {
log.debug("FATAL: " + message + " " + cause);
fatalCount++;
}
// ----------------------------------------------------------------------
// Un-implemented methods
// ----------------------------------------------------------------------
@Override
public void listenerNotExecuted(ServletContextListener listener) {
throw new RuntimeException(
"StartupStatusStub.listenerNotExecuted() not implemented.");
}
@Override
public void listenerExecuted(ServletContextListener listener) {
throw new RuntimeException(
"StartupStatusStub.listenerExecuted() not implemented.");
}
@Override
public boolean allClear() {
throw new RuntimeException(
"StartupStatusStub.allClear() not implemented.");
}
@Override
public boolean isStartupAborted() {
throw new RuntimeException(
"StartupStatusStub.isStartupAborted() not implemented.");
}
@Override
public List<StatusItem> getStatusItems() {
throw new RuntimeException(
"StartupStatusStub.getStatusItems() not implemented.");
}
@Override
public List<StatusItem> getErrorItems() {
throw new RuntimeException(
"StartupStatusStub.getErrorItems() not implemented.");
}
@Override
public List<StatusItem> getWarningItems() {
throw new RuntimeException(
"StartupStatusStub.getWarningItems() not implemented.");
}
@Override
public List<StatusItem> getItemsForListener(ServletContextListener listener) {
throw new RuntimeException(
"StartupStatusStub.getItemsForListener() not implemented.");
}
}