diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..3d950a6 --- /dev/null +++ b/build.gradle @@ -0,0 +1,42 @@ +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath("org.springframework.boot:spring-boot-gradle-plugin:2.1.3.RELEASE") + } +} + +apply plugin: 'java' +apply plugin: 'idea' +apply plugin: 'org.springframework.boot' +apply plugin: 'io.spring.dependency-management' + +bootJar { + baseName = 'writer-fic' + version = '0.1.0' +} + +repositories { + mavenCentral() +} + +sourceCompatibility = 1.8 +targetCompatibility = 1.8 +compileJava.options.encoding = 'UTF-8' + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} +dependencies { + compile("org.springframework.boot:spring-boot-starter-data-jpa") + compile("org.springframework.boot:spring-boot-starter-web") + compile("org.springframework.boot:spring-boot-starter-test") + compile("org.springframework.boot:spring-boot-starter-hateoas") + + compile("org.projectlombok:lombok") + compile("mysql:mysql-connector-java") + compile("com.h2database:h2") + + testCompile("junit:junit") +} \ No newline at end of file diff --git a/src/main/java/fic/writer/Application.java b/src/main/java/fic/writer/Application.java new file mode 100644 index 0000000..7da4aa1 --- /dev/null +++ b/src/main/java/fic/writer/Application.java @@ -0,0 +1,11 @@ +package fic.writer; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/src/main/java/fic/writer/config/AuditConfig.java b/src/main/java/fic/writer/config/AuditConfig.java new file mode 100644 index 0000000..d052953 --- /dev/null +++ b/src/main/java/fic/writer/config/AuditConfig.java @@ -0,0 +1,9 @@ +package fic.writer.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; + +@Configuration +@EnableJpaAuditing +public class AuditConfig { +} diff --git a/src/main/java/fic/writer/domain/entity/Actor.java b/src/main/java/fic/writer/domain/entity/Actor.java new file mode 100644 index 0000000..8c88ef2 --- /dev/null +++ b/src/main/java/fic/writer/domain/entity/Actor.java @@ -0,0 +1,28 @@ +package fic.writer.domain.entity; + +import lombok.*; + +import javax.persistence.*; +import java.util.Set; + +@Entity +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class Actor { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(updatable = false) + private Long id; + private String name; + private String description; + @ManyToMany(fetch = FetchType.LAZY, mappedBy = "actors") + private Set books; + @OneToMany(cascade = {CascadeType.ALL}, + fetch = FetchType.LAZY, + orphanRemoval = true, + mappedBy = "actor") + private Set actorStates; +} \ No newline at end of file diff --git a/src/main/java/fic/writer/domain/entity/ActorState.java b/src/main/java/fic/writer/domain/entity/ActorState.java new file mode 100644 index 0000000..b3ef976 --- /dev/null +++ b/src/main/java/fic/writer/domain/entity/ActorState.java @@ -0,0 +1,25 @@ +package fic.writer.domain.entity; + +import lombok.*; + +import javax.persistence.*; + +@Entity +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@EqualsAndHashCode(of = "id") +public class ActorState { + @EmbeddedId + private ActorStateId id; + @MapsId("articleId") + @ManyToOne(fetch = FetchType.LAZY) + private Article article; + @MapsId("actorId") + @ManyToOne(fetch = FetchType.LAZY) + private Actor actor; + private String title; + private String content; +} \ No newline at end of file diff --git a/src/main/java/fic/writer/domain/entity/ActorStateId.java b/src/main/java/fic/writer/domain/entity/ActorStateId.java new file mode 100644 index 0000000..43425e0 --- /dev/null +++ b/src/main/java/fic/writer/domain/entity/ActorStateId.java @@ -0,0 +1,22 @@ +package fic.writer.domain.entity; + +import lombok.*; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import java.io.Serializable; + +@Embeddable +@NoArgsConstructor +@Getter +@Setter +@Builder +@AllArgsConstructor +@EqualsAndHashCode +public class ActorStateId implements Serializable { + @Column(name = "article_id") + private Long articleId; + @Column(name = "actor_id") + private Long actorId; + +} \ No newline at end of file diff --git a/src/main/java/fic/writer/domain/entity/Article.java b/src/main/java/fic/writer/domain/entity/Article.java new file mode 100644 index 0000000..5e1f6f1 --- /dev/null +++ b/src/main/java/fic/writer/domain/entity/Article.java @@ -0,0 +1,35 @@ +package fic.writer.domain.entity; + +import lombok.*; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import javax.persistence.*; +import java.util.Date; +import java.util.Set; + +@Entity +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@EntityListeners(AuditingEntityListener.class) +public class Article { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String title; + @CreatedDate + private Date created; + @LastModifiedDate + private Date lastModify; + @Column(columnDefinition = "text") + private String content; + private String annotation; + @ManyToOne(fetch = FetchType.LAZY) + private Book book; + @OneToMany(cascade = CascadeType.REMOVE) + private Set actorStates; +} \ No newline at end of file diff --git a/src/main/java/fic/writer/domain/entity/Book.java b/src/main/java/fic/writer/domain/entity/Book.java new file mode 100644 index 0000000..d3ad3e8 --- /dev/null +++ b/src/main/java/fic/writer/domain/entity/Book.java @@ -0,0 +1,54 @@ +package fic.writer.domain.entity; + +import fic.writer.domain.entity.enums.Size; +import fic.writer.domain.entity.enums.State; +import lombok.*; + +import javax.persistence.*; +import java.util.Set; + +@Entity +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class Book { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String title; + @ManyToOne + private User author; + @ManyToMany(fetch = FetchType.LAZY) + @JoinTable(name = "book_subauthors", + joinColumns = {@JoinColumn(name = "book_id")}, + inverseJoinColumns = {@JoinColumn(name = "user_id")} + ) + @Singular("subAuthors") + private Set subAuthors; + @OneToMany(fetch = FetchType.EAGER) + @Singular("source") + private Set source; + private String description; + @Enumerated + private Size size; + @Enumerated + private State state; + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true) + @Singular("articles") + private Set
articles; + @ManyToMany(fetch = FetchType.LAZY) + @JoinTable(name = "book_genres", + joinColumns = {@JoinColumn(name = "book_id")}, + inverseJoinColumns = {@JoinColumn(name = "genre_id")} + ) + private Set genres; + @ManyToMany(fetch = FetchType.LAZY) + @JoinTable(name = "book_actors", + joinColumns = {@JoinColumn(name = "book_id")}, + inverseJoinColumns = {@JoinColumn(name = "actor_id")} + ) + @Singular("actors") + private Set actors; +} diff --git a/src/main/java/fic/writer/domain/entity/Genre.java b/src/main/java/fic/writer/domain/entity/Genre.java new file mode 100644 index 0000000..9e14053 --- /dev/null +++ b/src/main/java/fic/writer/domain/entity/Genre.java @@ -0,0 +1,23 @@ +package fic.writer.domain.entity; + +import lombok.*; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.ManyToMany; +import java.util.Set; + +@Entity +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class Genre { + @Id + private Long id; + private String name; + @ManyToMany(mappedBy = "genres", fetch = FetchType.LAZY) + private Set book; +} diff --git a/src/main/java/fic/writer/domain/entity/User.java b/src/main/java/fic/writer/domain/entity/User.java new file mode 100644 index 0000000..d84375a --- /dev/null +++ b/src/main/java/fic/writer/domain/entity/User.java @@ -0,0 +1,27 @@ +package fic.writer.domain.entity; + +import lombok.*; + +import javax.persistence.*; +import java.util.Set; + +@Entity +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class User { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String username; + private String about; + private String information; + @ManyToMany(mappedBy = "subAuthors", fetch = FetchType.LAZY) + @Singular("booksAsSubAuthor") + private Set booksAsSubAuthor; + @OneToMany(fetch = FetchType.LAZY) + @Singular("booksAsAuthor") + private Set booksAsAuthor; +} diff --git a/src/main/java/fic/writer/domain/entity/auth/CustomUser.java b/src/main/java/fic/writer/domain/entity/auth/CustomUser.java new file mode 100644 index 0000000..22f2961 --- /dev/null +++ b/src/main/java/fic/writer/domain/entity/auth/CustomUser.java @@ -0,0 +1,22 @@ +package fic.writer.domain.entity.auth; + +import fic.writer.domain.entity.User; +import lombok.*; + +import javax.persistence.*; + +@Entity +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class CustomUser { + @Id + @GeneratedValue + private Long id; + @OneToOne(fetch = FetchType.EAGER) + private User profile; + private String email; + private String password; +} diff --git a/src/main/java/fic/writer/domain/entity/auth/OauthUser.java b/src/main/java/fic/writer/domain/entity/auth/OauthUser.java new file mode 100644 index 0000000..d9c38b4 --- /dev/null +++ b/src/main/java/fic/writer/domain/entity/auth/OauthUser.java @@ -0,0 +1,23 @@ +package fic.writer.domain.entity.auth; + +import fic.writer.domain.entity.User; +import lombok.*; + +import javax.persistence.*; +import java.util.Date; + +@Entity +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class OauthUser { + @Id + @GeneratedValue + private Long id; + @OneToOne(fetch = FetchType.EAGER) + private User profile; + private String token; + private Date expireDate; +} diff --git a/src/main/java/fic/writer/domain/entity/dto/ActorDto.java b/src/main/java/fic/writer/domain/entity/dto/ActorDto.java new file mode 100644 index 0000000..d8272e7 --- /dev/null +++ b/src/main/java/fic/writer/domain/entity/dto/ActorDto.java @@ -0,0 +1,24 @@ +package fic.writer.domain.entity.dto; + +import fic.writer.domain.entity.Actor; +import fic.writer.domain.entity.ActorState; +import lombok.Builder; +import lombok.Data; + +import java.util.Set; + +@Builder +@Data +public class ActorDto { + private String name; + private String description; + private Set actorStates; + + public static ActorDto of(Actor actor) { + return builder() + .name(actor.getName()) + .description(actor.getDescription()) + .actorStates(actor.getActorStates()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/fic/writer/domain/entity/dto/ActorStateDto.java b/src/main/java/fic/writer/domain/entity/dto/ActorStateDto.java new file mode 100644 index 0000000..9c38538 --- /dev/null +++ b/src/main/java/fic/writer/domain/entity/dto/ActorStateDto.java @@ -0,0 +1,23 @@ +package fic.writer.domain.entity.dto; + +import fic.writer.domain.entity.ActorState; +import fic.writer.domain.entity.ActorStateId; +import lombok.Builder; +import lombok.Data; + +@Builder +@Data +public class ActorStateDto { + private ActorStateId id; + private String title; + private String content; + + + public static ActorStateDto of(ActorState actorState) { + return builder() + .id(actorState.getId()) + .title(actorState.getTitle()) + .content(actorState.getContent()) + .build(); + } +} diff --git a/src/main/java/fic/writer/domain/entity/dto/ArticleDto.java b/src/main/java/fic/writer/domain/entity/dto/ArticleDto.java new file mode 100644 index 0000000..4bb8458 --- /dev/null +++ b/src/main/java/fic/writer/domain/entity/dto/ArticleDto.java @@ -0,0 +1,23 @@ +package fic.writer.domain.entity.dto; + +import fic.writer.domain.entity.Article; +import lombok.*; + +@Builder +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class ArticleDto { + private String title; + private String content; + private String annotation; + + public static ArticleDto of(Article article) { + return builder() + .title(article.getTitle()) + .content(article.getContent()) + .annotation(article.getAnnotation()) + .build(); + } +} diff --git a/src/main/java/fic/writer/domain/entity/dto/BookDto.java b/src/main/java/fic/writer/domain/entity/dto/BookDto.java new file mode 100644 index 0000000..ba254c0 --- /dev/null +++ b/src/main/java/fic/writer/domain/entity/dto/BookDto.java @@ -0,0 +1,28 @@ +package fic.writer.domain.entity.dto; + +import fic.writer.domain.entity.Book; +import fic.writer.domain.entity.enums.Size; +import fic.writer.domain.entity.enums.State; +import lombok.*; + + +@Builder +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class BookDto { + private String title; + private String description; + private Size size; + private State state; + + public static BookDto of(Book book) { + return builder() + .title(book.getTitle()) + .description(book.getDescription()) + .size(book.getSize()) + .state(book.getState()) + .build(); + } +} diff --git a/src/main/java/fic/writer/domain/entity/dto/UserDto.java b/src/main/java/fic/writer/domain/entity/dto/UserDto.java new file mode 100644 index 0000000..716a430 --- /dev/null +++ b/src/main/java/fic/writer/domain/entity/dto/UserDto.java @@ -0,0 +1,23 @@ +package fic.writer.domain.entity.dto; + +import fic.writer.domain.entity.User; +import lombok.*; + +@Builder +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class UserDto { + private String username; + private String about; + private String information; + + public static UserDto of(User user) { + return builder() + .username(user.getUsername()) + .about(user.getAbout()) + .information(user.getInformation()) + .build(); + } +} diff --git a/src/main/java/fic/writer/domain/entity/enums/Size.java b/src/main/java/fic/writer/domain/entity/enums/Size.java new file mode 100644 index 0000000..1b3b0a0 --- /dev/null +++ b/src/main/java/fic/writer/domain/entity/enums/Size.java @@ -0,0 +1,5 @@ +package fic.writer.domain.entity.enums; + +public enum Size { + MINI, MEDIUM, LONG +} diff --git a/src/main/java/fic/writer/domain/entity/enums/State.java b/src/main/java/fic/writer/domain/entity/enums/State.java new file mode 100644 index 0000000..318ac06 --- /dev/null +++ b/src/main/java/fic/writer/domain/entity/enums/State.java @@ -0,0 +1,5 @@ +package fic.writer.domain.entity.enums; + +public enum State { + FROZEN, IN_PROGRESS, DONE +} diff --git a/src/main/java/fic/writer/domain/repository/ActorRepository.java b/src/main/java/fic/writer/domain/repository/ActorRepository.java new file mode 100644 index 0000000..3eb5d55 --- /dev/null +++ b/src/main/java/fic/writer/domain/repository/ActorRepository.java @@ -0,0 +1,7 @@ +package fic.writer.domain.repository; + +import fic.writer.domain.entity.Actor; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ActorRepository extends JpaRepository { +} diff --git a/src/main/java/fic/writer/domain/repository/ActorStateRepository.java b/src/main/java/fic/writer/domain/repository/ActorStateRepository.java new file mode 100644 index 0000000..10cb175 --- /dev/null +++ b/src/main/java/fic/writer/domain/repository/ActorStateRepository.java @@ -0,0 +1,15 @@ +package fic.writer.domain.repository; + +import fic.writer.domain.entity.ActorState; +import fic.writer.domain.entity.ActorStateId; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface ActorStateRepository extends JpaRepository { + Page findAllByIdActorId(Long actorId, Pageable pageable); + + Optional findAByIdActorIdAndIdArticleId(Long actorId, Long articleId); +} diff --git a/src/main/java/fic/writer/domain/repository/ArticleRepository.java b/src/main/java/fic/writer/domain/repository/ArticleRepository.java new file mode 100644 index 0000000..0456388 --- /dev/null +++ b/src/main/java/fic/writer/domain/repository/ArticleRepository.java @@ -0,0 +1,10 @@ +package fic.writer.domain.repository; + +import fic.writer.domain.entity.Article; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface ArticleRepository extends JpaRepository { + List
findAllByBookId(Long bookId); +} diff --git a/src/main/java/fic/writer/domain/repository/BookRepository.java b/src/main/java/fic/writer/domain/repository/BookRepository.java new file mode 100644 index 0000000..a769dfb --- /dev/null +++ b/src/main/java/fic/writer/domain/repository/BookRepository.java @@ -0,0 +1,7 @@ +package fic.writer.domain.repository; + +import fic.writer.domain.entity.Book; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface BookRepository extends JpaRepository { +} diff --git a/src/main/java/fic/writer/domain/repository/GenreRepository.java b/src/main/java/fic/writer/domain/repository/GenreRepository.java new file mode 100644 index 0000000..fddb9e1 --- /dev/null +++ b/src/main/java/fic/writer/domain/repository/GenreRepository.java @@ -0,0 +1,7 @@ +package fic.writer.domain.repository; + +import fic.writer.domain.entity.Genre; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface GenreRepository extends JpaRepository { +} diff --git a/src/main/java/fic/writer/domain/repository/UserRepository.java b/src/main/java/fic/writer/domain/repository/UserRepository.java new file mode 100644 index 0000000..361fabf --- /dev/null +++ b/src/main/java/fic/writer/domain/repository/UserRepository.java @@ -0,0 +1,10 @@ +package fic.writer.domain.repository; + +import fic.writer.domain.entity.User; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface UserRepository extends JpaRepository { + Optional findByUsername(String username); +} diff --git a/src/main/java/fic/writer/domain/service/ActorService.java b/src/main/java/fic/writer/domain/service/ActorService.java new file mode 100644 index 0000000..e39043f --- /dev/null +++ b/src/main/java/fic/writer/domain/service/ActorService.java @@ -0,0 +1,25 @@ +package fic.writer.domain.service; + +import fic.writer.domain.entity.Actor; +import fic.writer.domain.entity.dto.ActorDto; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import java.util.List; +import java.util.Optional; + +public interface ActorService { + Actor getOne(Long id); + + Actor create(ActorDto actor); + + List findAll(); + + Page findPage(Pageable pageable); + + Optional findById(Long id); + + Actor update(Long id, ActorDto actor); + + void deleteById(Long aLong); +} diff --git a/src/main/java/fic/writer/domain/service/ActorStateService.java b/src/main/java/fic/writer/domain/service/ActorStateService.java new file mode 100644 index 0000000..f3988bf --- /dev/null +++ b/src/main/java/fic/writer/domain/service/ActorStateService.java @@ -0,0 +1,25 @@ +package fic.writer.domain.service; + +import fic.writer.domain.entity.ActorState; +import fic.writer.domain.entity.ActorStateId; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import java.util.List; +import java.util.Optional; + +public interface ActorStateService { + Page findAllByActor(Long id, Pageable pageable); + + Optional findForActorByArticle(Long actorId, Long articleId); + + List findAll(); + + Page findPage(Pageable pageable); + + Optional findById(ActorStateId actorStateId); + + void delete(ActorState actorState); + + void deleteById(ActorStateId actorStateId); +} diff --git a/src/main/java/fic/writer/domain/service/ArticleService.java b/src/main/java/fic/writer/domain/service/ArticleService.java new file mode 100644 index 0000000..8129e9a --- /dev/null +++ b/src/main/java/fic/writer/domain/service/ArticleService.java @@ -0,0 +1,25 @@ +package fic.writer.domain.service; + +import fic.writer.domain.entity.Article; +import fic.writer.domain.entity.dto.ArticleDto; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import java.util.List; +import java.util.Optional; + +public interface ArticleService { + List
findAll(); + + List
findAllForBook(Long bookId); + + Page
findPage(Pageable pageable); + + Article update(Long id, ArticleDto articleDto); + + Optional
findById(Long aLong); + + void delete(Article article); + + void deleteById(Long aLong); +} diff --git a/src/main/java/fic/writer/domain/service/BookService.java b/src/main/java/fic/writer/domain/service/BookService.java new file mode 100644 index 0000000..49a027d --- /dev/null +++ b/src/main/java/fic/writer/domain/service/BookService.java @@ -0,0 +1,34 @@ +package fic.writer.domain.service; + +import fic.writer.domain.entity.Book; +import fic.writer.domain.entity.dto.ArticleDto; +import fic.writer.domain.entity.dto.BookDto; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import java.io.IOException; +import java.util.List; +import java.util.Optional; + +public interface BookService { + + List findAll(); + + Page findPage(Pageable pageable); + + Optional findById(Long aLong); + + Book create(BookDto bookDto); + + Book update(Long id, BookDto bookDto); + + Book addArticle(Long bookId, ArticleDto articleDto); + + Book removeArticle(Long bookId, Long articleId); + + void delete(Book book); + + void deleteById(Long aLong); + + byte[] getBookAsByteArray(Long bookId) throws IOException; +} diff --git a/src/main/java/fic/writer/domain/service/CrudService.java b/src/main/java/fic/writer/domain/service/CrudService.java new file mode 100644 index 0000000..7e5739f --- /dev/null +++ b/src/main/java/fic/writer/domain/service/CrudService.java @@ -0,0 +1,21 @@ +package fic.writer.domain.service; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import java.util.List; +import java.util.Optional; + +public interface CrudService { + List findAll(); + + Page findPage(Pageable pageable); + + Optional findById(ID id); + + T save(T t); + + void delete(T t); + + void deleteById(ID id); +} diff --git a/src/main/java/fic/writer/domain/service/GenreService.java b/src/main/java/fic/writer/domain/service/GenreService.java new file mode 100644 index 0000000..9292154 --- /dev/null +++ b/src/main/java/fic/writer/domain/service/GenreService.java @@ -0,0 +1,7 @@ +package fic.writer.domain.service; + +import fic.writer.domain.entity.Genre; + +public interface GenreService extends CrudService { + +} diff --git a/src/main/java/fic/writer/domain/service/UserService.java b/src/main/java/fic/writer/domain/service/UserService.java new file mode 100644 index 0000000..5df0850 --- /dev/null +++ b/src/main/java/fic/writer/domain/service/UserService.java @@ -0,0 +1,27 @@ +package fic.writer.domain.service; + +import fic.writer.domain.entity.User; +import fic.writer.domain.entity.dto.UserDto; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import java.util.List; +import java.util.Optional; + +public interface UserService { + List findAll(); + + Page findPage(Pageable pageable); + + Optional findById(Long aLong); + + Optional findByUsername(String username); + + User create(UserDto user); + + User update(Long userId, UserDto user); + + void delete(User user); + + void deleteById(Long aLong); +} diff --git a/src/main/java/fic/writer/domain/service/impl/ActorServiceImpl.java b/src/main/java/fic/writer/domain/service/impl/ActorServiceImpl.java new file mode 100644 index 0000000..c67d57d --- /dev/null +++ b/src/main/java/fic/writer/domain/service/impl/ActorServiceImpl.java @@ -0,0 +1,75 @@ +package fic.writer.domain.service.impl; + +import fic.writer.domain.entity.Actor; +import fic.writer.domain.entity.dto.ActorDto; +import fic.writer.domain.repository.ActorRepository; +import fic.writer.domain.service.ActorService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import javax.persistence.EntityNotFoundException; +import java.util.List; +import java.util.Optional; + +@Service +public class ActorServiceImpl implements ActorService { + private ActorRepository actorRepository; + + @Autowired + public ActorServiceImpl(ActorRepository actorRepository) { + this.actorRepository = actorRepository; + } + + @Override + public List findAll() { + return actorRepository.findAll(); + } + + @Override + public Page findPage(Pageable pageable) { + return actorRepository.findAll(pageable); + } + + @Override + public Optional findById(Long id) { + return actorRepository.findById(id); + } + + @Override + public Actor update(Long id, ActorDto actorDto) { + Actor actor = actorRepository.findById(id).orElseThrow(EntityNotFoundException::new); + flushArticleDtoToArticle(actor, actorDto); + return actorRepository.save(actor); + } + + private void flushArticleDtoToArticle(Actor actor, ActorDto actorDto) { + if (actorDto.getName() != null) { + actor.setName(actorDto.getName()); + } + if (actorDto.getActorStates() != null) { + actor.setActorStates(actorDto.getActorStates()); + } + if (actorDto.getDescription() != null) { + actor.setDescription(actorDto.getDescription()); + } + } + + @Override + public Actor getOne(Long id) { + return actorRepository.getOne(id); + } + + @Override + public void deleteById(Long id) { + actorRepository.deleteById(id); + } + + @Override + public Actor create(ActorDto actorDto) { + Actor actor = Actor.builder().build(); + flushArticleDtoToArticle(actor, actorDto); + return actorRepository.save(actor); + } +} diff --git a/src/main/java/fic/writer/domain/service/impl/ActorStateServiceImpl.java b/src/main/java/fic/writer/domain/service/impl/ActorStateServiceImpl.java new file mode 100644 index 0000000..3749d67 --- /dev/null +++ b/src/main/java/fic/writer/domain/service/impl/ActorStateServiceImpl.java @@ -0,0 +1,70 @@ +package fic.writer.domain.service.impl; + +import fic.writer.domain.entity.ActorState; +import fic.writer.domain.entity.ActorStateId; +import fic.writer.domain.entity.dto.ActorStateDto; +import fic.writer.domain.repository.ActorRepository; +import fic.writer.domain.repository.ActorStateRepository; +import fic.writer.domain.service.ActorStateService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +public class ActorStateServiceImpl implements ActorStateService { + private ActorStateRepository actorStateRepository; + private ActorRepository actorRepository; + + @Autowired + public ActorStateServiceImpl(ActorStateRepository actorStateRepository) { + this.actorStateRepository = actorStateRepository; + } + + @Override + public List findAll() { + return actorStateRepository.findAll(); + } + + + @Override + public Page findPage(Pageable pageable) { + return actorStateRepository.findAll(pageable); + } + + @Override + public Optional findById(ActorStateId id) { + return actorStateRepository.findById(id); + } + + @Override + public void delete(ActorState actorState) { + actorStateRepository.delete(actorState); + } + + @Override + public void deleteById(ActorStateId id) { + actorStateRepository.deleteById(id); + } + + @Override + public Page findAllByActor(Long id, Pageable pageable) { + return actorStateRepository.findAllByIdActorId(id, pageable); + } + + @Override + public Optional findForActorByArticle(Long actorId, Long articleId) { + return actorStateRepository.findAByIdActorIdAndIdArticleId(actorId, articleId); + } + + private ActorState actorStateDtoForActorState(ActorStateDto actorState) { + return ActorState.builder() + .id(actorState.getId()) + .title(actorState.getTitle()) + .content(actorState.getContent()) + .build(); + } +} diff --git a/src/main/java/fic/writer/domain/service/impl/ArticleServiceImpl.java b/src/main/java/fic/writer/domain/service/impl/ArticleServiceImpl.java new file mode 100644 index 0000000..3ad1f61 --- /dev/null +++ b/src/main/java/fic/writer/domain/service/impl/ArticleServiceImpl.java @@ -0,0 +1,74 @@ +package fic.writer.domain.service.impl; + +import fic.writer.domain.entity.Article; +import fic.writer.domain.entity.dto.ArticleDto; +import fic.writer.domain.repository.ArticleRepository; +import fic.writer.domain.service.ArticleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import javax.persistence.EntityExistsException; +import java.util.List; +import java.util.Optional; + +@Service +public class ArticleServiceImpl implements ArticleService { + private ArticleRepository articleRepository; + + @Autowired + public ArticleServiceImpl(ArticleRepository articleRepository) { + this.articleRepository = articleRepository; + } + + @Override + public List
findAll() { + return articleRepository.findAll(); + } + + @Override + public List
findAllForBook(Long bookId) { + return articleRepository.findAllByBookId(bookId); + } + + @Override + public Page
findPage(Pageable pageable) { + return articleRepository.findAll(pageable); + } + + @Override + public Article update(Long id, ArticleDto articleDto) { + Article article = articleRepository.findById(id).orElseThrow(EntityExistsException::new); + flushArticleDtoToArticle(article, articleDto); + return articleRepository.save(article); + } + + @Override + public Optional
findById(Long id) { + return articleRepository.findById(id); + } + + @Override + public void delete(Article article) { + articleRepository.delete(article); + } + + @Override + public void deleteById(Long id) { + articleRepository.deleteById(id); + } + + + private void flushArticleDtoToArticle(Article article, ArticleDto articleDto) { + if (articleDto.getTitle() != null) { + article.setTitle(articleDto.getTitle()); + } + if (articleDto.getAnnotation() != null) { + article.setAnnotation(articleDto.getAnnotation()); + } + if (articleDto.getContent() != null) { + article.setContent(articleDto.getContent()); + } + } +} diff --git a/src/main/java/fic/writer/domain/service/impl/BookServiceImpl.java b/src/main/java/fic/writer/domain/service/impl/BookServiceImpl.java new file mode 100644 index 0000000..8d850e8 --- /dev/null +++ b/src/main/java/fic/writer/domain/service/impl/BookServiceImpl.java @@ -0,0 +1,154 @@ +package fic.writer.domain.service.impl; + +import fic.writer.domain.entity.Article; +import fic.writer.domain.entity.Book; +import fic.writer.domain.entity.User; +import fic.writer.domain.entity.dto.ArticleDto; +import fic.writer.domain.entity.dto.BookDto; +import fic.writer.domain.repository.BookRepository; +import fic.writer.domain.service.BookService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.EntityListeners; +import javax.persistence.EntityNotFoundException; +import java.io.IOException; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +@Service +@EntityListeners(AuditingEntityListener.class) +@Transactional +public class BookServiceImpl implements BookService { + private BookRepository bookRepository; + + @Autowired + + public BookServiceImpl(BookRepository bookRepository) { + this.bookRepository = bookRepository; + } + + @Override + public List findAll() { + return bookRepository.findAll(); + } + + + @Override + public Page findPage(Pageable pageable) { + return bookRepository.findAll(pageable); + } + + @Override + public Optional findById(Long id) { + return bookRepository.findById(id); + } + + @Override + public Book create(BookDto bookDto) { + Book book = Book.builder().build(); + flushBookDtoToBook(book, bookDto); + return bookRepository.save(book); + } + + @Override + public Book update(Long id, BookDto bookDto) { + Book book = bookRepository.getOne(id); + flushBookDtoToBook(book, bookDto); + return bookRepository.save(book); + } + + @Override + public Book addArticle(Long bookId, ArticleDto articleDto) { + Book book = bookRepository.getOne(bookId); + Article article = Article.builder().build(); + flushArticleDtoToArticle(article, articleDto); + article.setBook(Book.builder().id(bookId).build()); + book.getArticles().add(article); + bookRepository.save(book); + return book; + } + + @Override + public Book removeArticle(Long bookId, Long articleId) { + Book book = bookRepository.getOne(bookId); + book.getArticles().removeIf(article -> article.getId().equals(articleId)); + bookRepository.save(book); + return book; + } + + private void flushArticleDtoToArticle(Article article, ArticleDto articleDto) { + if (articleDto.getTitle() != null) { + article.setTitle(articleDto.getTitle()); + } + if (articleDto.getAnnotation() != null) { + article.setAnnotation(articleDto.getAnnotation()); + } + if (articleDto.getContent() != null) { + article.setContent(articleDto.getContent()); + } + } + + @Override + public void delete(Book book) { + bookRepository.delete(book); + } + + @Override + public void deleteById(Long id) { + bookRepository.deleteById(id); + } + + @Override + public byte[] getBookAsByteArray(Long bookId) throws IOException { + Book book = bookRepository.findById(bookId).orElseThrow(EntityNotFoundException::new); + String output = ""; + output += "Title:" + book.getTitle(); + output += " \nDescription:" + book.getDescription(); + if (book.getAuthor() != null) { + output += " \nAuthor:" + book.getAuthor().getUsername(); + } + String coauthors = book.getSubAuthors().stream().map(User::getUsername).reduce((b, a) -> b + "," + a).orElse(""); + output += " \nCoauthor:" + coauthors; + if (book.getSize() != null) { + output += " \nSize:" + book.getSize().name(); + } + if (book.getSize() != null) { + output += " \nState:" + book.getState().name(); + } + int counter = 0; + String content = " \nContent: \n"; + Set
articles = book.getArticles(); + for (Article article : articles) { + content += " \n" + ++counter + ". " + article.getTitle(); + } + output += content; + + for (Article article : articles) { + output += " \n" + article.getTitle(); + output += " \nAnnotation:" + article.getAnnotation(); + output += " \n" + article.getContent(); + } + return output.getBytes(); + } + + private void flushBookDtoToBook(Book book, BookDto bookDto) { + if (bookDto.getTitle() != null) { + book.setTitle(bookDto.getTitle()); + } + if (bookDto.getDescription() != null) { + book.setDescription(bookDto.getDescription()); + } + if (bookDto.getSize() != null) { + book.setSize(bookDto.getSize()); + } + if (bookDto.getState() != null) { + book.setState(bookDto.getState()); + } + } +} diff --git a/src/main/java/fic/writer/domain/service/impl/GenreServiceImpl.java b/src/main/java/fic/writer/domain/service/impl/GenreServiceImpl.java new file mode 100644 index 0000000..9ff80dd --- /dev/null +++ b/src/main/java/fic/writer/domain/service/impl/GenreServiceImpl.java @@ -0,0 +1,52 @@ +package fic.writer.domain.service.impl; + +import fic.writer.domain.entity.Genre; +import fic.writer.domain.repository.GenreRepository; +import fic.writer.domain.service.GenreService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +public class GenreServiceImpl implements GenreService { + private GenreRepository genreRepository; + + @Autowired + public GenreServiceImpl(GenreRepository genreRepository) { + this.genreRepository = genreRepository; + } + + @Override + public List findAll() { + return genreRepository.findAll(); + } + + @Override + public Page findPage(Pageable pageable) { + return genreRepository.findAll(pageable); + } + + @Override + public Optional findById(Long id) { + return genreRepository.findById(id); + } + + @Override + public Genre save(Genre genre) { + return genreRepository.save(genre); + } + + @Override + public void delete(Genre genre) { + genreRepository.delete(genre); + } + + @Override + public void deleteById(Long id) { + genreRepository.deleteById(id); + } +} \ No newline at end of file diff --git a/src/main/java/fic/writer/domain/service/impl/UserServiceImpl.java b/src/main/java/fic/writer/domain/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..30dba9e --- /dev/null +++ b/src/main/java/fic/writer/domain/service/impl/UserServiceImpl.java @@ -0,0 +1,82 @@ +package fic.writer.domain.service.impl; + +import fic.writer.domain.entity.User; +import fic.writer.domain.entity.dto.UserDto; +import fic.writer.domain.repository.UserRepository; +import fic.writer.domain.service.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import javax.persistence.EntityNotFoundException; +import java.util.List; +import java.util.Optional; + +@Service +public class UserServiceImpl implements UserService { + private UserRepository userRepository; + + @Autowired + public UserServiceImpl(UserRepository userRepository) { + this.userRepository = userRepository; + } + + @Override + public List findAll() { + return userRepository.findAll(); + } + + @Override + public Page findPage(Pageable pageable) { + return userRepository.findAll(pageable); + } + + @Override + public Optional findById(Long id) { + return userRepository.findById(id); + } + + @Override + public Optional findByUsername(String username) { + return userRepository.findByUsername(username); + } + + @Override + public User create(UserDto userDto) { + User user = User.builder().build(); + flushUserDtoToUser(user, userDto); + return userRepository.save(user); + + } + + @Override + public User update(Long userId, UserDto userDto) { + User user = userRepository.findById(userId).orElseThrow(EntityNotFoundException::new); + flushUserDtoToUser(user, userDto); + userRepository.save(user); + return user; + } + + private void flushUserDtoToUser(User user, UserDto userDto) { + if (userDto.getUsername() != null) { + user.setUsername(userDto.getUsername()); + } + if (userDto.getAbout() != null) { + user.setAbout(userDto.getAbout()); + } + if (userDto.getInformation() != null) { + user.setInformation(userDto.getInformation()); + } + } + + @Override + public void delete(User user) { + userRepository.delete(user); + } + + @Override + public void deleteById(Long id) { + userRepository.deleteById(id); + } +} diff --git a/src/main/java/fic/writer/web/controller/ActorController.java b/src/main/java/fic/writer/web/controller/ActorController.java new file mode 100644 index 0000000..0c254b7 --- /dev/null +++ b/src/main/java/fic/writer/web/controller/ActorController.java @@ -0,0 +1,59 @@ +package fic.writer.web.controller; + +import fic.writer.domain.entity.Actor; +import fic.writer.domain.entity.dto.ActorDto; +import fic.writer.domain.service.ActorService; +import fic.writer.web.response.ActorResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +import javax.persistence.EntityNotFoundException; +import java.util.List; +import java.util.stream.Collectors; + +@RestController +@RequestMapping("/actors") +public class ActorController { + private static final String ID_TEMPLATE_PATH = "/{actorId}"; + private static final String ID_TEMPLATE = "actorId"; + + private ActorService actorService; + + @Autowired + public ActorController(ActorService actorService) { + this.actorService = actorService; + } + + @GetMapping + public List getAllActors() { + return actorService.findAll().stream() + .map(ActorResponse::new) + .collect(Collectors.toList()); + } + + @GetMapping(ID_TEMPLATE_PATH) + public ActorResponse getActorById(@PathVariable(ID_TEMPLATE) Long id) { + return actorService.findById(id) + .map(ActorResponse::new) + .orElseThrow(EntityNotFoundException::new); + } + + @PostMapping + public ActorResponse createActor(ActorDto actor) { + Actor savedActor = actorService.create(actor); + return new ActorResponse(savedActor); + } + + @PutMapping(ID_TEMPLATE_PATH) + public ActorResponse updateActor(Long id, ActorDto actor) { + Actor savedActor = actorService.update(id, actor); + return new ActorResponse(savedActor); + } + + @DeleteMapping(ID_TEMPLATE_PATH) + public HttpStatus deleteActor(Long id) { + actorService.deleteById(id); + return HttpStatus.NO_CONTENT; + } +} diff --git a/src/main/java/fic/writer/web/controller/ArticleController.java b/src/main/java/fic/writer/web/controller/ArticleController.java new file mode 100644 index 0000000..4016fbb --- /dev/null +++ b/src/main/java/fic/writer/web/controller/ArticleController.java @@ -0,0 +1,61 @@ +package fic.writer.web.controller; + +import fic.writer.domain.entity.dto.ArticleDto; +import fic.writer.domain.service.ArticleService; +import fic.writer.domain.service.BookService; +import fic.writer.web.response.ArticleResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +import javax.persistence.EntityNotFoundException; +import java.util.List; +import java.util.stream.Collectors; + +@RestController +@RequestMapping(value = "/books/{bookId}/articles", produces = MediaType.APPLICATION_JSON_VALUE) +@CrossOrigin(origins = "http://localhost:3000") +public class ArticleController { + private static final String ID_TEMPLATE_PATH = "/{articleId}"; + private static final String ID_TEMPLATE = "articleId"; + private static final String BOOK_ID_TEMPLATE_PATH = "/{bookId}"; + private static final String BOOK_ID_TEMPLATE = "bookId"; + @Autowired + private ArticleService articleService; + @Autowired + private BookService bookService; + + @GetMapping + public List getAllArticles(@PathVariable(BOOK_ID_TEMPLATE) Long bookId) { + List list = articleService.findAllForBook(bookId).stream().map(ArticleResponse::new).collect(Collectors.toList()); + return list; + } + + @GetMapping(ID_TEMPLATE_PATH) + public ArticleResponse getOneArticle(@PathVariable(BOOK_ID_TEMPLATE) Long bookId, @PathVariable(ID_TEMPLATE) Long articleId) { + return articleService.findAllForBook(bookId).stream(). + filter(article -> article.getId().equals(articleId)) + .map(ArticleResponse::new) + .findFirst() + .orElseThrow(EntityNotFoundException::new); + } + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public void createArticle(@PathVariable(BOOK_ID_TEMPLATE) Long bookId, @RequestBody ArticleDto articleDto) { + bookService.addArticle(bookId, articleDto); + } + + @DeleteMapping(ID_TEMPLATE_PATH) + @ResponseStatus(HttpStatus.NO_CONTENT) + public void deleteArticle(@PathVariable(BOOK_ID_TEMPLATE) Long bookId, @PathVariable(ID_TEMPLATE) Long articleId) { + bookService.removeArticle(bookId, articleId); + } + + @PutMapping(ID_TEMPLATE_PATH) + @ResponseStatus(HttpStatus.OK) + public void updateArticle(@PathVariable(ID_TEMPLATE) Long articleId, @RequestBody ArticleDto articleDto) { + articleService.update(articleId, articleDto); + } +} \ No newline at end of file diff --git a/src/main/java/fic/writer/web/controller/BookController.java b/src/main/java/fic/writer/web/controller/BookController.java new file mode 100644 index 0000000..1969ea6 --- /dev/null +++ b/src/main/java/fic/writer/web/controller/BookController.java @@ -0,0 +1,82 @@ +package fic.writer.web.controller; + +import fic.writer.domain.entity.Book; +import fic.writer.domain.entity.dto.BookDto; +import fic.writer.domain.service.BookService; +import fic.writer.web.response.BookResponse; +import fic.writer.web.response.PageResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.persistence.EntityNotFoundException; +import java.io.IOException; + +@RestController +@RequestMapping(value = "/books", produces = MediaType.APPLICATION_JSON_VALUE) +@CrossOrigin(origins = "http://localhost:3000") +public class BookController { + private static final String ID_TEMPLATE_PATH = "/{bookId}"; + private static final String ID_TEMPLATE = "bookId"; + + private BookService bookService; + + @Autowired + public BookController(BookService bookService) { + this.bookService = bookService; + } + + @GetMapping + public PageResponse getAllBooks(Pageable pageable) { + Page resourcePage = bookService.findPage(pageable).map(BookResponse::new); + return new PageResponse<>(resourcePage); + } + + @GetMapping(ID_TEMPLATE_PATH) + public BookResponse getBookById(@PathVariable(ID_TEMPLATE) Long id) { + return bookService.findById(id) + .map(BookResponse::new) + .orElseThrow(EntityNotFoundException::new); + } + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public BookResponse createBook(@RequestBody BookDto book) { + Book savedBook = bookService.create(book); + return new BookResponse(savedBook); + } + + @PutMapping(ID_TEMPLATE_PATH) + public BookResponse updateBook(@PathVariable(ID_TEMPLATE) Long id, @RequestBody BookDto book) { + Book savedBook = bookService.update(id, book); + return new BookResponse(savedBook); + } + + @DeleteMapping(ID_TEMPLATE_PATH) + public HttpStatus deleteBook(Long id) { + bookService.deleteById(id); + return HttpStatus.NO_CONTENT; + } + + @GetMapping(ID_TEMPLATE_PATH + "/download") + public ResponseEntity downloadBook(@PathVariable(ID_TEMPLATE) Long id) throws IOException { + byte[] bytes = bookService.getBookAsByteArray(id); + Book book = bookService.findById(id).get(); + + ByteArrayResource resource = new ByteArrayResource(bytes); + MediaType mediaType = MediaType.TEXT_PLAIN; + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + book.getTitle() + ".txt") + .contentType(mediaType) + .contentLength(bytes.length) + .body(resource); + } + + +} diff --git a/src/main/java/fic/writer/web/controller/UserController.java b/src/main/java/fic/writer/web/controller/UserController.java new file mode 100644 index 0000000..dd1f123 --- /dev/null +++ b/src/main/java/fic/writer/web/controller/UserController.java @@ -0,0 +1,61 @@ +package fic.writer.web.controller; + +import fic.writer.domain.entity.User; +import fic.writer.domain.entity.dto.UserDto; +import fic.writer.domain.service.UserService; +import fic.writer.web.response.UserResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +import javax.persistence.EntityNotFoundException; +import java.util.List; +import java.util.stream.Collectors; + +@RestController +@RequestMapping("/users") +@CrossOrigin(origins = "http://localhost:3000") +public class UserController { + private static final String ID_TEMPLATE_PATH = "/{userId}"; + private static final String ID_TEMPLATE = "userId"; + + private UserService userService; + + @Autowired + public UserController(UserService userService) { + this.userService = userService; + } + + @GetMapping + public List getAllUsers() { + return userService.findAll().stream() + .map(UserResponse::new) + .collect(Collectors.toList()); + } + + @GetMapping(ID_TEMPLATE_PATH) + public UserResponse getUserById(@PathVariable(ID_TEMPLATE) Long id) { + return userService.findById(id) + .map(UserResponse::new) + .orElseThrow(EntityNotFoundException::new); + } + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public UserResponse createUser(@RequestBody UserDto user) { + User savedUser = userService.create(user); + return new UserResponse(savedUser); + } + + @PutMapping(ID_TEMPLATE_PATH) + public UserResponse updateUser(@PathVariable(ID_TEMPLATE) Long id, @RequestBody UserDto userDto) { + User savedUser = userService.update(id, userDto); + return new UserResponse(savedUser); + } + + @DeleteMapping(ID_TEMPLATE_PATH) + @ResponseStatus(HttpStatus.NO_CONTENT) + public void deleteUser(Long id) { + userService.deleteById(id); + } +} diff --git a/src/main/java/fic/writer/web/response/ActorResponse.java b/src/main/java/fic/writer/web/response/ActorResponse.java new file mode 100644 index 0000000..b86ea74 --- /dev/null +++ b/src/main/java/fic/writer/web/response/ActorResponse.java @@ -0,0 +1,39 @@ +package fic.writer.web.response; + +import fic.writer.domain.entity.Actor; +import fic.writer.web.controller.ActorController; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.hateoas.ResourceSupport; + +import java.util.Set; +import java.util.stream.Collectors; + +import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; +import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +public class ActorResponse extends ResourceSupport { + private Long actorId; + private String name; + private String description; + private Set books; + private Set actorStates; + + public ActorResponse(Actor actor) { + actorId = actor.getId(); + name = actor.getName(); + description = actor.getDescription(); + books = actor.getBooks().stream().map(BookResponse::new).collect(Collectors.toSet()); + actorStates = actor.getActorStates().stream().map(ActorStateResponse::new).collect(Collectors.toSet()); + addSelfLink(actorId); + } + + + private void addSelfLink(Long id) { + add(linkTo(methodOn(ActorController.class, id).getActorById(id)).withSelfRel()); + } +} diff --git a/src/main/java/fic/writer/web/response/ActorStateResponse.java b/src/main/java/fic/writer/web/response/ActorStateResponse.java new file mode 100644 index 0000000..67a6718 --- /dev/null +++ b/src/main/java/fic/writer/web/response/ActorStateResponse.java @@ -0,0 +1,12 @@ +package fic.writer.web.response; + +import fic.writer.domain.entity.ActorState; +import org.springframework.hateoas.ResourceSupport; + +public class ActorStateResponse extends ResourceSupport { + private ActorState actorState; + + public ActorStateResponse(ActorState actorState) { + this.actorState = actorState; + } +} diff --git a/src/main/java/fic/writer/web/response/ArticleResponse.java b/src/main/java/fic/writer/web/response/ArticleResponse.java new file mode 100644 index 0000000..ca96f1e --- /dev/null +++ b/src/main/java/fic/writer/web/response/ArticleResponse.java @@ -0,0 +1,37 @@ +package fic.writer.web.response; + +import fic.writer.domain.entity.Article; +import fic.writer.web.controller.BookController; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.hateoas.ResourceSupport; + +import java.util.Date; + +import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; +import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +public class ArticleResponse extends ResourceSupport { + private Long articleId; + private String title; + private Date created; + private String content; + private String annotation; + + public ArticleResponse(Article article) { + articleId = article.getId(); + title = article.getTitle(); + created = article.getCreated(); + content = article.getContent(); + annotation = article.getAnnotation(); + addSelfLink(articleId); + } + + private void addSelfLink(Long id) { + add(linkTo(methodOn(BookController.class, id).getBookById(id)).withSelfRel()); + } +} diff --git a/src/main/java/fic/writer/web/response/BookResponse.java b/src/main/java/fic/writer/web/response/BookResponse.java new file mode 100644 index 0000000..5baaa2c --- /dev/null +++ b/src/main/java/fic/writer/web/response/BookResponse.java @@ -0,0 +1,74 @@ +package fic.writer.web.response; + +import fic.writer.domain.entity.Book; +import fic.writer.domain.entity.Genre; +import fic.writer.domain.entity.enums.Size; +import fic.writer.domain.entity.enums.State; +import fic.writer.web.controller.ArticleController; +import fic.writer.web.controller.BookController; +import fic.writer.web.controller.UserController; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.hateoas.Link; +import org.springframework.hateoas.ResourceSupport; + +import java.io.IOException; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; +import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +public class BookResponse extends ResourceSupport { + private Long bookId; + private String title; + private Link author; + private Set subAuthors; + private Set source; + private String description; + private Size size; + private State state; + private Set genres; + private Set actors; + private Link articles; + + public BookResponse(Book book) { + this.bookId = book.getId(); + title = book.getTitle(); + if (book.getAuthor() != null) { + Long authorId = book.getAuthor().getId(); + author = linkTo(methodOn(UserController.class, authorId).getUserById(authorId)).withRel("author"); + } + subAuthors = book.getSubAuthors().stream().map(author -> + linkTo(methodOn(UserController.class, author.getId()).getUserById(author.getId())) + .withRel("subauthor")).collect(Collectors.toSet()); + source = book.getSource().stream().map(BookResponse::new).map(ResourceSupport::getId).collect(Collectors.toSet()); + description = book.getDescription(); + size = book.getSize(); + state = book.getState(); + genres = book.getGenres(); + actors = book.getActors().stream().map(ActorResponse::new).map(ResourceSupport::getId).collect(Collectors.toSet()); + articles = linkTo(methodOn(ArticleController.class, bookId).getAllArticles(bookId)).withRel("articles"); + addSelfLink(bookId); + addDownloadLink((bookId)); + } + + private void addSelfLink(Long id) { + add(linkTo(methodOn(BookController.class, id).getBookById(id)).withSelfRel()); + } + + private void addDownloadLink(Long id) { + + try { + add(linkTo(methodOn(BookController.class, id).downloadBook(id)).withRel("download")); + } catch (IOException e) { + e.printStackTrace(); + } + } + + +} diff --git a/src/main/java/fic/writer/web/response/PageResponse.java b/src/main/java/fic/writer/web/response/PageResponse.java new file mode 100644 index 0000000..3b6e4ce --- /dev/null +++ b/src/main/java/fic/writer/web/response/PageResponse.java @@ -0,0 +1,52 @@ +package fic.writer.web.response; + +import org.springframework.data.domain.Page; +import org.springframework.hateoas.Link; +import org.springframework.hateoas.PagedResources; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +public class PageResponse extends PagedResources { + private Page page; + + public PageResponse(Page page) { + super(page.getContent(), new PageMetadata(page.getSize(), page.getNumber(), page.getTotalElements(), page.getTotalPages())); + this.page = page; + addSelfLink(); + addPageableLinks(); + } + + private void addPageableLinks() { + int firstPageNumber = 0; + int lastPageNumber = page.getTotalPages() <= 0 ? 0 : page.getTotalPages() - 1; + if (page.getTotalElements() != 0) { + addPageNumberLinkWithRel(firstPageNumber, Link.REL_FIRST); + addPageNumberLinkWithRel(lastPageNumber, Link.REL_LAST); + } + + if (page.hasNext()) { + int nextPageNumber = page.nextPageable().getPageNumber(); + addPageNumberLinkWithRel(nextPageNumber, Link.REL_NEXT); + } + + if (page.hasPrevious()) { + int previousPageNumber = page.previousPageable().getPageNumber(); + addPageNumberLinkWithRel(previousPageNumber, Link.REL_PREVIOUS); + } + } + + private void addSelfLink() { + String path = getCurrentRequestUriBuilder().build().toString(); + Link link = new Link(path, Link.REL_SELF); + add(link); + } + + private void addPageNumberLinkWithRel(Integer number, String rel) { + String path = getCurrentRequestUriBuilder().replaceQueryParam("page", number).build().toString(); + Link link = new Link(path, rel); + add(link); + } + + private ServletUriComponentsBuilder getCurrentRequestUriBuilder() { + return ServletUriComponentsBuilder.fromCurrentRequest(); + } +} diff --git a/src/main/java/fic/writer/web/response/UserResponse.java b/src/main/java/fic/writer/web/response/UserResponse.java new file mode 100644 index 0000000..bc6d942 --- /dev/null +++ b/src/main/java/fic/writer/web/response/UserResponse.java @@ -0,0 +1,45 @@ +package fic.writer.web.response; + +import fic.writer.domain.entity.User; +import fic.writer.web.controller.UserController; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.hateoas.ResourceSupport; + +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; +import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +public class UserResponse extends ResourceSupport { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long userId; + private String username; + private String about; + private String information; + private Set booksAsSubAuthor; + private Set booksAsAuthor; + + public UserResponse(User user) { + this.userId = user.getId(); + username = user.getUsername(); + about = user.getAbout(); + information = user.getInformation(); + booksAsSubAuthor = user.getBooksAsSubAuthor().stream().map(BookResponse::new).collect(Collectors.toSet()); + booksAsAuthor = user.getBooksAsAuthor().stream().map(BookResponse::new).collect(Collectors.toSet()); + addSelfLink(userId); + } + + private void addSelfLink(Long id) { + add(linkTo(methodOn(UserController.class, id).getUserById(id)).withSelfRel()); + } +} diff --git a/src/main/resources/application-db-mysql.yml b/src/main/resources/application-db-mysql.yml new file mode 100644 index 0000000..c27a72f --- /dev/null +++ b/src/main/resources/application-db-mysql.yml @@ -0,0 +1,17 @@ +spring: + datasource: + url: jdbc:mysql://localhost:3306/ficwriter + username: dl + password: p@ssword + initialization-mode: always + + jpa: + hibernate: + ddl-auto: create-drop + properties: + hibernate: + dialect: org.hibernate.dialect.MySQL5InnoDBDialect + hbm2ddl: + import_files_sql_extractor: org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor + import_files: data/user.sql, data/actor.sql, data/book.sql, data/article.sql,data/book_article.sql, data/actor_state.sql + diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..596c249 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,9 @@ +spring: + profiles: + active: db-mysql +logging: + level: + org: + springframework: INFO +server: + port: 8080 \ No newline at end of file diff --git a/src/main/resources/data/actor.sql b/src/main/resources/data/actor.sql new file mode 100644 index 0000000..bb9597c --- /dev/null +++ b/src/main/resources/data/actor.sql @@ -0,0 +1,10 @@ +INSERT INTO actor(id,description,name)VALUES(1,'description1','name1'); +INSERT INTO actor(id,description,name)VALUES(2,'description2','name2'); +INSERT INTO actor(id,description,name)VALUES(3,'description3','name3'); +INSERT INTO actor(id,description,name)VALUES(987,'description','name'); +INSERT INTO actor(id,description,name)VALUES(333,'description','name'); +INSERT INTO actor(id,description,name)VALUES(334,'description','name'); + + + + diff --git a/src/main/resources/data/actor_state.sql b/src/main/resources/data/actor_state.sql new file mode 100644 index 0000000..6e99aca --- /dev/null +++ b/src/main/resources/data/actor_state.sql @@ -0,0 +1,7 @@ +INSERT INTO actor_state(content,title,actor_id,article_id)VALUES('content1','title1',1,1); +INSERT INTO actor_state(content,title,actor_id,article_id)VALUES('content2','title2',1,2); +INSERT INTO actor_state(content,title,actor_id,article_id)VALUES('content3','title3',2,1); +INSERT INTO actor_state(content,title,actor_id,article_id)VALUES('content4','title4',2,2); + +INSERT INTO actor_state(content,title,actor_id,article_id)VALUES('content4','title4',333,3); +INSERT INTO actor_state(content,title,actor_id,article_id)VALUES('content4','title4',334,3); \ No newline at end of file diff --git a/src/main/resources/data/article.sql b/src/main/resources/data/article.sql new file mode 100644 index 0000000..1572fba --- /dev/null +++ b/src/main/resources/data/article.sql @@ -0,0 +1,146 @@ +INSERT INTO article(id,annotation,content,title,book_id)VALUES(1,'Place for annotation','

Place for content.

','Summer inspiration',1); +INSERT INTO article(id,annotation,content,title)VALUES(2,'annotation2','content2','title2'); +INSERT INTO article(id,annotation,content,title)VALUES(3,'annotation','content','title'); +INSERT INTO article(id,annotation,content,title)VALUES(4,'annotation','content','title'); +INSERT INTO article(id,annotation,content,title)VALUES(333,'annotation','content','delete article'); + +INSERT INTO article(id,book_id,annotation,title,content)VALUES(335,1,'','Зимняя поэма', +'

Измеряются грустью и чашками чая
+Безымянные, кроткие, зимние дни.
+Проживаешь мгновения, не замечая,
+Как бесследно теряются в прошлом они.
+
+Покрывает надежды обманчивый иней,
+Запотевшая память подобна окну.
+Растворяется контур реальности синей:
+Над экраном холодным и ясным усну.
+
+Утомлен безучастностью, сентиментален,
+Погружаюсь, запутавшись, в тихую тьму.
+А приснятся весенние язвы проталин
+И снега, равнодушны к концу своему.
+
+И покажется, будто неловко ступаю
+По сулящему гибель лукавому льду,
+Приближаюсь безвольно к незримому краю,
+Безучастно забвения смертного жду.
+
+Обреченность души молодой беспричинна,
+И мечты, и стремления сердца смешны.
+Неизбежно и близко маячит кончина,
+Обещая обители вечной весны.
+
+А былого сомнения ныне убоги,
+Поглотила пучина загробной реки;
+Мысли канули в тени последней дороги.
+Берега колдовской глубины далеки.
+
+Не внимая молитвам, судьба непреклонна,
+И слова, и молчание тщетны, пусты,
+Но зовут перезвоны миров Авалона
+Сквозь слепую завесу могильной черты.
+
+Промелькнуло знамение в зыби туманной,
+Воплощение обетованной земли.
+Кровоточит сознание призрачной раной.
+Рассеченную веру, Харон, исцели!
+
+На морозе растрескалась черная лодка,
+Перевозчик не тронет стремнину веслом.
+Изменилась от боли и страха походка:
+Не устанешь терзаться, скорбеть о былом.
+
+Разрывается грудь от печали железной,
+Утянуло уныние душу на дно.
+Беспредельная пропасть зияющей бездной
+Констатирует факт: умереть суждено.
+
+Принимаю жестокую истину эту.
+Под ногами ни твердь, но крошащийся наст.
+Пересечь пожелавший замерзшую Лету
+Неизбежно бесценное стражу отдаст.
+
+Проседает поверхность, ломаясь и тая,
+Увлекаясь течением мертвой воды,
+И тасует агония льды, как живая,
+И надежды безлики и сердцу чужды.
+
+На сминаемой глади нельзя схорониться,
+Настигает невидимый ужас. Фантом
+Беспощаден. Аида владений граница
+Искаверкала личность в тумане густом.
+
+Просыпаюсь, но кровь под висками грохочет,
+Что увидел в зловещем, пророческом сне.
+И дрожу, возвратившийся первопроходчик,
+Почему темнота ухмыляется мне?
+
+Поднимусь, в запыленное зеркало гляну,
+Не поверю, что нет в волосах седины.
+Удивленный открытому в духе изъяну,
+Осознаю, подобные обречены.
+
+Не бывает беспечна дорога поэта,
+И печаль неотступная бдит за спиной.
+Угнетает суровая истина эта.
+Почему безучастность любезна со мной?
+
+Очарован иллюзией, горечью болен,
+За словами под землю бреду в глубину.
+В лабиринтах блуждаю заброшенных штолен
+И ищу драгоценную правду одну.
+
+И в прорубленных поиском чьим-то пещерах
+Затеряюсь: обманка, сомнения, ложь.
+А в рассветных, неискренних сумерках серых
+На умершего в зеркале старом похож.
+
+Бесполезен желанием я. Одноразов
+И порыв, и поэзии выкрик немой.
+Принимаю стекляшки за груды алмазов.
+Одиссей никогда не вернется домой.
+
+Помню Данте и вечный огонь Одиссею,
+И правдивый, бесплотный, печальный язык.
+Опереться на слабую веру не смею,
+К безысходности мрачной за годы привык.
+
+Не боюсь очевидной угрозы обвала,
+Не боюсь нависающей тяжести гор.
+Равнодушная память, чадя, истлевала.
+Неужели конец однозначен и скор?
+
+Умываюсь, покинув недвижность постели,
+Отвечает насмешкой безмолвие глаз.
+А секунды, минуты, недели летели.
+Поклянусь измениться единственный раз.
+
+И слезами обет приношу перед Богом,
+Не терять ни мгновения, миг не терять.
+На пути разрушения скользком, пологом
+Не могу, покатившись, подняться опять.
+
+Поклонюсь утешающим, строгим иконам,
+И молитва развеет гнетущую тьму.
+И прощенный, служивший делам беззаконным,
+Не надеюсь тщеславно спастись самому.
+
+На восходе сугроб переливчат и розов,
+И затейлив узор приукрасил окно.
+Неужели с уходом кристальных морозов
+Полотно белотканное обречено?
+
+Опалив чистоту, молодое светило
+Прожигает сияющий кров белизны,
+А снежинки в бесплодную грязь превратило.
+Обтекают деревья угрюмы, темны.
+
+Почему разрушения ярость воспета?
+Сожаления вязки, сугубы, остры.
+Разлилась половодьем забвения Лета,
+Разделяя потоком зеркальным миры.
+
+А тлетворная оттепель жизни хлопочет,
+Умирает в смирении зимний покой.
+Вырываются листья из лопнувших почек,
+И весна торжествует в капели слепой.
'); \ No newline at end of file diff --git a/src/main/resources/data/book.sql b/src/main/resources/data/book.sql new file mode 100644 index 0000000..49fd526 --- /dev/null +++ b/src/main/resources/data/book.sql @@ -0,0 +1,11 @@ +INSERT INTO book(id,title,description, size, state,author_id)VALUES(1,'Arabella','Artic monkeys', 1,2,1); +INSERT INTO user_books_as_author (user_id,books_as_author_id)VALUES(1,1); +INSERT INTO book_subauthors (user_id,book_id)VALUES(2,1); +INSERT INTO book(title,description, size, state)VALUES('Old yellow bricks','Artic monkeys', 1,2); +INSERT INTO book(title,description, size, state)VALUES('End of me','Apocalyptica', 0,1); +INSERT INTO book(title,description, size, state)VALUES('Отблеск разочарований','Безнадежности печать...', 0,1); + + + + + diff --git a/src/main/resources/data/book_article.sql b/src/main/resources/data/book_article.sql new file mode 100644 index 0000000..1c61683 --- /dev/null +++ b/src/main/resources/data/book_article.sql @@ -0,0 +1,2 @@ +INSERT INTO book_articles(book_id,articles_id)VALUES(1,335); +INSERT INTO book_articles(book_id,articles_id)VALUES(1,1); \ No newline at end of file diff --git a/src/main/resources/data/user.sql b/src/main/resources/data/user.sql new file mode 100644 index 0000000..deb354d --- /dev/null +++ b/src/main/resources/data/user.sql @@ -0,0 +1,2 @@ +INSERT INTO user(id,about, information, username)VALUES(1,'I am author',' zaraza-takaja@mail.ru','Zaraza takaja'); +INSERT INTO user(id,about, information, username)VALUES(2,'I am author, too',' zaraza-takaja@mail.ru','@uthor'); \ No newline at end of file diff --git a/src/test/java/fic/writer/domain/service/ActorAndActorStateServicesTest.java b/src/test/java/fic/writer/domain/service/ActorAndActorStateServicesTest.java new file mode 100644 index 0000000..4c36603 --- /dev/null +++ b/src/test/java/fic/writer/domain/service/ActorAndActorStateServicesTest.java @@ -0,0 +1,105 @@ +package fic.writer.domain.service; + +import fic.writer.domain.entity.Actor; +import fic.writer.domain.entity.ActorState; +import fic.writer.domain.entity.ActorStateId; +import fic.writer.domain.entity.Article; +import fic.writer.domain.entity.dto.ActorDto; +import org.hibernate.Session; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.EntityManager; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +@RunWith(SpringRunner.class) +@SpringBootTest +@Transactional +public class ActorAndActorStateServicesTest { + @Autowired + private ActorService actorService; + @Autowired + private ActorStateService actorStateService; + @Autowired + private EntityManager entityManager; + + @Test + public void updateActorWithActorStates_whenCorrect_shouldUpdateInActorState() { + final Long ACTOR_ID = 333L; + final Long ARTICLE_ID = 3L; + final String NEW_ACTOR_NAME = "new name"; + Actor actor = actorService.findById(ACTOR_ID).get(); + ActorStateId actorStateId = ActorStateId.builder() + .actorId(ACTOR_ID) + .articleId(ARTICLE_ID) + .build(); + actor.setName(NEW_ACTOR_NAME); + actorService.update(ACTOR_ID, ActorDto.of(actor)); + + ActorState actorState = actorStateService.findById(actorStateId).get(); + + assertEquals(NEW_ACTOR_NAME, actorState.getActor().getName()); + } + + private Session getSession() { + return entityManager.unwrap(Session.class); + } + + @Test + public void deleteActorState_whenCorrect_shouldCleanInActor() { + final Long ACTOR_ID = 333L; + final Long ARTICLE_ID = 3L; + Session session = getSession(); + ActorStateId actorStateId = ActorStateId.builder() + .actorId(ACTOR_ID) + .articleId(ARTICLE_ID) + .build(); + + actorStateService.deleteById(actorStateId); + session.flush(); + Actor actor = actorService.findById(ACTOR_ID).get(); + + Boolean isStateInActor = actor.getActorStates().stream().anyMatch(as -> as.getId().equals(actorStateId)); + assertFalse(isStateInActor); + } + + + @Test + public void deleteActor_whenCorrect_shouldCleanActorStates() { + final Long ACTOR_ID = 334L; + + Actor actor = actorService.findById(ACTOR_ID).get(); + + actorService.deleteById(ACTOR_ID); + + assertFalse(actorStateService.findAll().stream().anyMatch(as -> as.getActor().equals(actor))); + } + + @Test + public void createActorState_whenCorrect_shouldCascadeAddInActor() { + final Long ACTOR_ID = 333L; + final Long ARTICLE_ID = 1L; + final int EXPECTED_SIZE = 2; + Article article = Article.builder().id(ARTICLE_ID).build(); + Actor actor = actorService.findById(ACTOR_ID).get(); + ActorState actorState = ActorState.builder() + .id(ActorStateId.builder().actorId(ACTOR_ID).articleId(ARTICLE_ID).build()) + .actor(actor) + .article(article) + .title("title") + .build(); + Set actorStates = actor.getActorStates(); + actorStates.add(actorState); + actor.setActorStates(actorStates); + actorService.update(ACTOR_ID, ActorDto.of(actor)); + int changedSize = actorService.findById(ACTOR_ID).get().getActorStates().size(); + assertEquals(EXPECTED_SIZE, changedSize); + } +} diff --git a/src/test/java/fic/writer/domain/service/ActorServiceTest.java b/src/test/java/fic/writer/domain/service/ActorServiceTest.java new file mode 100644 index 0000000..85f6754 --- /dev/null +++ b/src/test/java/fic/writer/domain/service/ActorServiceTest.java @@ -0,0 +1,59 @@ +package fic.writer.domain.service; + +import fic.writer.domain.entity.Actor; +import fic.writer.domain.entity.dto.ActorDto; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Optional; + +import static org.junit.Assert.*; + +@RunWith(SpringRunner.class) +@SpringBootTest +@Transactional +public class ActorServiceTest { + @Autowired + private ActorService actorService; + + @Test + public void createActor_whenCorrect_shouldFindWithId() { + Actor actor = Actor.builder().build(); + actor = actorService.create(ActorDto.of(actor)); + + assertTrue(actorService.findById(actor.getId()).isPresent()); + } + + @Test + public void createActor_whenIdExists_shouldFindUpdate() { + final Long ACTOR_ID = 1L; + final String NEW_NAME = "new name"; + actorService.update(ACTOR_ID, ActorDto.builder().name(NEW_NAME).build()); + Optional updatedActor = actorService.findById(ACTOR_ID); + assertTrue(updatedActor.isPresent()); + assertEquals(NEW_NAME, updatedActor.get().getName()); + } + + @Test + public void deleteActor_whenExists_shouldNotFound() { + final Long AUTHOR_ID = 987L; + assertTrue(actorService.findById(AUTHOR_ID).isPresent()); + actorService.deleteById(AUTHOR_ID); + assertFalse(actorService.findById(AUTHOR_ID).isPresent()); + } + + @Test(expected = EmptyResultDataAccessException.class) + public void deleteActor_whenNotExists_shouldThrowException() { + final Long AUTHOR_ID = -1L; + + assertFalse(actorService.findById(AUTHOR_ID).isPresent()); + actorService.deleteById(AUTHOR_ID); + } + + +} \ No newline at end of file diff --git a/src/test/java/fic/writer/domain/service/ActorStateServiceTest.java b/src/test/java/fic/writer/domain/service/ActorStateServiceTest.java new file mode 100644 index 0000000..419ba1a --- /dev/null +++ b/src/test/java/fic/writer/domain/service/ActorStateServiceTest.java @@ -0,0 +1,125 @@ +package fic.writer.domain.service; + +import fic.writer.domain.entity.Actor; +import fic.writer.domain.entity.ActorState; +import fic.writer.domain.entity.ActorStateId; +import fic.writer.domain.entity.Article; +import fic.writer.domain.entity.dto.ActorDto; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Optional; + +import static org.junit.Assert.*; + +@RunWith(SpringRunner.class) +@SpringBootTest +@Transactional +public class ActorStateServiceTest { + @Autowired + private ActorStateService actorStateService; + @Autowired + private ActorService actorService; + + @Test + public void createActorState_whenCorrect_shouldFindWithId() { + final Long ARTICLE_ID = 3L; + final Long ACTOR_ID = 3L; + Actor actor = actorService.findById(ACTOR_ID).get(); + ActorState actorState = buildActorState(actor, ARTICLE_ID); + actor.getActorStates().add(actorState); + + actor = actorService.update(ACTOR_ID, ActorDto.of(actor)); + assertTrue(actorStateService.findById(actorState.getId()).isPresent()); + } + + private ActorState buildActorState(Actor actor, Long articleId) { + Article article = Article.builder().id(articleId).build(); + ActorStateId actorStateId = ActorStateId.builder().articleId(articleId).actorId(actor.getId()).build(); + return ActorState.builder() + .id(actorStateId) + .actor(actor) + .article(article) + .build(); + } + + private ActorState buildActorState(Long actorId, Long articleId) { + Article article = Article.builder().id(articleId).build(); + Actor actor = actorService.findById(actorId).get(); + ActorStateId actorStateId = ActorStateId.builder().articleId(articleId).actorId(actor.getId()).build(); + return ActorState.builder() + .id(actorStateId) + .actor(actor) + .article(article) + .build(); + } + + @Test + public void findActorStateByArticle_whenCorrect_shouldExist() { + assertTrue(actorStateService.findForActorByArticle(1L, 1L).isPresent()); + } + + @Test + public void findActorStateByActor_whenCorrect_shouldExist() { + Pageable pageable = new PageRequest(0, 10); + assertNotEquals(0, actorStateService.findAllByActor(1L, pageable).getTotalElements()); + } + + @Test + public void findActorStateByActor_whenActorNotExist_shouldReturnEmptyPage() { + Pageable pageable = new PageRequest(0, 10); + assertEquals(0, actorStateService.findAllByActor(-1L, pageable).getTotalElements()); + } + + @Test + public void findActorStateByArticle_whenArticleNotExists_shouldExist() { + assertFalse(actorStateService.findForActorByArticle(1L, -1L).isPresent()); + } + + @Test + public void createActorState_whenAlreadyExist_shouldCreateId() { + final Long ARTICLE_ID = 1L; + final Long ACTOR_ID = 1L; + + Actor actor = actorService.findById(ACTOR_ID).get(); + ActorState actorState = buildActorState(ACTOR_ID, ARTICLE_ID); + actor.getActorStates().add(actorState); + actorService.update(ACTOR_ID, ActorDto.of(actor)); + + assertNotNull(actorStateService.findForActorByArticle(ACTOR_ID, ARTICLE_ID)); + } + + @Test + public void deleteActorState_whenCorrect_shouldNotFoundAfterDelete() { + final Long ARTICLE_ID = 2L; + final Long ACTOR_ID = 2L; + ActorStateId actorStateId = ActorStateId.builder().actorId(ACTOR_ID).articleId(ARTICLE_ID).build(); + + Optional actorState = actorStateService.findById(actorStateId); + assertTrue(actorState.isPresent()); + + actorStateService.delete(actorState.get()); + + assertFalse(actorStateService.findById(actorStateId).isPresent()); + } + + @Test(expected = EmptyResultDataAccessException.class) + public void deleteActorState_whenIdNotExist_should() { + final Long ARTICLE_ID = 2L; + final Long ACTOR_ID = -2L; + + ActorStateId actorStateId = ActorStateId.builder() + .actorId(ACTOR_ID) + .articleId(ARTICLE_ID) + .build(); + + actorStateService.deleteById(actorStateId); + } +} \ No newline at end of file diff --git a/src/test/java/fic/writer/domain/service/ArticleServiceTest.java b/src/test/java/fic/writer/domain/service/ArticleServiceTest.java new file mode 100644 index 0000000..9c52f6f --- /dev/null +++ b/src/test/java/fic/writer/domain/service/ArticleServiceTest.java @@ -0,0 +1,54 @@ +package fic.writer.domain.service; + +import fic.writer.domain.entity.Article; +import fic.writer.domain.entity.dto.ArticleDto; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.Date; + +import static org.junit.Assert.*; + +@RunWith(SpringRunner.class) +@SpringBootTest +@EnableJpaAuditing +public class ArticleServiceTest { + @Autowired + private ArticleService articleService; + + + @Test + public void updateArticle_whenUpdateTitle_shouldChangeTitle() { + final Long ARTICLE_ID = 3L; + final String NEW_TITLE = "new title"; + + ArticleDto articleDto = ArticleDto.builder().title(NEW_TITLE).build(); + articleService.update(ARTICLE_ID, articleDto); + Article article = articleService.findById(ARTICLE_ID).get(); + assertEquals(NEW_TITLE, article.getTitle()); + } + + @Test + public void updateArticle_whenUpdateTitle_shouldChangeUpdateDate() { + final Long ARTICLE_ID = 4L; + final String NEW_TITLE = "new title"; + Date prevUpdateDate = articleService.findById(ARTICLE_ID).get().getLastModify(); + + ArticleDto articleDto = ArticleDto.builder().title(NEW_TITLE).build(); + articleService.update(ARTICLE_ID, articleDto); + Article article = articleService.findById(ARTICLE_ID).get(); + assertNotEquals(prevUpdateDate, article.getLastModify()); + } + + @Test + public void deleteArticle_whenExist_shouldNotFoundById() { + final Long ARTICLE_ID = 333L; + articleService.deleteById(ARTICLE_ID); + assertFalse(articleService.findById(ARTICLE_ID).isPresent()); + } + +} \ No newline at end of file diff --git a/src/test/java/fic/writer/domain/service/BookAndArticleServicesTest.java b/src/test/java/fic/writer/domain/service/BookAndArticleServicesTest.java new file mode 100644 index 0000000..3b2b564 --- /dev/null +++ b/src/test/java/fic/writer/domain/service/BookAndArticleServicesTest.java @@ -0,0 +1,56 @@ +package fic.writer.domain.service; + +import fic.writer.domain.entity.Article; +import fic.writer.domain.entity.Book; +import fic.writer.domain.entity.dto.ArticleDto; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.transaction.annotation.Transactional; + +import static org.junit.Assert.*; + +@RunWith(SpringRunner.class) +@SpringBootTest +@EnableJpaAuditing +@Transactional +public class BookAndArticleServicesTest { + @Autowired + private ArticleService articleService; + @Autowired + private BookService bookService; + + @Test + public void createArticle_shouldFindByGeneratedId() { + final Long BOOK_ID = 1L; + Article article = Article.builder().build(); + bookService.addArticle(BOOK_ID, ArticleDto.of(article)); + + Book book = bookService.findById(BOOK_ID).get(); + book.getArticles().forEach(art -> assertTrue(articleService.findById(art.getId()).isPresent())); + } + + @Test + public void createArticle_shouldGenerateCreatedDate() { + final Long BOOK_ID = 1L; + Article article = Article.builder().build(); + bookService.addArticle(BOOK_ID, ArticleDto.of(article)); + + Book book = bookService.findById(BOOK_ID).get(); + book.getArticles().forEach(art -> assertNotNull(art.getCreated())); + } + + @Test + public void removeArticle_shouldGenerateCreatedDate() { + final Long BOOK_ID = 334L; + Book book = bookService.findById(BOOK_ID).get(); + + Long articleId = book.getArticles().stream().findFirst().get().getId(); + book = bookService.removeArticle(BOOK_ID, articleId); + + book.getArticles().forEach(art -> assertNotEquals(articleId, art.getId())); + } +} diff --git a/src/test/java/fic/writer/domain/service/BookServiceTest.java b/src/test/java/fic/writer/domain/service/BookServiceTest.java new file mode 100644 index 0000000..279574c --- /dev/null +++ b/src/test/java/fic/writer/domain/service/BookServiceTest.java @@ -0,0 +1,69 @@ +package fic.writer.domain.service; + +import fic.writer.domain.entity.Book; +import fic.writer.domain.entity.dto.BookDto; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.junit.Assert.*; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class BookServiceTest { + @Autowired + private BookService bookService; + + @Test + public void createBook_shouldChangeCount() { + final int SIZE_BEFORE = bookService.findAll().size(); + Book emptyBook = Book.builder().build(); + bookService.create(BookDto.of(emptyBook)); + + assertNotEquals(SIZE_BEFORE, bookService.findAll().size()); + } + + @Test + public void createBook_whenTitleIsCyrillic_shouldFindByGeneratedId() { + final String TITLE = "Заголовок"; + final long CURRENT_COUNT = 1L; + Book emptyBook = Book.builder().title(TITLE).build(); + bookService.create(BookDto.of(emptyBook)); + + assertEquals(CURRENT_COUNT, bookService.findAll().stream().filter(book -> book.getTitle().equals(TITLE)).count()); + } + + @Test + public void findBook_whenContainSizeEnum_shouldConvertToNotNullSize() { + final Long BOOK_ID = 3L; + Book book = bookService.findById(BOOK_ID).get(); + + assertNotNull(book.getSize()); + } + + @Test + public void findBook_whenContainStateEnum_shouldConvertToNotNullState() { + final Long BOOK_ID = 4L; + Book book = bookService.findById(BOOK_ID).get(); + + assertNotNull(book.getState()); + } + + @Test + public void deletedBook_whenExist_shouldNotFound() { + final Long DELETE_BOOK_ID = 333L; + bookService.deleteById(DELETE_BOOK_ID); + + assertNotNull(bookService.findById(DELETE_BOOK_ID)); + } + + @Test(expected = EmptyResultDataAccessException.class) + public void deletedBook_whenNotExist_shouldThorwException() { + final Long DELETE_BOOK_ID = -1L; + bookService.deleteById(DELETE_BOOK_ID); + } + +} \ No newline at end of file diff --git a/src/test/java/fic/writer/domain/service/UserServiceTest.java b/src/test/java/fic/writer/domain/service/UserServiceTest.java new file mode 100644 index 0000000..2dc5473 --- /dev/null +++ b/src/test/java/fic/writer/domain/service/UserServiceTest.java @@ -0,0 +1,42 @@ +package fic.writer.domain.service; + +import fic.writer.domain.entity.dto.UserDto; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.junit.Assert.*; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class UserServiceTest { + @Autowired + private UserService userService; + + @Test + public void createUser() { + final String USERNAME = "createTestUser"; + UserDto user = UserDto.builder().username(USERNAME).build(); + userService.create(user); + assertTrue(userService.findAll().stream().anyMatch(u -> u.getUsername().equals(USERNAME))); + } + + @Test + public void deleteUser() { + final Long USER_ID = 123L; + assertTrue(userService.findById(USER_ID).isPresent()); + userService.deleteById(USER_ID); + assertFalse(userService.findById(USER_ID).isPresent()); + } + + @Test + public void updateUser_whenUpdateAbout_shouldChangeAbout() { + final Long USER_ID = 1L; + final String NEW_ABOUT = "new about"; + UserDto userDto = UserDto.builder().about(NEW_ABOUT).build(); + userService.update(USER_ID, userDto); + assertEquals(NEW_ABOUT, userService.findById(USER_ID).get().getAbout()); + } +} \ No newline at end of file diff --git a/src/test/java/fic/writer/web/controller/UserControllerTest.java b/src/test/java/fic/writer/web/controller/UserControllerTest.java new file mode 100644 index 0000000..3c2eb61 --- /dev/null +++ b/src/test/java/fic/writer/web/controller/UserControllerTest.java @@ -0,0 +1,133 @@ +package fic.writer.web.controller; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.ObjectMapper; +import fic.writer.domain.entity.User; +import fic.writer.domain.entity.dto.UserDto; +import fic.writer.domain.service.UserService; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@WebMvcTest(value = UserController.class, secure = false) +public class UserControllerTest { + private static final String USERS_PATH = "/users"; + private static final String USER_ID_PATH_TEMPLATE = USERS_PATH + "/{id}"; + @Autowired + private UserController userController; + @Autowired + private MockMvc mockMvc; + @MockBean + private UserService userService; + + + @Test + public void getUsers_whenDtoIsEmpty_shouldReturnOk() throws Exception { + List userList = new ArrayList<>(); + User user = new User(); + user.setId(1L); + user.setUsername("testUsername"); + userList.add(user); + Mockito.when(userService.findAll()).thenReturn(userList); + + mockMvc.perform(get(USERS_PATH)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.[0].username").value(user.getUsername())) + .andExpect(jsonPath("$.[0].links.[0].rel").value("self")); + } + + @Test + public void getUserById_whenUserExists_shouldReturnOk() throws Exception { + final long ID = 1L; + User user = new User(); + user.setId(ID); + user.setUsername("testUsername"); + + Mockito.when(userService.findById(1L)).thenReturn(Optional.of(user)); + + mockMvc.perform(get(USER_ID_PATH_TEMPLATE, ID)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.username").value(user.getUsername())) + .andExpect(jsonPath("$._links.self").hasJsonPath()); + } + + @Test + public void createUser() throws Exception { + final Long USER_ID = 1L; + final String username = "testUsername", about = "about", information = "inform"; + UserDto dto = new UserDto(username, about, information); + ObjectMapper mapper = new ObjectMapper(); + + User user = User.builder() + .id(USER_ID) + .username(username) + .about(about) + .information(information) + .booksAsAuthor(new HashSet<>()) + .booksAsSubAuthor(new HashSet<>()) + .build(); + + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + String body = mapper.writeValueAsString(dto); + Mockito.when(userService.create(any(UserDto.class))).thenReturn(user); + + mockMvc.perform(post(USERS_PATH) + .content(body) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$.username").value(user.getUsername())) + .andExpect(jsonPath("$._links.self").hasJsonPath()); + } + + @Test + public void updateUser() throws Exception { + final Long USER_ID = 1L; + final String NEW_USERNAME = "testUsername"; + User updatedUser = User.builder() + .id(USER_ID) + .username(NEW_USERNAME) + .booksAsAuthor(new HashSet<>()) + .booksAsSubAuthor(new HashSet<>()) + .build(); + UserDto dto = new UserDto(NEW_USERNAME, null, null); + ObjectMapper mapper = new ObjectMapper(); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + String body = mapper.writeValueAsString(dto); + + Mockito.when(userService.update(anyLong(), any(UserDto.class))).thenReturn(updatedUser); + + mockMvc.perform(put(USER_ID_PATH_TEMPLATE, USER_ID) + .content(body) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.username").value(updatedUser.getUsername())) + .andExpect(jsonPath("$._links.self").hasJsonPath()); + + } + + @Test + public void deleteUser() throws Exception { + final long ID = 1L; + + mockMvc.perform(delete(USER_ID_PATH_TEMPLATE, ID)) + .andExpect(status().isNoContent()); + } +} \ No newline at end of file diff --git a/src/test/resources/application-db-h2.yml b/src/test/resources/application-db-h2.yml new file mode 100644 index 0000000..ced131b --- /dev/null +++ b/src/test/resources/application-db-h2.yml @@ -0,0 +1,13 @@ +spring: + datasource: + url: jdbc:h2:mem:testdb + driverClassName: org.h2.Driver + username: sa + password: + jpa: + properties: + hibernate: + dialect: org.hibernate.dialect.H2Dialect + h2: + console: + enabled: true \ No newline at end of file diff --git a/src/test/resources/application-db-mysql.yml b/src/test/resources/application-db-mysql.yml new file mode 100644 index 0000000..68c4a70 --- /dev/null +++ b/src/test/resources/application-db-mysql.yml @@ -0,0 +1,12 @@ +spring: + datasource: + url: jdbc:mysql://localhost:3306/ficwriter-test + username: dl + password: p@ssword + initialization-mode: always + jpa: + hibernate: + ddl-auto: create-drop + properties: + hibernate: + dialect: org.hibernate.dialect.MySQL5InnoDBDialect \ No newline at end of file diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml new file mode 100644 index 0000000..5828953 --- /dev/null +++ b/src/test/resources/application.yml @@ -0,0 +1,15 @@ +spring: + profiles: + active: db-mysql + jpa: + hibernate: + ddl-auto: create-drop + properties: + hibernate: + hbm2ddl: + import_files: data/user.sql, data/actor.sql, data/book.sql, data/article.sql, data/book_article.sql, data/actor_state.sql +logging: + level: + org: + springframework: INFO + diff --git a/src/test/resources/data/actor.sql b/src/test/resources/data/actor.sql new file mode 100644 index 0000000..bb9597c --- /dev/null +++ b/src/test/resources/data/actor.sql @@ -0,0 +1,10 @@ +INSERT INTO actor(id,description,name)VALUES(1,'description1','name1'); +INSERT INTO actor(id,description,name)VALUES(2,'description2','name2'); +INSERT INTO actor(id,description,name)VALUES(3,'description3','name3'); +INSERT INTO actor(id,description,name)VALUES(987,'description','name'); +INSERT INTO actor(id,description,name)VALUES(333,'description','name'); +INSERT INTO actor(id,description,name)VALUES(334,'description','name'); + + + + diff --git a/src/test/resources/data/actor_state.sql b/src/test/resources/data/actor_state.sql new file mode 100644 index 0000000..6e99aca --- /dev/null +++ b/src/test/resources/data/actor_state.sql @@ -0,0 +1,7 @@ +INSERT INTO actor_state(content,title,actor_id,article_id)VALUES('content1','title1',1,1); +INSERT INTO actor_state(content,title,actor_id,article_id)VALUES('content2','title2',1,2); +INSERT INTO actor_state(content,title,actor_id,article_id)VALUES('content3','title3',2,1); +INSERT INTO actor_state(content,title,actor_id,article_id)VALUES('content4','title4',2,2); + +INSERT INTO actor_state(content,title,actor_id,article_id)VALUES('content4','title4',333,3); +INSERT INTO actor_state(content,title,actor_id,article_id)VALUES('content4','title4',334,3); \ No newline at end of file diff --git a/src/test/resources/data/article.sql b/src/test/resources/data/article.sql new file mode 100644 index 0000000..3ca4a6e --- /dev/null +++ b/src/test/resources/data/article.sql @@ -0,0 +1,12 @@ +INSERT INTO article(id,annotation,content,title)VALUES(1,'annotation1','content1','title1'); +INSERT INTO article(id,annotation,content,title)VALUES(2,'annotation2','content2','title2'); +INSERT INTO article(id,annotation,content,title)VALUES(3,'annotation','content','title'); +INSERT INTO article(id,annotation,content,title)VALUES(4,'annotation','content','title'); +INSERT INTO article(id,annotation,content,title)VALUES(333,'annotation','content','delete article'); +INSERT INTO article(id,annotation,content,title)VALUES(334,'annotation','content','delete article'); + +INSERT INTO article(id,annotation,content,title,book_id)VALUES(5,'Place for annotation','

Place for content.

','Summer inspiration',335); +INSERT INTO article(id,annotation,content,title,book_id)VALUES(6,'Place for annotation','

Place for content.

','Summer inspiration#2',335); +INSERT INTO article(id,annotation,content,title,book_id)VALUES(7,'Place for annotation','

Place for content.

','Summer #3',335); +INSERT INTO article(id,annotation,content,title,book_id)VALUES(8,'Place for annotation','

Place for content.

','Winrte',335); + diff --git a/src/test/resources/data/book.sql b/src/test/resources/data/book.sql new file mode 100644 index 0000000..b3adcdc --- /dev/null +++ b/src/test/resources/data/book.sql @@ -0,0 +1,15 @@ +INSERT INTO book(id,title)VALUES(1,'book title'); +INSERT INTO book(id,title,description)VALUES(2,'book title','description'); +INSERT INTO book(id,title,size)VALUES(3,'book title',1); +INSERT INTO book(id,title,state)VALUES(4,'book title',1); +INSERT INTO book(id,title)VALUES(5,'book title'); +INSERT INTO book(id,title)VALUES(333,'delete book'); +INSERT INTO book(id,title)VALUES(334,'Книга для удаления'); + +INSERT INTO book(id,title,description, size, state,author_id)VALUES(335,'Arabella','Artic monkeys', 1,2,3); +INSERT INTO user_books_as_author (user_id,books_as_author_id)VALUES(3,335); +INSERT INTO book_subauthors (user_id,book_id)VALUES(4,335); + + + + diff --git a/src/test/resources/data/book_article.sql b/src/test/resources/data/book_article.sql new file mode 100644 index 0000000..7cf2f23 --- /dev/null +++ b/src/test/resources/data/book_article.sql @@ -0,0 +1,5 @@ +INSERT INTO book_articles(book_id,articles_id)VALUES(334,334); +INSERT INTO book_articles(book_id,articles_id)VALUES(335,5); +INSERT INTO book_articles(book_id,articles_id)VALUES(335,6); +INSERT INTO book_articles(book_id,articles_id)VALUES(335,7); +INSERT INTO book_articles(book_id,articles_id)VALUES(335,8); \ No newline at end of file diff --git a/src/test/resources/data/user.sql b/src/test/resources/data/user.sql new file mode 100644 index 0000000..dd5d16b --- /dev/null +++ b/src/test/resources/data/user.sql @@ -0,0 +1,4 @@ +INSERT INTO user(id,username)VALUES(123,'delete user'); +INSERT INTO user(id,username)VALUES(1,'test user'); +INSERT INTO user(id,username)VALUES(3,'Bella'); +INSERT INTO user(id,username)VALUES(4,'Bella junior'); \ No newline at end of file