You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by et...@apache.org on 2008/04/03 02:40:14 UTC

svn commit: r644123 [3/3] - in /incubator/shindig/trunk: features/core.io/ java/gadgets/ java/gadgets/conf/ java/gadgets/src/main/java/org/apache/shindig/gadgets/ java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ java/gadgets/src/main/java/or...

Added: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/UrlGenerator.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/UrlGenerator.java?rev=644123&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/UrlGenerator.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/UrlGenerator.java Wed Apr  2 17:40:05 2008
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.shindig.gadgets.http;
+
+import org.apache.shindig.gadgets.Gadget;
+import org.apache.shindig.gadgets.GadgetContext;
+import org.apache.shindig.gadgets.GadgetFeature;
+import org.apache.shindig.gadgets.GadgetFeatureFactory;
+import org.apache.shindig.gadgets.GadgetFeatureRegistry;
+import org.apache.shindig.gadgets.JsLibrary;
+import org.apache.shindig.gadgets.UserPrefs;
+import org.apache.shindig.gadgets.spec.GadgetSpec;
+import org.apache.shindig.gadgets.spec.UserPref;
+import org.apache.shindig.gadgets.spec.View;
+import org.apache.shindig.util.HashUtil;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Collection;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * Generates urls for various public entrypoints
+ */
+public class UrlGenerator {
+
+  private final String jsPrefix;
+  private final String iframePrefix;
+  private final String jsChecksum;
+  private final static Pattern ALLOWED_FEATURE_NAME
+      = Pattern.compile("[0-9a-zA-Z\\.\\-]+");
+
+  /**
+   * @param features The list of features that js is needed for.
+   * @return The url for the bundled javascript that includes all referenced
+   *    feature libraries.
+   */
+  public String getBundledJsUrl(Collection<String> features,
+      GadgetContext context) {
+    return jsPrefix + getBundledJsParam(features, context);
+  }
+
+  /**
+   * @param features
+   * @param context
+   * @return The bundled js parameter for type=url gadgets.
+   */
+  public String getBundledJsParam(Collection<String> features,
+      GadgetContext context) {
+    StringBuilder buf = new StringBuilder();
+    boolean first = false;
+    for (String feature : features) {
+      if (ALLOWED_FEATURE_NAME.matcher(feature).matches()) {
+        if (!first) {
+          first = true;
+        } else {
+          buf.append(':');
+        }
+        buf.append(feature);
+      }
+    }
+    buf.append(".js?v=").append(jsChecksum)
+       .append("&synd=").append(context.getSyndicator())
+       .append("&debug=").append(context.getDebug() ? "1" : "0");
+    return buf.toString();
+  }
+
+  /**
+   * Generates iframe urls for meta data service.
+   * Use this rather than generating your own urls by hand.
+   *
+   * @param gadget
+   * @return The generated iframe url.
+   */
+  public String getIframeUrl(Gadget gadget) {
+    StringBuilder buf = new StringBuilder();
+    GadgetContext context = gadget.getContext();
+    GadgetSpec spec = gadget.getSpec();
+    try {
+      String url = context.getUrl().toString();
+      View.ContentType type = spec.getView(context.getView()).getType();
+      switch (type) {
+        case URL:
+          // type = url
+          buf.append(url);
+          if (url.indexOf('?') == -1) {
+            buf.append('?');
+          } else {
+            buf.append('&');
+          }
+          break;
+        case HTML:
+        default:
+          buf.append(iframePrefix)
+             .append("url=")
+             .append(URLEncoder.encode(url, "UTF-8"))
+             .append("&");
+          break;
+      }
+      if (context.getModuleId() != 0) {
+        buf.append("mid=").append(context.getModuleId());
+      }
+      buf.append("&synd=").append(context.getSyndicator());
+      if (context.getIgnoreCache()) {
+        buf.append("&nocache=1");
+      } else {
+        buf.append("&v=").append(spec.getChecksum());
+      }
+
+      buf.append("&lang=").append(context.getLocale().getLanguage());
+      buf.append("&country=").append(context.getLocale().getCountry());
+
+      UserPrefs prefs = context.getUserPrefs();
+      for (UserPref pref : gadget.getSpec().getUserPrefs()) {
+        String name = pref.getName();
+        String value = prefs.getPref(name);
+        if (value == null) {
+          value = pref.getDefaultValue();
+        }
+        buf.append("&up_").append(URLEncoder.encode(pref.getName(), "UTF-8"))
+           .append("=").append(URLEncoder.encode(value, "UTF-8"));
+      }
+    } catch (UnsupportedEncodingException e) {
+      throw new RuntimeException("UTF-8 Not supported!", e);
+    }
+    return buf.toString();
+  }
+
+  @Inject
+  public UrlGenerator(@Named("urls.iframe.prefix") String iframePrefix,
+                      @Named("urls.js.prefix") String jsPrefix,
+                      GadgetFeatureRegistry registry) {
+    this.iframePrefix = iframePrefix;
+    this.jsPrefix = jsPrefix;
+
+    StringBuilder jsBuf = new StringBuilder();
+    for (Map.Entry<String, GadgetFeatureRegistry.Entry> entry :
+        registry.getAllFeatures().entrySet()) {
+      GadgetFeatureFactory factory = entry.getValue().getFeature();
+      GadgetFeature feature = factory.create();
+      for (JsLibrary library : feature.getJsLibraries(null)) {
+        jsBuf.append(library.getContent());
+      }
+    }
+    jsChecksum = HashUtil.checksum(jsBuf.toString().getBytes());
+  }
+}

Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/Preload.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/Preload.java?rev=644123&r1=644122&r2=644123&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/Preload.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/Preload.java Wed Apr  2 17:40:05 2008
@@ -1,10 +1,10 @@
 package org.apache.shindig.gadgets.spec;
 
 import org.apache.shindig.util.XmlUtil;
+
 import org.w3c.dom.Element;
 
 import java.net.URI;
-import java.util.Map;
 
 /**
  * Represents an addressable piece of content that can be preloaded by the server
@@ -41,7 +41,4 @@
       throw new SpecParserException("Preload@href is required.");
     }
   }
-
-
-
 }

Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/GadgetDataServlet.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/GadgetDataServlet.java?rev=644123&r1=644122&r2=644123&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/GadgetDataServlet.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/GadgetDataServlet.java Wed Apr  2 17:40:05 2008
@@ -17,24 +17,27 @@
  */
 package org.apache.shindig.social;
 
+import org.apache.shindig.gadgets.GadgetException;
+import org.apache.shindig.gadgets.GadgetToken;
+import org.apache.shindig.gadgets.GadgetTokenDecoder;
+import org.apache.shindig.gadgets.http.InjectedServlet;
+import org.apache.shindig.social.opensocial.OpenSocialDataHandler;
+import org.apache.shindig.social.samplecontainer.StateFileDataHandler;
+
+import com.google.inject.Inject;
+
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
-import org.apache.shindig.social.samplecontainer.StateFileDataHandler;
-import org.apache.shindig.social.opensocial.OpenSocialDataHandler;
-import org.apache.shindig.gadgets.GadgetException;
-import org.apache.shindig.gadgets.GadgetToken;
-import org.apache.shindig.gadgets.http.CrossServletState;
 
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.util.logging.Logger;
-import java.util.List;
 import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
 
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
@@ -54,7 +57,7 @@
  *
  * This class is meant to work with the logic in jsoncontainer.js.
  */
-public class GadgetDataServlet extends HttpServlet {
+public class GadgetDataServlet extends InjectedServlet {
   private static final Logger logger
       = Logger.getLogger("org.apache.shindig.social");
 
@@ -62,10 +65,17 @@
   private static final List<GadgetDataHandler> handlers
       = new ArrayList<GadgetDataHandler>();
 
+
+  private GadgetTokenDecoder gadgetTokenDecoder;
+
+  @Inject
+  public void setGadgetTokenDecoder(GadgetTokenDecoder gadgetTokenDecoder) {
+   this.gadgetTokenDecoder = gadgetTokenDecoder;
+  }
+
   @Override
   public void init(ServletConfig config) throws ServletException {
     super.init(config);
-    servletState = CrossServletState.get(config);
 
     String handlerNames = config.getInitParameter("handlers");
     if (handlerNames == null) {
@@ -74,7 +84,8 @@
     } else {
       for (String handlerName : handlerNames.split(",")) {
         try {
-          GadgetDataHandler handler = (GadgetDataHandler) (Class.forName(handlerName)).newInstance();
+          GadgetDataHandler handler
+              = (GadgetDataHandler) (Class.forName(handlerName)).newInstance();
           handlers.add(handler);
         } catch (Exception ex) {
           throw new ServletException(ex);
@@ -83,8 +94,6 @@
     }
   }
 
-  private CrossServletState servletState;
-
   @Override
   protected void doPost(HttpServletRequest req, HttpServletResponse resp)
       throws IOException {
@@ -112,7 +121,7 @@
     if (token == null || token.trim().length() == 0) {
       throw new GadgetException(GadgetException.Code.INVALID_GADGET_TOKEN);
     }
-    GadgetToken securityToken = servletState.getGadgetSigner().createToken(token);
+    GadgetToken securityToken = gadgetTokenDecoder.createToken(token);
 
     // TODO: Improve json input handling. The json request should get auto
     // translated into objects

Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/opensocial/OpenSocialDataHandler.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/opensocial/OpenSocialDataHandler.java?rev=644123&r1=644122&r2=644123&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/opensocial/OpenSocialDataHandler.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/opensocial/OpenSocialDataHandler.java Wed Apr  2 17:40:05 2008
@@ -17,34 +17,26 @@
  */
 package org.apache.shindig.social.opensocial;
 
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.JSONArray;
-
-import org.apache.shindig.gadgets.GadgetToken;
-
-import org.apache.shindig.social.samplecontainer.BasicPeopleService;
-import org.apache.shindig.social.samplecontainer.BasicDataService;
-import org.apache.shindig.social.samplecontainer.BasicActivitiesService;
-import org.apache.shindig.social.opensocial.PeopleService;
-import org.apache.shindig.social.opensocial.DataService;
-import org.apache.shindig.social.opensocial.model.IdSpec;
-import org.apache.shindig.social.opensocial.model.Activity;
-import org.apache.shindig.social.ResponseError;
-import org.apache.shindig.social.RequestItem;
 import org.apache.shindig.social.GadgetDataHandler;
+import org.apache.shindig.social.RequestItem;
+import org.apache.shindig.social.ResponseError;
 import org.apache.shindig.social.ResponseItem;
+import org.apache.shindig.social.opensocial.model.Activity;
+import org.apache.shindig.social.opensocial.model.IdSpec;
+import org.apache.shindig.social.samplecontainer.BasicActivitiesService;
+import org.apache.shindig.social.samplecontainer.BasicDataService;
+import org.apache.shindig.social.samplecontainer.BasicPeopleService;
 
-import java.util.logging.Logger;
-import java.util.logging.Level;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-import java.util.ArrayList;
-
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 /**
  * Servlet for serving the data required for opensocial.

Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/samplecontainer/XmlStateFileFetcher.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/samplecontainer/XmlStateFileFetcher.java?rev=644123&r1=644122&r2=644123&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/samplecontainer/XmlStateFileFetcher.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/social/samplecontainer/XmlStateFileFetcher.java Wed Apr  2 17:40:05 2008
@@ -1,15 +1,17 @@
 package org.apache.shindig.social.samplecontainer;
 
 import org.apache.shindig.gadgets.BasicRemoteContentFetcher;
+import org.apache.shindig.gadgets.GadgetException;
 import org.apache.shindig.gadgets.RemoteContent;
 import org.apache.shindig.gadgets.RemoteContentFetcher;
 import org.apache.shindig.gadgets.RemoteContentRequest;
 import org.apache.shindig.social.opensocial.model.Activity;
+import org.apache.shindig.social.opensocial.model.Enum;
 import org.apache.shindig.social.opensocial.model.MediaItem;
 import org.apache.shindig.social.opensocial.model.Name;
 import org.apache.shindig.social.opensocial.model.Person;
 import org.apache.shindig.social.opensocial.model.Phone;
-import org.apache.shindig.social.opensocial.model.Enum;
+
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
@@ -18,8 +20,6 @@
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
 import java.io.IOException;
 import java.io.StringReader;
 import java.net.URI;
@@ -29,6 +29,9 @@
 import java.util.List;
 import java.util.Map;
 
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
 /**
  * @author Cassandra Doll <do...@google.com>
  */
@@ -102,7 +105,12 @@
     // TODO: Eventually get the fetcher and processing options from a
     // config file, just like the GadgetServer
     RemoteContentFetcher fetcher = new BasicRemoteContentFetcher(1024 * 1024);
-    RemoteContent xml = fetcher.fetch(new RemoteContentRequest(stateFile));
+    RemoteContent xml = null;
+    try {
+      xml = fetcher.fetch(new RemoteContentRequest(stateFile));
+    } catch (GadgetException e) {
+      throw new RuntimeException(e);
+    }
 
     InputSource is = new InputSource(new StringReader(
         xml.getResponseAsString()));

Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/util/BlobCrypter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/util/BlobCrypter.java?rev=644123&r1=644122&r2=644123&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/util/BlobCrypter.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/util/BlobCrypter.java Wed Apr  2 17:40:05 2008
@@ -22,16 +22,18 @@
 import org.apache.commons.codec.digest.DigestUtils;
 
 import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
 import java.net.URLEncoder;
 import java.security.GeneralSecurityException;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
 
 /**
  * Utility class for managing signed, encrypted, and time stamped blobs.
  * Blobs are made up of name/value pairs.  Time stamps are automatically
  * included under BlobCrypter.TIMESTAMP_KEY.
+ * 
+ * Thread safe.
  */
 public class BlobCrypter {
 
@@ -174,8 +176,8 @@
     String[] items = base.split("[&=]");
     Map<String, String> map = new HashMap<String, String>();
     for (int i=0; i < items.length; ) {
-      String key = items[i++];
-      String val = items[i++];
+      String key = URLDecoder.decode(items[i++], UTF8);
+      String val = URLDecoder.decode(items[i++], UTF8);
       map.put(key, val);
     }
     return map;

Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/util/ResourceLoader.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/util/ResourceLoader.java?rev=644123&r1=644122&r2=644123&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/util/ResourceLoader.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/util/ResourceLoader.java Wed Apr  2 17:40:05 2008
@@ -31,21 +31,45 @@
 public class ResourceLoader {
 
   /**
-   * Reads the contents of a resource as a string.
+   * Opens a given path as either a resource or a file, depending on the path
+   * name.
    *
+   * If path starts with res://, we interpret it as a resource.
+   * Otherwise we attempt to load it as a file.
+   * @param path
+   * @return The opened input stream
+   */
+  public static InputStream open(String path) throws IOException {
+    if (path.startsWith("res://")) {
+      return openResource(path.substring(6));
+    }
+    File file = new File(path);
+    return new FileInputStream(file);
+  }
+
+  /**
    * @param resource
-   * @return Contents of the resource.
-   * @throws IOException
+   * @return An input stream for the given named resource
+   * @throws FileNotFoundException
    */
-  public static String getContent(String resource)
-      throws IOException, FileNotFoundException {
+  public static InputStream openResource(String resource) throws IOException {
     ClassLoader cl = ResourceLoader.class.getClassLoader();
     InputStream is = cl.getResourceAsStream(resource.trim());
     if (is == null) {
       throw new FileNotFoundException("Can not locate resource: " + resource);
     }
+    return is;
+  }
 
-    return InputStreamConsumer.readToString(is);
+  /**
+   * Reads the contents of a resource as a string.
+   *
+   * @param resource
+   * @return Contents of the resource.
+   * @throws IOException
+   */
+  public static String getContent(String resource) throws IOException {
+    return InputStreamConsumer.readToString(openResource(resource));
   }
 
   /**

Modified: incubator/shindig/trunk/java/gadgets/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/webapp/WEB-INF/web.xml?rev=644123&r1=644122&r2=644123&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/webapp/WEB-INF/web.xml (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/webapp/WEB-INF/web.xml Wed Apr  2 17:40:05 2008
@@ -23,18 +23,15 @@
 
 <web-app>
   <!-- configuration -->
+  <!-- If you have your own Guice module(s), put them here as a colon-separated list. -->
   <context-param>
-    <param-name>features</param-name>
-    <param-value>res://features/features.txt</param-value>
-  </context-param>
-  <context-param>
-    <param-name>syndicators</param-name>
-    <param-value>res://syndicators/default/syndicator.js</param-value>
-  </context-param>
-  <context-param>
-    <param-name>servlet-data-class</param-name>
-    <param-value>org.apache.shindig.gadgets.http.DefaultCrossServletState</param-value>
+    <param-name>guice-modules</param-name>
+    <param-value>org.apache.shindig.gadgets.http.HttpGuiceModule</param-value>
   </context-param>
+
+  <listener>
+    <listener-class>org.apache.shindig.gadgets.http.GuiceServletContextListener</listener-class>
+  </listener>
 
   <!-- Render a Gadget -->
   <servlet>

Modified: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/EasyMockTestCase.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/EasyMockTestCase.java?rev=644123&r1=644122&r2=644123&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/EasyMockTestCase.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/EasyMockTestCase.java Wed Apr  2 17:40:05 2008
@@ -17,7 +17,7 @@
  */
 package org.apache.shindig.gadgets;
 
-import org.easymock.EasyMock;
+import org.easymock.classextension.EasyMock;
 
 import junit.framework.TestCase;
 
@@ -52,11 +52,11 @@
    * list of all mocks, and returns it.
    *
    * @param clazz Class to be mocked.
-   * @param nice whether or not to make a nice mock (non-strict).
+   * @param strict whether or not to make a strict mock
    * @return A mock instance of the given type.
    **/
-  protected <T> T mock(Class<T> clazz, boolean nice) {
-    T m = nice ? EasyMock.createNiceMock(clazz) : EasyMock.createMock(clazz);
+  protected <T> T mock(Class<T> clazz, boolean strict) {
+    T m = strict ? EasyMock.createMock(clazz) : EasyMock.createNiceMock(clazz);
     mocks.add(m);
     return m;
   }

Modified: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetServerTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetServerTest.java?rev=644123&r1=644122&r2=644123&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetServerTest.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetServerTest.java Wed Apr  2 17:40:05 2008
@@ -21,7 +21,6 @@
 import static org.easymock.EasyMock.expect;
 
 import org.apache.shindig.gadgets.spec.GadgetSpec;
-import org.apache.shindig.gadgets.spec.MessageBundle;
 
 import java.net.URI;
 import java.util.HashMap;
@@ -30,7 +29,11 @@
 public class GadgetServerTest extends GadgetTestFixture {
 
   private final static URI SPEC_URL = URI.create("http://example.org/g.xml");
+  private final static RemoteContentRequest SPEC_REQUEST
+      = new RemoteContentRequest(SPEC_URL);
   private final static URI BUNDLE_URL = URI.create("http://example.org/m.xml");
+  private final static RemoteContentRequest BUNDLE_REQUEST
+      = new RemoteContentRequest(BUNDLE_URL);
   private final static GadgetContext BASIC_CONTEXT = new GadgetContext() {
     @Override
     public URI getUrl() {
@@ -49,14 +52,16 @@
        "</messagebundle>";
 
   public void testGadgetSpecLookup() throws Exception {
-    GadgetSpec spec = new GadgetSpec(SPEC_URL, BASIC_SPEC_XML);
     RemoteContentRequest req = new RemoteContentRequest(SPEC_URL);
+    RemoteContent resp = new RemoteContent(BASIC_SPEC_XML);
 
-    expect(specFetcher.fetch(eq(SPEC_URL), eq(false))).andReturn(spec);
+    expect(fetcher.fetch(req)).andReturn(resp);
     replay();
 
     Gadget gadget = gadgetServer.processGadget(BASIC_CONTEXT);
     verify();
+    assertEquals("GadgetServerTest",
+        gadget.getSpec().getModulePrefs().getTitle());
   }
 
   public void testSubstitutionsDone() throws Exception {
@@ -83,11 +88,11 @@
       }
     };
 
-    GadgetSpec spec = new GadgetSpec(SPEC_URL, gadgetXml);
-    MessageBundle bundle = new MessageBundle(BASIC_BUNDLE_XML);
+    RemoteContent spec = new RemoteContent(gadgetXml);
+    RemoteContent bundle = new RemoteContent(BASIC_BUNDLE_XML);
 
-    expect(specFetcher.fetch(eq(SPEC_URL), eq(false))).andReturn(spec);
-    expect(bundleFetcher.fetch(eq(BUNDLE_URL), eq(false))).andReturn(bundle);
+    expect(fetcher.fetch(SPEC_REQUEST)).andReturn(spec);
+    expect(fetcher.fetch(BUNDLE_REQUEST)).andReturn(bundle);
     replay();
 
     Gadget gadget = gadgetServer.processGadget(context);
@@ -98,6 +103,31 @@
     assertEquals("TITLE", gadget.getSpec().getModulePrefs().getTitle());
     assertEquals("BODY",
         gadget.getSpec().getView(GadgetSpec.DEFAULT_VIEW).getContent());
+  }
+
+  public void testPreloadsFetched() throws Exception {
+    String preloadUrl = "http://example.org/preload.txt";
+    String preloadData = "Preload Data";
+    RemoteContentRequest preloadRequest
+        = new RemoteContentRequest(URI.create(preloadUrl));
+
+    String gadgetXml
+        = "<Module>" +
+          "  <ModulePrefs title=\"foo\">" +
+          "    <Preload href=\"" + preloadUrl + "\"/>" +
+          "  </ModulePrefs>" +
+          "  <Content type=\"html\">dummy</Content>" +
+          "</Module>";
+    expect(fetcher.fetch(SPEC_REQUEST))
+         .andReturn(new RemoteContent(gadgetXml));
+    expect(fetcher.fetch(preloadRequest))
+        .andReturn(new RemoteContent(preloadData));
+    replay();
+
+    Gadget gadget = gadgetServer.processGadget(BASIC_CONTEXT);
+
+    assertEquals(preloadData, gadget.getPreloadMap().values().iterator().next()
+                                    .get().getResponseAsString());
   }
 
   public void testBlacklistedGadget() throws Exception {

Modified: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java?rev=644123&r1=644122&r2=644123&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java Wed Apr  2 17:40:05 2008
@@ -19,115 +19,27 @@
 
 package org.apache.shindig.gadgets;
 
+import java.util.concurrent.Executor;
 
-import org.apache.shindig.gadgets.http.CrossServletState;
-import org.apache.shindig.gadgets.http.ProxyHandler;
-import org.apache.shindig.gadgets.spec.GadgetSpec;
-import org.apache.shindig.gadgets.spec.MessageBundle;
-import org.apache.shindig.util.BlobCrypterException;
-
-import java.util.Set;
-import java.util.concurrent.Executors;
-
-import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 public class GadgetTestFixture extends EasyMockTestCase {
-  public final HttpServletRequest request = mock(HttpServletRequest.class, true);
-  public final HttpServletResponse response = mock(HttpServletResponse.class, true);
+  public final HttpServletRequest request = mock(HttpServletRequest.class);
+  public final HttpServletResponse response = mock(HttpServletResponse.class);
   public final GadgetServer gadgetServer;
-  public final ProxyHandler proxyHandler;
-  public final RemoteContentFetcher fetcher = mock(RemoteContentFetcher.class, true);
-  @SuppressWarnings(value="unchecked")
-  public final DataFetcher<GadgetSpec> specFetcher = mock(DataFetcher.class, true);
-  @SuppressWarnings(value="unchecked")
-  public final DataFetcher<MessageBundle> bundleFetcher
-      = mock(DataFetcher.class);
-  public final GadgetBlacklist blacklist = mock(GadgetBlacklist.class, true);
+  public final RemoteContentFetcher fetcher = mock(RemoteContentFetcher.class);
+  public final GadgetBlacklist blacklist = mock(GadgetBlacklist.class);
   public GadgetFeatureRegistry registry;
   public SyndicatorConfig syndicatorConfig;
-  public final CrossServletState state = new CrossServletState() {
-    @Override
-    public GadgetServer getGadgetServer() {
-      return gadgetServer;
-    }
-
-    @Override
-    public GadgetSigner getGadgetSigner() {
-      return new GadgetSigner() {
-        public GadgetToken createToken(String tokenString)
-            throws GadgetException {
-          try {
-            return new BasicGadgetToken("owner", "viewer", "app", "domain");
-          } catch (BlobCrypterException e) {
-            throw new GadgetException(GadgetException.Code.INVALID_GADGET_TOKEN, e);
-          }
-        }
-      };
-    }
-
-    @Override
-    public String getJsUrl(Set<String> libs, GadgetContext context) {
-      StringBuilder bs = new StringBuilder();
-      boolean first = false;
-      for (String lib : libs) {
-        if (!first) {
-          first = true;
-        } else {
-          bs.append(':');
-        }
-        bs.append(lib);
-      }
-      return bs.toString();
-    }
-
-    @Override
-    public String getIframeUrl(Gadget gadget) {
-      return "";
-    }
-
-    @Override
-    public void init(ServletContext config) {
-
-    }
-
-    @Override
-    public RequestSigner makeOAuthRequestSigner(GadgetToken token) {
-      return null;
-    }
-
-    @Override
-    public RequestSigner makeSignedFetchRequestSigner(GadgetToken token) {
-      // Real implementations should use their own key, probably pulled from
-      // disk rather than hardcoded in the source.
-      final String PRIVATE_KEY_TEXT =
-        "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALRiMLAh9iimur8V" +
-        "A7qVvdqxevEuUkW4K+2KdMXmnQbG9Aa7k7eBjK1S+0LYmVjPKlJGNXHDGuy5Fw/d" +
-        "7rjVJ0BLB+ubPK8iA/Tw3hLQgXMRRGRXXCn8ikfuQfjUS1uZSatdLB81mydBETlJ" +
-        "hI6GH4twrbDJCR2Bwy/XWXgqgGRzAgMBAAECgYBYWVtleUzavkbrPjy0T5FMou8H" +
-        "X9u2AC2ry8vD/l7cqedtwMPp9k7TubgNFo+NGvKsl2ynyprOZR1xjQ7WgrgVB+mm" +
-        "uScOM/5HVceFuGRDhYTCObE+y1kxRloNYXnx3ei1zbeYLPCHdhxRYW7T0qcynNmw" +
-        "rn05/KO2RLjgQNalsQJBANeA3Q4Nugqy4QBUCEC09SqylT2K9FrrItqL2QKc9v0Z" +
-        "zO2uwllCbg0dwpVuYPYXYvikNHHg+aCWF+VXsb9rpPsCQQDWR9TT4ORdzoj+Nccn" +
-        "qkMsDmzt0EfNaAOwHOmVJ2RVBspPcxt5iN4HI7HNeG6U5YsFBb+/GZbgfBT3kpNG" +
-        "WPTpAkBI+gFhjfJvRw38n3g/+UeAkwMI2TJQS4n8+hid0uus3/zOjDySH3XHCUno" +
-        "cn1xOJAyZODBo47E+67R4jV1/gzbAkEAklJaspRPXP877NssM5nAZMU0/O/NGCZ+" +
-        "3jPgDUno6WbJn5cqm8MqWhW1xGkImgRk+fkDBquiq4gPiT898jusgQJAd5Zrr6Q8" +
-        "AO/0isr/3aa6O6NLQxISLKcPDk2NOccAfS/xOtfOz4sJYM3+Bs4Io9+dZGSDCA54" +
-        "Lw03eHTNQghS0A==";
-      final String PRIVATE_KEY_NAME = "shindig-insecure-key";
-      return new SignedFetchRequestSigner(token, PRIVATE_KEY_NAME,
-          PRIVATE_KEY_TEXT);
+  public final Executor executor = new Executor() {
+    public void execute(Runnable r) {
+      r.run();
     }
   };
 
+
   public GadgetTestFixture() {
-    GadgetServerConfig config = new GadgetServerConfig();
-    config.setExecutor(Executors.newSingleThreadExecutor());
-    config.setGadgetSpecFetcher(specFetcher);
-    config.setMessageBundleFetcher(bundleFetcher);
-    config.setContentFetcher(fetcher);
     try {
       registry = new GadgetFeatureRegistry(null, fetcher);
     } catch (Exception e) {
@@ -142,10 +54,7 @@
       fail("Failed to create syndicator config");
     }
 
-    config.setSyndicatorConfig(syndicatorConfig);
-    config.setFeatureRegistry(registry);
-    config.setGadgetBlacklist(blacklist);
-    gadgetServer = new GadgetServer(config);
-    proxyHandler = new ProxyHandler(fetcher);
+    gadgetServer = new GadgetServer(executor, registry, blacklist, fetcher,
+        fetcher, fetcher);
   }
 }

Added: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/InterceptingContentFetcher.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/InterceptingContentFetcher.java?rev=644123&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/InterceptingContentFetcher.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/InterceptingContentFetcher.java Wed Apr  2 17:40:05 2008
@@ -0,0 +1,34 @@
+/*
+ * 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 org.apache.shindig.gadgets;
+
+/**
+ * Test utility to intercept remote content requests for inspection.
+ */
+public class InterceptingContentFetcher extends RemoteContentFetcher {
+
+  protected InterceptingContentFetcher() {
+    super(null);
+  }
+
+  public RemoteContentRequest interceptedRequest;
+
+  @Override
+  public RemoteContent fetch(RemoteContentRequest request) {
+    interceptedRequest = request;
+    return null;
+  }
+
+}

Modified: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/JsLibraryTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/JsLibraryTest.java?rev=644123&r1=644122&r2=644123&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/JsLibraryTest.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/JsLibraryTest.java Wed Apr  2 17:40:05 2008
@@ -34,7 +34,7 @@
         "};";
   private final static String URL_JS = "while(true){alert('hello');}";
 
-  public void testInline() {
+  public void testInline() throws GadgetException {
     JsLibrary lib
         = JsLibrary.create(JsLibrary.Type.INLINE, INLINE_JS, null, null);
     assertEquals(JsLibrary.Type.INLINE, lib.getType());

Added: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/SigningFetcherTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/SigningFetcherTest.java?rev=644123&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/SigningFetcherTest.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/SigningFetcherTest.java Wed Apr  2 17:40:05 2008
@@ -0,0 +1,268 @@
+/*
+ * 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 org.apache.shindig.gadgets;
+
+import net.oauth.OAuth;
+import net.oauth.OAuthAccessor;
+import net.oauth.OAuthConsumer;
+import net.oauth.OAuthMessage;
+import net.oauth.OAuth.Parameter;
+import net.oauth.signature.RSA_SHA1;
+
+import junit.framework.TestCase;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests the signed fetch code.
+ */
+public class SigningFetcherTest extends TestCase {
+  private static final String PRIVATE_KEY_TEXT =
+    "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALRiMLAh9iimur8V" +
+    "A7qVvdqxevEuUkW4K+2KdMXmnQbG9Aa7k7eBjK1S+0LYmVjPKlJGNXHDGuy5Fw/d" +
+    "7rjVJ0BLB+ubPK8iA/Tw3hLQgXMRRGRXXCn8ikfuQfjUS1uZSatdLB81mydBETlJ" +
+    "hI6GH4twrbDJCR2Bwy/XWXgqgGRzAgMBAAECgYBYWVtleUzavkbrPjy0T5FMou8H" +
+    "X9u2AC2ry8vD/l7cqedtwMPp9k7TubgNFo+NGvKsl2ynyprOZR1xjQ7WgrgVB+mm" +
+    "uScOM/5HVceFuGRDhYTCObE+y1kxRloNYXnx3ei1zbeYLPCHdhxRYW7T0qcynNmw" +
+    "rn05/KO2RLjgQNalsQJBANeA3Q4Nugqy4QBUCEC09SqylT2K9FrrItqL2QKc9v0Z" +
+    "zO2uwllCbg0dwpVuYPYXYvikNHHg+aCWF+VXsb9rpPsCQQDWR9TT4ORdzoj+Nccn" +
+    "qkMsDmzt0EfNaAOwHOmVJ2RVBspPcxt5iN4HI7HNeG6U5YsFBb+/GZbgfBT3kpNG" +
+    "WPTpAkBI+gFhjfJvRw38n3g/+UeAkwMI2TJQS4n8+hid0uus3/zOjDySH3XHCUno" +
+    "cn1xOJAyZODBo47E+67R4jV1/gzbAkEAklJaspRPXP877NssM5nAZMU0/O/NGCZ+" +
+    "3jPgDUno6WbJn5cqm8MqWhW1xGkImgRk+fkDBquiq4gPiT898jusgQJAd5Zrr6Q8" +
+    "AO/0isr/3aa6O6NLQxISLKcPDk2NOccAfS/xOtfOz4sJYM3+Bs4Io9+dZGSDCA54" +
+    "Lw03eHTNQghS0A==";
+
+  private static final String CERTIFICATE_TEXT =
+    "-----BEGIN CERTIFICATE-----\n" +
+    "MIIBpjCCAQ+gAwIBAgIBATANBgkqhkiG9w0BAQUFADAZMRcwFQYDVQQDDA5UZXN0\n" +
+    "IFByaW5jaXBhbDAeFw03MDAxMDEwODAwMDBaFw0zODEyMzEwODAwMDBaMBkxFzAV\n" +
+    "BgNVBAMMDlRlc3QgUHJpbmNpcGFsMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n" +
+    "gQC0YjCwIfYoprq/FQO6lb3asXrxLlJFuCvtinTF5p0GxvQGu5O3gYytUvtC2JlY\n" +
+    "zypSRjVxwxrsuRcP3e641SdASwfrmzyvIgP08N4S0IFzEURkV1wp/IpH7kH41Etb\n" +
+    "mUmrXSwfNZsnQRE5SYSOhh+LcK2wyQkdgcMv11l4KoBkcwIDAQABMA0GCSqGSIb3\n" +
+    "DQEBBQUAA4GBAGZLPEuJ5SiJ2ryq+CmEGOXfvlTtEL2nuGtr9PewxkgnOjZpUy+d\n" +
+    "4TvuXJbNQc8f4AMWL/tO9w0Fk80rWKp9ea8/df4qMq5qlFWlx6yOLQxumNOmECKb\n" +
+    "WpkUQDIDJEoFUzKMVuJf4KO/FJ345+BNLGgbJ6WujreoM1X/gYfdnJ/J\n" +
+    "-----END CERTIFICATE-----";
+
+  private InterceptingContentFetcher interceptor;
+  private SigningFetcher signer;
+  private BasicGadgetToken authToken;
+  private OAuthAccessor accessor;
+
+  @Override
+  public void setUp() throws Exception {
+    interceptor = new InterceptingContentFetcher();
+    authToken = new BasicGadgetToken("o", "v", "a", "d");
+    signer = SigningFetcher.makeFromB64PrivateKey(
+        interceptor, authToken, "foo", PRIVATE_KEY_TEXT);
+    OAuthConsumer consumer = new OAuthConsumer(null, null, null, null);
+    consumer.setProperty(RSA_SHA1.X509_CERTIFICATE, CERTIFICATE_TEXT);
+    accessor = new OAuthAccessor(consumer);
+  }
+
+  private RemoteContentRequest makeContentRequest(String method, String url)
+      throws URISyntaxException {
+    return makeContentRequest(method, url, null);
+  }
+
+  private RemoteContentRequest makeContentRequest(String method, String url,
+      byte[] body) throws URISyntaxException {
+    return new RemoteContentRequest(method, new URI(url), null, body, null);
+  }
+
+  private RemoteContentRequest signAndInspect(RemoteContentRequest orig)
+      throws GadgetException {
+    signer.fetch(orig);
+    return interceptor.interceptedRequest;
+  }
+
+  public void testParametersSet() throws Exception {
+    RemoteContentRequest unsigned
+        = makeContentRequest("GET", "http://test", null);
+    RemoteContentRequest out = signAndInspect(unsigned);
+    List<OAuth.Parameter> queryParams
+        = OAuth.decodeForm(out.getUri().getRawQuery());
+    assertTrue(contains(queryParams, "opensocial_owner_id", "o"));
+    assertTrue(contains(queryParams, "opensocial_viewer_id", "v"));
+    assertTrue(contains(queryParams, "opensocial_app_id", "a"));
+    assertTrue(contains(queryParams, OAuth.OAUTH_CONSUMER_KEY, "d"));
+    assertTrue(contains(queryParams, "xoauth_signature_publickey", "foo"));
+  }
+
+  public void testTrickyParametersInQuery() throws Exception {
+    String tricky = "%6fpensocial_owner_id=gotcha";
+    RemoteContentRequest unsigned
+        = makeContentRequest("GET", "http://test?" + tricky, null);
+    RemoteContentRequest out = signAndInspect(unsigned);
+    assertFalse(out.getUri().getRawQuery().contains("gotcha"));
+    assertSignatureOK(out);
+  }
+
+  public void testTrickyParametersInBody() throws Exception {
+    String tricky = "%6fpensocial_owner_id=gotcha";
+    RemoteContentRequest unsigned
+        = makeContentRequest("POST", "http://test", tricky.getBytes());
+    RemoteContentRequest out = signAndInspect(unsigned);
+    assertSignatureInvalid(out);
+  }
+
+  public void testGetNoQuery() throws Exception {
+    RemoteContentRequest unsigned
+        = makeContentRequest("GET", "http://test", null);
+    RemoteContentRequest out = signAndInspect(unsigned);
+    assertSignatureOK(out);
+  }
+
+  public void testGetWithQuery() throws Exception {
+    RemoteContentRequest unsigned
+        = makeContentRequest("GET", "http://test?a=b", null);
+    RemoteContentRequest out = signAndInspect(unsigned);
+    List<OAuth.Parameter> queryParams
+        = OAuth.decodeForm(out.getUri().getRawQuery());
+    assertTrue(contains(queryParams, "a", "b"));
+    assertSignatureOK(out);
+  }
+
+
+  public void testGetWithQueryMultiParam() throws Exception {
+    RemoteContentRequest unsigned
+        = makeContentRequest("GET", "http://test?a=b&a=c");
+    RemoteContentRequest out = signAndInspect(unsigned);
+    List<OAuth.Parameter> queryParams
+        = OAuth.decodeForm(out.getUri().getRawQuery());
+    assertTrue(contains(queryParams, "a", "b"));
+    assertTrue(contains(queryParams, "a", "c"));
+    assertSignatureOK(out);
+  }
+
+  public void testPostNoQueryNoData() throws Exception {
+    RemoteContentRequest unsigned = makeContentRequest("GET", "http://test");
+    RemoteContentRequest out = signAndInspect(unsigned);
+    assertSignatureOK(out);
+  }
+
+  public void testPostWithQueryNoData() throws Exception {
+    RemoteContentRequest unsigned
+        = makeContentRequest("GET", "http://test?name=value");
+    RemoteContentRequest out = signAndInspect(unsigned);
+    List<OAuth.Parameter> queryParams
+        = OAuth.decodeForm(out.getUri().getRawQuery());
+    assertTrue(contains(queryParams, "name", "value"));
+    assertSignatureOK(out);
+  }
+
+  public void testPostNoQueryWithData() throws Exception {
+    RemoteContentRequest unsigned = makeContentRequest(
+        "POST", "http://test", "name=value".getBytes());
+    RemoteContentRequest out = signAndInspect(unsigned);
+    List<OAuth.Parameter> queryParams
+        = OAuth.decodeForm(out.getUri().getRawQuery());
+    assertFalse(contains(queryParams, "name", "value"));
+    assertSignatureOK(out);
+  }
+
+  public void testPostWithQueryWithData() throws Exception {
+    RemoteContentRequest unsigned = makeContentRequest(
+        "POST", "http://test?queryName=queryValue", "name=value".getBytes());
+    RemoteContentRequest out = signAndInspect(unsigned);
+    List<OAuth.Parameter> queryParams
+        = OAuth.decodeForm(out.getUri().getRawQuery());
+    assertTrue(contains(queryParams, "queryName", "queryValue"));
+    assertSignatureOK(out);
+  }
+
+  public void testStripOpenSocialParamsFromQuery() throws Exception {
+    RemoteContentRequest unsigned = makeContentRequest(
+        "POST", "http://test?opensocial_foo=bar");
+    RemoteContentRequest out = signAndInspect(unsigned);
+    List<OAuth.Parameter> queryParams
+        = OAuth.decodeForm(out.getUri().getRawQuery());
+    assertFalse(contains(queryParams, "opensocial_foo", "bar"));
+    assertSignatureOK(out);
+  }
+
+  public void testStripOAuthParamsFromQuery() throws Exception {
+    RemoteContentRequest unsigned = makeContentRequest(
+        "POST", "http://test?oauth_foo=bar", "name=value".getBytes());
+    RemoteContentRequest out = signAndInspect(unsigned);
+    List<OAuth.Parameter> queryParams
+        = OAuth.decodeForm(out.getUri().getRawQuery());
+    assertFalse(contains(queryParams, "oauth_foo", "bar"));
+    assertSignatureOK(out);
+  }
+
+  public void testStripOpenSocialParamsFromBody() throws Exception {
+    RemoteContentRequest unsigned = makeContentRequest(
+        "POST", "http://test", "opensocial_foo=bar".getBytes());
+    RemoteContentRequest out = signAndInspect(unsigned);
+    assertSignatureInvalid(out);
+  }
+
+  public void testStripOAuthParamsFromBody() throws Exception {
+    RemoteContentRequest unsigned = makeContentRequest(
+        "POST", "http://test", "oauth_foo=bar".getBytes());
+    RemoteContentRequest out = signAndInspect(unsigned);
+    assertSignatureInvalid(out);
+  }
+
+  private void assertSignatureOK(RemoteContentRequest req)
+  throws Exception {
+    URL url = req.getUri().toURL();
+    URL noQuery = new URL(url.getProtocol(), url.getHost(), url.getPort(),
+        url.getPath());
+    List<OAuth.Parameter> queryParams = OAuth.decodeForm(url.getQuery());
+    String body = req.getPostBodyAsString();
+    if (body.length() == 0) {
+      body = null;
+    }
+    List<OAuth.Parameter> postParams = OAuth.decodeForm(body);
+
+    ArrayList<OAuth.Parameter> msgParams = new ArrayList<OAuth.Parameter>();
+    msgParams.addAll(queryParams);
+    msgParams.addAll(postParams);
+
+    OAuthMessage message = new OAuthMessage(req.getMethod(), noQuery.toString(),
+        msgParams);
+
+    // Throws on failure
+    message.validateSignature(accessor);
+  }
+
+  private void assertSignatureInvalid(RemoteContentRequest req) {
+    try {
+      assertSignatureOK(req);
+      fail("Signature verification should have failed");
+    } catch (Exception e) {
+      // good
+    }
+  }
+
+  // Checks whether the given parameter list contains the specified
+  // key/value pair
+  private boolean contains(List<Parameter> params, String key, String value) {
+    for (Parameter p : params) {
+      if (p.getKey().equals(key) && p.getValue().equals(value)) {
+        return true;
+      }
+    }
+    return false;
+  }
+}

Modified: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/GadgetRendererTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/GadgetRendererTest.java?rev=644123&r1=644122&r2=644123&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/GadgetRendererTest.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/GadgetRendererTest.java Wed Apr  2 17:40:05 2008
@@ -1,128 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.apache.shindig.gadgets.http;
-
-import static org.easymock.EasyMock.eq;
-import static org.easymock.EasyMock.expect;
-
-import org.apache.shindig.gadgets.GadgetTestFixture;
-import org.apache.shindig.gadgets.SyndicatorConfig;
-import org.apache.shindig.gadgets.spec.GadgetSpec;
-
-import org.json.JSONArray;
-import org.json.JSONObject;
-
-import java.io.ByteArrayOutputStream;
-import java.io.PrintWriter;
-import java.net.URI;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Set;
-
-public class GadgetRendererTest extends GadgetTestFixture {
-
-  final static Enumeration<String> EMPTY_PARAMS = new Enumeration<String>() {
-    public boolean hasMoreElements() {
-      return false;
-    }
-    public String nextElement() {
-      return null;
-    }
-  };
-
-  final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-  final PrintWriter writer = new PrintWriter(baos);
-
-  final static URI SPEC_URL = URI.create("http://example.org/gadget.xml");
-  final static String CONTENT = "Hello, world!";
-  final static String ALT_CONTENT = "Goodbye, city.";
-  final static String SPEC_XML
-      = "<Module>" +
-        "<ModulePrefs title=\"hello\"/>" +
-        "<Content type=\"html\" quirks=\"false\">" + CONTENT + "</Content>" +
-        "<Content type=\"html\" view=\"quirks\" quirks=\"true\"/>" +
-        "<Content type=\"html\" view=\"ALIAS\">" + ALT_CONTENT + "</Content>" +
-        "</Module>";
-  final static String LIBS = "dummy:blah";
-
-  /**
-   * Performs boilerplate operations to get basic gadgets rendered
-   * @return Output of the rendering request
-   * @throws Exception
-   */
-  private String parseBasicGadget(String view) throws Exception {
-    GadgetSpec spec = new GadgetSpec(SPEC_URL, SPEC_XML);
-    expect(request.getParameter("url")).andReturn(SPEC_URL.toString());
-    expect(request.getParameter("libs")).andReturn(LIBS);
-    expect(request.getParameter("view")).andReturn(view);
-    expect(request.getParameterNames()).andReturn(EMPTY_PARAMS);
-    expect(specFetcher.fetch(eq(SPEC_URL), eq(false))).andReturn(spec);
-    expect(response.getWriter()).andReturn(writer);
-    replay();
-    GadgetRenderer renderer = new GadgetRenderer(request, response, state);
-    renderer.process();
-    verify();
-    writer.close();
-    return new String(baos.toByteArray(), "UTF-8");
-  }
-
-  public void testStandardsMode() throws Exception {
-    String content = parseBasicGadget(GadgetSpec.DEFAULT_VIEW);
-    assertTrue(-1 != content.indexOf(GadgetRenderer.STRICT_MODE_DOCTYPE));
-  }
-
-  public void testQuirksMode() throws Exception {
-    String content = parseBasicGadget("quirks");
-    assertTrue(-1 == content.indexOf(GadgetRenderer.STRICT_MODE_DOCTYPE));
-  }
-
-
-  public void testContentRendered() throws Exception {
-    String content = parseBasicGadget(GadgetSpec.DEFAULT_VIEW);
-    assertTrue(-1 != content.indexOf(CONTENT));
-  }
-
-  public void testForcedLibsIncluded() throws Exception {
-    String content = parseBasicGadget(GadgetSpec.DEFAULT_VIEW);
-    Set<String> libs = new HashSet<String>();
-    libs.addAll(Arrays.asList(LIBS.split(":")));
-    String libStr = state.getJsUrl(libs, null);
-    assertTrue(-1 != content.indexOf("<script src=\"" + libStr + "\">"));
-  }
-
-  public void testViewAliases() throws Exception {
-    JSONObject json = new JSONObject();
-    json.put("gadgets.syndicator",
-             new JSONArray().put(SyndicatorConfig.DEFAULT_SYNDICATOR));
-    JSONArray aliases = new JSONArray().put("ALIAS");
-    JSONObject dummy = new JSONObject().put("aliases", aliases);
-    JSONObject views = new JSONObject().put("dummy", dummy);
-    JSONObject features = new JSONObject().put("views", views);
-    json.put("gadgets.features", features);
-    syndicatorConfig.loadFromString(json.toString());
-
-    String content = parseBasicGadget("dummy");
-
-    assertTrue(-1 != content.indexOf(ALT_CONTENT));
-  }
-
-  // TODO: Lots of ugly tests on html content.
-}

Added: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/GadgetRenderingTaskTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/GadgetRenderingTaskTest.java?rev=644123&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/GadgetRenderingTaskTest.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/GadgetRenderingTaskTest.java Wed Apr  2 17:40:05 2008
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.shindig.gadgets.http;
+
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
+
+import org.apache.shindig.gadgets.GadgetContext;
+import org.apache.shindig.gadgets.RemoteContent;
+import org.apache.shindig.gadgets.RemoteContentRequest;
+import org.apache.shindig.gadgets.SyndicatorConfig;
+import org.apache.shindig.gadgets.spec.GadgetSpec;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.List;
+
+public class GadgetRenderingTaskTest extends HttpTestFixture {
+
+  final static Enumeration<String> EMPTY_PARAMS = new Enumeration<String>() {
+    public boolean hasMoreElements() {
+      return false;
+    }
+    public String nextElement() {
+      return null;
+    }
+  };
+
+  final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+  final PrintWriter writer = new PrintWriter(baos);
+
+  final static URI SPEC_URL = URI.create("http://example.org/gadget.xml");
+  final static RemoteContentRequest SPEC_REQUEST
+      = new RemoteContentRequest(SPEC_URL);
+  final static String CONTENT = "Hello, world!";
+  final static String ALT_CONTENT = "Goodbye, city.";
+  final static String SPEC_XML
+      = "<Module>" +
+        "<ModulePrefs title=\"hello\"/>" +
+        "<Content type=\"html\" quirks=\"false\">" + CONTENT + "</Content>" +
+        "<Content type=\"html\" view=\"quirks\" quirks=\"true\"/>" +
+        "<Content type=\"html\" view=\"ALIAS\">" + ALT_CONTENT + "</Content>" +
+        "</Module>";
+  final static String LIBS = "dummy:blah";
+
+  /**
+   * Performs boilerplate operations to get basic gadgets rendered
+   * @return Output of the rendering request
+   * @throws Exception
+   */
+  private String parseBasicGadget(String view) throws Exception {
+
+    expect(request.getParameter("url")).andReturn(SPEC_URL.toString());
+    expect(request.getParameter("libs")).andReturn(LIBS);
+    expect(request.getParameter("view")).andReturn(view);
+    expect(request.getParameterNames()).andReturn(EMPTY_PARAMS);
+    expect(fetcher.fetch(SPEC_REQUEST)).andReturn(new RemoteContent(SPEC_XML));
+    expect(response.getWriter()).andReturn(writer);
+    replay();
+    gadgetRenderer.render(request, response);
+    verify();
+    writer.close();
+    return new String(baos.toByteArray(), "UTF-8");
+  }
+
+  public void testStandardsMode() throws Exception {
+    String content = parseBasicGadget(GadgetSpec.DEFAULT_VIEW);
+    assertTrue(-1 != content.indexOf(GadgetRenderingTask.STRICT_MODE_DOCTYPE));
+  }
+
+  public void testQuirksMode() throws Exception {
+    String content = parseBasicGadget("quirks");
+    assertTrue(-1 == content.indexOf(GadgetRenderingTask.STRICT_MODE_DOCTYPE));
+  }
+
+
+  public void testContentRendered() throws Exception {
+    String content = parseBasicGadget(GadgetSpec.DEFAULT_VIEW);
+    assertTrue(-1 != content.indexOf(CONTENT));
+  }
+
+  @SuppressWarnings("unchecked")
+  public void testForcedLibsIncluded() throws Exception {
+    String jsLibs = "http://example.org/js/foo:bar.js";
+    List<String> libs = Arrays.asList(LIBS.split(":"));
+    expect(urlGenerator.getBundledJsUrl(isA(Collection.class),
+        isA(GadgetContext.class))).andReturn(jsLibs);
+    String content = parseBasicGadget(GadgetSpec.DEFAULT_VIEW);
+    assertTrue(-1 != content.indexOf("<script src=\"" + jsLibs + "\">"));
+  }
+
+  public void testViewAliases() throws Exception {
+    JSONObject json = new JSONObject();
+    json.put("gadgets.syndicator",
+             new JSONArray().put(SyndicatorConfig.DEFAULT_SYNDICATOR));
+    JSONArray aliases = new JSONArray().put("ALIAS");
+    JSONObject dummy = new JSONObject().put("aliases", aliases);
+    JSONObject views = new JSONObject().put("dummy", dummy);
+    JSONObject features = new JSONObject().put("views", views);
+    json.put("gadgets.features", features);
+    syndicatorConfig.loadFromString(json.toString());
+
+    String content = parseBasicGadget("dummy");
+
+    assertTrue(-1 != content.indexOf(ALT_CONTENT));
+  }
+
+  // TODO: Lots of ugly tests on html content.
+}

Added: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/HttpTestFixture.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/HttpTestFixture.java?rev=644123&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/HttpTestFixture.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/HttpTestFixture.java Wed Apr  2 17:40:05 2008
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.shindig.gadgets.http;
+
+import org.apache.shindig.gadgets.GadgetTestFixture;
+import org.apache.shindig.gadgets.GadgetTokenDecoder;
+import org.apache.shindig.gadgets.SigningFetcherFactory;
+
+
+public class HttpTestFixture extends GadgetTestFixture {
+  public final ProxyHandler proxyHandler;
+  public final GadgetRenderer gadgetRenderer;
+  public final JsonRpcHandler jsonRpcHandler;
+  public final SigningFetcherFactory signingFetcherFactory
+      = mock(SigningFetcherFactory.class);
+  public final UrlGenerator urlGenerator = mock(UrlGenerator.class);
+  public final GadgetTokenDecoder gadgetTokenDecoder
+      = mock(GadgetTokenDecoder.class);
+
+  public HttpTestFixture() {
+    super();
+    proxyHandler
+        = new ProxyHandler(fetcher, gadgetTokenDecoder, signingFetcherFactory);
+    gadgetRenderer = new GadgetRenderer(
+          gadgetServer, registry, syndicatorConfig, urlGenerator);
+    jsonRpcHandler = new JsonRpcHandler(executor, gadgetServer, urlGenerator);
+  }
+}

Added: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/JsonRpcHandlerTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/JsonRpcHandlerTest.java?rev=644123&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/JsonRpcHandlerTest.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/JsonRpcHandlerTest.java Wed Apr  2 17:40:05 2008
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.shindig.gadgets.http;
+
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
+
+import org.apache.shindig.gadgets.Gadget;
+import org.apache.shindig.gadgets.RemoteContent;
+import org.apache.shindig.gadgets.RemoteContentRequest;
+import org.apache.shindig.gadgets.spec.GadgetSpec;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.net.URI;
+import java.util.Collections;
+import java.util.Map;
+
+public class JsonRpcHandlerTest extends HttpTestFixture {
+  private static final URI SPEC_URL = URI.create("http://example.org/g.xml");
+  private static final RemoteContentRequest SPEC_REQUEST
+      = new RemoteContentRequest(SPEC_URL);
+  private static final URI SPEC_URL2 = URI.create("http://example.org/g2.xml");
+  private static final RemoteContentRequest SPEC_REQUEST2
+      = new RemoteContentRequest(SPEC_URL2);
+  private static final String SPEC_TITLE = "JSON-TEST";
+  private static final String SPEC_TITLE2 = "JSON-TEST2";
+  private static final String SPEC_XML
+      = "<Module>" +
+        "<ModulePrefs title=\"" + SPEC_TITLE + "\"/>" +
+        "<Content type=\"html\">Hello, world</Content>" +
+        "</Module>";
+  private static final String SPEC_XML2
+      = "<Module>" +
+        "<ModulePrefs title=\"" + SPEC_TITLE2 + "\"/>" +
+        "<Content type=\"html\">Hello, world</Content>" +
+        "</Module>";
+
+  private JSONObject createContext(String lang, String country)
+      throws JSONException {
+    return new JSONObject().put("language", lang).put("country", country);
+  }
+
+  private JSONObject createGadget(String url, int moduleId,
+      Map<String, String> prefs) throws JSONException {
+    return new JSONObject()
+        .put("url", url)
+        .put("moduleId", moduleId)
+        .put("prefs", prefs == null ? Collections.emptySet() : prefs);
+  }
+
+  public void testSimpleRequest() throws Exception {
+    JSONArray gadgets = new JSONArray()
+      .put(createGadget(SPEC_URL.toString(), 0, null));
+    JSONObject input = new JSONObject()
+        .put("context", createContext("en", "US"))
+        .put("gadgets", gadgets);
+
+    GadgetSpec spec = new GadgetSpec(SPEC_URL, SPEC_XML);
+
+    expect(fetcher.fetch(SPEC_REQUEST)).andReturn(new RemoteContent(SPEC_XML));
+    expect(urlGenerator.getIframeUrl(isA(Gadget.class)))
+        .andReturn(SPEC_URL.toString());
+
+    replay();
+    JSONObject response = jsonRpcHandler.process(input);
+    verify();
+
+    JSONArray outGadgets = response.getJSONArray("gadgets");
+    JSONObject gadget = outGadgets.getJSONObject(0);
+    assertEquals(SPEC_URL.toString(), gadget.getString("iframeUrl"));
+    assertEquals(SPEC_TITLE, gadget.getString("title"));
+    assertEquals(0, gadget.getInt("moduleId"));
+  }
+
+  public void testMultipleGadgets() throws Exception {
+    JSONArray gadgets = new JSONArray()
+     .put(createGadget(SPEC_URL.toString(), 0, null))
+     .put(createGadget(SPEC_URL2.toString(), 1, null));
+    JSONObject input = new JSONObject()
+        .put("context", createContext("en", "US"))
+        .put("gadgets", gadgets);
+
+    GadgetSpec spec = new GadgetSpec(SPEC_URL, SPEC_XML);
+    GadgetSpec spec2 = new GadgetSpec(SPEC_URL2, SPEC_XML2);
+
+    expect(fetcher.fetch(SPEC_REQUEST))
+        .andReturn(new RemoteContent(SPEC_XML));
+    expect(fetcher.fetch(SPEC_REQUEST2))
+        .andReturn(new RemoteContent(SPEC_XML2));
+
+    replay();
+    JSONObject response = jsonRpcHandler.process(input);
+    verify();
+
+    JSONArray outGadgets = response.getJSONArray("gadgets");
+    JSONObject gadget = outGadgets.getJSONObject(0);
+    if (gadget.getString("url").equals(SPEC_URL.toString())) {
+      assertEquals(SPEC_TITLE, gadget.getString("title"));
+      assertEquals(0, gadget.getInt("moduleId"));
+    } else {
+      assertEquals(SPEC_TITLE2, gadget.getString("title"));
+      assertEquals(1, gadget.getInt("moduleId"));
+    }
+  }
+}

Modified: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/JsonRpcRequestTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/JsonRpcRequestTest.java?rev=644123&r1=644122&r2=644123&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/JsonRpcRequestTest.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/JsonRpcRequestTest.java Wed Apr  2 17:40:05 2008
@@ -1,114 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.apache.shindig.gadgets.http;
-
-import static org.easymock.EasyMock.expect;
-
-import org.apache.shindig.gadgets.GadgetTestFixture;
-import org.apache.shindig.gadgets.spec.GadgetSpec;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.net.URI;
-import java.util.Collections;
-import java.util.Map;
-
-public class JsonRpcRequestTest extends GadgetTestFixture {
-  private static final URI SPEC_URL = URI.create("http://example.org/g.xml");
-  private static final URI SPEC_URL2 = URI.create("http://example.org/g2.xml");
-  private static final String SPEC_TITLE = "JSON-TEST";
-  private static final String SPEC_TITLE2 = "JSON-TEST2";
-  private static final String SPEC_XML
-      = "<Module>" +
-        "<ModulePrefs title=\"" + SPEC_TITLE + "\"/>" +
-        "<Content type=\"html\">Hello, world</Content>" +
-        "</Module>";
-  private static final String SPEC_XML2
-      = "<Module>" +
-        "<ModulePrefs title=\"" + SPEC_TITLE2 + "\"/>" +
-        "<Content type=\"html\">Hello, world</Content>" +
-        "</Module>";
-
-  private JSONObject createContext(String lang, String country)
-      throws JSONException {
-    return new JSONObject().put("language", lang).put("country", country);
-  }
-
-  private JSONObject createGadget(String url, int moduleId,
-      Map<String, String> prefs) throws JSONException {
-    return new JSONObject()
-        .put("url", url)
-        .put("moduleId", moduleId)
-        .put("prefs", prefs == null ? Collections.emptySet() : prefs);
-  }
-
-  public void testSimpleRequest() throws Exception {
-    JSONArray gadgets = new JSONArray()
-      .put(createGadget(SPEC_URL.toString(), 0, null));
-    JSONObject input = new JSONObject()
-        .put("context", createContext("en", "US"))
-        .put("gadgets", gadgets);
-
-    GadgetSpec spec = new GadgetSpec(SPEC_URL, SPEC_XML);
-
-    expect(specFetcher.fetch(SPEC_URL, false)).andReturn(spec);
-
-    replay();
-    JsonRpcRequest request = new JsonRpcRequest(input.toString());
-    JSONObject response = request.process(state);
-    verify();
-
-    JSONArray outGadgets = response.getJSONArray("gadgets");
-    JSONObject gadget = outGadgets.getJSONObject(0);
-    assertEquals(SPEC_TITLE, gadget.getString("title"));
-    assertEquals(0, gadget.getInt("moduleId"));
-  }
-
-  public void testMultipleGadgets() throws Exception {
-    JSONArray gadgets = new JSONArray()
-     .put(createGadget(SPEC_URL.toString(), 0, null))
-     .put(createGadget(SPEC_URL2.toString(), 1, null));
-    JSONObject input = new JSONObject()
-        .put("context", createContext("en", "US"))
-        .put("gadgets", gadgets);
-
-    GadgetSpec spec = new GadgetSpec(SPEC_URL, SPEC_XML);
-    GadgetSpec spec2 = new GadgetSpec(SPEC_URL2, SPEC_XML2);
-
-    expect(specFetcher.fetch(SPEC_URL, false)).andReturn(spec);
-    expect(specFetcher.fetch(SPEC_URL2, false)).andReturn(spec2);
-
-    replay();
-    JsonRpcRequest request = new JsonRpcRequest(input.toString());
-    JSONObject response = request.process(state);
-    verify();
-
-    JSONArray outGadgets = response.getJSONArray("gadgets");
-    JSONObject gadget = outGadgets.getJSONObject(0);
-    if (gadget.getString("url").equals(SPEC_URL.toString())) {
-      assertEquals(SPEC_TITLE, gadget.getString("title"));
-      assertEquals(0, gadget.getInt("moduleId"));
-    } else {
-      assertEquals(SPEC_TITLE2, gadget.getString("title"));
-      assertEquals(1, gadget.getInt("moduleId"));
-    }
-  }
-}

Modified: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/ProxyHandlerTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/ProxyHandlerTest.java?rev=644123&r1=644122&r2=644123&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/ProxyHandlerTest.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/ProxyHandlerTest.java Wed Apr  2 17:40:05 2008
@@ -19,35 +19,63 @@
 
 package org.apache.shindig.gadgets.http;
 
+import static org.easymock.EasyMock.eq;
 import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
 
-import java.io.ByteArrayOutputStream;
-import java.io.PrintWriter;
-import java.net.URI;
-
-import org.apache.shindig.gadgets.GadgetTestFixture;
+import org.apache.shindig.gadgets.GadgetException;
+import org.apache.shindig.gadgets.GadgetToken;
 import org.apache.shindig.gadgets.RemoteContent;
+import org.apache.shindig.gadgets.RemoteContentFetcher;
 import org.apache.shindig.gadgets.RemoteContentRequest;
-import org.easymock.EasyMock;
-import org.easymock.IArgumentMatcher;
+
 import org.json.JSONObject;
 
-public class ProxyHandlerTest extends GadgetTestFixture {
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+import java.net.URI;
+
+public class ProxyHandlerTest extends HttpTestFixture {
 
   private final static String URL_ONE = "http://www.example.com/test.html";
   private final static String DATA_ONE = "hello world";
 
+  private static final GadgetToken DUMMY_TOKEN = new GadgetToken() {
+    public String getOwnerId() {
+      return "owner";
+    }
+
+    public String getViewerId() {
+      return "viewer";
+    }
+
+    public String getAppId() {
+      return "app";
+    }
+
+    public String getDomain() {
+      return "domain";
+    }
+
+    public String toSerialForm() {
+      return "";
+    }
+  };
+
   final ByteArrayOutputStream baos = new ByteArrayOutputStream();
   final PrintWriter writer = new PrintWriter(baos);
 
-  private void expectGetAndReturnData(String url, byte[] data) throws Exception {
+
+  private void expectGetAndReturnData(String url, byte[] data)
+      throws Exception {
     RemoteContentRequest req = new RemoteContentRequest(
         "GET", new URI(url), null, null, new RemoteContentRequest.Options());
     RemoteContent resp = new RemoteContent(200, data, null);
     expect(fetcher.fetch(req)).andReturn(resp);
   }
 
-  private void expectPostAndReturnData(String url, byte[] body, byte[] data) throws Exception {
+  private void expectPostAndReturnData(String url, byte[] body, byte[] data)
+      throws Exception {
     RemoteContentRequest req = new RemoteContentRequest(
         "POST", new URI(url), null, body, new RemoteContentRequest.Options());
     RemoteContent resp = new RemoteContent(200, data, null);
@@ -63,7 +91,8 @@
     setupGenericRequestMock("GET", url);
   }
 
-  private void setupGenericRequestMock(String method, String url) throws Exception {
+  private void setupGenericRequestMock(String method, String url)
+      throws Exception {
     expect(request.getMethod()).andReturn("POST").atLeastOnce();
     expect(request.getParameter("httpMethod")).andReturn(method).atLeastOnce();
     expect(request.getParameter("url")).andReturn(url).atLeastOnce();
@@ -71,7 +100,8 @@
   }
 
   private JSONObject readJSONResponse(String body) throws Exception {
-    String json = body.substring("throw 1; < don't be evil' >".length(), body.length());
+    String json
+        = body.substring("throw 1; < don't be evil' >".length(), body.length());
     return new JSONObject(json);
   }
 
@@ -79,7 +109,7 @@
     setupGetRequestMock(URL_ONE);
     expectGetAndReturnData(URL_ONE, DATA_ONE.getBytes());
     replay();
-    proxyHandler.fetchJson(request, response, state);
+    proxyHandler.fetchJson(request, response);
     verify();
     writer.close();
     JSONObject json = readJSONResponse(baos.toString());
@@ -94,7 +124,7 @@
     setupGetRequestMock(origUrl);
     expectGetAndReturnData(cleanedUrl, DATA_ONE.getBytes());
     replay();
-    proxyHandler.fetchJson(request, response, state);
+    proxyHandler.fetchJson(request, response);
     verify();
     writer.close();
     JSONObject json = readJSONResponse(baos.toString());
@@ -107,7 +137,7 @@
     setupGetRequestMock(URL_ONE);
     expectGetAndReturnData(URL_ONE, "".getBytes());
     replay();
-    proxyHandler.fetchJson(request, response, state);
+    proxyHandler.fetchJson(request, response);
     verify();
     writer.close();
     JSONObject json = readJSONResponse(baos.toString());
@@ -121,7 +151,7 @@
     setupPostRequestMock(URL_ONE, body);
     expectPostAndReturnData(URL_ONE, body.getBytes(), DATA_ONE.getBytes());
     replay();
-    proxyHandler.fetchJson(request, response, state);
+    proxyHandler.fetchJson(request, response);
     verify();
     writer.close();
     JSONObject json = readJSONResponse(baos.toString());
@@ -131,44 +161,122 @@
   }
 
   public void testSignedGetRequest() throws Exception {
+    // Doesn't actually sign since it returns the standard fetcher.
+    // Signing tests are in SigningFetcherTest
     setupGetRequestMock(URL_ONE);
-    expect(request.getParameter("st")).andReturn("fake-token").atLeastOnce();
-    expect(request.getParameter("authz")).andReturn("signed").atLeastOnce();
+    expect(gadgetTokenDecoder.createToken("fake-token")).andReturn(DUMMY_TOKEN);
+    expect(request.getParameter(ProxyHandler.SECURITY_TOKEN_PARAM))
+        .andReturn("fake-token").atLeastOnce();
+    expect(request.getParameter(ProxyHandler.AUTHZ_PARAM))
+        .andReturn(ProxyHandler.AUTHZ_SIGNED).atLeastOnce();
     RemoteContent resp = new RemoteContent(200, DATA_ONE.getBytes(), null);
-    expect(fetcher.fetch(looksLikeSignedFetch(URL_ONE))).andReturn(resp);
+    expect(signingFetcherFactory.getSigningFetcher(
+        isA(RemoteContentFetcher.class), eq(DUMMY_TOKEN))).andReturn(fetcher);
+    expect(fetcher.fetch(isA(RemoteContentRequest.class))).andReturn(resp);
     replay();
-    proxyHandler.fetchJson(request, response, state);
+    proxyHandler.fetchJson(request, response);
     verify();
     writer.close();
   }
 
-  private RemoteContentRequest looksLikeSignedFetch(String url) {
-    EasyMock.reportMatcher(new SignedFetchArgumentMatcher(url));
-    return null;
+  public void testSignedPostRequest() throws Exception {
+    // Doesn't actually sign since it returns the standard fetcher.
+    // Signing tests are in SigningFetcherTest
+    String postBody = "foo=bar%20baz";
+    setupPostRequestMock(URL_ONE, postBody);
+    expect(gadgetTokenDecoder.createToken("fake-token")).andReturn(DUMMY_TOKEN);
+    expect(request.getParameter(ProxyHandler.SECURITY_TOKEN_PARAM))
+        .andReturn("fake-token").atLeastOnce();
+    expect(request.getParameter(ProxyHandler.AUTHZ_PARAM))
+        .andReturn(ProxyHandler.AUTHZ_SIGNED).atLeastOnce();
+    RemoteContent resp = new RemoteContent(200, DATA_ONE.getBytes(), null);
+    expect(signingFetcherFactory.getSigningFetcher(
+        isA(RemoteContentFetcher.class), eq(DUMMY_TOKEN))).andReturn(fetcher);
+    expect(fetcher.fetch(isA(RemoteContentRequest.class))).andReturn(resp);
+    replay();
+    proxyHandler.fetchJson(request, response);
+    verify();
+    writer.close();
   }
 
-  private class SignedFetchArgumentMatcher implements IArgumentMatcher {
-
-    private String expectedUrl;
-
-    public SignedFetchArgumentMatcher(String expectedUrl) {
-      this.expectedUrl = expectedUrl;
-    }
-
-    public void appendTo(StringBuffer sb) {
-      sb.append("SignedFetchArgumentMatcher(");
-      sb.append(expectedUrl);
-      sb.append(')');
-    }
-
-    public boolean matches(Object arg0) {
-      RemoteContentRequest request = (RemoteContentRequest)arg0;
-      String url = request.getUri().toASCIIString();
-      return (url.startsWith(expectedUrl) &&
-          url.contains("opensocial_owner_id") &&
-          url.contains("opensocial_viewer_id") &&
-          url.contains("opensocial_app_id"));
+  public void testInvalidSigningType() throws Exception {
+    setupGetRequestMock(URL_ONE);
+    expect(request.getParameter(ProxyHandler.SECURITY_TOKEN_PARAM))
+        .andReturn("fake-token").atLeastOnce();
+    expect(request.getParameter(ProxyHandler.AUTHZ_PARAM))
+        .andReturn("garbage").atLeastOnce();
+    replay();
+    try {
+      proxyHandler.fetchJson(request, response);
+      fail("proxyHandler accepted invalid authz type");
+    } catch (GadgetException e) {
+      assertEquals(GadgetException.Code.UNSUPPORTED_FEATURE, e.getCode());
     }
+  }
 
+  public void testValidateUrlNoPath() throws Exception {
+    URI url = proxyHandler.validateUrl("http://www.example.com");
+    assertEquals("http", url.getScheme());
+    assertEquals("www.example.com", url.getHost());
+    assertEquals(-1, url.getPort());
+    assertEquals("/", url.getPath());
+    assertNull(url.getQuery());
+    assertNull(url.getFragment());
+  }
+
+  public void testValidateUrlWithPath() throws Exception {
+    URI url = proxyHandler.validateUrl("http://www.example.com/foo");
+    assertEquals("http", url.getScheme());
+    assertEquals("www.example.com", url.getHost());
+    assertEquals(-1, url.getPort());
+    assertEquals("/foo", url.getPath());
+    assertNull(url.getQuery());
+    assertNull(url.getFragment());
+  }
+
+  public void testValidateUrlWithPort() throws Exception {
+    URI url = proxyHandler.validateUrl("http://www.example.com:8080/foo");
+    assertEquals("http", url.getScheme());
+    assertEquals("www.example.com", url.getHost());
+    assertEquals(8080, url.getPort());
+    assertEquals("/foo", url.getPath());
+    assertNull(url.getQuery());
+    assertNull(url.getFragment());
+  }
+
+  public void testValidateUrlWithEncodedPath() throws Exception {
+    URI url
+        = proxyHandler.validateUrl("http://www.example.com:8080/foo%20bar");
+    assertEquals("http", url.getScheme());
+    assertEquals("www.example.com", url.getHost());
+    assertEquals(8080, url.getPort());
+    assertEquals("/foo%20bar", url.getRawPath());
+    assertEquals("/foo bar", url.getPath());
+    assertNull(url.getQuery());
+    assertNull(url.getFragment());
+  }
+
+  public void testValidateUrlWithEncodedQuery() throws Exception {
+    URI url= proxyHandler.validateUrl(
+        "http://www.example.com:8080/foo?q=with%20space");
+    assertEquals("http", url.getScheme());
+    assertEquals("www.example.com", url.getHost());
+    assertEquals(8080, url.getPort());
+    assertEquals("/foo", url.getPath());
+    assertEquals("q=with%20space", url.getRawQuery());
+    assertEquals("q=with space", url.getQuery());
+    assertNull(url.getFragment());
+  }
+
+  public void testValidateUrlWithNoPathAndEncodedQuery() throws Exception {
+    URI url
+        = proxyHandler.validateUrl("http://www.example.com?q=with%20space");
+    assertEquals("http", url.getScheme());
+    assertEquals("www.example.com", url.getHost());
+    assertEquals(-1, url.getPort());
+    assertEquals("/", url.getPath());
+    assertEquals("q=with%20space", url.getRawQuery());
+    assertEquals("q=with space", url.getQuery());
+    assertNull(url.getFragment());
   }
-}
+}
\ No newline at end of file

Modified: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/ModulePrefsTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/ModulePrefsTest.java?rev=644123&r1=644122&r2=644123&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/ModulePrefsTest.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/ModulePrefsTest.java Wed Apr  2 17:40:05 2008
@@ -45,7 +45,7 @@
                  " category2=\"category2\">" +
                  "  <Require feature=\"require\"/>" +
                  "  <Optional feature=\"optional\"/>" +
-                 "  <Preload href=\"http://www.google.com\"/>" +
+                 "  <Preload href=\"http://example.org\"/>" +
                  "  <Icon/>" +
                  "  <Locale/>" +
                  "</ModulePrefs>";
@@ -64,7 +64,7 @@
     assertEquals("category2", prefs.getCategories().get(1));
     assertEquals(true, prefs.getFeatures().get("require").getRequired());
     assertEquals(false, prefs.getFeatures().get("optional").getRequired());
-    assertEquals("http://www.google.com",
+    assertEquals("http://example.org",
         prefs.getPreloads().get(0).getHref().toString());
     assertEquals(1, prefs.getIcons().size());
     assertEquals(1, prefs.getLocales().size());

Modified: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/util/BlobCrypterTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/util/BlobCrypterTest.java?rev=644123&r1=644122&r2=644123&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/util/BlobCrypterTest.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/util/BlobCrypterTest.java Wed Apr  2 17:40:05 2008
@@ -49,6 +49,8 @@
     checkString("ab");
     checkString("dfkljdasklsdfklasdjfklajsdfkljasdklfjasdkljfaskldjf");
     checkString(Crypto.getRandomString(500));
+    checkString("foo bar baz");
+    checkString("foo\nbar\nbaz");
   }
 
   private void checkString(String string) throws Exception {