From 507e00fb190713b1654579123d284bcd3d750abe Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Wed, 10 Apr 2013 10:31:19 +0000
Subject: [PATCH] Partial fix for OPENDJ-693: Implement modify/update support
---
opendj3/opendj-rest2ldap/src/test/java/org/forgerock/opendj/rest2ldap/BasicRequestsTest.java | 134 ++++++++++++++++++++++++++++++++------------
1 files changed, 98 insertions(+), 36 deletions(-)
diff --git a/opendj3/opendj-rest2ldap/src/test/java/org/forgerock/opendj/rest2ldap/BasicRequestsTest.java b/opendj3/opendj-rest2ldap/src/test/java/org/forgerock/opendj/rest2ldap/BasicRequestsTest.java
index 28a8851..2123a74 100644
--- a/opendj3/opendj-rest2ldap/src/test/java/org/forgerock/opendj/rest2ldap/BasicRequestsTest.java
+++ b/opendj3/opendj-rest2ldap/src/test/java/org/forgerock/opendj/rest2ldap/BasicRequestsTest.java
@@ -19,20 +19,27 @@
import static org.fest.assertions.Fail.fail;
import static org.forgerock.json.resource.Requests.newDeleteRequest;
import static org.forgerock.json.resource.Requests.newReadRequest;
+import static org.forgerock.json.resource.Requests.newUpdateRequest;
import static org.forgerock.json.resource.Resources.newCollection;
import static org.forgerock.json.resource.Resources.newInternalConnection;
import static org.forgerock.opendj.ldap.Connections.newInternalConnectionFactory;
import static org.forgerock.opendj.rest2ldap.Rest2LDAP.object;
import static org.forgerock.opendj.rest2ldap.Rest2LDAP.simple;
+import static org.forgerock.opendj.rest2ldap.TestUtils.asResource;
+import static org.forgerock.opendj.rest2ldap.TestUtils.content;
+import static org.forgerock.opendj.rest2ldap.TestUtils.ctx;
+import static org.forgerock.opendj.rest2ldap.TestUtils.field;
+import static org.forgerock.opendj.rest2ldap.TestUtils.object;
import java.io.IOException;
+import org.forgerock.json.fluent.JsonValue;
+import org.forgerock.json.resource.BadRequestException;
import org.forgerock.json.resource.Connection;
import org.forgerock.json.resource.NotFoundException;
import org.forgerock.json.resource.PreconditionFailedException;
import org.forgerock.json.resource.RequestHandler;
import org.forgerock.json.resource.Resource;
-import org.forgerock.json.resource.RootContext;
import org.forgerock.opendj.ldap.ConnectionFactory;
import org.forgerock.opendj.ldap.MemoryBackend;
import org.forgerock.opendj.ldif.LDIFEntryReader;
@@ -54,10 +61,10 @@
public void testDelete() throws Exception {
final RequestHandler handler = newCollection(builder().build());
final Connection connection = newInternalConnection(handler);
- final Resource resource = connection.delete(c(), newDeleteRequest("/test1"));
- checkTestUser1(resource);
+ final Resource resource = connection.delete(ctx(), newDeleteRequest("/test1"));
+ checkResourcesAreEqual(resource, getTestUser1(12345));
try {
- connection.read(c(), newReadRequest("/test1"));
+ connection.read(ctx(), newReadRequest("/test1"));
fail("Read succeeded unexpectedly");
} catch (final NotFoundException e) {
// Expected.
@@ -69,10 +76,10 @@
final RequestHandler handler = newCollection(builder().build());
final Connection connection = newInternalConnection(handler);
final Resource resource =
- connection.delete(c(), newDeleteRequest("/test1").setRevision("12345"));
- checkTestUser1(resource);
+ connection.delete(ctx(), newDeleteRequest("/test1").setRevision("12345"));
+ checkResourcesAreEqual(resource, getTestUser1(12345));
try {
- connection.read(c(), newReadRequest("/test1"));
+ connection.read(ctx(), newReadRequest("/test1"));
fail("Read succeeded unexpectedly");
} catch (final NotFoundException e) {
// Expected.
@@ -83,50 +90,50 @@
public void testDeleteMVCCNoMatch() throws Exception {
final RequestHandler handler = newCollection(builder().build());
final Connection connection = newInternalConnection(handler);
- connection.delete(c(), newDeleteRequest("/test1").setRevision("12346"));
+ connection.delete(ctx(), newDeleteRequest("/test1").setRevision("12346"));
}
@Test(expectedExceptions = NotFoundException.class)
public void testDeleteNotFound() throws Exception {
final RequestHandler handler = newCollection(builder().build());
final Connection connection = newInternalConnection(handler);
- connection.delete(c(), newDeleteRequest("/missing"));
+ connection.delete(ctx(), newDeleteRequest("/missing"));
}
@Test
public void testRead() throws Exception {
final RequestHandler handler = newCollection(builder().build());
final Resource resource =
- newInternalConnection(handler).read(c(), newReadRequest("/test1"));
- checkTestUser1(resource);
+ newInternalConnection(handler).read(ctx(), newReadRequest("/test1"));
+ checkResourcesAreEqual(resource, getTestUser1(12345));
}
@Test(expectedExceptions = NotFoundException.class)
public void testReadNotFound() throws Exception {
final RequestHandler handler = newCollection(builder().build());
- newInternalConnection(handler).read(c(), newReadRequest("/missing"));
+ newInternalConnection(handler).read(ctx(), newReadRequest("/missing"));
}
@Test
public void testReadSelectAllFields() throws Exception {
final RequestHandler handler = newCollection(builder().build());
final Resource resource =
- newInternalConnection(handler).read(c(), newReadRequest("/test1").addField("/"));
- checkTestUser1(resource);
+ newInternalConnection(handler).read(ctx(), newReadRequest("/test1").addField("/"));
+ checkResourcesAreEqual(resource, getTestUser1(12345));
}
@Test
public void testReadSelectPartial() throws Exception {
final RequestHandler handler = newCollection(builder().build());
final Resource resource =
- newInternalConnection(handler).read(c(),
+ newInternalConnection(handler).read(ctx(),
newReadRequest("/test1").addField("surname"));
assertThat(resource.getId()).isEqualTo("test1");
assertThat(resource.getRevision()).isEqualTo("12345");
- assertThat(resource.getContent().get("id").asString()).isNull();
+ assertThat(resource.getContent().get("_id").asString()).isNull();
assertThat(resource.getContent().get("displayName").asString()).isNull();
assertThat(resource.getContent().get("surname").asString()).isEqualTo("user 1");
- assertThat(resource.getContent().get("rev").asString()).isNull();
+ assertThat(resource.getContent().get("_rev").asString()).isNull();
}
// Disabled - see CREST-86 (Should JSON resource fields be case insensitive?)
@@ -134,14 +141,60 @@
public void testReadSelectPartialInsensitive() throws Exception {
final RequestHandler handler = newCollection(builder().build());
final Resource resource =
- newInternalConnection(handler).read(c(),
+ newInternalConnection(handler).read(ctx(),
newReadRequest("/test1").addField("SURNAME"));
assertThat(resource.getId()).isEqualTo("test1");
assertThat(resource.getRevision()).isEqualTo("12345");
- assertThat(resource.getContent().get("id").asString()).isNull();
+ assertThat(resource.getContent().get("_id").asString()).isNull();
assertThat(resource.getContent().get("displayName").asString()).isNull();
assertThat(resource.getContent().get("surname").asString()).isEqualTo("user 1");
- assertThat(resource.getContent().get("rev").asString()).isNull();
+ assertThat(resource.getContent().get("_rev").asString()).isNull();
+ }
+
+ @Test
+ public void testUpdate() throws Exception {
+ final RequestHandler handler = newCollection(builder().build());
+ final Connection connection = newInternalConnection(handler);
+ final Resource resource1 =
+ connection.update(ctx(), newUpdateRequest("/test1", getTestUser1Updated(12345)));
+ checkResourcesAreEqual(resource1, getTestUser1Updated(12345));
+ final Resource resource2 = connection.read(ctx(), newReadRequest("/test1"));
+ checkResourcesAreEqual(resource2, getTestUser1Updated(12345));
+ }
+
+ @Test
+ public void testUpdateMVCCMatch() throws Exception {
+ final RequestHandler handler = newCollection(builder().build());
+ final Connection connection = newInternalConnection(handler);
+ final Resource resource1 =
+ connection.update(ctx(), newUpdateRequest("/test1", getTestUser1Updated(12345))
+ .setRevision("12345"));
+ checkResourcesAreEqual(resource1, getTestUser1Updated(12345));
+ final Resource resource2 = connection.read(ctx(), newReadRequest("/test1"));
+ checkResourcesAreEqual(resource2, getTestUser1Updated(12345));
+ }
+
+ @Test(expectedExceptions = PreconditionFailedException.class)
+ public void testUpdateMVCCNoMatch() throws Exception {
+ final RequestHandler handler = newCollection(builder().build());
+ final Connection connection = newInternalConnection(handler);
+ connection.update(ctx(), newUpdateRequest("/test1", getTestUser1Updated(12345))
+ .setRevision("12346"));
+ }
+
+ @Test(expectedExceptions = NotFoundException.class)
+ public void testUpdateNotFound() throws Exception {
+ final RequestHandler handler = newCollection(builder().build());
+ final Connection connection = newInternalConnection(handler);
+ connection.update(ctx(), newUpdateRequest("/missing", getTestUser1Updated(12345)));
+ }
+
+ @Test(expectedExceptions = BadRequestException.class)
+ public void testUpdateReadOnlyAttribute() throws Exception {
+ final RequestHandler handler = newCollection(builder().build());
+ final Connection connection = newInternalConnection(handler);
+ // Etag is read-only.
+ connection.update(ctx(), newUpdateRequest("/test1", getTestUser1Updated(99999)));
}
private Builder builder() throws IOException {
@@ -149,24 +202,23 @@
.useEtagAttribute().useClientDNNaming("uid").readOnUpdatePolicy(
ReadOnUpdatePolicy.CONTROLS).authorizationPolicy(AuthorizationPolicy.NONE)
.additionalLDAPAttribute("objectClass", "top", "person").mapper(
- object().attribute("id", simple("uid").isSingleValued().isRequired())
- .attribute("displayName",
- simple("cn").isSingleValued().isRequired()).attribute(
- "surname", simple("sn").isSingleValued().isRequired())
- .attribute("rev", simple("etag").isSingleValued().isRequired()));
+ object().attribute(
+ "_id",
+ simple("uid").isSingleValued().isRequired().writability(
+ WritabilityPolicy.CREATE_ONLY)).attribute("displayName",
+ simple("cn").isSingleValued().isRequired()).attribute("surname",
+ simple("sn").isSingleValued().isRequired()).attribute(
+ "_rev",
+ simple("etag").isSingleValued().isRequired().writability(
+ WritabilityPolicy.READ_ONLY)));
}
- private RootContext c() {
- return new RootContext();
- }
-
- private void checkTestUser1(final Resource resource) {
- assertThat(resource.getId()).isEqualTo("test1");
- assertThat(resource.getRevision()).isEqualTo("12345");
- assertThat(resource.getContent().get("id").asString()).isEqualTo("test1");
- assertThat(resource.getContent().get("displayName").asString()).isEqualTo("test user 1");
- assertThat(resource.getContent().get("surname").asString()).isEqualTo("user 1");
- assertThat(resource.getContent().get("rev").asString()).isEqualTo("12345");
+ private void checkResourcesAreEqual(final Resource actual, final JsonValue expected) {
+ final Resource expectedResource = asResource(expected);
+ assertThat(actual.getId()).isEqualTo(expectedResource.getId());
+ assertThat(actual.getRevision()).isEqualTo(expectedResource.getRevision());
+ assertThat(actual.getContent().getObject()).isEqualTo(
+ expectedResource.getContent().getObject());
}
private ConnectionFactory getConnectionFactory() throws IOException {
@@ -200,4 +252,14 @@
return newInternalConnectionFactory(backend);
}
+
+ private JsonValue getTestUser1(final int rev) {
+ return content(object(field("_id", "test1"), field("_rev", String.valueOf(rev)), field(
+ "displayName", "test user 1"), field("surname", "user 1")));
+ }
+
+ private JsonValue getTestUser1Updated(final int rev) {
+ return content(object(field("_id", "test1"), field("_rev", String.valueOf(rev)), field(
+ "displayName", "changed"), field("surname", "user 1")));
+ }
}
--
Gitblit v1.10.0