update api endpoint config and updated related tests (#26)

This commit is contained in:
cato
2022-06-14 19:33:28 +02:00
committed by GitHub
parent 7bfdf7a3e0
commit ebfd1b78e5
9 changed files with 99 additions and 158 deletions

View File

@@ -12,7 +12,6 @@ class RepositoryConfig implements RepositoryRestConfigurer {
@Override @Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) { public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) {
config.exposeIdsFor(Item.class); config.exposeIdsFor(Item.class);
config.setBasePath("/api/v1");
} }
} }

View File

@@ -1,57 +0,0 @@
package whattocook.controller;
import whattocook.exception.ItemNotFoundException;
import lombok.extern.slf4j.Slf4j;
import whattocook.models.Item;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import whattocook.services.ItemService;
import java.util.List;
@Slf4j
@RestController()
public class ItemController {
@Autowired
private ItemService itemService;
@GetMapping("/item")
public Item getItem(@RequestParam String name){
return itemService.findByName(name).orElseThrow(() -> new ItemNotFoundException("item " + name + " not found"));
}
@GetMapping("/items")
public List<Item> getItemList() {
return itemService.findAll();
}
@GetMapping("/items/{itemId}")
public Item getItem(@PathVariable(value = "itemId") Long itemId) {
return itemService.findById(itemId).orElseThrow(() -> new ItemNotFoundException("itemId " + itemId + " not found"));
}
@PostMapping("/items")
public Item createItem(@RequestBody Item item) {
return itemService.save(item);
}
@PutMapping("/items/{itemId}")
public void updateItem(@PathVariable(value = "itemId") Long itemId, @RequestBody Item item) {
itemService.findById(itemId).map(i -> {
i.setName(item.getName());
i.setQuantity(item.getQuantity());
i.setUnit(item.getUnit());
itemService.save(i);
return "Item updated";
}).orElseThrow(() -> new ItemNotFoundException("itemId " + itemId + " not found"));
}
@DeleteMapping("/items/{itemId}")
public void deleteItem(@PathVariable(value = "itemId") Long itemId) {
itemService.findById(itemId).map(p -> {
itemService.deleteById(itemId);
return "Item deleted";
}).orElseThrow(() -> new ItemNotFoundException("itemId " + itemId + " not found"));
}
}

View File

@@ -6,7 +6,6 @@ import org.springframework.stereotype.Service;
import whattocook.repositories.ItemRepository; import whattocook.repositories.ItemRepository;
import whattocook.services.ItemService; import whattocook.services.ItemService;
import java.util.List;
import java.util.Optional; import java.util.Optional;
@Service @Service
@@ -36,7 +35,7 @@ public class ItemServiceImpl implements ItemService {
} }
@Override @Override
public List<Item> findAll() { public Iterable<Item> findAll() {
return itemRepository.findAll(); return itemRepository.findAll();
} }
} }

View File

@@ -1,18 +1,22 @@
package whattocook.models; package whattocook.models;
import lombok.*; import lombok.*;
import org.hibernate.Hibernate;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.GeneratedValue; import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType; import javax.persistence.GenerationType;
import javax.persistence.Id; import javax.persistence.Id;
import java.util.Objects;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @Getter
@Data @Setter
@ToString
@Entity @Entity
public class Item { public class Item {
@Setter(AccessLevel.NONE)
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; private Long id;
@@ -22,4 +26,27 @@ public class Item {
private Unit unit; private Unit unit;
private int quantity; private int quantity;
public Item(String name, Unit unit, int quantity){
this.name = name;
this.unit = unit;
this.quantity = quantity;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) {
return false;
}
Item item = (Item) o;
return id != null && Objects.equals(id, item.id);
}
@Override
public int hashCode() {
return getClass().hashCode();
}
} }

View File

@@ -1,12 +1,12 @@
package whattocook.repositories; package whattocook.repositories;
import org.springframework.data.repository.CrudRepository;
import whattocook.models.Item; import whattocook.models.Item;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.util.Optional; import java.util.Optional;
@Repository @Repository
public interface ItemRepository extends JpaRepository<Item, Long> { public interface ItemRepository extends CrudRepository<Item, Long> {
Optional<Item> findByName(String name); Optional<Item> findByName(String name);
} }

View File

@@ -2,7 +2,6 @@ package whattocook.services;
import whattocook.models.Item; import whattocook.models.Item;
import java.util.List;
import java.util.Optional; import java.util.Optional;
public interface ItemService { public interface ItemService {
@@ -10,5 +9,5 @@ public interface ItemService {
void deleteById(Long id); void deleteById(Long id);
Optional<Item> findById(long id); Optional<Item> findById(long id);
Optional<Item> findByName(String name); Optional<Item> findByName(String name);
List<Item> findAll(); Iterable<Item> findAll();
} }

View File

@@ -7,6 +7,9 @@ spring:
username: sa username: sa
password: password:
driverClassName: org.h2.Driver driverClassName: org.h2.Driver
data:
rest:
base-path: /api/v1
logging: logging:
level: level:

View File

@@ -1,139 +1,107 @@
package items; package items;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import whattocook.controller.ItemController;
import whattocook.models.Item; import whattocook.models.Item;
import whattocook.models.Unit; import whattocook.models.Unit;
import whattocook.repositories.ItemRepository;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
@SpringBootTest(classes = whattocook.Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @SpringBootTest(classes = whattocook.Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public final class ItemTests { final class ItemTests {
@LocalServerPort
private int port;
@Autowired @Autowired
private TestRestTemplate testRestTemplate; private ItemRepository itemRepository;
@BeforeEach
@Test private void resetItems() {
public void postTest() { itemRepository.deleteAll();
Item item = new Item(5L, "kartoffel", Unit.GRAMMS, 5000);
assertThat(this.testRestTemplate.postForEntity("http://localhost:" + port + "/items", item, Item.class).getBody()).isEqualTo(item);
} }
@Test @Test
public void getOneTest() { public void saveTest() {
Item item = new Item(1L, "tortillias", Unit.GRAMMS, 5000); Item item = new Item("kartoffel", Unit.GRAMMS, 5000);
itemRepository.save(item);
assertTrue(itemRepository.existsById(item.getId()));
Long id= this.testRestTemplate.postForEntity("http://localhost:" + port + "/items", item, Item.class).getBody().getId(); }
assertTrue(compNotId(this.testRestTemplate.getForObject("http://localhost:" + port + "/items/"+id, Item.class),item));
@Test
public void findByIDTest() {
Item item = new Item("tortillias", Unit.GRAMMS, 5000);
itemRepository.save(item);
assertEquals(item, itemRepository.findById(item.getId()).get());
} }
@Test @Test
public void getOneExeptionTest() { public void findByIdNotPresentTest() {
assertFalse(itemRepository.findById(77L).isPresent());
assertThat(this.testRestTemplate.getForEntity("http://localhost:" + port + "/items/"+900000L, Item.class).getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
} }
@Test @Test
public void getallTest() { public void findByNameTest(){
List<Item> items = new ArrayList(); Item item = new Item("tortillias", Unit.GRAMMS, 5000);
items.add( new Item(1L, "nachos", Unit.GRAMMS, 5000)); itemRepository.save(item);
items.add( new Item(2L, "wurst", Unit.GRAMMS, 5000)); assertEquals(item, itemRepository.findByName(item.getName()).get());
items.add( new Item(3L, "schinken", Unit.GRAMMS, 5000)); }
items.add( new Item(4L, "brokkoli", Unit.GRAMMS, 5000));
items.add( new Item(5L, "eiscreme", Unit.GRAMMS, 5000));
@Test
public void findAllTest() {
List<Item> savedItems = new ArrayList();
savedItems.add( new Item("nachos", Unit.GRAMMS, 5000));
savedItems.add( new Item("wurst", Unit.GRAMMS, 5000));
savedItems.add( new Item("schinken", Unit.GRAMMS, 5000));
savedItems.add( new Item("brokkoli", Unit.GRAMMS, 5000));
savedItems.add( new Item("eiscreme", Unit.GRAMMS, 5000));
for (Item item:items) { itemRepository.saveAll(savedItems);
this.testRestTemplate.postForEntity("http://localhost:" + port + "/items", item, Item.class);
}
List<Map> getlist = this.testRestTemplate.getForObject("http://localhost:" + port + "/items",
List.class);
assertThat(mapListToName(getlist,"name")).containsAll(items.stream().map(Item::getName).toList());
List<Item> foundItems = (List<Item>)itemRepository.findAll();
assertTrue(compListNotId(savedItems, foundItems));
} }
@Test @Test
public void deleteTest() { public void deleteTest() {
Item item = new Item(16L, "elefantenfuß", Unit.GRAMMS, 5000); Item item = new Item("elefantenfuß", Unit.GRAMMS, 5000);
itemRepository.save(item);
assertEquals(item, itemRepository.findById(item.getId()).get());
long id=this.testRestTemplate.postForEntity("http://localhost:" + port + "/items", item, Item.class).getBody().getId(); itemRepository.delete(item);
this.testRestTemplate.delete("http://localhost:" + port + "/items/"+id); assertTrue(itemRepository.findById(item.getId()).isEmpty());
List<Map> getlist = this.testRestTemplate.getForObject("http://localhost:" + port + "/items",
List.class);
assertThat(mapListToName(getlist,"name")).doesNotContain(item.getName());
} }
@Test @Test
public void deleteExceptionTest() throws URISyntaxException { public void updateTest() {
ResponseEntity<Void> resp = testRestTemplate.exchange(new URI("http://localhost:" + port + "/items/"+70000), HttpMethod.DELETE, HttpEntity.EMPTY, Void.class); Item item = new Item("schokoküsse", Unit.GRAMMS, 5000);
assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); itemRepository.save(item);
} long itemCount = itemRepository.count();
item.setQuantity(4574);
@Test itemRepository.save(item);
public void putTest() { assertEquals(itemCount, itemRepository.count());
Item item = new Item(32L, "schokoküsse", Unit.GRAMMS, 5000); assertEquals(4574, itemRepository.findById(item.getId()).get().getQuantity());
Item changed = new Item(32L, "schokoküsse", Unit.GRAMMS, 45634);
long id= this.testRestTemplate.postForEntity("http://localhost:" + port + "/items", item, Item.class).getBody().getId();
this.testRestTemplate.put("http://localhost:" + port + "/items/"+id, changed);
List<Map> getlist = this.testRestTemplate.getForObject("http://localhost:" + port + "/items",
List.class);
assertThat(mapListToName(getlist,"quantity")).contains(changed.getQuantity());
}
@Test
public void putExceptionTest() throws URISyntaxException {
Item changed = new Item(70000L, "gazellenkopf", Unit.GRAMMS, 80000);
String resourceUrl =
"http://localhost:" + port + "/items/"+700000;
HttpEntity<Item> requestUpdate = new HttpEntity<>(changed);
ResponseEntity<Void> resp = testRestTemplate.exchange(resourceUrl, HttpMethod.PUT, requestUpdate,Void.class);
assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
}
private List mapListToName(List<Map> input, String param){
return input.stream().map(t -> t.get(param)).toList();
} }
private boolean compNotId(Item item1, Item item2){ private boolean compNotId(Item item1, Item item2){
return item1.getName().equals(item2.getName())&&item1.getQuantity()==item2.getQuantity()&&item1.getUnit().equals(item2.getUnit()); return item1.getName().equals(item2.getName())&&item1.getQuantity()==item2.getQuantity()&&item1.getUnit().equals(item2.getUnit());
} }
private boolean compListNotId(List<Item> expected, List<Item> actual){
if (expected.size() != actual.size()){
return false;
}
for (int i = 0; i < expected.size(); i++){
if(!compNotId(expected.get(i), actual.get(i))){
return false;
}
}
return true;
}
} }

View File

@@ -7,6 +7,9 @@ spring:
username: sa username: sa
password: password:
driverClassName: org.h2.Driver driverClassName: org.h2.Driver
data:
rest:
base-path: /api/v1
logging: logging:
level: level: