private RequestHandler createHandler(boolean collection, Object provider) {
   RequestHandler handler =
       collection ? Resources.newCollection(provider) : Resources.newSingleton(provider);
   UriRouter router = new UriRouter();
   router.addRoute(collection ? STARTS_WITH : EQUALS, "test", handler);
   return router;
 }
 @SuppressWarnings("unchecked")
 @Test(dataProvider = "testCollectionResourceProviderData")
 public void testCollectionResourceProvider(String resourcePath, String expectedId)
     throws Exception {
   CollectionResourceProvider collection = mock(CollectionResourceProvider.class);
   RequestHandler handler = Resources.newCollection(collection);
   Connection connection = Resources.newInternalConnection(handler);
   ReadRequest read = Requests.newReadRequest(resourcePath);
   connection.readAsync(new RootContext(), read);
   ArgumentCaptor<ReadRequest> captor = ArgumentCaptor.forClass(ReadRequest.class);
   verify(collection).readInstance(any(ServerContext.class), eq(expectedId), captor.capture());
   Assertions.assertThat(captor.getValue().getResourcePath()).isEqualTo("");
 }
  @Test(dataProvider = "annotatedRequestHandlerData")
  public void testPatchCollectionItemAnnotatedRequestHandler(
      Class<?> requestHandler,
      boolean collection,
      boolean create,
      boolean read,
      boolean update,
      boolean delete,
      boolean patch,
      boolean resourceAction,
      boolean collectionAction,
      boolean query)
      throws Exception {

    // Given
    Object provider = requestHandler.newInstance();
    Connection connection = Resources.newInternalConnection(createHandler(collection, provider));
    PatchRequest req = Requests.newPatchRequest("/test/fred");

    // When
    Promise<Resource, ResourceException> promise = connection.patchAsync(new RootContext(), req);

    // Then
    if (patch && collection) {
      assertThat(promise).succeeded().withId().isEqualTo("patch-fred");
    } else if (collection) {
      assertThat(promise).failedWithException().isInstanceOf(NotSupportedException.class);
    } else {
      assertThat(promise).failedWithException().isInstanceOf(NotFoundException.class);
    }
  }
  @Test(dataProvider = "annotatedRequestHandlerData")
  public void testUpdateAnnotatedRequestHandler(
      Class<?> requestHandler,
      boolean collection,
      boolean create,
      boolean read,
      boolean update,
      boolean delete,
      boolean patch,
      boolean resourceAction,
      boolean collectionAction,
      boolean query)
      throws Exception {

    // Given
    Object provider = requestHandler.newInstance();
    Connection connection = Resources.newInternalConnection(createHandler(collection, provider));
    UpdateRequest req = Requests.newUpdateRequest("/test", json(object(field("dummy", "test"))));

    // When
    Promise<Resource, ResourceException> promise = connection.updateAsync(new RootContext(), req);

    // Then
    if (update && !collection) {
      assertThat(promise).succeeded().withId().isEqualTo("update");
    } else if (!collection) {
      assertThat(promise).failedWithException().isInstanceOf(NotSupportedException.class);
    } else {
      assertThat(promise).failedWithException().isInstanceOf(BadRequestException.class);
    }
  }
  @Test(dataProvider = "annotatedRequestHandlerData")
  public void testActionCollectionItemAnnotatedRequestHandler(
      Class<?> requestHandler,
      boolean collection,
      boolean create,
      boolean read,
      boolean update,
      boolean delete,
      boolean patch,
      boolean resourceAction,
      boolean collectionAction,
      boolean query)
      throws Exception {

    // Given
    Object provider = requestHandler.newInstance();
    Connection connection = Resources.newInternalConnection(createHandler(collection, provider));
    ActionRequest req1 = Requests.newActionRequest("/test/fred", "instanceAction1");
    ActionRequest req2 = Requests.newActionRequest("/test/fred", "instanceAction2");

    // When
    Promise<JsonValue, ResourceException> promise1 =
        connection.actionAsync(new RootContext(), req1);
    Promise<JsonValue, ResourceException> promise2 =
        connection.actionAsync(new RootContext(), req2);

    // Then
    if (collectionAction && collection) {
      AssertJJsonValueAssert.assertThat(promise1)
          .succeeded()
          .stringAt("result")
          .isEqualTo("instanceAction1-fred");
      AssertJJsonValueAssert.assertThat(promise2)
          .succeeded()
          .stringAt("result")
          .isEqualTo("instanceAction2-fred");
    } else if (collection) {
      AssertJJsonValueAssert.assertThat(promise1)
          .failedWithException()
          .isInstanceOf(NotSupportedException.class);
      AssertJJsonValueAssert.assertThat(promise2)
          .failedWithException()
          .isInstanceOf(NotSupportedException.class);
    } else {
      AssertJJsonValueAssert.assertThat(promise1)
          .failedWithException()
          .isInstanceOf(NotFoundException.class);
      AssertJJsonValueAssert.assertThat(promise2)
          .failedWithException()
          .isInstanceOf(NotFoundException.class);
    }
  }
  @Test(dataProvider = "annotatedRequestHandlerData")
  public void testQueryCollectionAnnotatedRequestHandler(
      Class<?> requestHandler,
      boolean collection,
      boolean create,
      boolean read,
      boolean update,
      boolean delete,
      boolean patch,
      boolean resourceAction,
      boolean collectionAction,
      boolean query)
      throws Exception {

    // Given
    Object provider = requestHandler.newInstance();
    Connection connection = Resources.newInternalConnection(createHandler(collection, provider));
    QueryRequest req = Requests.newQueryRequest("/test");

    // When
    Promise<QueryResult, ResourceException> promise =
        connection.queryAsync(new RootContext(), req, mock(QueryResourceHandler.class));

    // Then
    if (query && collection) {
      AssertJPromiseAssert.assertThat(promise).succeeded();
      QueryResult result = promise.get();
      Assertions.assertThat(result.getPagedResultsCookie()).isEqualTo("query");
    } else if (collection) {
      AssertJPromiseAssert.assertThat(promise)
          .failedWithException()
          .isInstanceOf(NotSupportedException.class);
    } else {
      AssertJPromiseAssert.assertThat(promise)
          .failedWithException()
          .isInstanceOf(BadRequestException.class);
    }
  }
  @Test(dataProvider = "annotatedRequestHandlerData")
  public void testActionAnnotatedRequestHandler(
      Class<?> requestHandler,
      boolean collection,
      boolean create,
      boolean read,
      boolean update,
      boolean delete,
      boolean patch,
      boolean resourceAction,
      boolean collectionAction,
      boolean query)
      throws Exception {

    // Given
    Object provider = requestHandler.newInstance();
    Connection connection = Resources.newInternalConnection(createHandler(collection, provider));
    String actionId1 = collection ? "collectionAction1" : "instanceAction1";
    ActionRequest req1 = Requests.newActionRequest("/test", actionId1);
    String actionId2 = collection ? "collectionAction2" : "instanceAction2";
    ActionRequest req2 = Requests.newActionRequest("/test", actionId2);

    // When
    Promise<JsonValue, ResourceException> promise1 =
        connection.actionAsync(new RootContext(), req1);
    Promise<JsonValue, ResourceException> promise2 =
        connection.actionAsync(new RootContext(), req2);

    // Then
    if ((collection && collectionAction) || (!collection && resourceAction)) {
      assertThatJsonValue(promise1).succeeded().stringAt("result").isEqualTo(actionId1);
      assertThatJsonValue(promise2).succeeded().stringAt("result").isEqualTo(actionId2);
    } else {
      assertThatJsonValue(promise1).failedWithException().isInstanceOf(NotSupportedException.class);
      assertThatJsonValue(promise2).failedWithException().isInstanceOf(NotSupportedException.class);
    }
  }
 @Test(dataProvider = "testFilterData")
 public void testFilter(List<JsonPointer> filter, JsonValue content, JsonValue expected) {
   Assertions.assertThat(Resources.filterResource(content, filter).getObject())
       .isEqualTo(expected.getObject());
 }