| | |
| | | * Header, with the fields enclosed by brackets [] replaced by your own identifying |
| | | * information: "Portions copyright [year] [name of copyright owner]". |
| | | * |
| | | * Copyright 2013-2015 ForgeRock AS. |
| | | * Copyright 2013-2016 ForgeRock AS. |
| | | */ |
| | | package org.forgerock.opendj.rest2ldap; |
| | | |
| | |
| | | import org.forgerock.json.resource.NotSupportedException; |
| | | import org.forgerock.json.resource.PreconditionFailedException; |
| | | import org.forgerock.json.resource.QueryResponse; |
| | | import org.forgerock.json.resource.Requests; |
| | | import org.forgerock.json.resource.ResourceResponse; |
| | | import org.forgerock.opendj.ldap.ConnectionFactory; |
| | | import org.forgerock.opendj.ldap.IntermediateResponseHandler; |
| | | import org.forgerock.opendj.ldap.LdapException; |
| | | import org.forgerock.opendj.ldap.LdapResultHandler; |
| | | import org.forgerock.opendj.ldap.MemoryBackend; |
| | | import org.forgerock.opendj.ldap.RequestContext; |
| | |
| | | import org.forgerock.opendj.ldap.responses.Result; |
| | | import org.forgerock.opendj.ldif.LDIFEntryReader; |
| | | import org.forgerock.opendj.rest2ldap.Rest2LDAP.Builder; |
| | | import org.forgerock.services.context.Context; |
| | | import org.forgerock.testng.ForgeRockTestCase; |
| | | import org.forgerock.util.query.QueryFilter; |
| | | import org.testng.annotations.Test; |
| | |
| | | final Connection connection = newConnection(); |
| | | final List<ResourceResponse> resources = new LinkedList<>(); |
| | | final QueryResponse result = connection.query( |
| | | ctx(), Requests.newQueryRequest("").setQueryFilter(NO_FILTER), resources); |
| | | newAuthConnectionContext(), newQueryRequest("").setQueryFilter(NO_FILTER), resources); |
| | | assertThat(resources).hasSize(5); |
| | | assertThat(result.getPagedResultsCookie()).isNull(); |
| | | assertThat(result.getTotalPagedResults()).isEqualTo(-1); |
| | |
| | | public void testQueryNone() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | final List<ResourceResponse> resources = new LinkedList<>(); |
| | | final QueryResponse result = connection.query( |
| | | ctx(), Requests.newQueryRequest("").setQueryFilter(QueryFilter.<JsonPointer>alwaysFalse()), resources); |
| | | final QueryResponse result = connection.query(newAuthConnectionContext(), |
| | | newQueryRequest("").setQueryFilter(QueryFilter.<JsonPointer> alwaysFalse()), resources); |
| | | assertThat(resources).hasSize(0); |
| | | assertThat(result.getPagedResultsCookie()).isNull(); |
| | | assertThat(result.getTotalPagedResults()).isEqualTo(-1); |
| | |
| | | |
| | | // Read first page. |
| | | QueryResponse result = connection.query( |
| | | ctx(), newQueryRequest("").setQueryFilter(NO_FILTER).setPageSize(2), resources); |
| | | newAuthConnectionContext(), newQueryRequest("").setQueryFilter(NO_FILTER).setPageSize(2), resources); |
| | | assertThat(result.getPagedResultsCookie()).isNotNull(); |
| | | assertThat(resources).hasSize(2); |
| | | assertThat(resources.get(0).getId()).isEqualTo("test1"); |
| | |
| | | resources.clear(); |
| | | |
| | | // Read second page. |
| | | result = connection.query(ctx(), |
| | | result = connection.query(newAuthConnectionContext(), |
| | | newQueryRequest("").setQueryFilter(NO_FILTER).setPageSize(2).setPagedResultsCookie(cookie), resources); |
| | | assertThat(result.getPagedResultsCookie()).isNotNull(); |
| | | assertThat(resources).hasSize(2); |
| | |
| | | resources.clear(); |
| | | |
| | | // Read third page. |
| | | result = connection.query(ctx(), |
| | | result = connection.query(newAuthConnectionContext(), |
| | | newQueryRequest("").setQueryFilter(NO_FILTER).setPageSize(2).setPagedResultsCookie(cookie), resources); |
| | | assertThat(result.getPagedResultsCookie()).isNull(); |
| | | assertThat(resources).hasSize(1); |
| | |
| | | public void testQueryPageResultsIndexed() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | final List<ResourceResponse> resources = new ArrayList<>(); |
| | | QueryResponse result = connection.query(ctx(), |
| | | QueryResponse result = connection.query(newAuthConnectionContext(), |
| | | newQueryRequest("").setQueryFilter(NO_FILTER).setPageSize(2).setPagedResultsOffset(1), resources); |
| | | assertThat(result.getPagedResultsCookie()).isNotNull(); |
| | | assertThat(resources).hasSize(2); |
| | |
| | | |
| | | @Test(expectedExceptions = NotFoundException.class) |
| | | public void testDelete() throws Exception { |
| | | final Context context = newAuthConnectionContext(); |
| | | final Connection connection = newConnection(); |
| | | final ResourceResponse resource = connection.delete(ctx(), newDeleteRequest("/test1")); |
| | | final ResourceResponse resource = connection.delete(context, newDeleteRequest("/test1")); |
| | | checkResourcesAreEqual(resource, getTestUser1(12345)); |
| | | connection.read(ctx(), newReadRequest("/test1")); |
| | | connection.read(context, newReadRequest("/test1")); |
| | | } |
| | | |
| | | @Test(expectedExceptions = NotFoundException.class) |
| | | public void testDeleteMVCCMatch() throws Exception { |
| | | final Context context = newAuthConnectionContext(); |
| | | final Connection connection = newConnection(); |
| | | final ResourceResponse resource = connection.delete(ctx(), newDeleteRequest("/test1").setRevision("12345")); |
| | | final ResourceResponse resource = connection.delete(context, newDeleteRequest("/test1").setRevision("12345")); |
| | | checkResourcesAreEqual(resource, getTestUser1(12345)); |
| | | connection.read(ctx(), newReadRequest("/test1")); |
| | | connection.read(context, newReadRequest("/test1")); |
| | | } |
| | | |
| | | @Test(expectedExceptions = PreconditionFailedException.class) |
| | | public void testDeleteMVCCNoMatch() throws Exception { |
| | | final Context context = newAuthConnectionContext(); |
| | | final Connection connection = newConnection(); |
| | | connection.delete(ctx(), newDeleteRequest("/test1").setRevision("12346")); |
| | | connection.delete(context, newDeleteRequest("/test1").setRevision("12346")); |
| | | } |
| | | |
| | | @Test(expectedExceptions = NotFoundException.class) |
| | | public void testDeleteNotFound() throws Exception { |
| | | final Context context = newAuthConnectionContext(); |
| | | final Connection connection = newConnection(); |
| | | connection.delete(ctx(), newDeleteRequest("/missing")); |
| | | connection.delete(context, newDeleteRequest("/missing")); |
| | | } |
| | | |
| | | @Test |
| | | public void testPatch() throws Exception { |
| | | final Context context = newAuthConnectionContext(); |
| | | final Connection connection = newConnection(); |
| | | final ResourceResponse resource1 = |
| | | connection.patch(ctx(), newPatchRequest("/test1", add("/name/displayName", "changed"))); |
| | | final ResourceResponse resource1 = connection.patch(context, |
| | | newPatchRequest("/test1", add("/name/displayName", "changed"))); |
| | | checkResourcesAreEqual(resource1, getTestUser1Updated(12345)); |
| | | final ResourceResponse resource2 = connection.read(ctx(), newReadRequest("/test1")); |
| | | final ResourceResponse resource2 = connection.read(context, newReadRequest("/test1")); |
| | | checkResourcesAreEqual(resource2, getTestUser1Updated(12345)); |
| | | } |
| | | |
| | | @Test |
| | | public void testPatchEmpty() throws Exception { |
| | | final List<Request> requests = new LinkedList<>(); |
| | | final Context context = newAuthConnectionContext(requests); |
| | | final Connection connection = newConnection(requests); |
| | | final ResourceResponse resource1 = connection.patch(ctx(), newPatchRequest("/test1")); |
| | | final ResourceResponse resource1 = connection.patch(context, newPatchRequest("/test1")); |
| | | checkResourcesAreEqual(resource1, getTestUser1(12345)); |
| | | |
| | | /* |
| | |
| | | assertThat(requests).hasSize(1); |
| | | assertThat(requests.get(0)).isInstanceOf(SearchRequest.class); |
| | | |
| | | final ResourceResponse resource2 = connection.read(ctx(), newReadRequest("/test1")); |
| | | final ResourceResponse resource2 = connection.read(context, newReadRequest("/test1")); |
| | | checkResourcesAreEqual(resource2, getTestUser1(12345)); |
| | | } |
| | | |
| | | @Test |
| | | public void testPatchAddOptionalAttribute() throws Exception { |
| | | final Context context = newAuthConnectionContext(); |
| | | final Connection connection = newConnection(); |
| | | final JsonValue newContent = getTestUser1(12345); |
| | | newContent.put("description", asList("one", "two")); |
| | | final ResourceResponse resource1 = |
| | | connection.patch(ctx(), newPatchRequest("/test1", add("/description", asList("one", |
| | | "two")))); |
| | | connection.patch(context, |
| | | newPatchRequest("/test1", add("/description", asList("one", "two")))); |
| | | checkResourcesAreEqual(resource1, newContent); |
| | | final ResourceResponse resource2 = connection.read(ctx(), newReadRequest("/test1")); |
| | | final ResourceResponse resource2 = connection.read(context, newReadRequest("/test1")); |
| | | checkResourcesAreEqual(resource2, newContent); |
| | | } |
| | | |
| | | @Test |
| | | public void testPatchAddOptionalAttributeIndexAppend() throws Exception { |
| | | final Context context = newAuthConnectionContext(); |
| | | final Connection connection = newConnection(); |
| | | final JsonValue newContent = getTestUser1(12345); |
| | | newContent.put("description", asList("one", "two")); |
| | | final ResourceResponse resource1 = connection.patch( |
| | | ctx(), newPatchRequest("/test1", add("/description/-", "one"), add("/description/-", "two"))); |
| | | context, newPatchRequest("/test1", add("/description/-", "one"), add("/description/-", "two"))); |
| | | checkResourcesAreEqual(resource1, newContent); |
| | | final ResourceResponse resource2 = connection.read(ctx(), newReadRequest("/test1")); |
| | | final ResourceResponse resource2 = connection.read(context, newReadRequest("/test1")); |
| | | checkResourcesAreEqual(resource2, newContent); |
| | | } |
| | | |
| | | @Test(expectedExceptions = BadRequestException.class) |
| | | public void testPatchConstantAttribute() throws Exception { |
| | | newConnection().patch(ctx(), newPatchRequest("/test1", add("/schemas", asList("junk")))); |
| | | newConnection().patch(newAuthConnectionContext(), newPatchRequest("/test1", add("/schemas", asList("junk")))); |
| | | } |
| | | |
| | | @Test |
| | | public void testPatchDeleteOptionalAttribute() throws Exception { |
| | | final Context context = newAuthConnectionContext(); |
| | | final Connection connection = newConnection(); |
| | | connection.patch(ctx(), newPatchRequest("/test1", add("/description", asList("one", "two")))); |
| | | final ResourceResponse resource1 = connection.patch(ctx(), newPatchRequest("/test1", remove("/description"))); |
| | | connection.patch(context, newPatchRequest("/test1", add("/description", asList("one", "two")))); |
| | | final ResourceResponse resource1 = connection.patch(context, newPatchRequest("/test1", remove("/description"))); |
| | | checkResourcesAreEqual(resource1, getTestUser1(12345)); |
| | | final ResourceResponse resource2 = connection.read(ctx(), newReadRequest("/test1")); |
| | | final ResourceResponse resource2 = connection.read(context, newReadRequest("/test1")); |
| | | checkResourcesAreEqual(resource2, getTestUser1(12345)); |
| | | } |
| | | |
| | | @Test |
| | | public void testPatchIncrement() throws Exception { |
| | | final Context context = newAuthConnectionContext(); |
| | | final Connection connection = newConnection(); |
| | | final JsonValue newContent = getTestUser1(12345); |
| | | newContent.put("singleNumber", 100); |
| | | newContent.put("multiNumber", asList(200, 300)); |
| | | |
| | | final ResourceResponse resource1 = connection.patch(ctx(), newPatchRequest("/test1", |
| | | final ResourceResponse resource1 = connection.patch(context, newPatchRequest("/test1", |
| | | add("/singleNumber", 0), |
| | | add("/multiNumber", asList(100, 200)), |
| | | increment("/singleNumber", 100), |
| | | increment("/multiNumber", 100))); |
| | | checkResourcesAreEqual(resource1, newContent); |
| | | final ResourceResponse resource2 = connection.read(ctx(), newReadRequest("/test1")); |
| | | final ResourceResponse resource2 = connection.read(context, newReadRequest("/test1")); |
| | | checkResourcesAreEqual(resource2, newContent); |
| | | } |
| | | |
| | | @Test(expectedExceptions = BadRequestException.class) |
| | | public void testPatchMissingRequiredAttribute() throws Exception { |
| | | newConnection().patch(ctx(), newPatchRequest("/test1", remove("/name/surname"))); |
| | | newConnection().patch(newAuthConnectionContext(), newPatchRequest("/test1", remove("/name/surname"))); |
| | | } |
| | | |
| | | @Test |
| | | public void testPatchModifyOptionalAttribute() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | connection.patch(ctx(), newPatchRequest("/test1", add("/description", asList("one", "two")))); |
| | | final Context context = newAuthConnectionContext(); |
| | | connection.patch(context, newPatchRequest("/test1", add("/description", asList("one", "two")))); |
| | | final ResourceResponse resource1 = |
| | | connection.patch(ctx(), newPatchRequest("/test1", add("/description", asList("three")))); |
| | | connection.patch(context, newPatchRequest("/test1", add("/description", asList("three")))); |
| | | final JsonValue newContent = getTestUser1(12345); |
| | | newContent.put("description", asList("one", "two", "three")); |
| | | checkResourcesAreEqual(resource1, newContent); |
| | | final ResourceResponse resource2 = connection.read(ctx(), newReadRequest("/test1")); |
| | | final ResourceResponse resource2 = connection.read(context, newReadRequest("/test1")); |
| | | checkResourcesAreEqual(resource2, newContent); |
| | | } |
| | | |
| | | @Test(expectedExceptions = NotSupportedException.class) |
| | | public void testPatchMultiValuedAttributeIndexAppend() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | connection.patch(ctx(), newPatchRequest("/test1", add("/description/0", "junk"))); |
| | | connection.patch(newAuthConnectionContext(), newPatchRequest("/test1", add("/description/0", "junk"))); |
| | | } |
| | | |
| | | @Test(expectedExceptions = BadRequestException.class) |
| | | public void testPatchMultiValuedAttributeIndexAppendWithList() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | connection.patch(ctx(), newPatchRequest("/test1", add("/description/-", |
| | | connection.patch(newAuthConnectionContext(), newPatchRequest("/test1", add("/description/-", |
| | | asList("one", "two")))); |
| | | } |
| | | |
| | | @Test(expectedExceptions = BadRequestException.class) |
| | | public void testPatchMultiValuedAttributeWithSingleValue() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | connection.patch(ctx(), newPatchRequest("/test1", add("/description", "one"))); |
| | | connection.patch(newAuthConnectionContext(), newPatchRequest("/test1", add("/description", "one"))); |
| | | } |
| | | |
| | | @Test |
| | | public void testPatchMVCCMatch() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | final Context context = newAuthConnectionContext(); |
| | | final ResourceResponse resource1 = connection.patch( |
| | | ctx(), newPatchRequest("/test1", add("/name/displayName", "changed")).setRevision("12345")); |
| | | context, newPatchRequest("/test1", add("/name/displayName", "changed")).setRevision("12345")); |
| | | checkResourcesAreEqual(resource1, getTestUser1Updated(12345)); |
| | | final ResourceResponse resource2 = connection.read(ctx(), newReadRequest("/test1")); |
| | | final ResourceResponse resource2 = connection.read(context, newReadRequest("/test1")); |
| | | checkResourcesAreEqual(resource2, getTestUser1Updated(12345)); |
| | | } |
| | | |
| | | @Test(expectedExceptions = PreconditionFailedException.class) |
| | | public void testPatchMVCCNoMatch() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | connection.patch(ctx(), newPatchRequest("/test1", add("/name/displayName", "changed")).setRevision("12346")); |
| | | connection.patch( |
| | | newAuthConnectionContext(), |
| | | newPatchRequest("/test1", add("/name/displayName", "changed")).setRevision("12346")); |
| | | } |
| | | |
| | | @Test(expectedExceptions = NotFoundException.class) |
| | | public void testPatchNotFound() throws Exception { |
| | | newConnection().patch(ctx(), newPatchRequest("/missing", add("/name/displayName", "changed"))); |
| | | newConnection().patch( |
| | | newAuthConnectionContext(), |
| | | newPatchRequest("/missing", add("/name/displayName", "changed"))); |
| | | } |
| | | |
| | | @Test(expectedExceptions = BadRequestException.class) |
| | | public void testPatchReadOnlyAttribute() throws Exception { |
| | | // Etag is read-only. |
| | | newConnection().patch(ctx(), newPatchRequest("/test1", add("_rev", "99999"))); |
| | | newConnection().patch(newAuthConnectionContext(), newPatchRequest("/test1", add("_rev", "99999"))); |
| | | } |
| | | |
| | | @Test |
| | | public void testPatchReplacePartialObject() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | final Context context = newAuthConnectionContext(); |
| | | final JsonValue expected = json(object( |
| | | field("schemas", asList("urn:scim:schemas:core:1.0")), |
| | | field("_id", "test1"), |
| | | field("_rev", "12345"), |
| | | field("name", object(field("displayName", "Humpty"), |
| | | field("surname", "Dumpty"))))); |
| | | final ResourceResponse resource1 = connection.patch(ctx(), newPatchRequest("/test1", |
| | | final ResourceResponse resource1 = connection.patch(context, newPatchRequest("/test1", |
| | | replace("/name", object(field("displayName", "Humpty"), field("surname", "Dumpty"))))); |
| | | checkResourcesAreEqual(resource1, expected); |
| | | final ResourceResponse resource2 = connection.read(ctx(), newReadRequest("/test1")); |
| | | final ResourceResponse resource2 = connection.read(context, newReadRequest("/test1")); |
| | | checkResourcesAreEqual(resource2, expected); |
| | | } |
| | | |
| | | @Test |
| | | public void testPatchReplaceWholeObject() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | final Context context = newAuthConnectionContext(); |
| | | final JsonValue newContent = json(object( |
| | | field("name", object(field("displayName", "Humpty"), |
| | | field("surname", "Dumpty"))))); |
| | |
| | | field("name", object(field("displayName", "Humpty"), |
| | | field("surname", "Dumpty"))))); |
| | | final ResourceResponse resource1 = |
| | | connection.patch(ctx(), newPatchRequest("/test1", replace("/", newContent))); |
| | | connection.patch(context, newPatchRequest("/test1", replace("/", newContent))); |
| | | checkResourcesAreEqual(resource1, expected); |
| | | final ResourceResponse resource2 = connection.read(ctx(), newReadRequest("/test1")); |
| | | final ResourceResponse resource2 = connection.read(context, newReadRequest("/test1")); |
| | | checkResourcesAreEqual(resource2, expected); |
| | | } |
| | | |
| | | @Test(expectedExceptions = BadRequestException.class) |
| | | public void testPatchSingleValuedAttributeIndexAppend() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | connection.patch(ctx(), newPatchRequest("/test1", add("/name/surname/-", "junk"))); |
| | | connection.patch(newAuthConnectionContext(), newPatchRequest("/test1", add("/name/surname/-", "junk"))); |
| | | } |
| | | |
| | | @Test(expectedExceptions = NotSupportedException.class) |
| | | public void testPatchSingleValuedAttributeIndexNumber() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | connection.patch(ctx(), newPatchRequest("/test1", add("/name/surname/0", "junk"))); |
| | | connection.patch(newAuthConnectionContext(), newPatchRequest("/test1", add("/name/surname/0", "junk"))); |
| | | } |
| | | |
| | | @Test(expectedExceptions = BadRequestException.class) |
| | | public void testPatchSingleValuedAttributeWithMultipleValues() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | connection.patch(ctx(), newPatchRequest("/test1", add("/name/surname", asList("black", |
| | | connection.patch(newAuthConnectionContext(), newPatchRequest("/test1", add("/name/surname", asList("black", |
| | | "white")))); |
| | | } |
| | | |
| | | @Test(expectedExceptions = BadRequestException.class) |
| | | public void testPatchUnknownAttribute() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | connection.patch(ctx(), newPatchRequest("/test1", add("/dummy", "junk"))); |
| | | connection.patch(newAuthConnectionContext(), newPatchRequest("/test1", add("/dummy", "junk"))); |
| | | } |
| | | |
| | | @Test(expectedExceptions = BadRequestException.class) |
| | | public void testPatchUnknownSubAttribute() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | connection.patch(ctx(), newPatchRequest("/test1", add("/description/dummy", "junk"))); |
| | | connection.patch(newAuthConnectionContext(), newPatchRequest("/test1", add("/description/dummy", "junk"))); |
| | | } |
| | | |
| | | @Test(expectedExceptions = BadRequestException.class) |
| | | public void testPatchUnknownSubSubAttribute() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | connection.patch(ctx(), newPatchRequest("/test1", add("/description/dummy/dummy", "junk"))); |
| | | connection.patch(newAuthConnectionContext(), |
| | | newPatchRequest("/test1", add("/description/dummy/dummy", "junk"))); |
| | | } |
| | | |
| | | @Test |
| | | public void testRead() throws Exception { |
| | | final ResourceResponse resource = newConnection().read(ctx(), newReadRequest("/test1")); |
| | | final ResourceResponse resource = newConnection().read(newAuthConnectionContext(), newReadRequest("/test1")); |
| | | checkResourcesAreEqual(resource, getTestUser1(12345)); |
| | | } |
| | | |
| | | @Test(expectedExceptions = NotFoundException.class) |
| | | public void testReadNotFound() throws Exception { |
| | | newConnection().read(ctx(), newReadRequest("/missing")); |
| | | newConnection().read(newAuthConnectionContext(), newReadRequest("/missing")); |
| | | } |
| | | |
| | | @Test |
| | | public void testReadSelectAllFields() throws Exception { |
| | | final ResourceResponse resource = newConnection().read(ctx(), newReadRequest("/test1").addField("/")); |
| | | final ResourceResponse resource = newConnection().read(newAuthConnectionContext(), |
| | | newReadRequest("/test1").addField("/")); |
| | | checkResourcesAreEqual(resource, getTestUser1(12345)); |
| | | } |
| | | |
| | | @Test |
| | | public void testReadSelectPartial() throws Exception { |
| | | final ResourceResponse resource = newConnection().read( |
| | | ctx(), newReadRequest("/test1").addField("/name/surname")); |
| | | newAuthConnectionContext(), newReadRequest("/test1").addField("/name/surname")); |
| | | assertThat(resource.getId()).isEqualTo("test1"); |
| | | assertThat(resource.getRevision()).isEqualTo("12345"); |
| | | assertThat(resource.getContent().get("_id").asString()).isNull(); |
| | |
| | | @Test(enabled = false) |
| | | public void testReadSelectPartialInsensitive() throws Exception { |
| | | final ResourceResponse resource = newConnection().read( |
| | | ctx(), newReadRequest("/test1").addField("/name/SURNAME")); |
| | | newAuthConnectionContext(), newReadRequest("/test1").addField("/name/SURNAME")); |
| | | assertThat(resource.getId()).isEqualTo("test1"); |
| | | assertThat(resource.getRevision()).isEqualTo("12345"); |
| | | assertThat(resource.getContent().get("_id").asString()).isNull(); |
| | |
| | | @Test |
| | | public void testUpdate() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | final Context context = newAuthConnectionContext(); |
| | | final ResourceResponse resource1 = connection.update( |
| | | ctx(), newUpdateRequest("/test1", getTestUser1Updated(12345))); |
| | | context, newUpdateRequest("/test1", getTestUser1Updated(12345))); |
| | | checkResourcesAreEqual(resource1, getTestUser1Updated(12345)); |
| | | final ResourceResponse resource2 = connection.read(ctx(), newReadRequest("/test1")); |
| | | final ResourceResponse resource2 = connection.read(context, newReadRequest("/test1")); |
| | | checkResourcesAreEqual(resource2, getTestUser1Updated(12345)); |
| | | } |
| | | |
| | |
| | | public void testUpdateNoChange() throws Exception { |
| | | final List<Request> requests = new LinkedList<>(); |
| | | final Connection connection = newConnection(requests); |
| | | final ResourceResponse resource1 = connection.update(ctx(), newUpdateRequest("/test1", getTestUser1(12345))); |
| | | final Context context = newAuthConnectionContext(requests); |
| | | final ResourceResponse resource1 = connection.update(context, newUpdateRequest("/test1", getTestUser1(12345))); |
| | | |
| | | // Check that no modify operation was sent |
| | | // (only a single search should be sent in order to get the current resource). |
| | |
| | | assertThat(requests.get(0)).isInstanceOf(SearchRequest.class); |
| | | |
| | | checkResourcesAreEqual(resource1, getTestUser1(12345)); |
| | | final ResourceResponse resource2 = connection.read(ctx(), newReadRequest("/test1")); |
| | | final ResourceResponse resource2 = connection.read(context, newReadRequest("/test1")); |
| | | checkResourcesAreEqual(resource2, getTestUser1(12345)); |
| | | } |
| | | |
| | | @Test |
| | | public void testUpdateAddOptionalAttribute() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | final Context context = newAuthConnectionContext(); |
| | | final JsonValue newContent = getTestUser1Updated(12345); |
| | | newContent.put("description", asList("one", "two")); |
| | | final ResourceResponse resource1 = connection.update(ctx(), newUpdateRequest("/test1", newContent)); |
| | | final ResourceResponse resource1 = connection.update(context, newUpdateRequest("/test1", newContent)); |
| | | checkResourcesAreEqual(resource1, newContent); |
| | | final ResourceResponse resource2 = connection.read(ctx(), newReadRequest("/test1")); |
| | | final ResourceResponse resource2 = connection.read(context, newReadRequest("/test1")); |
| | | checkResourcesAreEqual(resource2, newContent); |
| | | } |
| | | |
| | |
| | | final Connection connection = newConnection(); |
| | | final JsonValue newContent = getTestUser1Updated(12345); |
| | | newContent.put("schemas", asList("junk")); |
| | | connection.update(ctx(), newUpdateRequest("/test1", newContent)); |
| | | connection.update(newAuthConnectionContext(), newUpdateRequest("/test1", newContent)); |
| | | } |
| | | |
| | | @Test |
| | | public void testUpdateDeleteOptionalAttribute() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | final Context context = newAuthConnectionContext(); |
| | | final JsonValue newContent = getTestUser1Updated(12345); |
| | | newContent.put("description", asList("one", "two")); |
| | | connection.update(ctx(), newUpdateRequest("/test1", newContent)); |
| | | connection.update(newAuthConnectionContext(), newUpdateRequest("/test1", newContent)); |
| | | newContent.remove("description"); |
| | | final ResourceResponse resource1 = connection.update(ctx(), newUpdateRequest("/test1", newContent)); |
| | | final ResourceResponse resource1 = connection.update(context, newUpdateRequest("/test1", newContent)); |
| | | checkResourcesAreEqual(resource1, newContent); |
| | | final ResourceResponse resource2 = connection.read(ctx(), newReadRequest("/test1")); |
| | | final ResourceResponse resource2 = connection.read(context, newReadRequest("/test1")); |
| | | checkResourcesAreEqual(resource2, newContent); |
| | | } |
| | | |
| | |
| | | final Connection connection = newConnection(); |
| | | final JsonValue newContent = getTestUser1Updated(12345); |
| | | newContent.get("name").remove("surname"); |
| | | connection.update(ctx(), newUpdateRequest("/test1", newContent)); |
| | | connection.update(newAuthConnectionContext(), newUpdateRequest("/test1", newContent)); |
| | | } |
| | | |
| | | @Test |
| | | public void testUpdateModifyOptionalAttribute() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | final Context context = newAuthConnectionContext(); |
| | | final JsonValue newContent = getTestUser1Updated(12345); |
| | | newContent.put("description", asList("one", "two")); |
| | | connection.update(ctx(), newUpdateRequest("/test1", newContent)); |
| | | connection.update(newAuthConnectionContext(), newUpdateRequest("/test1", newContent)); |
| | | newContent.put("description", asList("three")); |
| | | final ResourceResponse resource1 = connection.update(ctx(), newUpdateRequest("/test1", newContent)); |
| | | final ResourceResponse resource1 = connection.update(context, newUpdateRequest("/test1", newContent)); |
| | | checkResourcesAreEqual(resource1, newContent); |
| | | final ResourceResponse resource2 = connection.read(ctx(), newReadRequest("/test1")); |
| | | final ResourceResponse resource2 = connection.read(context, newReadRequest("/test1")); |
| | | checkResourcesAreEqual(resource2, newContent); |
| | | } |
| | | |
| | | @Test |
| | | public void testUpdateMVCCMatch() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | final Context context = newAuthConnectionContext(); |
| | | final ResourceResponse resource1 = |
| | | connection.update(ctx(), newUpdateRequest("/test1", getTestUser1Updated(12345)).setRevision("12345")); |
| | | connection.update(context, newUpdateRequest("/test1", getTestUser1Updated(12345)).setRevision("12345")); |
| | | checkResourcesAreEqual(resource1, getTestUser1Updated(12345)); |
| | | final ResourceResponse resource2 = connection.read(ctx(), newReadRequest("/test1")); |
| | | final ResourceResponse resource2 = connection.read(context, newReadRequest("/test1")); |
| | | checkResourcesAreEqual(resource2, getTestUser1Updated(12345)); |
| | | } |
| | | |
| | | @Test(expectedExceptions = PreconditionFailedException.class) |
| | | public void testUpdateMVCCNoMatch() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | connection.update(ctx(), newUpdateRequest("/test1", getTestUser1Updated(12345)) |
| | | connection.update(newAuthConnectionContext(), newUpdateRequest("/test1", getTestUser1Updated(12345)) |
| | | .setRevision("12346")); |
| | | } |
| | | |
| | | @Test(expectedExceptions = NotFoundException.class) |
| | | public void testUpdateNotFound() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | connection.update(ctx(), newUpdateRequest("/missing", getTestUser1Updated(12345))); |
| | | connection.update(newAuthConnectionContext(), newUpdateRequest("/missing", getTestUser1Updated(12345))); |
| | | } |
| | | |
| | | @Test(expectedExceptions = BadRequestException.class) |
| | | public void testUpdateReadOnlyAttribute() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | // Etag is read-only. |
| | | connection.update(ctx(), newUpdateRequest("/test1", getTestUser1Updated(99999))); |
| | | connection.update(newAuthConnectionContext(), newUpdateRequest("/test1", getTestUser1Updated(99999))); |
| | | } |
| | | |
| | | @Test(expectedExceptions = BadRequestException.class) |
| | |
| | | final Connection connection = newConnection(); |
| | | final JsonValue newContent = getTestUser1Updated(12345); |
| | | newContent.put("surname", asList("black", "white")); |
| | | connection.update(ctx(), newUpdateRequest("/test1", newContent)); |
| | | connection.update(newAuthConnectionContext(), newUpdateRequest("/test1", newContent)); |
| | | } |
| | | |
| | | @Test(expectedExceptions = BadRequestException.class) |
| | |
| | | final Connection connection = newConnection(); |
| | | final JsonValue newContent = getTestUser1Updated(12345); |
| | | newContent.add("dummy", "junk"); |
| | | connection.update(ctx(), newUpdateRequest("/test1", newContent)); |
| | | connection.update(newAuthConnectionContext(), newUpdateRequest("/test1", newContent)); |
| | | } |
| | | |
| | | private Connection newConnection() throws IOException { |
| | |
| | | |
| | | private Builder builder(final List<Request> requests) throws IOException { |
| | | return Rest2LDAP.builder() |
| | | .ldapConnectionFactory(getConnectionFactory(requests)) |
| | | .baseDN("dc=test") |
| | | .useEtagAttribute() |
| | | .useClientDNNaming("uid") |
| | | .readOnUpdatePolicy(ReadOnUpdatePolicy.CONTROLS) |
| | | .authorizationPolicy(AuthorizationPolicy.NONE) |
| | | .additionalLDAPAttribute("objectClass", "top", "person") |
| | | .mapper(object() |
| | | .attribute("schemas", constant(asList("urn:scim:schemas:core:1.0"))) |
| | |
| | | expectedResource.getContent().getObject()); |
| | | } |
| | | |
| | | private AuthenticatedConnectionContext newAuthConnectionContext() throws LdapException, IOException { |
| | | return newAuthConnectionContext(new ArrayList<Request>()); |
| | | } |
| | | |
| | | private AuthenticatedConnectionContext newAuthConnectionContext(List<Request> requests) |
| | | throws LdapException, IOException { |
| | | return new AuthenticatedConnectionContext(ctx(), getConnectionFactory(requests).getConnection()); |
| | | } |
| | | |
| | | private ConnectionFactory getConnectionFactory(final List<Request> requests) throws IOException { |
| | | // @formatter:off |
| | | final MemoryBackend backend = |