VIVO-12 NIHVIVO-4011 Provide config and GUI for selecting Locale
This commit is contained in:
parent
1ba6204815
commit
bb6b2fa970
19 changed files with 1346 additions and 10 deletions
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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.");
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue