@Test public void getLinks() throws Exception { String link1Rel = "foo"; String link2Rel = "bar"; Uri link1Href = Uri.parse("http://example.org/foo"); Uri link2Href = Uri.parse("/bar"); String xml = "<ModulePrefs title='links'>" + " <Link rel='" + link1Rel + "' href='" + link1Href + "'/>" + " <Link rel='" + link2Rel + "' href='" + link2Href + "'/>" + "</ModulePrefs>"; ModulePrefs prefs = new ModulePrefs(XmlUtil.parse(xml), SPEC_URL).substitute(new Substitutions()); assertEquals(link1Href, prefs.getLinks().get(link1Rel).getHref()); assertEquals(SPEC_URL.resolve(link2Href), prefs.getLinks().get(link2Rel).getHref()); }
/** * @param request the outbound http request * @return true if the request should be authenticated */ private boolean isAuthEndpoint(HttpRequest request) { Uri uri = request.getUri(); String path = uri.getPath(); for (String authEndpoint : authEndpoints) { if (path.startsWith(authEndpoint)) { return true; } } return false; }
private void expectMime(String expectedMime, String contentMime, String outputMime) throws Exception { String url = "http://example.org/file.img?" + Param.REWRITE_MIME_TYPE.getKey() + '=' + expectedMime; String domain = "example.org"; setupProxyRequestMock(domain, url, false, -1, expectedMime, null); HttpRequest req = new HttpRequest(Uri.parse(url)).setRewriteMimeType(expectedMime); HttpResponse resp = new HttpResponseBuilder() .setResponseString("Hello") .addHeader("Content-Type", contentMime) .create(); expect(pipeline.execute(req)).andReturn(resp); replay(); HttpResponse response = proxyHandler.fetch(request); verify(); assertEquals(outputMime, response.getHeader("Content-Type")); reset(); }
/** Generate a remote content request based on the parameters sent from the client. */ private HttpRequest buildHttpRequest(HttpServletRequest request) throws GadgetException { Uri url = validateUrl(request.getParameter(URL_PARAM)); HttpRequest req = new HttpRequest(url); req.setContainer(getContainer(request)); if (request.getParameter(GADGET_PARAM) != null) { req.setGadget(Uri.parse(request.getParameter(GADGET_PARAM))); } // Allow the rewriter to use an externally forced mime type. This is needed // allows proper rewriting of <script src="x"/> where x is returned with // a content type like text/html which unfortunately happens all too often req.setRewriteMimeType(request.getParameter(REWRITE_MIME_TYPE_PARAM)); req.setIgnoreCache(getIgnoreCache(request)); // If the proxy request specifies a refresh param then we want to force the min TTL for // the retrieved entry in the cache regardless of the headers on the content when it // is fetched from the original source. if (request.getParameter(REFRESH_PARAM) != null) { try { req.setCacheTtl(Integer.parseInt(request.getParameter(REFRESH_PARAM))); } catch (NumberFormatException nfe) { // Ignore } } return req; }
@Test public void testInvalidHeaderDropped() throws Exception { String url = "http://example.org/mypage.html"; String domain = "example.org"; setupProxyRequestMock(domain, url, true, -1, null, null); HttpRequest req = new HttpRequest(Uri.parse(url)).setIgnoreCache(true); String contentType = "text/html; charset=UTF-8"; HttpResponse resp = new HttpResponseBuilder() .setResponseString("Hello") .addHeader("Content-Type", contentType) .addHeader("Content-Length", "200") // Disallowed header. .addHeader(":", "someDummyValue") // Invalid header name. .create(); expect(pipeline.execute(req)).andReturn(resp); replay(); HttpResponse recorder = proxyHandler.fetch(request); verify(); assertNull(recorder.getHeader(":")); assertNull(recorder.getHeader("Content-Length")); assertEquals(recorder.getHeader("Content-Type"), contentType); }
private void setupProxyRequestMock( String host, String url, boolean noCache, int refresh, String rewriteMime, String fallbackUrl) throws Exception { request = new ProxyUriManager.ProxyUri( refresh, false, noCache, ContainerConfig.DEFAULT_CONTAINER, null, Uri.parse(url)); request.setFallbackUrl(fallbackUrl); request.setRewriteMimeType(rewriteMime); }
private void setupNoArgsProxyRequestMock(String host, String url) throws Exception { request = new ProxyUriManager.ProxyUri( -1, false, false, ContainerConfig.DEFAULT_CONTAINER, null, url != null ? Uri.parse(url) : null); }
@Before public void setUp() { servlet.setMakeRequestHandler(handler); expect(fixture.request.getHeaderNames()).andReturn(EMPTY_ENUM).anyTimes(); expect(fixture.request.getParameter(MakeRequestHandler.METHOD_PARAM)) .andReturn("GET") .anyTimes(); expect(fixture.request.getParameter(ProxyBase.URL_PARAM)) .andReturn(REQUEST_URL.toString()) .anyTimes(); }
private void assertResponseOk(int expectedStatus, String expectedBody) throws JSONException { if (recorder.getHttpStatusCode() == HttpServletResponse.SC_OK) { String body = recorder.getResponseAsString(); assertStartsWith(MakeRequestHandler.UNPARSEABLE_CRUFT, body); body = body.substring(MakeRequestHandler.UNPARSEABLE_CRUFT.length()); JSONObject object = new JSONObject(body); object = object.getJSONObject(REQUEST_URL.toString()); assertEquals(expectedStatus, object.getInt("rc")); assertEquals(expectedBody, object.getString("body")); } else { fail("Invalid response for request."); } }
@Test public void testFetch_noToken() throws Exception { Uri uri = Uri.parse("http://host?p=1"); HttpRequest request = createMock(HttpRequest.class); expect(request.getUri()).andReturn(uri); expect(request.setUri(Uri.parse("http://host?p=1&st=default%3Anull"))).andReturn(request); replay(request); HttpResponse response = new HttpResponse(); HttpFetcher fetcher = createMock(HttpFetcher.class); expect(fetcher.fetch(request)).andReturn(response); replay(fetcher); FakeUserHttpFetcher fakeFetcher; fakeFetcher = new FakeUserHttpFetcher(config, fetcher, crypter); fakeFetcher.fetch(request); verify(request); verify(fetcher); }
@Test public void testWithBadTtl() throws Exception { String url = "http://example.org/file.evil"; String domain = "example.org"; setupProxyRequestMock(domain, url, false, -1, null, null); HttpRequest req = new HttpRequestCache(Uri.parse(url)).setCacheTtl(-1).setIgnoreCache(false); HttpResponse resp = new HttpResponse("Hello"); expect(pipeline.execute(req)).andReturn(resp); replay(); proxyHandler.fetch(request); verify(); }
/** * Derived from Harmony Resolves a given url relative to this url. Resolution rules are the same * as for {@code java.net.URI.resolve(URI)} */ public Uri resolve(Uri relative) { if (relative == null) { return null; } if (relative.isAbsolute()) { return relative; } UriBuilder result; if (StringUtils.isEmpty(relative.path) && relative.scheme == null && relative.authority == null && relative.query == null && relative.fragment != null) { // if the relative URI only consists of fragment, // the resolved URI is very similar to this URI, // except that it has the fragement from the relative URI. result = new UriBuilder(this); result.setFragment(relative.fragment); } else if (relative.scheme != null) { result = new UriBuilder(relative); } else if (relative.authority != null) { // if the relative URI has authority, // the resolved URI is almost the same as the relative URI, // except that it has the scheme of this URI. result = new UriBuilder(relative); result.setScheme(scheme); } else { // since relative URI has no authority, // the resolved URI is very similar to this URI, // except that it has the query and fragment of the relative URI, // and the path is different. result = new UriBuilder(this); result.setFragment(relative.fragment); result.setQuery(relative.query); String relativePath = (relative.path == null) ? "" : relative.path; if (relativePath.startsWith("/")) { // $NON-NLS-1$ result.setPath(relativePath); } else { // resolve a relative reference int endindex = path.lastIndexOf('/') + 1; result.setPath(normalizePath(path.substring(0, endindex) + relativePath)); } } Uri resolved = result.toUri(); validate(resolved); return resolved; }
@Test public void testGetFallback() throws Exception { String url = "http://example.org/file.evil"; String domain = "example.org"; String fallback_url = "http://fallback.com/fallback.png"; setupProxyRequestMock(domain, url, true, -1, null, fallback_url); HttpRequest req = new HttpRequest(Uri.parse(url)).setIgnoreCache(true); HttpResponse resp = HttpResponse.error(); HttpResponse fallback_resp = new HttpResponse("Fallback"); expect(pipeline.execute(req)).andReturn(resp); expect(pipeline.execute(isA(HttpRequest.class))).andReturn(fallback_resp); replay(); proxyHandler.fetch(request); verify(); }
@Test public void testHttpRequestFillsParentAndContainer() throws Exception { setupNoArgsProxyRequestMock("www.example.com", URL_ONE); // HttpRequest req = new HttpRequest(Uri.parse(URL_ONE)); HttpResponse resp = new HttpResponseBuilder().setResponse(DATA_ONE.getBytes()).create(); Capture<HttpRequest> httpRequest = new Capture<HttpRequest>(); expect(pipeline.execute(capture(httpRequest))).andReturn(resp); replay(); HttpResponse response = proxyHandler.fetch(request); verify(); // Check that the HttpRequest passed in has all the relevant fields sets assertEquals("default", httpRequest.getValue().getContainer()); assertEquals(Uri.parse(URL_ONE), httpRequest.getValue().getUri()); assertEquals(DATA_ONE, response.getResponseAsString()); assertTrue(rewriter.responseWasRewritten()); }
@Test public void testFetch_withToken() throws Exception { Uri uri = Uri.parse("http://host?p=1&st=sometoken"); // We should get the request untouched. HttpRequest request = createMock(HttpRequest.class); expect(request.getUri()).andReturn(uri); replay(request); HttpResponse response = new HttpResponse(); HttpFetcher fetcher = createMock(HttpFetcher.class); expect(fetcher.fetch(request)).andReturn(response); replay(fetcher); FakeUserHttpFetcher fakeFetcher; fakeFetcher = new FakeUserHttpFetcher(config, fetcher, crypter); fakeFetcher.fetch(request); verify(request); verify(fetcher); }
public class DefaultInvalidationServiceTest extends Assert { private static final Uri URI = Uri.parse("http://www.example.org/spec.xml"); private static final HttpResponse CACHEABLE = new HttpResponseBuilder() .setResponseString("ORIGINALCONTENT") .setHeader("Cache-Control", "max-age=1000") .create(); IMocksControl control; HttpCache cache; DefaultInvalidationService service; LruCacheProvider cacheProvider; FakeGadgetToken appxToken; FakeGadgetToken appyToken; DefaultRequestPipelineTest.FakeHttpFetcher fetcher; DefaultRequestPipelineTest.FakeOAuthRequestProvider oauth; DefaultRequestPipeline requestPipeline; HttpRequest signedRequest; @Before public void setUp() { cacheProvider = new LruCacheProvider(100); cache = new DefaultHttpCache(cacheProvider); service = new DefaultInvalidationService(cache, cacheProvider, new AtomicLong()); appxToken = new FakeGadgetToken(); appxToken.setAppId("AppX"); appxToken.setOwnerId("OwnerX"); appxToken.setViewerId("ViewerX"); appyToken = new FakeGadgetToken(); appyToken.setAppId("AppY"); appyToken.setOwnerId("OwnerY"); appyToken.setViewerId("ViewerY"); signedRequest = new HttpRequest(URI); signedRequest.setAuthType(AuthType.SIGNED); signedRequest.setSecurityToken(appxToken); signedRequest.setOAuthArguments(new OAuthArguments()); signedRequest.getOAuthArguments().setUseToken(OAuthArguments.UseToken.NEVER); signedRequest.getOAuthArguments().setSignOwner(true); signedRequest.getOAuthArguments().setSignViewer(true); fetcher = new DefaultRequestPipelineTest.FakeHttpFetcher(); oauth = new DefaultRequestPipelineTest.FakeOAuthRequestProvider(); requestPipeline = new DefaultRequestPipeline( fetcher, cache, oauth, new DefaultResponseRewriterRegistry(null, null), service, new HttpResponseMetadataHelper()); } @Test public void testInvalidateUrl() throws Exception { cache.addResponse(new HttpRequest(URI), CACHEABLE); assertEquals(1, cacheProvider.createCache(DefaultHttpCache.CACHE_NAME).getSize()); service.invalidateApplicationResources(ImmutableSet.of(URI), appxToken); assertEquals(0, cacheProvider.createCache(DefaultHttpCache.CACHE_NAME).getSize()); } @Test public void testInvalidateUsers() throws Exception { service.invalidateUserResources(ImmutableSet.of("example.org:1", "example.org:2"), appxToken); service.invalidateUserResources(ImmutableSet.of("example.org:1", "example.org:2"), appyToken); assertEquals(4, cacheProvider.createCache(DefaultInvalidationService.CACHE_NAME).getSize()); assertNotNull( cacheProvider .createCache(DefaultInvalidationService.CACHE_NAME) .getElement("INV_TOK:AppX:1")); assertNotNull( cacheProvider .createCache(DefaultInvalidationService.CACHE_NAME) .getElement("INV_TOK:AppX:2")); assertNotNull( cacheProvider .createCache(DefaultInvalidationService.CACHE_NAME) .getElement("INV_TOK:AppY:1")); assertNotNull( cacheProvider .createCache(DefaultInvalidationService.CACHE_NAME) .getElement("INV_TOK:AppY:2")); } @Test public void testFetchWithInvalidationEnabled() throws Exception { cache.addResponse(new HttpRequest(URI), CACHEABLE); assertEquals(CACHEABLE, requestPipeline.execute(new HttpRequest(URI))); } @Test public void testFetchInvalidatedContent() throws Exception { // Prime the cache cache.addResponse(new HttpRequest(URI), CACHEABLE); // Invalidate the entry service.invalidateApplicationResources(ImmutableSet.of(URI), appxToken); fetcher.response = new HttpResponseBuilder(CACHEABLE).setResponseString("NEWCONTENT1").create(); assertEquals(requestPipeline.execute(new HttpRequest(URI)), fetcher.response); } @Test public void testFetchContentWithMarker() throws Exception { oauth.httpResponse = CACHEABLE; // First entry added to cache is unmarked HttpResponse httpResponse = requestPipeline.execute(signedRequest); assertEquals(CACHEABLE, httpResponse); assertEquals(1, cacheProvider.createCache(DefaultHttpCache.CACHE_NAME).getSize()); // Invalidate content for OwnerX. Next entry will have owner mark service.invalidateUserResources(ImmutableSet.of("OwnerX"), appxToken); oauth.httpResponse = new HttpResponseBuilder(CACHEABLE).setResponseString("NEWCONTENT1").create(); httpResponse = requestPipeline.execute(signedRequest); assertEquals("NEWCONTENT1", httpResponse.getResponseAsString()); assertEquals("o=1;", httpResponse.getHeader(DefaultInvalidationService.INVALIDATION_HEADER)); assertEquals(1, cacheProvider.createCache(DefaultHttpCache.CACHE_NAME).getSize()); // Invalidate content for ViewerX. Next entry will have both owner and viewer mark service.invalidateUserResources(ImmutableSet.of("ViewerX"), appxToken); oauth.httpResponse = new HttpResponseBuilder(CACHEABLE).setResponseString("NEWCONTENT2").create(); httpResponse = requestPipeline.execute(signedRequest); assertEquals("NEWCONTENT2", httpResponse.getResponseAsString()); assertEquals( "o=1;v=2;", httpResponse.getHeader(DefaultInvalidationService.INVALIDATION_HEADER)); assertEquals(1, cacheProvider.createCache(DefaultHttpCache.CACHE_NAME).getSize()); } @Test public void testFetchContentSignedOwner() throws Exception { oauth.httpResponse = CACHEABLE; signedRequest.getOAuthArguments().setSignViewer(false); HttpResponse httpResponse = requestPipeline.execute(signedRequest); assertEquals(CACHEABLE, httpResponse); assertEquals(1, cacheProvider.createCache(DefaultHttpCache.CACHE_NAME).getSize()); // Invalidate by owner only service.invalidateUserResources(ImmutableSet.of("OwnerX"), appxToken); oauth.httpResponse = new HttpResponseBuilder(CACHEABLE).setResponseString("NEWCONTENT1").create(); httpResponse = requestPipeline.execute(signedRequest); assertEquals("NEWCONTENT1", httpResponse.getResponseAsString()); assertEquals("o=1;", httpResponse.getHeader(DefaultInvalidationService.INVALIDATION_HEADER)); assertEquals(1, cacheProvider.createCache(DefaultHttpCache.CACHE_NAME).getSize()); // Invalidating viewer has no effect service.invalidateUserResources(ImmutableSet.of("ViewerX"), appxToken); oauth.httpResponse = new HttpResponseBuilder(CACHEABLE).setResponseString("NEWCONTENT2").create(); httpResponse = requestPipeline.execute(signedRequest); assertEquals("NEWCONTENT1", httpResponse.getResponseAsString()); assertEquals("o=1;", httpResponse.getHeader(DefaultInvalidationService.INVALIDATION_HEADER)); assertEquals(1, cacheProvider.createCache(DefaultHttpCache.CACHE_NAME).getSize()); } @Test public void testFetchContentSignedViewer() throws Exception { oauth.httpResponse = CACHEABLE; signedRequest.getOAuthArguments().setSignOwner(false); HttpResponse httpResponse = requestPipeline.execute(signedRequest); assertEquals(CACHEABLE, httpResponse); assertEquals(1, cacheProvider.createCache(DefaultHttpCache.CACHE_NAME).getSize()); // Invalidate by owner has no effect service.invalidateUserResources(ImmutableSet.of("OwnerX"), appxToken); oauth.httpResponse = new HttpResponseBuilder(CACHEABLE).setResponseString("NEWCONTENT1").create(); httpResponse = requestPipeline.execute(signedRequest); assertEquals(CACHEABLE, httpResponse); // Invalidate the viewer service.invalidateUserResources(ImmutableSet.of("ViewerX"), appxToken); oauth.httpResponse = new HttpResponseBuilder(CACHEABLE).setResponseString("NEWCONTENT2").create(); httpResponse = requestPipeline.execute(signedRequest); assertEquals("NEWCONTENT2", httpResponse.getResponseAsString()); assertEquals("v=2;", httpResponse.getHeader(DefaultInvalidationService.INVALIDATION_HEADER)); assertEquals(1, cacheProvider.createCache(DefaultHttpCache.CACHE_NAME).getSize()); } @Test public void testServeInvalidatedContentWithFetcherError() throws Exception { oauth.httpResponse = CACHEABLE; HttpResponse httpResponse = requestPipeline.execute(signedRequest); // Invalidate by owner service.invalidateUserResources(ImmutableSet.of("OwnerX"), appxToken); // Next request returns error oauth.httpResponse = HttpResponse.error(); httpResponse = requestPipeline.execute(signedRequest); assertEquals(CACHEABLE, httpResponse); } }
private void doAsserts(ModulePrefs prefs) { assertEquals("title", prefs.getTitle()); assertEquals(SPEC_URL.resolve(Uri.parse("title_url")), prefs.getTitleUrl()); assertEquals("description", prefs.getDescription()); assertEquals("author", prefs.getAuthor()); assertEquals("author_email", prefs.getAuthorEmail()); assertEquals(SPEC_URL.resolve(Uri.parse("screenshot")), prefs.getScreenshot()); assertEquals(SPEC_URL.resolve(Uri.parse("thumbnail")), prefs.getThumbnail()); assertEquals("directory_title", prefs.getDirectoryTitle()); assertEquals(1, prefs.getWidth()); assertEquals(2, prefs.getHeight()); assertTrue(prefs.getScrolling()); assertFalse(prefs.getScaling()); assertEquals("category", prefs.getCategories().get(0)); assertEquals("category2", prefs.getCategories().get(1)); assertEquals("author_affiliation", prefs.getAuthorAffiliation()); assertEquals("author_location", prefs.getAuthorLocation()); assertEquals(SPEC_URL.resolve(Uri.parse("author_photo")), prefs.getAuthorPhoto()); assertEquals(SPEC_URL.resolve(Uri.parse("author_link")), prefs.getAuthorLink()); assertEquals("author_aboutme", prefs.getAuthorAboutme()); assertEquals("author_quote", prefs.getAuthorQuote()); assertTrue(prefs.getShowStats()); assertTrue(prefs.getShowInDirectory()); assertTrue(prefs.getSingleton()); assertTrue(prefs.getFeatures().get("require").getRequired()); assertFalse(prefs.getFeatures().get("optional").getRequired()); assertEquals("http://example.org", prefs.getPreloads().get(0).getHref().toString()); assertEquals(1, prefs.getIcons().size()); assertEquals(1, prefs.getLocales().size()); assertEquals(Uri.parse("http://example.org/link"), prefs.getLinks().get("link").getHref()); OAuthService oauth = prefs.getOAuthSpec().getServices().get("serviceOne"); assertEquals(Uri.parse("http://www.example.com/request"), oauth.getRequestUrl().url); assertEquals(OAuthService.Method.GET, oauth.getRequestUrl().method); assertEquals(OAuthService.Method.GET, oauth.getAccessUrl().method); assertEquals(OAuthService.Location.HEADER, oauth.getAccessUrl().location); assertEquals(Uri.parse("http://www.example.com/authorize"), oauth.getAuthorizationUrl()); Multimap<String, Node> extra = prefs.getExtraElements(); assertTrue(extra.containsKey("NavigationItem")); assertEquals(1, extra.get("NavigationItem").iterator().next().getChildNodes().getLength()); }
/** * Tests for MakeRequestServlet. * * <p>Tests are trivial; real tests are in MakeRequestHandlerTest. */ public class MakeRequestServletTest { private static final Uri REQUEST_URL = Uri.parse("http://example.org/file"); private static final String RESPONSE_BODY = "Hello, world!"; private static final String ERROR_MESSAGE = "Broken!"; private static final Enumeration<String> EMPTY_ENUM = Collections.enumeration(Collections.<String>emptyList()); private final ServletTestFixture fixture = new ServletTestFixture(); private final MakeRequestServlet servlet = new MakeRequestServlet(); private final MakeRequestHandler handler = new MakeRequestHandler( fixture.contentFetcherFactory, fixture.securityTokenDecoder, fixture.rewriter); private final HttpServletResponseRecorder recorder = new HttpServletResponseRecorder(fixture.response); private final HttpRequest request = new HttpRequest(REQUEST_URL); private final HttpResponse response = new HttpResponse(RESPONSE_BODY); @Before public void setUp() { servlet.setMakeRequestHandler(handler); expect(fixture.request.getHeaderNames()).andReturn(EMPTY_ENUM).anyTimes(); expect(fixture.request.getParameter(MakeRequestHandler.METHOD_PARAM)) .andReturn("GET") .anyTimes(); expect(fixture.request.getParameter(ProxyBase.URL_PARAM)) .andReturn(REQUEST_URL.toString()) .anyTimes(); } private void setupGet() { expect(fixture.request.getMethod()).andReturn("GET").anyTimes(); } private void setupPost() { expect(fixture.request.getMethod()).andReturn("POST").anyTimes(); } private void assertResponseOk(int expectedStatus, String expectedBody) throws JSONException { if (recorder.getHttpStatusCode() == HttpServletResponse.SC_OK) { String body = recorder.getResponseAsString(); assertStartsWith(MakeRequestHandler.UNPARSEABLE_CRUFT, body); body = body.substring(MakeRequestHandler.UNPARSEABLE_CRUFT.length()); JSONObject object = new JSONObject(body); object = object.getJSONObject(REQUEST_URL.toString()); assertEquals(expectedStatus, object.getInt("rc")); assertEquals(expectedBody, object.getString("body")); } else { fail("Invalid response for request."); } } @Test public void doGetNormal() throws Exception { setupGet(); expect(fixture.httpFetcher.fetch(request)).andReturn(response); fixture.replay(); servlet.doGet(fixture.request, recorder); assertResponseOk(HttpResponse.SC_OK, RESPONSE_BODY); } @Test public void doGetHttpError() throws Exception { setupGet(); expect(fixture.httpFetcher.fetch(request)).andReturn(HttpResponse.notFound()); fixture.replay(); servlet.doGet(fixture.request, recorder); assertResponseOk(HttpResponse.SC_NOT_FOUND, ""); } @Test public void doGetException() throws Exception { setupGet(); expect(fixture.httpFetcher.fetch(request)) .andThrow( new GadgetException(GadgetException.Code.FAILED_TO_RETRIEVE_CONTENT, ERROR_MESSAGE)); fixture.replay(); servlet.doGet(fixture.request, recorder); assertEquals(HttpServletResponse.SC_BAD_REQUEST, recorder.getHttpStatusCode()); assertContains(ERROR_MESSAGE, recorder.getResponseAsString()); } @Test public void doPostNormal() throws Exception { setupPost(); expect(fixture.httpFetcher.fetch(request)).andReturn(response); fixture.replay(); servlet.doPost(fixture.request, recorder); assertResponseOk(HttpResponse.SC_OK, RESPONSE_BODY); } @Test public void doPostHttpError() throws Exception { setupPost(); expect(fixture.httpFetcher.fetch(request)).andReturn(HttpResponse.notFound()); fixture.replay(); servlet.doGet(fixture.request, recorder); assertResponseOk(HttpResponse.SC_NOT_FOUND, ""); } @Test public void doPostException() throws Exception { setupPost(); expect(fixture.httpFetcher.fetch(request)) .andThrow( new GadgetException(GadgetException.Code.FAILED_TO_RETRIEVE_CONTENT, ERROR_MESSAGE)); fixture.replay(); servlet.doPost(fixture.request, recorder); assertEquals(HttpServletResponse.SC_BAD_REQUEST, recorder.getHttpStatusCode()); assertContains(ERROR_MESSAGE, recorder.getResponseAsString()); } }
private URI nullSafeToJavaUri(org.apache.shindig.common.uri.Uri shindigUri) { if (shindigUri != null) { return shindigUri.toJavaUri(); } return null; }
private void expectGetAndReturnHeaders(String url, Map<String, List<String>> headers) throws Exception { HttpRequest req = new HttpRequest(Uri.parse(url)); HttpResponse resp = new HttpResponseBuilder().addAllHeaders(headers).create(); expect(pipeline.execute(req)).andReturn(resp); }
private void expectGetAndReturnData(String url, byte[] data) throws Exception { HttpRequest req = new HttpRequest(Uri.parse(url)); HttpResponse resp = new HttpResponseBuilder().setResponse(data).create(); expect(pipeline.execute(req)).andReturn(resp); }
public HttpResponse fetch(org.apache.shindig.gadgets.http.HttpRequest request) throws GadgetException { HttpUriRequest httpMethod = null; Preconditions.checkNotNull(request); final String methodType = request.getMethod(); final org.apache.http.HttpResponse response; final long started = System.currentTimeMillis(); // Break the request Uri to its components: Uri uri = request.getUri(); if (StringUtils.isEmpty(uri.getAuthority())) { throw new GadgetException( GadgetException.Code.INVALID_USER_DATA, "Missing domain name for request: " + uri, HttpServletResponse.SC_BAD_REQUEST); } if (StringUtils.isEmpty(uri.getScheme())) { throw new GadgetException( GadgetException.Code.INVALID_USER_DATA, "Missing schema for request: " + uri, HttpServletResponse.SC_BAD_REQUEST); } String[] hostparts = StringUtils.splitPreserveAllTokens(uri.getAuthority(), ':'); int port = -1; // default port if (hostparts.length > 2) { throw new GadgetException( GadgetException.Code.INVALID_USER_DATA, "Bad host name in request: " + uri.getAuthority(), HttpServletResponse.SC_BAD_REQUEST); } if (hostparts.length == 2) { try { port = Integer.parseInt(hostparts[1]); } catch (NumberFormatException e) { throw new GadgetException( GadgetException.Code.INVALID_USER_DATA, "Bad port number in request: " + uri.getAuthority(), HttpServletResponse.SC_BAD_REQUEST); } } String requestUri = uri.getPath(); // Treat path as / if set as null. if (uri.getPath() == null) { requestUri = "/"; } if (uri.getQuery() != null) { requestUri += '?' + uri.getQuery(); } // Get the http host to connect to. HttpHost host = new HttpHost(hostparts[0], port, uri.getScheme()); try { if ("POST".equals(methodType) || "PUT".equals(methodType)) { HttpEntityEnclosingRequestBase enclosingMethod = ("POST".equals(methodType)) ? new HttpPost(requestUri) : new HttpPut(requestUri); if (request.getPostBodyLength() > 0) { enclosingMethod.setEntity( new InputStreamEntity(request.getPostBody(), request.getPostBodyLength())); } httpMethod = enclosingMethod; } else if ("GET".equals(methodType)) { httpMethod = new HttpGet(requestUri); } else if ("HEAD".equals(methodType)) { httpMethod = new HttpHead(requestUri); } else if ("DELETE".equals(methodType)) { httpMethod = new HttpDelete(requestUri); } for (Map.Entry<String, List<String>> entry : request.getHeaders().entrySet()) { httpMethod.addHeader(entry.getKey(), StringUtils.join(entry.getValue(), ',')); } // Disable following redirects. if (!request.getFollowRedirects()) { httpMethod.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false); } // HttpClient doesn't handle all cases when breaking url (specifically '_' in domain) // So lets pass it the url parsed: response = FETCHER.execute(host, httpMethod); if (response == null) { throw new IOException("Unknown problem with request"); } long now = System.currentTimeMillis(); if (now - started > slowResponseWarning) { slowResponseWarning(request, started, now); } return makeResponse(response); } catch (Exception e) { long now = System.currentTimeMillis(); // Find timeout exceptions, respond accordingly if (TIMEOUT_EXCEPTIONS.contains(e.getClass())) { LOG.info( "Timeout for " + request.getUri() + " Exception: " + e.getClass().getName() + " - " + e.getMessage() + " - " + (now - started) + "ms"); return HttpResponse.timeout(); } LOG.log( Level.INFO, "Got Exception fetching " + request.getUri() + " - " + (now - started) + "ms", e); // Separate shindig error from external error throw new GadgetException( GadgetException.Code.INTERNAL_SERVER_ERROR, e, HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } finally { // cleanup any outstanding resources.. if (httpMethod != null) try { httpMethod.abort(); } catch (UnsupportedOperationException e) { // ignore } } }
public class PipelineExecutorTest { private IMocksControl control; private PipelinedDataPreloader preloader; private PreloaderService preloaderService; private GadgetContext context; private PipelineExecutor executor; private static final Uri GADGET_URI = Uri.parse("http://example.org/gadget.php"); private static final String CONTENT = "<Content xmlns:os=\"http://ns.opensocial.org/2008/markup\">" + " <os:PeopleRequest key=\"me\" userId=\"canonical\"/>" + " <os:HttpRequest key=\"json\" href=\"test.json\"/>" + "</Content>"; // Two requests, one depends on the other private static final String TWO_BATCH_CONTENT = "<Content xmlns:os=\"http://ns.opensocial.org/2008/markup\">" + " <os:PeopleRequest key=\"me\" userId=\"${json.user}\"/>" + " <os:HttpRequest key=\"json\" href=\"${ViewParams.file}\"/>" + "</Content>"; // One request, but it requires data that isn\"t present private static final String BLOCKED_FIRST_BATCH_CONTENT = "<Content xmlns:os=\"http://ns.opensocial.org/2008/markup\">" + " <os:PeopleRequest key=\"me\" userId=\"${json.user}\"/>" + "</Content>"; @Before public void setUp() throws Exception { control = EasyMock.createStrictControl(); preloader = control.createMock(PipelinedDataPreloader.class); preloaderService = new ConcurrentPreloaderService(Executors.newSingleThreadExecutor(), null); executor = new PipelineExecutor(preloader, preloaderService, Expressions.forTesting()); context = new GadgetContext() {}; } private PipelinedData getPipelinedData(String pipelineXml) throws SpecParserException { Element element = XmlUtil.parseSilent(pipelineXml); return new PipelinedData(element, GADGET_URI); } @Test public void execute() throws Exception { PipelinedData pipeline = getPipelinedData(CONTENT); Capture<PipelinedData.Batch> batchCapture = new Capture<PipelinedData.Batch>(); JSONObject expectedData = new JSONObject("{result: {foo: 'bar'}}"); // Dummy return results (the "real" return would have two values) Callable<PreloadedData> callable = createPreloadTask("key", expectedData.toString()); // One batch with 1 each HTTP and Social preload expect(preloader.createPreloadTasks(same(context), and(eqBatch(1, 1), capture(batchCapture)))) .andReturn(ImmutableList.of(callable)); control.replay(); PipelineExecutor.Results results = executor.execute(context, ImmutableList.of(pipeline)); // Verify the data set is injected, and the os-data was deleted assertTrue(batchCapture.getValue().getPreloads().containsKey("me")); assertTrue(batchCapture.getValue().getPreloads().containsKey("json")); JsonAssert.assertJsonEquals( "[{id: 'key', result: {foo: 'bar'}}]", JsonSerializer.serialize(results.results)); JsonAssert.assertJsonEquals( "{foo: 'bar'}", JsonSerializer.serialize(results.keyedResults.get("key"))); assertTrue(results.remainingPipelines.isEmpty()); control.verify(); } @Test public void executeWithTwoBatches() throws Exception { PipelinedData pipeline = getPipelinedData(TWO_BATCH_CONTENT); context = new GadgetContext() { @Override public String getParameter(String property) { // Provide the filename to be requested in the first batch if ("view-params".equals(property)) { return "{'file': 'test.json'}"; } return null; } }; // First batch, the HTTP fetch Capture<PipelinedData.Batch> firstBatch = new Capture<PipelinedData.Batch>(); Callable<PreloadedData> firstTask = createPreloadTask("json", "{result: {user: '******'}}"); // Second batch, the user fetch Capture<PipelinedData.Batch> secondBatch = new Capture<PipelinedData.Batch>(); Callable<PreloadedData> secondTask = createPreloadTask("me", "{result: {'id':'canonical'}}"); // First, a batch with an HTTP request expect(preloader.createPreloadTasks(same(context), and(eqBatch(0, 1), capture(firstBatch)))) .andReturn(ImmutableList.of(firstTask)); // Second, a batch with a social request expect(preloader.createPreloadTasks(same(context), and(eqBatch(1, 0), capture(secondBatch)))) .andReturn(ImmutableList.of(secondTask)); control.replay(); PipelineExecutor.Results results = executor.execute(context, ImmutableList.of(pipeline)); JsonAssert.assertJsonEquals( "[{id: 'json', result: {user: '******'}}," + "{id: 'me', result: {id: 'canonical'}}]", JsonSerializer.serialize(results.results)); assertEquals(ImmutableSet.of("json", "me"), results.keyedResults.keySet()); assertTrue(results.remainingPipelines.isEmpty()); control.verify(); // Verify the data set is injected, and the os-data was deleted // Check the evaluated HTTP request RequestAuthenticationInfo request = (RequestAuthenticationInfo) firstBatch.getValue().getPreloads().get("json").getData(); assertEquals("http://example.org/test.json", request.getHref().toString()); // Check the evaluated person request JSONObject personRequest = (JSONObject) secondBatch.getValue().getPreloads().get("me").getData(); assertEquals("canonical", personRequest.getJSONObject("params").getJSONArray("userId").get(0)); } @Test public void executeWithBlockedBatch() throws Exception { PipelinedData pipeline = getPipelinedData(BLOCKED_FIRST_BATCH_CONTENT); // Expect a batch with no content expect(preloader.createPreloadTasks(same(context), eqBatch(0, 0))) .andReturn(ImmutableList.<Callable<PreloadedData>>of()); control.replay(); PipelineExecutor.Results results = executor.execute(context, ImmutableList.of(pipeline)); assertEquals(0, results.results.size()); assertTrue(results.keyedResults.isEmpty()); assertEquals(1, results.remainingPipelines.size()); assertSame(pipeline, results.remainingPipelines.iterator().next()); control.verify(); } @Test public void executeError() throws Exception { PipelinedData pipeline = getPipelinedData(CONTENT); Capture<PipelinedData.Batch> batchCapture = new Capture<PipelinedData.Batch>(); JSONObject expectedData = new JSONObject("{error: {message: 'NO!', code: 500}}"); // Dummy return results (the "real" return would have two values) Callable<PreloadedData> callable = createPreloadTask("key", expectedData.toString()); // One batch with 1 each HTTP and Social preload expect(preloader.createPreloadTasks(same(context), and(eqBatch(1, 1), capture(batchCapture)))) .andReturn(ImmutableList.of(callable)); control.replay(); PipelineExecutor.Results results = executor.execute(context, ImmutableList.of(pipeline)); // Verify the data set is injected, and the os-data was deleted assertTrue(batchCapture.getValue().getPreloads().containsKey("me")); assertTrue(batchCapture.getValue().getPreloads().containsKey("json")); JsonAssert.assertJsonEquals( "[{id: 'key', error: {message: 'NO!', code: 500}}]", JsonSerializer.serialize(results.results)); JsonAssert.assertJsonEquals( "{message: 'NO!', code: 500}", JsonSerializer.serialize(results.keyedResults.get("key"))); assertTrue(results.remainingPipelines.isEmpty()); control.verify(); } @Test public void executePreloadException() throws Exception { PipelinedData pipeline = getPipelinedData(CONTENT); final PreloadedData willThrow = control.createMock(PreloadedData.class); Callable<PreloadedData> callable = new Callable<PreloadedData>() { public PreloadedData call() throws Exception { return willThrow; } }; // One batch expect(preloader.createPreloadTasks(same(context), isA(PipelinedData.Batch.class))) .andReturn(ImmutableList.of(callable)); // And PreloadedData that throws an exception expect(willThrow.toJson()).andThrow(new PreloadException("Failed")); control.replay(); PipelineExecutor.Results results = executor.execute(context, ImmutableList.of(pipeline)); // The exception is fully handled, and leads to empty results assertEquals(0, results.results.size()); assertTrue(results.keyedResults.isEmpty()); assertTrue(results.remainingPipelines.isEmpty()); control.verify(); } /** Match a batch with the specified count of social and HTTP data items */ private PipelinedData.Batch eqBatch(int socialCount, int httpCount) { reportMatcher(new BatchMatcher(socialCount, httpCount)); return null; } private static class BatchMatcher implements IArgumentMatcher { private final int socialCount; private final int httpCount; public BatchMatcher(int socialCount, int httpCount) { this.socialCount = socialCount; this.httpCount = httpCount; } public void appendTo(StringBuffer buffer) { buffer .append("eqBuffer[social=") .append(socialCount) .append(",http=") .append(httpCount) .append(']'); } public boolean matches(Object obj) { if (!(obj instanceof PipelinedData.Batch)) { return false; } PipelinedData.Batch batch = (PipelinedData.Batch) obj; int actualSocialCount = 0; int actualHttpCount = 0; for (PipelinedData.BatchItem item : batch.getPreloads().values()) { if (item.getType() == PipelinedData.BatchType.HTTP) { actualHttpCount++; } else if (item.getType() == PipelinedData.BatchType.SOCIAL) { actualSocialCount++; } } return socialCount == actualSocialCount && httpCount == actualHttpCount; } } /** Create a mock Callable for a single preload task */ private Callable<PreloadedData> createPreloadTask(final String key, String jsonResult) throws JSONException { final JSONObject value = new JSONObject(jsonResult); value.put("id", key); final PreloadedData preloadResult = new PreloadedData() { public Collection<Object> toJson() throws PreloadException { return ImmutableList.<Object>of(value); } }; Callable<PreloadedData> callable = new Callable<PreloadedData>() { public PreloadedData call() throws Exception { return preloadResult; } }; return callable; } }
/** Tests for HtmlRenderer */ public class HtmlRendererTest { private static final Uri SPEC_URL = Uri.parse("http://example.org/gadget.xml"); private static final String BASIC_HTML_CONTENT = "Hello, World!"; private static final String PROXIED_HTML_CONTENT = "Hello, Universe!"; private static final Uri PROXIED_HTML_HREF = Uri.parse("http://example.org/proxied.php"); private static final GadgetContext CONTEXT = new GadgetContext() { @Override public SecurityToken getToken() { return new AnonymousSecurityToken(); } }; private final FakePreloaderService preloaderService = new FakePreloaderService(); private final FakeProxyRenderer proxyRenderer = new FakeProxyRenderer(); private final CaptureRewriter captureRewriter = new CaptureRewriter(); private HtmlRenderer renderer; private Gadget makeGadget(String content) throws GadgetException { GadgetSpec spec = new GadgetSpec( SPEC_URL, "<Module><ModulePrefs title=''/><Content><![CDATA[" + content + "]]></Content></Module>"); return new Gadget().setSpec(spec).setContext(CONTEXT).setCurrentView(spec.getView("default")); } private Gadget makeHrefGadget(String authz) throws Exception { Gadget gadget = makeGadget(""); String doc = "<Content href='" + PROXIED_HTML_HREF + "' authz='" + authz + "'/>"; View view = new View("proxied", Arrays.asList(XmlUtil.parse(doc)), SPEC_URL); gadget.setCurrentView(view); return gadget; } @Before public void setUp() throws Exception { renderer = new HtmlRenderer( preloaderService, proxyRenderer, new GadgetRewritersProvider(ImmutableList.of((GadgetRewriter) captureRewriter)), null); } @Test public void renderPlainTypeHtml() throws Exception { String content = renderer.render(makeGadget(BASIC_HTML_CONTENT)); assertEquals(BASIC_HTML_CONTENT, content); } @Test public void renderProxied() throws Exception { String content = renderer.render(makeHrefGadget("none")); assertEquals(PROXIED_HTML_CONTENT, content); } @Test public void doPreloading() throws Exception { renderer.render(makeGadget(BASIC_HTML_CONTENT)); assertTrue("Preloading not performed.", preloaderService.wasPreloaded); } @Test public void doRewriting() throws Exception { renderer.render(makeGadget(BASIC_HTML_CONTENT)); assertTrue("Rewriting not performed.", captureRewriter.viewWasRewritten()); } private static class FakeProxyRenderer extends ProxyRenderer { public FakeProxyRenderer() { super(null, null, null); } @Override public String render(Gadget gadget) throws RenderingException, GadgetException { return PROXIED_HTML_CONTENT; } } private static class FakePreloaderService implements PreloaderService { protected boolean wasPreloaded; protected Collection<PreloadedData> preloads; protected FakePreloaderService() {} public Collection<PreloadedData> preload(Gadget gadget) { wasPreloaded = true; return preloads; } public Collection<PreloadedData> preload(Collection<Callable<PreloadedData>> tasks) { wasPreloaded = true; return preloads; } } }
public class ModulePrefsTest { private static final Uri SPEC_URL = Uri.parse("http://example.org/g.xml"); private static final String FULL_XML = "<ModulePrefs" + " title='title'" + " title_url='title_url'" + " description='description'" + " author='author'" + " author_email='author_email'" + " screenshot='screenshot'" + " thumbnail='thumbnail'" + " directory_title='directory_title'" + " width='1'" + " height='2'" + " scrolling='true'" + " category='category'" + " category2='category2'" + " author_affiliation='author_affiliation'" + " author_location='author_location'" + " author_photo='author_photo'" + " author_aboutme='author_aboutme'" + " author_quote='author_quote'" + " author_link='author_link'" + " show_stats='true'" + " show_in_directory='true'" + " singleton='true'>" + " <Require feature='require'/>" + " <Optional feature='optional'/>" + " <Preload href='http://example.org' authz='signed'/>" + " <Icon/>" + " <Locale/>" + " <Link rel='link' href='http://example.org/link'/>" + " <OAuth>" + " <Service name='serviceOne'>" + " <Request url='http://www.example.com/request'" + " method='GET' param_location='auth-header' />" + " <Authorization url='http://www.example.com/authorize'/>" + " <Access url='http://www.example.com/access' method='GET'" + " param_location='auth-header' />" + " </Service>" + " </OAuth>" + " <NavigationItem title=\"moo\"><AppParameter key=\"test\" value=\"1\"/></NavigationItem>" + "</ModulePrefs>"; private void doAsserts(ModulePrefs prefs) { assertEquals("title", prefs.getTitle()); assertEquals(SPEC_URL.resolve(Uri.parse("title_url")), prefs.getTitleUrl()); assertEquals("description", prefs.getDescription()); assertEquals("author", prefs.getAuthor()); assertEquals("author_email", prefs.getAuthorEmail()); assertEquals(SPEC_URL.resolve(Uri.parse("screenshot")), prefs.getScreenshot()); assertEquals(SPEC_URL.resolve(Uri.parse("thumbnail")), prefs.getThumbnail()); assertEquals("directory_title", prefs.getDirectoryTitle()); assertEquals(1, prefs.getWidth()); assertEquals(2, prefs.getHeight()); assertTrue(prefs.getScrolling()); assertFalse(prefs.getScaling()); assertEquals("category", prefs.getCategories().get(0)); assertEquals("category2", prefs.getCategories().get(1)); assertEquals("author_affiliation", prefs.getAuthorAffiliation()); assertEquals("author_location", prefs.getAuthorLocation()); assertEquals(SPEC_URL.resolve(Uri.parse("author_photo")), prefs.getAuthorPhoto()); assertEquals(SPEC_URL.resolve(Uri.parse("author_link")), prefs.getAuthorLink()); assertEquals("author_aboutme", prefs.getAuthorAboutme()); assertEquals("author_quote", prefs.getAuthorQuote()); assertTrue(prefs.getShowStats()); assertTrue(prefs.getShowInDirectory()); assertTrue(prefs.getSingleton()); assertTrue(prefs.getFeatures().get("require").getRequired()); assertFalse(prefs.getFeatures().get("optional").getRequired()); assertEquals("http://example.org", prefs.getPreloads().get(0).getHref().toString()); assertEquals(1, prefs.getIcons().size()); assertEquals(1, prefs.getLocales().size()); assertEquals(Uri.parse("http://example.org/link"), prefs.getLinks().get("link").getHref()); OAuthService oauth = prefs.getOAuthSpec().getServices().get("serviceOne"); assertEquals(Uri.parse("http://www.example.com/request"), oauth.getRequestUrl().url); assertEquals(OAuthService.Method.GET, oauth.getRequestUrl().method); assertEquals(OAuthService.Method.GET, oauth.getAccessUrl().method); assertEquals(OAuthService.Location.HEADER, oauth.getAccessUrl().location); assertEquals(Uri.parse("http://www.example.com/authorize"), oauth.getAuthorizationUrl()); Multimap<String, Node> extra = prefs.getExtraElements(); assertTrue(extra.containsKey("NavigationItem")); assertEquals(1, extra.get("NavigationItem").iterator().next().getChildNodes().getLength()); } @Test public void basicElementsParseOk() throws Exception { doAsserts(new ModulePrefs(XmlUtil.parse(FULL_XML), SPEC_URL)); } @Test public void getAttribute() throws Exception { String xml = "<ModulePrefs title='title' some_attribute='attribute' " + "empty_attribute=''/>"; ModulePrefs prefs = new ModulePrefs(XmlUtil.parse(xml), SPEC_URL); assertEquals("title", prefs.getAttribute("title")); assertEquals("attribute", prefs.getAttribute("some_attribute")); assertEquals("", prefs.getAttribute("empty_attribute")); assertNull(prefs.getAttribute("gobbledygook")); } @Test public void getLocale() throws Exception { String xml = "<ModulePrefs title='locales'>" + " <Locale lang='en' country='UK' messages='en.xml'/>" + " <Locale lang='foo' language_direction='rtl'/>" + "</ModulePrefs>"; ModulePrefs prefs = new ModulePrefs(XmlUtil.parse(xml), SPEC_URL); LocaleSpec spec = prefs.getLocale(new Locale("en", "UK")); assertEquals("http://example.org/en.xml", spec.getMessages().toString()); spec = prefs.getLocale(new Locale("foo", "ALL")); assertEquals("rtl", spec.getLanguageDirection()); spec = prefs.getLocale(new Locale("en", "notexist")); assertNull(spec); } @Test public void getLinks() throws Exception { String link1Rel = "foo"; String link2Rel = "bar"; Uri link1Href = Uri.parse("http://example.org/foo"); Uri link2Href = Uri.parse("/bar"); String xml = "<ModulePrefs title='links'>" + " <Link rel='" + link1Rel + "' href='" + link1Href + "'/>" + " <Link rel='" + link2Rel + "' href='" + link2Href + "'/>" + "</ModulePrefs>"; ModulePrefs prefs = new ModulePrefs(XmlUtil.parse(xml), SPEC_URL).substitute(new Substitutions()); assertEquals(link1Href, prefs.getLinks().get(link1Rel).getHref()); assertEquals(SPEC_URL.resolve(link2Href), prefs.getLinks().get(link2Rel).getHref()); } @Test public void doSubstitution() throws Exception { String xml = "<ModulePrefs title='__MSG_title__'>" + " <Icon>__MSG_icon__</Icon>" + " <Link rel='__MSG_rel__' href='__MSG_link_href__'/>" + " <Preload href='__MSG_pre_href__'/>" + "</ModulePrefs>"; String title = "blah"; String icon = "http://example.org/icon.gif"; String rel = "foo-bar"; String linkHref = "http://example.org/link.html"; String preHref = "http://example.org/preload.html"; ModulePrefs prefs = new ModulePrefs(XmlUtil.parse(xml), SPEC_URL); Substitutions subst = new Substitutions(); subst.addSubstitution(Substitutions.Type.MESSAGE, "title", title); subst.addSubstitution(Substitutions.Type.MESSAGE, "icon", icon); subst.addSubstitution(Substitutions.Type.MESSAGE, "rel", rel); subst.addSubstitution(Substitutions.Type.MESSAGE, "link_href", linkHref); subst.addSubstitution(Substitutions.Type.MESSAGE, "pre_href", preHref); prefs = prefs.substitute(subst); assertEquals(title, prefs.getTitle()); assertEquals(icon, prefs.getIcons().get(0).getContent()); assertEquals(rel, prefs.getLinks().get(rel).getRel()); assertEquals(linkHref, prefs.getLinks().get(rel).getHref().toString()); assertEquals(preHref, prefs.getPreloads().get(0).getHref().toString()); } @Test public void malformedIntAttributeTreatedAsZero() throws Exception { String xml = "<ModulePrefs title='' height='100px' width='foobar' arbitrary='0xff'/>"; ModulePrefs prefs = new ModulePrefs(XmlUtil.parse(xml), SPEC_URL); assertEquals(0, prefs.getHeight()); assertEquals(0, prefs.getWidth()); assertEquals(0, prefs.getIntAttribute("arbitrary")); } @Test public void missingTitleOkay() throws Exception { String xml = "<ModulePrefs/>"; ModulePrefs prefs = new ModulePrefs(XmlUtil.parse(xml), SPEC_URL); assertNotNull("Empty ModulePrefs Parses", prefs); assertEquals("Title is empty string", "", prefs.getTitle()); } @Test public void coreInjectedAutomatically() throws Exception { String xml = "<ModulePrefs title=''><Require feature='foo'/></ModulePrefs>"; ModulePrefs prefs = new ModulePrefs(XmlUtil.parse(xml), SPEC_URL); assertEquals(2, prefs.getFeatures().size()); assertTrue(prefs.getFeatures().containsKey("foo")); assertTrue(prefs.getFeatures().containsKey("core")); } @Test public void coreNotInjectedOnSplitCoreInclusion() throws Exception { String xml = "<ModulePrefs title=''><Require feature='core.config'/></ModulePrefs>"; ModulePrefs prefs = new ModulePrefs(XmlUtil.parse(xml), SPEC_URL); assertEquals(1, prefs.getFeatures().size()); assertTrue(prefs.getFeatures().containsKey("core.config")); } @Test public void securityTokenInjectedOnOAuthTag() throws Exception { String xml = "<ModulePrefs title=''>" + " <OAuth>" + " <Service name='serviceOne'>" + " <Request url='http://www.example.com/request'" + " method='GET' param_location='auth-header' />" + " <Authorization url='http://www.example.com/authorize'/>" + " <Access url='http://www.example.com/access' method='GET'" + " param_location='auth-header' />" + " </Service>" + " </OAuth>" + "</ModulePrefs>"; ModulePrefs prefs = new ModulePrefs(XmlUtil.parse(xml), SPEC_URL); assertEquals(2, prefs.getFeatures().size()); assertTrue(prefs.getFeatures().containsKey("core")); assertTrue(prefs.getFeatures().containsKey("security-token")); } @Test public void toStringIsSane() throws Exception { ModulePrefs prefs = new ModulePrefs(XmlUtil.parse(FULL_XML), SPEC_URL); doAsserts(new ModulePrefs(XmlUtil.parse(prefs.toString()), SPEC_URL)); } @Test public void needsUserPrefSubstInTitle() throws Exception { String xml = "<ModulePrefs title='Title __UP_foo__'/>"; ModulePrefs prefs = new ModulePrefs(XmlUtil.parse(xml), SPEC_URL); assertTrue(prefs.needsUserPrefSubstitution()); } @Test public void needsUserPrefSubstInTitleUrl() throws Exception { String xml = "<ModulePrefs title='foo' title_url='http://__UP_url__'/>"; ModulePrefs prefs = new ModulePrefs(XmlUtil.parse(xml), SPEC_URL); assertTrue(prefs.needsUserPrefSubstitution()); } @Test public void needsUserPrefSubstInPreload() throws Exception { String xml = "<ModulePrefs title='foo'>" + " <Preload href='__UP_foo__' authz='signed'/></ModulePrefs>"; ModulePrefs prefs = new ModulePrefs(XmlUtil.parse(xml), SPEC_URL); assertTrue(prefs.needsUserPrefSubstitution()); } }