You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by rb...@apache.org on 2011/10/02 21:44:15 UTC

svn commit: r1178236 [2/4] - in /shindig/trunk: config/ content/samplecontainer/examples/commoncontainer/ features/src/main/javascript/features/container.util/ features/src/main/javascript/features/container/ features/src/main/javascript/features/rpc/ ...

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/MakeRequestHandler.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/MakeRequestHandler.java?rev=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/MakeRequestHandler.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/MakeRequestHandler.java Sun Oct  2 19:44:13 2011
@@ -18,9 +18,13 @@
  */
 package org.apache.shindig.gadgets.servlet;
 
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import com.google.inject.Singleton;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.Collections;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.shindig.auth.AuthInfoUtil;
@@ -33,9 +37,9 @@ import org.apache.shindig.config.Contain
 import org.apache.shindig.gadgets.AuthType;
 import org.apache.shindig.gadgets.FeedProcessor;
 import org.apache.shindig.gadgets.FetchResponseUtils;
-import org.apache.shindig.gadgets.GadgetBlacklist;
 import org.apache.shindig.gadgets.GadgetException;
 import org.apache.shindig.gadgets.GadgetException.Code;
+import org.apache.shindig.gadgets.admin.GadgetAdminStore;
 import org.apache.shindig.gadgets.http.HttpRequest;
 import org.apache.shindig.gadgets.http.HttpResponse;
 import org.apache.shindig.gadgets.http.RequestPipeline;
@@ -47,13 +51,9 @@ import org.apache.shindig.gadgets.rewrit
 import org.apache.shindig.gadgets.uri.UriCommon;
 import org.apache.shindig.gadgets.uri.UriCommon.Param;
 
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.Collections;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
 
 /**
  * Handles gadgets.io.makeRequest requests.
@@ -77,18 +77,18 @@ public class MakeRequestHandler {
   private final RequestPipeline requestPipeline;
   private final ResponseRewriterRegistry contentRewriterRegistry;
   private final Provider<FeedProcessor> feedProcessorProvider;
-  private final GadgetBlacklist gadgetBlacklist;
+  private final GadgetAdminStore gadgetAdminStore;
 
   @Inject
   public MakeRequestHandler(RequestPipeline requestPipeline,
       @RewriterRegistry(rewriteFlow = RewriteFlow.DEFAULT)
       ResponseRewriterRegistry contentRewriterRegistry,
       Provider<FeedProcessor> feedProcessorProvider,
-      GadgetBlacklist gadgetBlacklist) {
+      GadgetAdminStore gadgetAdminStore) {
     this.requestPipeline = requestPipeline;
     this.contentRewriterRegistry = contentRewriterRegistry;
     this.feedProcessorProvider = feedProcessorProvider;
-    this.gadgetBlacklist = gadgetBlacklist;
+    this.gadgetAdminStore = gadgetAdminStore;
   }
 
   /**
@@ -97,12 +97,15 @@ public class MakeRequestHandler {
   public void fetch(HttpServletRequest request, HttpServletResponse response)
       throws GadgetException, IOException {
     HttpRequest rcr = buildHttpRequest(request);
+    String container = rcr.getContainer();
+    Uri gadget = rcr.getGadget();
 
-    if (rcr.getGadget() != null && gadgetBlacklist.isBlacklisted(rcr.getGadget())) {
-      throw new GadgetException(GadgetException.Code.BLACKLISTED_GADGET,
-          "The requested content is unavailable", HttpResponse.SC_FORBIDDEN);
+    if (gadget != null &&
+            !gadgetAdminStore.isWhitelisted(container, gadget.toString())) {
+      throw new GadgetException(GadgetException.Code.NON_WHITELISTED_GADGET,
+              "The requested content is unavailable", HttpResponse.SC_FORBIDDEN);
     }
-    
+
     // Serialize the response
     HttpResponse results = requestPipeline.execute(rcr);
 

Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyHandler.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyHandler.java?rev=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyHandler.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyHandler.java Sun Oct  2 19:44:13 2011
@@ -18,17 +18,16 @@
  */
 package org.apache.shindig.gadgets.servlet;
 
-import com.google.common.base.Strings;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import com.google.inject.name.Named;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.shindig.common.Nullable;
 import org.apache.shindig.common.uri.Uri;
-import org.apache.shindig.gadgets.GadgetBlacklist;
 import org.apache.shindig.gadgets.GadgetException;
+import org.apache.shindig.gadgets.admin.GadgetAdminStore;
 import org.apache.shindig.gadgets.http.HttpRequest;
 import org.apache.shindig.gadgets.http.HttpResponse;
 import org.apache.shindig.gadgets.http.HttpResponseBuilder;
@@ -41,10 +40,10 @@ import org.apache.shindig.gadgets.uri.Pr
 import org.apache.shindig.gadgets.uri.UriUtils;
 import org.apache.shindig.gadgets.uri.UriUtils.DisallowedHeaders;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
+import com.google.common.base.Strings;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.google.inject.name.Named;
 
 /**
  * Handles open proxy requests.
@@ -54,7 +53,7 @@ public class ProxyHandler {
   private final RequestPipeline requestPipeline;
   private final ResponseRewriterRegistry contentRewriterRegistry;
   protected final boolean remapInternalServerError;
-  private final GadgetBlacklist gadgetBlacklist;
+  private final GadgetAdminStore gadgetAdminStore;
   private final Integer longLivedRefreshSec;
   private static final String POST = "POST";
 
@@ -62,12 +61,12 @@ public class ProxyHandler {
   public ProxyHandler(RequestPipeline requestPipeline,
       @RewriterRegistry(rewriteFlow = RewriteFlow.DEFAULT) ResponseRewriterRegistry contentRewriterRegistry,
       @Named("shindig.proxy.remapInternalServerError") Boolean remapInternalServerError,
-      GadgetBlacklist gadgetBlacklist,
+      GadgetAdminStore gadgetAdminStore,
       @Named("org.apache.shindig.gadgets.servlet.longLivedRefreshSec") int longLivedRefreshSec) {
     this.requestPipeline = requestPipeline;
     this.contentRewriterRegistry = contentRewriterRegistry;
     this.remapInternalServerError = remapInternalServerError;
-    this.gadgetBlacklist = gadgetBlacklist;
+    this.gadgetAdminStore = gadgetAdminStore;
     this.longLivedRefreshSec = longLivedRefreshSec;
   }
 
@@ -102,8 +101,9 @@ public class ProxyHandler {
         "No url parameter in request", HttpResponse.SC_BAD_REQUEST);
     }
 
-    if (rcr.getGadget() != null && gadgetBlacklist.isBlacklisted(rcr.getGadget())) {
-      throw new GadgetException(GadgetException.Code.BLACKLISTED_GADGET,
+    if (rcr.getGadget() != null &&
+            !gadgetAdminStore.isWhitelisted(rcr.getContainer(), rcr.getGadget().toString())) {
+      throw new GadgetException(GadgetException.Code.NON_WHITELISTED_GADGET,
         "The requested content is unavailable", HttpResponse.SC_FORBIDDEN);
     }
 

Added: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/BasicGadgetAdminStoreTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/BasicGadgetAdminStoreTest.java?rev=1178236&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/BasicGadgetAdminStoreTest.java (added)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/BasicGadgetAdminStoreTest.java Sun Oct  2 19:44:13 2011
@@ -0,0 +1,462 @@
+/*
+ * 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.admin;
+
+import static org.easymock.EasyMock.eq;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.shindig.common.EasyMockTestCase;
+import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.config.BasicContainerConfig;
+import org.apache.shindig.config.ContainerConfig;
+import org.apache.shindig.gadgets.Gadget;
+import org.apache.shindig.gadgets.GadgetContext;
+import org.apache.shindig.gadgets.GadgetException;
+import org.apache.shindig.gadgets.admin.FeatureAdminData.Type;
+import org.apache.shindig.gadgets.features.FeatureRegistry;
+import org.apache.shindig.gadgets.features.FeatureRegistryProvider;
+import org.apache.shindig.gadgets.spec.Feature;
+import org.apache.shindig.gadgets.spec.GadgetSpec;
+import org.apache.shindig.gadgets.spec.ModulePrefs;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+/**
+ * @version $Id: $
+ */
+public class BasicGadgetAdminStoreTest extends EasyMockTestCase {
+
+  private static final String SAMPLE_STORE = "{" + "\"default\" : {" + "\"gadgets\" : {"
+          + "\"http://www.google.com/ig/modules/horoscope.xml\" : {"
+          + "\"features\" : [\"views\", \"tabs\", \"setprefs\", \"dynamic-height\", \"settitle\"],"
+          + "\"type\" : \"whitelist\"" + "},"
+          + "\"http://www.labpixies.com/campaigns/todo/todo.xml\" : {"
+          + "\"features\" : [\"setprefs\", \"dynamic-height\", \"views\"],"
+          + "\"type\" : \"blacklist\"" + "},"
+          + "\"http://foo.com/*\" : {"
+          + "\"features\" : []" + "},"
+          + "\"http://*\" : {"
+          + "\"features\" : []," + "\"type\" : \"whitelist\"" + "},"+ "}" + "}" + "}";
+
+  private static final String DEFAULT = "default";
+  private static final String HOROSCOPE = "http://www.google.com/ig/modules/horoscope.xml";
+  private static final String TODO = "http://www.labpixies.com/campaigns/todo/todo.xml";
+  private static final String TEST_GADGET = "http://www.example.com/gadget.xml";
+  private static final String FOO_GADGET = "http://foo.com/*";
+  private static final String HTTP_GADGET = "http://*";
+  private Set<String> HOROSCOPE_FEATURES = Sets.newHashSet("views", "tabs", "setprefs",
+          "dynamic-height", "settitle", "core");
+  private Set<String> TODO_FEATURES = Sets.newHashSet("views", "setprefs", "dynamic-height");
+  private Set<String> FOO_FEATURES = Sets.newHashSet("core");
+  private Set<String> HTTP_FEATURES = Sets.newHashSet("core");
+
+  private final FeatureRegistry mockRegistry = mock(FeatureRegistry.class);
+  private final Gadget mockGadget = mock(Gadget.class);
+  private final GadgetContext mockContext = mock(GadgetContext.class);
+  private final GadgetSpec mockSpec = mock(GadgetSpec.class);
+  private final ModulePrefs mockPrefs = mock(ModulePrefs.class);
+  private final ContainerConfig enabledConfig = new FakeContainerConfig(true, true);
+  private final ContainerConfig disabledConfig = new FakeContainerConfig(false, false);
+
+  private BasicGadgetAdminStore enabledStore;
+  private BasicGadgetAdminStore disabledStore;
+  private GadgetAdminData horoscopeAdminData;
+  private GadgetAdminData todoAdminData;
+  private GadgetAdminData fooAdminData;
+  private GadgetAdminData httpAdminData;
+  private ContainerAdminData defaultAdminData;
+  private FeatureRegistryProvider featureRegistryProvider;
+
+  @Before
+  public void setUp() throws Exception {
+    featureRegistryProvider = new FeatureRegistryProvider() {
+      @Override
+      public FeatureRegistry get(String repository) throws GadgetException {
+        return mockRegistry;
+      }
+    };
+    enabledStore = new BasicGadgetAdminStore(featureRegistryProvider, enabledConfig);
+    enabledStore.init(SAMPLE_STORE);
+
+    disabledStore = new BasicGadgetAdminStore(featureRegistryProvider, disabledConfig);
+
+    horoscopeAdminData = new GadgetAdminData(new FeatureAdminData(HOROSCOPE_FEATURES,
+            Type.WHITELIST));
+    todoAdminData = new GadgetAdminData(new FeatureAdminData(TODO_FEATURES,
+            Type.BLACKLIST));
+    fooAdminData = new GadgetAdminData(new FeatureAdminData(FOO_FEATURES,
+            Type.WHITELIST));
+    httpAdminData = new GadgetAdminData(new FeatureAdminData(HTTP_FEATURES,
+            Type.WHITELIST));
+
+    defaultAdminData = new ContainerAdminData();
+    defaultAdminData.addGadgetAdminData(TODO, todoAdminData);
+    defaultAdminData.addGadgetAdminData(HOROSCOPE, horoscopeAdminData);
+    defaultAdminData.addGadgetAdminData(FOO_GADGET, fooAdminData);
+    defaultAdminData.addGadgetAdminData(HTTP_GADGET, httpAdminData);
+
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    enabledStore = null;
+    horoscopeAdminData = null;
+    todoAdminData = null;
+    defaultAdminData = null;
+  }
+
+  private void mockGadget(List<Feature> allFeatures) {
+    mockGadget(allFeatures, DEFAULT, TEST_GADGET);
+  }
+
+  private void mockGadget(List<Feature> allFeatures, String container) {
+    mockGadget(allFeatures, container, TEST_GADGET);
+  }
+
+  private void mockGadget(List<Feature> allFeatures, String container, String gadgetUrl) {
+    mockGadgetContext(container);
+    mockGadgetSpec(allFeatures, gadgetUrl);
+    EasyMock.expect(mockGadget.getContext()).andReturn(mockContext).anyTimes();
+    EasyMock.expect(mockGadget.getSpec()).andReturn(mockSpec).anyTimes();
+  }
+
+  private void mockGadgetContext(String container) {
+    EasyMock.expect(mockContext.getContainer()).andReturn(container).anyTimes();
+  }
+
+  private void mockGadgetSpec(List<Feature> allFeatures, String gadgetUrl) {
+    mockModulePrefs(allFeatures);
+    EasyMock.expect(mockSpec.getUrl()).andReturn(Uri.parse(gadgetUrl)).anyTimes();
+    EasyMock.expect(mockSpec.getModulePrefs()).andReturn(mockPrefs).anyTimes();
+  }
+
+  private void mockModulePrefs(List<Feature> features) {
+    EasyMock.expect(mockPrefs.getAllFeatures()).andReturn(features).anyTimes();
+  }
+
+  private Feature createMockFeature(String name, boolean required) {
+    Feature feature = mock(Feature.class);
+    EasyMock.expect(feature.getName()).andReturn(name).anyTimes();
+    EasyMock.expect(feature.getRequired()).andReturn(required).anyTimes();
+    return feature;
+  }
+
+  private void mockRegistryForFeatureAdmin(Set<String> allowed, List<String> getFeaturesAllowed,
+          List<String> allGadgetFeatures, List<String> gadgetRequiredFeatureNames) {
+    EasyMock.expect(mockRegistry.getFeatures(eq(Sets.newHashSet(allowed))))
+            .andReturn(Lists.newArrayList(getFeaturesAllowed)).anyTimes();
+    EasyMock.expect(mockRegistry.getFeatures(eq(Lists.newArrayList("core"))))
+            .andReturn(Lists.newArrayList(allGadgetFeatures)).anyTimes();
+    EasyMock.expect(mockRegistry.getFeatures(eq(gadgetRequiredFeatureNames)))
+            .andReturn(allGadgetFeatures).anyTimes();
+  }
+
+  @Test
+  public void testGetGadgetAdminData() {
+    assertEquals(horoscopeAdminData, enabledStore.getGadgetAdminData(DEFAULT, HOROSCOPE));
+    assertEquals(todoAdminData, enabledStore.getGadgetAdminData(DEFAULT, TODO));
+    assertEquals(fooAdminData, enabledStore.getGadgetAdminData(DEFAULT, "http://foo.com/bar/gadget.xml"));
+    assertNull(enabledStore.getGadgetAdminData("my_container", HOROSCOPE));
+    assertEquals(httpAdminData, enabledStore.getGadgetAdminData(DEFAULT, "http://example.com/gadget2.xml"));
+  }
+
+  @Test
+  public void testSetGadgetAdminData() {
+    assertEquals(horoscopeAdminData, enabledStore.getGadgetAdminData(DEFAULT, HOROSCOPE));
+
+    horoscopeAdminData.getFeatureAdminData().addFeature("foo_feature");
+    enabledStore.setGadgetAdminData(DEFAULT, HOROSCOPE, horoscopeAdminData);
+    assertTrue(enabledStore.getGadgetAdminData(DEFAULT, HOROSCOPE).getFeatureAdminData()
+            .getFeatures().contains("foo_feature"));
+
+    assertEquals(httpAdminData, enabledStore.getGadgetAdminData(DEFAULT, "http://example.com/gadget2.xml"));
+    enabledStore.setGadgetAdminData(DEFAULT, "http://example.com/gadget2.xml", todoAdminData);
+    assertEquals(todoAdminData,
+            enabledStore.getGadgetAdminData(DEFAULT, "http://example.com/gadget2.xml"));
+
+    enabledStore.setGadgetAdminData(DEFAULT, "http://example.com/gadget1.xml", null);
+    assertNotNull(enabledStore.getGadgetAdminData(DEFAULT, "http://example.com/gadget1.xml"));
+
+    enabledStore.setGadgetAdminData(DEFAULT, null, horoscopeAdminData);
+    assertNull(enabledStore.getGadgetAdminData(DEFAULT, null));
+  }
+
+  @Test
+  public void testGetContainerAdminData() {
+    assertEquals(defaultAdminData, enabledStore.getContainerAdminData(DEFAULT));
+    assertNull(enabledStore.getContainerAdminData("my_constianer"));
+  }
+
+  @Test
+  public void testSetContainerAdminData() {
+    assertEquals(defaultAdminData, enabledStore.getContainerAdminData(DEFAULT));
+
+    defaultAdminData.removeGadgetAdminData(TODO);
+    enabledStore.setContainerAdminData(DEFAULT, defaultAdminData);
+    assertEquals(defaultAdminData, enabledStore.getContainerAdminData(DEFAULT));
+
+    assertNull(enabledStore.getContainerAdminData("my_container"));
+    enabledStore.setContainerAdminData("my_container", defaultAdminData);
+    assertEquals(defaultAdminData, enabledStore.getContainerAdminData("my_container"));
+
+    enabledStore.setContainerAdminData(null, defaultAdminData);
+    assertNull(enabledStore.getContainerAdminData(null));
+
+    enabledStore.setContainerAdminData("my_container_2", null);
+    assertNotNull(enabledStore.getContainerAdminData("my_container_2"));
+  }
+
+  @Test
+  public void testGetServerAdminData() {
+    ServerAdminData test = new ServerAdminData();
+    test.addContainerAdminData(DEFAULT, defaultAdminData);
+    assertEquals(test, enabledStore.getServerAdminData());
+  }
+
+  @Test
+  public void testBlacklistAll() throws Exception {
+    Set<String> features = Sets.newHashSet();
+    List<String> featuresAndDeps = Lists.newArrayList();
+    List<String> allGadgetFeatures = Lists.newArrayList("dep1", "dep2", "foo1", "foo2", "foo3");
+    FeatureAdminData data = new FeatureAdminData(features, Type.WHITELIST);
+    List<String> gadgetRequiredFeatureNames = Lists.newArrayList("foo1", "foo2", "foo3");
+    List<Feature> allFeatures = Lists.newArrayList(
+            createMockFeature(gadgetRequiredFeatureNames.get(0), true),
+            createMockFeature(gadgetRequiredFeatureNames.get(1), true),
+            createMockFeature(gadgetRequiredFeatureNames.get(2), true));
+    enabledStore.getContainerAdminData(DEFAULT).addGadgetAdminData(TEST_GADGET,
+            new GadgetAdminData(data));
+    mockRegistryForFeatureAdmin(features, featuresAndDeps,
+            allGadgetFeatures, gadgetRequiredFeatureNames);
+    mockGadget(allFeatures);
+    replay();
+    assertFalse(enabledStore.checkFeatureAdminInfo(mockGadget));
+    assertTrue(disabledStore.checkFeatureAdminInfo(mockGadget));
+    verify();
+  }
+
+  @Test
+  public void testWhitelistAll() throws Exception {
+    Set<String> features = Sets.newHashSet();
+    List<String> featuresAndDeps = Lists.newArrayList();
+    List<String> allGadgetFeatures = Lists.newArrayList("dep1", "dep2", "foo1", "foo2", "foo3");
+    FeatureAdminData data = new FeatureAdminData(features, Type.BLACKLIST);
+    List<String> gadgetRequiredFeatureNames = Lists.newArrayList("foo1", "foo2", "foo3");
+    List<Feature> allFeatures = Lists.newArrayList(
+            createMockFeature(gadgetRequiredFeatureNames.get(0), true),
+            createMockFeature(gadgetRequiredFeatureNames.get(1), true),
+            createMockFeature(gadgetRequiredFeatureNames.get(2), true));
+    enabledStore.getContainerAdminData(DEFAULT).addGadgetAdminData(TEST_GADGET,
+            new GadgetAdminData(data));
+    mockRegistryForFeatureAdmin(features, featuresAndDeps,
+            allGadgetFeatures, gadgetRequiredFeatureNames);
+    mockGadget(allFeatures);
+    replay();
+    assertTrue(enabledStore.checkFeatureAdminInfo(mockGadget));
+    assertTrue(disabledStore.checkFeatureAdminInfo(mockGadget));
+    verify();
+  }
+
+  @Test
+  public void testAllowedGadgetWhitelist() throws Exception {
+    Set<String> features = Sets.newHashSet("foo4", "foo3");
+    List<String> featuresAndDeps = Lists.newArrayList("foo4", "dep1", "dep2", "foo3");
+    List<String> allGadgetFeatures = Lists.newArrayList("dep1", "dep2", "foo3", "foo4");
+    List<String> gadgetRequiredFeatureNames = Lists.newArrayList("foo3", "foo4");
+    List<Feature> allFeatures = Lists.newArrayList(
+            createMockFeature(gadgetRequiredFeatureNames.get(0), true),
+            createMockFeature(gadgetRequiredFeatureNames.get(1), true));
+    FeatureAdminData data = new FeatureAdminData(features,Type.WHITELIST);
+    enabledStore.getContainerAdminData(DEFAULT).addGadgetAdminData(TEST_GADGET,
+            new GadgetAdminData(data));
+    mockRegistryForFeatureAdmin(features, featuresAndDeps,
+            allGadgetFeatures, gadgetRequiredFeatureNames);
+    mockGadget(allFeatures);
+    replay();
+    assertTrue(enabledStore.checkFeatureAdminInfo(mockGadget));
+    assertTrue(disabledStore.checkFeatureAdminInfo(mockGadget));
+    verify();
+  }
+
+  @Test
+  public void testDeniedGadgetWhitelist() throws Exception {
+    Set<String> features = Sets.newHashSet("foo4", "foo3");
+    List<String> featuresAndDeps = Lists.newArrayList("foo4", "dep1", "dep2", "foo3");
+    List<String> allGadgetFeatures = Lists.newArrayList("dep1", "dep2", "foo3", "foo4", "foo5");
+    List<String> gadgetRequiredFeatureNames = Lists.newArrayList("foo3", "foo4", "foo5");
+    List<Feature> allFeatures = Lists.newArrayList(
+            createMockFeature(gadgetRequiredFeatureNames.get(0), true),
+            createMockFeature(gadgetRequiredFeatureNames.get(1), true),
+            createMockFeature(gadgetRequiredFeatureNames.get(2), true));
+    FeatureAdminData data = new FeatureAdminData(features,Type.WHITELIST);
+    enabledStore.getContainerAdminData(DEFAULT).addGadgetAdminData(TEST_GADGET,
+            new GadgetAdminData(data));
+    mockRegistryForFeatureAdmin(features, featuresAndDeps,
+            allGadgetFeatures, gadgetRequiredFeatureNames);
+    mockGadget(allFeatures);
+    replay();
+    assertFalse(enabledStore.checkFeatureAdminInfo(mockGadget));
+    assertTrue(disabledStore.checkFeatureAdminInfo(mockGadget));
+    verify();
+  }
+
+  @Test
+  public void testAllowedGadgetBlacklist() throws Exception {
+    Set<String> features = Sets.newHashSet("foo5", "foo6");
+    List<String> featuresAndDeps = Lists.newArrayList("foo5", "dep1", "dep2", "foo6");
+    List<String> allGadgetFeatures = Lists.newArrayList("dep1", "dep2", "foo3", "foo4");
+    List<String> gadgetRequiredFeatureNames = Lists.newArrayList("foo3", "foo4");
+    List<Feature> allFeatures = Lists.newArrayList(
+            createMockFeature(gadgetRequiredFeatureNames.get(0), true),
+            createMockFeature(gadgetRequiredFeatureNames.get(1), true));
+    FeatureAdminData data = new FeatureAdminData(features,Type.BLACKLIST);
+    enabledStore.getContainerAdminData(DEFAULT).addGadgetAdminData(TEST_GADGET,
+            new GadgetAdminData(data));
+    mockRegistryForFeatureAdmin(features, featuresAndDeps,
+            allGadgetFeatures, gadgetRequiredFeatureNames);
+    mockGadget(allFeatures);
+    replay();
+    assertTrue(enabledStore.checkFeatureAdminInfo(mockGadget));
+    assertTrue(disabledStore.checkFeatureAdminInfo(mockGadget));
+    verify();
+  }
+
+  @Test
+  public void testDeniedGadgetBlacklist() throws Exception {
+    Set<String> features = Sets.newHashSet("foo4", "foo3");
+    List<String> featuresAndDeps = Lists.newArrayList("foo5", "dep1", "dep2", "foo6");
+    List<String> allGadgetFeatures = Lists.newArrayList("dep1", "dep2", "foo3", "foo4");
+    List<String> gadgetRequiredFeatureNames = Lists.newArrayList("foo3", "foo4");
+    List<Feature> allFeatures = Lists.newArrayList(
+            createMockFeature(gadgetRequiredFeatureNames.get(0), true),
+            createMockFeature(gadgetRequiredFeatureNames.get(1), true));
+    FeatureAdminData data = new FeatureAdminData(features,Type.BLACKLIST);
+    enabledStore.getContainerAdminData(DEFAULT).addGadgetAdminData(TEST_GADGET,
+            new GadgetAdminData(data));
+    mockRegistryForFeatureAdmin(features, featuresAndDeps,
+            allGadgetFeatures, gadgetRequiredFeatureNames);
+    mockGadget(allFeatures);
+    replay();
+    assertFalse(enabledStore.checkFeatureAdminInfo(mockGadget));
+    assertTrue(disabledStore.checkFeatureAdminInfo(mockGadget));
+    verify();
+  }
+
+  @Test
+  public void testDeniedOptionalFeature() throws Exception {
+    Set<String> features = Sets.newHashSet("foo4", "foo3");
+    List<String> featuresAndDeps = Lists.newArrayList("foo4", "dep1", "dep2", "foo3");
+    List<String> allGadgetFeatures = Lists.newArrayList("dep1", "dep2", "foo3", "foo4");
+    List<String> gadgetRequiredFeatureNames = Lists.newArrayList("foo3", "foo4");
+    List<Feature> allFeatures = Lists.newArrayList(
+            createMockFeature(gadgetRequiredFeatureNames.get(0), true),
+            createMockFeature(gadgetRequiredFeatureNames.get(1), true),
+            createMockFeature("foo5", false));
+    FeatureAdminData data = new FeatureAdminData(features,Type.WHITELIST);
+    enabledStore.getContainerAdminData(DEFAULT).addGadgetAdminData(TEST_GADGET,
+            new GadgetAdminData(data));
+    mockRegistryForFeatureAdmin(features, featuresAndDeps,
+            allGadgetFeatures, gadgetRequiredFeatureNames);
+    mockGadget(allFeatures);
+    replay();
+    assertTrue(enabledStore.checkFeatureAdminInfo(mockGadget));
+    assertTrue(disabledStore.checkFeatureAdminInfo(mockGadget));
+    verify();
+  }
+
+  @Test
+  public void testFeatureAdminNullGadgetData() throws Exception {
+    List<String> gadgetRequiredFeatureNames = Lists.newArrayList("foo3", "foo4");
+    List<Feature> allFeatures = Lists.newArrayList(
+            createMockFeature(gadgetRequiredFeatureNames.get(0), true),
+            createMockFeature(gadgetRequiredFeatureNames.get(1), true));
+    mockGadget(allFeatures, DEFAULT, "https://example.com/dontexist.xml");
+    replay();
+    assertFalse(enabledStore.checkFeatureAdminInfo(mockGadget));
+    assertTrue(disabledStore.checkFeatureAdminInfo(mockGadget));
+    verify();
+  }
+
+  @Test
+  public void testFeatureAdminNullContainerData() throws Exception {
+    List<String> gadgetRequiredFeatureNames = Lists.newArrayList("foo3", "foo4");
+    List<Feature> allFeatures = Lists.newArrayList(
+            createMockFeature(gadgetRequiredFeatureNames.get(0), true),
+            createMockFeature(gadgetRequiredFeatureNames.get(1), true));
+    mockGadget(allFeatures, "foocontainer");
+    replay();
+    assertFalse(enabledStore.checkFeatureAdminInfo(mockGadget));
+    assertTrue(disabledStore.checkFeatureAdminInfo(mockGadget));
+    verify();
+  }
+
+  @Test
+  public void testIsWhiteListed() throws Exception {
+    assertTrue(enabledStore.isWhitelisted(DEFAULT, HOROSCOPE));
+    assertTrue(enabledStore.isWhitelisted(DEFAULT, TEST_GADGET));
+    assertFalse(enabledStore.isWhitelisted(DEFAULT, "https://example.com/gadget.xml"));
+    assertFalse(enabledStore.isWhitelisted("myContainer", HOROSCOPE));
+    assertTrue(enabledStore.isWhitelisted(DEFAULT, "http://foo.com/gadget.xml"));
+    assertTrue(enabledStore.isWhitelisted(DEFAULT, "http://example.com/gadget.xml"));
+    assertTrue(disabledStore.isWhitelisted(DEFAULT, HOROSCOPE));
+    assertTrue(disabledStore.isWhitelisted(DEFAULT, TEST_GADGET));
+    assertTrue(disabledStore.isWhitelisted("myContainer", HOROSCOPE));
+  }
+
+  @Test
+  public void testIsAllowedFeature() throws Exception {
+    mockGadget(ImmutableList.<Feature> of(), DEFAULT, TODO);
+    Feature denied = createMockFeature("setprefs", true);
+    Feature allowed = createMockFeature("foo", true);
+    replay();
+    assertFalse(enabledStore.isAllowedFeature(denied, mockGadget));
+    assertTrue(enabledStore.isAllowedFeature(allowed, mockGadget));
+    assertTrue(disabledStore.isAllowedFeature(denied, mockGadget));
+    assertTrue(disabledStore.isAllowedFeature(allowed, mockGadget));
+  }
+
+  private static class FakeContainerConfig extends BasicContainerConfig {
+    protected final Map<String, Object> data;
+
+    public FakeContainerConfig(boolean enableFeatureAdministration, boolean enableGadgetWhitelist) {
+      data = ImmutableMap
+              .<String, Object> builder()
+              .put("gadgets.admin.enableFeatureAdministration",
+                      new Boolean(enableFeatureAdministration).toString())
+              .put("gadgets.admin.enableGadgetWhitelist", new Boolean(enableGadgetWhitelist))
+              .build();
+    }
+
+    @Override
+    public Object getProperty(String container, String name) {
+      return data.get(name);
+    }
+  }
+
+}

Added: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/ContainerAdminDataTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/ContainerAdminDataTest.java?rev=1178236&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/ContainerAdminDataTest.java (added)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/ContainerAdminDataTest.java Sun Oct  2 19:44:13 2011
@@ -0,0 +1,200 @@
+/*
+ * 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.admin;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.shindig.gadgets.admin.FeatureAdminData.Type;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.caja.util.Sets;
+import com.google.common.base.Objects;
+import com.google.common.collect.Maps;
+
+/**
+ * @version $Id: 3.0.0
+ */
+public class ContainerAdminDataTest {
+
+  private static final String VIEWS = "views";
+  private static final String SETPREFS = "setprefs";
+  private static final String TABS = "tabs";
+  private static final String EE = "embedded-experiences";
+  private static final String SELECTION = "selection";
+  private static final String GADGET_URL_1 = "http://sample.com/gadget1.xml";
+  private static final String GADGET_URL_2 = "http://sample.com/gadget2.xml";
+  private static final String GADGET_URL_3 = "http://example.com/*";
+
+  private Set<String> whitelist;
+  private Set<String> blacklist;
+  private FeatureAdminData whitelistFeatures;
+  private FeatureAdminData blacklistFeatures;
+  private GadgetAdminData whitelistData;
+  private GadgetAdminData blacklistData;
+  private Map<String, GadgetAdminData> gadgetMap;
+  private ContainerAdminData validData;
+  private ContainerAdminData emptyData;
+  private ContainerAdminData nullData;
+  private ContainerAdminData defaultData;
+
+  @Before
+  public void setUp() throws Exception {
+    whitelist = Sets.newHashSet(VIEWS, SETPREFS, TABS);
+    blacklist = Sets.newHashSet(EE, SELECTION);
+    whitelistFeatures = new FeatureAdminData(whitelist, Type.WHITELIST);
+    blacklistFeatures = new FeatureAdminData(blacklist, Type.BLACKLIST);
+
+    whitelistData = new GadgetAdminData(whitelistFeatures);
+    blacklistData = new GadgetAdminData(blacklistFeatures);
+
+    gadgetMap = Maps.newHashMap();
+    gadgetMap.put(GADGET_URL_1, whitelistData);
+    gadgetMap.put(GADGET_URL_2, blacklistData);
+    gadgetMap.put(GADGET_URL_3, new GadgetAdminData());
+    gadgetMap.put("http://*", blacklistData);
+
+    validData = new ContainerAdminData(gadgetMap);
+    emptyData = new ContainerAdminData(new HashMap<String, GadgetAdminData>());
+    nullData = new ContainerAdminData(null);
+    defaultData = new ContainerAdminData();
+
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    whitelist = null;
+    blacklist = null;
+    whitelistFeatures = null;
+    blacklistFeatures = null;
+    whitelistData = null;
+    blacklistData = null;
+    gadgetMap = null;
+    validData = null;
+    emptyData = null;
+    nullData = null;
+    defaultData = null;
+  }
+
+  @Test
+  public void testGetGadgetAdminData() {
+    assertEquals(whitelistData, validData.getGadgetAdminData(GADGET_URL_1));
+    assertEquals(blacklistData, validData.getGadgetAdminData(GADGET_URL_2));
+    assertEquals(new GadgetAdminData(),
+            validData.getGadgetAdminData("http://example.com/gadgets/gadget.xml"));
+    assertEquals(new GadgetAdminData(),
+            validData.getGadgetAdminData("http://example.com/gadget.xml"));
+    assertEquals(blacklistData, validData.getGadgetAdminData("http://foo.com/gadget.xml"));
+    assertNull(emptyData.getGadgetAdminData(GADGET_URL_1));
+    assertNull(nullData.getGadgetAdminData(GADGET_URL_1));
+    assertNull(defaultData.getGadgetAdminData(GADGET_URL_1));
+  }
+
+  @Test
+  public void testGetGadgetAdminMap() {
+    assertEquals(gadgetMap, validData.getGadgetAdminMap());
+    assertEquals(new HashMap<String, GadgetAdminData>(), emptyData.getGadgetAdminMap());
+    assertEquals(new HashMap<String, GadgetAdminData>(), nullData.getGadgetAdminMap());
+    assertEquals(new HashMap<String, GadgetAdminData>(), defaultData.getGadgetAdminMap());
+  }
+
+  @Test
+  public void testEquals() {
+    assertTrue(validData.equals(new ContainerAdminData(gadgetMap)));
+    assertTrue(emptyData.equals(new ContainerAdminData(new HashMap<String, GadgetAdminData>())));
+    assertTrue(defaultData.equals(new ContainerAdminData(new HashMap<String, GadgetAdminData>())));
+    assertTrue(nullData.equals(new ContainerAdminData(null)));
+    assertTrue(emptyData.equals(defaultData));
+    assertFalse(validData.equals(null));
+    assertFalse(validData.equals(new Object()));
+    assertFalse(validData.equals(gadgetMap));
+    assertFalse(validData.equals(emptyData));
+    assertFalse(validData.equals(nullData));
+  }
+
+  @Test
+  public void testAddAndRemove() {
+    defaultData.addGadgetAdminData(GADGET_URL_1, whitelistData);
+    assertEquals(whitelistData, defaultData.getGadgetAdminData(GADGET_URL_1));
+    GadgetAdminData test = defaultData.removeGadgetAdminData(GADGET_URL_1);
+    assertNull(defaultData.getGadgetAdminData(GADGET_URL_1));
+    assertEquals(whitelistData, test);
+
+    defaultData.addGadgetAdminData(null, whitelistData);
+    assertNull(defaultData.getGadgetAdminData(null));
+
+    test = defaultData.removeGadgetAdminData(null);
+    assertNull(defaultData.getGadgetAdminData(null));
+    assertNull(test);
+
+    defaultData.addGadgetAdminData(GADGET_URL_1, null);
+    assertNotNull(defaultData.getGadgetAdminData(GADGET_URL_1));
+
+    validData.addGadgetAdminData(GADGET_URL_2, null);
+    assertNotNull(validData.getGadgetAdminData(GADGET_URL_2));
+  }
+
+  @Test
+  public void testClearGadgetAdminData() {
+    assertEquals(gadgetMap, validData.getGadgetAdminMap());
+    assertEquals(new HashMap<String, GadgetAdminData>(), nullData.getGadgetAdminMap());
+    assertEquals(new HashMap<String, GadgetAdminData>(), emptyData.getGadgetAdminMap());
+    assertEquals(new HashMap<String, GadgetAdminData>(), defaultData.getGadgetAdminMap());
+
+    validData.clearGadgetAdminData();
+    nullData.clearGadgetAdminData();
+    emptyData.clearGadgetAdminData();
+    defaultData.clearGadgetAdminData();
+
+    assertEquals(new HashMap<String, GadgetAdminData>(), validData.getGadgetAdminMap());
+    assertEquals(new HashMap<String, GadgetAdminData>(), nullData.getGadgetAdminMap());
+    assertEquals(new HashMap<String, GadgetAdminData>(), emptyData.getGadgetAdminMap());
+    assertEquals(new HashMap<String, GadgetAdminData>(), defaultData.getGadgetAdminMap());
+  }
+
+  @Test
+  public void testHasGadgetAdminData() {
+    assertTrue(validData.hasGadgetAdminData(GADGET_URL_1));
+    assertTrue(validData.hasGadgetAdminData(GADGET_URL_2));
+    assertTrue(validData.hasGadgetAdminData("http://example.com/gadget3.xml"));
+    assertFalse(validData.hasGadgetAdminData("https://example.com/gadget3.xml"));
+    assertFalse(nullData.hasGadgetAdminData(GADGET_URL_1));
+    assertFalse(emptyData.hasGadgetAdminData(GADGET_URL_2));
+    assertFalse(defaultData.hasGadgetAdminData(GADGET_URL_2));
+  }
+
+  @Test
+  public void testHashCode() {
+    assertEquals(Objects.hashCode(this.gadgetMap), validData.hashCode());
+    assertEquals(Objects.hashCode(Maps.newHashMap()), nullData.hashCode());
+    assertEquals(Objects.hashCode(Maps.newHashMap()), emptyData.hashCode());
+    assertEquals(Objects.hashCode(Maps.newHashMap()), defaultData.hashCode());
+    assertEquals(nullData.hashCode(), emptyData.hashCode());
+    assertFalse(validData.hashCode() == defaultData.hashCode());
+  }
+}

Added: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/FeatureAdminDataTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/FeatureAdminDataTest.java?rev=1178236&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/FeatureAdminDataTest.java (added)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/FeatureAdminDataTest.java Sun Oct  2 19:44:13 2011
@@ -0,0 +1,226 @@
+/*
+ * 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.admin;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.shindig.gadgets.admin.FeatureAdminData.Type;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.caja.util.Sets;
+import com.google.common.base.Objects;
+
+/**
+ * Tests for feature admin data.
+ *
+ * @version $Id: $
+ */
+public class FeatureAdminDataTest {
+
+  private static final String VIEWS = "views";
+  private static final String SETPREFS = "setprefs";
+  private static final String TABS = "tabs";
+  private static final String EE = "embedded-experiences";
+  private static final String SELECTION = "selection";
+  private Set<String> blacklist;
+  private Set<String> whitelist;
+  private FeatureAdminData whitelistData;
+  private FeatureAdminData blacklistData;
+  private FeatureAdminData nullData;
+  private FeatureAdminData defaultData;
+
+  @Before
+  public void setUp() throws Exception {
+    whitelist = Sets.newHashSet();
+    whitelist.add(VIEWS);
+    whitelist.add(SETPREFS);
+    whitelist.add(TABS);
+
+    blacklist = Sets.newHashSet();
+    blacklist.add(EE);
+    blacklist.add(SELECTION);
+
+    whitelistData = new FeatureAdminData(whitelist, Type.WHITELIST);
+    blacklistData = new FeatureAdminData(blacklist, Type.BLACKLIST);
+    nullData = new FeatureAdminData(null, null);
+    defaultData = new FeatureAdminData();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    whitelist = null;
+    blacklist = null;
+    whitelistData = null;
+    blacklistData = null;
+    nullData = null;
+    defaultData = null;
+  }
+
+  private void validateDefaultFeatures() {
+    assertEquals(whitelist, whitelistData.getFeatures());
+    assertEquals(blacklist, blacklistData.getFeatures());
+    assertEquals(Sets.newHashSet(), nullData.getFeatures());
+    assertEquals(Sets.newHashSet(), defaultData.getFeatures());
+  }
+
+  @Test
+  public void testGetFeatures() {
+    validateDefaultFeatures();
+  }
+
+  @Test
+  public void testAddFeatures() {
+    validateDefaultFeatures();
+
+    Set<String> toAdd = Sets.newHashSet("foo", "bar", null);
+    whitelistData.addFeatures(toAdd);
+    blacklistData.addFeatures(toAdd);
+    nullData.addFeatures(toAdd);
+    defaultData.addFeatures(toAdd);
+
+    Set<String> actuallyAdded = Sets.newHashSet("foo", "bar");
+    whitelist.addAll(actuallyAdded);
+    blacklist.addAll(actuallyAdded);
+    assertEquals(whitelist, whitelistData.getFeatures());
+    assertEquals(blacklist, blacklistData.getFeatures());
+    assertEquals(actuallyAdded, nullData.getFeatures());
+    assertEquals(actuallyAdded, defaultData.getFeatures());
+  }
+
+  @Test
+  public void testAddFeature() {
+    validateDefaultFeatures();
+
+    whitelistData.addFeature("foo");
+    blacklistData.addFeature("foo");
+    nullData.addFeature("foo");
+    defaultData.addFeature("foo");
+    defaultData.addFeature(null);
+
+    whitelist.add("foo");
+    blacklist.add("foo");
+    assertEquals(whitelist, whitelistData.getFeatures());
+    assertEquals(blacklist, blacklistData.getFeatures());
+    assertEquals(Sets.newHashSet("foo"), nullData.getFeatures());
+    assertEquals(Sets.newHashSet("foo"), defaultData.getFeatures());
+  }
+
+  @Test
+  public void testClearFeatures() {
+    validateDefaultFeatures();
+
+    whitelistData.clearFeatures();
+    blacklistData.clearFeatures();
+    nullData.clearFeatures();
+    defaultData.clearFeatures();
+
+    assertEquals(Sets.newHashSet(), whitelistData.getFeatures());
+    assertEquals(Sets.newHashSet(), blacklistData.getFeatures());
+    assertEquals(Sets.newHashSet(), nullData.getFeatures());
+    assertEquals(Sets.newHashSet(), defaultData.getFeatures());
+  }
+
+  @Test
+  public void testRemoveFeatures() {
+    validateDefaultFeatures();
+
+    Set<String> toRemoveWhitelist = Sets.newHashSet(TABS, VIEWS);
+    Set<String> toRemoveBlacklist = Sets.newHashSet(EE);
+    whitelistData.removeFeatures(toRemoveWhitelist);
+    blacklistData.removeFeatures(toRemoveBlacklist);
+    nullData.removeFeatures(toRemoveWhitelist);
+    defaultData.removeFeatures(toRemoveWhitelist);
+
+    assertEquals(Sets.newHashSet(SETPREFS), whitelistData.getFeatures());
+    assertEquals(Sets.newHashSet(SELECTION), blacklistData.getFeatures());
+    assertEquals(Sets.newHashSet(), nullData.getFeatures());
+    assertEquals(Sets.newHashSet(), defaultData.getFeatures());
+  }
+
+  @Test
+  public void testRemoveFeature() {
+    validateDefaultFeatures();
+
+    whitelistData.removeFeature(TABS);
+    blacklistData.removeFeature(SELECTION);
+    nullData.removeFeature(TABS);
+    defaultData.removeFeature(TABS);
+
+    assertEquals(Sets.newHashSet(SETPREFS, VIEWS), whitelistData.getFeatures());
+    assertEquals(Sets.newHashSet(EE), blacklistData.getFeatures());
+    assertEquals(Sets.newHashSet(), nullData.getFeatures());
+    assertEquals(Sets.newHashSet(), defaultData.getFeatures());
+  }
+
+  @Test
+  public void testGetPriority() {
+    assertEquals(Type.WHITELIST, whitelistData.getType());
+    assertEquals(Type.BLACKLIST, blacklistData.getType());
+    assertEquals(Type.WHITELIST, nullData.getType());
+    assertEquals(Type.WHITELIST, defaultData.getType());
+  }
+
+  @Test
+  public void testSetPriority() {
+    whitelistData.setType(Type.BLACKLIST);
+    blacklistData.setType(Type.WHITELIST);
+    nullData.setType(Type.BLACKLIST);
+    defaultData.setType(Type.BLACKLIST);
+
+    assertEquals(Type.BLACKLIST, whitelistData.getType());
+    assertEquals(Type.BLACKLIST, nullData.getType());
+    assertEquals(Type.BLACKLIST, defaultData.getType());
+    assertEquals(Type.WHITELIST, blacklistData.getType());
+
+    nullData.setType(null);
+    assertEquals(Type.WHITELIST, nullData.getType());
+  }
+
+  @Test
+  public void testEquals() {
+    assertTrue(whitelistData.equals(new FeatureAdminData(whitelist, Type.WHITELIST)));
+    assertFalse(whitelistData.equals(new FeatureAdminData(whitelist,Type.BLACKLIST)));
+    assertFalse(whitelistData.equals(new FeatureAdminData(new HashSet<String>(),
+            Type.WHITELIST)));
+    assertFalse(whitelistData.equals(new FeatureAdminData(Sets.newHashSet(EE), Type.WHITELIST)));
+    assertFalse(whitelistData.equals(null));
+    assertTrue(blacklistData.equals(new FeatureAdminData(blacklist, Type.BLACKLIST)));
+    assertTrue(nullData.equals(defaultData));
+    assertFalse(nullData.equals(whitelistData));
+  }
+
+  @Test
+  public void testHashCode() {
+    assertEquals(Objects.hashCode(this.whitelist, Type.WHITELIST), whitelistData.hashCode());
+    assertEquals(Objects.hashCode(this.blacklist, Type.BLACKLIST), blacklistData.hashCode());
+    assertEquals(Objects.hashCode(Sets.newHashSet(), Type.WHITELIST),
+            nullData.hashCode());
+    assertEquals(Objects.hashCode(Sets.newHashSet(), Type.WHITELIST),
+            defaultData.hashCode());
+    assertFalse(Objects.hashCode(this.blacklist, Type.WHITELIST) == whitelistData
+            .hashCode());
+  }
+}

Added: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/GadgetAdminDataTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/GadgetAdminDataTest.java?rev=1178236&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/GadgetAdminDataTest.java (added)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/GadgetAdminDataTest.java Sun Oct  2 19:44:13 2011
@@ -0,0 +1,108 @@
+/*
+ * 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.admin;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Set;
+
+import org.apache.shindig.gadgets.admin.FeatureAdminData.Type;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.caja.util.Sets;
+import com.google.common.base.Objects;
+
+/**
+ * @version $Id: 3.0.0
+ */
+public class GadgetAdminDataTest {
+
+  private static final String VIEWS = "views";
+  private static final String SETPREFS = "setprefs";
+  private static final String TABS = "tabs";
+  private static final String EE = "embedded-experiences";
+  private static final String SELECTION = "selection";
+  private Set<String> whitelist;
+  private Set<String> blacklist;
+  private FeatureAdminData whitelistFeatures;
+  private FeatureAdminData blacklistFeatures;
+  private GadgetAdminData whitelistInfo;
+  private GadgetAdminData blacklistInfo;
+  private GadgetAdminData nullInfo;
+  private GadgetAdminData defaultInfo;
+
+  @Before
+  public void setUp() throws Exception {
+    whitelist = Sets.newHashSet(VIEWS, SETPREFS, TABS);
+    blacklist = Sets.newHashSet(EE, SELECTION);
+    whitelistFeatures = new FeatureAdminData(whitelist, Type.WHITELIST);
+    blacklistFeatures = new FeatureAdminData(blacklist, Type.BLACKLIST);
+    whitelistInfo = new GadgetAdminData(whitelistFeatures);
+    blacklistInfo = new GadgetAdminData(blacklistFeatures);
+    nullInfo = new GadgetAdminData(null);
+    defaultInfo = new GadgetAdminData();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    whitelist = null;
+    whitelistInfo = null;
+    blacklistInfo = null;
+    whitelistFeatures = null;
+    blacklistFeatures = null;
+    nullInfo = null;
+    defaultInfo = null;
+  }
+
+  @Test
+  public void testGetFeatureAdminData() {
+    assertEquals(whitelistFeatures, whitelistInfo.getFeatureAdminData());
+    assertEquals(blacklistFeatures, blacklistInfo.getFeatureAdminData());
+    assertEquals(new FeatureAdminData(), nullInfo.getFeatureAdminData());
+    assertEquals(new FeatureAdminData(), defaultInfo.getFeatureAdminData());
+  }
+
+  @Test
+  public void testEquals() {
+    assertTrue(whitelistInfo.equals(new GadgetAdminData(whitelistFeatures)));
+    assertTrue(nullInfo.equals(new GadgetAdminData(null)));
+    assertTrue(defaultInfo.equals(new GadgetAdminData()));
+    assertTrue(nullInfo.equals(defaultInfo));
+    assertFalse(whitelistInfo.equals(null));
+    assertFalse(whitelistInfo.equals(new Object()));
+    assertFalse(whitelistInfo.equals(blacklistInfo));
+    assertFalse(whitelistInfo.equals(defaultInfo));
+    assertFalse(whitelistInfo.equals(nullInfo));
+  }
+
+  @Test
+  public void testHashCode() {
+    assertEquals(Objects.hashCode(whitelistFeatures), whitelistInfo.hashCode());
+    assertEquals(Objects.hashCode(blacklistFeatures), blacklistInfo.hashCode());
+    assertEquals(Objects.hashCode(new FeatureAdminData()), nullInfo.hashCode());
+    assertEquals(Objects.hashCode(new FeatureAdminData()), defaultInfo.hashCode());
+    assertEquals(nullInfo.hashCode(), defaultInfo.hashCode());
+    assertFalse(blacklistInfo.hashCode() == whitelistInfo.hashCode());
+  }
+
+}

Added: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/ServerAdminDataTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/ServerAdminDataTest.java?rev=1178236&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/ServerAdminDataTest.java (added)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/ServerAdminDataTest.java Sun Oct  2 19:44:13 2011
@@ -0,0 +1,213 @@
+/*
+ * 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.admin;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.shindig.gadgets.admin.FeatureAdminData.Type;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.caja.util.Sets;
+import com.google.common.base.Objects;
+import com.google.common.collect.Maps;
+
+/**
+ * @version $Id: $
+ */
+public class ServerAdminDataTest {
+
+  private static final String VIEWS = "views";
+  private static final String SETPREFS = "setprefs";
+  private static final String TABS = "tabs";
+  private static final String EE = "embedded-experiences";
+  private static final String SELECTION = "selection";
+  private static final String GADGET_URL_1 = "http://sample.com/gadget1.xml";
+  private static final String GADGET_URL_2 = "http://sample.com/gadget2.xml";
+  private static final String DEFAULT = "default";
+  private static final String MY_CONTAINER = "my_container";
+
+  private Set<String> whitelist;
+  private Set<String> blacklist;
+  private FeatureAdminData whitelistFeatures;
+  private FeatureAdminData blacklistFeatures;
+  private GadgetAdminData whitelistInfo;
+  private GadgetAdminData blacklistInfo;
+  private Map<String, GadgetAdminData> defaultMap;
+  private Map<String, GadgetAdminData> myMap;
+  private Map<String, ContainerAdminData> containerMap;
+  private ContainerAdminData defaultContainerData;
+  private ContainerAdminData myContainerData;
+  private ServerAdminData validData;
+  private ServerAdminData emptyData;
+  private ServerAdminData defaultData;
+  private ServerAdminData nullData;
+
+  @Before
+  public void setUp() throws Exception {
+    whitelist = Sets.newHashSet(VIEWS, SETPREFS, TABS);
+    blacklist = Sets.newHashSet(EE, SELECTION);
+    whitelistFeatures = new FeatureAdminData(whitelist, Type.WHITELIST);
+    blacklistFeatures = new FeatureAdminData(blacklist, Type.BLACKLIST);
+
+    whitelistInfo = new GadgetAdminData(whitelistFeatures);
+    blacklistInfo = new GadgetAdminData(blacklistFeatures);
+
+    defaultMap = Maps.newHashMap();
+    defaultMap.put(GADGET_URL_1, whitelistInfo);
+    defaultMap.put(GADGET_URL_2, blacklistInfo);
+
+    myMap = Maps.newHashMap();
+    myMap.put(GADGET_URL_2, whitelistInfo);
+    myMap.put(GADGET_URL_1, new GadgetAdminData());
+
+    defaultContainerData = new ContainerAdminData(defaultMap);
+    myContainerData = new ContainerAdminData(myMap);
+
+    containerMap = Maps.newHashMap();
+    containerMap.put(DEFAULT, defaultContainerData);
+    containerMap.put(MY_CONTAINER, myContainerData);
+
+    validData = new ServerAdminData(containerMap);
+    emptyData = new ServerAdminData(new HashMap<String, ContainerAdminData>());
+    defaultData = new ServerAdminData();
+    nullData = new ServerAdminData(null);
+
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    whitelist = null;
+    blacklist = null;
+    whitelistFeatures = null;
+    blacklistFeatures = null;
+    whitelistInfo = null;
+    blacklistInfo = null;
+    defaultMap = null;
+    myMap = null;
+    containerMap = null;
+    defaultContainerData = null;
+    myContainerData = null;
+    validData = null;
+    emptyData = null;
+    defaultData = null;
+    nullData = null;
+  }
+
+  @Test
+  public void testGetContainerAdminData() {
+    assertEquals(myContainerData, validData.getContainerAdminData(MY_CONTAINER));
+    assertEquals(defaultContainerData, validData.getContainerAdminData(DEFAULT));
+    assertNull(emptyData.getContainerAdminData(MY_CONTAINER));
+    assertNull(nullData.getContainerAdminData(DEFAULT));
+    assertNull(defaultData.getContainerAdminData(MY_CONTAINER));
+  }
+
+  @Test
+  public void testRemoveContainerAdminData() {
+    validData.removeContainerAdminData(DEFAULT);
+    emptyData.removeContainerAdminData(MY_CONTAINER);
+    nullData.removeContainerAdminData(DEFAULT);
+    defaultData.removeContainerAdminData(MY_CONTAINER);
+    Map<String, ContainerAdminData> newMap = Maps.newHashMap();
+    newMap.put(MY_CONTAINER, myContainerData);
+    assertEquals(newMap, validData.getContainerAdminDataMap());
+    assertEquals(new HashMap<String, ContainerAdminData>(), emptyData.getContainerAdminDataMap());
+    assertEquals(new HashMap<String, ContainerAdminData>(), nullData.getContainerAdminDataMap());
+    assertEquals(new HashMap<String, ContainerAdminData>(), defaultData.getContainerAdminDataMap());
+  }
+
+  @Test
+  public void testAddContainerAdminData() {
+    emptyData.addContainerAdminData(MY_CONTAINER, myContainerData);
+    nullData.addContainerAdminData(DEFAULT, defaultContainerData);
+    defaultData.addContainerAdminData(MY_CONTAINER, myContainerData);
+    defaultData.addContainerAdminData(DEFAULT, defaultContainerData);
+    defaultData.addContainerAdminData(null, myContainerData);
+
+    assertEquals(myContainerData, emptyData.getContainerAdminData(MY_CONTAINER));
+    assertEquals(defaultContainerData, nullData.getContainerAdminData(DEFAULT));
+    assertEquals(defaultContainerData, defaultData.getContainerAdminData(DEFAULT));
+    assertEquals(myContainerData, defaultData.getContainerAdminData(MY_CONTAINER));
+    assertNull(defaultData.getContainerAdminData(null));
+  }
+
+  @Test
+  public void testGetContainerAdminDataMap() {
+    assertEquals(containerMap, validData.getContainerAdminDataMap());
+    assertEquals(new HashMap<String, ContainerAdminData>(), emptyData.getContainerAdminDataMap());
+    assertEquals(new HashMap<String, ContainerAdminData>(), nullData.getContainerAdminDataMap());
+    assertEquals(new HashMap<String, ContainerAdminData>(), defaultData.getContainerAdminDataMap());
+  }
+
+  @Test
+  public void testClearContainerAdminData() {
+    validData.clearContainerAdminData();
+    emptyData.clearContainerAdminData();
+    nullData.clearContainerAdminData();
+    defaultData.clearContainerAdminData();
+
+    assertEquals(new HashMap<String, ContainerAdminData>(), validData.getContainerAdminDataMap());
+    assertEquals(new HashMap<String, ContainerAdminData>(), emptyData.getContainerAdminDataMap());
+    assertEquals(new HashMap<String, ContainerAdminData>(), nullData.getContainerAdminDataMap());
+    assertEquals(new HashMap<String, ContainerAdminData>(), defaultData.getContainerAdminDataMap());
+  }
+
+  @Test
+  public void testEqualsObject() {
+    Map<String, ContainerAdminData> testMap = Maps.newHashMap();
+    testMap.put(DEFAULT, defaultContainerData);
+    testMap.put(MY_CONTAINER, myContainerData);
+    assertTrue(validData.equals(new ServerAdminData(testMap)));
+    assertFalse(validData.equals(nullData));
+    assertTrue(nullData.equals(defaultData));
+
+    testMap = Maps.newHashMap();
+    testMap.put(MY_CONTAINER, myContainerData);
+    assertFalse(validData.equals(testMap));
+  }
+
+  @Test
+  public void testHasContainerAdminData() {
+    assertTrue(validData.hasContainerAdminData(MY_CONTAINER));
+    assertTrue(validData.hasContainerAdminData(DEFAULT));
+    assertFalse(validData.hasContainerAdminData("foo"));
+    assertFalse(nullData.hasContainerAdminData(MY_CONTAINER));
+    assertFalse(defaultData.hasContainerAdminData(DEFAULT));
+    assertFalse(emptyData.hasContainerAdminData(MY_CONTAINER));
+  }
+
+  @Test
+  public void testHashCode() {
+    assertEquals(Objects.hashCode(this.containerMap), validData.hashCode());
+    assertEquals(Objects.hashCode(Maps.newHashMap()), nullData.hashCode());
+    assertEquals(Objects.hashCode(Maps.newHashMap()), emptyData.hashCode());
+    assertEquals(Objects.hashCode(Maps.newHashMap()), defaultData.hashCode());
+    assertEquals(nullData.hashCode(), emptyData.hashCode());
+    assertFalse(validData.hashCode() == defaultData.hashCode());
+  }
+}

Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/process/ProcessorTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/process/ProcessorTest.java?rev=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/process/ProcessorTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/process/ProcessorTest.java Sun Oct  2 19:44:13 2011
@@ -17,36 +17,33 @@
  */
 package org.apache.shindig.gadgets.process;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
 
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.shindig.common.EasyMockTestCase;
 import org.apache.shindig.common.uri.Uri;
 import org.apache.shindig.config.ContainerConfig;
 import org.apache.shindig.config.JsonContainerConfig;
 import org.apache.shindig.expressions.Expressions;
 import org.apache.shindig.gadgets.Gadget;
-import org.apache.shindig.gadgets.GadgetBlacklist;
 import org.apache.shindig.gadgets.GadgetContext;
 import org.apache.shindig.gadgets.GadgetException;
 import org.apache.shindig.gadgets.GadgetSpecFactory;
+import org.apache.shindig.gadgets.admin.GadgetAdminStore;
 import org.apache.shindig.gadgets.features.FeatureRegistry;
 import org.apache.shindig.gadgets.features.FeatureRegistryProvider;
 import org.apache.shindig.gadgets.spec.GadgetSpec;
+import org.apache.shindig.gadgets.variables.Substituter;
 import org.apache.shindig.gadgets.variables.VariableSubstituter;
-
 import org.json.JSONObject;
 import org.junit.Before;
 import org.junit.Test;
 
-import javax.servlet.http.HttpServletResponse;
-
 import com.google.common.collect.Lists;
 
-import org.apache.shindig.gadgets.variables.Substituter;
-
-public class ProcessorTest {
+public class ProcessorTest extends EasyMockTestCase {
   private static final Uri SPEC_URL = Uri.parse("http://example.org/gadget.xml");
   private static final Uri TYPE_URL_HREF = Uri.parse("http://example.org/gadget.php");
   private static final String BASIC_HTML_CONTENT = "Hello, World!";
@@ -60,7 +57,7 @@ public class ProcessorTest {
 
   private final FakeGadgetSpecFactory gadgetSpecFactory = new FakeGadgetSpecFactory();
   private final FakeVariableSubstituter substituter = new FakeVariableSubstituter();
-  private final FakeBlacklist blacklist = new FakeBlacklist();
+  private final GadgetAdminStore gadgetAdminStore = mock(GadgetAdminStore.class);
 
   private ContainerConfig containerConfig;
   private Processor processor;
@@ -79,7 +76,8 @@ public class ProcessorTest {
         return null;
       }
     };
-    processor = new Processor(gadgetSpecFactory, substituter, containerConfig, blacklist,
+
+    processor = new Processor(gadgetSpecFactory, substituter, containerConfig, gadgetAdminStore,
         registryProvider);
   }
 
@@ -111,6 +109,8 @@ public class ProcessorTest {
 
   @Test
   public void normalProcessing() throws Exception {
+    expect(gadgetAdminStore.isWhitelisted(isA(String.class), isA(String.class))).andReturn(true);
+    replay();
     Gadget gadget = processor.process(makeContext("html"));
     assertEquals(BASIC_HTML_CONTENT, gadget.getCurrentView().getContent());
   }
@@ -123,44 +123,48 @@ public class ProcessorTest {
 
   @Test
   public void doViewAliasing() throws Exception {
+    expect(gadgetAdminStore.isWhitelisted(isA(String.class), isA(String.class))).andReturn(true);
+    replay();
     Gadget gadget = processor.process(makeContext("aliased"));
     assertEquals(BASIC_HTML_CONTENT, gadget.getCurrentView().getContent());
   }
 
   @Test
   public void noSupportedViewHasNoCurrentView() throws Exception {
+    expect(gadgetAdminStore.isWhitelisted(isA(String.class), isA(String.class))).andReturn(true);
+    replay();
     Gadget gadget = processor.process(makeContext("not-real-view"));
     assertNull(gadget.getCurrentView());
   }
 
   @Test
   public void substitutionsPerformedTypeHtml() throws Exception {
+    expect(gadgetAdminStore.isWhitelisted(isA(String.class), isA(String.class))).andReturn(true);
+    replay();
     processor.process(makeContext("html"));
     assertTrue("Substitutions not performed", substituter.wasSubstituted);
   }
 
   @Test
   public void substitutionsPerformedTypeUrl() throws Exception {
+    expect(gadgetAdminStore.isWhitelisted(isA(String.class), isA(String.class))).andReturn(true);
+    replay();
     processor.process(makeContext("url"));
     assertTrue("Substitutions not performed", substituter.wasSubstituted);
   }
 
   @Test
-  public void blacklistChecked() throws Exception {
+  public void whitelistChecked() throws Exception {
+    expect(gadgetAdminStore.isWhitelisted(isA(String.class), isA(String.class))).andReturn(true);
+    replay();
     processor.process(makeContext("url"));
-    assertTrue("Blacklist not checked", blacklist.wasChecked);
   }
 
-  @Test
-  public void blacklistedGadgetThrows() throws Exception {
-    blacklist.isBlacklisted = true;
-    try {
-      processor.process(makeContext("html"));
-      fail("expected ProcessingException");
-    } catch (ProcessingException e) {
-      assertEquals(HttpServletResponse.SC_FORBIDDEN, e.getHttpStatusCode());
-    }
-
+  @Test(expected = ProcessingException.class)
+  public void nonWhitelistedGadgetThrows() throws Exception {
+    expect(gadgetAdminStore.isWhitelisted(isA(String.class), isA(String.class))).andReturn(false);
+    replay();
+    processor.process(makeContext("html"));
   }
 
   @Test
@@ -185,25 +189,15 @@ public class ProcessorTest {
 
   @Test
   public void typeUrlViewsAreSkippedForSanitizedGadget() throws Exception {
+    expect(gadgetAdminStore.isWhitelisted(isA(String.class), isA(String.class)))
+    .andReturn(true).anyTimes();
+    replay();
     Gadget gadget = processor.process(makeContext("url", SPEC_URL, true));
     assertNull(gadget.getCurrentView());
     gadget = processor.process(makeContext("html", SPEC_URL, true));
     assertEquals(BASIC_HTML_CONTENT, gadget.getCurrentView().getContent());
   }
 
-  private static class FakeBlacklist implements GadgetBlacklist {
-    protected boolean wasChecked;
-    protected boolean isBlacklisted;
-
-    protected FakeBlacklist() {
-    }
-
-    public boolean isBlacklisted(Uri gadgetUri) {
-      wasChecked = true;
-      return isBlacklisted;
-    }
-  }
-
   private static class FakeGadgetSpecFactory implements GadgetSpecFactory {
     protected GadgetException exception;
 

Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriterTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriterTest.java?rev=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriterTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriterTest.java Sun Oct  2 19:44:13 2011
@@ -26,13 +26,18 @@ import static org.easymock.EasyMock.crea
 import static org.easymock.EasyMock.eq;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.getCurrentArguments;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.reset;
+import static org.easymock.EasyMock.isA;
 import static org.easymock.EasyMock.same;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
 
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.shindig.common.EasyMockTestCase;
 import org.apache.shindig.common.JsonAssert;
 import org.apache.shindig.common.PropertiesModule;
 import org.apache.shindig.common.uri.Uri;
@@ -41,6 +46,7 @@ import org.apache.shindig.config.BasicCo
 import org.apache.shindig.gadgets.Gadget;
 import org.apache.shindig.gadgets.GadgetContext;
 import org.apache.shindig.gadgets.GadgetException;
+import org.apache.shindig.gadgets.admin.GadgetAdminStore;
 import org.apache.shindig.gadgets.config.ConfigContributor;
 import org.apache.shindig.gadgets.config.CoreUtilConfigContributor;
 import org.apache.shindig.gadgets.config.DefaultConfigProcessor;
@@ -58,6 +64,7 @@ import org.apache.shindig.gadgets.preloa
 import org.apache.shindig.gadgets.preload.PreloadedData;
 import org.apache.shindig.gadgets.rewrite.MutableContent;
 import org.apache.shindig.gadgets.rewrite.RewritingException;
+import org.apache.shindig.gadgets.spec.Feature;
 import org.apache.shindig.gadgets.spec.GadgetSpec;
 import org.apache.shindig.gadgets.spec.View;
 import org.apache.shindig.gadgets.uri.JsUriManager;
@@ -69,14 +76,6 @@ import org.json.JSONObject;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
 import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -91,7 +90,7 @@ import com.google.inject.Injector;
 /**
  * Tests for RenderingContentRewriter.
  */
-public class RenderingGadgetRewriterTest {
+public class RenderingGadgetRewriterTest extends EasyMockTestCase{
   private static final Uri SPEC_URL = Uri.parse("http://example.org/gadget.xml");
   private static final String BODY_CONTENT = "Some body content";
   static final Pattern DOCUMENT_SPLIT_PATTERN = Pattern.compile(
@@ -111,6 +110,7 @@ public class RenderingGadgetRewriterTest
   private final FakeContainerConfig config = new FakeContainerConfig();
   private final JsUriManager jsUriManager = new FakeJsUriManager();
   private final MapGadgetContext context = new MapGadgetContext();
+  private final GadgetAdminStore gadgetAdminStore = mock(GadgetAdminStore.class);
 
   private FeatureRegistry featureRegistry;
   private JsServingPipeline jsServingPipeline;
@@ -127,13 +127,14 @@ public class RenderingGadgetRewriterTest
     };
     jsServingPipeline = createMock(JsServingPipeline.class);
     Map<String, ConfigContributor> configContributors = ImmutableMap.of(
-        "core.util", new CoreUtilConfigContributor(featureRegistry),
+        "core.util", new CoreUtilConfigContributor(featureRegistry,
+                gadgetAdminStore),
         "shindig.xhrwrapper", new XhrwrapperConfigContributor()
     );
     rewriter
         = new RenderingGadgetRewriter(messageBundleFactory, config, featureRegistryProvider,
             jsServingPipeline, jsUriManager,
-            new DefaultConfigProcessor(configContributors, config));
+            new DefaultConfigProcessor(configContributors, config), gadgetAdminStore);
     Injector injector = Guice.createInjector(new ParseModule(), new PropertiesModule());
     parser = injector.getInstance(GadgetHtmlParser.class);
   }
@@ -153,6 +154,13 @@ public class RenderingGadgetRewriterTest
         ImmutableList.<FeatureResource>of(),
         ImmutableSet.<String>of(),
         ImmutableList.<FeatureResource>of());
+
+    //Convenience: by default expect that the gadget is allowed to render
+    reset(gadgetAdminStore);
+    expect(gadgetAdminStore.checkFeatureAdminInfo(isA(Gadget.class))).andReturn(true);
+    expect(gadgetAdminStore.isAllowedFeature(isA(Feature.class), isA(Gadget.class)))
+    .andReturn(true).anyTimes();
+    replay(gadgetAdminStore);
     return gadget;
   }
 
@@ -602,6 +610,103 @@ public class RenderingGadgetRewriterTest
         rewritten.contains("<script src=\"http://example.org/external.js\">"));
   }
 
+  @Test(expected = RewritingException.class)
+  public void exceptionWhenFeatureNotAllowed() throws Exception {
+    Gadget gadget = makeDefaultGadget();
+    reset(gadgetAdminStore);
+    expect(gadgetAdminStore.checkFeatureAdminInfo(isA(Gadget.class))).andReturn(false);
+    replay(gadgetAdminStore);
+    rewrite(gadget, BODY_CONTENT);
+  }
+
+  @Test
+  public void  gadgetAdminDefaultContent() throws Exception {
+    String gadgetXml =
+      "<Module><ModulePrefs title=''>" +
+      "  <Require feature='foo'/>" +
+      "</ModulePrefs>" +
+      "<Content type='html'/>" +
+      "</Module>";
+
+    final Set<String> libs = ImmutableSortedSet.of("foo", "bar", "baz");
+    GadgetContext context = new GadgetContext() {
+      @Override
+      public String getParameter(String name) {
+        if (name.equals("libs")) {
+          return Joiner.on(':').join(libs);
+        }
+        return null;
+      }
+    };
+
+    Gadget gadget = makeGadgetWithSpec(gadgetXml).setContext(context);
+    FeatureResource fooResource = inline("foo-content", "foo-debug");
+    expectFeatureCalls(gadget,
+        ImmutableList.of(fooResource),
+        libs,
+        ImmutableList.of(fooResource, inline("bar-c", "bar-d"), inline("baz-c", "baz-d")));
+    String rewritten = rewrite(gadget, BODY_CONTENT);
+
+    Matcher matcher = DOCUMENT_SPLIT_PATTERN.matcher(rewritten);
+    assertTrue("Output is not valid HTML.", matcher.matches());
+    assertTrue("Missing opening html tag", matcher.group(BEFORE_HEAD_GROUP).
+        toLowerCase().contains("<html>"));
+    assertTrue("Default CSS missing.", matcher.group(HEAD_GROUP).contains(DEFAULT_CSS));
+    // Not very accurate -- could have just been user prefs.
+    assertTrue("Default javascript not included.",
+        matcher.group(HEAD_GROUP).contains("<script>"));
+    assertTrue("Original document not preserved.",
+        matcher.group(BODY_GROUP).contains(BODY_CONTENT));
+    assertTrue("gadgets.util.runOnLoadHandlers not invoked.",
+        matcher.group(BODY_GROUP).contains("gadgets.util.runOnLoadHandlers();"));
+  }
+
+  @Test
+  public void optionalDeniedFeature() throws Exception {
+    String gadgetXml =
+      "<Module><ModulePrefs title=''>" +
+      "  <Require feature='core.util'/>" +
+      "  <Require feature='foo'/>" +
+      "  <Optional feature='hello'/>" +
+      "</ModulePrefs>" +
+      "<Content type='html'/>" +
+      "</Module>";
+
+    final Set<String> libs = ImmutableSortedSet.of("core.util", "foo", "bar", "baz");
+    GadgetContext context = new GadgetContext() {
+      @Override
+      public String getParameter(String name) {
+        if (name.equals("libs")) {
+          return Joiner.on(':').join(libs);
+        }
+        return null;
+      }
+    };
+
+    Gadget gadget = makeGadgetWithSpec(gadgetXml).setContext(context);
+    reset(gadgetAdminStore);
+    Feature denied = mock(Feature.class);
+    expect(denied.getName()).andReturn("hello");
+    expect(gadgetAdminStore.checkFeatureAdminInfo(isA(Gadget.class))).andReturn(true);
+    expect(gadgetAdminStore.isAllowedFeature(eq(denied), isA(Gadget.class))).andReturn(false);
+    replay();
+
+    FeatureResource fooResource = inline("foo-content", "foo-debug");
+    expectFeatureCalls(gadget,
+        ImmutableList.of(fooResource),
+        libs,
+        ImmutableList.of(fooResource, inline("bar-c", "bar-d"), inline("baz-c", "baz-d")));
+
+    String rewritten = rewrite(gadget, "");
+    JSONObject json = getConfigJson(rewritten);
+
+    Set<String> actual = getInjectedScript(rewritten);
+    Set<String> expected = ImmutableSortedSet.of("core.util", "foo", "bar", "baz");
+    assertFalse(actual.contains("hello"));
+    assertEquals(expected, actual);
+    assertFalse(json.getJSONObject("core.util").has("hello"));
+  }
+
   private JSONObject getConfigJson(String content) throws JSONException {
     Pattern prefsPattern
         = Pattern.compile("(?:.*)gadgets\\.config\\.init\\((.*)\\);(?:.*)", Pattern.DOTALL);
@@ -1134,6 +1239,17 @@ public class RenderingGadgetRewriterTest
         BODY_CONTENT.equals(rewrite(gadget, BODY_CONTENT)));
   }
 
+  private List<String> getAllRequiredFeatures(Gadget gadget) {
+    List<String> names = Lists.newArrayList();
+    List<Feature> features = gadget.getSpec().getModulePrefs().getAllFeatures();
+    for(Feature feature : features) {
+      if(feature.getRequired()) {
+        names.add(feature.getName());
+      }
+    }
+    return names;
+  }
+
   private void expectFeatureCalls(Gadget gadget,
                                   List<FeatureResource> gadgetResources,
                                   Set<String> externLibs,
@@ -1144,6 +1260,9 @@ public class RenderingGadgetRewriterTest
     List<String> allFeatures = Lists.newLinkedList(gadgetFeatures);
     List<String> allFeaturesAndLibs = Lists.newLinkedList(gadgetFeatures);
     allFeaturesAndLibs.addAll(externLibs);
+    List<String> allRequiredFeatures = Lists.newLinkedList(getAllRequiredFeatures(gadget));
+    List<String> allRequiredFeatuesAndLibs = Lists.newLinkedList(allRequiredFeatures);
+    allRequiredFeatuesAndLibs.addAll(externLibs);
     List<String> emptyList = Lists.newLinkedList();
     final FeatureRegistry.LookupResult externLr = createMock(FeatureRegistry.LookupResult.class);
     expect(externLr.getResources()).andReturn(externResources);
@@ -1156,9 +1275,19 @@ public class RenderingGadgetRewriterTest
     expect(featureRegistry.getFeatureResources(same(gadgetContext), eq(gadgetFeatures),
         eq(emptyList))).andReturn(gadgetLr);
     expect(featureRegistry.getFeatures(eq(allFeatures)))
-        .andReturn(allFeatures);
+        .andReturn(allFeatures).anyTimes();
     expect(featureRegistry.getFeatures(eq(Sets.newHashSet(allFeaturesAndLibs))))
         .andReturn(allFeaturesAndLibs);
+    expect(featureRegistry.getFeatures(eq(ImmutableSet.of("*"))))
+    .andReturn(ImmutableList.<String>of()).anyTimes();
+    expect(featureRegistry.getFeatures(eq(ImmutableSet.of("hello"))))
+    .andReturn(ImmutableList.<String>of("hello")).anyTimes();
+    if(!allRequiredFeatures.equals(allFeatures)) {
+      expect(featureRegistry.getFeatures(eq(allRequiredFeatures)))
+      .andReturn(allRequiredFeatuesAndLibs).anyTimes();
+      expect(featureRegistry.getFeatures(eq(Sets.newHashSet(allRequiredFeatuesAndLibs))))
+      .andReturn(allRequiredFeatuesAndLibs).anyTimes();
+    }
     // Add CoreUtilConfigContributor behavior
     expect(featureRegistry.getAllFeatureNames()).
         andReturn(ImmutableSet.of("foo", "foo2", "core.util")).anyTimes();

Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/RewriteModuleTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/RewriteModuleTest.java?rev=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/RewriteModuleTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/RewriteModuleTest.java Sun Oct  2 19:44:13 2011
@@ -18,25 +18,27 @@
  */
 package org.apache.shindig.gadgets.rewrite;
 
-import com.google.inject.Guice;
-import com.google.inject.Inject;
-import com.google.inject.Injector;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
 
 import org.apache.shindig.common.PropertiesModule;
 import org.apache.shindig.config.ContainerConfig;
 import org.apache.shindig.gadgets.DefaultGuiceModule;
+import org.apache.shindig.gadgets.admin.GadgetAdminModule;
 import org.apache.shindig.gadgets.oauth.OAuthModule;
 import org.apache.shindig.gadgets.render.CajaResponseRewriter;
 import org.apache.shindig.gadgets.render.SanitizingResponseRewriter;
 import org.apache.shindig.gadgets.rewrite.ResponseRewriterList.RewriteFlow;
 import org.apache.shindig.gadgets.rewrite.image.BasicImageRewriter;
 import org.apache.shindig.gadgets.uri.AccelUriManager;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.util.List;
+import com.google.inject.Guice;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
 
 /**
  * Tests for RewriteModule. Tests the flows and the associated rewriters.
@@ -66,6 +68,7 @@ public class RewriteModuleTest {
   public void setUp() {
     injector = Guice.createInjector(
         new PropertiesModule(),
+        new GadgetAdminModule(),
         new DefaultGuiceModule(), new OAuthModule());
   }
 

Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/StyleTagProxyEmbeddedUrlsVisitorTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/StyleTagProxyEmbeddedUrlsVisitorTest.java?rev=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/StyleTagProxyEmbeddedUrlsVisitorTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/StyleTagProxyEmbeddedUrlsVisitorTest.java Sun Oct  2 19:44:13 2011
@@ -18,16 +18,15 @@
  */
 package org.apache.shindig.gadgets.rewrite;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
+import static org.junit.Assert.assertEquals;
+
 import org.apache.commons.lang.StringUtils;
 import org.apache.shindig.common.PropertiesModule;
 import org.apache.shindig.common.uri.Uri;
 import org.apache.shindig.config.ContainerConfig;
 import org.apache.shindig.gadgets.DefaultGuiceModule;
 import org.apache.shindig.gadgets.Gadget;
+import org.apache.shindig.gadgets.admin.GadgetAdminModule;
 import org.apache.shindig.gadgets.http.HttpRequest;
 import org.apache.shindig.gadgets.oauth.OAuthModule;
 import org.apache.shindig.gadgets.parse.ParseModule;
@@ -41,7 +40,10 @@ import org.junit.Test;
 import org.w3c.dom.Document;
 import org.w3c.dom.NodeList;
 
-import static org.junit.Assert.assertEquals;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
 
 /**
  * Tests for StyleTagProxyEmbeddedUrlsVisitor.
@@ -64,7 +66,8 @@ public class StyleTagProxyEmbeddedUrlsVi
   public void setUp() throws Exception {
     super.setUp();
     injector = Guice.createInjector(
-        new PropertiesModule(), new DefaultGuiceModule(), new OAuthModule());
+        new PropertiesModule(), new GadgetAdminModule(), new DefaultGuiceModule(),
+        new OAuthModule());
     ParseModule.DOMImplementationProvider domImpl =
         new ParseModule.DOMImplementationProvider();
     htmlParser = new CajaHtmlParser(domImpl.get());

Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeProcessor.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeProcessor.java?rev=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeProcessor.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeProcessor.java Sun Oct  2 19:44:13 2011
@@ -109,7 +109,7 @@ public class FakeProcessor extends Proce
 
   private final FeatureRegistry featureRegistry;
 
-  public static final List FEATURE_NAMES=ImmutableList.of(FEATURE1, FEATURE2, FEATURE3);
+  public static final List<String> FEATURE_NAMES=ImmutableList.of(FEATURE1, FEATURE2, FEATURE3);
 
   public FakeProcessor() {
     this(null);
@@ -133,7 +133,7 @@ public class FakeProcessor extends Proce
     }
 
     try {
-      GadgetSpec spec = new GadgetSpec(Uri.parse("#"), gadgets.get(context.getUrl()));
+      GadgetSpec spec = new GadgetSpec(context.getUrl(), gadgets.get(context.getUrl()));
       View view = spec.getView(context.getView());
       return new Gadget()
           .setContext(context)