jio.test.pbt.rest.CRUDPropBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jio-test Show documentation
Show all versions of jio-test Show documentation
JIO test library based on Property Based Testing and Java Flight Recording Debuggers
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;
}
}