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

svn commit: r710100 - in /incubator/shindig/trunk: ./ java/social-api/ java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/

Author: ieb
Date: Mon Nov  3 08:40:20 2008
New Revision: 710100

URL: http://svn.apache.org/viewvc?rev=710100&view=rev
Log:
SHINDIG-562

       Converted the JSON tests into XML tests in preparation for validating the implementaiton, however I think there are some
       areas where the specification is not complete, and there are others area where I can see the current implementation will
       not produce valid output. Next step is to get the converter conforming to the unit tests, unfortunately this will break
       other xml tests that are already passing.

Added:
    incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulXmlActivityDisabled.java
    incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulXmlDataDisabled.java
    incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulXmlPeopleDisabled.java
Modified:
    incubator/shindig/trunk/java/social-api/pom.xml
    incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/AbstractLargeRestfulTests.java
    incubator/shindig/trunk/pom.xml

Modified: incubator/shindig/trunk/java/social-api/pom.xml
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/pom.xml?rev=710100&r1=710099&r2=710100&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/pom.xml (original)
+++ incubator/shindig/trunk/java/social-api/pom.xml Mon Nov  3 08:40:20 2008
@@ -131,6 +131,10 @@
         <groupId>xpp3</groupId>
         <artifactId>xpp3</artifactId>
     </dependency>
-    
+    <dependency>
+        <groupId>woodstox</groupId>
+        <artifactId>wstx</artifactId>
+        <scope>test</scope>
+    </dependency>
   </dependencies>
 </project>

Modified: incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/AbstractLargeRestfulTests.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/AbstractLargeRestfulTests.java?rev=710100&r1=710099&r2=710100&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/AbstractLargeRestfulTests.java (original)
+++ incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/AbstractLargeRestfulTests.java Mon Nov  3 08:40:20 2008
@@ -17,6 +17,12 @@
  */
 package org.apache.shindig.social.dataservice.integration;
 
+import com.google.common.collect.Maps;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
+import junit.framework.TestCase;
+
 import org.apache.shindig.common.testing.FakeGadgetToken;
 import org.apache.shindig.social.SocialApiTestsGuiceModule;
 import org.apache.shindig.social.core.util.BeanJsonConverter;
@@ -26,21 +32,22 @@
 import org.apache.shindig.social.opensocial.service.DataServiceServlet;
 import org.apache.shindig.social.opensocial.service.HandlerDispatcher;
 
-import com.google.common.collect.Maps;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-
-import junit.framework.TestCase;
 import org.easymock.classextension.EasyMock;
 import org.json.JSONObject;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Vector;
+
 import javax.servlet.ServletInputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -168,9 +175,99 @@
           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 = new HashMap<String, List<String>>();
+    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 = new ArrayList<String>();
+          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 = new HashMap<String, Map<String, List<String>>>();
+    for ( int i = 0; i < 3; i++ ) {
+      Node entry = result.item(i);
+      NodeList keyValue = entry.getChildNodes();
+      assertEquals(2, keyValue.getLength());
+      Node key = keyValue.item(0);
+      Node value = keyValue.item(1);
+      if ( "key".equals(keyValue.item(1).getNodeName()) ) {
+        key = value;
+        value = keyValue.item(0);
+      }      
+      NodeList entries = value.getChildNodes();
+      for ( int j = 0; j < entries.getLength(); j++) {
+        Map<String, List<String>> ve = childNodesToMap(entries.item(j));
+        assertTrue(ve.containsKey("key"));
+        v.put(key.getTextContent(), ve);
+      }
+    }
+    return v;
+  }
+  
+  
+  /**
+   * @param personNode
+   * @return
+   */
+  protected Map<String, List<Node>> childNodesToNodeMap(Node n) {
+    Map<String, List<Node>> v = new HashMap<String, List<Node>>();
+    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 = new ArrayList<Node>();
+          v.put(nv.getLocalName(),l);
+        }
+        l.add(nv);
+      }
+    }
+    return v;
+  }
+
 
 }

Added: incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulXmlActivityDisabled.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulXmlActivityDisabled.java?rev=710100&view=auto
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulXmlActivityDisabled.java (added)
+++ incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulXmlActivityDisabled.java Mon Nov  3 08:40:20 2008
@@ -0,0 +1,168 @@
+/*
+ * 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.social.dataservice.integration;
+
+import org.apache.shindig.social.core.model.ActivityImpl;
+import org.apache.shindig.social.opensocial.model.Activity;
+
+import org.junit.Test;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+import java.io.StringReader;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathFactory;
+
+public class RestfulXmlActivityDisabled extends AbstractLargeRestfulTests {
+  Activity johnsActivity;
+  private XPathFactory xpathFactory;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    johnsActivity = new ActivityImpl("1", "john.doe");
+    johnsActivity.setTitle("yellow");
+    johnsActivity.setBody("what a color!");
+
+    xpathFactory = XPathFactory.newInstance();
+
+  }
+
+  /**
+   * Expected response for an activity in xml: <map> <entry> <key>entry</key>
+   * <value> <id>1</id> <userId>john.doe</userId> <title>yellow</title>
+   * <body>what a color!</body> </value> </entry> </map>
+   *
+   * @throws Exception
+   *           if test encounters an error
+   */
+  @Test
+  public void testGetActivityJson() throws Exception {
+    String resp = getResponse("/activities/john.doe/@self/@app/1", "GET",
+        "xml", "application/xml");
+    InputSource source = new InputSource(new StringReader(resp));
+    XPath xp = xpathFactory.newXPath();
+    NodeList result = (NodeList) xp.evaluate("/response/activity", source,
+        XPathConstants.NODESET);
+    assertEquals(1, result.getLength());
+    Node n = result.item(0);
+
+    Map<String, List<String>> v = childNodesToMap(n);
+
+    assertEquals(4, v.size());
+    assertActivitiesEqual(johnsActivity, v);
+  }
+
+  /**
+   * 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" : [ {<activity>} // layed out
+   * like above ] }
+   *
+   * @throws Exception
+   *           if test encounters an error
+   */
+  @Test
+  public void testGetActivitiesJson() throws Exception {
+    String resp = getResponse("/activities/john.doe/@self", "GET", "xml",
+        "application/xml");
+    System.err.println("Got " + resp);
+    XPath xp = xpathFactory.newXPath();
+    assertEquals("0", xp.evaluate("/response/startIndex", new InputSource(
+        new StringReader(resp))));
+    assertEquals("1", xp.evaluate("/response/totalResults", new InputSource(
+        new StringReader(resp))));
+    NodeList nl = (NodeList) xp.evaluate("/response/entry", new InputSource(
+        new StringReader(resp)), XPathConstants.NODESET);
+    assertEquals(1, nl.getLength());
+
+    assertActivitiesEqual(johnsActivity, childNodesToMap(nl.item(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" : [ {<activity>} // layed out
+   * like above, except for jane.doe ] }
+   *
+   * @throws Exception
+   *           if test encounters an error
+   */
+  @Test
+  public void testGetFriendsActivitiesJson() throws Exception {
+    String resp = getResponse("/activities/john.doe/@friends", "GET", "xml",
+        "application/xml");
+    System.err.println("Got " + resp);
+
+    XPath xp = xpathFactory.newXPath();
+    assertEquals("0", xp.evaluate("/response/startIndex", new InputSource(
+        new StringReader(resp))));
+    assertEquals("2", xp.evaluate("/response/totalResults", new InputSource(
+        new StringReader(resp))));
+    NodeList nl = (NodeList) xp.evaluate("/response/entry", new InputSource(
+        new StringReader(resp)), XPathConstants.NODESET);
+    assertEquals(2, nl.getLength());
+
+  }
+
+  private void assertActivitiesEqual(Activity activity,
+      Map<String, List<String>> result) {
+    assertEquals(activity.getId(), result.get("id").get(0));
+    assertEquals(activity.getUserId(), result.get("userId").get(0));
+    assertEquals(activity.getTitle(), result.get("title").get(0));
+    assertEquals(activity.getBody(), result.get("body").get(0));
+  }
+
+  @Test
+  public void testCreateActivity() throws Exception {
+    String postData = "{title : 'hi mom!', body : 'and dad.'}";
+    String createResponse = getResponse("/activities/john.doe/@self", "POST",
+        postData, "xml", "application/xml");
+    System.err.println("Got " + createResponse);
+
+    String resp = getResponse("/activities/john.doe/@self", "GET", "xml",
+        "application/xml");
+    System.err.println("Got " + resp);
+
+    XPath xp = xpathFactory.newXPath();
+    assertEquals("0", xp.evaluate("/response/startIndex", new InputSource(
+        new StringReader(resp))));
+    assertEquals("2", xp.evaluate("/response/totalResults", new InputSource(
+        new StringReader(resp))));
+    NodeList nl = (NodeList) xp.evaluate("/response/entry", new InputSource(
+        new StringReader(resp)), XPathConstants.NODESET);
+    assertEquals(2, nl.getLength());
+
+    Map<String, List<String>> v = childNodesToMap(nl.item(0));
+    if (v.containsKey("id")) {
+      v = childNodesToMap(nl.item(1));
+    }
+
+    assertEquals("hi mom!", v.get("title").get(0));
+    assertEquals("and dad.", v.get("body").get(0));
+  }
+
+  // TODO: Add tests for the fields= parameter
+}
\ No newline at end of file

Added: incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulXmlDataDisabled.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulXmlDataDisabled.java?rev=710100&view=auto
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulXmlDataDisabled.java (added)
+++ incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulXmlDataDisabled.java Mon Nov  3 08:40:20 2008
@@ -0,0 +1,237 @@
+/*
+ * 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.social.dataservice.integration;
+
+import com.google.common.collect.Maps;
+
+import org.junit.Test;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+import java.io.StringReader;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathFactory;
+
+public class RestfulXmlDataDisabled extends AbstractLargeRestfulTests {
+
+  private XPathFactory xpathFactory;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    xpathFactory = XPathFactory.newInstance();
+
+  }
+
+  /**
+   * Expected response for app data in json:
+   *
+   * {
+   * "entry" : {
+   * "jane.doe" : {"count" : "7"},
+   * "george.doe" : {"count" : "2"},
+   * "maija.m" : {}, // TODO: Should this entry really be included if she
+   * doesn't have any data? } }
+   *
+   * @throws Exception
+   *           if test encounters an error
+   */
+  @Test
+  public void testGetFriendsAppDataJson() throws Exception {
+    // app id is mocked out
+    Map<String, String> extraParams = Maps.newHashMap();
+    extraParams.put("fields", "count");
+    String resp = getResponse("/appdata/john.doe/@friends/app", "GET",
+        extraParams, "xml", "application/xml");
+
+    XPath xp = xpathFactory.newXPath();
+    NodeList result = (NodeList) xp.evaluate("/appdata/entry", new InputSource(
+        new StringReader(resp)), XPathConstants.NODESET);
+    assertEquals(3, result.getLength());
+
+    Map<String, Map<String, List<String>>> v = childNodesToMapofMap(result);
+
+    assertEquals(3, v.size());
+    assertTrue(v.containsKey("jane.doe"));
+    assertTrue(v.containsKey("george.doe"));
+    assertTrue(v.containsKey("maija.m"));
+
+    assertEquals(1, v.get("jane.doe").size());
+    assertEquals(1, v.get("george.doe").size());
+    assertEquals(0, v.get("maija.m").size());
+
+    assertEquals("7", v.get("jane.doe").get("count").get(0));
+    assertEquals("2", v.get("george.doe").get("count").get(0));
+  }
+
+  /**
+   * Expected response for app data in json:
+   *
+   * { "entry" : {
+   * "john.doe" : {"count" : "0"}, } }
+   *
+   * @throws Exception
+   *           if test encounters an error
+   */
+  @Test
+  public void testGetSelfAppDataJson() throws Exception {
+    // app id is mocked out
+    Map<String, String> extraParams = Maps.newHashMap();
+    extraParams.put("fields", null);
+    String resp = getResponse("/appdata/john.doe/@self/app", "GET",
+        extraParams, "xml", "application/xml");
+
+    XPath xp = xpathFactory.newXPath();
+    NodeList result = (NodeList) xp.evaluate("/appdata/entry", new InputSource(
+        new StringReader(resp)), XPathConstants.NODESET);
+
+    Map<String, Map<String, List<String>>> v = childNodesToMapofMap(result);
+
+    assertEquals(1, v.size());
+    assertTrue(v.containsKey("john.doe"));
+
+    assertEquals(1, v.get("john.doe").size());
+
+    assertEquals("0", v.get("john.doe").get("count").get(0));
+
+  }
+
+  /**
+   * Expected response for app data in json:
+   *
+   * { "entry" : { "john.doe" : {"count" : "0"}, } }
+   *
+   * @throws Exception
+   *           if test encounters an error
+   */
+  @Test
+  public void testGetSelfAppDataJsonWithKey() throws Exception {
+    // app id is mocked out
+    Map<String, String> extraParams = Maps.newHashMap();
+    extraParams.put("fields", "count");
+    String resp = getResponse("/appdata/john.doe/@self/app", "GET",
+        extraParams, "xml", "application/xml");
+
+    XPath xp = xpathFactory.newXPath();
+    NodeList result = (NodeList) xp.evaluate("/appdata/entry", new InputSource(
+        new StringReader(resp)), XPathConstants.NODESET);
+
+    Map<String, Map<String, List<String>>> v = childNodesToMapofMap(result);
+
+    assertEquals(1, v.size());
+    assertTrue(v.containsKey("john.doe"));
+
+    assertEquals(1, v.get("john.doe").size());
+
+    assertEquals("0", v.get("john.doe").get("count").get(0));
+  }
+
+  /**
+   * Expected response for app data in json with non-existant key: TODO: Double
+   * check this output with the spec
+   *
+   * { "entry" : { "john.doe" : {}, } }
+   *
+   * @throws Exception
+   *           if test encounters an error
+   */
+  @Test
+  public void testGetSelfAppDataJsonWithInvalidKeys() throws Exception {
+    // app id is mocked out
+    Map<String, String> extraParams = Maps.newHashMap();
+    extraParams.put("fields", "peabody");
+    String resp = getResponse("/appdata/john.doe/@self/app", "GET",
+        extraParams, "xml", "application/xml");
+
+    XPath xp = xpathFactory.newXPath();
+    NodeList result = (NodeList) xp.evaluate("/appdata/entry", new InputSource(
+        new StringReader(resp)), XPathConstants.NODESET);
+
+    Map<String, Map<String, List<String>>> v = childNodesToMapofMap(result);
+
+    assertEquals(1, v.size());
+    assertTrue(v.containsKey("john.doe"));
+
+    assertEquals(0, v.get("john.doe").size());
+  }
+
+  @Test
+  public void testDeleteAppData() throws Exception {
+    assertCount("0");
+
+    // With the wrong field
+    Map<String, String> extraParams = Maps.newHashMap();
+    extraParams.put("fields", "peabody");
+    getResponse("/appdata/john.doe/@self/app", "DELETE", extraParams, "xml",
+        "application/xml");
+
+    assertCount("0");
+
+    // should be xml ?
+    extraParams.put("fields", "count");
+    getResponse("/appdata/john.doe/@self/app", "DELETE", extraParams, "xml",
+        "application/xml");
+
+    assertCount(null);
+  }
+
+  @Test
+  public void testUpdateAppData() throws Exception {
+    assertCount("0");
+
+    Map<String, String> extraParams = Maps.newHashMap();
+    extraParams.put("fields", "count");
+    // should be xml ?
+    String postData = "{count : 5}";
+    getResponse("/appdata/john.doe/@self/app", "POST", extraParams, postData,
+        "xml", "application/xml");
+
+    assertCount("5");
+  }
+
+  private void assertCount(String expectedCount) throws Exception {
+    String resp = getResponse("/appdata/john.doe/@self/app", "GET", "xml",
+        "application/xml");
+
+    XPath xp = xpathFactory.newXPath();
+    NodeList result = (NodeList) xp.evaluate("/appdata/entry", new InputSource(
+        new StringReader(resp)), XPathConstants.NODESET);
+
+    Map<String, Map<String, List<String>>> v = childNodesToMapofMap(result);
+
+    assertEquals(1, v.size());
+    assertTrue(v.containsKey("john.doe"));
+
+    if (expectedCount != null) {
+      assertEquals(1, v.get("john.doe").size());
+
+      assertEquals(String.valueOf(expectedCount), v.get("john.doe")
+          .get("count").get(0));
+    } else {
+      assertEquals(0, v.get("john.doe").size());
+
+    }
+  }
+
+  // TODO: support for indexBy??
+
+}
\ No newline at end of file

Added: incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulXmlPeopleDisabled.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulXmlPeopleDisabled.java?rev=710100&view=auto
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulXmlPeopleDisabled.java (added)
+++ incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/RestfulXmlPeopleDisabled.java Mon Nov  3 08:40:20 2008
@@ -0,0 +1,568 @@
+/*
+ * 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.social.dataservice.integration;
+
+import org.apache.shindig.social.core.model.AddressImpl;
+import org.apache.shindig.social.core.model.BodyTypeImpl;
+import org.apache.shindig.social.core.model.EnumImpl;
+import org.apache.shindig.social.core.model.ListFieldImpl;
+import org.apache.shindig.social.core.model.NameImpl;
+import org.apache.shindig.social.core.model.OrganizationImpl;
+import org.apache.shindig.social.core.model.PersonImpl;
+import org.apache.shindig.social.core.model.UrlImpl;
+import org.apache.shindig.social.opensocial.model.Address;
+import org.apache.shindig.social.opensocial.model.BodyType;
+import org.apache.shindig.social.opensocial.model.Enum;
+import org.apache.shindig.social.opensocial.model.ListField;
+import org.apache.shindig.social.opensocial.model.Name;
+import org.apache.shindig.social.opensocial.model.Organization;
+import org.apache.shindig.social.opensocial.model.Person;
+import org.apache.shindig.social.opensocial.model.Url;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.junit.Test;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+import java.io.StringReader;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathFactory;
+
+public class RestfulXmlPeopleDisabled extends AbstractLargeRestfulTests {
+  private Person canonical;
+  private XPathFactory xpathFactory;
+
+  protected void setUp() throws Exception {
+    super.setUp();
+    xpathFactory = XPathFactory.newInstance();
+
+    NameImpl name = new NameImpl("Sir Shin H. Digg Social Butterfly");
+    name.setAdditionalName("H");
+    name.setFamilyName("Digg");
+    name.setGivenName("Shin");
+    name.setHonorificPrefix("Sir");
+    name.setHonorificSuffix("Social Butterfly");
+    canonical = new PersonImpl("canonical", "Shin Digg", name);
+
+    canonical.setAboutMe("I have an example of every piece of data");
+    canonical.setActivities(Lists.newArrayList("Coding Shindig"));
+
+    Address address = new AddressImpl(
+        "PoBox 3565, 1 OpenStandards Way, Apache, CA");
+    address.setCountry("US");
+    address.setLatitude(28.3043F);
+    address.setLongitude(143.0859F);
+    address.setLocality("who knows");
+    address.setPostalCode("12345");
+    address.setRegion("Apache, CA");
+    address.setStreetAddress("1 OpenStandards Way");
+    address.setType("home");
+    address.setFormatted("PoBox 3565, 1 OpenStandards Way, Apache, CA");
+    canonical.setAddresses(Lists.newArrayList(address));
+
+    canonical.setAge(33);
+    BodyTypeImpl bodyType = new BodyTypeImpl();
+    bodyType.setBuild("svelte");
+    bodyType.setEyeColor("blue");
+    bodyType.setHairColor("black");
+    bodyType.setHeight("1.84M");
+    bodyType.setWeight("184lbs");
+    canonical.setBodyType(bodyType);
+
+    canonical.setBooks(Lists.newArrayList("The Cathedral & the Bazaar",
+        "Catch 22"));
+    canonical.setCars(Lists.newArrayList("beetle", "prius"));
+    canonical.setChildren("3");
+    AddressImpl location = new AddressImpl();
+    location.setLatitude(48.858193F);
+    location.setLongitude(2.29419F);
+    canonical.setCurrentLocation(location);
+
+    canonical.setBirthday(new Date());
+    canonical.setDrinker(new EnumImpl<Enum.Drinker>(Enum.Drinker.SOCIALLY));
+    ListField email = new ListFieldImpl("work",
+        "shindig-dev@incubator.apache.org");
+    canonical.setEmails(Lists.newArrayList(email));
+
+    canonical.setEthnicity("developer");
+    canonical.setFashion("t-shirts");
+    canonical.setFood(Lists.newArrayList("sushi", "burgers"));
+    canonical.setGender(Person.Gender.male);
+    canonical.setHappiestWhen("coding");
+    canonical.setHasApp(true);
+    canonical
+        .setHeroes(Lists.newArrayList("Doug Crockford", "Charles Babbage"));
+    canonical.setHumor("none to speak of");
+    canonical.setInterests(Lists.newArrayList("PHP", "Java"));
+    canonical.setJobInterests("will work for beer");
+
+    Organization job1 = new OrganizationImpl();
+    job1.setAddress(new AddressImpl("1 Shindig Drive"));
+    job1.setDescription("lots of coding");
+    job1.setEndDate(new Date());
+    job1.setField("Software Engineering");
+    job1.setName("Apache.com");
+    job1.setSalary("$1000000000");
+    job1.setStartDate(new Date());
+    job1.setSubField("Development");
+    job1.setTitle("Grand PooBah");
+    job1.setWebpage("http://incubator.apache.org/projects/shindig.html");
+    job1.setType("job");
+
+    Organization job2 = new OrganizationImpl();
+    job2.setAddress(new AddressImpl("1 Skid Row"));
+    job2.setDescription("");
+    job2.setEndDate(new Date());
+    job2.setField("College");
+    job2.setName("School of hard Knocks");
+    job2.setSalary("$100");
+    job2.setStartDate(new Date());
+    job2.setSubField("Lab Tech");
+    job2.setTitle("Gopher");
+    job2.setWebpage("");
+    job2.setType("job");
+
+    canonical.setOrganizations(Lists.newArrayList(job1, job2));
+
+    canonical.setUpdated(new Date());
+    canonical.setLanguagesSpoken(Lists.newArrayList("English", "Dutch",
+        "Esperanto"));
+    canonical.setLivingArrangement("in a house");
+    Enum<Enum.LookingFor> lookingForRandom = new EnumImpl<Enum.LookingFor>(
+        Enum.LookingFor.RANDOM, "Random");
+    Enum<Enum.LookingFor> lookingForNetworking = new EnumImpl<Enum.LookingFor>(
+        Enum.LookingFor.NETWORKING, "Networking");
+    canonical.setLookingFor(Lists.newArrayList(lookingForRandom,
+        lookingForNetworking));
+    canonical.setMovies(Lists.newArrayList("Iron Man", "Nosferatu"));
+    canonical.setMusic(Lists.newArrayList("Chieftains", "Beck"));
+    canonical.setNetworkPresence(new EnumImpl<Enum.NetworkPresence>(
+        Enum.NetworkPresence.ONLINE));
+    canonical.setNickname("diggy");
+    canonical.setPets("dog,cat");
+    canonical.setPhoneNumbers(Lists.<ListField> newArrayList(new ListFieldImpl(
+        "work", "111-111-111"), new ListFieldImpl("mobile", "999-999-999")));
+
+    canonical.setPoliticalViews("open leaning");
+    canonical.setProfileSong(new UrlImpl(
+        "http://www.example.org/songs/OnlyTheLonely.mp3", "Feelin' blue",
+        "road"));
+    canonical.setProfileVideo(new UrlImpl(
+        "http://www.example.org/videos/Thriller.flv", "Thriller", "video"));
+
+    canonical.setQuotes(Lists.newArrayList("I am therfore I code", "Doh!"));
+    canonical.setRelationshipStatus("married to my job");
+    canonical.setReligion("druidic");
+    canonical.setRomance("twice a year");
+    canonical.setScaredOf("COBOL");
+    canonical.setSexualOrientation("north");
+    canonical.setSmoker(new EnumImpl<Enum.Smoker>(Enum.Smoker.NO));
+    canonical.setSports(Lists.newArrayList("frisbee", "rugby"));
+    canonical.setStatus("happy");
+    canonical.setTags(Lists.newArrayList("C#", "JSON", "template"));
+    canonical.setThumbnailUrl("http://www.example.org/pic/?id=1");
+    canonical.setUtcOffset(-8L);
+    canonical.setTurnOffs(Lists.newArrayList("lack of unit tests", "cabbage"));
+    canonical.setTurnOns(Lists.newArrayList("well document code"));
+    canonical.setTvShows(Lists.newArrayList("House", "Battlestar Galactica"));
+
+    canonical
+        .setUrls(Lists.<Url> newArrayList(new UrlImpl(
+            "http://www.example.org/?id=1", "my profile", "Profile"),
+            new UrlImpl("http://www.example.org/pic/?id=1",
+                "my awesome picture", "Thumbnail")));
+
+  }
+
+  /**
+   * Expected response for john.doe's json:
+   *
+   * { 'entry' :
+   * { 'id' : 'john.doe',
+   * 'name' : {'unstructured' : 'John Doe'},
+   * 'phoneNumbers' : [ { 'number' : '+33H000000000', 'type' : 'home'}, ],
+   * 'addresses' : [ {'unstructuredAddress' : 'My home address'} ],
+   * 'emails' : [
+   *    { 'value' : 'john.doe@work.bar', 'type' : 'work'}, ]
+   *
+   * ... etc, etc for all fields in the person object } } TODO: Finish up this
+   * test and make refactor so that it is easier to read
+   *
+   * @throws Exception
+   *           if test encounters an error
+   */
+  @Test
+  public void testGetPersonJson() throws Exception {
+    // TODO(doll): Test all of the date fields
+
+    Map<String, String> extraParams = Maps.newHashMap();
+    String allFieldsParam = "";
+    for (String allField : Person.Field.ALL_FIELDS) {
+      allFieldsParam += allField + ",";
+    }
+    extraParams.put("fields", allFieldsParam);
+
+    // Currently, for Shindig {pid}/@all/{uid} == {uid}/@self
+    String resp = getResponse("/people/canonical/@self", "GET", extraParams,
+        "xml", "application/xml");
+
+    XPath xp = xpathFactory.newXPath();
+    NodeList resultNodeList = (NodeList) xp.evaluate("/response/entry",
+        new InputSource(new StringReader(resp)), XPathConstants.NODESET);
+    assertEquals(1, resultNodeList.getLength());
+
+    Node personNode = resultNodeList.item(0);
+
+    Map<String, List<Node>> childNodeMap = childNodesToNodeMap(personNode);
+    Map<String, List<String>> result = childNodesToMap(personNode);
+
+    assertStringField(result, canonical.getAboutMe(), Person.Field.ABOUT_ME);
+    assertStringListField(result, canonical.getActivities(),
+        Person.Field.ACTIVITIES);
+
+    List<Node> addressNodes = childNodeMap.get(Person.Field.ADDRESSES
+        .toString());
+    assertEquals(addressNodes.size(), canonical.getAddresses().size());
+    for (int i = 0; i < addressNodes.size(); i++) {
+      assertAddressField(canonical.getAddresses().get(i),
+          childNodesToMap(addressNodes.get(i)));
+    }
+
+    assertEquals(canonical.getAge().intValue(), Integer.parseInt(result.get(
+        Person.Field.AGE.toString()).get(0)));
+
+    Map<String, List<String>> bodyMap = childNodesToMap(childNodeMap.get(
+        Person.Field.BODY_TYPE.toString()).get(0));
+    BodyType body = canonical.getBodyType();
+
+    assertStringField(bodyMap, body.getBuild(), BodyType.Field.BUILD);
+    assertStringField(bodyMap, body.getEyeColor(), BodyType.Field.EYE_COLOR);
+    assertStringField(bodyMap, body.getHairColor(), BodyType.Field.HAIR_COLOR);
+    assertStringField(bodyMap, body.getHeight(), BodyType.Field.HEIGHT);
+    assertStringField(bodyMap, body.getWeight(), BodyType.Field.WEIGHT);
+
+    assertStringListField(result, canonical.getBooks(), Person.Field.BOOKS);
+    assertStringListField(result, canonical.getCars(), Person.Field.CARS);
+    assertStringField(result, canonical.getChildren(), Person.Field.CHILDREN);
+
+    Map<String, List<String>> currentLocation = childNodesToMap(childNodeMap
+        .get(Person.Field.CURRENT_LOCATION.toString()).get(0));
+    assertFloatField(currentLocation, canonical.getCurrentLocation()
+        .getLatitude(), Address.Field.LATITUDE);
+    assertFloatField(currentLocation, canonical.getCurrentLocation()
+        .getLongitude(), Address.Field.LONGITUDE);
+
+    assertStringField(result, canonical.getDisplayName(),
+        Person.Field.DISPLAY_NAME);
+
+    // assertLongField(result, canonical.getBirthday().getTime(),
+    // Person.Field.BIRTHDAY);
+    // assertEnumField(result, canonical.getDrinker(), Person.Field.DRINKER);
+
+    List<Node> emailArray = childNodeMap.get(Person.Field.EMAILS.toString());
+    assertEquals(1, emailArray.size());
+
+    for (int i = 0; i < canonical.getEmails().size(); i++) {
+      ListField expectedEmail = canonical.getEmails().get(i);
+      Map<String, List<String>> actualEmail = childNodesToMap(emailArray.get(i));
+
+      assertStringField(actualEmail, expectedEmail.getType(),
+          ListField.Field.TYPE);
+      assertStringField(actualEmail, expectedEmail.getValue(),
+          ListField.Field.VALUE);
+    }
+
+    assertStringField(result, canonical.getEthnicity(), Person.Field.ETHNICITY);
+    assertStringField(result, canonical.getFashion(), Person.Field.FASHION);
+    assertStringListField(result, canonical.getFood(), Person.Field.FOOD);
+    assertStringField(result, canonical.getGender().toString(),
+        Person.Field.GENDER);
+    assertStringField(result, canonical.getHappiestWhen(),
+        Person.Field.HAPPIEST_WHEN);
+    assertBooleanField(result, canonical.getHasApp(), Person.Field.HAS_APP);
+    assertStringListField(result, canonical.getHeroes(), Person.Field.HEROES);
+    assertStringField(result, canonical.getHumor(), Person.Field.HUMOR);
+    assertStringField(result, canonical.getId(), Person.Field.ID);
+    assertStringListField(result, canonical.getInterests(),
+        Person.Field.INTERESTS);
+    assertStringField(result, canonical.getJobInterests(),
+        Person.Field.JOB_INTERESTS);
+
+    assertOrganizationField(canonical.getOrganizations().get(0), childNodeMap
+        .get(Person.Field.ORGANIZATIONS.toString()).get(0));
+
+    assertStringListField(result, canonical.getLanguagesSpoken(),
+        Person.Field.LANGUAGES_SPOKEN);
+    // assertDateField(result, canonical.getUpdated(),
+    // Person.Field.LAST_UPDATED);
+    assertStringField(result, canonical.getLivingArrangement(),
+        Person.Field.LIVING_ARRANGEMENT);
+    assertListEnumField(childNodeMap, canonical.getLookingFor(),
+        Person.Field.LOOKING_FOR);
+    assertStringListField(result, canonical.getMovies(), Person.Field.MOVIES);
+    assertStringListField(result, canonical.getMusic(), Person.Field.MUSIC);
+
+    assertEquals(canonical.getName().getFormatted(), childNodesToMap(
+        childNodeMap.get(Person.Field.NAME.toString()).get(0)).get(
+        Name.Field.FORMATTED.toString()).get(0));
+
+    assertEnumField(childNodeMap, canonical.getNetworkPresence(),
+        Person.Field.NETWORKPRESENCE);
+    assertStringField(result, canonical.getNickname(), Person.Field.NICKNAME);
+    assertStringField(result, canonical.getPets(), Person.Field.PETS);
+
+    List<Node> phoneArray = childNodeMap.get(Person.Field.PHONE_NUMBERS
+        .toString());
+    assertEquals(canonical.getPhoneNumbers().size(), phoneArray.size());
+
+    for (int i = 0; i < canonical.getPhoneNumbers().size(); i++) {
+      ListField expectedPhone = canonical.getPhoneNumbers().get(i);
+      Map<String, List<String>> actualPhone = childNodesToMap(phoneArray.get(i));
+      assertEquals(expectedPhone.getType(), actualPhone.get(
+          ListField.Field.TYPE.toString()).get(0));
+      assertEquals(expectedPhone.getValue(), actualPhone.get(
+          ListField.Field.VALUE.toString()).get(0));
+    }
+
+    assertStringField(result, canonical.getPoliticalViews(),
+        Person.Field.POLITICAL_VIEWS);
+
+    assertUrlField(canonical.getProfileSong(), childNodesToMap(childNodeMap
+        .get(Person.Field.PROFILE_SONG.toString()).get(0)));
+    assertStringField(result, canonical.getProfileUrl(),
+        Person.Field.PROFILE_URL);
+    assertUrlField(canonical.getProfileVideo(), childNodesToMap(childNodeMap
+        .get(Person.Field.PROFILE_VIDEO.toString()).get(0)));
+
+    assertStringListField(result, canonical.getQuotes(), Person.Field.QUOTES);
+    assertStringField(result, canonical.getRelationshipStatus(),
+        Person.Field.RELATIONSHIP_STATUS);
+    assertStringField(result, canonical.getReligion(), Person.Field.RELIGION);
+    assertStringField(result, canonical.getRomance(), Person.Field.ROMANCE);
+    assertStringField(result, canonical.getScaredOf(), Person.Field.SCARED_OF);
+
+    assertStringField(result, canonical.getSexualOrientation(),
+        Person.Field.SEXUAL_ORIENTATION);
+    assertEnumField(childNodeMap, canonical.getSmoker(), Person.Field.SMOKER);
+    assertStringListField(result, canonical.getSports(), Person.Field.SPORTS);
+    assertStringField(result, canonical.getStatus(), Person.Field.STATUS);
+    assertStringListField(result, canonical.getTags(), Person.Field.TAGS);
+    assertStringField(result, canonical.getThumbnailUrl(),
+        Person.Field.THUMBNAIL_URL);
+    // TODO: time zone
+    assertStringListField(result, canonical.getTurnOffs(),
+        Person.Field.TURN_OFFS);
+    assertStringListField(result, canonical.getTurnOns(), Person.Field.TURN_ONS);
+    assertStringListField(result, canonical.getTvShows(), Person.Field.TV_SHOWS);
+  }
+
+  private void assertAddressField(Address expected,
+      Map<String, List<String>> actual) {
+    assertStringField(actual, expected.getCountry(), Address.Field.COUNTRY);
+    assertFloatField(actual, expected.getLatitude(), Address.Field.LATITUDE);
+    assertStringField(actual, expected.getLocality(), Address.Field.LOCALITY);
+    assertFloatField(actual, expected.getLongitude(), Address.Field.LONGITUDE);
+    assertStringField(actual, expected.getPostalCode(),
+        Address.Field.POSTAL_CODE);
+    assertStringField(actual, expected.getRegion(), Address.Field.REGION);
+    assertStringField(actual, expected.getStreetAddress(),
+        Address.Field.STREET_ADDRESS);
+    assertStringField(actual, expected.getType(), Address.Field.TYPE);
+    assertStringField(actual, expected.getFormatted(), Address.Field.FORMATTED);
+  }
+
+  private void assertUrlField(Url expected, Map<String, List<String>> actual) {
+    assertStringField(actual, expected.getValue(), Url.Field.VALUE);
+    assertStringField(actual, expected.getLinkText(), Url.Field.LINK_TEXT);
+    assertStringField(actual, expected.getType(), Url.Field.TYPE);
+  }
+
+  private void assertOrganizationField(Organization expected, Node orgNode) {
+    Map<String, List<String>> actual = childNodesToMap(orgNode);
+    Map<String, List<Node>> actualNode = childNodesToNodeMap(orgNode);
+    assertStringField(childNodesToMap(actualNode.get(
+        Organization.Field.ADDRESS.toString()).get(0)), expected.getAddress()
+        .getFormatted(), Address.Field.FORMATTED);
+    assertStringField(actual, expected.getDescription(),
+        Organization.Field.DESCRIPTION);
+    // assertDateField(actual, expected.getEndDate(),
+    // Organization.Field.END_DATE);
+    assertStringField(actual, expected.getField(), Organization.Field.FIELD);
+    assertStringField(actual, expected.getName(), Organization.Field.NAME);
+    assertStringField(actual, expected.getSalary(), Organization.Field.SALARY);
+    // assertDateField(actual, expected.getStartDate(),
+    // Organization.Field.START_DATE);
+    assertStringField(actual, expected.getSubField(),
+        Organization.Field.SUB_FIELD);
+    assertStringField(actual, expected.getTitle(), Organization.Field.TITLE);
+    assertStringField(actual, expected.getWebpage(), Organization.Field.WEBPAGE);
+    assertStringField(actual, expected.getType(), Organization.Field.TYPE);
+  }
+
+  private void assertBooleanField(Map<String, List<String>> result,
+      boolean expected, Object field) {
+    assertEquals(expected, Boolean.parseBoolean(result.get(field.toString())
+        .get(0)));
+  }
+
+  private void assertFloatField(Map<String, List<String>> result,
+      Float expected, Object field) {
+    assertEquals(expected.floatValue(), Float.valueOf(result.get(
+        field.toString()).get(0)));
+  }
+
+  private void assertStringField(Map<String, List<String>> result,
+      String expected, Object field) {
+    assertEquals(expected, result.get(field.toString()).get(0));
+  }
+
+  private void assertStringListField(Map<String, List<String>> result,
+      List<String> list, Person.Field field) {
+    assertEquals(list.size(), result.get(field.toString()).size());
+    for (int i = 0; i < list.size(); i++) {
+      assertEquals(list.get(i), result.get(field.toString()).get(i));
+    }
+  }
+
+  private void assertEnumField(Map<String, List<Node>> result, Enum expected,
+      Person.Field field) {
+    Map<String, List<String>> actual = childNodesToMap(result.get(
+        field.toString()).get(0));
+    assertEquals(expected.getDisplayValue(), actual.get("displayValue").get(0));
+    assertEquals(expected.getValue().toString(), actual.get("value").get(0));
+  }
+
+  private void assertListEnumField(Map<String, List<Node>> result,
+      List<? extends Enum<? extends Enum.EnumKey>> expected, Person.Field field) {
+    List<Node> actual = result.get(field.toString());
+    for (int i = 0; i < actual.size(); i++) {
+      Map<String, List<String>> nm = childNodesToMap(actual.get(i));
+      assertEquals(expected.get(i).getDisplayValue(), nm.get("displayValue")
+          .get(0));
+      assertEquals(expected.get(i).getValue().toString(), nm.get("value")
+          .get(0));
+    }
+  }
+
+  /**
+   * Expected response for a list of people in json:
+   *
+   * { "totalResults" : 3,
+   *     "startIndex" : 0
+   *     "entry" : [ {<jane doe>}, // layed out like above
+   * {<george doe>}, {<maija m>}, ] }
+   *
+   * @throws Exception
+   *           if test encounters an error
+   */
+  @Test
+  public void testGetPeople() throws Exception {
+    Map<String, String> extraParams = Maps.newHashMap();
+    extraParams.put("sortBy", "name");
+    extraParams.put("sortOrder", null);
+    extraParams.put("filterBy", null);
+    extraParams.put("startIndex", null);
+    extraParams.put("count", "20");
+    extraParams.put("fields", null);
+
+    // Currently, for Shindig @all == @friends
+    String resp = getResponse("/people/john.doe/@friends", "GET", extraParams,
+        "xml", "application/xml");
+    XPath xp = xpathFactory.newXPath();
+    NodeList resultNodeList = (NodeList) xp.evaluate("/response/entry",
+        new InputSource(new StringReader(resp)), XPathConstants.NODESET);
+    assertEquals(1, resultNodeList.getLength());
+
+    Map<String, List<String>> result = childNodesToMap(resultNodeList.item(0));
+    Map<String, List<Node>> resultNodes = childNodesToNodeMap(resultNodeList
+        .item(0));
+
+    assertEquals("3", result.get("totalResults").get(0));
+    assertEquals("0", result.get("startIndex").get(0));
+
+    // The users should be in alphabetical order
+    assertPerson(childNodesToNodeMap(resultNodes.get("entry").get(0)),
+        "george.doe", "George Doe");
+    assertPerson(childNodesToNodeMap(resultNodes.get("entry").get(1)),
+        "jane.doe", "Jane Doe");
+  }
+
+  @Test
+  public void testGetPeoplePagination() throws Exception {
+    Map<String, String> extraParams = Maps.newHashMap();
+    extraParams.put("sortBy", "name");
+    extraParams.put("sortOrder", null);
+    extraParams.put("filterBy", null);
+    extraParams.put("startIndex", "0");
+    extraParams.put("count", "1");
+    extraParams.put("fields", null);
+
+    String resp = getResponse("/people/john.doe/@friends", "GET", extraParams,
+        "xml", "application/xml");
+
+    XPath xp = xpathFactory.newXPath();
+    NodeList resultNodeList = (NodeList) xp.evaluate("/response/entry",
+        new InputSource(new StringReader(resp)), XPathConstants.NODESET);
+    assertEquals(1, resultNodeList.getLength());
+
+    Map<String, List<String>> result = childNodesToMap(resultNodeList.item(0));
+    Map<String, List<Node>> resultNodes = childNodesToNodeMap(resultNodeList
+        .item(0));
+
+    assertEquals("3", result.get("totalResults").get(0));
+    assertEquals("0", result.get("startIndex").get(0));
+
+    assertPerson(childNodesToNodeMap(resultNodes.get("entry").get(0)),
+        "george.doe", "George Doe");
+
+    // Get the second page
+    extraParams.put("startIndex", "1");
+    resp = getResponse("/people/john.doe/@friends", "GET", extraParams, "xml",
+        "application/xml");
+    xp = xpathFactory.newXPath();
+    resultNodeList = (NodeList) xp.evaluate("/response/entry", new InputSource(
+        new StringReader(resp)), XPathConstants.NODESET);
+    assertEquals(1, resultNodeList.getLength());
+
+    result = childNodesToMap(resultNodeList.item(0));
+    resultNodes = childNodesToNodeMap(resultNodeList.item(0));
+
+    assertEquals("3", result.get("totalResults").get(0));
+    assertEquals("1", result.get("startIndex").get(0));
+
+    assertPerson(childNodesToNodeMap(resultNodes.get("entry").get(0)),
+        "jane.doe", "Jane Doe");
+  }
+
+  private void assertPerson(Map<String, List<Node>> person, String expectedId,
+      String expectedName) throws Exception {
+    assertEquals(expectedId, person.get("id").get(0).getTextContent());
+    assertEquals(expectedName, childNodesToMap(person.get("name").get(0)).get(
+        "formatted").get(0));
+  }
+
+  // TODO: Add tests for fields parameter
+  // TODO: Add tests for networkDistance
+}
\ No newline at end of file

Modified: incubator/shindig/trunk/pom.xml
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/pom.xml?rev=710100&r1=710099&r2=710100&view=diff
==============================================================================
--- incubator/shindig/trunk/pom.xml (original)
+++ incubator/shindig/trunk/pom.xml Mon Nov  3 08:40:20 2008
@@ -1020,6 +1020,11 @@
         <artifactId>xercesImpl</artifactId>
         <version>2.9.1</version>
       </dependency>
+      <dependency>
+        <groupId>woodstox</groupId>
+        <artifactId>wstx</artifactId>
+        <version>1.0.7</version>
+      </dependency>
     </dependencies>
   </dependencyManagement>
 </project>