This commit is contained in:
Meutel 2023-10-22 18:28:39 +02:00
parent ba66fd20d1
commit c97bb7d64a
15 changed files with 328 additions and 7 deletions

View File

@ -13,8 +13,8 @@ import net.meutel.recettes.api.model.RecetteParam;
import net.meutel.recettes.api.service.ParametersService;
@RestController
public class ParametersApiController implements ParametersApi {
private final Logger LOG = LoggerFactory.getLogger(ParametersApiController.class);
public class ParameterController implements ParametersApi {
private final Logger LOG = LoggerFactory.getLogger(ParameterController.class);
@Autowired
private ParametersService service;

View File

@ -0,0 +1,32 @@
package net.meutel.recettes.api.controller;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
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 {
@Autowired
private ReceipeService service;
@Override
public Optional<NativeWebRequest> getRequest() {
return ReceipeApi.super.getRequest();
}
@Override
public ResponseEntity<List<Receipe>> findReceipes() {
return ResponseEntity.ok(service.findReceipes());
}
}

View File

@ -0,0 +1,60 @@
package net.meutel.recettes.api.entity;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document("receipes")
public class ReceipeEntity {
@Id
private String id;
private String name;
private String description;
private String cookTime;
private String prepTime;
private String author;
@Override
public String toString() {
return "ReceipeEntity [id=" + id + ", name=" + name + ", description=" + description + ", cookTime=" + cookTime
+ ", prepTime=" + prepTime + ", author=" + author + "]";
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCookTime() {
return cookTime;
}
public void setCookTime(String cookTime) {
this.cookTime = cookTime;
}
public String getPrepTime() {
return prepTime;
}
public void setPrepTime(String prepTime) {
this.prepTime = prepTime;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}

View File

@ -1,4 +1,4 @@
package net.meutel.recettes.api.enitity;
package net.meutel.recettes.api.entity;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

View File

@ -0,0 +1,15 @@
package net.meutel.recettes.api.mapper;
import org.mapstruct.Mapper;
import net.meutel.recettes.api.entity.ReceipeEntity;
import net.meutel.recettes.api.model.Receipe;
@Mapper(componentModel = "spring")
public interface ReceipeMapper {
Receipe fromEntity(ReceipeEntity entity);
ReceipeEntity toEntity(Receipe model);
}

View File

@ -3,14 +3,13 @@ package net.meutel.recettes.api.mapper;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import net.meutel.recettes.api.enitity.RecetteParamEntity;
import net.meutel.recettes.api.entity.RecetteParamEntity;
import net.meutel.recettes.api.model.RecetteParam;
@Mapper(componentModel = "spring")
public interface RecetteParamMapper {
@Mapping(target = "atType", source = "entity._type")
@Mapping(target = "add", ignore = true)
RecetteParam fromEntity(RecetteParamEntity entity);
@Mapping(target = "_type", source = "model.atType")

View File

@ -0,0 +1,9 @@
package net.meutel.recettes.api.repository;
import org.springframework.data.mongodb.repository.MongoRepository;
import net.meutel.recettes.api.entity.ReceipeEntity;
public interface ReceipeRepository extends MongoRepository<ReceipeEntity, String> {
}

View File

@ -4,7 +4,7 @@ import java.util.stream.Stream;
import org.springframework.data.mongodb.repository.MongoRepository;
import net.meutel.recettes.api.enitity.RecetteParamEntity;
import net.meutel.recettes.api.entity.RecetteParamEntity;

View File

@ -0,0 +1,13 @@
package net.meutel.recettes.api.service;
import java.util.List;
import net.meutel.recettes.api.model.Receipe;
public interface ReceipeService {
default List<Receipe> findReceipes() {
return List.of();
}
}

View File

@ -0,0 +1,31 @@
package net.meutel.recettes.api.service;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
import net.meutel.recettes.api.mapper.ReceipeMapper;
import net.meutel.recettes.api.model.Receipe;
import net.meutel.recettes.api.repository.ReceipeRepository;
@Service
public class ReceipeServiceImpl implements ReceipeService {
private final ReceipeRepository repo;
private final ReceipeMapper mapper;
public ReceipeServiceImpl(ReceipeRepository repo, ReceipeMapper mapper) {
this.repo = repo;
this.mapper = mapper;
}
@Override
public List<Receipe> findReceipes() {
return repo.findAll()
.stream()
.map(mapper::fromEntity)
.collect(Collectors.toList());
}
}

View File

@ -1,3 +1,4 @@
spring.data.mongodb.database=recettes
logging.level.org.springframework.data.mongodb=DEBUG
management.endpoint.health.show-details=always
spring.jackson.default-property-inclusion=non-null

View File

@ -0,0 +1,57 @@
package net.meutel.recettes.api.controller;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
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.model.Receipe;
import net.meutel.recettes.api.service.ReceipeService;
@SpringBootTest
@AutoConfigureMockMvc
public class ReceipeControllerTest {
@Autowired
private MockMvc mockMvc;
@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());
}
@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());
}
}

View File

@ -10,7 +10,7 @@ import static org.mockito.Mockito.when;
import java.util.List;
import net.meutel.recettes.api.enitity.RecetteParamEntity;
import net.meutel.recettes.api.entity.RecetteParamEntity;
import net.meutel.recettes.api.model.RecetteParam;
import net.meutel.recettes.api.repository.RecetteParamRepository;

View File

@ -0,0 +1,57 @@
package net.meutel.recettes.api.service;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
import java.util.List;
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.model.Receipe;
import net.meutel.recettes.api.repository.ReceipeRepository;
@SpringBootTest
public class ReceipeServiceImplTest {
@Autowired
ReceipeService tested;
@MockBean
ReceipeRepository repo;
@Test
void findReceipes_noData_empty() {
var result = tested.findReceipes();
assertThat(result)
.isNotNull()
.isEmpty();
}
@Test
void findReceipes_exists_list() {
ReceipeEntity r1 = new ReceipeEntity();
r1.setName("pates carbo");
ReceipeEntity r2 = new ReceipeEntity();
r2.setName("soupe a l'oignon");
when(repo.findAll())
.thenReturn(List.of(r1, r2));
var result = tested.findReceipes();
assertThat(result)
.isNotNull()
.hasSize(2);
assertThat(result).element(0)
.returns("pates carbo", Receipe::getName);
assertThat(result).element(1)
.returns("soupe a l'oignon", Receipe::getName);
}
}

View File

@ -106,3 +106,50 @@ components:
type: string
Receipe:
type: object
required:
- id
properties:
id:
description: Receipe unique id
type: string
maxLength: 24
minLength: 24
name:
description: Receipe name
type: string
description:
description: Receipe description
type: string
cookTime:
description: Cooking time
type: string
format: duration
prepTime:
description: Preparation time
type: string
format: duration
author:
description: Receipe author/source
type: string
receipeYield:
description: Quantity produced by receipe
type: object
required:
- quantity
- what
properties:
quantity:
$ref: '#/components/schemas/Quantity'
what:
description: Production target
type: string
Quantity:
type: object
required:
- value
properties:
value:
type: number
unit:
description: Unit of quantity
type: string