/*
* 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.service.requestcontext;
import static com.alibaba.citrus.test.TestUtil.*;
import static com.alibaba.citrus.util.CollectionUtil.*;
import static org.junit.Assert.*;
import java.util.List;
import javax.servlet.http.HttpServletResponseWrapper;
import com.alibaba.citrus.service.requestcontext.basic.BasicRequestContext;
import com.alibaba.citrus.service.requestcontext.buffered.BufferedRequestContext;
import com.alibaba.citrus.service.requestcontext.lazycommit.LazyCommitRequestContext;
import com.alibaba.citrus.service.requestcontext.locale.SetLocaleRequestContext;
import com.alibaba.citrus.service.requestcontext.parser.ParserRequestContext;
import com.alibaba.citrus.service.requestcontext.rewrite.RewriteRequestContext;
import com.alibaba.citrus.service.requestcontext.rundata.RunData;
import com.alibaba.citrus.service.requestcontext.session.SessionRequestContext;
import com.alibaba.citrus.service.requestcontext.support.AbstractRequestContextFactory;
import com.alibaba.citrus.service.requestcontext.support.AbstractRequestContextWrapper;
import com.alibaba.citrus.service.requestcontext.util.RequestContextUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.beans.factory.BeanCreationException;
/**
* 测试<code>RequestContextChainingService</code>。
*
* @author Michael Zhou
*/
public class RequestContextChainingServiceTests extends AbstractRequestContextsTests<RequestContext> {
private static ThreadLocal<RequestContextChainingServiceTests> testCaseHolder = new ThreadLocal<RequestContextChainingServiceTests>();
private List<Integer> prepareOrder;
private List<Integer> commitOrder;
@BeforeClass
public static void initFactory() {
createBeanFactory("services.xml");
}
@Before
public void init() throws Exception {
invokeReadFileServlet("form.html");
prepareOrder = createArrayList();
commitOrder = createArrayList();
testCaseHolder.set(this);
}
@After
public void destroy() {
testCaseHolder.set(null);
}
@Test
public void defaultNameAndAlias() {
RequestContextChainingService requestContexts = (RequestContextChainingService) factory
.getBean("requestContexts");
assertNotNull(requestContexts);
assertSame(requestContexts, factory.getBean("requestContextChainingService"));
}
@Test
public void emptyRequestContext() throws Exception {
initRequestContext("empty");
// 在没有任何request context factory的时候,
// requestContext.getRequest()就是原来的request
// requestContext.getResponse()是CommittingAwareResponse,包着原来的response
assertSame(request, newRequest);
assertTrue(newResponse instanceof HttpServletResponseWrapper);
assertSame(response, ((HttpServletResponseWrapper) newResponse).getResponse());
// 确保可以从request中取得requestContext
assertSame(requestContext, RequestContextUtil.getRequestContext(request));
}
@Test
public void _toString() throws Exception {
initRequestContext("order");
String expectedResult = "";
expectedResult += "MyContext[4] {\n";
expectedResult += " MyContext[3] {\n";
expectedResult += " MyContext[2] {\n";
expectedResult += " MyContext[1] {\n";
expectedResult += " MyContext[0] {\n";
expectedResult += " SimpleRequestContext {\n";
expectedResult += " request = " + request + "\n";
expectedResult += " response = " + response + "\n"; // CommittingAwareResponse.toString()将显示原始的response内容
expectedResult += " webapp = " + config.getServletContext() + "\n";
expectedResult += " }\n";
expectedResult += " }\n";
expectedResult += " }\n";
expectedResult += " }\n";
expectedResult += " }\n";
expectedResult += "}";
assertEquals(expectedResult, requestContext.toString());
}
@Test
public void prepareCommitOrder() throws Exception {
initRequestContext("order");
requestContexts.commitRequestContext(requestContext);
assertArrayEquals(new Object[] { 0, 1, 2, 3, 4 }, prepareOrder.toArray());
assertArrayEquals(new Object[] { 4, 3, 2, 1, 0 }, commitOrder.toArray());
}
@Test
public void sort() throws Exception {
initRequestContext("sort");
requestContexts.commitRequestContext(requestContext);
assertArrayEquals(new Object[] { -3, -2, 4, 5, 2, 3, 1, 0, -1, -4 }, prepareOrder.toArray());
assertArrayEquals(new Object[] { -4, -1, 0, 1, 3, 2, 5, 4, -2, -3 }, commitOrder.toArray());
}
@Test
public void sort1() throws Exception {
initRequestContext("sort1");
requestContexts.commitRequestContext(requestContext);
// 顺序虽然与sort()不同,但仍然符合所有条件。
assertArrayEquals(new Object[] { -3, -2, 5, 4, 3, 2, 1, 0, -1, -4 }, prepareOrder.toArray());
assertArrayEquals(new Object[] { -4, -1, 0, 1, 2, 3, 4, 5, -2, -3 }, commitOrder.toArray());
}
@Test
public void sort2() throws Exception {
initRequestContext("all");
RequestContextInfo<?>[] infos = requestContexts.getRequestContextInfos();
assertEquals(9, infos.length);
int i = 0;
assertEquals(BasicRequestContext.class, infos[i++].getRequestContextInterface());
assertEquals(ParserRequestContext.class, infos[i++].getRequestContextInterface());
assertEquals(BufferedRequestContext.class, infos[i++].getRequestContextInterface());
assertEquals(LazyCommitRequestContext.class, infos[i++].getRequestContextInterface());
assertEquals(SessionRequestContext.class, infos[i++].getRequestContextInterface());
assertEquals(SetLocaleRequestContext.class, infos[i++].getRequestContextInterface());
assertEquals(RewriteRequestContext.class, infos[i++].getRequestContextInterface());
assertEquals(RequestContext.class, infos[i++].getRequestContextInterface());
assertEquals(RunData.class, infos[i++].getRequestContextInterface());
}
@Test
public void missingRequired() throws Exception {
try {
initRequestContext("missingRequired");
fail();
} catch (BeanCreationException e) {
assertThat(e, exception(IllegalArgumentException.class, "Missing feature", "f2", "required by", "[1]"));
}
}
@Test
public void destructionCallbacks() throws Exception {
initRequestContext("all");
final String[] data = new String[1];
RequestContextUtil.registerRequestDestructionCallback("testCallback", new Runnable() {
public void run() {
data[0] = "destructed!";
}
});
requestContexts.commitRequestContext(requestContext);
assertArrayEquals(new String[] { "destructed!" }, data);
}
public static class MyRequestContextFactory extends AbstractRequestContextFactory<MyRequestContext> {
private int index;
public void setIndex(int index) {
this.index = index;
}
public MyRequestContext getRequestContextWrapper(RequestContext wrappedContext) {
return new MyRequestContextImpl(wrappedContext, index);
}
public String[] getFeatures() {
return new String[] { "f" + index };
}
public FeatureOrder[] featureOrders() {
switch (index) {
case -3:
return new FeatureOrder[] { new BeforeFeature("f-2") };
case -2:
return new FeatureOrder[] { new BeforeFeature("*") }; // *表示在所有feature之前
case -1:
return new FeatureOrder[] { new AfterFeature("*") }; // *表示在所有feature之后
case -4:
return new FeatureOrder[] { new AfterFeature("f-1") };
case 0:
return new FeatureOrder[] { new AfterFeature("f1") };
case 1:
return new FeatureOrder[] { new RequiresFeature("f2"), new AfterFeature("f3") };
case 2:
return new FeatureOrder[] { new AfterFeature("f4") };
case 3:
return new FeatureOrder[] { new AfterFeature("f4") };
case 5:
return new FeatureOrder[] { new BeforeFeature("f2") };
case 4:
default:
return null;
}
}
@Override
public String toString() {
return "MyRequestContextFactory[" + index + "]";
}
}
public static class MyRequestContextImpl extends AbstractRequestContextWrapper implements MyRequestContext {
private final int index;
public MyRequestContextImpl(RequestContext wrappedContext, int index) {
super(wrappedContext);
this.index = index;
}
@Override
public void prepare() {
testCaseHolder.get().prepareOrder.add(index);
}
@Override
public void commit() throws RequestContextException {
testCaseHolder.get().commitOrder.add(index);
}
@Override
protected String thisToString() {
return "MyContext[" + index + "]";
}
}
public static interface MyRequestContext extends RequestContext {
}
}