Skip to content

Commit

Permalink
Add JsonPayload coverage tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jcarranzan committed Jul 17, 2024
1 parent 567369d commit 9e807be
Show file tree
Hide file tree
Showing 10 changed files with 2,423 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package io.quarkus.ts.http.advanced.reactive;

import java.util.Date;
import java.util.List;

public class FootballTeam {

private String name;
private String colorTShirt;
private int euroCups;
private Date foundationDate;
private String stadium;
private List<String> keyPlayers;

public FootballTeam() {
}

public FootballTeam(String name, String colorTShirt, int euroCups, Date foundationDate, String stadium,
List<String> keyPlayers) {
this.name = name;
this.colorTShirt = colorTShirt;
this.euroCups = euroCups;
this.foundationDate = foundationDate;
this.stadium = stadium;
this.keyPlayers = keyPlayers;
}

public Date getFoundationDate() {
return foundationDate;
}

public void setFoundationDate(Date foundationDate) {
this.foundationDate = foundationDate;
}

public String getStadium() {
return stadium;
}

public void setStadium(String stadium) {
this.stadium = stadium;
}

public List<String> getKeyPlayers() {
return keyPlayers;
}

public void setKeyPlayers(List<String> keyPlayers) {
this.keyPlayers = keyPlayers;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getColorTShirt() {
return colorTShirt;
}

public void setColorTShirt(String colorTShirt) {
this.colorTShirt = colorTShirt;
}

public int getEuroCups() {
return euroCups;
}

public void setEuroCups(int euroCups) {
this.euroCups = euroCups;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package io.quarkus.ts.http.advanced.reactive;

import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;

import org.jboss.logging.Logger;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.smallrye.mutiny.Uni;

@Path("/resource")
public class FootballTeamResource {

private static final Logger LOG = Logger.getLogger(FootballTeamResource.class);

private Set<FootballTeam> footballTeamSet = Collections.synchronizedSet(new LinkedHashSet<>());

public FootballTeamResource() {
footballTeamSet.add(new FootballTeam("Norway", "Red", 0, new Date(1920, 6, 1), "Oslo Stadium",
Arrays.asList("Ole Gunnar Solskjær", "Joshua King")));
}

/**
*
* When a JSON extension is installed such as quarkus-rest-jackson or quarkus-rest-jsonb
* Quarkus will use the application/json media type by default for most return values
*/
@GET
public Response list() {
return Response.ok(footballTeamSet).build();
}

@POST
@Path("/upload-football-json")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Uni<Response> uploadFootballJson(String data) {
try {
ObjectMapper objectMapper = new ObjectMapper();
Set<FootballTeam> teamSet = objectMapper.readValue(data, new TypeReference<Set<FootballTeam>>() {
});
for (FootballTeam footballTeam : teamSet) {
if (footballTeam == null || footballTeam.getName().isEmpty()) {
return Uni.createFrom().item(Response.status(400).entity("Some fields are empty or null").build());
} else {
footballTeamSet.add(footballTeam);
}
}
return Uni.createFrom()
.item(() -> {
Map<String, Object> responseMap = new HashMap<>();
responseMap.put("teams", footballTeamSet);
responseMap.put("message", "Teams added successfully");
return Response.status(201).entity(responseMap).build();
});
} catch (JsonMappingException ex) {
LOG.error(ex.getMessage());
return Uni.createFrom()
.item(Response.status(400).entity("JsonMappingException : " + ex.getMessage()).build());
} catch (JsonProcessingException e) {
LOG.error(e.getMessage());
return Uni.createFrom().item(
Response.status(400).entity("Invalid JSON - JsonProcessingException : " + e.getOriginalMessage()).build());
}

}

@POST
@Path("/process-json")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Uni<Response> processJson(String jsonData) {
return Uni.createFrom().item(() -> Response.ok().entity(jsonData).build());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package io.quarkus.ts.http.advanced.reactive;

import static io.restassured.RestAssured.given;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Date;

import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.quarkus.test.bootstrap.RestService;
import io.quarkus.test.scenarios.QuarkusScenario;
import io.quarkus.test.services.QuarkusApplication;
import io.restassured.http.ContentType;
import io.restassured.response.Response;

@QuarkusScenario
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class JsonPayloadIT {

@QuarkusApplication(classes = { FootballTeamResource.class, FootballTeam.class
}, properties = "oidcdisable.properties")
static RestService app = new RestService();

@Test
@Order(1)
public void sendSuccessfulJSONPayloadFromAFile() throws IOException {

String jsonPayload = FileUtils.readFileToString(
Paths.get("src", "test", "resources", "football-teams.json").toFile(),
StandardCharsets.UTF_8);

Response response = given()
.contentType(ContentType.JSON)
.body(jsonPayload)
.when()
.post("/resource/upload-football-json")
.then()
.statusCode(201)
.body("teams.size()", is(27))
.extract().response();
assertThat(response.body().asString(), containsString("Teams added successfully"));

}

@Test
public void sendLargeComplexJSONPayload() throws IOException {
String jsonPayload = FileUtils.readFileToString(
Paths.get("src", "test", "resources", "big_sample.json").toFile(),
StandardCharsets.UTF_8);

Response response = given()
.contentType(ContentType.JSON)
.body(jsonPayload)
.when()
.post("/resource/process-json")
.then()
.statusCode(jakarta.ws.rs.core.Response.Status.OK.getStatusCode())
.extract().response();
assertThat(response.body().asString(), containsString("Hello, Singleton Middleton! You have 4 unread messages."));
}

@Test
public void sendJSONWithEmptyFieldsPayload() throws IOException {
String jsonPayload = FileUtils.readFileToString(
Paths.get("src", "test", "resources", "football-empty-teams.json").toFile(),
StandardCharsets.UTF_8);

Response response = given()
.contentType(ContentType.JSON)
.body(jsonPayload)
.when()
.post("/resource/upload-football-json")
.then()
.statusCode(jakarta.ws.rs.core.Response.Status.BAD_REQUEST.getStatusCode())
.extract().response();

assertThat(response.body().asString(), containsString("Some fields are empty or null"));
}

@Test
public void sendInvalidJSONPayload() throws IOException {
String jsonPayload = FileUtils.readFileToString(
Paths.get("src", "test", "resources", "football-teams_invalid.json").toFile(),
StandardCharsets.UTF_8);

Response response = given()
.contentType(ContentType.JSON)
.body(jsonPayload)
.when()
.post("/resource/upload-football-json")
.then()
.statusCode(jakarta.ws.rs.core.Response.Status.BAD_REQUEST.getStatusCode())
.extract().response();

assertThat(response.body().asString(), containsString(
"Invalid JSON - JsonProcessingException : Unexpected character ('{' (code 123)): was expecting comma to separate Array entries"));
}

@Test
public void sendASingleJSONObject() throws JsonProcessingException {
FootballTeam teamX = new FootballTeam(
"Single Team",
"Pink",
3,
new Date(1900, 1, 1),
"A",
Arrays.asList("You", "You"));
ObjectMapper objectMapper = new ObjectMapper();
String jsonPayload = objectMapper.writeValueAsString(teamX);

Response response = given()
.contentType(ContentType.JSON)
.body(jsonPayload)
.when()
.post("/resource/upload-football-json")
.then()
.statusCode(400)
.extract().response();
assertThat(response.body().asString(), containsString(
"JsonMappingException : Cannot deserialize value of type `java.util.HashSet<io.quarkus.ts.http.advanced.reactive.FootballTeam>`"));
}

@Test
public void sendIncorrectContentType() throws IOException {
String jsonPayload = FileUtils.readFileToString(
Paths.get("src", "test", "resources", "football-teams.json").toFile(),
StandardCharsets.UTF_8);

given()
.contentType(ContentType.TEXT)
.body(jsonPayload)
.when()
.post("/resource/upload-football-json")
.then()
.statusCode(415);

}

@Test
public void sendSpecialCharactersJSONPayload() throws Exception {
FootballTeam team1 = new FootballTeam(
"Føøbåll™ Tëâm",
"Rëd&Blüé",
3,
new Date(1900, 1, 1),
"Städiümß©",
Arrays.asList("Pläÿér Ône", "Pläÿér Twø´ñ"));

FootballTeam team2 = new FootballTeam(
"Tëâm 2",
"Grëèn&Yëllöw",
2,
new Date(2010, 1, 15),
"New Städiüm©",
Arrays.asList("Pläÿér Thrëéñ", "Pläÿér Fòur"));

ObjectMapper objectMapper = new ObjectMapper();
String jsonPayload = objectMapper.writeValueAsString(Arrays.asList(team1, team2));

Response response = given()
.contentType(ContentType.JSON)
.body(jsonPayload)
.when()
.post("/resource/upload-football-json")
.then()
.statusCode(201)
.extract().response();

assertThat(response.body().asString(), containsString("Teams added successfully"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public class NonJsonPayLoadIT {
@QuarkusApplication(classes = { YamlProvider.class, CityResource.class, City.class, CityListDTO.class,
CityListWrapper.class,
CityListWrapperSerializer.class,
}, properties = "nonjson.properties")
}, properties = "oidcdisable.properties")
static RestService app = new RestService();

private static File imageFile;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.quarkus.ts.http.advanced.reactive;

import io.quarkus.test.scenarios.OpenShiftScenario;

@OpenShiftScenario
public class OpenShiftJsonPayloadIT extends JsonPayloadIT{
}
Loading

0 comments on commit 9e807be

Please sign in to comment.