Author: lindner
Date: Fri Nov 19 18:52:36 2010
New Revision: 1036980

URL: http://svn.apache.org/viewvc?rev=1036980&view=rev
Log:
SHINDIG-1472 | Patch from Eric Woods | ActivityStreams Tests Implemented

Added:
    shindig/trunk/extras/src/test/
    shindig/trunk/extras/src/test/java/
    shindig/trunk/extras/src/test/java/org/
    shindig/trunk/extras/src/test/java/org/apache/
    shindig/trunk/extras/src/test/java/org/apache/shindig/
    shindig/trunk/extras/src/test/java/org/apache/shindig/extras/
    shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/
    
shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/ActivityStreamsTestsGuiceModule.java
    shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/dataservice/
    
shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/dataservice/integration/
    
shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/dataservice/integration/AbstractActivityStreamsRestfulTests.java
    
shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/dataservice/integration/RestfulJsonActivityEntryTest.java
    shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/opensocial/
    
shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/opensocial/service/
    
shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/opensocial/service/ActivityStreamsHandlerTest.java
    shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/sample/
    shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/sample/spi/
    
shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/sample/spi/ActivityStreamsJsonDbServiceTest.java

Added: 
shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/ActivityStreamsTestsGuiceModule.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/ActivityStreamsTestsGuiceModule.java?rev=1036980&view=auto
==============================================================================
--- 
shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/ActivityStreamsTestsGuiceModule.java
 (added)
+++ 
shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/ActivityStreamsTestsGuiceModule.java
 Fri Nov 19 18:52:36 2010
@@ -0,0 +1,71 @@
+package org.apache.shindig.extras.as;
+
+import java.util.Set;
+
+import org.apache.shindig.config.ContainerConfig;
+import org.apache.shindig.config.JsonContainerConfig;
+import org.apache.shindig.extras.as.opensocial.service.ActivityStreamsHandler;
+import org.apache.shindig.extras.as.opensocial.spi.ActivityStreamService;
+import org.apache.shindig.extras.as.sample.ActivityStreamsJsonDbService;
+import org.apache.shindig.protocol.conversion.BeanConverter;
+import org.apache.shindig.protocol.conversion.BeanJsonConverter;
+import org.apache.shindig.protocol.conversion.BeanXStreamConverter;
+import org.apache.shindig.protocol.conversion.xstream.XStreamConfiguration;
+import org.apache.shindig.social.core.util.xstream.XStream081Configuration;
+import org.apache.shindig.social.opensocial.service.ActivityHandler;
+import org.apache.shindig.social.opensocial.service.AppDataHandler;
+import org.apache.shindig.social.opensocial.service.MessageHandler;
+import org.apache.shindig.social.opensocial.service.PersonHandler;
+import org.apache.shindig.social.opensocial.spi.ActivityService;
+import org.apache.shindig.social.opensocial.spi.AppDataService;
+import org.apache.shindig.social.opensocial.spi.MessageService;
+import org.apache.shindig.social.opensocial.spi.PersonService;
+import org.apache.shindig.social.sample.spi.JsonDbOpensocialService;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.AbstractModule;
+import com.google.inject.TypeLiteral;
+import com.google.inject.name.Names;
+
+/*
+ * Note: This class and dataservice > intergration >
+ * AbstractActivityStreamsRestfulTests.java are unecessary if ActivityStreams
+ * are moved into social-api.  These classes simply register the AS service for
+ * testing.  They duplicate their counterparts in social-api other than
+ * registering the AS service.
+ */
+public class ActivityStreamsTestsGuiceModule extends AbstractModule {
+
+  @Override
+  protected void configure() {
+    bind(ActivityService.class).to(JsonDbOpensocialService.class);
+    bind(AppDataService.class).to(JsonDbOpensocialService.class);
+    bind(MessageService.class).to(JsonDbOpensocialService.class);
+    bind(PersonService.class).to(JsonDbOpensocialService.class);
+    bind(ActivityStreamService.class).to(ActivityStreamsJsonDbService.class);
+    
+    bind(String.class).annotatedWith(Names.named("shindig.canonical.json.db"))
+        .toInstance("sampledata/canonicaldb.json");
+    
+    bind(XStreamConfiguration.class).to(XStream081Configuration.class);
+    
bind(BeanConverter.class).annotatedWith(Names.named("shindig.bean.converter.xml")).to(
+        BeanXStreamConverter.class);
+    
bind(BeanConverter.class).annotatedWith(Names.named("shindig.bean.converter.json")).to(
+        BeanJsonConverter.class);
+    
+    bind(new TypeLiteral<Set<Object>>(){}).annotatedWith(
+        Names.named("org.apache.shindig.handlers"))
+        .toInstance(ImmutableSet.<Object>of(ActivityHandler.class, 
AppDataHandler.class,
+            PersonHandler.class, MessageHandler.class, 
ActivityStreamsHandler.class));
+    
+    bindConstant().annotatedWith(Names.named("shindig.containers.default"))
+        .to("res://containers/default/container.js");
+    bindConstant().annotatedWith(Names.named("shindig.port")).to("8080");
+    bindConstant().annotatedWith(Names.named("shindig.host")).to("localhost");
+    bind(ContainerConfig.class).to(JsonContainerConfig.class);
+    
+    bind(Integer.class).annotatedWith(
+        Names.named("shindig.cache.lru.default.capacity"))
+        .toInstance(10);
+  }
+}

Added: 
shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/dataservice/integration/AbstractActivityStreamsRestfulTests.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/dataservice/integration/AbstractActivityStreamsRestfulTests.java?rev=1036980&view=auto
==============================================================================
--- 
shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/dataservice/integration/AbstractActivityStreamsRestfulTests.java
 (added)
+++ 
shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/dataservice/integration/AbstractActivityStreamsRestfulTests.java
 Fri Nov 19 18:52:36 2010
@@ -0,0 +1,296 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  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.  For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.shindig.extras.as.dataservice.integration;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.shindig.auth.AuthInfo;
+import org.apache.shindig.common.EasyMockTestCase;
+import org.apache.shindig.common.testing.FakeGadgetToken;
+import org.apache.shindig.common.testing.FakeHttpServletRequest;
+import org.apache.shindig.config.ContainerConfig;
+import org.apache.shindig.extras.as.ActivityStreamsTestsGuiceModule;
+import org.apache.shindig.protocol.DataServiceServlet;
+import org.apache.shindig.protocol.HandlerRegistry;
+import org.apache.shindig.protocol.conversion.BeanJsonConverter;
+import org.apache.shindig.protocol.conversion.BeanXStreamConverter;
+import org.apache.shindig.social.core.util.BeanXStreamAtomConverter;
+import org.apache.shindig.social.core.util.xstream.XStream081Configuration;
+import org.custommonkey.xmlunit.NamespaceContext;
+import org.custommonkey.xmlunit.SimpleNamespaceContext;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.custommonkey.xmlunit.XpathEngine;
+import org.easymock.EasyMock;
+import org.json.JSONObject;
+import org.junit.Before;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.TypeLiteral;
+import com.google.inject.name.Names;
+
+public abstract class AbstractActivityStreamsRestfulTests extends 
EasyMockTestCase {
+  protected static final String XMLSCHEMA = " 
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"; \n"
+    + " xsi:schemaLocation=\"http://ns.opensocial.org/2008/opensocial 
classpath:opensocial.xsd\" ";
+  protected static final String XSDRESOURCE = "opensocial.xsd";
+  protected XpathEngine xp;
+  private HttpServletResponse res;
+
+  private DataServiceServlet servlet;
+
+  private static final FakeGadgetToken FAKE_GADGET_TOKEN = new 
FakeGadgetToken()
+      .setOwnerId("john.doe").setViewerId("john.doe");
+
+  protected HttpServletResponse getResponse() {
+    return res;
+  }
+
+  protected void setResponse(HttpServletResponse res) {
+    this.res = res;
+  }
+
+  protected DataServiceServlet getServlet() {
+    return servlet;
+  }
+  protected void setServlet(DataServiceServlet servlet) {
+    this.servlet = servlet;
+  }
+
+  @Before
+  public void abstractActivityStreamsRestfulBefore() throws Exception {
+    Injector injector = Guice.createInjector(new 
ActivityStreamsTestsGuiceModule());
+
+    servlet = new DataServiceServlet();
+
+    HandlerRegistry dispatcher = injector.getInstance(HandlerRegistry.class);
+    dispatcher.addHandlers(injector.getInstance(Key.get(new 
TypeLiteral<Set<Object>>(){},
+        Names.named("org.apache.shindig.handlers"))));
+    servlet.setHandlerRegistry(dispatcher);
+    ContainerConfig containerConfig = 
EasyMock.createMock(ContainerConfig.class);
+    EasyMock.expect(containerConfig.<String>getList(null, 
"gadgets.parentOrigins")).andReturn(Collections.<String>singletonList("*")).anyTimes();
+    EasyMock.replay(containerConfig);
+    servlet.setContainerConfig(containerConfig);
+    servlet.setBeanConverters(new BeanJsonConverter(injector),
+        new BeanXStreamConverter(new XStream081Configuration(injector)),
+        new BeanXStreamAtomConverter(new XStream081Configuration(injector)));
+
+    res = EasyMock.createMock(HttpServletResponse.class);
+    NamespaceContext ns = new SimpleNamespaceContext(ImmutableMap.of("", 
"http://ns.opensocial.org/2008/opensocial";));
+    XMLUnit.setXpathNamespaceContext(ns);
+    xp = XMLUnit.newXpathEngine();
+  }
+
+  protected String getResponse(String path, String method, String format,
+      String contentType) throws Exception {
+    return getResponse(path, method, Maps.<String, String> newHashMap(), "",
+        format, contentType);
+  }
+
+  protected String getResponse(String path, String method,
+      Map<String, String> extraParams, String format, String contentType)
+      throws Exception {
+    return getResponse(path, method, extraParams, "", format, contentType);
+  }
+
+  protected String getResponse(String path, String method, String postData,
+      String format, String contentType) throws Exception {
+    return getResponse(path, method, Maps.<String,String> newHashMap(),
+        postData, format, contentType);
+  }
+
+  protected String getResponse(String path, String method,
+      Map<String, String> extraParams, String postData, String format,
+      String contentType) throws Exception {
+    FakeHttpServletRequest req = new FakeHttpServletRequest();
+    req.setCharacterEncoding("UTF-8");
+    req.setPathInfo(path);
+    req.setParameter("format",format);
+    req.setParameter("X-HTTP-Method-Override", method);
+    req.setAttribute(AuthInfo.Attribute.SECURITY_TOKEN.getId(), 
FAKE_GADGET_TOKEN);
+    req.setContentType(contentType);
+    for (Map.Entry<String,String> entry : extraParams.entrySet()) {
+      req.setParameter(entry.getKey(), entry.getValue());
+    }
+
+    if (!("GET").equals(method) && !("HEAD").equals(method)) {
+      if (postData == null) {
+        postData = "";
+      }
+      req.setPostData(postData.getBytes());
+    }
+    req.setMethod(method);
+
+    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+    PrintWriter writer = new PrintWriter(outputStream);
+    EasyMock.expect(res.getWriter()).andReturn(writer);
+    res.setCharacterEncoding("UTF-8");
+    res.setContentType(contentType);
+    res.addHeader("Access-Control-Allow-Origin", "*");
+
+    EasyMock.replay(res);
+    servlet.service(req, res);
+    EasyMock.verify(res);
+    EasyMock.reset(res);
+
+    writer.flush();
+    return outputStream.toString();
+  }
+
+  protected JSONObject getJson(String json) throws Exception {
+    return new JSONObject(json);
+  }
+
+  /**
+   * parse entry.content xml into a Map<> struct
+   *
+   * @param str
+   *          input content string
+   * @return the map<> of <name, value> pairs from the content xml
+   * @throws javax.xml.stream.XMLStreamException
+   *           If the str is not valid xml
+   */
+  protected Map<String, String> parseXmlContent(String str)
+      throws XMLStreamException {
+    ByteArrayInputStream inStr = new ByteArrayInputStream(str.getBytes());
+    XMLInputFactory factory = XMLInputFactory.newInstance();
+    XMLStreamReader parser = factory.createXMLStreamReader(inStr);
+    Map<String, String> columns = Maps.newHashMap();
+
+    while (true) {
+      int event = parser.next();
+      if (event == XMLStreamConstants.END_DOCUMENT) {
+        parser.close();
+        break;
+      } else if (event == XMLStreamConstants.START_ELEMENT) {
+        String name = parser.getLocalName();
+        int eventType = parser.next();
+        if (eventType == XMLStreamConstants.CHARACTERS) {
+          String value = parser.getText();
+          columns.put(name, value);
+        }
+      }
+    }
+    return columns;
+  }
+
+  /**
+   * Converts a node which child nodes into a map keyed on element names
+   * containing the text inside each child node.
+   *
+   * @param n
+   *          the node to convert.
+   * @return a map keyed on element name, containing the contents of each
+   *         element.
+   */
+  protected Map<String, List<String>> childNodesToMap(Node n) {
+    Map<String, List<String>> v = Maps.newHashMap();
+    NodeList result = n.getChildNodes();
+    for (int i = 0; i < result.getLength(); i++) {
+      Node nv = result.item(i);
+      if (nv.getNodeType() == Node.ELEMENT_NODE) {
+        List<String> l = v.get(nv.getLocalName());
+        if (l == null) {
+          l = Lists.newArrayList();
+          v.put(nv.getLocalName(), l);
+        }
+        l.add(nv.getTextContent());
+      }
+    }
+    return v;
+  }
+
+  /**
+   * Converts <entry> <key>k</key> <value> <entry> <key>count</key>
+   * <value>val</value> </entry> <entry> <key>lastUpdate</key>
+   * <value>val</value> </entry> </value> </entry>
+   *
+   * To map.get("k").get("count")
+   *
+   * @param result
+   * @return
+   */
+  protected Map<String, Map<String, List<String>>> childNodesToMapofMap(
+      NodeList result) {
+    Map<String, Map<String, List<String>>> v = Maps.newHashMap();
+    for (int i = 0; i < result.getLength(); i++) {
+      Map<String, List<Node>> keyValue = childNodesToNodeMap(result.item(i));
+
+      assertEquals(2, keyValue.size());
+      assertTrue(keyValue.containsKey("key"));
+      assertTrue(keyValue.containsKey("value"));
+      Node valueNode = keyValue.get("value").get(0);
+      Node key = keyValue.get("key").get(0);
+      NodeList entryList = valueNode.getChildNodes();
+      Map<String, List<String>> pv = Maps.newHashMap();
+      v.put(key.getTextContent(), pv);
+      for (int j = 0; j < entryList.getLength(); j++) {
+        Node n = entryList.item(j);
+        if ("entry".equals(n.getNodeName())) {
+          Map<String, List<String>> ve = childNodesToMap(entryList.item(j));
+          assertTrue(ve.containsKey("key"));
+          List<String> l = pv.get(ve.get("key").get(0));
+          if ( l == null ) {
+            l = Lists.newArrayList();
+            pv.put(ve.get("key").get(0), l);
+          }
+          l.add(ve.get("value").get(0));
+        }
+      }
+    }
+    return v;
+  }
+
+  /**
+   * @param n
+   * @return
+   */
+  protected Map<String, List<Node>> childNodesToNodeMap(Node n) {
+    Map<String, List<Node>> v = Maps.newHashMap();
+    NodeList result = n.getChildNodes();
+    for (int i = 0; i < result.getLength(); i++) {
+      Node nv = result.item(i);
+      if (nv.getNodeType() == Node.ELEMENT_NODE) {
+        List<Node> l = v.get(nv.getLocalName());
+        if (l == null) {
+          l = Lists.newArrayList();
+          v.put(nv.getLocalName(), l);
+        }
+        l.add(nv);
+      }
+    }
+    return v;
+  }
+}

Added: 
shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/dataservice/integration/RestfulJsonActivityEntryTest.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/dataservice/integration/RestfulJsonActivityEntryTest.java?rev=1036980&view=auto
==============================================================================
--- 
shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/dataservice/integration/RestfulJsonActivityEntryTest.java
 (added)
+++ 
shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/dataservice/integration/RestfulJsonActivityEntryTest.java
 Fri Nov 19 18:52:36 2010
@@ -0,0 +1,148 @@
+package org.apache.shindig.extras.as.dataservice.integration;
+
+import org.apache.shindig.extras.as.core.model.ActivityEntryImpl;
+import org.apache.shindig.extras.as.core.model.ActivityObjectImpl;
+import org.apache.shindig.extras.as.opensocial.model.ActivityEntry;
+import org.apache.shindig.extras.as.opensocial.model.ActivityObject;
+import org.apache.shindig.protocol.ContentTypes;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Test;
+
+public class RestfulJsonActivityEntryTest extends 
AbstractActivityStreamsRestfulTests {
+  ActivityEntry johnsEntry;
+
+  @Before
+  public void restfulJsonActivityEntryTestBefore() throws Exception {
+    ActivityObject actor = new ActivityObjectImpl();
+    actor.setId("john.doe");
+    actor.setDisplayName("John Doe");
+    
+    ActivityObject object = new ActivityObjectImpl();
+    object.setId("myObjectId123");
+    object.setDisplayName("My Object");
+    
+    johnsEntry = new ActivityEntryImpl();
+    johnsEntry.setTitle("This is my ActivityEntry!");
+    johnsEntry.setBody("ActivityStreams are so much fun!");
+    johnsEntry.setActor(actor);
+    johnsEntry.setObject(object);
+  }
+
+  /**
+   * Expected response for an activity in json:
+   * { 'entry' : {
+   *     'title' : 'This is my ActivityEntry!',
+   *     'body' : 'ActivityStreams are so much fun!',
+   *     'actor' : {
+   *       'id' : 'john.doe',
+   *       'displayName' : 'John Doe'
+   *     },
+   *     'object' : {
+   *       'id' : 'myObjectId123',
+   *       'displayName' : 'My Object'
+   *     }
+   *   }
+   * }
+   *
+   * @throws Exception if test encounters an error
+   */
+  @Test
+  public void testGetActivityEntryJson() throws Exception {
+    String resp = 
getResponse("/activitystreams/john.doe/@self/@app/myObjectId123", "GET", null,
+        ContentTypes.OUTPUT_JSON_CONTENT_TYPE);
+    JSONObject result = getJson(resp);
+    assertActivityEntriesEqual(johnsEntry, result.getJSONObject("entry"));
+  }
+
+  /**
+   * Expected response for a list of activities in json:
+   *
+   * {
+   *  "totalResults" : 1,
+   *  "startIndex" : 0
+   *  "itemsPerPage" : 10 // Note: the js doesn't support paging. Should rest?
+   *  "entry" : [
+   *     {<entry>} // layed out like above
+   *  ]
+   * }
+   *
+   * @throws Exception if test encounters an error
+   */
+  @Test
+  public void testGetActivityEntriesJson() throws Exception {
+    String resp = getResponse("/activitystreams/john.doe/@self", "GET", null,
+        ContentTypes.OUTPUT_JSON_CONTENT_TYPE);
+    JSONObject result = getJson(resp);
+
+    assertEquals(1, result.getInt("totalResults"));
+    assertEquals(0, result.getInt("startIndex"));
+    assertActivityEntriesEqual(johnsEntry, 
result.getJSONArray("entry").getJSONObject(0));
+  }
+
+  /**
+   * Expected response for a list of activities in json:
+   *
+   * {
+   *  "totalResults" : 3,
+   *  "startIndex" : 0
+   *  "itemsPerPage" : 10 // Note: the js doesn't support paging. Should rest?
+   *  "entry" : [
+   *     {<entry>} // layed out like above, except for jane.doe
+   *  ]
+   * }
+   *
+   * @throws Exception if test encounters an error
+   */
+  @Test
+  public void testGetFriendsActivityEntriesJson() throws Exception {
+    String resp = getResponse("/activitystreams/jane.doe/@friends", "GET", 
null,
+        ContentTypes.OUTPUT_JSON_CONTENT_TYPE);
+    JSONObject result = getJson(resp);
+
+    assertEquals(1, result.getInt("totalResults"));
+    assertEquals(0, result.getInt("startIndex"));
+  }
+
+  private void assertActivityEntriesEqual(ActivityEntry entry, JSONObject 
result)
+      throws JSONException {
+    assertEquals(entry.getTitle(), result.getString("title"));
+    assertEquals(entry.getBody(), result.getString("body"));
+    assertEquals(entry.getActor().getId(), 
result.getJSONObject("actor").getString("id"));
+    assertEquals(entry.getActor().getDisplayName(), 
result.getJSONObject("actor").getString("displayName"));
+    assertEquals(entry.getObject().getId(), 
result.getJSONObject("object").getString("id"));
+    assertEquals(entry.getObject().getDisplayName(), 
result.getJSONObject("object").getString("displayName"));
+  }
+
+  @Test
+  public void testCreateActivityEntry() throws Exception {
+    String postData = "{title : 'hi mom!', body : 'and dad.', object : {id: 
'1'}}";
+    // Create the activity entry
+    getResponse("/activitystreams/john.doe/@self", "POST", postData, null,
+        ContentTypes.OUTPUT_JSON_CONTENT_TYPE);
+
+    // Verify it can be retrieved
+    String resp = getResponse("/activitystreams/john.doe/@self", "GET", null,
+        ContentTypes.OUTPUT_JSON_CONTENT_TYPE);
+    JSONObject result = getJson(resp);
+
+    assertEquals(2, result.getInt("totalResults"));
+    assertEquals(0, result.getInt("startIndex"));
+
+    JSONArray entries = result.getJSONArray("entry");
+    int newEntryIndex = 0;
+    if (entries.getJSONObject(0).getJSONObject("object").getString("id")
+        .equals("myObjectId123")) {
+      newEntryIndex = 1;
+    }
+
+    JSONObject jsonEntry = entries.getJSONObject(newEntryIndex);
+    assertEquals("hi mom!", jsonEntry.getString("title"));
+    assertEquals("and dad.", jsonEntry.getString("body"));
+    assertEquals("1", jsonEntry.getJSONObject("object").getString("id"));
+  }
+
+  // TODO: Add tests for the fields= parameter
+}

Added: 
shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/opensocial/service/ActivityStreamsHandlerTest.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/opensocial/service/ActivityStreamsHandlerTest.java?rev=1036980&view=auto
==============================================================================
--- 
shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/opensocial/service/ActivityStreamsHandlerTest.java
 (added)
+++ 
shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/opensocial/service/ActivityStreamsHandlerTest.java
 Fri Nov 19 18:52:36 2010
@@ -0,0 +1,236 @@
+/*
+ * 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.extras.as.opensocial.service;
+
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.isNull;
+
+import java.io.StringReader;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Future;
+
+import org.apache.shindig.common.EasyMockTestCase;
+import org.apache.shindig.common.testing.FakeGadgetToken;
+import org.apache.shindig.common.util.ImmediateFuture;
+import org.apache.shindig.config.ContainerConfig;
+import org.apache.shindig.config.JsonContainerConfig;
+import org.apache.shindig.expressions.Expressions;
+import org.apache.shindig.extras.as.core.model.ActivityEntryImpl;
+import org.apache.shindig.extras.as.opensocial.model.ActivityEntry;
+import org.apache.shindig.extras.as.opensocial.spi.ActivityStreamService;
+import org.apache.shindig.protocol.DefaultHandlerRegistry;
+import org.apache.shindig.protocol.HandlerExecutionListener;
+import org.apache.shindig.protocol.HandlerRegistry;
+import org.apache.shindig.protocol.ProtocolException;
+import org.apache.shindig.protocol.RestHandler;
+import org.apache.shindig.protocol.RestfulCollection;
+import org.apache.shindig.protocol.conversion.BeanJsonConverter;
+import org.apache.shindig.social.opensocial.spi.CollectionOptions;
+import org.apache.shindig.social.opensocial.spi.GroupId;
+import org.apache.shindig.social.opensocial.spi.UserId;
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
+/**
+ * Tests the ActivityStreamsHandler.
+ */
+public class ActivityStreamsHandlerTest extends EasyMockTestCase {
+  
+  private BeanJsonConverter converter;
+  
+  private ActivityStreamService service;
+  
+  private ActivityStreamsHandler handler; // TODO: Rename to 
ActivityStreamHandler
+  
+  private FakeGadgetToken token;
+  
+  private static final Set<UserId> JOHN_DOE = ImmutableSet.of(new UserId(
+      UserId.Type.userId, "john.doe"));
+  
+  protected HandlerRegistry registry;
+  protected ContainerConfig containerConfig;
+  
+  @Before
+  public void setUp() throws Exception {
+    token = new FakeGadgetToken();
+    token.setAppId("appId");
+
+    converter = mock(BeanJsonConverter.class);
+    service = mock(ActivityStreamService.class);
+
+    JSONObject config = new JSONObject('{' + ContainerConfig.DEFAULT_CONTAINER 
+ ':' +
+        "{'gadgets.container': ['default']," +
+         "'gadgets.features':{opensocial:" +
+           "{supportedFields: {activityEntry: ['id', 'title']}}" +
+         "}}}");
+
+    containerConfig = new JsonContainerConfig(config, 
Expressions.forTesting());
+    handler = new ActivityStreamsHandler(service, containerConfig);
+    registry = new DefaultHandlerRegistry(null, converter,
+        new HandlerExecutionListener.NoOpHandler());
+    registry.addHandlers(ImmutableSet.<Object>of(handler));
+  }
+  
+  /* Helper for retrieving groups. */
+  private void assertHandleGetForGroup(GroupId.Type group) throws Exception {
+    String path = "/activitystreams/john.doe/@" + group.toString();
+    RestHandler operation = registry.getRestHandler(path, "GET");
+
+    List<ActivityEntry> entries = ImmutableList.of();
+    RestfulCollection<ActivityEntry> data = new 
RestfulCollection<ActivityEntry>(entries);
+    org.easymock.EasyMock.expect(service.getActivityEntries(eq(JOHN_DOE),
+       eq(new GroupId(group, null)), (String)isNull(), 
eq(ImmutableSet.<String>of()),
+        org.easymock.EasyMock.isA(CollectionOptions.class), eq(token))).
+        andReturn(ImmediateFuture.newInstance(data));
+
+    replay();
+    assertEquals(data, operation.execute(Maps.<String, String[]>newHashMap(),
+        null, token, converter).get());
+    verify();
+    reset();
+  }
+  
+  @Test
+  public void testHandleGetAll() throws Exception {
+    assertHandleGetForGroup(GroupId.Type.all);
+  }
+
+  @Test
+  public void testHandleGetFriends() throws Exception {
+    assertHandleGetForGroup(GroupId.Type.friends);
+  }
+
+  @Test
+  public void testHandleGetSelf() throws Exception {
+    assertHandleGetForGroup(GroupId.Type.self);
+  }
+  
+  @Test
+  public void testHandleGetPlural() throws Exception {
+    String path = "/activitystreams/john.doe,jane.doe/@self/@app";
+    RestHandler operation = registry.getRestHandler(path, "GET");
+
+    List<ActivityEntry> entries = ImmutableList.of();
+    RestfulCollection<ActivityEntry> data = new 
RestfulCollection<ActivityEntry>(entries);
+    Set<UserId> userIdSet = Sets.newLinkedHashSet(JOHN_DOE);
+    userIdSet.add(new UserId(UserId.Type.userId, "jane.doe"));
+    org.easymock.EasyMock.expect(service.getActivityEntries(eq(userIdSet),
+        eq(new GroupId(GroupId.Type.self, null)), 
eq("appId"),eq(ImmutableSet.<String>of()),
+        org.easymock.EasyMock.isA((CollectionOptions.class)), 
eq(token))).andReturn(
+          ImmediateFuture.newInstance(data));
+
+    replay();
+    assertEquals(data, operation.execute(Maps.<String, String[]>newHashMap(),
+        null, token, converter).get());
+    verify();
+    reset();
+  }
+  
+  @Test
+  public void testHandleGetActivityEntryById() throws Exception {
+    String path = "/activitystreams/john.doe/@friends/@app/myObjectId123";  // 
TODO: change id=1 in DB for consistency
+    RestHandler operation = registry.getRestHandler(path, "GET");
+
+    ActivityEntry entry = new ActivityEntryImpl();
+    
org.easymock.EasyMock.expect(service.getActivityEntry(eq(JOHN_DOE.iterator().next()),
+        eq(new GroupId(GroupId.Type.friends, null)),
+        eq("appId"), eq(ImmutableSet.<String>of()), eq("myObjectId123"), 
eq(token))).andReturn(
+        ImmediateFuture.newInstance(entry));
+
+    replay();
+    assertEquals(entry, operation.execute(Maps.<String, String[]>newHashMap(),
+        null, token, converter).get());
+    verify();
+    reset();
+  }
+  
+  /* Helper for testing PUT and POST */
+  private Future<?> setupBodyRequest(String method) throws ProtocolException {
+    String jsonActivityEntry = "{title: hi mom!, etc etc}";
+
+    String path = "/activitystreams/john.doe/@self/@app";
+    RestHandler operation = registry.getRestHandler(path, method);
+
+    ActivityEntry entry = new ActivityEntryImpl();
+    
org.easymock.EasyMock.expect(converter.convertToObject(eq(jsonActivityEntry), 
eq(ActivityEntry.class)))
+        .andReturn(entry);
+
+    
org.easymock.EasyMock.expect(service.createActivityEntry(eq(JOHN_DOE.iterator().next()),
+        eq(new GroupId(GroupId.Type.self, null)), eq("appId"), 
eq(ImmutableSet.<String>of()),
+        eq(entry), eq(token))).andReturn(ImmediateFuture.newInstance((Void) 
null));
+    replay();
+
+    return operation.execute(Maps.<String, String[]>newHashMap(),
+        new StringReader(jsonActivityEntry), token, converter);
+  }
+  
+  @Test
+  public void testHandlePost() throws Exception {
+    Future<?> future = setupBodyRequest("POST");
+    assertNull(future.get());
+    verify();
+    reset();
+  }
+
+  @Test
+  public void testHandlePut() throws Exception {
+    Future<?> future = setupBodyRequest("PUT");
+    assertNull(future.get());
+    verify();
+    reset();
+  }
+  
+  @Test
+  public void testHandleDelete() throws Exception {
+    String path = "/activitystreams/john.doe/@self/@app/myObjectId123";
+    RestHandler operation = registry.getRestHandler(path, "DELETE");
+
+    
org.easymock.EasyMock.expect(service.deleteActivityEntries(eq(JOHN_DOE.iterator().next()),
+        eq(new GroupId(GroupId.Type.self, null)), eq("appId"), 
eq(ImmutableSet.of("myObjectId123")),
+        eq(token))).andReturn(ImmediateFuture.newInstance((Void) null));
+
+    replay();
+    assertNull(operation.execute(Maps.<String, String[]>newHashMap(), null,
+        token, converter).get());
+    verify();
+    reset();
+  }
+  
+  @Test
+  public void testHandleGetSupportedFields() throws Exception {
+    String path = "/activitystreams/@supportedFields";
+    RestHandler operation = registry.getRestHandler(path, "GET");
+
+    replay();
+    @SuppressWarnings("unchecked")
+    List<Object> received = (List<Object>) operation.execute(Maps.<String, 
String[]>newHashMap(),
+        null, token, converter).get();
+    assertEquals(2, received.size());
+    assertEquals("id", received.get(0).toString());
+    assertEquals("title", received.get(1).toString());
+
+    verify();
+  }
+}

Added: 
shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/sample/spi/ActivityStreamsJsonDbServiceTest.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/sample/spi/ActivityStreamsJsonDbServiceTest.java?rev=1036980&view=auto
==============================================================================
--- 
shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/sample/spi/ActivityStreamsJsonDbServiceTest.java
 (added)
+++ 
shindig/trunk/extras/src/test/java/org/apache/shindig/extras/as/sample/spi/ActivityStreamsJsonDbServiceTest.java
 Fri Nov 19 18:52:36 2010
@@ -0,0 +1,82 @@
+package org.apache.shindig.extras.as.sample.spi;
+
+import java.util.Collections;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.shindig.common.testing.FakeGadgetToken;
+import org.apache.shindig.extras.as.opensocial.model.ActivityEntry;
+import org.apache.shindig.extras.as.sample.ActivityStreamsJsonDbService;
+import org.apache.shindig.protocol.ProtocolException;
+import org.apache.shindig.protocol.RestfulCollection;
+import org.apache.shindig.social.SocialApiTestsGuiceModule;
+import org.apache.shindig.social.opensocial.spi.GroupId;
+import org.apache.shindig.social.opensocial.spi.UserId;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
+/**
+ * Tests the sample ActivityStreamsJsonDbService.
+ */
+public class ActivityStreamsJsonDbServiceTest extends Assert {
+  private ActivityStreamsJsonDbService db;
+
+  private static final UserId CANON_USER = new UserId(UserId.Type.userId, 
"canonical");
+  private static final UserId JOHN_DOE = new UserId(UserId.Type.userId, 
"john.doe");
+
+  private static final GroupId SELF_GROUP = new GroupId(GroupId.Type.self, 
null);
+  private static final String APP_ID = "1";
+  
+  @Before
+  public void setUp() throws Exception {
+    Injector injector = Guice.createInjector(new SocialApiTestsGuiceModule());
+    db = injector.getInstance(ActivityStreamsJsonDbService.class);
+  }
+
+  @Test
+  public void testGetExpectedActivityEntries() throws Exception {
+    RestfulCollection<ActivityEntry> responseItem = db.getActivityEntries(
+        ImmutableSet.of(JOHN_DOE), SELF_GROUP, APP_ID, 
Collections.<String>emptySet(), null,
+        new FakeGadgetToken()).get();
+    assertSame(1, responseItem.getTotalResults());
+  }
+
+  @Test
+  public void testGetExpectedActivityEntriesForPlural() throws Exception {
+    RestfulCollection<ActivityEntry> responseItem = db.getActivityEntries(
+        ImmutableSet.of(CANON_USER, JOHN_DOE), SELF_GROUP, APP_ID, 
Collections.<String>emptySet(), null,
+        new FakeGadgetToken()).get();
+    assertSame(1, responseItem.getTotalResults());
+  }
+
+  @Test
+  public void testGetExpectedActivityEntry() throws Exception {
+    ActivityEntry entry = db.getActivityEntry(JOHN_DOE, SELF_GROUP, APP_ID,
+        ImmutableSet.of("body"), "myObjectId123", new FakeGadgetToken()).get();
+    assertNotNull(entry);
+    // Check that some fields are fetched and others are not
+    assertNotNull(entry.getBody());
+    assertNull(entry.getPostedTime());
+  }
+
+  @Test
+  public void testDeleteExpectedActivityEntry() throws Exception {
+    db.deleteActivityEntries(JOHN_DOE, SELF_GROUP, APP_ID, 
ImmutableSet.of(APP_ID),
+        new FakeGadgetToken());
+
+    // Try to fetch the activity
+    try {
+      db.getActivityEntry(
+          JOHN_DOE, SELF_GROUP, APP_ID,
+          ImmutableSet.of("body"), APP_ID, new FakeGadgetToken()).get();
+      fail();
+    } catch (ProtocolException sse) {
+      assertEquals(HttpServletResponse.SC_BAD_REQUEST, sse.getCode());
+    }
+  }
+}


Reply via email to