Skip to content

Commit

Permalink
support the Atom Slug: header to provide the name of the node to crea…
Browse files Browse the repository at this point in the history
…te on POST to an existing collection node
  • Loading branch information
cbeer committed Jul 30, 2013
1 parent 88bfddc commit f9edd2f
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 4 deletions.
11 changes: 10 additions & 1 deletion fcrepo-http-api/src/main/java/org/fcrepo/api/FedoraNodes.java
Expand Up @@ -401,6 +401,8 @@ public Response createObject(@PathParam("path")
final String checksum,
@HeaderParam("Content-Type")
final MediaType requestContentType,
@HeaderParam("Slug")
final String slug,
@Context
final UriInfo uriInfo, final InputStream requestBodyStream)
throws RepositoryException, IOException, InvalidChecksumException, URISyntaxException {
Expand All @@ -410,7 +412,14 @@ public Response createObject(@PathParam("path")


if (nodeService.exists(session, path)) {
final String pid = pidMinter.mintPid();
final String pid;

if (slug != null) {
pid = slug;
} else {
pid = pidMinter.mintPid();
}

newObjectPath = path + "/" + pid;
} else {
newObjectPath = path;
Expand Down
53 changes: 50 additions & 3 deletions fcrepo-http-api/src/test/java/org/fcrepo/api/FedoraNodesTest.java
Expand Up @@ -63,6 +63,7 @@
import org.fcrepo.FedoraObject;
import org.fcrepo.FedoraResource;
import org.fcrepo.exception.InvalidChecksumException;
import org.fcrepo.identifiers.PidMinter;
import org.fcrepo.identifiers.UUIDPidMinter;
import org.fcrepo.rdf.GraphProperties;
import org.fcrepo.rdf.GraphSubjects;
Expand Down Expand Up @@ -115,6 +116,9 @@ public class FedoraNodesTest {

@Mock
private HttpServletResponse mockResponse;

@Mock
private PidMinter mockPidMinter;

private UriInfo uriInfo;

Expand All @@ -126,7 +130,7 @@ public void setUp() throws Exception {
setField(testObj, "nodeService", mockNodes);
this.uriInfo = getUriInfoImpl();
setField(testObj, "uriInfo", uriInfo);
setField(testObj, "pidMinter", new UUIDPidMinter());
setField(testObj, "pidMinter", mockPidMinter);
setField(testObj, "objectService", mockObjects);
mockSession = mockSession(testObj);
setField(testObj, "session", mockSession);
Expand All @@ -152,14 +156,57 @@ public void testCreateObject() throws RepositoryException, IOException,
when(mockNode.getPath()).thenReturn(path);
final Response actual =
testObj.createObject(createPathList(pid), FEDORA_OBJECT, null,
null, getUriInfoImpl(), null);
null, null, getUriInfoImpl(), null);
assertNotNull(actual);
assertEquals(CREATED.getStatusCode(), actual.getStatus());
assertTrue(actual.getEntity().toString().endsWith(pid));
verify(mockObjects).createObject(mockSession, path);
verify(mockSession).save();
}

@Test
public void testCreateChildObject() throws RepositoryException, IOException,
InvalidChecksumException, URISyntaxException, NoSuchFieldException {

setField(testObj, "pidMinter", mockPidMinter);
final String pid = "testObject";
final String path = "/" + pid + "/a";
when(mockNodes.exists(mockSession, "/" + pid)).thenReturn(true);
when(mockPidMinter.mintPid()).thenReturn("a");
when(mockObjects.createObject(mockSession, path)).thenReturn(mockObject);
when(mockObject.getNode()).thenReturn(mockNode);
when(mockNode.getPath()).thenReturn(path);
final Response actual =
testObj.createObject(createPathList(pid), FEDORA_OBJECT, null,
null, null, getUriInfoImpl(), null);
assertNotNull(actual);
assertEquals(CREATED.getStatusCode(), actual.getStatus());
assertTrue(actual.getEntity().toString().endsWith("a"));
verify(mockObjects).createObject(mockSession, path);
verify(mockSession).save();
}

@Test
public void testCreateChildObjectWithSlug() throws RepositoryException, IOException,
InvalidChecksumException, URISyntaxException, NoSuchFieldException {
setField(testObj, "pidMinter", mockPidMinter);

final String pid = "testObject";
final String path = "/" + pid + "/some-slug";
when(mockNodes.exists(mockSession, "/" + pid)).thenReturn(true);
when(mockObjects.createObject(mockSession, path)).thenReturn(mockObject);
when(mockObject.getNode()).thenReturn(mockNode);
when(mockNode.getPath()).thenReturn(path);
final Response actual =
testObj.createObject(createPathList(pid), FEDORA_OBJECT, null,
null, "some-slug", getUriInfoImpl(), null);
assertNotNull(actual);
assertEquals(CREATED.getStatusCode(), actual.getStatus());
assertTrue(actual.getEntity().toString().endsWith("some-slug"));
verify(mockObjects).createObject(mockSession, path);
verify(mockSession).save();
}

@Test
public void testCreateDatastream() throws RepositoryException, IOException,
InvalidChecksumException, URISyntaxException {
Expand All @@ -178,7 +225,7 @@ public void testCreateDatastream() throws RepositoryException, IOException,
when(mockNode.getPath()).thenReturn(dsPath);
final Response actual =
testObj.createObject(createPathList(pid, dsId),
FEDORA_DATASTREAM, null, null, getUriInfoImpl(),
FEDORA_DATASTREAM, null, null, null, getUriInfoImpl(),
dsContentStream);
assertEquals(CREATED.getStatusCode(), actual.getStatus());
verify(mockDatastreams)
Expand Down
Expand Up @@ -108,6 +108,24 @@ public void testIngestWithNew() throws Exception {
getStatus(new HttpGet(location)));
}

@Test
public void testIngestWithSlug() throws Exception {
final HttpPost method = postObjMethod("");
method.addHeader("Slug", "xyz");
final HttpResponse response = client.execute(method);
final String content = EntityUtils.toString(response.getEntity());
final int status = response.getStatusLine().getStatusCode();
assertEquals("Didn't get a CREATED response! Got content:\n" + content,
CREATED.getStatusCode(), status);
assertTrue("Response wasn't a PID", compile("[a-z]+").matcher(content)
.find());
final String location = response.getFirstHeader("Location").getValue();
assertNotEquals(serverAddress + "/objects", location);

assertEquals("Object wasn't created!", OK.getStatusCode(),
getStatus(new HttpGet(location)));
}

@Test
public void testDeleteObject() throws Exception {
assertEquals(CREATED.getStatusCode(),
Expand Down

0 comments on commit f9edd2f

Please sign in to comment.