Add book entity to jhipster-5 project

This commit is contained in:
Michael Pratt 2019-03-19 06:42:25 -06:00
parent a03ec155b4
commit 57ae9db854
32 changed files with 2089 additions and 0 deletions

View File

@ -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"
}

View File

@ -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() +
"}";
}
}

View File

@ -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<Book, Long> {
}

View File

@ -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<BookDTO> findAll();
/**
* Get the "id" book.
*
* @param id the id of the entity
* @return the entity
*/
Optional<BookDTO> findOne(Long id);
/**
* Delete the "id" book.
*
* @param id the id of the entity
*/
void delete(Long id);
}

View File

@ -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() +
"}";
}
}

View File

@ -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<BookDTO> 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<BookDTO> 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);
}
}

View File

@ -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<BookDTO, Book> {
default Book fromId(Long id) {
if (id == null) {
return null;
}
Book book = new Book();
book.setId(id);
return book;
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.jhipster5.service.mapper;
import java.util.List;
/**
* Contract for a generic dto to entity mapper.
*
* @param <D> - DTO type parameter.
* @param <E> - Entity type parameter.
*/
public interface EntityMapper <D, E> {
E toEntity(D dto);
D toDto(E entity);
List <E> toEntity(List<D> dtoList);
List <D> toDto(List<E> entityList);
}

View File

@ -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<BookDTO> 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<BookDTO> 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<BookDTO> 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<BookDTO> getBook(@PathVariable Long id) {
log.debug("REST request to get Book : {}", id);
Optional<BookDTO> 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<Void> 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();
}
}

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<property name="now" value="now()" dbms="h2"/>
<property name="now" value="now()" dbms="mysql"/>
<property name="autoIncrement" value="true"/>
<property name="floatType" value="float4" dbms="postgresql, h2"/>
<property name="floatType" value="float" dbms="mysql, oracle, mssql"/>
<!--
Added the entity Book.
-->
<changeSet id="20190319124041-1" author="jhipster">
<createTable tableName="book">
<column name="id" type="bigint" autoIncrement="${autoIncrement}">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="title" type="varchar(255)">
<constraints nullable="false" />
</column>
<column name="author" type="varchar(255)">
<constraints nullable="false" />
</column>
<column name="published" type="date">
<constraints nullable="false" />
</column>
<column name="quantity" type="integer">
<constraints nullable="false" />
</column>
<column name="price" type="double">
<constraints nullable="false" />
</column>
<!-- jhipster-needle-liquibase-add-column - JHipster will add columns here, do not remove-->
</createTable>
</changeSet>
<!-- jhipster-needle-liquibase-add-changeset - JHipster will add changesets here, do not remove-->
</databaseChangeLog>

View File

@ -5,6 +5,7 @@
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd"> xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<include file="config/liquibase/changelog/00000000000000_initial_schema.xml" relativeToChangelogFile="false"/> <include file="config/liquibase/changelog/00000000000000_initial_schema.xml" relativeToChangelogFile="false"/>
<include file="config/liquibase/changelog/20190319124041_added_entity_Book.xml" relativeToChangelogFile="false"/>
<!-- jhipster-needle-liquibase-add-changelog - JHipster will add liquibase changelogs here --> <!-- jhipster-needle-liquibase-add-changelog - JHipster will add liquibase changelogs here -->
<!-- jhipster-needle-liquibase-add-constraints-changelog - JHipster will add liquibase constraints changelogs here --> <!-- jhipster-needle-liquibase-add-constraints-changelog - JHipster will add liquibase constraints changelogs here -->
</databaseChangeLog> </databaseChangeLog>

View File

@ -0,0 +1,19 @@
<form name="deleteForm" (ngSubmit)="confirmDelete(book.id)">
<div class="modal-header">
<h4 class="modal-title">Confirm delete operation</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"
(click)="clear()">&times;</button>
</div>
<div class="modal-body">
<jhi-alert-error></jhi-alert-error>
<p id="jhi-delete-book-heading">Are you sure you want to delete this Book?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="clear()">
<fa-icon [icon]="'ban'"></fa-icon>&nbsp;<span>Cancel</span>
</button>
<button id="jhi-confirm-delete-book" type="submit" class="btn btn-danger">
<fa-icon [icon]="'times'"></fa-icon>&nbsp;<span>Delete</span>
</button>
</div>
</form>

View File

@ -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;
}
}

View File

@ -0,0 +1,43 @@
<div class="row justify-content-center">
<div class="col-8">
<div *ngIf="book">
<h2><span>Book</span> {{book.id}}</h2>
<hr>
<jhi-alert-error></jhi-alert-error>
<dl class="row-md jh-entity-details">
<dt><span>Title</span></dt>
<dd>
<span>{{book.title}}</span>
</dd>
<dt><span>Author</span></dt>
<dd>
<span>{{book.author}}</span>
</dd>
<dt><span>Published</span></dt>
<dd>
<span>{{book.published}}</span>
</dd>
<dt><span>Quantity</span></dt>
<dd>
<span>{{book.quantity}}</span>
</dd>
<dt><span>Price</span></dt>
<dd>
<span>{{book.price}}</span>
</dd>
</dl>
<button type="submit"
(click)="previousState()"
class="btn btn-info">
<fa-icon [icon]="'arrow-left'"></fa-icon>&nbsp;<span> Back</span>
</button>
<button type="button"
[routerLink]="['/book', book.id, 'edit']"
class="btn btn-primary">
<fa-icon [icon]="'pencil-alt'"></fa-icon>&nbsp;<span> Edit</span>
</button>
</div>
</div>
</div>

View File

@ -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();
}
}

View File

@ -0,0 +1,100 @@
<div class="row justify-content-center">
<div class="col-8">
<form name="editForm" role="form" novalidate (ngSubmit)="save()" #editForm="ngForm">
<h2 id="jhi-book-heading">Create or edit a Book</h2>
<div>
<jhi-alert-error></jhi-alert-error>
<div class="form-group" [hidden]="!book.id">
<label for="id">ID</label>
<input type="text" class="form-control" id="id" name="id"
[(ngModel)]="book.id" readonly />
</div>
<div class="form-group">
<label class="form-control-label" for="field_title">Title</label>
<input type="text" class="form-control" name="title" id="field_title"
[(ngModel)]="book.title" required/>
<div [hidden]="!(editForm.controls.title?.dirty && editForm.controls.title?.invalid)">
<small class="form-text text-danger"
[hidden]="!editForm.controls.title?.errors?.required">
This field is required.
</small>
</div>
</div>
<div class="form-group">
<label class="form-control-label" for="field_author">Author</label>
<input type="text" class="form-control" name="author" id="field_author"
[(ngModel)]="book.author" required/>
<div [hidden]="!(editForm.controls.author?.dirty && editForm.controls.author?.invalid)">
<small class="form-text text-danger"
[hidden]="!editForm.controls.author?.errors?.required">
This field is required.
</small>
</div>
</div>
<div class="form-group">
<label class="form-control-label" for="field_published">Published</label>
<div class="input-group">
<input id="field_published" type="text" class="form-control" name="published" ngbDatepicker #publishedDp="ngbDatepicker" [(ngModel)]="book.published"
required/>
<span class="input-group-append">
<button type="button" class="btn btn-secondary" (click)="publishedDp.toggle()"><fa-icon [icon]="'calendar-alt'"></fa-icon></button>
</span>
</div>
<div [hidden]="!(editForm.controls.published?.dirty && editForm.controls.published?.invalid)">
<small class="form-text text-danger"
[hidden]="!editForm.controls.published?.errors?.required">
This field is required.
</small>
</div>
</div>
<div class="form-group">
<label class="form-control-label" for="field_quantity">Quantity</label>
<input type="number" class="form-control" name="quantity" id="field_quantity"
[(ngModel)]="book.quantity" required min="0" jhiMin="0"/>
<div [hidden]="!(editForm.controls.quantity?.dirty && editForm.controls.quantity?.invalid)">
<small class="form-text text-danger"
[hidden]="!editForm.controls.quantity?.errors?.required">
This field is required.
</small>
<small class="form-text text-danger"
[hidden]="!editForm.controls.quantity?.errors?.min">
This field should be at least 0.
</small>
<small class="form-text text-danger"
[hidden]="!editForm.controls.quantity?.errors?.number">
This field should be a number.
</small>
</div>
</div>
<div class="form-group">
<label class="form-control-label" for="field_price">Price</label>
<input type="number" class="form-control" name="price" id="field_price"
[(ngModel)]="book.price" required min="0" jhiMin="0"/>
<div [hidden]="!(editForm.controls.price?.dirty && editForm.controls.price?.invalid)">
<small class="form-text text-danger"
[hidden]="!editForm.controls.price?.errors?.required">
This field is required.
</small>
<small class="form-text text-danger"
[hidden]="!editForm.controls.price?.errors?.min">
This field should be at least 0.
</small>
<small class="form-text text-danger"
[hidden]="!editForm.controls.price?.errors?.number">
This field should be a number.
</small>
</div>
</div>
</div>
<div>
<button type="button" id="cancel-save" class="btn btn-secondary" (click)="previousState()">
<fa-icon [icon]="'ban'"></fa-icon>&nbsp;<span>Cancel</span>
</button>
<button type="submit" id="save-entity" [disabled]="editForm.form.invalid || isSaving" class="btn btn-primary">
<fa-icon [icon]="'save'"></fa-icon>&nbsp;<span>Save</span>
</button>
</div>
</form>
</div>
</div>

View File

@ -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<HttpResponse<IBook>>) {
result.subscribe((res: HttpResponse<IBook>) => this.onSaveSuccess(), (res: HttpErrorResponse) => this.onSaveError());
}
protected onSaveSuccess() {
this.isSaving = false;
this.previousState();
}
protected onSaveError() {
this.isSaving = false;
}
}

View File

@ -0,0 +1,62 @@
<div>
<h2 id="page-heading">
<span>Books</span>
<button id="jh-create-entity" class="btn btn-primary float-right jh-create-entity create-book" [routerLink]="['/book/new']">
<fa-icon [icon]="'plus'"></fa-icon>
<span >
Create new Book
</span>
</button>
</h2>
<jhi-alert></jhi-alert>
<br/>
<div class="table-responsive" *ngIf="books">
<table class="table table-striped">
<thead>
<tr>
<th><span>ID</span></th>
<th><span>Title</span></th>
<th><span>Author</span></th>
<th><span>Published</span></th>
<th><span>Quantity</span></th>
<th><span>Price</span></th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let book of books ;trackBy: trackId">
<td><a [routerLink]="['/book', book.id, 'view' ]">{{book.id}}</a></td>
<td>{{book.title}}</td>
<td>{{book.author}}</td>
<td>{{book.published | date:'mediumDate'}}</td>
<td>{{book.quantity}}</td>
<td>{{book.price}}</td>
<td class="text-right">
<div class="btn-group flex-btn-group-container">
<button type="submit"
[routerLink]="['/book', book.id, 'view' ]"
class="btn btn-info btn-sm">
<fa-icon [icon]="'eye'"></fa-icon>
<span class="d-none d-md-inline">View</span>
</button>
<button type="submit"
[routerLink]="['/book', book.id, 'edit']"
class="btn btn-primary btn-sm">
<fa-icon [icon]="'pencil-alt'"></fa-icon>
<span class="d-none d-md-inline">Edit</span>
</button>
<button type="submit"
[routerLink]="['/', 'book', { outlets: { popup: book.id + '/delete'} }]"
replaceUrl="true"
queryParamsHandling="merge"
class="btn btn-danger btn-sm">
<fa-icon [icon]="'times'"></fa-icon>
<span class="d-none d-md-inline">Delete</span>
</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>

View File

@ -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<IBook[]>) => res.ok),
map((res: HttpResponse<IBook[]>) => 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);
}
}

View File

@ -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 {}

View File

@ -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<IBook> {
constructor(private service: BookService) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<IBook> {
const id = route.params['id'] ? route.params['id'] : null;
if (id) {
return this.service.find(id).pipe(
filter((response: HttpResponse<Book>) => response.ok),
map((book: HttpResponse<Book>) => 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'
}
];

View File

@ -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<IBook>;
type EntityArrayResponseType = HttpResponse<IBook[]>;
@Injectable({ providedIn: 'root' })
export class BookService {
public resourceUrl = SERVER_API_URL + 'api/books';
constructor(protected http: HttpClient) {}
create(book: IBook): Observable<EntityResponseType> {
const copy = this.convertDateFromClient(book);
return this.http
.post<IBook>(this.resourceUrl, copy, { observe: 'response' })
.pipe(map((res: EntityResponseType) => this.convertDateFromServer(res)));
}
update(book: IBook): Observable<EntityResponseType> {
const copy = this.convertDateFromClient(book);
return this.http
.put<IBook>(this.resourceUrl, copy, { observe: 'response' })
.pipe(map((res: EntityResponseType) => this.convertDateFromServer(res)));
}
find(id: number): Observable<EntityResponseType> {
return this.http
.get<IBook>(`${this.resourceUrl}/${id}`, { observe: 'response' })
.pipe(map((res: EntityResponseType) => this.convertDateFromServer(res)));
}
query(req?: any): Observable<EntityArrayResponseType> {
const options = createRequestOption(req);
return this.http
.get<IBook[]>(this.resourceUrl, { params: options, observe: 'response' })
.pipe(map((res: EntityArrayResponseType) => this.convertDateArrayFromServer(res)));
}
delete(id: number): Observable<HttpResponse<any>> {
return this.http.delete<any>(`${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;
}
}

View File

@ -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';

View File

@ -4,6 +4,10 @@ import { RouterModule } from '@angular/router';
@NgModule({ @NgModule({
imports: [ imports: [
RouterModule.forChild([ RouterModule.forChild([
{
path: 'book',
loadChildren: './book/book.module#BookstoreBookModule'
}
/* jhipster-needle-add-entity-route - JHipster will add entity modules routes here */ /* jhipster-needle-add-entity-route - JHipster will add entity modules routes here */
]) ])
], ],

View File

@ -27,6 +27,12 @@
</span> </span>
</a> </a>
<ul class="dropdown-menu" ngbDropdownMenu aria-labelledby="entity-menu"> <ul class="dropdown-menu" ngbDropdownMenu aria-labelledby="entity-menu">
<li>
<a class="dropdown-item" routerLink="book" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }" (click)="collapseNavbar()">
<fa-icon icon="asterisk" fixedWidth="true"></fa-icon>
<span>Book</span>
</a>
</li>
<!-- jhipster-needle-add-entity-to-menu - JHipster will add entities to the menu here --> <!-- jhipster-needle-add-entity-to-menu - JHipster will add entities to the menu here -->
</ul> </ul>
</li> </li>

View File

@ -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
) {}
}

View File

@ -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<Book> 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<Book> 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<Book> 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<Book> 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<Book> 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<Book> 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<Book> 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<Book> 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<Book> 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<Book> 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();
}
}

View File

@ -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<BookDeleteDialogComponent>;
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();
})
));
});
});
});

View File

@ -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<BookDetailComponent>;
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 }));
});
});
});
});

View File

@ -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<BookUpdateComponent>;
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);
}));
});
});
});

View File

@ -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<BookComponent>;
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 }));
});
});
});

View File

@ -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();
});
});
});