From 57ae9db85485c3ac92025c451f3486e7b6a58e4c Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Tue, 19 Mar 2019 06:42:25 -0600 Subject: [PATCH] Add book entity to jhipster-5 project --- .../bookstore-monolith/.jhipster/Book.json | 54 +++ .../com/baeldung/jhipster5/domain/Book.java | 153 +++++++ .../jhipster5/repository/BookRepository.java | 15 + .../jhipster5/service/BookService.java | 43 ++ .../jhipster5/service/dto/BookDTO.java | 112 +++++ .../service/impl/BookServiceImpl.java | 90 ++++ .../jhipster5/service/mapper/BookMapper.java | 24 + .../service/mapper/EntityMapper.java | 21 + .../jhipster5/web/rest/BookResource.java | 112 +++++ .../20190319124041_added_entity_Book.xml | 50 +++ .../resources/config/liquibase/master.xml | 1 + .../book/book-delete-dialog.component.html | 19 + .../book/book-delete-dialog.component.ts | 65 +++ .../entities/book/book-detail.component.html | 43 ++ .../entities/book/book-detail.component.ts | 24 + .../entities/book/book-update.component.html | 100 +++++ .../entities/book/book-update.component.ts | 53 +++ .../app/entities/book/book.component.html | 62 +++ .../app/entities/book/book.component.ts | 65 +++ .../webapp/app/entities/book/book.module.ts | 23 + .../webapp/app/entities/book/book.route.ts | 93 ++++ .../webapp/app/entities/book/book.service.ts | 74 ++++ .../main/webapp/app/entities/book/index.ts | 6 + .../main/webapp/app/entities/entity.module.ts | 4 + .../app/layouts/navbar/navbar.component.html | 6 + .../webapp/app/shared/model/book.model.ts | 21 + .../web/rest/BookResourceIntTest.java | 416 ++++++++++++++++++ .../book/book-delete-dialog.component.spec.ts | 52 +++ .../book/book-detail.component.spec.ts | 40 ++ .../book/book-update.component.spec.ts | 60 +++ .../app/entities/book/book.component.spec.ts | 51 +++ .../app/entities/book/book.service.spec.ts | 137 ++++++ 32 files changed, 2089 insertions(+) create mode 100644 jhipster-5/bookstore-monolith/.jhipster/Book.json create mode 100644 jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/domain/Book.java create mode 100644 jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/repository/BookRepository.java create mode 100644 jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/BookService.java create mode 100644 jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/dto/BookDTO.java create mode 100644 jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/impl/BookServiceImpl.java create mode 100644 jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/mapper/BookMapper.java create mode 100644 jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/mapper/EntityMapper.java create mode 100644 jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/BookResource.java create mode 100644 jhipster-5/bookstore-monolith/src/main/resources/config/liquibase/changelog/20190319124041_added_entity_Book.xml create mode 100644 jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-delete-dialog.component.html create mode 100644 jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-delete-dialog.component.ts create mode 100644 jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.html create mode 100644 jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.ts create mode 100644 jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-update.component.html create mode 100644 jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-update.component.ts create mode 100644 jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.component.html create mode 100644 jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.component.ts create mode 100644 jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.module.ts create mode 100644 jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.route.ts create mode 100644 jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.service.ts create mode 100644 jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/index.ts create mode 100644 jhipster-5/bookstore-monolith/src/main/webapp/app/shared/model/book.model.ts create mode 100644 jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/BookResourceIntTest.java create mode 100644 jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-delete-dialog.component.spec.ts create mode 100644 jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-detail.component.spec.ts create mode 100644 jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-update.component.spec.ts create mode 100644 jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book.component.spec.ts create mode 100644 jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book.service.spec.ts diff --git a/jhipster-5/bookstore-monolith/.jhipster/Book.json b/jhipster-5/bookstore-monolith/.jhipster/Book.json new file mode 100644 index 0000000000..4c5bd1fa52 --- /dev/null +++ b/jhipster-5/bookstore-monolith/.jhipster/Book.json @@ -0,0 +1,54 @@ +{ + "fluentMethods": true, + "clientRootFolder": "", + "relationships": [], + "fields": [ + { + "fieldName": "title", + "fieldType": "String", + "fieldValidateRules": [ + "required" + ] + }, + { + "fieldName": "author", + "fieldType": "String", + "fieldValidateRules": [ + "required" + ] + }, + { + "fieldName": "published", + "fieldType": "LocalDate", + "fieldValidateRules": [ + "required" + ] + }, + { + "fieldName": "quantity", + "fieldType": "Integer", + "fieldValidateRules": [ + "required", + "min" + ], + "fieldValidateRulesMin": 0 + }, + { + "fieldName": "price", + "fieldType": "Double", + "fieldValidateRules": [ + "required", + "min" + ], + "fieldValidateRulesMin": 0 + } + ], + "changelogDate": "20190319124041", + "dto": "mapstruct", + "searchEngine": false, + "service": "serviceImpl", + "entityTableName": "book", + "databaseType": "sql", + "jpaMetamodelFiltering": false, + "pagination": "no" +} diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/domain/Book.java b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/domain/Book.java new file mode 100644 index 0000000000..16771d9e09 --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/domain/Book.java @@ -0,0 +1,153 @@ +package com.baeldung.jhipster5.domain; + + + +import javax.persistence.*; +import javax.validation.constraints.*; + +import java.io.Serializable; +import java.time.LocalDate; +import java.util.Objects; + +/** + * A Book. + */ +@Entity +@Table(name = "book") +public class Book implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NotNull + @Column(name = "title", nullable = false) + private String title; + + @NotNull + @Column(name = "author", nullable = false) + private String author; + + @NotNull + @Column(name = "published", nullable = false) + private LocalDate published; + + @NotNull + @Min(value = 0) + @Column(name = "quantity", nullable = false) + private Integer quantity; + + @NotNull + @DecimalMin(value = "0") + @Column(name = "price", nullable = false) + private Double price; + + // jhipster-needle-entity-add-field - JHipster will add fields here, do not remove + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public Book title(String title) { + this.title = title; + return this; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthor() { + return author; + } + + public Book author(String author) { + this.author = author; + return this; + } + + public void setAuthor(String author) { + this.author = author; + } + + public LocalDate getPublished() { + return published; + } + + public Book published(LocalDate published) { + this.published = published; + return this; + } + + public void setPublished(LocalDate published) { + this.published = published; + } + + public Integer getQuantity() { + return quantity; + } + + public Book quantity(Integer quantity) { + this.quantity = quantity; + return this; + } + + public void setQuantity(Integer quantity) { + this.quantity = quantity; + } + + public Double getPrice() { + return price; + } + + public Book price(Double price) { + this.price = price; + return this; + } + + public void setPrice(Double price) { + this.price = price; + } + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Book book = (Book) o; + if (book.getId() == null || getId() == null) { + return false; + } + return Objects.equals(getId(), book.getId()); + } + + @Override + public int hashCode() { + return Objects.hashCode(getId()); + } + + @Override + public String toString() { + return "Book{" + + "id=" + getId() + + ", title='" + getTitle() + "'" + + ", author='" + getAuthor() + "'" + + ", published='" + getPublished() + "'" + + ", quantity=" + getQuantity() + + ", price=" + getPrice() + + "}"; + } +} diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/repository/BookRepository.java b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/repository/BookRepository.java new file mode 100644 index 0000000000..ebd3117e65 --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/repository/BookRepository.java @@ -0,0 +1,15 @@ +package com.baeldung.jhipster5.repository; + +import com.baeldung.jhipster5.domain.Book; +import org.springframework.data.jpa.repository.*; +import org.springframework.stereotype.Repository; + + +/** + * Spring Data repository for the Book entity. + */ +@SuppressWarnings("unused") +@Repository +public interface BookRepository extends JpaRepository { + +} diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/BookService.java b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/BookService.java new file mode 100644 index 0000000000..bb052dc03c --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/BookService.java @@ -0,0 +1,43 @@ +package com.baeldung.jhipster5.service; + +import com.baeldung.jhipster5.service.dto.BookDTO; + +import java.util.List; +import java.util.Optional; + +/** + * Service Interface for managing Book. + */ +public interface BookService { + + /** + * Save a book. + * + * @param bookDTO the entity to save + * @return the persisted entity + */ + BookDTO save(BookDTO bookDTO); + + /** + * Get all the books. + * + * @return the list of entities + */ + List findAll(); + + + /** + * Get the "id" book. + * + * @param id the id of the entity + * @return the entity + */ + Optional findOne(Long id); + + /** + * Delete the "id" book. + * + * @param id the id of the entity + */ + void delete(Long id); +} diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/dto/BookDTO.java b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/dto/BookDTO.java new file mode 100644 index 0000000000..5aa550e989 --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/dto/BookDTO.java @@ -0,0 +1,112 @@ +package com.baeldung.jhipster5.service.dto; +import java.time.LocalDate; +import javax.validation.constraints.*; +import java.io.Serializable; +import java.util.Objects; + +/** + * A DTO for the Book entity. + */ +public class BookDTO implements Serializable { + + private Long id; + + @NotNull + private String title; + + @NotNull + private String author; + + @NotNull + private LocalDate published; + + @NotNull + @Min(value = 0) + private Integer quantity; + + @NotNull + @DecimalMin(value = "0") + private Double price; + + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public LocalDate getPublished() { + return published; + } + + public void setPublished(LocalDate published) { + this.published = published; + } + + public Integer getQuantity() { + return quantity; + } + + public void setQuantity(Integer quantity) { + this.quantity = quantity; + } + + public Double getPrice() { + return price; + } + + public void setPrice(Double price) { + this.price = price; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + BookDTO bookDTO = (BookDTO) o; + if (bookDTO.getId() == null || getId() == null) { + return false; + } + return Objects.equals(getId(), bookDTO.getId()); + } + + @Override + public int hashCode() { + return Objects.hashCode(getId()); + } + + @Override + public String toString() { + return "BookDTO{" + + "id=" + getId() + + ", title='" + getTitle() + "'" + + ", author='" + getAuthor() + "'" + + ", published='" + getPublished() + "'" + + ", quantity=" + getQuantity() + + ", price=" + getPrice() + + "}"; + } +} diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/impl/BookServiceImpl.java b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/impl/BookServiceImpl.java new file mode 100644 index 0000000000..00f68b84af --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/impl/BookServiceImpl.java @@ -0,0 +1,90 @@ +package com.baeldung.jhipster5.service.impl; + +import com.baeldung.jhipster5.service.BookService; +import com.baeldung.jhipster5.domain.Book; +import com.baeldung.jhipster5.repository.BookRepository; +import com.baeldung.jhipster5.service.dto.BookDTO; +import com.baeldung.jhipster5.service.mapper.BookMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.LinkedList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * Service Implementation for managing Book. + */ +@Service +@Transactional +public class BookServiceImpl implements BookService { + + private final Logger log = LoggerFactory.getLogger(BookServiceImpl.class); + + private final BookRepository bookRepository; + + private final BookMapper bookMapper; + + public BookServiceImpl(BookRepository bookRepository, BookMapper bookMapper) { + this.bookRepository = bookRepository; + this.bookMapper = bookMapper; + } + + /** + * Save a book. + * + * @param bookDTO the entity to save + * @return the persisted entity + */ + @Override + public BookDTO save(BookDTO bookDTO) { + log.debug("Request to save Book : {}", bookDTO); + Book book = bookMapper.toEntity(bookDTO); + book = bookRepository.save(book); + return bookMapper.toDto(book); + } + + /** + * Get all the books. + * + * @return the list of entities + */ + @Override + @Transactional(readOnly = true) + public List findAll() { + log.debug("Request to get all Books"); + return bookRepository.findAll().stream() + .map(bookMapper::toDto) + .collect(Collectors.toCollection(LinkedList::new)); + } + + + /** + * Get one book by id. + * + * @param id the id of the entity + * @return the entity + */ + @Override + @Transactional(readOnly = true) + public Optional findOne(Long id) { + log.debug("Request to get Book : {}", id); + return bookRepository.findById(id) + .map(bookMapper::toDto); + } + + /** + * Delete the book by id. + * + * @param id the id of the entity + */ + @Override + public void delete(Long id) { + log.debug("Request to delete Book : {}", id); + bookRepository.deleteById(id); + } +} diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/mapper/BookMapper.java b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/mapper/BookMapper.java new file mode 100644 index 0000000000..cd24c7088e --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/mapper/BookMapper.java @@ -0,0 +1,24 @@ +package com.baeldung.jhipster5.service.mapper; + +import com.baeldung.jhipster5.domain.*; +import com.baeldung.jhipster5.service.dto.BookDTO; + +import org.mapstruct.*; + +/** + * Mapper for the entity Book and its DTO BookDTO. + */ +@Mapper(componentModel = "spring", uses = {}) +public interface BookMapper extends EntityMapper { + + + + default Book fromId(Long id) { + if (id == null) { + return null; + } + Book book = new Book(); + book.setId(id); + return book; + } +} diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/mapper/EntityMapper.java b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/mapper/EntityMapper.java new file mode 100644 index 0000000000..68af78179d --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/service/mapper/EntityMapper.java @@ -0,0 +1,21 @@ +package com.baeldung.jhipster5.service.mapper; + +import java.util.List; + +/** + * Contract for a generic dto to entity mapper. + * + * @param - DTO type parameter. + * @param - Entity type parameter. + */ + +public interface EntityMapper { + + E toEntity(D dto); + + D toDto(E entity); + + List toEntity(List dtoList); + + List toDto(List entityList); +} diff --git a/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/BookResource.java b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/BookResource.java new file mode 100644 index 0000000000..efcc2c3495 --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/java/com/baeldung/jhipster5/web/rest/BookResource.java @@ -0,0 +1,112 @@ +package com.baeldung.jhipster5.web.rest; +import com.baeldung.jhipster5.service.BookService; +import com.baeldung.jhipster5.web.rest.errors.BadRequestAlertException; +import com.baeldung.jhipster5.web.rest.util.HeaderUtil; +import com.baeldung.jhipster5.service.dto.BookDTO; +import io.github.jhipster.web.util.ResponseUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.net.URI; +import java.net.URISyntaxException; + +import java.util.List; +import java.util.Optional; + +/** + * REST controller for managing Book. + */ +@RestController +@RequestMapping("/api") +public class BookResource { + + private final Logger log = LoggerFactory.getLogger(BookResource.class); + + private static final String ENTITY_NAME = "book"; + + private final BookService bookService; + + public BookResource(BookService bookService) { + this.bookService = bookService; + } + + /** + * POST /books : Create a new book. + * + * @param bookDTO the bookDTO to create + * @return the ResponseEntity with status 201 (Created) and with body the new bookDTO, or with status 400 (Bad Request) if the book has already an ID + * @throws URISyntaxException if the Location URI syntax is incorrect + */ + @PostMapping("/books") + public ResponseEntity createBook(@Valid @RequestBody BookDTO bookDTO) throws URISyntaxException { + log.debug("REST request to save Book : {}", bookDTO); + if (bookDTO.getId() != null) { + throw new BadRequestAlertException("A new book cannot already have an ID", ENTITY_NAME, "idexists"); + } + BookDTO result = bookService.save(bookDTO); + return ResponseEntity.created(new URI("/api/books/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(ENTITY_NAME, result.getId().toString())) + .body(result); + } + + /** + * PUT /books : Updates an existing book. + * + * @param bookDTO the bookDTO to update + * @return the ResponseEntity with status 200 (OK) and with body the updated bookDTO, + * or with status 400 (Bad Request) if the bookDTO is not valid, + * or with status 500 (Internal Server Error) if the bookDTO couldn't be updated + * @throws URISyntaxException if the Location URI syntax is incorrect + */ + @PutMapping("/books") + public ResponseEntity updateBook(@Valid @RequestBody BookDTO bookDTO) throws URISyntaxException { + log.debug("REST request to update Book : {}", bookDTO); + if (bookDTO.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + BookDTO result = bookService.save(bookDTO); + return ResponseEntity.ok() + .headers(HeaderUtil.createEntityUpdateAlert(ENTITY_NAME, bookDTO.getId().toString())) + .body(result); + } + + /** + * GET /books : get all the books. + * + * @return the ResponseEntity with status 200 (OK) and the list of books in body + */ + @GetMapping("/books") + public List getAllBooks() { + log.debug("REST request to get all Books"); + return bookService.findAll(); + } + + /** + * GET /books/:id : get the "id" book. + * + * @param id the id of the bookDTO to retrieve + * @return the ResponseEntity with status 200 (OK) and with body the bookDTO, or with status 404 (Not Found) + */ + @GetMapping("/books/{id}") + public ResponseEntity getBook(@PathVariable Long id) { + log.debug("REST request to get Book : {}", id); + Optional bookDTO = bookService.findOne(id); + return ResponseUtil.wrapOrNotFound(bookDTO); + } + + /** + * DELETE /books/:id : delete the "id" book. + * + * @param id the id of the bookDTO to delete + * @return the ResponseEntity with status 200 (OK) + */ + @DeleteMapping("/books/{id}") + public ResponseEntity deleteBook(@PathVariable Long id) { + log.debug("REST request to delete Book : {}", id); + bookService.delete(id); + return ResponseEntity.ok().headers(HeaderUtil.createEntityDeletionAlert(ENTITY_NAME, id.toString())).build(); + } +} diff --git a/jhipster-5/bookstore-monolith/src/main/resources/config/liquibase/changelog/20190319124041_added_entity_Book.xml b/jhipster-5/bookstore-monolith/src/main/resources/config/liquibase/changelog/20190319124041_added_entity_Book.xml new file mode 100644 index 0000000000..f040387cf1 --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/resources/config/liquibase/changelog/20190319124041_added_entity_Book.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jhipster-5/bookstore-monolith/src/main/resources/config/liquibase/master.xml b/jhipster-5/bookstore-monolith/src/main/resources/config/liquibase/master.xml index f2b0b1f7e6..e045ee0100 100644 --- a/jhipster-5/bookstore-monolith/src/main/resources/config/liquibase/master.xml +++ b/jhipster-5/bookstore-monolith/src/main/resources/config/liquibase/master.xml @@ -5,6 +5,7 @@ xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd"> + diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-delete-dialog.component.html b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-delete-dialog.component.html new file mode 100644 index 0000000000..be3647e9df --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-delete-dialog.component.html @@ -0,0 +1,19 @@ +
+ + + +
diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-delete-dialog.component.ts b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-delete-dialog.component.ts new file mode 100644 index 0000000000..7992a5d26d --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-delete-dialog.component.ts @@ -0,0 +1,65 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; + +import { NgbActiveModal, NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; +import { JhiEventManager } from 'ng-jhipster'; + +import { IBook } from 'app/shared/model/book.model'; +import { BookService } from './book.service'; + +@Component({ + selector: 'jhi-book-delete-dialog', + templateUrl: './book-delete-dialog.component.html' +}) +export class BookDeleteDialogComponent { + book: IBook; + + constructor(protected bookService: BookService, public activeModal: NgbActiveModal, protected eventManager: JhiEventManager) {} + + clear() { + this.activeModal.dismiss('cancel'); + } + + confirmDelete(id: number) { + this.bookService.delete(id).subscribe(response => { + this.eventManager.broadcast({ + name: 'bookListModification', + content: 'Deleted an book' + }); + this.activeModal.dismiss(true); + }); + } +} + +@Component({ + selector: 'jhi-book-delete-popup', + template: '' +}) +export class BookDeletePopupComponent implements OnInit, OnDestroy { + protected ngbModalRef: NgbModalRef; + + constructor(protected activatedRoute: ActivatedRoute, protected router: Router, protected modalService: NgbModal) {} + + ngOnInit() { + this.activatedRoute.data.subscribe(({ book }) => { + setTimeout(() => { + this.ngbModalRef = this.modalService.open(BookDeleteDialogComponent as Component, { size: 'lg', backdrop: 'static' }); + this.ngbModalRef.componentInstance.book = book; + this.ngbModalRef.result.then( + result => { + this.router.navigate(['/book', { outlets: { popup: null } }]); + this.ngbModalRef = null; + }, + reason => { + this.router.navigate(['/book', { outlets: { popup: null } }]); + this.ngbModalRef = null; + } + ); + }, 0); + }); + } + + ngOnDestroy() { + this.ngbModalRef = null; + } +} diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.html b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.html new file mode 100644 index 0000000000..0aef73282a --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.html @@ -0,0 +1,43 @@ +
+
+
+

Book {{book.id}}

+
+ +
+
Title
+
+ {{book.title}} +
+
Author
+
+ {{book.author}} +
+
Published
+
+ {{book.published}} +
+
Quantity
+
+ {{book.quantity}} +
+
Price
+
+ {{book.price}} +
+
+ + + + +
+
+
diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.ts b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.ts new file mode 100644 index 0000000000..50a6bec9ad --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-detail.component.ts @@ -0,0 +1,24 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; + +import { IBook } from 'app/shared/model/book.model'; + +@Component({ + selector: 'jhi-book-detail', + templateUrl: './book-detail.component.html' +}) +export class BookDetailComponent implements OnInit { + book: IBook; + + constructor(protected activatedRoute: ActivatedRoute) {} + + ngOnInit() { + this.activatedRoute.data.subscribe(({ book }) => { + this.book = book; + }); + } + + previousState() { + window.history.back(); + } +} diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-update.component.html b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-update.component.html new file mode 100644 index 0000000000..3b41c6e1e0 --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-update.component.html @@ -0,0 +1,100 @@ +
+
+
+

Create or edit a Book

+
+ +
+ + +
+
+ + +
+ + This field is required. + +
+
+
+ + +
+ + This field is required. + +
+
+
+ +
+ + + + +
+
+ + This field is required. + +
+
+
+ + +
+ + This field is required. + + + This field should be at least 0. + + + This field should be a number. + +
+
+
+ + +
+ + This field is required. + + + This field should be at least 0. + + + This field should be a number. + +
+
+ +
+
+ + +
+
+
+
diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-update.component.ts b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-update.component.ts new file mode 100644 index 0000000000..67f46a67c2 --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book-update.component.ts @@ -0,0 +1,53 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { HttpResponse, HttpErrorResponse } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { filter, map } from 'rxjs/operators'; +import * as moment from 'moment'; +import { IBook } from 'app/shared/model/book.model'; +import { BookService } from './book.service'; + +@Component({ + selector: 'jhi-book-update', + templateUrl: './book-update.component.html' +}) +export class BookUpdateComponent implements OnInit { + book: IBook; + isSaving: boolean; + publishedDp: any; + + constructor(protected bookService: BookService, protected activatedRoute: ActivatedRoute) {} + + ngOnInit() { + this.isSaving = false; + this.activatedRoute.data.subscribe(({ book }) => { + this.book = book; + }); + } + + previousState() { + window.history.back(); + } + + save() { + this.isSaving = true; + if (this.book.id !== undefined) { + this.subscribeToSaveResponse(this.bookService.update(this.book)); + } else { + this.subscribeToSaveResponse(this.bookService.create(this.book)); + } + } + + protected subscribeToSaveResponse(result: Observable>) { + result.subscribe((res: HttpResponse) => this.onSaveSuccess(), (res: HttpErrorResponse) => this.onSaveError()); + } + + protected onSaveSuccess() { + this.isSaving = false; + this.previousState(); + } + + protected onSaveError() { + this.isSaving = false; + } +} diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.component.html b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.component.html new file mode 100644 index 0000000000..74ad02a8e3 --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.component.html @@ -0,0 +1,62 @@ +
+

+ Books + +

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + +
IDTitleAuthorPublishedQuantityPrice
{{book.id}}{{book.title}}{{book.author}}{{book.published | date:'mediumDate'}}{{book.quantity}}{{book.price}} +
+ + + +
+
+
+
diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.component.ts b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.component.ts new file mode 100644 index 0000000000..91a71c2f5c --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.component.ts @@ -0,0 +1,65 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { HttpErrorResponse, HttpResponse } from '@angular/common/http'; +import { Subscription } from 'rxjs'; +import { filter, map } from 'rxjs/operators'; +import { JhiEventManager, JhiAlertService } from 'ng-jhipster'; + +import { IBook } from 'app/shared/model/book.model'; +import { AccountService } from 'app/core'; +import { BookService } from './book.service'; + +@Component({ + selector: 'jhi-book', + templateUrl: './book.component.html' +}) +export class BookComponent implements OnInit, OnDestroy { + books: IBook[]; + currentAccount: any; + eventSubscriber: Subscription; + + constructor( + protected bookService: BookService, + protected jhiAlertService: JhiAlertService, + protected eventManager: JhiEventManager, + protected accountService: AccountService + ) {} + + loadAll() { + this.bookService + .query() + .pipe( + filter((res: HttpResponse) => res.ok), + map((res: HttpResponse) => res.body) + ) + .subscribe( + (res: IBook[]) => { + this.books = res; + }, + (res: HttpErrorResponse) => this.onError(res.message) + ); + } + + ngOnInit() { + this.loadAll(); + this.accountService.identity().then(account => { + this.currentAccount = account; + }); + this.registerChangeInBooks(); + } + + ngOnDestroy() { + this.eventManager.destroy(this.eventSubscriber); + } + + trackId(index: number, item: IBook) { + return item.id; + } + + registerChangeInBooks() { + this.eventSubscriber = this.eventManager.subscribe('bookListModification', response => this.loadAll()); + } + + protected onError(errorMessage: string) { + this.jhiAlertService.error(errorMessage, null, null); + } +} diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.module.ts b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.module.ts new file mode 100644 index 0000000000..fe221a0eb9 --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.module.ts @@ -0,0 +1,23 @@ +import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { BookstoreSharedModule } from 'app/shared'; +import { + BookComponent, + BookDetailComponent, + BookUpdateComponent, + BookDeletePopupComponent, + BookDeleteDialogComponent, + bookRoute, + bookPopupRoute +} from './'; + +const ENTITY_STATES = [...bookRoute, ...bookPopupRoute]; + +@NgModule({ + imports: [BookstoreSharedModule, RouterModule.forChild(ENTITY_STATES)], + declarations: [BookComponent, BookDetailComponent, BookUpdateComponent, BookDeleteDialogComponent, BookDeletePopupComponent], + entryComponents: [BookComponent, BookUpdateComponent, BookDeleteDialogComponent, BookDeletePopupComponent], + schemas: [CUSTOM_ELEMENTS_SCHEMA] +}) +export class BookstoreBookModule {} diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.route.ts b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.route.ts new file mode 100644 index 0000000000..154fa89a5c --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.route.ts @@ -0,0 +1,93 @@ +import { Injectable } from '@angular/core'; +import { HttpResponse } from '@angular/common/http'; +import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Routes } from '@angular/router'; +import { UserRouteAccessService } from 'app/core'; +import { Observable, of } from 'rxjs'; +import { filter, map } from 'rxjs/operators'; +import { Book } from 'app/shared/model/book.model'; +import { BookService } from './book.service'; +import { BookComponent } from './book.component'; +import { BookDetailComponent } from './book-detail.component'; +import { BookUpdateComponent } from './book-update.component'; +import { BookDeletePopupComponent } from './book-delete-dialog.component'; +import { IBook } from 'app/shared/model/book.model'; + +@Injectable({ providedIn: 'root' }) +export class BookResolve implements Resolve { + constructor(private service: BookService) {} + + resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { + const id = route.params['id'] ? route.params['id'] : null; + if (id) { + return this.service.find(id).pipe( + filter((response: HttpResponse) => response.ok), + map((book: HttpResponse) => book.body) + ); + } + return of(new Book()); + } +} + +export const bookRoute: Routes = [ + { + path: '', + component: BookComponent, + data: { + authorities: ['ROLE_USER'], + pageTitle: 'Books' + }, + canActivate: [UserRouteAccessService] + }, + { + path: ':id/view', + component: BookDetailComponent, + resolve: { + book: BookResolve + }, + data: { + authorities: ['ROLE_USER'], + pageTitle: 'Books' + }, + canActivate: [UserRouteAccessService] + }, + { + path: 'new', + component: BookUpdateComponent, + resolve: { + book: BookResolve + }, + data: { + authorities: ['ROLE_USER'], + pageTitle: 'Books' + }, + canActivate: [UserRouteAccessService] + }, + { + path: ':id/edit', + component: BookUpdateComponent, + resolve: { + book: BookResolve + }, + data: { + authorities: ['ROLE_USER'], + pageTitle: 'Books' + }, + canActivate: [UserRouteAccessService] + } +]; + +export const bookPopupRoute: Routes = [ + { + path: ':id/delete', + component: BookDeletePopupComponent, + resolve: { + book: BookResolve + }, + data: { + authorities: ['ROLE_USER'], + pageTitle: 'Books' + }, + canActivate: [UserRouteAccessService], + outlet: 'popup' + } +]; diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.service.ts b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.service.ts new file mode 100644 index 0000000000..3ff649d25d --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/book.service.ts @@ -0,0 +1,74 @@ +import { Injectable } from '@angular/core'; +import { HttpClient, HttpResponse } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import * as moment from 'moment'; +import { DATE_FORMAT } from 'app/shared/constants/input.constants'; +import { map } from 'rxjs/operators'; + +import { SERVER_API_URL } from 'app/app.constants'; +import { createRequestOption } from 'app/shared'; +import { IBook } from 'app/shared/model/book.model'; + +type EntityResponseType = HttpResponse; +type EntityArrayResponseType = HttpResponse; + +@Injectable({ providedIn: 'root' }) +export class BookService { + public resourceUrl = SERVER_API_URL + 'api/books'; + + constructor(protected http: HttpClient) {} + + create(book: IBook): Observable { + const copy = this.convertDateFromClient(book); + return this.http + .post(this.resourceUrl, copy, { observe: 'response' }) + .pipe(map((res: EntityResponseType) => this.convertDateFromServer(res))); + } + + update(book: IBook): Observable { + const copy = this.convertDateFromClient(book); + return this.http + .put(this.resourceUrl, copy, { observe: 'response' }) + .pipe(map((res: EntityResponseType) => this.convertDateFromServer(res))); + } + + find(id: number): Observable { + return this.http + .get(`${this.resourceUrl}/${id}`, { observe: 'response' }) + .pipe(map((res: EntityResponseType) => this.convertDateFromServer(res))); + } + + query(req?: any): Observable { + const options = createRequestOption(req); + return this.http + .get(this.resourceUrl, { params: options, observe: 'response' }) + .pipe(map((res: EntityArrayResponseType) => this.convertDateArrayFromServer(res))); + } + + delete(id: number): Observable> { + return this.http.delete(`${this.resourceUrl}/${id}`, { observe: 'response' }); + } + + protected convertDateFromClient(book: IBook): IBook { + const copy: IBook = Object.assign({}, book, { + published: book.published != null && book.published.isValid() ? book.published.format(DATE_FORMAT) : null + }); + return copy; + } + + protected convertDateFromServer(res: EntityResponseType): EntityResponseType { + if (res.body) { + res.body.published = res.body.published != null ? moment(res.body.published) : null; + } + return res; + } + + protected convertDateArrayFromServer(res: EntityArrayResponseType): EntityArrayResponseType { + if (res.body) { + res.body.forEach((book: IBook) => { + book.published = book.published != null ? moment(book.published) : null; + }); + } + return res; + } +} diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/index.ts b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/index.ts new file mode 100644 index 0000000000..603cf68f9f --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/book/index.ts @@ -0,0 +1,6 @@ +export * from './book.service'; +export * from './book-update.component'; +export * from './book-delete-dialog.component'; +export * from './book-detail.component'; +export * from './book.component'; +export * from './book.route'; diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/entity.module.ts b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/entity.module.ts index b0f67260c7..fba1f55ef7 100644 --- a/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/entity.module.ts +++ b/jhipster-5/bookstore-monolith/src/main/webapp/app/entities/entity.module.ts @@ -4,6 +4,10 @@ import { RouterModule } from '@angular/router'; @NgModule({ imports: [ RouterModule.forChild([ + { + path: 'book', + loadChildren: './book/book.module#BookstoreBookModule' + } /* jhipster-needle-add-entity-route - JHipster will add entity modules routes here */ ]) ], diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.component.html b/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.component.html index bd3e80b3cb..e58d234c22 100644 --- a/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.component.html +++ b/jhipster-5/bookstore-monolith/src/main/webapp/app/layouts/navbar/navbar.component.html @@ -27,6 +27,12 @@ diff --git a/jhipster-5/bookstore-monolith/src/main/webapp/app/shared/model/book.model.ts b/jhipster-5/bookstore-monolith/src/main/webapp/app/shared/model/book.model.ts new file mode 100644 index 0000000000..ee943a4127 --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/main/webapp/app/shared/model/book.model.ts @@ -0,0 +1,21 @@ +import { Moment } from 'moment'; + +export interface IBook { + id?: number; + title?: string; + author?: string; + published?: Moment; + quantity?: number; + price?: number; +} + +export class Book implements IBook { + constructor( + public id?: number, + public title?: string, + public author?: string, + public published?: Moment, + public quantity?: number, + public price?: number + ) {} +} diff --git a/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/BookResourceIntTest.java b/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/BookResourceIntTest.java new file mode 100644 index 0000000000..ef8f27ceea --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/test/java/com/baeldung/jhipster5/web/rest/BookResourceIntTest.java @@ -0,0 +1,416 @@ +package com.baeldung.jhipster5.web.rest; + +import com.baeldung.jhipster5.BookstoreApp; + +import com.baeldung.jhipster5.domain.Book; +import com.baeldung.jhipster5.repository.BookRepository; +import com.baeldung.jhipster5.service.BookService; +import com.baeldung.jhipster5.service.dto.BookDTO; +import com.baeldung.jhipster5.service.mapper.BookMapper; +import com.baeldung.jhipster5.web.rest.errors.ExceptionTranslator; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.web.PageableHandlerMethodArgumentResolver; +import org.springframework.http.MediaType; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.Validator; + +import javax.persistence.EntityManager; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.List; + + +import static com.baeldung.jhipster5.web.rest.TestUtil.createFormattingConversionService; +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.hasItem; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +/** + * Test class for the BookResource REST controller. + * + * @see BookResource + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = BookstoreApp.class) +public class BookResourceIntTest { + + private static final String DEFAULT_TITLE = "AAAAAAAAAA"; + private static final String UPDATED_TITLE = "BBBBBBBBBB"; + + private static final String DEFAULT_AUTHOR = "AAAAAAAAAA"; + private static final String UPDATED_AUTHOR = "BBBBBBBBBB"; + + private static final LocalDate DEFAULT_PUBLISHED = LocalDate.ofEpochDay(0L); + private static final LocalDate UPDATED_PUBLISHED = LocalDate.now(ZoneId.systemDefault()); + + private static final Integer DEFAULT_QUANTITY = 0; + private static final Integer UPDATED_QUANTITY = 1; + + private static final Double DEFAULT_PRICE = 0D; + private static final Double UPDATED_PRICE = 1D; + + @Autowired + private BookRepository bookRepository; + + @Autowired + private BookMapper bookMapper; + + @Autowired + private BookService bookService; + + @Autowired + private MappingJackson2HttpMessageConverter jacksonMessageConverter; + + @Autowired + private PageableHandlerMethodArgumentResolver pageableArgumentResolver; + + @Autowired + private ExceptionTranslator exceptionTranslator; + + @Autowired + private EntityManager em; + + @Autowired + private Validator validator; + + private MockMvc restBookMockMvc; + + private Book book; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + final BookResource bookResource = new BookResource(bookService); + this.restBookMockMvc = MockMvcBuilders.standaloneSetup(bookResource) + .setCustomArgumentResolvers(pageableArgumentResolver) + .setControllerAdvice(exceptionTranslator) + .setConversionService(createFormattingConversionService()) + .setMessageConverters(jacksonMessageConverter) + .setValidator(validator).build(); + } + + /** + * Create an entity for this test. + * + * This is a static method, as tests for other entities might also need it, + * if they test an entity which requires the current entity. + */ + public static Book createEntity(EntityManager em) { + Book book = new Book() + .title(DEFAULT_TITLE) + .author(DEFAULT_AUTHOR) + .published(DEFAULT_PUBLISHED) + .quantity(DEFAULT_QUANTITY) + .price(DEFAULT_PRICE); + return book; + } + + @Before + public void initTest() { + book = createEntity(em); + } + + @Test + @Transactional + public void createBook() throws Exception { + int databaseSizeBeforeCreate = bookRepository.findAll().size(); + + // Create the Book + BookDTO bookDTO = bookMapper.toDto(book); + restBookMockMvc.perform(post("/api/books") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(bookDTO))) + .andExpect(status().isCreated()); + + // Validate the Book in the database + List bookList = bookRepository.findAll(); + assertThat(bookList).hasSize(databaseSizeBeforeCreate + 1); + Book testBook = bookList.get(bookList.size() - 1); + assertThat(testBook.getTitle()).isEqualTo(DEFAULT_TITLE); + assertThat(testBook.getAuthor()).isEqualTo(DEFAULT_AUTHOR); + assertThat(testBook.getPublished()).isEqualTo(DEFAULT_PUBLISHED); + assertThat(testBook.getQuantity()).isEqualTo(DEFAULT_QUANTITY); + assertThat(testBook.getPrice()).isEqualTo(DEFAULT_PRICE); + } + + @Test + @Transactional + public void createBookWithExistingId() throws Exception { + int databaseSizeBeforeCreate = bookRepository.findAll().size(); + + // Create the Book with an existing ID + book.setId(1L); + BookDTO bookDTO = bookMapper.toDto(book); + + // An entity with an existing ID cannot be created, so this API call must fail + restBookMockMvc.perform(post("/api/books") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(bookDTO))) + .andExpect(status().isBadRequest()); + + // Validate the Book in the database + List bookList = bookRepository.findAll(); + assertThat(bookList).hasSize(databaseSizeBeforeCreate); + } + + @Test + @Transactional + public void checkTitleIsRequired() throws Exception { + int databaseSizeBeforeTest = bookRepository.findAll().size(); + // set the field null + book.setTitle(null); + + // Create the Book, which fails. + BookDTO bookDTO = bookMapper.toDto(book); + + restBookMockMvc.perform(post("/api/books") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(bookDTO))) + .andExpect(status().isBadRequest()); + + List bookList = bookRepository.findAll(); + assertThat(bookList).hasSize(databaseSizeBeforeTest); + } + + @Test + @Transactional + public void checkAuthorIsRequired() throws Exception { + int databaseSizeBeforeTest = bookRepository.findAll().size(); + // set the field null + book.setAuthor(null); + + // Create the Book, which fails. + BookDTO bookDTO = bookMapper.toDto(book); + + restBookMockMvc.perform(post("/api/books") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(bookDTO))) + .andExpect(status().isBadRequest()); + + List bookList = bookRepository.findAll(); + assertThat(bookList).hasSize(databaseSizeBeforeTest); + } + + @Test + @Transactional + public void checkPublishedIsRequired() throws Exception { + int databaseSizeBeforeTest = bookRepository.findAll().size(); + // set the field null + book.setPublished(null); + + // Create the Book, which fails. + BookDTO bookDTO = bookMapper.toDto(book); + + restBookMockMvc.perform(post("/api/books") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(bookDTO))) + .andExpect(status().isBadRequest()); + + List bookList = bookRepository.findAll(); + assertThat(bookList).hasSize(databaseSizeBeforeTest); + } + + @Test + @Transactional + public void checkQuantityIsRequired() throws Exception { + int databaseSizeBeforeTest = bookRepository.findAll().size(); + // set the field null + book.setQuantity(null); + + // Create the Book, which fails. + BookDTO bookDTO = bookMapper.toDto(book); + + restBookMockMvc.perform(post("/api/books") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(bookDTO))) + .andExpect(status().isBadRequest()); + + List bookList = bookRepository.findAll(); + assertThat(bookList).hasSize(databaseSizeBeforeTest); + } + + @Test + @Transactional + public void checkPriceIsRequired() throws Exception { + int databaseSizeBeforeTest = bookRepository.findAll().size(); + // set the field null + book.setPrice(null); + + // Create the Book, which fails. + BookDTO bookDTO = bookMapper.toDto(book); + + restBookMockMvc.perform(post("/api/books") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(bookDTO))) + .andExpect(status().isBadRequest()); + + List bookList = bookRepository.findAll(); + assertThat(bookList).hasSize(databaseSizeBeforeTest); + } + + @Test + @Transactional + public void getAllBooks() throws Exception { + // Initialize the database + bookRepository.saveAndFlush(book); + + // Get all the bookList + restBookMockMvc.perform(get("/api/books?sort=id,desc")) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(jsonPath("$.[*].id").value(hasItem(book.getId().intValue()))) + .andExpect(jsonPath("$.[*].title").value(hasItem(DEFAULT_TITLE.toString()))) + .andExpect(jsonPath("$.[*].author").value(hasItem(DEFAULT_AUTHOR.toString()))) + .andExpect(jsonPath("$.[*].published").value(hasItem(DEFAULT_PUBLISHED.toString()))) + .andExpect(jsonPath("$.[*].quantity").value(hasItem(DEFAULT_QUANTITY))) + .andExpect(jsonPath("$.[*].price").value(hasItem(DEFAULT_PRICE.doubleValue()))); + } + + @Test + @Transactional + public void getBook() throws Exception { + // Initialize the database + bookRepository.saveAndFlush(book); + + // Get the book + restBookMockMvc.perform(get("/api/books/{id}", book.getId())) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(jsonPath("$.id").value(book.getId().intValue())) + .andExpect(jsonPath("$.title").value(DEFAULT_TITLE.toString())) + .andExpect(jsonPath("$.author").value(DEFAULT_AUTHOR.toString())) + .andExpect(jsonPath("$.published").value(DEFAULT_PUBLISHED.toString())) + .andExpect(jsonPath("$.quantity").value(DEFAULT_QUANTITY)) + .andExpect(jsonPath("$.price").value(DEFAULT_PRICE.doubleValue())); + } + + @Test + @Transactional + public void getNonExistingBook() throws Exception { + // Get the book + restBookMockMvc.perform(get("/api/books/{id}", Long.MAX_VALUE)) + .andExpect(status().isNotFound()); + } + + @Test + @Transactional + public void updateBook() throws Exception { + // Initialize the database + bookRepository.saveAndFlush(book); + + int databaseSizeBeforeUpdate = bookRepository.findAll().size(); + + // Update the book + Book updatedBook = bookRepository.findById(book.getId()).get(); + // Disconnect from session so that the updates on updatedBook are not directly saved in db + em.detach(updatedBook); + updatedBook + .title(UPDATED_TITLE) + .author(UPDATED_AUTHOR) + .published(UPDATED_PUBLISHED) + .quantity(UPDATED_QUANTITY) + .price(UPDATED_PRICE); + BookDTO bookDTO = bookMapper.toDto(updatedBook); + + restBookMockMvc.perform(put("/api/books") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(bookDTO))) + .andExpect(status().isOk()); + + // Validate the Book in the database + List bookList = bookRepository.findAll(); + assertThat(bookList).hasSize(databaseSizeBeforeUpdate); + Book testBook = bookList.get(bookList.size() - 1); + assertThat(testBook.getTitle()).isEqualTo(UPDATED_TITLE); + assertThat(testBook.getAuthor()).isEqualTo(UPDATED_AUTHOR); + assertThat(testBook.getPublished()).isEqualTo(UPDATED_PUBLISHED); + assertThat(testBook.getQuantity()).isEqualTo(UPDATED_QUANTITY); + assertThat(testBook.getPrice()).isEqualTo(UPDATED_PRICE); + } + + @Test + @Transactional + public void updateNonExistingBook() throws Exception { + int databaseSizeBeforeUpdate = bookRepository.findAll().size(); + + // Create the Book + BookDTO bookDTO = bookMapper.toDto(book); + + // If the entity doesn't have an ID, it will throw BadRequestAlertException + restBookMockMvc.perform(put("/api/books") + .contentType(TestUtil.APPLICATION_JSON_UTF8) + .content(TestUtil.convertObjectToJsonBytes(bookDTO))) + .andExpect(status().isBadRequest()); + + // Validate the Book in the database + List bookList = bookRepository.findAll(); + assertThat(bookList).hasSize(databaseSizeBeforeUpdate); + } + + @Test + @Transactional + public void deleteBook() throws Exception { + // Initialize the database + bookRepository.saveAndFlush(book); + + int databaseSizeBeforeDelete = bookRepository.findAll().size(); + + // Delete the book + restBookMockMvc.perform(delete("/api/books/{id}", book.getId()) + .accept(TestUtil.APPLICATION_JSON_UTF8)) + .andExpect(status().isOk()); + + // Validate the database is empty + List bookList = bookRepository.findAll(); + assertThat(bookList).hasSize(databaseSizeBeforeDelete - 1); + } + + @Test + @Transactional + public void equalsVerifier() throws Exception { + TestUtil.equalsVerifier(Book.class); + Book book1 = new Book(); + book1.setId(1L); + Book book2 = new Book(); + book2.setId(book1.getId()); + assertThat(book1).isEqualTo(book2); + book2.setId(2L); + assertThat(book1).isNotEqualTo(book2); + book1.setId(null); + assertThat(book1).isNotEqualTo(book2); + } + + @Test + @Transactional + public void dtoEqualsVerifier() throws Exception { + TestUtil.equalsVerifier(BookDTO.class); + BookDTO bookDTO1 = new BookDTO(); + bookDTO1.setId(1L); + BookDTO bookDTO2 = new BookDTO(); + assertThat(bookDTO1).isNotEqualTo(bookDTO2); + bookDTO2.setId(bookDTO1.getId()); + assertThat(bookDTO1).isEqualTo(bookDTO2); + bookDTO2.setId(2L); + assertThat(bookDTO1).isNotEqualTo(bookDTO2); + bookDTO1.setId(null); + assertThat(bookDTO1).isNotEqualTo(bookDTO2); + } + + @Test + @Transactional + public void testEntityFromId() { + assertThat(bookMapper.fromId(42L).getId()).isEqualTo(42); + assertThat(bookMapper.fromId(null)).isNull(); + } +} diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-delete-dialog.component.spec.ts b/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-delete-dialog.component.spec.ts new file mode 100644 index 0000000000..6ffba6ee1e --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-delete-dialog.component.spec.ts @@ -0,0 +1,52 @@ +/* tslint:disable max-line-length */ +import { ComponentFixture, TestBed, inject, fakeAsync, tick } from '@angular/core/testing'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; +import { Observable, of } from 'rxjs'; +import { JhiEventManager } from 'ng-jhipster'; + +import { BookstoreTestModule } from '../../../test.module'; +import { BookDeleteDialogComponent } from 'app/entities/book/book-delete-dialog.component'; +import { BookService } from 'app/entities/book/book.service'; + +describe('Component Tests', () => { + describe('Book Management Delete Component', () => { + let comp: BookDeleteDialogComponent; + let fixture: ComponentFixture; + let service: BookService; + let mockEventManager: any; + let mockActiveModal: any; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [BookstoreTestModule], + declarations: [BookDeleteDialogComponent] + }) + .overrideTemplate(BookDeleteDialogComponent, '') + .compileComponents(); + fixture = TestBed.createComponent(BookDeleteDialogComponent); + comp = fixture.componentInstance; + service = fixture.debugElement.injector.get(BookService); + mockEventManager = fixture.debugElement.injector.get(JhiEventManager); + mockActiveModal = fixture.debugElement.injector.get(NgbActiveModal); + }); + + describe('confirmDelete', () => { + it('Should call delete service on confirmDelete', inject( + [], + fakeAsync(() => { + // GIVEN + spyOn(service, 'delete').and.returnValue(of({})); + + // WHEN + comp.confirmDelete(123); + tick(); + + // THEN + expect(service.delete).toHaveBeenCalledWith(123); + expect(mockActiveModal.dismissSpy).toHaveBeenCalled(); + expect(mockEventManager.broadcastSpy).toHaveBeenCalled(); + }) + )); + }); + }); +}); diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-detail.component.spec.ts b/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-detail.component.spec.ts new file mode 100644 index 0000000000..b0ff94b3ea --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-detail.component.spec.ts @@ -0,0 +1,40 @@ +/* tslint:disable max-line-length */ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ActivatedRoute } from '@angular/router'; +import { of } from 'rxjs'; + +import { BookstoreTestModule } from '../../../test.module'; +import { BookDetailComponent } from 'app/entities/book/book-detail.component'; +import { Book } from 'app/shared/model/book.model'; + +describe('Component Tests', () => { + describe('Book Management Detail Component', () => { + let comp: BookDetailComponent; + let fixture: ComponentFixture; + const route = ({ data: of({ book: new Book(123) }) } as any) as ActivatedRoute; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [BookstoreTestModule], + declarations: [BookDetailComponent], + providers: [{ provide: ActivatedRoute, useValue: route }] + }) + .overrideTemplate(BookDetailComponent, '') + .compileComponents(); + fixture = TestBed.createComponent(BookDetailComponent); + comp = fixture.componentInstance; + }); + + describe('OnInit', () => { + it('Should call load all on init', () => { + // GIVEN + + // WHEN + comp.ngOnInit(); + + // THEN + expect(comp.book).toEqual(jasmine.objectContaining({ id: 123 })); + }); + }); + }); +}); diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-update.component.spec.ts b/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-update.component.spec.ts new file mode 100644 index 0000000000..336a2e2397 --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book-update.component.spec.ts @@ -0,0 +1,60 @@ +/* tslint:disable max-line-length */ +import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing'; +import { HttpResponse } from '@angular/common/http'; +import { Observable, of } from 'rxjs'; + +import { BookstoreTestModule } from '../../../test.module'; +import { BookUpdateComponent } from 'app/entities/book/book-update.component'; +import { BookService } from 'app/entities/book/book.service'; +import { Book } from 'app/shared/model/book.model'; + +describe('Component Tests', () => { + describe('Book Management Update Component', () => { + let comp: BookUpdateComponent; + let fixture: ComponentFixture; + let service: BookService; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [BookstoreTestModule], + declarations: [BookUpdateComponent] + }) + .overrideTemplate(BookUpdateComponent, '') + .compileComponents(); + + fixture = TestBed.createComponent(BookUpdateComponent); + comp = fixture.componentInstance; + service = fixture.debugElement.injector.get(BookService); + }); + + describe('save', () => { + it('Should call update service on save for existing entity', fakeAsync(() => { + // GIVEN + const entity = new Book(123); + spyOn(service, 'update').and.returnValue(of(new HttpResponse({ body: entity }))); + comp.book = entity; + // WHEN + comp.save(); + tick(); // simulate async + + // THEN + expect(service.update).toHaveBeenCalledWith(entity); + expect(comp.isSaving).toEqual(false); + })); + + it('Should call create service on save for new entity', fakeAsync(() => { + // GIVEN + const entity = new Book(); + spyOn(service, 'create').and.returnValue(of(new HttpResponse({ body: entity }))); + comp.book = entity; + // WHEN + comp.save(); + tick(); // simulate async + + // THEN + expect(service.create).toHaveBeenCalledWith(entity); + expect(comp.isSaving).toEqual(false); + })); + }); + }); +}); diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book.component.spec.ts b/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book.component.spec.ts new file mode 100644 index 0000000000..3b3d472650 --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book.component.spec.ts @@ -0,0 +1,51 @@ +/* tslint:disable max-line-length */ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { Observable, of } from 'rxjs'; +import { HttpHeaders, HttpResponse } from '@angular/common/http'; + +import { BookstoreTestModule } from '../../../test.module'; +import { BookComponent } from 'app/entities/book/book.component'; +import { BookService } from 'app/entities/book/book.service'; +import { Book } from 'app/shared/model/book.model'; + +describe('Component Tests', () => { + describe('Book Management Component', () => { + let comp: BookComponent; + let fixture: ComponentFixture; + let service: BookService; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [BookstoreTestModule], + declarations: [BookComponent], + providers: [] + }) + .overrideTemplate(BookComponent, '') + .compileComponents(); + + fixture = TestBed.createComponent(BookComponent); + comp = fixture.componentInstance; + service = fixture.debugElement.injector.get(BookService); + }); + + it('Should call load all on init', () => { + // GIVEN + const headers = new HttpHeaders().append('link', 'link;link'); + spyOn(service, 'query').and.returnValue( + of( + new HttpResponse({ + body: [new Book(123)], + headers + }) + ) + ); + + // WHEN + comp.ngOnInit(); + + // THEN + expect(service.query).toHaveBeenCalled(); + expect(comp.books[0]).toEqual(jasmine.objectContaining({ id: 123 })); + }); + }); +}); diff --git a/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book.service.spec.ts b/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book.service.spec.ts new file mode 100644 index 0000000000..cd0c5b7318 --- /dev/null +++ b/jhipster-5/bookstore-monolith/src/test/javascript/spec/app/entities/book/book.service.spec.ts @@ -0,0 +1,137 @@ +/* tslint:disable max-line-length */ +import { TestBed, getTestBed } from '@angular/core/testing'; +import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; +import { HttpClient, HttpResponse } from '@angular/common/http'; +import { of } from 'rxjs'; +import { take, map } from 'rxjs/operators'; +import * as moment from 'moment'; +import { DATE_FORMAT } from 'app/shared/constants/input.constants'; +import { BookService } from 'app/entities/book/book.service'; +import { IBook, Book } from 'app/shared/model/book.model'; + +describe('Service Tests', () => { + describe('Book Service', () => { + let injector: TestBed; + let service: BookService; + let httpMock: HttpTestingController; + let elemDefault: IBook; + let currentDate: moment.Moment; + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [HttpClientTestingModule] + }); + injector = getTestBed(); + service = injector.get(BookService); + httpMock = injector.get(HttpTestingController); + currentDate = moment(); + + elemDefault = new Book(0, 'AAAAAAA', 'AAAAAAA', currentDate, 0, 0); + }); + + describe('Service methods', async () => { + it('should find an element', async () => { + const returnedFromService = Object.assign( + { + published: currentDate.format(DATE_FORMAT) + }, + elemDefault + ); + service + .find(123) + .pipe(take(1)) + .subscribe(resp => expect(resp).toMatchObject({ body: elemDefault })); + + const req = httpMock.expectOne({ method: 'GET' }); + req.flush(JSON.stringify(returnedFromService)); + }); + + it('should create a Book', async () => { + const returnedFromService = Object.assign( + { + id: 0, + published: currentDate.format(DATE_FORMAT) + }, + elemDefault + ); + const expected = Object.assign( + { + published: currentDate + }, + returnedFromService + ); + service + .create(new Book(null)) + .pipe(take(1)) + .subscribe(resp => expect(resp).toMatchObject({ body: expected })); + const req = httpMock.expectOne({ method: 'POST' }); + req.flush(JSON.stringify(returnedFromService)); + }); + + it('should update a Book', async () => { + const returnedFromService = Object.assign( + { + title: 'BBBBBB', + author: 'BBBBBB', + published: currentDate.format(DATE_FORMAT), + quantity: 1, + price: 1 + }, + elemDefault + ); + + const expected = Object.assign( + { + published: currentDate + }, + returnedFromService + ); + service + .update(expected) + .pipe(take(1)) + .subscribe(resp => expect(resp).toMatchObject({ body: expected })); + const req = httpMock.expectOne({ method: 'PUT' }); + req.flush(JSON.stringify(returnedFromService)); + }); + + it('should return a list of Book', async () => { + const returnedFromService = Object.assign( + { + title: 'BBBBBB', + author: 'BBBBBB', + published: currentDate.format(DATE_FORMAT), + quantity: 1, + price: 1 + }, + elemDefault + ); + const expected = Object.assign( + { + published: currentDate + }, + returnedFromService + ); + service + .query(expected) + .pipe( + take(1), + map(resp => resp.body) + ) + .subscribe(body => expect(body).toContainEqual(expected)); + const req = httpMock.expectOne({ method: 'GET' }); + req.flush(JSON.stringify([returnedFromService])); + httpMock.verify(); + }); + + it('should delete a Book', async () => { + const rxPromise = service.delete(123).subscribe(resp => expect(resp.ok)); + + const req = httpMock.expectOne({ method: 'DELETE' }); + req.flush({ status: 200 }); + }); + }); + + afterEach(() => { + httpMock.verify(); + }); + }); +});