253 lines
8.1 KiB
Java
253 lines
8.1 KiB
Java
package server.api;
|
|
|
|
|
|
import commons.Recipe;
|
|
import org.junit.jupiter.api.BeforeEach;
|
|
import org.junit.jupiter.api.Tag;
|
|
import org.junit.jupiter.api.Test;
|
|
import org.junit.jupiter.api.TestInfo;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
|
import org.springframework.context.annotation.Import;
|
|
import org.springframework.http.HttpStatus;
|
|
import org.springframework.messaging.simp.SimpMessagingTemplate;
|
|
import org.springframework.test.context.ActiveProfiles;
|
|
import server.WebSocketConfig;
|
|
import server.database.RecipeRepository;
|
|
import server.service.RecipeService;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
import java.util.Set;
|
|
import java.util.stream.LongStream;
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
|
|
// Spring Boot unit testing magic
|
|
// Before each test the state of the repository is reset by
|
|
// rolling back transaction of changes from previous test
|
|
@DataJpaTest
|
|
|
|
// This test sources its application profile from
|
|
// resources/application-mock-data-test.properties
|
|
// This config uses an in-memory database
|
|
@ActiveProfiles("mock-data-test")
|
|
|
|
// This is required to enable WebSocket messaging in tests
|
|
//
|
|
// Without this line, Spring screams about missing SimpMessagingTemplate bean
|
|
@Import({WebSocketConfig.class, RecipeService.class})
|
|
public class RecipeControllerTest {
|
|
private final RecipeService recipeService;
|
|
private final RecipeRepository recipeRepository;
|
|
private final SimpMessagingTemplate template;
|
|
private RecipeController controller;
|
|
|
|
private List<Recipe> recipes;
|
|
private List<Long> recipeIds;
|
|
public static final int NUM_RECIPES = 10;
|
|
|
|
// Injects a test repository into the test class
|
|
@Autowired
|
|
public RecipeControllerTest(
|
|
RecipeService recipeService,
|
|
RecipeRepository recipeRepository,
|
|
SimpMessagingTemplate template
|
|
) {
|
|
this.recipeService = recipeService;
|
|
this.recipeRepository = recipeRepository;
|
|
this.template = template;
|
|
}
|
|
|
|
@BeforeEach
|
|
public void setup(TestInfo info) {
|
|
recipes = LongStream
|
|
.range(0, NUM_RECIPES)
|
|
.mapToObj(x -> new Recipe(
|
|
null,
|
|
"Recipe " + x,
|
|
"en",
|
|
List.of(),
|
|
List.of()))
|
|
.toList();
|
|
controller = new RecipeController(
|
|
recipeService,
|
|
template
|
|
);
|
|
Set<String> tags = info.getTags();
|
|
List<Long> ids = new ArrayList<>();
|
|
|
|
// Some tests want initial data to be created.
|
|
if (tags.contains("test-from-init-data")) {
|
|
ids = LongStream
|
|
.range(0, NUM_RECIPES)
|
|
.map(idx -> recipeRepository
|
|
.save(recipes.get((int) idx))
|
|
.getId())
|
|
.boxed()
|
|
.toList();
|
|
}
|
|
|
|
// Some tests need to know the stored IDs of objects
|
|
if (tags.contains("need-ids")) {
|
|
recipeIds = ids;
|
|
}
|
|
|
|
// If no tags specified, the repository is initialized as empty.
|
|
}
|
|
|
|
@Test
|
|
public void createOneRecipe() {
|
|
controller.createRecipe(recipes.getFirst());
|
|
|
|
// There is 1 recipe in the repository
|
|
assertEquals(1,
|
|
recipeRepository.count());
|
|
}
|
|
@Test
|
|
public void createManyRecipes() {
|
|
recipes.forEach(recipe ->
|
|
controller.createRecipe(recipe));
|
|
|
|
// There are the same number of recipes in the repository as the input list
|
|
assertEquals(recipes.size(),
|
|
recipeRepository.count());
|
|
}
|
|
@Test
|
|
@Tag("test-from-init-data")
|
|
public void getManyRecipes() {
|
|
// The number of recipes returned is the same as the entire input list
|
|
assertEquals(recipes.size(),
|
|
controller.getRecipes(
|
|
Optional.empty(),
|
|
Optional.empty(),
|
|
Optional.of(List.of("en", "nl")))
|
|
.getBody()
|
|
.size());
|
|
}
|
|
|
|
@Test
|
|
@Tag("test-from-init-data")
|
|
public void getSomeRecipes() {
|
|
final int LIMIT = 5;
|
|
// The number of recipes returned is the same as the limit
|
|
assertEquals(LIMIT,
|
|
controller.getRecipes(
|
|
Optional.empty(),
|
|
Optional.of(LIMIT),
|
|
Optional.of(List.of("en")))
|
|
.getBody()
|
|
.size());
|
|
}
|
|
|
|
@Test
|
|
@Tag("test-from-init-data")
|
|
public void getManyRecipesWithLocale() {
|
|
// The number of recipes returned is the same as the entire input list
|
|
assertEquals(recipes.size(),
|
|
controller.getRecipes(
|
|
Optional.empty(),
|
|
Optional.empty(),
|
|
Optional.of(List.of("en", "nl")))
|
|
.getBody()
|
|
.size());
|
|
}
|
|
|
|
@Test
|
|
@Tag("test-from-init-data")
|
|
public void getNoRecipesWithLocale() {
|
|
// should have NO Dutch recipes (thank god)
|
|
assertEquals(0,
|
|
controller.getRecipes(
|
|
Optional.empty(),
|
|
Optional.empty(),
|
|
Optional.of(List.of("nl")))
|
|
.getBody()
|
|
.size());
|
|
}
|
|
@Test
|
|
@Tag("test-from-init-data")
|
|
public void getSomeRecipesWithLocale() {
|
|
final int LIMIT = 5;
|
|
assertEquals(LIMIT,
|
|
controller.getRecipes(
|
|
Optional.empty(),
|
|
Optional.of(LIMIT),
|
|
Optional.of(List.of("en", "nl")))
|
|
.getBody()
|
|
.size());
|
|
}
|
|
|
|
@Test
|
|
@Tag("test-from-init-data")
|
|
@Tag("need-ids")
|
|
public void findOneRecipeExists() {
|
|
final int CHECK_INDEX = 3;
|
|
// The third item in the input list is the same as the third item retrieved from the database
|
|
assertEquals(
|
|
recipes.get(CHECK_INDEX),
|
|
controller.getRecipe(recipeIds.get(CHECK_INDEX))
|
|
.getBody());
|
|
}
|
|
|
|
@Test
|
|
public void findOneRecipeNotExists() {
|
|
final int CHECK_INDEX = 3;
|
|
// There does not exist a recipe with ID=3 since there are no items in the repository.
|
|
assertEquals(
|
|
HttpStatus.NOT_FOUND,
|
|
controller.getRecipe((long) CHECK_INDEX)
|
|
.getStatusCode());
|
|
}
|
|
|
|
@Test
|
|
@Tag("test-from-init-data")
|
|
@Tag("need-ids")
|
|
public void deleteOneRecipeGood() {
|
|
final int DELETE_INDEX = 5;
|
|
|
|
// The object has been successfully deleted
|
|
assertEquals(HttpStatus.OK,
|
|
controller.deleteRecipe(recipeIds.get(DELETE_INDEX))
|
|
.getStatusCode());
|
|
}
|
|
|
|
@Test
|
|
@Tag("test-from-init-data")
|
|
@Tag("need-ids")
|
|
public void deleteOneRecipeCountGood() {
|
|
final int DELETE_INDEX = 5;
|
|
controller.deleteRecipe(recipeIds.get(DELETE_INDEX));
|
|
|
|
// The count of items decreased by 1 after the 5th item has been removed.
|
|
assertEquals(recipeIds.size() - 1,
|
|
recipeRepository.count());
|
|
}
|
|
|
|
@Test
|
|
public void deleteOneRecipeFail() {
|
|
final Long DELETE_INDEX = 5L;
|
|
assertEquals(HttpStatus.BAD_REQUEST,
|
|
controller.deleteRecipe(DELETE_INDEX)
|
|
.getStatusCode());
|
|
}
|
|
|
|
@Test
|
|
@Tag("test-from-init-data")
|
|
@Tag("need-ids")
|
|
public void updateOneRecipeHasNewData() {
|
|
final int UPDATE_INDEX = 5;
|
|
Recipe newRecipe = controller.getRecipe(recipeIds
|
|
.get(UPDATE_INDEX))
|
|
.getBody();
|
|
|
|
newRecipe.setName("New recipe");
|
|
controller.updateRecipe(newRecipe.getId(), newRecipe);
|
|
|
|
assertEquals("New recipe",
|
|
recipeRepository.getReferenceById(recipeIds
|
|
.get(UPDATE_INDEX))
|
|
.getName());
|
|
}
|
|
}
|