You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@roller.apache.org by sn...@apache.org on 2005/09/21 18:38:16 UTC
svn commit: r290739 - in /incubator/roller/branches/roller_2.0:
sandbox/atomprotocol/src/org/roller/presentation/atomapi/
sandbox/atomprotocol/tests/ sandbox/atomprotocol/tests/org/
sandbox/atomprotocol/tests/org/roller/ sandbox/atomprotocol/tests/org/...
Author: snoopdave
Date: Wed Sep 21 09:38:07 2005
New Revision: 290739
URL: http://svn.apache.org/viewcvs?rev=290739&view=rev
Log:
Starting new Atom Protocol impl
Added:
incubator/roller/branches/roller_2.0/sandbox/atomprotocol/tests/
incubator/roller/branches/roller_2.0/sandbox/atomprotocol/tests/org/
incubator/roller/branches/roller_2.0/sandbox/atomprotocol/tests/org/roller/
incubator/roller/branches/roller_2.0/sandbox/atomprotocol/tests/org/roller/presentation/
incubator/roller/branches/roller_2.0/sandbox/atomprotocol/tests/org/roller/presentation/atomapi04/
incubator/roller/branches/roller_2.0/sandbox/atomprotocol/tests/org/roller/presentation/atomapi04/AtomCollectionTest.java
incubator/roller/branches/roller_2.0/sandbox/atomprotocol/tests/org/roller/presentation/atomapi04/AtomServletTest.java
incubator/roller/branches/roller_2.0/tests/org/roller/presentation/atomapi04/
- copied from r289678, incubator/roller/branches/roller_2.0/tests/org/roller/presentation/atomapi/
Removed:
incubator/roller/branches/roller_2.0/tests/org/roller/presentation/atomapi/
incubator/roller/branches/roller_2.0/tests/org/roller/presentation/atomapi04/AtomCollectionTest.java
incubator/roller/branches/roller_2.0/tests/org/roller/presentation/atomapi04/AtomServletTest.java
Modified:
incubator/roller/branches/roller_2.0/sandbox/atomprotocol/src/org/roller/presentation/atomapi/AtomCollection.java
Modified: incubator/roller/branches/roller_2.0/sandbox/atomprotocol/src/org/roller/presentation/atomapi/AtomCollection.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_2.0/sandbox/atomprotocol/src/org/roller/presentation/atomapi/AtomCollection.java?rev=290739&r1=290738&r2=290739&view=diff
==============================================================================
--- incubator/roller/branches/roller_2.0/sandbox/atomprotocol/src/org/roller/presentation/atomapi/AtomCollection.java (original)
+++ incubator/roller/branches/roller_2.0/sandbox/atomprotocol/src/org/roller/presentation/atomapi/AtomCollection.java Wed Sep 21 09:38:07 2005
@@ -34,31 +34,24 @@
/*
* Based on: draft-ietf-atompub-protocol-04.txt
*
- * appCollection = element
- * app:collection {
- * attribute next { text } ?,
- * appMember*
- * }
+ * appCollection =
+ * element app:collection {
+ * ( appMemberType*
+ * appSearchTemplate
+ * & anyElement* )
+ * }
*
* Here is an example Atom collection:
*
* <?xml version="1.0" encoding='utf-8'?>
- * <collection xmlns="http://purl.org/atom/app#">
- * <member href="http://example.org/1"
- * hrefreadonly="http://example.com/1/bar"
- * title="Sample 1"
- * updated="2003-12-13T18:30:02Z" />
- * <member href="http://example.org/2"
- * hrefreadonly="http://example.com/2/bar"
- * title="Sample 2"
- * updated="2003-12-13T18:30:02Z" />
- * <member href="http://example.org/3"
- * hrefreadonly="http://example.com/3/bar"
- * title="Sample 3"
- * updated="2003-12-13T18:30:02Z" />
- * <member href="http://example.org/4"
- * title="Sample 4"
- * updated="2003-12-13T18:30:02Z" />
+ * <collection xmlns="http://purl.org/atom/app">
+ * <member-type>text</member-type>
+ * <member-type>html</member-type>
+ * <member-type>xhtml</member-type>
+ * <member-type>src</member-type>
+ * <member-type>generic</member-type>
+ * <search-template>http://example.org/{index}</search-template>
+ * <search-template>http://example.org/d/{daterange}</search-template>
* </collection>
*/
public class AtomCollection
@@ -66,100 +59,27 @@
public static final Namespace ns =
Namespace.getNamespace("http://purl.org/atom/app#");
- private static SimpleDateFormat df =
- new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssZ" );
- private String next = null;
- private List members = new ArrayList();
+ private List memberTypes = new ArrayList(); // array of strings
+ private String dateRangeTemplate = null;
+ private String indexTemplate = null;
public AtomCollection()
{
}
-
- /** URI of collection containing member elements updated earlier in time */
- public String getNext()
- {
- return next;
- }
-
- public void setNext(String next)
- {
- this.next = next;
- }
-
- public List getMembers()
- {
- return members;
- }
-
- public void setMembers(List members)
+
+ public List getMemberTypes()
{
- this.members = members;
+ return memberTypes;
}
- public void addMember(Member member)
+ public void setMemberTypes(List memberTypes)
{
- members.add(member);
+ this.memberTypes = memberTypes;
}
- /** Models an Atom collection member */
- /*
- * appMember = element app:member { attribute title { text }, attribute href {
- * text }, attribute hrefreadonly { text } ?, attribute updated { text } }
- */
- public static class Member
+ public void addMemberType(String memberType)
{
- private String title;
- private String href;
- private String hrefreadonly;
- private Date updated;
-
- public Member()
- {
- }
-
- /** Human readable title */
- public String getTitle()
- {
- return title;
- }
-
- public void setTitle(String title)
- {
- this.title = title;
- }
-
- /** The URI used to edit the member source */
- public String getHref()
- {
- return href;
- }
-
- public void setHref(String href)
- {
- this.href = href;
- }
-
- /** The URI for readonly access to member source */
- public String getHrefreadonly()
- {
- return hrefreadonly;
- }
-
- public void setHrefreadonly(String hrefreadonly)
- {
- this.hrefreadonly = hrefreadonly;
- }
-
- /** Same as updated value of collection member */
- public Date getUpdated()
- {
- return updated;
- }
-
- public void setUpdated(Date updated)
- {
- this.updated = updated;
- }
+ memberTypes.add(memberType);
}
/** Deserialize an Atom Collection XML document into an object */
@@ -168,17 +88,17 @@
{
AtomCollection collection = new AtomCollection();
Element root = document.getRootElement();
- if (root.getAttribute("next") != null)
- {
- collection.setNext(root.getAttribute("next").getValue());
- }
- List mems = root.getChildren("member", ns);
- Iterator iter = mems.iterator();
- while (iter.hasNext())
- {
- Element e = (Element) iter.next();
- collection.addMember(AtomCollection.elementToMember(e));
- }
+// if (root.getAttribute("next") != null)
+// {
+// collection.setNext(root.getAttribute("next").getValue());
+// }
+// List mems = root.getChildren("member", ns);
+// Iterator iter = mems.iterator();
+// while (iter.hasNext())
+// {
+// Element e = (Element) iter.next();
+// collection.addMember(AtomCollection.elementToMember(e));
+// }
return collection;
}
@@ -186,78 +106,19 @@
public static Document collectionToDocument(AtomCollection collection)
{
Document doc = new Document();
- Element root = new Element("collection", ns);
- doc.setRootElement(root);
- if (collection.getNext() != null)
- {
- root.setAttribute("next", collection.getNext());
- }
- Iterator iter = collection.getMembers().iterator();
- while (iter.hasNext())
- {
- Member member = (Member) iter.next();
- root.addContent(AtomCollection.memberToElement(member));
- }
+// Element root = new Element("collection", ns);
+// doc.setRootElement(root);
+// if (collection.getNext() != null)
+// {
+// root.setAttribute("next", collection.getNext());
+// }
+// Iterator iter = collection.getMembers().iterator();
+// while (iter.hasNext())
+// {
+// Member member = (Member) iter.next();
+// root.addContent(AtomCollection.memberToElement(member));
+// }
return doc;
}
- /** Deserialize an Atom collection member XML element into an object */
- public static Member elementToMember(Element element) throws Exception
- {
- Member member = new Member();
- member.setTitle(element.getAttribute("title").getValue());
- member.setHref(element.getAttribute("href").getValue());
- if (element.getAttribute("href") != null)
- {
- member.setHref(element.getAttribute("href").getValue());
- }
- member.setUpdated(df.parse(element.getAttribute("updated").getValue()));
- return member;
- }
-
- /** Serialize a collection member into an XML element */
- public static Element memberToElement(Member member)
- {
- Element element = new Element("member", ns);
- element.setAttribute("title", member.getTitle()); // TODO: escape/strip HTML?
- element.setAttribute("href", member.getHref());
- if (member.getHrefreadonly() != null)
- {
- element.setAttribute("hrefreadonly", member.getHrefreadonly());
- }
- element.setAttribute("updated", df.format(member.getUpdated()));
- return element;
- }
-
- /** Start and end date range */
- public static class Range { Date start=null; Date end=null; }
-
- /** Parse HTTP Range header into a start and end date range */
- public static Range parseRange(String rangeString) throws ParseException
- {
- // Range: updated=<isodate>/<isodate>
- // Range: updated=<isodate>/
- // Range: updated=/<isodate>
-
- Range range = new Range();
- String[] split = rangeString.split("=");
- if (split[1].startsWith("/"))
- {
- // we have only end date
- range.end = df.parse(split[1].split("/")[1]);
- }
- else if (split[1].endsWith("/"))
- {
- // we have only start date
- range.start = df.parse(split[1].split("/")[0]);
- }
- else
- {
- // both dates present
- String[] dates = split[1].split("/");
- range.start = df.parse(dates[0]);
- range.end = df.parse(dates[1]);
- }
- return range;
- }
}
Added: incubator/roller/branches/roller_2.0/sandbox/atomprotocol/tests/org/roller/presentation/atomapi04/AtomCollectionTest.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_2.0/sandbox/atomprotocol/tests/org/roller/presentation/atomapi04/AtomCollectionTest.java?rev=290739&view=auto
==============================================================================
--- incubator/roller/branches/roller_2.0/sandbox/atomprotocol/tests/org/roller/presentation/atomapi04/AtomCollectionTest.java (added)
+++ incubator/roller/branches/roller_2.0/sandbox/atomprotocol/tests/org/roller/presentation/atomapi04/AtomCollectionTest.java Wed Sep 21 09:38:07 2005
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2005 David M Johnson (For RSS and Atom In Action)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.roller.presentation.atomapi04;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.jdom.Document;
+import org.roller.presentation.atomapi.AtomCollection;
+import org.roller.presentation.atomapi.AtomService;
+
+/**
+ * @author Dave Johnson
+ */
+public class AtomCollectionTest extends TestCase {
+
+ private static SimpleDateFormat df =
+ new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssZ" );
+
+ /** Creates a new instance of AtomCollectionTest */
+ public AtomCollectionTest() {
+ }
+
+ public void testRangeParsing() throws Exception {
+ Date end = new Date(); // now
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(end);
+ cal.add(Calendar.DATE, -1);
+ Date start = cal.getTime(); // one day ago
+ String startString = df.format(start);
+ String endString = df.format(end);
+
+ String r1 = "Range: updated="+startString+"/"+endString;
+ AtomCollection.Range range = AtomCollection.parseRange(r1);
+ assertNotNull(range.start);
+ assertNotNull(range.end);
+
+ String r2 = "Range: updated="+startString+"/";
+ range = AtomCollection.parseRange(r2);
+ assertNotNull(range.start);
+ assertNull(range.end);
+
+ String r3 = "Range: updated="+"/"+endString;
+ range = AtomCollection.parseRange(r3);
+ assertNull(range.start);
+ assertNotNull(range.end);
+ }
+
+ public void testCollectionBean() throws Exception {
+
+ // create a collection with a member
+ Date date1 = new Date();
+ AtomCollection collection = new AtomCollection();
+ AtomCollection.Member member1 = new AtomCollection.Member();
+ member1.setTitle("title1");
+ member1.setHref("http://example.com/item1");
+ member1.setUpdated(date1);
+ collection.addMember(member1);
+
+ // add another member
+ Date date2 = new Date();
+ AtomCollection.Member member2 = new AtomCollection.Member();
+ member2.setTitle("title2");
+ member2.setHref("http://example.com/item2");
+ member2.setUpdated(date2);
+ collection.addMember(member2);
+
+ // serialize to XML
+ Document doc = AtomCollection.collectionToDocument(collection);
+ assertEquals("collection", doc.getRootElement().getName());
+ assertEquals(2, doc.getRootElement().getContent().size());
+
+ // deserialize from XML and assert we've got the same stuff
+ AtomCollection col2 = AtomCollection.documentToCollection(doc);
+ assertEquals(2, col2.getMembers().size());
+
+ AtomCollection.Member m1 = (AtomCollection.Member)col2.getMembers().get(0);
+ assertEquals("title1", m1.getTitle());
+ assertEquals("http://example.com/item1", m1.getHref());
+ assertCloseEnough(date1, m1.getUpdated());
+
+ AtomCollection.Member m2 = (AtomCollection.Member)col2.getMembers().get(1);
+ assertEquals("title2", m2.getTitle());
+ assertEquals("http://example.com/item2", m2.getHref());
+ assertCloseEnough(date2, m2.getUpdated());
+ }
+
+ public void testServiceBean() {
+
+ AtomService.Collection collection = new AtomService.Collection();
+ collection.setTitle("All blog entries");
+ collection.setContents("entries");
+ collection.setHref("http://example.com/collection1");
+
+ AtomService.Workspace workspace = new AtomService.Workspace();
+ workspace.setTitle("My blog");
+ workspace.addCollection(collection);
+
+ AtomService service = new AtomService();
+ service.addWorkspace(workspace);
+
+ // serialize to XML
+ Document doc = AtomService.serviceToDocument(service);
+ assertEquals("service", doc.getRootElement().getName());
+ assertEquals(1, doc.getRootElement().getContent().size());
+
+ // deserialize from XML and assert we've got the same stuff
+ AtomService service2 = AtomService.documentToService(doc);
+
+ AtomService.Workspace workspace2 =
+ (AtomService.Workspace)service2.getWorkspaces().get(0);
+ assertEquals("My blog", workspace2.getTitle());
+
+ AtomService.Collection collection2 =
+ (AtomService.Collection)workspace2.getCollections().get(0);
+ assertEquals("All blog entries", collection2.getTitle());
+ assertEquals("entries", collection.getContents());
+ assertEquals("http://example.com/collection1", collection2.getHref());
+ }
+
+ /** Compare times ignoring milliseconds */
+ public void assertCloseEnough(Date d1, Date d2) {
+ long t1 = d1.getTime() - d1.getTime() % 1000;
+ long t2 = d2.getTime() - d2.getTime() % 1000;
+ assertEquals(t1, t2);
+ }
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(new TestSuite(AtomCollectionTest.class));
+ return suite;
+ }
+}
Added: incubator/roller/branches/roller_2.0/sandbox/atomprotocol/tests/org/roller/presentation/atomapi04/AtomServletTest.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_2.0/sandbox/atomprotocol/tests/org/roller/presentation/atomapi04/AtomServletTest.java?rev=290739&view=auto
==============================================================================
--- incubator/roller/branches/roller_2.0/sandbox/atomprotocol/tests/org/roller/presentation/atomapi04/AtomServletTest.java (added)
+++ incubator/roller/branches/roller_2.0/sandbox/atomprotocol/tests/org/roller/presentation/atomapi04/AtomServletTest.java Wed Sep 21 09:38:07 2005
@@ -0,0 +1,448 @@
+package org.roller.presentation.atomapi04;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+import javax.servlet.http.HttpServletResponse;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.jdom.Document;
+import org.jdom.input.SAXBuilder;
+import org.roller.RollerTestBase;
+import org.roller.model.WeblogManager;
+import org.roller.pojos.UserData;
+import org.roller.pojos.WeblogEntryData;
+import org.roller.pojos.WebsiteData;
+import org.roller.presentation.MockRollerContext;
+import org.roller.presentation.atomapi.AtomCollection;
+import org.roller.presentation.atomapi.AtomService;
+import org.roller.presentation.atomapi.AtomServlet;
+import org.roller.presentation.atomapi.WSSEUtilities;
+import org.roller.util.Utilities;
+
+import com.mockrunner.mock.web.ActionMockObjectFactory;
+import com.mockrunner.mock.web.MockHttpServletRequest;
+import com.mockrunner.mock.web.MockHttpServletResponse;
+import com.mockrunner.mock.web.MockServletContext;
+import com.mockrunner.mock.web.WebMockObjectFactory;
+import com.mockrunner.servlet.ServletTestModule;
+import com.mockrunner.struts.ActionTestModule;
+import com.sun.syndication.feed.atom.Content;
+import com.sun.syndication.feed.atom.Entry;
+
+/**
+ * Test new Rome based Atom API implementation.
+ * @author David M Johnson
+ */
+public class AtomServletTest extends RollerTestBase
+{
+ private ActionMockObjectFactory mockFactory;
+ protected MockRollerContext rollerContext;
+ protected ActionTestModule strutsModule;
+ private ServletTestModule servletModule;
+ private static SimpleDateFormat df =
+ new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssZ" );
+
+ protected WebMockObjectFactory getMockFactory()
+ {
+ if (mockFactory == null)
+ {
+ mockFactory = new ActionMockObjectFactory();
+ }
+ return mockFactory;
+ }
+
+ //------------------------------------------------------------------------------
+ /**
+ * Test get of introspection URI
+ */
+ public void testGetIntrospection() throws Exception
+ {
+ UserData user = (UserData)mUsersCreated.get(0);
+
+ MockHttpServletRequest mockRequest = getMockFactory().getMockRequest();
+ mockRequest.addHeader("X-WSSE",
+ generateWSSEHeader(user.getUserName(), user.getPassword()));
+ mockRequest.setContextPath("/atom");
+ mockRequest.setPathInfo("/" + user.getUserName());
+ getServletModule().doGet();
+
+ String output = getServletModule().getOutput();
+ SAXBuilder builder = new SAXBuilder();
+ Document doc = builder.build(new StringReader(output));
+
+ AtomService service = AtomService.documentToService(doc);
+ assertEquals(1, service.getWorkspaces().size());
+ }
+
+ //------------------------------------------------------------------------------
+ /**
+ * Test get of entries collection URI
+ */
+ public void testGetEntriesCollection() throws Exception
+ {
+ UserData user = (UserData)mUsersCreated.get(0);
+
+ // get entries collection
+ MockHttpServletRequest mockRequest = getMockFactory().getMockRequest();
+ mockRequest.addHeader("X-WSSE",
+ generateWSSEHeader(user.getUserName(), user.getPassword()));
+ mockRequest.setContextPath("/atom");
+ mockRequest.setPathInfo("/" + user.getUserName() + "/entries");
+ getServletModule().doGet();
+
+ // assert that we got 20 entries
+ String output = getServletModule().getOutput();
+ SAXBuilder builder = new SAXBuilder();
+ Document doc = builder.build(new StringReader(output));
+ AtomCollection col = AtomCollection.documentToCollection(doc);
+ assertEquals(20, col.getMembers().size());
+
+ // use collection next URI to get next batch of entries
+ resetMocks();
+ String[] next = Utilities.stringToStringArray(col.getNext(), "/");
+
+ mockRequest = getMockFactory().getMockRequest();
+ mockRequest.addHeader("X-WSSE",
+ generateWSSEHeader(user.getUserName(), user.getPassword()));
+ mockRequest.setContextPath("/atom");
+ mockRequest.setPathInfo(
+ "/" + user.getUserName() + "/entries/" + next[next.length-1]);
+ getServletModule().doGet();
+
+ // assert that we got another 20 entries
+ output = getServletModule().getOutput();
+ doc = builder.build(new StringReader(output));
+ col = AtomCollection.documentToCollection(doc);
+ assertEquals(10, col.getMembers().size());
+ }
+
+ //------------------------------------------------------------------------------
+ /**
+ * Test get of entries collection URI with a range
+ */
+ public void testGetEntriesCollectionRange() throws Exception
+ {
+ UserData user = (UserData)mUsersCreated.get(0);
+
+ Date end = new Date(); // now
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(end);
+ cal.add(Calendar.DATE, -30);
+ Date start = cal.getTime(); // one day ago
+ String startString = df.format(start);
+ String endString = df.format(end);
+
+ // get entries collection
+ MockHttpServletRequest mockRequest = getMockFactory().getMockRequest();
+ mockRequest.addHeader("X-WSSE",
+ generateWSSEHeader(user.getUserName(), user.getPassword()));
+ mockRequest.addHeader("Range",
+ "updated=" + startString + "/" + endString);
+ mockRequest.setContextPath("/atom");
+ mockRequest.setPathInfo("/" + user.getUserName() + "/entries");
+ getServletModule().doGet();
+
+ // assert that we got 20 entries
+ String output = getServletModule().getOutput();
+ SAXBuilder builder = new SAXBuilder();
+ Document doc = builder.build(new StringReader(output));
+ AtomCollection col = AtomCollection.documentToCollection(doc);
+ assertEquals(20, col.getMembers().size());
+
+ // use collection next URI to get next batch of entries
+ resetMocks();
+ String[] next = Utilities.stringToStringArray(col.getNext(), "/");
+
+ mockRequest = getMockFactory().getMockRequest();
+ mockRequest.addHeader("X-WSSE",
+ generateWSSEHeader(user.getUserName(), user.getPassword()));
+ mockRequest.setContextPath("/atom");
+ mockRequest.setPathInfo("/" + user.getUserName() + "/entries");
+ mockRequest.setQueryString("Range=updated="+startString+"/"+endString);
+ getServletModule().doGet();
+
+ // assert that we got another 20 entries
+ output = getServletModule().getOutput();
+ doc = builder.build(new StringReader(output));
+ col = AtomCollection.documentToCollection(doc);
+ assertEquals(20, col.getMembers().size());
+ }
+
+ //------------------------------------------------------------------------------
+ /**
+ * Test that GET on the EditURI returns an entry.
+ */
+ public void testGetEntry() throws Exception
+ {
+ UserData user = (UserData)mUsersCreated.get(0);
+ WebsiteData website = (WebsiteData)
+ getRoller().getUserManager().getWebsites(user, null).get(0);
+ WeblogEntryData entry = (WeblogEntryData)
+ getRoller().getWeblogManager().getWeblogEntries(
+ website, null, null, null, null, new Integer(1)).get(0);
+
+ Entry fetchedEntry = getEntry(user, entry.getId());
+ assertEquals(entry.getId(), fetchedEntry.getId());
+ }
+
+ //------------------------------------------------------------------------------
+ /**
+ * Test that POST to the PostURI returns an entry.
+ */
+ public void testPostEntry() throws Exception
+ {
+ UserData user = (UserData)mUsersCreated.get(0);
+
+ // Create an entry in a feed, so Rome can handle it
+ Content content = new Content();
+ content.setMode(Content.ESCAPED);
+ content.setValue("test entry text");
+ List contents = new ArrayList();
+ contents.add(content);
+
+ Entry entry = new Entry();
+ entry.setTitle("test entry title");
+ entry.setContents(contents);
+
+ StringWriter entryWriter = new StringWriter();
+ AtomServlet.serializeEntry(entry, entryWriter);
+
+ MockHttpServletRequest mockRequest = getMockFactory().getMockRequest();
+ mockRequest.setContextPath("/atom");
+ mockRequest.setPathInfo(user.getUserName() + "/entries/");
+ mockRequest.addHeader("X-WSSE",
+ generateWSSEHeader(user.getUserName(), user.getPassword()));
+ mockRequest.setBodyContent(entryWriter.toString());
+ getServletModule().doPost();
+
+ String output = getServletModule().getOutput();
+ Entry returnedEntry = AtomServlet.parseEntry(new StringReader(output));
+ assertEquals(returnedEntry.getTitle(), entry.getTitle());
+
+ MockHttpServletResponse mockResponse = getMockFactory().getMockResponse();
+ assertEquals(HttpServletResponse.SC_CREATED, mockResponse.getStatusCode());
+ assertTrue(mockResponse.containsHeader("Location"));
+
+ getRoller().release();
+ resetMocks();
+
+ Entry fetchedEntry = getEntry(user, returnedEntry.getId());
+ assertEquals(returnedEntry.getId(), fetchedEntry.getId());
+ }
+
+ //------------------------------------------------------------------------------
+ /**
+ * Test that PUT on the EditURI updates an entry.
+ */
+ public void testPutEntry() throws Exception
+ {
+ UserData user = (UserData)mUsersCreated.get(0);
+ WebsiteData website = (WebsiteData)
+ getRoller().getUserManager().getWebsites(user, null).get(0);
+
+ WeblogEntryData entry = (WeblogEntryData)
+ getRoller().getWeblogManager().getWeblogEntries(
+ website, null, null, null, null, new Integer(1)).get(0);
+
+ // Fetch that entry using Atom
+ Entry fetchedEntry = getEntry(user, entry.getId());
+ assertEquals(entry.getId(), fetchedEntry.getId());
+
+ // Make a change to the fetched entry
+ fetchedEntry.setTitle("TEST TITLE");
+
+ // Use Atom PUT to update the entry
+ StringWriter entryWriter = new StringWriter();
+ AtomServlet.serializeEntry(fetchedEntry, entryWriter);
+ MockHttpServletRequest mockRequest2 = getMockFactory().getMockRequest();
+ mockRequest2.setContextPath("/atom");
+ mockRequest2.setPathInfo(user.getUserName() + "/entry/" + entry.getId());
+ mockRequest2.addHeader("X-WSSE",
+ generateWSSEHeader(user.getUserName(), user.getPassword()));
+ mockRequest2.setBodyContent(entryWriter.toString());
+ getServletModule().doPut();
+
+ getRoller().release();
+ resetMocks();
+
+ // Get the entry again to make sure the update was made
+ Entry fetchedEntry2 = getEntry(user, entry.getId());
+ assertEquals(fetchedEntry.getTitle(), fetchedEntry2.getTitle());
+ }
+
+ //------------------------------------------------------------------------------
+ /**
+ * Test that DELETE on EditURI deletes entry.
+ */
+ public void testDeleteEntry() throws Exception
+ {
+ UserData user = (UserData)mUsersCreated.get(0);
+ WebsiteData website = (WebsiteData)
+ getRoller().getUserManager().getWebsites(user, null).get(0);
+
+ WeblogEntryData entry = (WeblogEntryData)
+ getRoller().getWeblogManager().getWeblogEntries(
+ website, null, null, null, null, new Integer(1)).get(0);
+
+ Entry fetchedEntry = getEntry(user, entry.getId());
+ assertEquals(entry.getId(), fetchedEntry.getId());
+
+ // Use Atom DELETE to delete the entry
+ MockHttpServletRequest mockRequest2 = getMockFactory().getMockRequest();
+ mockRequest2.setContextPath("/atom");
+ mockRequest2.setPathInfo(user.getUserName() + "/entry/" + entry.getId());
+ mockRequest2.addHeader("X-WSSE",
+ generateWSSEHeader(user.getUserName(), user.getPassword()));
+ getServletModule().doDelete();
+ getRoller().release();
+ resetMocks();
+ try
+ {
+ getEntry(user, entry.getId()).getId();
+ fail(); // no exception was thrown!
+ }
+ catch (Exception expected) {}
+ }
+
+ //------------------------------------------------------------------------------
+ private Entry getEntry(UserData user, String id) throws Exception
+ {
+ MockHttpServletRequest mockRequest = getMockFactory().getMockRequest();
+ mockRequest.setContextPath("/atom");
+ mockRequest.setPathInfo(user.getUserName() + "/entry/" + id);
+ mockRequest.addHeader("X-WSSE",
+ generateWSSEHeader(user.getUserName(), user.getPassword()));
+ getServletModule().doGet();
+
+ String output = getServletModule().getOutput();
+ return AtomServlet.parseEntry(new StringReader(output));
+ }
+
+ //------------------------------------------------------------------------------
+ public void testPostResource() throws Exception
+ {
+ UserData user = (UserData)mUsersCreated.get(0);
+
+ // read test file into byte array
+ String fileName = "rssbadge.gif";
+ File testFile = new File(fileName);
+ FileInputStream fis = new FileInputStream(testFile);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Utilities.copyInputToOutput(fis, baos);
+
+ // post file as resource
+ MockHttpServletRequest mockRequest = getMockFactory().getMockRequest();
+ mockRequest.setContextPath("/atom");
+ mockRequest.setPathInfo(user.getUserName() + "/resources/");
+ mockRequest.addHeader("Name", fileName);
+ mockRequest.addHeader("X-WSSE",
+ generateWSSEHeader(user.getUserName(), user.getPassword()));
+ mockRequest.setBodyContent(baos.toByteArray());
+ getServletModule().doPost();
+
+ MockHttpServletResponse mockResponse = getMockFactory().getMockResponse();
+ assertEquals(HttpServletResponse.SC_CREATED, mockResponse.getStatusCode());
+ assertTrue(mockResponse.containsHeader("Location"));
+
+ getRoller().release();
+ resetMocks();
+ }
+
+ //------------------------------------------------------------------------------
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ super.setUpTestWeblogs();
+ resetMocks();
+ MockServletContext ctx = getMockFactory().getMockServletContext();
+ ctx.setRealPath("/", "");
+ rollerContext = new MockRollerContext();
+ rollerContext.init(ctx);
+ }
+
+ //------------------------------------------------------------------------------
+ /**
+ * Really really reset mocks.
+ */
+ private void resetMocks()
+ {
+ mockFactory = null;
+ getMockFactory().refresh();
+ getMockFactory().getMockRequest().clearParameters();
+ getMockFactory().getMockRequest().clearAttributes();
+ setServletModule(new ServletTestModule(getMockFactory()));
+ getServletModule().setServlet(
+ getServletModule().createServlet(AtomServlet.class));
+ getServletModule().clearOutput();
+ }
+
+ //------------------------------------------------------------------------------
+ /**
+ * @param servletModule The servletModule to set.
+ */
+ protected void setServletModule(ServletTestModule servletModule)
+ {
+ this.servletModule = servletModule;
+ }
+
+ //------------------------------------------------------------------------------
+ /**
+ * @return Returns the servletModule.
+ */
+ protected ServletTestModule getServletModule()
+ {
+ return servletModule;
+ }
+
+ //------------------------------------------------------------------------------
+ public void tearDown() throws Exception
+ {
+ super.tearDown();
+ super.tearDownTestWeblogs();
+ }
+
+ //------------------------------------------------------------------------
+ public static Test suite()
+ {
+ return new TestSuite(AtomServletTest.class);
+ }
+
+ //------------------------------------------------------------------------------
+ public static String generateWSSEHeader(String username, String password)
+ throws Exception
+ {
+ byte[] nonceBytes = Long.toString(new Date().getTime()).getBytes();
+ String nonce = new String(WSSEUtilities.base64Encode(nonceBytes));
+
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+ String created = sdf.format(new Date());
+
+ String digest = WSSEUtilities.generateDigest(
+ nonceBytes, created.getBytes("UTF-8"), password.getBytes("UTF-8"));
+
+ StringBuffer header = new StringBuffer("UsernameToken Username=\"");
+ header.append(username);
+ header.append("\", ");
+ header.append("PasswordDigest=\"");
+ header.append(digest);
+ header.append("\", ");
+ header.append("Nonce=\"");
+ header.append(nonce);
+ header.append("\", ");
+ header.append("Created=\"");
+ header.append(created);
+ header.append("\"");
+ return header.toString();
+ }
+}