All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jio.test.pbt.rest.CRUDPropBuilder Maven / Gradle / Ivy

Go to download

JIO test library based on Property Based Testing and Java Flight Recording Debuggers

There is a newer version: 3.0.0-RC2
Show newest version
package jio.test.pbt.rest;

import fun.gen.Gen;
import jio.BiLambda;
import jio.IO;
import jio.Lambda;
import jio.test.pbt.PropertyBuilder;
import jio.test.pbt.TestFailure;
import jio.test.pbt.TestResult;
import jsonvalues.JsObj;

import java.net.http.HttpResponse;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * A builder class for creating property tests that cover CRUD (Create, Read, Update, Delete)
 * operations on a RESTful API endpoint.
 *
 * @param  The type of data generated to feed the property tests.
 */
public final class CRUDPropBuilder extends RestPropBuilder> implements
    Supplier> {


  private final BiLambda, HttpResponse> update;

  private Function, TestResult> updateAssert = DEFAULT_RESP_ASSERT;


  private CRUDPropBuilder(String name,
      Gen gen,
      BiLambda> p_post,
      BiLambda> p_get,
      BiLambda, HttpResponse> p_update,
      BiLambda> p_delete
  ) {
    super(name, gen, p_post, p_get, p_delete);
    this.update = Objects.requireNonNull(p_update);
  }

  /**
   * Creates a new instance of CRUDPropBuilder with the specified parameters.
   *
   * @param name     The name of the property test.
   * @param gen      The data generator that produces pseudorandom data for testing.
   * @param p_post   The lambda function representing the HTTP POST operation.
   * @param p_get    The lambda function representing the HTTP GET operation.
   * @param p_update The lambda function representing the HTTP UPDATE operation.
   * @param p_delete The lambda function representing the HTTP DELETE operation.
   * @param       The type of data generated to feed the property tests.
   * @return a CRUDPropBuilder
   */
  public static  CRUDPropBuilder of(final String name,
      final Gen gen,
      final Lambda> p_post,
      final Lambda> p_get,
      final Lambda, HttpResponse> p_update,
      final Lambda> p_delete
  ) {
    Objects.requireNonNull(p_post);
    Objects.requireNonNull(p_get);
    Objects.requireNonNull(p_update);
    Objects.requireNonNull(p_delete);
    return new CRUDPropBuilder<>(name,
        gen,
        (conf, body) -> Objects.requireNonNull(p_post).apply(body),
        (conf, id) -> Objects.requireNonNull(p_get).apply(id),
        (conf, id) -> Objects.requireNonNull(p_update).apply(id),
        (conf, id) -> Objects.requireNonNull(p_delete).apply(id));
  }

  /**
   * Creates a new instance of CRUDPropBuilder with the specified parameters.
   *
   * @param name     The name of the property test.
   * @param gen      The data generator that produces pseudorandom data for testing.
   * @param p_post   The lambda function representing the HTTP POST operation.
   * @param p_get    The lambda function representing the HTTP GET operation.
   * @param p_update The lambda function representing the HTTP UPDATE operation.
   * @param p_delete The lambda function representing the HTTP DELETE operation.
   * @param       The type of data generated to feed the property tests.
   * @return a CRUDPropBuilder
   */
  public static  CRUDPropBuilder of(final String name,
      final Gen gen,
      final BiLambda> p_post,
      final BiLambda> p_get,
      final BiLambda, HttpResponse> p_update,
      final BiLambda> p_delete
  ) {
    return new CRUDPropBuilder<>(name, gen, p_post, p_get, p_update, p_delete);
  }

  /**
   * Creates a property test based on the configuration of this builder.
   *
   * @return A property test for the CRUD operations defined by this builder.
   */
  @Override
  public PropertyBuilder get() {
    BiLambda lambda =
        (conf, body) -> post.apply(conf, body)
            .then(resp -> {
                  TestResult result = postAssert.apply(resp);
              if (result instanceof TestFailure f) {
                return IO.fail(f);
              }
                  return getId.apply(body, resp);
                }
            )
            .then(id -> get.apply(conf, id)
                .then(assertResp(getAssert, id))
            )
            .then(idResp -> update.apply(conf, idResp.resp())
                .then(assertResp(updateAssert, idResp.id())))
            .then(idResp -> delete.apply(conf, idResp.id())
                .then(assertResp(deleteAssert, idResp.id()))
            )
            .then(idResp -> get.apply(conf, idResp.id()))
            .map(resp -> resp.statusCode() == 404 ?
                TestResult.SUCCESS :
                TestFailure.reason(
                    "Entity found after being deleted successfully. Status code received %d".formatted(
                        resp.statusCode())));

    return PropertyBuilder.ofLambda(name, gen, lambda);
  }


  /**
   * Sets the assertion function for the HTTP UPDATE operation.
   *
   * @param updateAssert The assertion function for the HTTP UPDATE operation.
   * @return This CRUDPropBuilder instance with the updated assertion function.
   */
  public CRUDPropBuilder withUpdateAssert(
      Function, TestResult> updateAssert) {
    this.updateAssert = Objects.requireNonNull(updateAssert);
    return this;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy