added tests and enabled the schema validation for upload

This commit is contained in:
verboomp
2026-01-27 15:29:28 +01:00
parent e4b2dd0462
commit 98764dc51e
10 changed files with 101 additions and 62 deletions

View File

@@ -5,17 +5,11 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.ext.MessageBodyReader;
import jakarta.ws.rs.ext.Provider;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@@ -25,6 +19,15 @@ import com.networknt.schema.JsonSchema;
import com.networknt.schema.JsonSchemaFactory; import com.networknt.schema.JsonSchemaFactory;
import com.networknt.schema.ValidationMessage; import com.networknt.schema.ValidationMessage;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
import jakarta.ws.rs.ext.MessageBodyReader;
import jakarta.ws.rs.ext.Provider;
/** /**
* *
* *
@@ -65,8 +68,9 @@ public class ValidatedMessageBodyReader implements MessageBodyReader<SchemaValid
Optional<JsonSchemaValidate> annotation = Arrays.stream(annotations).filter(a -> a.annotationType() == JsonSchemaValidate.class).map(a -> (JsonSchemaValidate) a).findAny(); Optional<JsonSchemaValidate> annotation = Arrays.stream(annotations).filter(a -> a.annotationType() == JsonSchemaValidate.class).map(a -> (JsonSchemaValidate) a).findAny();
if (annotation.isPresent()) { if (annotation.isPresent()) {
ValidationReply reply = validate(annotation.get(), jsonData); ValidationReply reply = validate(annotation.get(), jsonData);
if (!reply.success) { if (!reply.success()) {
throw new WebApplicationException(reply.getErrorResponse()); var response = Response.status(Status.BAD_REQUEST).entity(reply.errors()).build();
throw new WebApplicationException(response);
} }
} }
@@ -87,12 +91,12 @@ public class ValidatedMessageBodyReader implements MessageBodyReader<SchemaValid
Set<ValidationMessage> errors = schema.validate(node); Set<ValidationMessage> errors = schema.validate(node);
if (!errors.isEmpty()) { if (!errors.isEmpty()) {
LOG.error("Failed to validate json to schema " + schemaPath); LOG.error("Failed to validate json to schema " + schemaPath);
errors.stream().forEach(LOG::error); errors.forEach(LOG::error);
} }
return new ValidationReply.Builder().success(errors.isEmpty()).errors(errors).build(); return new ValidationReply(errors.isEmpty(), errors);
} catch (IOException e) { } catch (IOException e) {
LOG.error(e.getMessage(), e); LOG.error(e.getMessage(), e);
return new ValidationReply.Builder().success(false).build(); return new ValidationReply(false, new HashSet<>());
} }
} }

View File

@@ -1,11 +1,7 @@
package marketing.heyday.hartmann.fotodocumentation.rest.jackson; package marketing.heyday.hartmann.fotodocumentation.rest.jackson;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
import com.networknt.schema.ValidationMessage; import com.networknt.schema.ValidationMessage;
/** /**
@@ -17,35 +13,5 @@ import com.networknt.schema.ValidationMessage;
* *
* created: Feb 14, 2017 * created: Feb 14, 2017
*/ */
public final class ValidationReply { public record ValidationReply(boolean success, Set<ValidationMessage> errors) {
public final boolean success;
public final Set<ValidationMessage> errors = new HashSet<>();
private ValidationReply(boolean success, Set<ValidationMessage> errors) {
this.success = success;
this.errors.addAll(errors);
}
public Response getErrorResponse() {
return Response.status(Status.BAD_REQUEST).entity(errors).build();
}
public static final class Builder {
private boolean success;
private Set<ValidationMessage> errors = new HashSet<>();
public Builder success(boolean success) {
this.success = success;
return this;
}
public Builder errors(Set<ValidationMessage> errors) {
this.errors = errors;
return this;
}
public ValidationReply build() {
return new ValidationReply(success, errors);
}
}
} }

View File

@@ -3,6 +3,7 @@ package marketing.heyday.hartmann.fotodocumentation.rest.vo;
import java.util.Date; import java.util.Date;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import marketing.heyday.hartmann.fotodocumentation.rest.jackson.SchemaValidated;
/** /**
* *
@@ -14,6 +15,6 @@ import io.swagger.v3.oas.annotations.media.Schema;
* created: 19 Jan 2026 * created: 19 Jan 2026
*/ */
@Schema(name = "CustomerPictureUpload") @Schema(name = "CustomerPictureUpload")
public record CustomerPictureValue(String username, String pharmacyName, String customerNumber, Date date, String comment, String category, String base64String) { public record CustomerPictureValue(String username, String pharmacyName, String customerNumber, Date date, String comment, String category, String base64String) implements SchemaValidated {
} }

View File

@@ -112,4 +112,12 @@ public abstract class AbstractRestTest extends AbstractTest {
String className = this.getClass().getName(); String className = this.getClass().getName();
return getResponseText(httpResponse, () -> className + "-" + name + ".json"); return getResponseText(httpResponse, () -> className + "-" + name + ".json");
} }
protected int customerCount() {
return getCount("select count(*) from customer");
}
protected int pictureCount() {
return getCount("select count(*) from picture");
}
} }

View File

@@ -37,10 +37,13 @@ public class CustomerPictureResourceTest extends AbstractRestTest {
} }
@Test @Test
@Order(1) @Order(2)
public void doAddCustomerPicture() throws IOException { public void doAddCustomerPicture() throws IOException {
LOG.info("doAddCustomerPicture"); LOG.info("doAddCustomerPicture");
assertEquals(3, customerCount());
assertEquals(5, pictureCount());
String authorization = getBasicHeader(); String authorization = getBasicHeader();
LOG.info("authorization: " + authorization); LOG.info("authorization: " + authorization);
String path = deploymentURL + PATH; String path = deploymentURL + PATH;
@@ -51,10 +54,56 @@ public class CustomerPictureResourceTest extends AbstractRestTest {
HttpResponse httpResponse = executeRequest(request); HttpResponse httpResponse = executeRequest(request);
int code = httpResponse.getStatusLine().getStatusCode(); int code = httpResponse.getStatusLine().getStatusCode();
assertEquals(200, code); assertEquals(200, code);
assertEquals(3, customerCount());
assertEquals(6, pictureCount());
}
@Test
@Order(3)
public void doAddCustomerWithPicture() throws IOException {
LOG.info("doAddCustomerWithPicture");
assertEquals(3, customerCount());
assertEquals(6, pictureCount());
String authorization = getBasicHeader();
LOG.info("authorization: " + authorization);
String path = deploymentURL + PATH;
Request request = Request.Post(path).addHeader("Accept", "application/json; charset=utf-8")
.addHeader("Authorization", authorization)
.bodyFile(new File(BASE_UPLOAD + "addNewCustomer.json"), ContentType.APPLICATION_JSON);
HttpResponse httpResponse = executeRequest(request);
int code = httpResponse.getStatusLine().getStatusCode();
assertEquals(200, code);
assertEquals(4, customerCount());
assertEquals(7, pictureCount());
}
@Test
@Order(1)
public void doAddCustomerPictureWrongJson() throws IOException {
LOG.info("doAddCustomerPictureWrongJson");
String authorization = getBasicHeader();
LOG.info("authorization: " + authorization);
String path = deploymentURL + PATH;
Request request = Request.Post(path).addHeader("Accept", "application/json; charset=utf-8")
.addHeader("Authorization", authorization)
.bodyFile(new File(BASE_UPLOAD + "addWrong.json"), ContentType.APPLICATION_JSON);
HttpResponse httpResponse = executeRequest(request);
int code = httpResponse.getStatusLine().getStatusCode();
assertEquals(400, code);
String text = getResponseText(httpResponse, "doGetAll");
System.out.println(text);
} }
@Test @Test
@Order(2) @Order(1)
public void doAddCustomerPictureNoAuth() throws IOException { public void doAddCustomerPictureNoAuth() throws IOException {
LOG.info("doAddCustomerPictureNoAuth"); LOG.info("doAddCustomerPictureNoAuth");
@@ -74,6 +123,6 @@ public class CustomerPictureResourceTest extends AbstractRestTest {
test.username = "adm"; test.username = "adm";
test.password = "x1t0e7Pb49"; test.password = "x1t0e7Pb49";
test.doAddCustomerPicture(); test.doAddCustomerPictureWrongJson();
} }
} }

View File

@@ -48,13 +48,12 @@ public class CustomerResourceTest extends AbstractRestTest {
HttpResponse httpResponse = executeRequest(request); HttpResponse httpResponse = executeRequest(request);
int code = httpResponse.getStatusLine().getStatusCode(); int code = httpResponse.getStatusLine().getStatusCode();
assertEquals(200, code); assertEquals(200, code);
String text = getResponseText(httpResponse, "doGetAll"); String text = getResponseText(httpResponse, "doGetAll");
String expected = fileToString(BASE_DOWNLOAD + "doGetAll.json"); String expected = fileToString(BASE_DOWNLOAD + "doGetAll.json");
jsonAssert(expected, text); jsonAssert(expected, text);
} }
@Test @Test
@Order(1) @Order(1)
public void doGetCustomer() throws IOException { public void doGetCustomer() throws IOException {
@@ -62,14 +61,13 @@ public class CustomerResourceTest extends AbstractRestTest {
String authorization = getAuthorization(); String authorization = getAuthorization();
LOG.info("authorization: " + authorization); LOG.info("authorization: " + authorization);
String path = deploymentURL + PATH +"/1"; String path = deploymentURL + PATH + "/1";
Request request = Request.Get(path).addHeader("Accept", "application/json; charset=utf-8") Request request = Request.Get(path).addHeader("Accept", "application/json; charset=utf-8")
.addHeader("Authorization", authorization); .addHeader("Authorization", authorization);
HttpResponse httpResponse = executeRequest(request); HttpResponse httpResponse = executeRequest(request);
int code = httpResponse.getStatusLine().getStatusCode(); int code = httpResponse.getStatusLine().getStatusCode();
assertEquals(200, code); assertEquals(200, code);
String text = getResponseText(httpResponse, "doGetCustomer"); String text = getResponseText(httpResponse, "doGetCustomer");
String expected = fileToString(BASE_DOWNLOAD + "doGetCustomer.json"); String expected = fileToString(BASE_DOWNLOAD + "doGetCustomer.json");

View File

@@ -27,7 +27,7 @@ import org.junit.jupiter.api.TestMethodOrder;
public class PictureResourceTest extends AbstractRestTest { public class PictureResourceTest extends AbstractRestTest {
private static final Log LOG = LogFactory.getLog(PictureResourceTest.class); private static final Log LOG = LogFactory.getLog(PictureResourceTest.class);
private static final String PATH = "api/picture"; private static final String PATH = "api/picture";
@BeforeAll @BeforeAll
public static void init() { public static void init() {
initDB(); initDB();
@@ -50,7 +50,7 @@ public class PictureResourceTest extends AbstractRestTest {
assertEquals(4, pictureCount()); assertEquals(4, pictureCount());
} }
@Test @Test
@Order(1) @Order(1)
public void doDeleteNotFound() throws IOException { public void doDeleteNotFound() throws IOException {
@@ -68,8 +68,5 @@ public class PictureResourceTest extends AbstractRestTest {
assertEquals(5, pictureCount()); assertEquals(5, pictureCount());
} }
private int pictureCount() {
return getCount("select count(*) from picture");
}
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long