1 package com.atlassian.plugin.servlet.filter;
2
3 import static com.atlassian.plugin.servlet.filter.FilterTestUtils.newList;
4 import static com.atlassian.plugin.servlet.filter.FilterTestUtils.singletonFilterChain;
5
6 import java.io.IOException;
7 import java.util.ArrayList;
8 import java.util.LinkedList;
9 import java.util.List;
10
11 import javax.servlet.Filter;
12 import javax.servlet.FilterChain;
13 import javax.servlet.ServletException;
14 import javax.servlet.ServletRequest;
15 import javax.servlet.ServletResponse;
16 import javax.servlet.http.HttpServletRequest;
17 import javax.servlet.http.HttpServletResponse;
18
19 import junit.framework.TestCase;
20
21 import com.atlassian.plugin.servlet.filter.FilterTestUtils.FilterAdapter;
22 import com.atlassian.plugin.servlet.filter.FilterTestUtils.SoundOffFilter;
23 import com.mockobjects.dynamic.Mock;
24
25 public class TestIteratingFilterChain extends TestCase
26 {
27 public void testFiltersCalledInProperOrder() throws IOException, ServletException
28 {
29 List<Integer> filterCallOrder = new LinkedList<Integer>();
30 List<Filter> filters = new ArrayList<Filter>();
31 for(int i = 0; i < 5; i++)
32 {
33 filters.add(new SoundOffFilter(filterCallOrder, i));
34 }
35
36 FilterChain chain = new IteratingFilterChain(filters.iterator(), singletonFilterChain(new SoundOffFilter(filterCallOrder, 100)));
37
38 Mock mockRequest = new Mock(HttpServletRequest.class);
39 mockRequest.expectAndReturn("getPathInfo", "some/path");
40 Mock mockResponse = new Mock(HttpServletResponse.class);
41
42 chain.doFilter((HttpServletRequest) mockRequest.proxy(), (HttpServletResponse) mockResponse.proxy());
43
44
45 assertEquals(newList(0, 1, 2, 3, 4, 100, 100, 4, 3, 2, 1, 0), filterCallOrder);
46 }
47
48 public void testFilterCanAbortChain() throws IOException, ServletException
49 {
50 final List<Integer> filterCallOrder = new LinkedList<Integer>();
51 List<Filter> filters = new ArrayList<Filter>();
52 for(int i = 0; i < 2; i++)
53 {
54 filters.add(new SoundOffFilter(filterCallOrder, i));
55 }
56 filters.add(new FilterAdapter()
57 {
58 @Override
59 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
60 throws IOException, ServletException
61 {
62 filterCallOrder.add(50);
63 }
64 });
65 for(int i = 3; i < 5; i++)
66 {
67 filters.add(new SoundOffFilter(filterCallOrder, i));
68 }
69
70 FilterChain chain = new IteratingFilterChain(filters.iterator(), singletonFilterChain(new SoundOffFilter(filterCallOrder, 100)));
71
72 Mock mockRequest = new Mock(HttpServletRequest.class);
73 mockRequest.expectAndReturn("getPathInfo", "some/path");
74 Mock mockResponse = new Mock(HttpServletResponse.class);
75
76 chain.doFilter((HttpServletRequest) mockRequest.proxy(), (HttpServletResponse) mockResponse.proxy());
77
78
79 assertEquals(newList(0, 1, 50, 1, 0), filterCallOrder);
80 }
81
82 public void testExceptionFiltersUpWhenFilterThrowsException() throws IOException, ServletException
83 {
84 final List<Integer> filterCallOrder = new LinkedList<Integer>();
85 List<Filter> filters = new ArrayList<Filter>();
86 for(int i = 0; i < 2; i++)
87 {
88 filters.add(new SoundOffFilter(filterCallOrder, i));
89 }
90 filters.add(new FilterAdapter()
91 {
92 @Override
93 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
94 throws IOException, ServletException
95 {
96 throw new ServletException();
97 }
98 });
99 for(int i = 3; i < 5; i++)
100 {
101 filters.add(new SoundOffFilter(filterCallOrder, i));
102 }
103
104 FilterChain chain = new IteratingFilterChain(filters.iterator(), singletonFilterChain(new SoundOffFilter(filterCallOrder, 100)));
105
106 Mock mockRequest = new Mock(HttpServletRequest.class);
107 mockRequest.expectAndReturn("getPathInfo", "some/path");
108 Mock mockResponse = new Mock(HttpServletResponse.class);
109
110 try
111 {
112 chain.doFilter((HttpServletRequest) mockRequest.proxy(), (HttpServletResponse) mockResponse.proxy());
113 fail("ServletException should filter up");
114 }
115 catch (ServletException e)
116 {
117
118 assertEquals(newList(0, 1), filterCallOrder);
119 }
120 }
121 }