/*
* Copyright (c) 2002-2012 Alibaba Group Holding Limited.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.citrus.turbine.util;
import static com.alibaba.citrus.test.TestUtil.*;
import static com.alibaba.citrus.util.CollectionUtil.*;
import static org.easymock.EasyMock.*;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.*;
import java.lang.reflect.Method;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.citrus.service.mappingrule.MappingRuleService;
import com.alibaba.citrus.service.moduleloader.ModuleLoaderService;
import com.alibaba.citrus.service.requestcontext.buffered.BufferedRequestContext;
import com.alibaba.citrus.service.template.TemplateService;
import com.alibaba.citrus.turbine.Context;
import com.alibaba.citrus.turbine.support.AbstractContext;
import com.alibaba.citrus.turbine.util.ControlTool.ControlParameters;
import com.alibaba.citrus.webx.WebxComponents;
import com.alibaba.test.app1.module.control.MyControlChangingTemplate;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class ControlToolTests extends AbstractPullToolTests<ControlTool> {
@Override
protected String toolName() {
return "control";
}
@Before
public void init() throws Exception {
rundata.getResponse().getWriter();
}
@After
public void destroy() {
while (rundata.getCurrentContext() != null) {
rundata.popContext();
}
}
@Test
public void init_noAutowiring() throws Exception {
assertInit("components");
assertInit("moduleLoaderService");
assertInit("mappingRuleService");
assertInit("templateService");
assertInit("request");
assertInit("bufferedRequestContext");
}
private void assertInit(String missingName) throws Exception {
tool = new ControlTool();
if (!"components".equals(missingName)) {
getAccessibleField(ControlTool.class, "components").set(tool, createMock(WebxComponents.class));
}
if (!"moduleLoaderService".equals(missingName)) {
getAccessibleField(ControlTool.class, "moduleLoaderService").set(tool,
createMock(ModuleLoaderService.class));
}
if (!"mappingRuleService".equals(missingName)) {
getAccessibleField(ControlTool.class, "mappingRuleService").set(tool, createMock(MappingRuleService.class));
}
if (!"templateService".equals(missingName)) {
getAccessibleField(ControlTool.class, "templateService").set(tool, createMock(TemplateService.class));
}
if (!"request".equals(missingName)) {
getAccessibleField(ControlTool.class, "request").set(tool, createMock(HttpServletRequest.class));
}
if (!"bufferedRequestContext".equals(missingName)) {
getAccessibleField(ControlTool.class, "bufferedRequestContext").set(tool,
createMock(BufferedRequestContext.class));
}
try {
tool.afterPropertiesSet();
fail();
} catch (IllegalArgumentException e) {
assertThat(e, exception("no " + missingName));
}
}
@Test
public void checkScope() throws Exception {
assertNotSame(tool, getTool()); // request scope
}
@Test
public void setTemplateModule() {
tool.setTemplate("mytemplate").setModule("mymodule");
assertEquals("mytemplate", getFieldValue(tool.getControlParameters(), "template", String.class));
assertEquals(null, getFieldValue(tool.getControlParameters(), "module", String.class));
}
@Test
public void setModuleTemplate() {
tool.setModule("mymodule").setTemplate("mytemplate");
assertEquals("mymodule", getFieldValue(tool.getControlParameters(), "module", String.class));
assertEquals(null, getFieldValue(tool.getControlParameters(), "template", String.class));
}
@Test
public void render() throws Exception {
String content = tool.setTemplate("myControl").render();
assertEquals("hello, baobao", content);
}
@Test
public void render_notInit() throws Exception {
tool = new ControlTool();
try {
tool.render();
fail();
} catch (IllegalStateException e) {
assertThat(e, exception("Bean instance of " + ControlTool.class.getName()
+ " has not been initialized yet."));
}
}
@Test
public void render_noTemplate() throws Exception {
String content = tool.setModule("myControlNoTemplate").render();
assertEquals("hello, baobao without template", content);
}
@Test
public void render_changingTemplate() throws Exception {
// setTemplate
MyControlChangingTemplate.expectedTemplateName = "myControlChangingTemplate";
MyControlChangingTemplate.changedTemplateName = "myOtherControl";
String content = tool.setTemplate("myControlChangingTemplate").render();
assertEquals("other control", content);
// setModule
MyControlChangingTemplate.expectedTemplateName = null;
MyControlChangingTemplate.changedTemplateName = "myOtherControl";
content = tool.setModule("myControlChangingTemplate").render();
assertEquals("other control", content);
// setTemplate - remove template
MyControlChangingTemplate.expectedTemplateName = "myControlChangingTemplate";
MyControlChangingTemplate.changedTemplateName = " ";
content = tool.setTemplate("myControlChangingTemplate").render();
assertEquals("", content);
}
@Test
public void render_contextValue() throws Exception {
String content = tool.setTemplate("myControlContextValue").setParameter("template", "myOtherControl").render();
assertEquals("other control", content);
}
@Test
public void render_withError() throws Exception {
String content = tool.setModule("myControlWithError").setParameter("with_XSS", true).render();
// dev mode, errorDetail == stackTrace, 确保html escape。
assertThat(
content,
containsAll(
"<!-- control failed: target=myControlWithError, exceptionType=java.lang.IllegalArgumentException -->",
"<div class=\"webx.error\">java.lang.IllegalArgumentException: <script>alert(1)</script>"));
assertThat(content, not(containsAll("<script>")));
}
@Test
public void render_nest() throws Exception {
String content = tool.setTemplate("nestedControl").render();
// dev mode, errorDetail == stackTrace
assertThat(
content,
containsAll(
"<!-- control failed: target=myControlWithError, exceptionType=java.lang.IllegalArgumentException -->",
"<div class=\"webx.error\">java.lang.IllegalArgumentException", "hello", "world"));
}
@Test
public void render_crossComponent() throws Exception {
String content = tool.setTemplate("app2:myControl").render();
assertEquals("hi, baobao app2", content);
content = tool.setModule("app2:myControlNoTemplate").render();
assertEquals("hi, baobao app2 without template", content);
}
@Test
public void controlContexts() throws Exception {
Context context1 = rundata.getContext();
Context context2 = rundata.getContext("app2");
assertFalse(tool.exportAll);
context1.put("var1", "init");
context1.put("var2", "init");
// no current context
AbstractContext controlContext1 = (AbstractContext) createContextForControl(null, null);
assertSame(context1, controlContext1.getParentContext());
controlContext1.put("var1", "value1");
assertEquals("value1", controlContext1.get("var1"));
assertEquals("init", context1.get("var1"));
controlContext1.remove("var2");
assertEquals(null, controlContext1.get("var2"));
assertEquals("init", context1.get("var2"));
// context1 -> controlContext1, without exports
rundata.pushContext(context1);
controlContext1 = (AbstractContext) createContextForControl(null, null);
assertSame(context1, controlContext1.getParentContext());
controlContext1.put("var1", "value1");
assertEquals("value1", controlContext1.get("var1"));
assertEquals("init", context1.get("var1"));
controlContext1.remove("var2");
assertEquals(null, controlContext1.get("var2"));
assertEquals("init", context1.get("var2"));
// context1 -> controlContext.export(var1, var2)
controlContext1 = (AbstractContext) createContextForControl(null, null, "var1", "var2");
assertSame(context1, controlContext1.getParentContext());
controlContext1.put("var1", "value1");
assertEquals("value1", controlContext1.get("var1"));
assertEquals("value1", context1.get("var1"));
controlContext1.remove("var2");
assertEquals(null, controlContext1.get("var2"));
assertEquals(null, context1.get("var2"));
// context1 -> controlContext1 -> app2:controlContext2.export(var1, var2)
context1.put("var1", "init");
context1.put("var2", "init");
controlContext1 = (AbstractContext) createContextForControl(null, null);
assertSame(context1, controlContext1.getParentContext());
controlContext1.put("var1", "init");
controlContext1.put("var2", "init");
rundata.pushContext(controlContext1);
AbstractContext controlContext2 = (AbstractContext) createContextForControl(null, "app2", "var1", "var2");
assertSame(context2, controlContext2.getParentContext());
controlContext2.put("var1", "value1");
assertEquals("value1", controlContext2.get("var1"));
assertEquals("value1", controlContext1.get("var1"));
assertEquals("init", context1.get("var1"));
controlContext2.remove("var2");
assertEquals(null, controlContext2.get("var2"));
assertEquals(null, controlContext1.get("var2"));
assertEquals("init", context1.get("var2"));
rundata.popContext();
// context1 -> controlContext1.export(var1, var2) -> app2:controlContext2.export(var1, var2)
context1.put("var1", "init");
context1.put("var2", "init");
controlContext1 = (AbstractContext) createContextForControl(null, null, "var1", "var2");
assertSame(context1, controlContext1.getParentContext());
controlContext1.put("var1", "init");
controlContext1.put("var2", "init");
rundata.pushContext(controlContext1);
controlContext2 = (AbstractContext) createContextForControl(null, "app2", "var1", "var2");
assertSame(context2, controlContext2.getParentContext());
controlContext2.put("var1", "value1");
assertEquals("value1", controlContext2.get("var1"));
assertEquals("value1", controlContext1.get("var1"));
assertEquals("value1", context1.get("var1"));
controlContext2.remove("var2");
assertEquals(null, controlContext2.get("var2"));
assertEquals(null, controlContext1.get("var2"));
assertEquals(null, context1.get("var2"));
rundata.popContext();
}
private Context createContextForControl(Map<String, Object> params, String component, String... exports)
throws Exception {
Method method = getAccessibleMethod(tool.getClass(), "createContextForControl", new Class<?>[] {
ControlParameters.class, String.class });
ControlParameters controlParameters = new ControlParameters();
if (params != null) {
controlParameters.putAll(params);
}
if (exports != null) {
getAccessibleField(controlParameters.getClass(), "exportVars").set(controlParameters,
createHashSet(exports));
}
return (Context) method.invoke(tool, controlParameters, component);
}
@Test
public void render_exportVars() throws Exception {
Context context1 = rundata.getContext();
Context context2 = rundata.getContext("app2");
assertFalse(tool.exportAll);
context1.put("var1", "init");
context1.put("var2", "init");
// no current context
tool.setTemplate("control_set").render();
assertEquals("init", context1.get("var1"));
assertEquals("init", context1.get("var2"));
// app1:context -> app1:control, without exports
rundata.pushContext(context1);
tool.setTemplate("control_set").render();
assertEquals("init", context1.get("var1"));
assertEquals("init", context1.get("var2"));
// app1:context -> app1:control.export(var1, var2)
context1.put("var1", "init");
context1.put("var2", "init");
tool.setTemplate("control_set").export("var1").render();
assertEquals("app1", context1.get("var1"));
assertEquals("init", context1.get("var2"));
context1.put("var1", "init");
context1.put("var2", "init");
tool.setTemplate("control_set").export("var2").render();
assertEquals("init", context1.get("var1"));
assertEquals(null, context1.get("var2"));
context1.put("var1", "init");
context1.put("var2", "init");
tool.setTemplate("control_set").export("var1", "var2").render();
assertEquals("app1", context1.get("var1"));
assertEquals(null, context1.get("var2"));
// app1:context -> app1:control -> app2:control.export(var1, var2)
context1.put("var1", "init");
context1.put("var2", "init");
context2.put("var1", "init");
context2.put("var2", "init");
String content = tool.setTemplate("control_nest").render();
assertEquals("init", context1.get("var1"));
assertEquals("init", context1.get("var2"));
assertEquals("init", context2.get("var1"));
assertEquals("init", context2.get("var2"));
assertThat(content, containsAll("1. app2", "2. $var2"));
// app1:context -> app1:control.export(var1, var2) -> app2:control.export(var1, var2)
context1.put("var1", "init");
context1.put("var2", "init");
context2.put("var1", "init");
context2.put("var2", "init");
content = tool.setTemplate("control_nest").export("var1", "var2").render();
assertEquals("app2", context1.get("var1"));
assertEquals(null, context1.get("var2"));
assertEquals("init", context2.get("var1"));
assertEquals("init", context2.get("var2"));
assertThat(content, containsAll("1. app2", "2. $var2"));
}
}