Compare commits
3 Commits
521cb0d670
...
deb36f05e3
Author | SHA1 | Date |
---|---|---|
Meutel | deb36f05e3 | |
Meutel | f5efa35c3d | |
Meutel | 6ff35ad6cf |
|
@ -31,10 +31,6 @@
|
|||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-mongodb</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-hateoas</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
|
@ -130,7 +126,6 @@
|
|||
<useSpringBoot3>true</useSpringBoot3>
|
||||
<apiPackage>net.meutel.recettes.api</apiPackage>
|
||||
<modelPackage>net.meutel.recettes.api.model</modelPackage>
|
||||
<hateoas>true</hateoas>
|
||||
<performBeanValidation>true</performBeanValidation>
|
||||
<useOptional>true</useOptional>
|
||||
<useSwaggerUI>false</useSwaggerUI>
|
||||
|
|
|
@ -1,19 +1,16 @@
|
|||
package net.meutel.recettes.api.controller;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
|
||||
import net.meutel.recettes.api.ReceipeApi;
|
||||
import net.meutel.recettes.api.ReceipesApi;
|
||||
import net.meutel.recettes.api.model.Receipe;
|
||||
import net.meutel.recettes.api.service.ReceipeService;
|
||||
|
||||
@RestController
|
||||
public class ReceipeController implements ReceipeApi, ReceipesApi {
|
||||
public class ReceipeController implements ReceipesApi {
|
||||
|
||||
private final ReceipeService service;
|
||||
|
||||
|
@ -21,14 +18,14 @@ public class ReceipeController implements ReceipeApi, ReceipesApi {
|
|||
this.service = service;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<NativeWebRequest> getRequest() {
|
||||
return ReceipeApi.super.getRequest();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<List<Receipe>> findReceipes() {
|
||||
return ResponseEntity.ok(service.findReceipes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<Receipe> getReceipeById(String receipeId) {
|
||||
return ResponseEntity.ok(service.getReceipeById(receipeId));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package net.meutel.recettes.api.exception;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ProblemDetail;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
|
||||
|
||||
@RestControllerAdvice
|
||||
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
|
||||
|
||||
@ExceptionHandler(ItemNotFoundException.class)
|
||||
ProblemDetail handleBookmarkNotFoundException(ItemNotFoundException e) {
|
||||
return ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, e.getMessage());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package net.meutel.recettes.api.exception;
|
||||
|
||||
public class ItemNotFoundException extends RuntimeException {
|
||||
|
||||
public ItemNotFoundException(String itemName, Object id) {
|
||||
super(itemName + " not found with id " + id);
|
||||
}
|
||||
|
||||
}
|
|
@ -6,7 +6,7 @@ import net.meutel.recettes.api.entity.ReceipeEntity;
|
|||
import net.meutel.recettes.api.model.Receipe;
|
||||
|
||||
@Mapper(componentModel = "spring")
|
||||
public interface ReceipeMapper {
|
||||
public interface ReceipeFullMapper {
|
||||
|
||||
Receipe fromEntity(ReceipeEntity entity);
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package net.meutel.recettes.api.mapper;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
|
||||
import net.meutel.recettes.api.entity.ReceipeEntity;
|
||||
import net.meutel.recettes.api.model.Receipe;
|
||||
|
||||
@Mapper(componentModel = "spring")
|
||||
public interface ReceipeSimplifiedMapper {
|
||||
|
||||
@Mapping(target = "receipeYield", ignore = true)
|
||||
Receipe fromEntity(ReceipeEntity entity);
|
||||
|
||||
ReceipeEntity toEntity(Receipe model);
|
||||
|
||||
}
|
|
@ -2,6 +2,9 @@ package net.meutel.recettes.api.service;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.lang.NonNull;
|
||||
|
||||
import net.meutel.recettes.api.exception.ItemNotFoundException;
|
||||
import net.meutel.recettes.api.model.Receipe;
|
||||
|
||||
public interface ReceipeService {
|
||||
|
@ -10,4 +13,9 @@ public interface ReceipeService {
|
|||
return List.of();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
default Receipe getReceipeById(String id) {
|
||||
throw new ItemNotFoundException("Receipe", id);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,7 +5,8 @@ import java.util.stream.Collectors;
|
|||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import net.meutel.recettes.api.mapper.ReceipeMapper;
|
||||
import net.meutel.recettes.api.exception.ItemNotFoundException;
|
||||
import net.meutel.recettes.api.mapper.ReceipeSimplifiedMapper;
|
||||
import net.meutel.recettes.api.model.Receipe;
|
||||
import net.meutel.recettes.api.repository.ReceipeRepository;
|
||||
|
||||
|
@ -13,9 +14,9 @@ import net.meutel.recettes.api.repository.ReceipeRepository;
|
|||
public class ReceipeServiceImpl implements ReceipeService {
|
||||
|
||||
private final ReceipeRepository repo;
|
||||
private final ReceipeMapper mapper;
|
||||
private final ReceipeSimplifiedMapper mapper;
|
||||
|
||||
public ReceipeServiceImpl(ReceipeRepository repo, ReceipeMapper mapper) {
|
||||
public ReceipeServiceImpl(ReceipeRepository repo, ReceipeSimplifiedMapper mapper) {
|
||||
this.repo = repo;
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
@ -28,4 +29,11 @@ public class ReceipeServiceImpl implements ReceipeService {
|
|||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Receipe getReceipeById(String id) {
|
||||
return repo.findById(id)
|
||||
.map(mapper::fromEntity)
|
||||
.orElseThrow(() -> new ItemNotFoundException("Receipe", id));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,42 +16,64 @@ import org.springframework.boot.test.context.SpringBootTest;
|
|||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import net.meutel.recettes.api.exception.ItemNotFoundException;
|
||||
import net.meutel.recettes.api.model.Receipe;
|
||||
import net.meutel.recettes.api.service.ReceipeService;
|
||||
|
||||
@SpringBootTest
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@AutoConfigureMockMvc
|
||||
public class ReceipeControllerTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@MockBean
|
||||
private ReceipeService service;
|
||||
@MockBean
|
||||
private ReceipeService service;
|
||||
|
||||
@Test
|
||||
public void findReceipes_none_empty() throws Exception {
|
||||
this.mockMvc.perform(get("/receipes"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$").isArray())
|
||||
.andExpect(jsonPath("$").isEmpty());
|
||||
public void getReceipeById_ItemNotFound_404() throws Exception {
|
||||
when(service.getReceipeById("TEST"))
|
||||
.thenThrow(new ItemNotFoundException("Receipe", "TEST"));
|
||||
|
||||
this.mockMvc.perform(get("/receipes/TEST"))
|
||||
.andExpect(status().isNotFound());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findReceipes_exists_list() throws Exception {
|
||||
Receipe r1 = new Receipe()
|
||||
.name("pates carbo");
|
||||
Receipe r2 = new Receipe()
|
||||
.name("soupe a l'oignon");
|
||||
when(service.findReceipes())
|
||||
.thenReturn(List.of(r1, r2));
|
||||
@Test
|
||||
public void getReceipeById_exixts_success() throws Exception {
|
||||
Receipe r1 = new Receipe()
|
||||
.name("pates carbo");
|
||||
when(service.getReceipeById("TEST"))
|
||||
.thenReturn(r1);
|
||||
|
||||
this.mockMvc.perform(get("/receipes"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$").isArray())
|
||||
.andExpect(jsonPath("$", hasSize(2)))
|
||||
.andExpect(jsonPath("$.[*].name").exists())
|
||||
.andExpect(jsonPath("$.[0].name", equalTo("pates carbo")))
|
||||
.andExpect(jsonPath("$.[*].description").doesNotExist());
|
||||
}
|
||||
this.mockMvc.perform(get("/receipes/TEST"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.name", equalTo("pates carbo")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findReceipes_none_empty() throws Exception {
|
||||
this.mockMvc.perform(get("/receipes"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$").isArray())
|
||||
.andExpect(jsonPath("$").isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findReceipes_exists_list() throws Exception {
|
||||
Receipe r1 = new Receipe()
|
||||
.name("pates carbo");
|
||||
Receipe r2 = new Receipe()
|
||||
.name("soupe a l'oignon");
|
||||
when(service.findReceipes())
|
||||
.thenReturn(List.of(r1, r2));
|
||||
|
||||
this.mockMvc.perform(get("/receipes"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$").isArray())
|
||||
.andExpect(jsonPath("$", hasSize(2)))
|
||||
.andExpect(jsonPath("$.[*].name").exists())
|
||||
.andExpect(jsonPath("$.[0].name", equalTo("pates carbo")))
|
||||
.andExpect(jsonPath("$.[*].description").doesNotExist());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,13 +4,16 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
|
||||
import net.meutel.recettes.api.entity.ReceipeEntity;
|
||||
import net.meutel.recettes.api.exception.ItemNotFoundException;
|
||||
import net.meutel.recettes.api.model.Receipe;
|
||||
import net.meutel.recettes.api.repository.ReceipeRepository;
|
||||
|
||||
|
@ -23,6 +26,26 @@ public class ReceipeServiceImplTest {
|
|||
@MockBean
|
||||
ReceipeRepository repo;
|
||||
|
||||
@Test
|
||||
void getReceipeById_noData_exception() {
|
||||
Assertions.assertThrows(ItemNotFoundException.class, () -> tested.getReceipeById("TEST"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getReceipeById_exists_receipe() {
|
||||
ReceipeEntity r1 = new ReceipeEntity();
|
||||
r1.setName("pates carbo");
|
||||
when(repo.findById("TEST"))
|
||||
.thenReturn(Optional.of(r1));
|
||||
|
||||
var result = tested.getReceipeById("TEST");
|
||||
|
||||
assertThat(result)
|
||||
.isNotNull()
|
||||
.extracting(Receipe::getName)
|
||||
.isEqualTo("pates carbo");
|
||||
}
|
||||
|
||||
@Test
|
||||
void findReceipes_noData_empty() {
|
||||
var result = tested.findReceipes();
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
meta {
|
||||
name: GET receipe notfound
|
||||
type: http
|
||||
seq: 1
|
||||
}
|
||||
|
||||
get {
|
||||
url: http://localhost:8080/receipes/test
|
||||
body: none
|
||||
auth: none
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"version": "1",
|
||||
"name": "Recettes",
|
||||
"type": "collection"
|
||||
}
|
|
@ -34,7 +34,7 @@ paths:
|
|||
items:
|
||||
$ref: '#/components/schemas/Receipe'
|
||||
|
||||
/receipe/{receipeId}:
|
||||
/receipes/{receipeId}:
|
||||
get:
|
||||
tags:
|
||||
- receipe
|
||||
|
|
Loading…
Reference in New Issue