Skip to content

Commit

Permalink
Merge pull request #151 from SAKPaaS/feature/TINF-XX-endpoint-tests
Browse files Browse the repository at this point in the history
TINF-324: Integration Test
  • Loading branch information
r-franzke committed May 6, 2020
2 parents dae1f47 + 5e75da6 commit cd02fa0
Show file tree
Hide file tree
Showing 12 changed files with 1,102 additions and 124 deletions.
7 changes: 1 addition & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,6 @@
<artifactId>reactor-spring</artifactId>
<version>1.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20190722</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
Expand All @@ -80,7 +75,7 @@
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
</dependency>
</dependencies>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/de/sakpaas/backend/service/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public UserInfoDto getUserInfo(String header) throws InvalidBearerTokenException
* @throws VerificationException iff the given JWT is invalid
*/
@VisibleForTesting
AccessToken verifyToken(String token) throws VerificationException {
public AccessToken verifyToken(String token) throws VerificationException {
return AdapterTokenVerifier.verifyToken(
token,
keycloakConfiguration.getKeycloakDeployment()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public ResponseEntity<List<LocationResultLocationDto>> getFavorites(

List<Favorite> favorites = favoriteService.findByUserUuid(userInfo.getId());
List<LocationResultLocationDto> response = favorites.stream()
.map(favorite -> locationMapper.mapLocationToOutputDto(favorite.getLocation()))
.map(favorite -> locationMapper.mapLocationToOutputDto(favorite.getLocation(), userInfo))
.collect(Collectors.toList());

return new ResponseEntity<>(response, OK);
Expand All @@ -79,7 +79,7 @@ public ResponseEntity<List<LocationResultLocationDto>> getFavorites(
* Post Endpoint that creates a favorite.
*
* @param locationId the location Id of the new favorite
* @param header The Authorization-Header that has to be provided in the request.
* @param header The Authorization-Header that has to be provided in the request.
* @return Returns a ResponseEntity
*/
@PostMapping("/self/favorites/{id}")
Expand All @@ -101,7 +101,7 @@ public ResponseEntity<LocationResultLocationDto> postFavorite(
* Delete Endpoint that deletes a favorite.
*
* @param locationId the location Id of the new favorite
* @param header The Authorization-Header that has to be provided in the request.
* @param header The Authorization-Header that has to be provided in the request.
* @return Returns a ResponseEntity
*/
@DeleteMapping("/self/favorites/{id}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public LocationResultLocationDto mapLocationToOutputDto(Location location, UserI

boolean flag = favoriteRepository.findByUserUuid(user.getId())
.stream()
.anyMatch(favorite -> favorite.getLocation() == location);
.anyMatch(favorite -> favorite.getLocation().equals(location));

return new LocationResultLocationDto(
location.getId(), location.getName(), flag,
Expand Down
6 changes: 5 additions & 1 deletion src/test/java/de/sakpaas/backend/HappyHamsterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

import de.sakpaas.backend.util.KeycloakConfiguration;
import org.junit.ClassRule;
import org.keycloak.adapters.springboot.KeycloakSpringBootProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.testcontainers.containers.PostgreSQLContainer;

@EnableConfigurationProperties(KeycloakSpringBootProperties.class)
public class HappyHamsterTest {

@MockBean
private KeycloakConfiguration keycloakConfiguration;
protected KeycloakConfiguration keycloakConfiguration;

@ClassRule
public static PostgreSQLContainer container = PostgresqlContainer.getInstance();
Expand Down
200 changes: 200 additions & 0 deletions src/test/java/de/sakpaas/backend/IntegrationTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
package de.sakpaas.backend;

import static org.hamcrest.Matchers.anything;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;

import de.sakpaas.backend.model.Favorite;
import de.sakpaas.backend.model.Location;
import de.sakpaas.backend.model.Occupancy;
import de.sakpaas.backend.service.AddressRepository;
import de.sakpaas.backend.service.FavoriteRepository;
import de.sakpaas.backend.service.LocationDetailsRepository;
import de.sakpaas.backend.service.LocationRepository;
import de.sakpaas.backend.service.OccupancyRepository;
import de.sakpaas.backend.service.UserService;
import java.util.List;
import java.util.UUID;
import lombok.SneakyThrows;
import net.minidev.json.JSONArray;
import net.minidev.json.JSONObject;
import net.minidev.json.JSONValue;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.keycloak.common.VerificationException;
import org.keycloak.representations.AccessToken;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultMatcher;

public class IntegrationTest extends HappyHamsterTest {

public static final UUID USER_UUID = UUID.fromString("550e8400-e29b-11d4-a716-446655440000");
public static final AccessToken USER_ACCESS_TOKEN = new AccessToken();
public static final String AUTHENTICATION_VALID = "Bearer token.valid.token";
public static final String AUTHENTICATION_INVALID = "Bearer token.invalid.token";
@Autowired
protected MockMvc mockMvc;
@SpyBean
protected UserService userService;
@Autowired
protected OccupancyRepository occupancyRepository;
@Autowired
protected FavoriteRepository favoriteRepository;
@Autowired
protected LocationRepository locationRepository;
@Autowired
protected LocationDetailsRepository locationDetailsRepository;
@Autowired
protected AddressRepository addressRepository;

@BeforeAll
static void setupAll() {
USER_ACCESS_TOKEN.setSubject(USER_UUID.toString());
USER_ACCESS_TOKEN.setPreferredUsername("test.user");
USER_ACCESS_TOKEN.setName("Testonius Tester");
USER_ACCESS_TOKEN.setGivenName("Testonius");
USER_ACCESS_TOKEN.setFamilyName("Tester");
USER_ACCESS_TOKEN.setEmail("testonius.tester@example.com");
}

@SneakyThrows
@BeforeEach
void setup() {
Mockito.doAnswer(invocation -> {
if (invocation.getArgument(0).equals("token.valid.token")) {
return USER_ACCESS_TOKEN;
}
throw new VerificationException();
})
.when(userService)
.verifyToken(Mockito.any());

// Cleanup tables
occupancyRepository.deleteAll();
favoriteRepository.deleteAll();
locationRepository.deleteAll();
addressRepository.deleteAll();
locationDetailsRepository.deleteAll();
}

@AfterEach
void tearDown() {
// Cleanup tables
occupancyRepository.deleteAll();
favoriteRepository.deleteAll();
locationRepository.deleteAll();
addressRepository.deleteAll();
locationDetailsRepository.deleteAll();
}

protected Location insert(Location location) {
locationDetailsRepository.save(location.getDetails());
addressRepository.save(location.getAddress());
return locationRepository.save(location);
}

protected Favorite insert(Favorite favorite) {
return favoriteRepository.save(favorite);
}

protected Occupancy insert(Occupancy occupancy) {
return occupancyRepository.save(occupancy);
}

protected ResultMatcher expectErrorObject() {
return result -> {
ResultMatcher[] matcher = new ResultMatcher[] {
jsonPath("$.timestamp").exists(),
jsonPath("$.status").isNumber(),
jsonPath("$.error").isString(),
jsonPath("$.path").isString(),
jsonPath("$.context.textId").isString(),
jsonPath("$.context.parameters").isArray(),
jsonPath("$.context.defaultMessage").isString(),
};
for (ResultMatcher resultMatcher : matcher) {
resultMatcher.match(result);
}
};
}

/**
* Checks if the given {@link org.springframework.test.web.servlet.MvcResult} has the form of a
* Location as defined in the openAPI specification. The fields given in the location parameter
* have to be correct.
*
* @param location the baseline {@link Location}
* @return the {@link ResultMatcher}
*/
protected ResultMatcher expectLocation(Location location) {
return result -> this.match(result, "$", location);
}


/**
* Checks if the given {@link org.springframework.test.web.servlet.MvcResult} has the form of a
* List of Locations as defined in the openAPI specification. The fields given in the locations
* parameter have to be correct.
*
* @param locations the baseline {@link List} of {@link Location}s
* @return the {@link ResultMatcher}
*/
protected ResultMatcher expectLocationList(List<Location> locations) {
return result -> {
// Check if the result is an array
jsonPath("$").isArray().match(result);

// Find correct Location for array element
JSONArray array = (JSONArray) JSONValue.parse(result.getResponse().getContentAsString());
for (int i = 0; i < array.size(); i++) {
long id = ((JSONObject) array.get(i))
.getAsNumber("id")
.longValue();
Location location = locations.stream()
.filter(loc -> loc.getId() == id)
.findAny()
.orElseThrow(() -> new AssertionError("Unknown LocationId in result."));
this.match(result, "$[" + i + "]", location);
}
};
}

private void match(MvcResult result, String selector, Location location) throws Exception {
// Define assertions
ResultMatcher[] matcher = new ResultMatcher[] {
jsonPath(selector + ".id").value(equalTo(location.getId()), Long.class),
jsonPath(selector + ".name").value(location.getName()),
// Favorite (unknown contents)
jsonPath(selector + ".favorite", anything()),
// Coordinates
jsonPath(selector + ".coordinates.latitude").value(location.getLatitude()),
jsonPath(selector + ".coordinates.longitude").value(location.getLongitude()),
// Details
jsonPath(selector + ".details.type").value(location.getDetails().getType()),
jsonPath(selector + ".details.brand").value(location.getDetails().getBrand()),
jsonPath(selector + ".details.openingHours")
.value(location.getDetails().getOpeningHours()),
// Occupancy (unknown contents)
jsonPath(selector + ".occupancy.value", anything()),
jsonPath(selector + ".occupancy.count", anything()),
jsonPath(selector + ".occupancy.latestReport", anything()),
// Address
jsonPath(selector + ".address.country").value(location.getAddress().getCountry()),
jsonPath(selector + ".address.city").value(location.getAddress().getCity()),
jsonPath(selector + ".address.postcode")
.value(location.getAddress().getPostcode()),
jsonPath(selector + ".address.street").value(location.getAddress().getStreet()),
jsonPath(selector + ".address.housenumber")
.value(location.getAddress().getHousenumber())
};
// Run assertions
for (ResultMatcher resultMatcher : matcher) {
resultMatcher.match(result);
}
}
}
112 changes: 0 additions & 112 deletions src/test/java/de/sakpaas/backend/controller/UserControllerTest.java

This file was deleted.

Loading

0 comments on commit cd02fa0

Please sign in to comment.