ScriptEngineActivationStrategy implements ActivationStrategy { @Override public boolean isActive(FeatureState featureState, FeatureUser user) { String lang = featureState.getParameter(PARAM_LANG); String script = featureState.getParameter(PARAM_SCRIPT); ScriptEngine engine = engineManager.getEngineByName(lang); if (engine == null) { log.error("Could not find script engine for: " + lang); return false; } engine.put("user", user); engine.put("date", new Date()); try { Object result = engine.eval(script); if (result instanceof Boolean) { return ((Boolean) result).booleanValue(); } } catch (ScriptException e) { log.error("Could not evaluate script for feature " + featureState.getFeature().name() + ": " + e.getMessage()); } return false; } ScriptEngineActivationStrategy(); @Override String getId(); @Override String getName(); @Override boolean isActive(FeatureState featureState, FeatureUser user); @Override Parameter[] getParameters(); static final String ID; static final String PARAM_SCRIPT; static final String PARAM_LANG; }
@Test public void shouldReturnFalseForUnsupportedLanguage() { ScriptEngineActivationStrategy strategy = new ScriptEngineActivationStrategy(); FeatureState state = aScriptState(UNKNOWN_LANGUAGE, SOME_SCRIPT); boolean active = strategy.isActive(state, aFeatureUser("john")); assertFalse(active); }
@Test public void shouldReturnFalseForInvalidJavaScript() { ScriptEngineActivationStrategy strategy = new ScriptEngineActivationStrategy(); FeatureState state = aScriptState(JAVASCRIPT, INVALID_JAVASCRIPT); boolean active = strategy.isActive(state, aFeatureUser("john")); assertFalse(active); }
@Test public void shouldReturnSameResultAsScriptForLiterals() { ScriptEngineActivationStrategy strategy = new ScriptEngineActivationStrategy(); FeatureState stateAlwaysTrue = aScriptState(JAVASCRIPT, "1 == 1"); assertTrue(strategy.isActive(stateAlwaysTrue, aFeatureUser("john"))); FeatureState stateAlwaysFalse = aScriptState(JAVASCRIPT, "0 == 1"); assertFalse(strategy.isActive(stateAlwaysFalse, aFeatureUser("john"))); }
@Test public void scriptCanAccessCurrentUser() { ScriptEngineActivationStrategy strategy = new ScriptEngineActivationStrategy(); FeatureState state = aScriptState(JAVASCRIPT, "user.name == 'john'"); assertTrue(strategy.isActive(state, aFeatureUser("john"))); assertFalse(strategy.isActive(state, aFeatureUser("jim"))); }
@Test public void scriptCanAccessUserAttributes() { ScriptEngineActivationStrategy strategy = new ScriptEngineActivationStrategy(); FeatureState ageCheck = aScriptState(JAVASCRIPT, "user.getAttribute('age') >= 21"); SimpleFeatureUser child = aFeatureUser("john"); child.setAttribute("age", 12); assertFalse(strategy.isActive(ageCheck, child)); SimpleFeatureUser adult = aFeatureUser("peter"); adult.setAttribute("age", 25); assertTrue(strategy.isActive(ageCheck, adult)); }
@Test public void scriptCanAccessCurrentDate() { ScriptEngineActivationStrategy strategy = new ScriptEngineActivationStrategy(); int currentYear = Calendar.getInstance().get(GregorianCalendar.YEAR) - 1900; FeatureState trueForCurrentYear = aScriptState(JAVASCRIPT, "date.year == " + currentYear); assertTrue(strategy.isActive(trueForCurrentYear, aFeatureUser("john"))); FeatureState trueForNextYear = aScriptState(JAVASCRIPT, "date.year > " + currentYear); assertFalse(strategy.isActive(trueForNextYear, aFeatureUser("john"))); }
@Test public void shouldSupportMultilineScripts() { ScriptEngineActivationStrategy strategy = new ScriptEngineActivationStrategy(); FeatureState state = aScriptState(JAVASCRIPT, "var len = user.name.length();\r\n len % 2 == 0;\n"); assertTrue(strategy.isActive(state, aFeatureUser("john"))); assertFalse(strategy.isActive(state, aFeatureUser("jim"))); }
@Test public void shouldSupportScriptWithFunction() { ScriptEngineActivationStrategy strategy = new ScriptEngineActivationStrategy(); FeatureState state = aScriptState(JAVASCRIPT, "function isJohn(name) { return name == 'john' }; isJohn(user.name);"); assertTrue(strategy.isActive(state, aFeatureUser("john"))); assertFalse(strategy.isActive(state, aFeatureUser("jim"))); }