1   /*
2    * Copyright 2004 Sun Microsystems, Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   */
17  package com.sun.syndication.fetcher.impl;
18  
19  import java.net.URL;
20  
21  import junit.framework.TestCase;
22  
23  import org.mortbay.http.HttpContext;
24  import org.mortbay.http.HttpListener;
25  import org.mortbay.http.HttpServer;
26  import org.mortbay.http.SocketListener;
27  import org.mortbay.jetty.servlet.ServletHandler;
28  
29  import com.sun.syndication.feed.synd.SyndFeedI;
30  import com.sun.syndication.fetcher.FeedFetcherI;
31  import com.sun.syndication.fetcher.FetcherEvent;
32  import com.sun.syndication.fetcher.FetcherException;
33  import com.sun.syndication.fetcher.FetcherListener;
34  import com.sun.syndication.fetcher.impl.FeedFetcherCacheI;
35  import com.sun.syndication.fetcher.impl.HashMapFeedInfoCache;
36  import com.sun.syndication.fetcher.impl.HttpURLFeedFetcher;
37  
38  
39  public class HttpURLFeedFetcherTest extends TestCase {
40  	HttpServer server;
41  	
42  	public void testUserAgent() {
43  		FeedFetcherI feedFetcher = new HttpURLFeedFetcher();
44  		System.out.println(feedFetcher.getUserAgent());
45  		System.out.println(System.getProperty("rome.fetcher.version", "UNKNOWN"));
46  		assertEquals("Rome Client (http://rome.dev.java.net/) Ver: " + System.getProperty("rome.fetcher.version", "UNKNOWN"), feedFetcher.getUserAgent());
47  	}	
48  	
49  	public void testRetrieveFeed() {
50  		FeedFetcherI feedFetcher = new HttpURLFeedFetcher();
51  		try {
52  			SyndFeedI feed = feedFetcher.retrieveFeed(new URL("http://localhost:8080/rome/FetcherTestServlet/"));
53  			assertEquals("atom_0.3.feed.title", feed.getTitle());			
54  		} catch (Exception e) {
55  			e.printStackTrace();
56  			fail(e.getMessage());
57  		}
58  	}
59  	
60  	/***
61  	 * Test getting a feed via a http 301 redirect
62  	 *
63  	 */
64  	public void testRetrieveRedirectedFeed() {
65  		FeedFetcherI feedFetcher = new HttpURLFeedFetcher();
66  		try {
67  			SyndFeedI feed = feedFetcher.retrieveFeed(new URL("http://localhost:8080/rome/FetcherTestServlet?redirect=TRUE"));
68  			assertEquals("atom_0.3.feed.title", feed.getTitle());
69  		} catch (Exception e) {
70  			e.printStackTrace();
71  			fail(e.getMessage());
72  		}
73  	}
74  	
75  	/***
76  	 * Test getting a feed via a http 301 redirect
77  	 *
78  	 */
79  	public void testErrorHandling() {
80  		FeedFetcherI feedFetcher = new HttpURLFeedFetcher();
81  		try {
82  			SyndFeedI feed = feedFetcher.retrieveFeed(new URL("http://localhost:8080/rome/FetcherTestServlet?error=404"));
83  			fail("4xx error handling did not work correctly");			
84  		} catch (FetcherException e) {
85  			// expect this exception		
86  			assertEquals(404, e.getResponseCode());				
87  		} catch (Exception e) {			
88  			e.printStackTrace();
89  			fail(e.getMessage());
90  		}
91  		
92  		try {
93  			SyndFeedI feed = feedFetcher.retrieveFeed(new URL("http://localhost:8080/rome/FetcherTestServlet?error=500"));
94  			fail("5xx error handling did not work correctly");			
95  		} catch (FetcherException e) {
96  			// expect this exception
97  			assertEquals(500, e.getResponseCode());						
98  		} catch (Exception e) {			
99  			e.printStackTrace();
100 			fail(e.getMessage());
101 		}		
102 	}	
103 	
104 	
105 	/***
106 	 * Test events fired when there is no cache in use
107 	 *
108 	 */
109 	public void testFetchEvents() {
110 		FeedFetcherI feedFetcher = new HttpURLFeedFetcher();
111 		FetcherEventListenerImpl listener = new FetcherEventListenerImpl();
112 		feedFetcher.addFetcherEventListener(listener);
113 		try {
114 			SyndFeedI feed = feedFetcher.retrieveFeed(new URL("http://localhost:8080/rome/FetcherTestServlet/"));
115 			assertTrue(listener.polled);
116 			assertTrue(listener.retrieved);
117 			assertFalse(listener.unchanged);			
118 			listener.reset();
119 			
120 			// since there is no cache, the events fired should be exactly the same if
121 			// we re-retrieve the feed 
122 			feed = feedFetcher.retrieveFeed(new URL("http://localhost:8080/rome/FetcherTestServlet/"));
123 			assertTrue(listener.polled);
124 			assertTrue(listener.retrieved);
125 			assertFalse(listener.unchanged);			
126 			listener.reset();															
127 		} catch (Exception e) {
128 			e.printStackTrace();
129 			fail(e.getMessage());
130 		}
131 	}	
132 	
133 	/***
134 	 * Test events fired when there is a cache in use
135 	 *
136 	 */
137 	public void testFetchEventsWithCache() {
138 		FeedFetcherCacheI feedInfoCache = new HashMapFeedInfoCache();
139 		FeedFetcherI feedFetcher = new HttpURLFeedFetcher(feedInfoCache);
140 		FetcherEventListenerImpl listener = new FetcherEventListenerImpl();
141 		feedFetcher.addFetcherEventListener(listener);
142 		try {
143 			SyndFeedI feed = feedFetcher.retrieveFeed(new URL("http://localhost:8080/rome/FetcherTestServlet/"));
144 			assertTrue(listener.polled);
145 			assertTrue(listener.retrieved);
146 			assertFalse(listener.unchanged);			
147 			listener.reset();
148 			
149 			// Since the feed is cached, the second request should not
150 			// actually retrieve the feed
151 			feed = feedFetcher.retrieveFeed(new URL("http://localhost:8080/rome/FetcherTestServlet/"));
152 			assertTrue(listener.polled);
153 			assertFalse(listener.retrieved);
154 			assertTrue(listener.unchanged);			
155 			listener.reset();				
156 			
157 			// now simulate getting the feed after it has changed
158 			feed = feedFetcher.retrieveFeed(new URL("http://localhost:8080/rome/FetcherTestServlet?refreshfeed=TRUE"));
159 			assertTrue(listener.polled);
160 			assertTrue(listener.retrieved);
161 			assertFalse(listener.unchanged);			
162 			listener.reset();														
163 		} catch (Exception e) {
164 			e.printStackTrace();
165 			fail(e.getMessage());
166 		}
167 	}	
168 	
169 	/***
170 	 * @see junit.framework.TestCase#setUp()
171 	 */
172 	protected void setUp() throws Exception {
173 		// Create the server
174 		if (server != null) {
175 			server.stop();
176 			server = null;
177 		}
178 		server = new HttpServer();		
179       
180 		// Create a port listener
181 		SocketListener listener=new SocketListener();
182 		listener.setPort(8080);
183 		server.addListener(listener);		
184 		
185 		HttpContext context = new HttpContext();	
186 		context.setContextPath("/rome/*");
187 		server.addContext(context);
188 		
189 		
190 		ServletHandler servlets = new ServletHandler();
191 		context.addHandler(servlets);
192 		
193 		servlets.addServlet("FetcherTestServlet","/FetcherTestServlet/*","com.sun.syndication.fetcher.impl.FetcherTestServlet");
194 
195 		server.start();
196 	}
197 	
198 	/***
199 	 * @see junit.framework.TestCase#tearDown()
200 	 */
201 	protected void tearDown() throws Exception {
202 		if (server != null) {
203 			server.stop();
204 			server.destroy();
205 			server = null;			
206 		}
207 	}
208 
209 	class FetcherEventListenerImpl implements FetcherListener {
210 		boolean polled = false;
211 		boolean retrieved = false;
212 		boolean unchanged = false;
213 		
214 		public void reset() {
215 			polled = false;
216 			retrieved = false;
217 			unchanged = false;			
218 		}
219 
220 		/***
221 		 * @see com.sun.syndication.fetcher.FetcherListener#fetcherEvent(com.sun.syndication.fetcher.FetcherEvent)
222 		 */
223 		public void fetcherEvent(FetcherEvent event) {
224 			String eventType = event.getEventType();
225 			if (FetcherEvent.EVENT_TYPE_FEED_POLLED.equals(eventType)) {
226 				System.err.println("\tEVENT: Feed Polled. URL = " + event.getUrl().toString());
227 				polled = true;				
228 			} else if (FetcherEvent.EVENT_TYPE_FEED_RETRIEVED.equals(eventType)) {
229 				System.err.println("\tEVENT: Feed Retrieved. URL = " + event.getUrl().toString());
230 				retrieved = true;				
231 			} else if (FetcherEvent.EVENT_TYPE_FEED_UNCHANGED.equals(eventType)) {
232 				System.err.println("\tEVENT: Feed Unchanged. URL = " + event.getUrl().toString());
233 				unchanged = true;				
234 			}			
235 		}
236 	}	
237 
238 }