diff --git a/src/main/java/org/rometools/propono/atom/client/ClientAtomService.java b/src/main/java/org/rometools/propono/atom/client/ClientAtomService.java index 822b5dd..7d2ed15 100644 --- a/src/main/java/org/rometools/propono/atom/client/ClientAtomService.java +++ b/src/main/java/org/rometools/propono/atom/client/ClientAtomService.java @@ -103,6 +103,8 @@ public class ClientAtomService extends AtomService { httpClient.executeMethod(method); final SAXBuilder builder = new SAXBuilder(); + String doc = method.getResponseBodyAsString(); + logger.debug(doc); return builder.build(method.getResponseBodyAsStream()); } catch (final Throwable t) { diff --git a/src/main/java/org/rometools/propono/atom/client/ClientEntry.java b/src/main/java/org/rometools/propono/atom/client/ClientEntry.java index 17d43b9..5af1d76 100644 --- a/src/main/java/org/rometools/propono/atom/client/ClientEntry.java +++ b/src/main/java/org/rometools/propono/atom/client/ClientEntry.java @@ -42,6 +42,7 @@ import com.sun.syndication.feed.atom.Entry; import com.sun.syndication.feed.atom.Link; import com.sun.syndication.io.impl.Atom10Generator; import com.sun.syndication.io.impl.Atom10Parser; +import java.util.Date; /** * Client implementation of Atom entry, extends ROME Entry to add methods for easily getting/setting content, updating and removing the entry from the server. @@ -250,4 +251,11 @@ public class ClientEntry extends Entry { return null; } + @Override + public void setCreated(Date d) { + // protected against null created property (an old Atom 0.3 property) + if (d != null) { + super.setCreated(d); + } + } } diff --git a/src/main/java/org/rometools/propono/atom/server/AtomHandlerFactory.java b/src/main/java/org/rometools/propono/atom/server/AtomHandlerFactory.java index a0b4a6a..f5ce26a 100644 --- a/src/main/java/org/rometools/propono/atom/server/AtomHandlerFactory.java +++ b/src/main/java/org/rometools/propono/atom/server/AtomHandlerFactory.java @@ -34,9 +34,9 @@ public abstract class AtomHandlerFactory { private static Log log = LogFactory.getFactory().getInstance(AtomHandlerFactory.class); - private static final String DEFAULT_PROPERTY_NAME = "com.sun.syndication.propono.atom.server.AtomHandlerFactory"; + private static final String DEFAULT_PROPERTY_NAME = "org.rometools.propono.atom.server.AtomHandlerFactory"; - private static final String FALLBACK_IMPL_NAME = "com.sun.syndication.propono.atom.server.impl.FileBasedAtomHandlerFactory"; + private static final String FALLBACK_IMPL_NAME = "org.rometools.propono.atom.server.impl.FileBasedAtomHandlerFactory"; /* *
Protected constructor to prevent instantiation. Use {@link #newInstance()}.
diff --git a/src/main/java/org/rometools/propono/atom/server/impl/FileBasedCollection.java b/src/main/java/org/rometools/propono/atom/server/impl/FileBasedCollection.java index 7f38d76..5f84600 100644 --- a/src/main/java/org/rometools/propono/atom/server/impl/FileBasedCollection.java +++ b/src/main/java/org/rometools/propono/atom/server/impl/FileBasedCollection.java @@ -777,7 +777,7 @@ public class FileBasedCollection extends Collection { } private String getCategoriesURI() { - if (relativeURIs) { + if (!relativeURIs) { return contextURI + servletPath + "/" + handle + "/" + singular + "/categories"; } else { return servletPath + "/" + handle + "/" + singular + "/categories"; diff --git a/src/test/java/org/rometools/propono/atom/server/AtomClientServerTest.java b/src/test/java/org/rometools/propono/atom/server/AtomClientServerTest.java index 0f5531e..a8fef3b 100644 --- a/src/test/java/org/rometools/propono/atom/server/AtomClientServerTest.java +++ b/src/test/java/org/rometools/propono/atom/server/AtomClientServerTest.java @@ -16,61 +16,78 @@ */ package org.rometools.propono.atom.server; +import com.sun.syndication.feed.atom.Category; +import com.sun.syndication.feed.atom.Content; +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; import java.util.logging.ConsoleHandler; import java.util.logging.Level; import java.util.logging.Logger; -import junit.framework.Test; -import junit.framework.TestSuite; -import org.junit.Ignore; +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertNotNull; +import static junit.framework.TestCase.assertTrue; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; import org.mortbay.http.HttpContext; import org.mortbay.http.HttpServer; import org.mortbay.http.SocketListener; import org.mortbay.jetty.servlet.ServletHandler; -import org.rometools.propono.atom.client.AtomClientTest; +import org.rometools.propono.atom.client.AtomClientFactory; +import org.rometools.propono.atom.client.BasicAuthStrategy; +import org.rometools.propono.atom.client.ClientAtomService; +import org.rometools.propono.atom.client.ClientCollection; +import org.rometools.propono.atom.client.ClientEntry; +import org.rometools.propono.atom.client.ClientMediaEntry; +import org.rometools.propono.atom.client.ClientWorkspace; +import org.rometools.propono.atom.common.Categories; +import org.rometools.propono.atom.common.Collection; +import org.rometools.propono.utils.ProponoException; /** - * Test Propono Atom Client against Atom Server via Jetty. ExtendsAtomClientTest
to start Jetty server, run tests and then stop the Jetty server.
+ * Test Propono Atom Client against Atom Server via Jetty. Extends AtomClientTest
to
+ * start Jetty server, run tests and then stop the Jetty server.
*/
-@Ignore
-public class AtomClientServerTest extends AtomClientTest {
+public class AtomClientServerTest {
- private HttpServer server;
+ private static final Log log = LogFactory.getFactory().getInstance(AtomClientServerTest.class);
+
+ private HttpServer server = null;
public static final int TESTPORT = 8283;
public static final String ENDPOINT = "http://localhost:" + TESTPORT + "/rome/app";
public static final String USERNAME = "admin";
public static final String PASSWORD = "admin";
- public AtomClientServerTest(final String s) {
- super(s);
- }
+ private static ClientAtomService service = null;
- @Override
public String getEndpoint() {
return ENDPOINT;
}
- @Override
public String getUsername() {
return USERNAME;
}
- @Override
public String getPassword() {
return PASSWORD;
}
- public static Test suite() {
- final TestSuite suite = new TestSuite(AtomClientServerTest.class);
- return suite;
- }
-
protected HttpServer getServer() {
return server;
}
- protected void setUp() throws Exception {
+ @Before
+ public void setUpClass() throws Exception {
+ log.info("---------------------------------------------");
+ log.info("Starting Jetty");
+ log.info("---------------------------------------------");
+
final ConsoleHandler handler = new ConsoleHandler();
final Logger logger = Logger.getLogger("org.rometools.propono");
logger.setLevel(Level.FINEST);
@@ -82,6 +99,19 @@ public class AtomClientServerTest extends AtomClientTest {
context.addHandler(servlets);
server.addContext(context);
server.start();
+
+ service = AtomClientFactory.getAtomService(getEndpoint(),
+ new BasicAuthStrategy(getUsername(), getPassword()));
+ }
+
+ @After
+ public void tearDownClass() throws Exception {
+ if (server != null) {
+ log.info("Stoping Jetty");
+ server.stop();
+ server.destroy();
+ server = null;
+ }
}
private void setupServer() throws InterruptedException {
@@ -100,8 +130,8 @@ public class AtomClientServerTest extends AtomClientTest {
private ServletHandler createServletHandler() {
System.setProperty(
- "org.rometools.propono.atom.server.AtomHandlerFactory",
- "org.rometools.propono.atom.server.TestAtomHandlerFactory");
+ "org.rometools.propono.atom.server.AtomHandlerFactory",
+ "org.rometools.propono.atom.server.TestAtomHandlerFactory");
final ServletHandler servlets = new ServletHandler();
servlets.addServlet("app", "/app/*", "org.rometools.propono.atom.server.AtomServlet");
return servlets;
@@ -113,11 +143,295 @@ public class AtomClientServerTest extends AtomClientTest {
return context;
}
- protected void tearDown() throws Exception {
- if (server != null) {
- server.stop();
- server.destroy();
- server = null;
+ /**
+ * Tests that server has introspection doc with at least one workspace.
+ */
+ @Test
+ public void testGetAtomService() throws Exception {
+ assertNotNull(service);
+ assertTrue(service.getWorkspaces().size() > 0);
+ for (final Iterator it = service.getWorkspaces().iterator(); it.hasNext();) {
+ final ClientWorkspace space = (ClientWorkspace) it.next();
+ assertNotNull(space.getTitle());
+ log.debug("Workspace: " + space.getTitle());
+ for (final Iterator colit = space.getCollections().iterator(); colit.hasNext();) {
+ final ClientCollection col = (ClientCollection) colit.next();
+ log.debug(" Collection: " + col.getTitle() + " Accepts: " + col.getAccepts());
+ log.debug(" href: " + col.getHrefResolved());
+ assertNotNull(col.getTitle());
+ }
}
}
+
+ /**
+ * Tests that entries can be posted and removed in all collections that accept entries. Fails if
+ * no collections found that accept entries.
+ */
+ @Test
+ public void testSimpleEntryPostAndRemove() throws Exception {
+ assertNotNull(service);
+ assertTrue(service.getWorkspaces().size() > 0);
+ int count = 0;
+ for (final Iterator it = service.getWorkspaces().iterator(); it.hasNext();) {
+ final ClientWorkspace space = (ClientWorkspace) it.next();
+ assertNotNull(space.getTitle());
+
+ for (final Iterator colit = space.getCollections().iterator(); colit.hasNext();) {
+ final ClientCollection col = (ClientCollection) colit.next();
+ if (col.accepts(Collection.ENTRY_TYPE)) {
+
+ // we found a collection that accepts entries, so post one
+ final ClientEntry m1 = col.createEntry();
+ m1.setTitle("Test post");
+ final Content c = new Content();
+ c.setValue("This is a test post");
+ c.setType("html");
+ m1.setContent(c);
+
+ col.addEntry(m1);
+
+ // entry should now exist on server
+ final ClientEntry m2 = col.getEntry(m1.getEditURI());
+ assertNotNull(m2);
+
+ // remove entry
+ m2.remove();
+
+ // fetching entry now should result in exception
+ boolean failed = false;
+ try {
+ col.getEntry(m1.getEditURI());
+ } catch (final ProponoException e) {
+ failed = true;
+ }
+ assertTrue(failed);
+ count++;
+ }
+ }
+ }
+ assertTrue(count > 0);
+ }
+
+ /**
+ * Tests that entries can be posted, updated and removed in all collections that accept entries.
+ * Fails if no collections found that accept entries.
+ */
+ @Test
+ public void testSimpleEntryPostUpdateAndRemove() throws Exception {
+ assertNotNull(service);
+ assertTrue(service.getWorkspaces().size() > 0);
+ int count = 0;
+ for (final Iterator it = service.getWorkspaces().iterator(); it.hasNext();) {
+ final ClientWorkspace space = (ClientWorkspace) it.next();
+ assertNotNull(space.getTitle());
+
+ for (final Iterator colit = space.getCollections().iterator(); colit.hasNext();) {
+ final ClientCollection col = (ClientCollection) colit.next();
+ if (col.accepts(Collection.ENTRY_TYPE)) {
+
+ // we found a collection that accepts entries, so post one
+ final ClientEntry m1 = col.createEntry();
+ m1.setTitle(col.getTitle() + ": Test post");
+ final Content c = new Content();
+ c.setValue("This is a test post");
+ c.setType("html");
+ m1.setContent(c);
+
+ col.addEntry(m1);
+
+ // entry should now exist on server
+ final ClientEntry m2 = col.getEntry(m1.getEditURI());
+ assertNotNull(m2);
+
+ m2.setTitle(col.getTitle() + ": Updated title");
+ m2.update();
+
+ // entry should now be updated on server
+ final ClientEntry m3 = col.getEntry(m1.getEditURI());
+ assertEquals(col.getTitle() + ": Updated title", m3.getTitle());
+
+ // remove entry
+ m3.remove();
+
+ // fetching entry now should result in exception
+ boolean failed = false;
+ try {
+ col.getEntry(m1.getEditURI());
+ } catch (final ProponoException e) {
+ failed = true;
+ }
+ assertTrue(failed);
+ count++;
+ }
+ }
+ }
+ assertTrue(count > 0);
+ }
+
+ @Test
+ public void testFindWorkspace() throws Exception {
+ assertNotNull(service);
+ final ClientWorkspace ws = (ClientWorkspace) service.findWorkspace("adminblog");
+ if (ws != null) {
+ final ClientCollection col = (ClientCollection) ws.findCollection(null, "entry");
+ final ClientEntry entry = col.createEntry();
+ entry.setTitle("NPE on submitting order query");
+ entry.setContent("This is a bad one!", Content.HTML);
+ col.addEntry(entry);
+
+ // entry should now exist on server
+ final ClientEntry saved = col.getEntry(entry.getEditURI());
+ assertNotNull(saved);
+
+ // remove entry
+ saved.remove();
+
+ // fetching entry now should result in exception
+ boolean failed = false;
+ try {
+ col.getEntry(saved.getEditURI());
+ } catch (final ProponoException e) {
+ failed = true;
+ }
+ assertTrue(failed);
+ }
+ }
+
+ /**
+ * Test posting an entry to every available collection with a fixed and an unfixed category if
+ * server support allows, then cleanup.
+ */
+ @Test
+ public void testEntryPostWithCategories() throws Exception {
+ assertNotNull(service);
+ assertTrue(service.getWorkspaces().size() > 0);
+ int count = 0;
+ for (final Iterator it = service.getWorkspaces().iterator(); it.hasNext();) {
+ final ClientWorkspace space = (ClientWorkspace) it.next();
+ assertNotNull(space.getTitle());
+
+ for (final Iterator colit = space.getCollections().iterator(); colit.hasNext();) {
+ final ClientCollection col = (ClientCollection) colit.next();
+ if (col.accepts(Collection.ENTRY_TYPE)) {
+
+ // we found a collection that accepts GIF, so post one
+ final ClientEntry m1 = col.createEntry();
+ m1.setTitle("Test post");
+ final Content c = new Content();
+ c.setValue("This is a test post");
+ c.setType("html");
+ m1.setContent(c);
+
+ // if possible, pick one fixed an un unfixed category
+ Category fixedCat = null;
+ Category unfixedCat = null;
+ final List entryCats = new ArrayList();
+ for (int i = 0; i < col.getCategories().size(); i++) {
+ final Categories cats = (Categories) col.getCategories().get(i);
+ if (cats.isFixed() && fixedCat == null) {
+ final String scheme = cats.getScheme();
+ fixedCat = (Category) cats.getCategories().get(0);
+ if (fixedCat.getScheme() == null) {
+ fixedCat.setScheme(scheme);
+ }
+ entryCats.add(fixedCat);
+ } else if (!cats.isFixed() && unfixedCat == null) {
+ final String scheme = cats.getScheme();
+ unfixedCat = new Category();
+ unfixedCat.setScheme(scheme);
+ unfixedCat.setTerm("tagster");
+ entryCats.add(unfixedCat);
+ }
+ }
+ m1.setCategories(entryCats);
+ col.addEntry(m1);
+
+ // entry should now exist on server
+ final ClientEntry m2 = col.getEntry(m1.getEditURI());
+ assertNotNull(m2);
+
+ if (fixedCat != null) {
+ // we added a fixed category, let's make sure it's there
+ boolean foundCat = false;
+ for (final Object element : m2.getCategories()) {
+ final Category cat = (Category) element;
+ if (cat.getTerm().equals(fixedCat.getTerm())) {
+ foundCat = true;
+ }
+ }
+ assertTrue(foundCat);
+ }
+
+ if (unfixedCat != null) {
+ // we added an unfixed category, let's make sure it's there
+ boolean foundCat = false;
+ for (final Object element : m2.getCategories()) {
+ final Category cat = (Category) element;
+ if (cat.getTerm().equals(unfixedCat.getTerm())) {
+ foundCat = true;
+ }
+ }
+ assertTrue(foundCat);
+ }
+
+ // remove entry
+ m2.remove();
+
+ // fetching entry now should result in exception
+ boolean failed = false;
+ try {
+ col.getEntry(m1.getEditURI());
+ } catch (final ProponoException e) {
+ failed = true;
+ }
+ assertTrue(failed);
+ count++;
+ }
+ }
+ }
+ assertTrue(count > 0);
+ }
+
+ /**
+ * Post media entry to every media colletion avialable on server, then cleanup.
+ */
+ public void testMediaPost() throws Exception {
+ assertNotNull(service);
+ assertTrue(service.getWorkspaces().size() > 0);
+ int count = 0;
+ for (final Iterator it = service.getWorkspaces().iterator(); it.hasNext();) {
+ final ClientWorkspace space = (ClientWorkspace) it.next();
+ assertNotNull(space.getTitle());
+
+ for (final Iterator colit = space.getCollections().iterator(); colit.hasNext();) {
+ final ClientCollection col = (ClientCollection) colit.next();
+ if (col.accepts("image/gif")) {
+
+ // we found a collection that accepts GIF, so post one
+ final ClientMediaEntry m1 = col.createMediaEntry("duke" + count, "duke" + count, "image/gif", new FileInputStream(
+ "test/testdata/duke-wave-shadow.gif"));
+ col.addEntry(m1);
+
+ // entry should now exist on server
+ final ClientMediaEntry m2 = (ClientMediaEntry) col.getEntry(m1.getEditURI());
+ assertNotNull(m2);
+
+ // remove entry
+ m2.remove();
+
+ // fetching entry now should result in exception
+ boolean failed = false;
+ try {
+ col.getEntry(m1.getEditURI());
+ } catch (final ProponoException e) {
+ failed = true;
+ }
+ assertTrue(failed);
+ count++;
+ }
+ }
+ }
+ assertTrue(count > 0);
+ }
+
}
diff --git a/src/test/java/org/rometools/propono/atom/server/TestAtomHandlerFactory.java b/src/test/java/org/rometools/propono/atom/server/TestAtomHandlerFactory.java
index 97e58ec..d3e9b10 100644
--- a/src/test/java/org/rometools/propono/atom/server/TestAtomHandlerFactory.java
+++ b/src/test/java/org/rometools/propono/atom/server/TestAtomHandlerFactory.java
@@ -23,6 +23,6 @@ public class TestAtomHandlerFactory extends AtomHandlerFactory {
@Override
public AtomHandler newAtomHandler(final HttpServletRequest req, final HttpServletResponse res) {
- return new TestAtomHandlerImpl(req, "build/testuploaddir");
+ return new TestAtomHandlerImpl(req, "target/testuploaddir");
}
}
diff --git a/src/test/resources/simplelog.properties b/src/test/resources/simplelog.properties
index 2277f2f..4fd23ca 100644
--- a/src/test/resources/simplelog.properties
+++ b/src/test/resources/simplelog.properties
@@ -14,6 +14,6 @@
# copyright in this work, please see the NOTICE file in the top level
# directory of this distribution.
+org.apache.commons.logging.simplelog.log.org.rometools.propono.atom=debug
org.apache.commons.logging.simplelog.log.org.rometools.propono.atom.server.impl.FileBasedAtomHandler=debug
-
-org.apache.commons.logging.simplelog.log.org.rometools.propono.atom.client.AtomClientTest=debug
+org.apache.commons.logging.simplelog.log.org.rometools.propono.atom.client.AtomClientServerTest=debug