From 971ff6cef4252dd16315f0d1474c04e614ab760f Mon Sep 17 00:00:00 2001 From: Rinae Hyun Date: Wed, 14 Aug 2024 16:16:46 +0200 Subject: [PATCH 01/10] Create a POST method to add a new book with IdService, Dto and Enum --- .../backend/controllers/BookController.java | 10 +++++++--- .../github/esgoet/backend/dto/NewBookDto.java | 15 +++++++++++++++ .../com/github/esgoet/backend/models/Book.java | 7 ++++++- .../github/esgoet/backend/models/Genre.java | 18 ++++++++++++++++++ .../esgoet/backend/services/BookService.java | 14 ++++++++++++++ .../esgoet/backend/services/IdService.java | 15 +++++++++++++++ 6 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 backend/src/main/java/com/github/esgoet/backend/dto/NewBookDto.java create mode 100644 backend/src/main/java/com/github/esgoet/backend/models/Genre.java create mode 100644 backend/src/main/java/com/github/esgoet/backend/services/IdService.java diff --git a/backend/src/main/java/com/github/esgoet/backend/controllers/BookController.java b/backend/src/main/java/com/github/esgoet/backend/controllers/BookController.java index f55eded..a8a754d 100644 --- a/backend/src/main/java/com/github/esgoet/backend/controllers/BookController.java +++ b/backend/src/main/java/com/github/esgoet/backend/controllers/BookController.java @@ -1,11 +1,10 @@ package com.github.esgoet.backend.controllers; +import com.github.esgoet.backend.dto.NewBookDto; import com.github.esgoet.backend.models.Book; import com.github.esgoet.backend.services.BookService; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.util.List; @@ -21,4 +20,9 @@ public class BookController { public List getBooks() { return bookService.getAllBooks(); } + + @PostMapping + public Book addABook(@RequestBody NewBookDto newBookDto) { + return bookService.saveNewABook(newBookDto); + } } diff --git a/backend/src/main/java/com/github/esgoet/backend/dto/NewBookDto.java b/backend/src/main/java/com/github/esgoet/backend/dto/NewBookDto.java new file mode 100644 index 0000000..1a462a2 --- /dev/null +++ b/backend/src/main/java/com/github/esgoet/backend/dto/NewBookDto.java @@ -0,0 +1,15 @@ +package com.github.esgoet.backend.dto; + +import com.github.esgoet.backend.models.Genre; +import lombok.With; + +import java.time.LocalDate; + +@With +public record NewBookDto( + String author, + String title, + Genre genre, + LocalDate publicationDate +) { +} diff --git a/backend/src/main/java/com/github/esgoet/backend/models/Book.java b/backend/src/main/java/com/github/esgoet/backend/models/Book.java index ff5d770..f5f1129 100644 --- a/backend/src/main/java/com/github/esgoet/backend/models/Book.java +++ b/backend/src/main/java/com/github/esgoet/backend/models/Book.java @@ -3,10 +3,15 @@ import lombok.With; import org.springframework.data.mongodb.core.mapping.Document; +import java.time.LocalDate; + @With @Document("books") public record Book( String id, String author, - String title) { + String title, + Genre genre, + LocalDate publicationDate +) { } diff --git a/backend/src/main/java/com/github/esgoet/backend/models/Genre.java b/backend/src/main/java/com/github/esgoet/backend/models/Genre.java new file mode 100644 index 0000000..6b89ae9 --- /dev/null +++ b/backend/src/main/java/com/github/esgoet/backend/models/Genre.java @@ -0,0 +1,18 @@ +package com.github.esgoet.backend.models; + +public enum Genre { + NONE("none"), + FICTION("Fiction"), + MYSTERY("Mystery"), + THRILLER("Thriller"), + FANTASY("Fantasy"), + SCIENCE("Science"), + NON_FICTION("None Fiction"), + HISTORY("History"); + + private final String genre; + + Genre(String genre) { this.genre = genre; } + + public String getGenre() { return genre; } +} diff --git a/backend/src/main/java/com/github/esgoet/backend/services/BookService.java b/backend/src/main/java/com/github/esgoet/backend/services/BookService.java index c42aaa4..392784b 100644 --- a/backend/src/main/java/com/github/esgoet/backend/services/BookService.java +++ b/backend/src/main/java/com/github/esgoet/backend/services/BookService.java @@ -1,6 +1,8 @@ package com.github.esgoet.backend.services; +import com.github.esgoet.backend.dto.NewBookDto; import com.github.esgoet.backend.models.Book; +import com.github.esgoet.backend.models.Genre; import com.github.esgoet.backend.repositories.BookRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -12,8 +14,20 @@ public class BookService { private final BookRepository bookRepository; + private final IdService idService; public List getAllBooks() { return bookRepository.findAll(); } + + public Book saveNewABook(NewBookDto newBookDto) { + Book bookToSave = new Book( + idService.randomId(), + newBookDto.author(), + newBookDto.title(), + newBookDto.genre(), + newBookDto.publicationDate() + ); + return bookRepository.save(bookToSave); + } } diff --git a/backend/src/main/java/com/github/esgoet/backend/services/IdService.java b/backend/src/main/java/com/github/esgoet/backend/services/IdService.java new file mode 100644 index 0000000..7caf4db --- /dev/null +++ b/backend/src/main/java/com/github/esgoet/backend/services/IdService.java @@ -0,0 +1,15 @@ +package com.github.esgoet.backend.services; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.UUID; + +@Service +@RequiredArgsConstructor +public class IdService { + + public String randomId() { + return UUID.randomUUID().toString(); + } +} From 6ddbd13f3de5519739b52978990d3f7cad77e29d Mon Sep 17 00:00:00 2001 From: Rinae Hyun Date: Wed, 14 Aug 2024 16:23:33 +0200 Subject: [PATCH 02/10] Write unit & integration tests for POST method (add a new book) --- .../BookControllerIntegrationTest.java | 33 +++++++++++++++++-- .../backend/services/BookServiceUnitTest.java | 31 ++++++++++++++--- 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/backend/src/test/java/com/github/esgoet/backend/controllers/BookControllerIntegrationTest.java b/backend/src/test/java/com/github/esgoet/backend/controllers/BookControllerIntegrationTest.java index c96131a..bcafa41 100644 --- a/backend/src/test/java/com/github/esgoet/backend/controllers/BookControllerIntegrationTest.java +++ b/backend/src/test/java/com/github/esgoet/backend/controllers/BookControllerIntegrationTest.java @@ -4,11 +4,14 @@ 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.http.MediaType; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @SpringBootTest @AutoConfigureMockMvc @@ -22,7 +25,33 @@ public void getAllBooks_Test_When_DbEmpty_Then_returnEmptyArray() throws Excepti mockMvc.perform(MockMvcRequestBuilders.get("/api/books")) .andExpect(status().isOk()) - .andExpect(MockMvcResultMatchers.content().json("[]")); + .andExpect(content().json("[]")); + + } + + @Test + @DirtiesContext + public void addABookTest_whenNewTodoExists_thenReturnNewTodo() throws Exception { + // GIVEN + + // WHEN + mockMvc.perform(post("/api/books") + .contentType(MediaType.APPLICATION_JSON) + .content(""" + { + "author": "Tolstoy", + "title": "War and Peace", + "genre": "HISTORY", + "publicationDate": "1869-01-01" + } + """)) + // THEN + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id").exists()) + .andExpect(jsonPath("$.author").value("Tolstoy")) + .andExpect(jsonPath("$.title").value("War and Peace")) + .andExpect(jsonPath("$.genre").value("HISTORY")) + .andExpect(jsonPath("$.publicationDate").value("1869-01-01")); } diff --git a/backend/src/test/java/com/github/esgoet/backend/services/BookServiceUnitTest.java b/backend/src/test/java/com/github/esgoet/backend/services/BookServiceUnitTest.java index 70104b5..0475d9e 100644 --- a/backend/src/test/java/com/github/esgoet/backend/services/BookServiceUnitTest.java +++ b/backend/src/test/java/com/github/esgoet/backend/services/BookServiceUnitTest.java @@ -1,10 +1,13 @@ package com.github.esgoet.backend.services; +import com.github.esgoet.backend.dto.NewBookDto; import com.github.esgoet.backend.models.Book; +import com.github.esgoet.backend.models.Genre; import com.github.esgoet.backend.repositories.BookRepository; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; +import java.time.LocalDate; import java.util.ArrayList; import java.util.List; @@ -15,18 +18,20 @@ class BookServiceUnitTest { private final BookRepository bookRepo = mock(BookRepository.class); - private final BookService bookService = new BookService(bookRepo); + private final IdService idService = mock(IdService.class); + private final BookService bookService = new BookService(bookRepo, idService); + private final LocalDate localDate = LocalDate.parse("2024-08-14"); @Test void getAllBooks_Test() { List allBooks = List.of( - new Book("1", "Simon", "Java for Dummies"), - new Book("2","Florian", "Java not for Dummies") + new Book("1", "Simon", "Java for Dummies", Genre.SCIENCE, localDate), + new Book("2","Florian", "Java not for Dummies", Genre.SCIENCE, localDate) ); List expectedBooks = List.of( - new Book("1", "Simon", "Java for Dummies"), - new Book("2","Florian", "Java not for Dummies") + new Book("1", "Simon", "Java for Dummies", Genre.SCIENCE, localDate), + new Book("2","Florian", "Java not for Dummies", Genre.SCIENCE, localDate) ); when(bookRepo.findAll()).thenReturn(allBooks); @@ -43,4 +48,20 @@ void getAllBooks_WhenEmpty_ReturnsEmptyList() { assertEquals(expectedBooks, actualBooks); } + + @Test + void addABookTest_whenNewBookAsInput_thenReturnNewBook() { + // GIVEN + NewBookDto newBookDto = new NewBookDto("J. K. Rowling", "Harry Potter", Genre.FANTASY, localDate); + Book bookToSave = new Book(idService.randomId(), newBookDto.author(), newBookDto.title(), newBookDto.genre(), newBookDto.publicationDate()); + when(bookRepo.save(bookToSave)).thenReturn(bookToSave); + + // WHEN + Book actual = bookService.saveNewABook(newBookDto); + + // THEN + Book expected = bookToSave; + verify(bookRepo).save(bookToSave); + assertEquals(expected, actual); + } } \ No newline at end of file From 4e76c8d15d62ef32afb333310d955c559b21c2e7 Mon Sep 17 00:00:00 2001 From: Rinae Hyun Date: Thu, 15 Aug 2024 09:21:02 +0200 Subject: [PATCH 03/10] Add router to add-book-form after clicking button --- frontend/src/App.tsx | 2 ++ .../bookGalleryPage/BookGalleryPage.tsx | 3 +++ .../components/addBookButton/AddBookButton.tsx | 10 ++++++++++ .../components/addBookButton/AddBookForm.tsx | 5 +++++ 4 files changed, 20 insertions(+) create mode 100644 frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookButton.tsx create mode 100644 frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index e5b4759..97018f0 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -6,6 +6,7 @@ import {useEffect, useState} from "react"; import {Link, Route, Routes} from "react-router-dom"; import BookDetailsPage from "./pages/BookDetailsPage/bookDetailsPage/BookDetailsPage.tsx"; import BookGalleryPage from "./pages/BookGalleryPage/bookGalleryPage/BookGalleryPage.tsx"; +import AddBookForm from "./pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx"; function App() { @@ -35,6 +36,7 @@ function App() { All Books }/> + }/> }/> diff --git a/frontend/src/pages/BookGalleryPage/bookGalleryPage/BookGalleryPage.tsx b/frontend/src/pages/BookGalleryPage/bookGalleryPage/BookGalleryPage.tsx index e63e769..29da3f7 100644 --- a/frontend/src/pages/BookGalleryPage/bookGalleryPage/BookGalleryPage.tsx +++ b/frontend/src/pages/BookGalleryPage/bookGalleryPage/BookGalleryPage.tsx @@ -1,6 +1,8 @@ import {Book} from "../../../types/types.ts"; import BookGallery from "../components/bookGallery/BookGallery.tsx"; import "./BookGalleryPage.css"; +import AddBookButton from "../components/addBookButton/AddBookButton.tsx"; +import {Link} from "react-router-dom"; type BookGalleryPageProps = { data: Book[] @@ -8,6 +10,7 @@ type BookGalleryPageProps = { export default function BookGalleryPage({data}: BookGalleryPageProps) { return ( <> + ); diff --git a/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookButton.tsx b/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookButton.tsx new file mode 100644 index 0000000..f1798b5 --- /dev/null +++ b/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookButton.tsx @@ -0,0 +1,10 @@ +export default function AddBookButton() { + + + + return ( + <> + + + ) +} \ No newline at end of file diff --git a/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx b/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx new file mode 100644 index 0000000..686d572 --- /dev/null +++ b/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx @@ -0,0 +1,5 @@ +export default function AddBookForm() { + return ( +

This is a form

+ ) +} \ No newline at end of file From 13afdb10e994e6aa7ba45a28cdb6cee8cba22bd1 Mon Sep 17 00:00:00 2001 From: Rinae Hyun Date: Thu, 15 Aug 2024 11:16:46 +0200 Subject: [PATCH 04/10] Add a form to create a new book info --- .../components/addBookButton/AddBookForm.tsx | 46 ++++++++++++++++++- frontend/src/types/types.ts | 7 +++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx b/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx index 686d572..828637f 100644 --- a/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx +++ b/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx @@ -1,5 +1,49 @@ +import {ChangeEvent, FormEvent, useState} from "react"; +import {NewBook} from "../../../../types/types.ts"; + export default function AddBookForm() { + + const [book, setBook] = useState({title: "", author: "", genre: "", publicationDate: ""}); + + function handleChange(event: ChangeEvent): void { + setBook({...book, [event.target.name]: event.target.value}) + } + + const handleSubmit = (event: FormEvent) => { + event.preventDefault(); + + console.log(event); + console.log(book); + } + return ( -

This is a form

+
+ + + + + + +
) } \ No newline at end of file diff --git a/frontend/src/types/types.ts b/frontend/src/types/types.ts index 6f94988..54a4b3c 100644 --- a/frontend/src/types/types.ts +++ b/frontend/src/types/types.ts @@ -3,3 +3,10 @@ export type Book = { author: string, title: string } + +export type NewBook = { + title: string, + author: string, + genre: string, + publicationDate: string +} \ No newline at end of file From d454d49f8fdc9d08eb9354005f6efb960c65b922 Mon Sep 17 00:00:00 2001 From: Rinae Hyun Date: Thu, 15 Aug 2024 11:39:27 +0200 Subject: [PATCH 05/10] Send a new book data from the form --- .../components/addBookButton/AddBookForm.tsx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx b/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx index 828637f..d26c70c 100644 --- a/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx +++ b/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx @@ -1,5 +1,6 @@ import {ChangeEvent, FormEvent, useState} from "react"; import {NewBook} from "../../../../types/types.ts"; +import axios from "axios"; export default function AddBookForm() { @@ -12,31 +13,42 @@ export default function AddBookForm() { const handleSubmit = (event: FormEvent) => { event.preventDefault(); - console.log(event); console.log(book); + axios.post("/api/books", { + title: book.title, + author: book.author, + genre: book.genre, + publicationDate: book.publicationDate + }) + .then(response => console.log(response)) + .catch(error => console.log(error)) + } return (
- + + + + Date: Thu, 15 Aug 2024 12:09:51 +0200 Subject: [PATCH 06/10] Replace text input with drowdown for genre and add Enum --- .../github/esgoet/backend/models/Genre.java | 3 ++- .../components/addBookButton/AddBookForm.tsx | 19 ++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/backend/src/main/java/com/github/esgoet/backend/models/Genre.java b/backend/src/main/java/com/github/esgoet/backend/models/Genre.java index 6b89ae9..ae46f2f 100644 --- a/backend/src/main/java/com/github/esgoet/backend/models/Genre.java +++ b/backend/src/main/java/com/github/esgoet/backend/models/Genre.java @@ -8,7 +8,8 @@ public enum Genre { FANTASY("Fantasy"), SCIENCE("Science"), NON_FICTION("None Fiction"), - HISTORY("History"); + HISTORY("History"), + NOVEL("Novel"); private final String genre; diff --git a/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx b/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx index d26c70c..1634a56 100644 --- a/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx +++ b/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx @@ -6,7 +6,9 @@ export default function AddBookForm() { const [book, setBook] = useState({title: "", author: "", genre: "", publicationDate: ""}); - function handleChange(event: ChangeEvent): void { + const genres: string[] = ["NONE", "FICTION", "MYSTERY", "THRILLER", "FANTASY", "SCIENCE", "NON_FICTION", "HISTORY", "NOVEL"]; + + function handleChange(event: ChangeEvent | ChangeEvent): void { setBook({...book, [event.target.name]: event.target.value}) } @@ -14,6 +16,8 @@ export default function AddBookForm() { event.preventDefault(); console.log(book); + console.log(event); + axios.post("/api/books", { title: book.title, author: book.author, @@ -33,6 +37,7 @@ export default function AddBookForm() { name={"title"} value={book.title} onChange={handleChange} + required={true} /> - + Date: Thu, 15 Aug 2024 12:52:38 +0200 Subject: [PATCH 07/10] Add data mapping for Book Genre --- .../components/addBookButton/AddBookForm.tsx | 23 +++++++++++++++---- frontend/src/types/types.ts | 14 ++++++++++- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx b/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx index 1634a56..cc9db5e 100644 --- a/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx +++ b/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx @@ -1,12 +1,22 @@ import {ChangeEvent, FormEvent, useState} from "react"; -import {NewBook} from "../../../../types/types.ts"; +import {Genre, NewBook} from "../../../../types/types.ts"; import axios from "axios"; export default function AddBookForm() { const [book, setBook] = useState({title: "", author: "", genre: "", publicationDate: ""}); - const genres: string[] = ["NONE", "FICTION", "MYSTERY", "THRILLER", "FANTASY", "SCIENCE", "NON_FICTION", "HISTORY", "NOVEL"]; + const genres: Genre = { + NONE: "None", + FICTION: "Fiction", + MYSTERY: "Mystery", + THRILLER: "Thriller", + FANTASY: "Fantasy", + SCIENCE: "Science", + NON_FICTION: "Non fiction", + HISTORY: "History", + NOVEL: "Novel" + } function handleChange(event: ChangeEvent | ChangeEvent): void { setBook({...book, [event.target.name]: event.target.value}) @@ -21,7 +31,8 @@ export default function AddBookForm() { axios.post("/api/books", { title: book.title, author: book.author, - genre: book.genre, + genre: Object.keys(genres).find( + key => genres[key as keyof typeof genres] === book.genre), publicationDate: book.publicationDate }) .then(response => console.log(response)) @@ -49,8 +60,10 @@ export default function AddBookForm() { /> diff --git a/frontend/src/types/types.ts b/frontend/src/types/types.ts index 54a4b3c..4b3172b 100644 --- a/frontend/src/types/types.ts +++ b/frontend/src/types/types.ts @@ -9,4 +9,16 @@ export type NewBook = { author: string, genre: string, publicationDate: string -} \ No newline at end of file +} + +export type Genre = { + NONE: string, + FICTION: string, + MYSTERY: string, + THRILLER: string, + FANTASY: string, + SCIENCE: string, + NON_FICTION: string, + HISTORY: string, + NOVEL: string +} From 564896288d0b307379caaac28e98662f09aeea00 Mon Sep 17 00:00:00 2001 From: Rinae Hyun Date: Thu, 15 Aug 2024 15:21:31 +0200 Subject: [PATCH 08/10] Adjust codes based on code reviews --- .../github/esgoet/backend/controllers/BookController.java | 2 +- .../main/java/com/github/esgoet/backend/models/Genre.java | 8 ++++---- .../com/github/esgoet/backend/services/BookService.java | 2 +- .../controllers/BookControllerIntegrationTest.java | 6 ++++-- .../esgoet/backend/services/BookServiceUnitTest.java | 8 +++++--- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/backend/src/main/java/com/github/esgoet/backend/controllers/BookController.java b/backend/src/main/java/com/github/esgoet/backend/controllers/BookController.java index 7bae4ea..0f72b10 100644 --- a/backend/src/main/java/com/github/esgoet/backend/controllers/BookController.java +++ b/backend/src/main/java/com/github/esgoet/backend/controllers/BookController.java @@ -37,6 +37,6 @@ public Book getBook(@PathVariable String id) { @PostMapping public Book addABook(@RequestBody NewBookDto newBookDto) { - return bookService.saveNewABook(newBookDto); + return bookService.saveBook(newBookDto); } } diff --git a/backend/src/main/java/com/github/esgoet/backend/models/Genre.java b/backend/src/main/java/com/github/esgoet/backend/models/Genre.java index ae46f2f..dfb1ae5 100644 --- a/backend/src/main/java/com/github/esgoet/backend/models/Genre.java +++ b/backend/src/main/java/com/github/esgoet/backend/models/Genre.java @@ -7,13 +7,13 @@ public enum Genre { THRILLER("Thriller"), FANTASY("Fantasy"), SCIENCE("Science"), - NON_FICTION("None Fiction"), + NON_FICTION("Non-fiction"), HISTORY("History"), NOVEL("Novel"); - private final String genre; + private final String genreValue; - Genre(String genre) { this.genre = genre; } + Genre(String genreValue) { this.genreValue = genreValue; } - public String getGenre() { return genre; } + public String getGenre() { return genreValue; } } diff --git a/backend/src/main/java/com/github/esgoet/backend/services/BookService.java b/backend/src/main/java/com/github/esgoet/backend/services/BookService.java index f41d2b6..2f47cf1 100644 --- a/backend/src/main/java/com/github/esgoet/backend/services/BookService.java +++ b/backend/src/main/java/com/github/esgoet/backend/services/BookService.java @@ -30,7 +30,7 @@ public Book getBook(String id) { .orElseThrow(() -> new BookNotFoundException("No book found with id: " + id)); } - public Book saveNewABook(NewBookDto newBookDto) { + public Book saveBook(NewBookDto newBookDto) { Book bookToSave = new Book( idService.randomId(), newBookDto.author(), diff --git a/backend/src/test/java/com/github/esgoet/backend/controllers/BookControllerIntegrationTest.java b/backend/src/test/java/com/github/esgoet/backend/controllers/BookControllerIntegrationTest.java index 30f868b..db0864e 100644 --- a/backend/src/test/java/com/github/esgoet/backend/controllers/BookControllerIntegrationTest.java +++ b/backend/src/test/java/com/github/esgoet/backend/controllers/BookControllerIntegrationTest.java @@ -50,14 +50,16 @@ void getBook_Test_whenIdExists() throws Exception { { "id": "1", "author": "George Orwell", - "title": "1984" + "title": "1984", + "genre": "FANTASY", + "publicationDate": "2024-08-14" } """)); } @Test @DirtiesContext - public void addABookTest_whenNewTodoExists_thenReturnNewTodo() throws Exception { + void addABookTest_whenNewTodoExists_thenReturnNewTodo() throws Exception { // GIVEN // WHEN diff --git a/backend/src/test/java/com/github/esgoet/backend/services/BookServiceUnitTest.java b/backend/src/test/java/com/github/esgoet/backend/services/BookServiceUnitTest.java index ff22b6c..12e07ec 100644 --- a/backend/src/test/java/com/github/esgoet/backend/services/BookServiceUnitTest.java +++ b/backend/src/test/java/com/github/esgoet/backend/services/BookServiceUnitTest.java @@ -76,15 +76,17 @@ void getBook_Test_whenBookDoesNotExists_thenThrow() { void addABookTest_whenNewBookAsInput_thenReturnNewBook() { // GIVEN NewBookDto newBookDto = new NewBookDto("J. K. Rowling", "Harry Potter", Genre.FANTASY, localDate); - Book bookToSave = new Book(idService.randomId(), newBookDto.author(), newBookDto.title(), newBookDto.genre(), newBookDto.publicationDate()); + Book bookToSave = new Book("1", newBookDto.author(), newBookDto.title(), newBookDto.genre(), newBookDto.publicationDate()); when(bookRepo.save(bookToSave)).thenReturn(bookToSave); + when(idService.randomId()).thenReturn(bookToSave.id()); // WHEN - Book actual = bookService.saveNewABook(newBookDto); + Book actual = bookService.saveBook(newBookDto); // THEN Book expected = bookToSave; - verify(bookRepo).save(bookToSave); + verify(bookRepo).save(new Book("1", newBookDto.author(), newBookDto.title(), newBookDto.genre(), newBookDto.publicationDate())); + verify(idService).randomId(); assertEquals(expected, actual); } From a768ad3bad1e5a4b6d06e4b7e43bbe77e9fc5652 Mon Sep 17 00:00:00 2001 From: Rinae Hyun Date: Thu, 15 Aug 2024 15:52:57 +0200 Subject: [PATCH 09/10] Convert button to Link (Add a Book), Reload all books, Delete unused component based on code reviews --- frontend/src/App.tsx | 2 +- .../bookGalleryPage/BookGalleryPage.tsx | 3 +-- .../components/addBookButton/AddBookButton.tsx | 10 ---------- .../components/addBookButton/AddBookForm.tsx | 16 ++++++++++++---- 4 files changed, 14 insertions(+), 17 deletions(-) delete mode 100644 frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookButton.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index e591d92..ad12692 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -42,7 +42,7 @@ function App() { All Books }/> - }/> + }/> }/> diff --git a/frontend/src/pages/BookGalleryPage/bookGalleryPage/BookGalleryPage.tsx b/frontend/src/pages/BookGalleryPage/bookGalleryPage/BookGalleryPage.tsx index 29da3f7..b3c65d5 100644 --- a/frontend/src/pages/BookGalleryPage/bookGalleryPage/BookGalleryPage.tsx +++ b/frontend/src/pages/BookGalleryPage/bookGalleryPage/BookGalleryPage.tsx @@ -1,7 +1,6 @@ import {Book} from "../../../types/types.ts"; import BookGallery from "../components/bookGallery/BookGallery.tsx"; import "./BookGalleryPage.css"; -import AddBookButton from "../components/addBookButton/AddBookButton.tsx"; import {Link} from "react-router-dom"; type BookGalleryPageProps = { @@ -10,7 +9,7 @@ type BookGalleryPageProps = { export default function BookGalleryPage({data}: BookGalleryPageProps) { return ( <> - + Add a Book ); diff --git a/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookButton.tsx b/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookButton.tsx deleted file mode 100644 index f1798b5..0000000 --- a/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookButton.tsx +++ /dev/null @@ -1,10 +0,0 @@ -export default function AddBookButton() { - - - - return ( - <> - - - ) -} \ No newline at end of file diff --git a/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx b/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx index cc9db5e..85de4cc 100644 --- a/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx +++ b/frontend/src/pages/BookGalleryPage/components/addBookButton/AddBookForm.tsx @@ -1,10 +1,16 @@ import {ChangeEvent, FormEvent, useState} from "react"; import {Genre, NewBook} from "../../../../types/types.ts"; import axios from "axios"; +import {useNavigate} from "react-router-dom"; -export default function AddBookForm() { +type FetchProps = { + fetchBooks: () => void; +} + +export default function AddBookForm({ fetchBooks }: FetchProps) { const [book, setBook] = useState({title: "", author: "", genre: "", publicationDate: ""}); + const navigate = useNavigate(); const genres: Genre = { NONE: "None", @@ -13,7 +19,7 @@ export default function AddBookForm() { THRILLER: "Thriller", FANTASY: "Fantasy", SCIENCE: "Science", - NON_FICTION: "Non fiction", + NON_FICTION: "Non-fiction", HISTORY: "History", NOVEL: "Novel" } @@ -35,9 +41,11 @@ export default function AddBookForm() { key => genres[key as keyof typeof genres] === book.genre), publicationDate: book.publicationDate }) + .then(() => fetchBooks()) .then(response => console.log(response)) .catch(error => console.log(error)) + navigate("/books") } return ( @@ -60,8 +68,8 @@ export default function AddBookForm() { />