diff --git a/.Postman/Stats-server.postman_collection.json b/.Postman/Stats-server.postman_collection.json deleted file mode 100644 index 8aeb528..0000000 --- a/.Postman/Stats-server.postman_collection.json +++ /dev/null @@ -1,464 +0,0 @@ -{ - "info": { - "_postman_id": "9866b6dd-6e16-4941-99ec-dadd50444c62", - "name": "Stats-server", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", - "_exporter_id": "23645999" - }, - "item": [ - { - "name": "Корректное добавление статистики", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test(\"Ответ должен содержать код статуса 200\", function() {\r", - " pm.response.to.be.ok;\r", - "}); " - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - }, - { - "key": "Accept", - "value": "*/*", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"app\": \"ewm-main-service\",\r\n \"uri\": \"/events/1\",\r\n \"ip\": \"192.163.0.1\",\r\n \"timestamp\": \"2022-09-06 11:00:23\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/hit", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "hit" - ] - } - }, - "response": [] - }, - { - "name": "Корректное добавление статистики Copy", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test(\"Ответ должен содержать код статуса 200\", function() {\r", - " pm.response.to.be.ok;\r", - "}); " - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - }, - { - "key": "Accept", - "value": "*/*", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"app\": \"ewm-main-service\",\r\n \"uri\": \"/events/1\",\r\n \"ip\": \"192.163.0.1\",\r\n \"timestamp\": \"2022-09-06 11:00:23\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/hit", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "hit" - ] - } - }, - "response": [] - }, - { - "name": "Отсутствует app", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test(\"Status code is 400\", function () {\r", - " pm.expect(pm.response.code).to.be.oneOf([400]);\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"app\": \"\",\r\n \"uri\": \"/events/1\",\r\n \"ip\": \"192.163.0.1\",\r\n \"timestamp\": \"2022-09-06 11:00:23\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/hit", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "hit" - ] - } - }, - "response": [] - }, - { - "name": "Отсутствует uri", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test(\"Status code is 400\", function () {\r", - " pm.expect(pm.response.code).to.be.oneOf([400]);\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"app\": \"ewm-main-service\",\r\n \"uri\": \"\",\r\n \"ip\": \"192.163.0.1\",\r\n \"timestamp\": \"2022-09-06 11:00:23\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/hit", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "hit" - ] - } - }, - "response": [] - }, - { - "name": "Отсутствует ip", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test(\"Status code is 400\", function () {\r", - " pm.expect(pm.response.code).to.be.oneOf([400]);\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"app\": \"ewm-main-service\",\r\n \"uri\": \"/events/1\",\r\n \"ip\": \"\",\r\n \"timestamp\": \"2022-09-06 11:00:23\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/hit", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "hit" - ] - } - }, - "response": [] - }, - { - "name": "Отсутствует timestamp", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test(\"Status code is 400\", function () {\r", - " pm.expect(pm.response.code).to.be.oneOf([400]);\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\r\n \"app\": \"ewm-main-service\",\r\n \"uri\": \"/events/1\",\r\n \"ip\": \"192.163.0.1\",\r\n \"timestamp\": \"\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/hit", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "hit" - ] - } - }, - "response": [] - }, - { - "name": "Корректное добавление статистики 3", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test(\"Ответ должен содержать код статуса 200\", function() {\r", - " pm.response.to.be.ok;\r", - "}); " - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"app\": \"ewm-main-service\",\r\n \"uri\": \"/events/3\",\r\n \"ip\": \"192.163.0.1\",\r\n \"timestamp\": \"2022-09-06 11:00:23\"\r\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{baseUrl}}/hit", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "hit" - ] - } - }, - "response": [] - }, - { - "name": "Список статистики", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "pm.test(\"Status code is 200\", function () {\r", - " pm.expect(pm.response.code).to.be.oneOf([200]);\r", - "});\r", - "pm.test(\"Test get all\", function () {\r", - " var jsonData = pm.response.json();\r", - " pm.expect(jsonData.length, 'items count in total').to.eql(2);\r", - " pm.expect(jsonData[0].hits, 'result[0]: \"hits\" field').to.eql(2);\r", - " pm.expect(jsonData[1].hits, 'result[1]: \"hits\" field').to.eql(1);\r", - "});" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{baseUrl}}/stats?start=2022-09-06 11:00:00&end=2022-09-06 12:00:00", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "stats" - ], - "query": [ - { - "key": "start", - "value": "2022-09-06 11:00:00" - }, - { - "key": "end", - "value": "2022-09-06 12:00:00" - }, - { - "key": "", - "value": null, - "disabled": true - } - ] - } - }, - "response": [] - }, - { - "name": "Список статистики c uri", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{baseUrl}}/stats?start=2022-09-06 11:00:00&end=2022-09-06 12:00:00&uri=/events/3&unique=false", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "stats" - ], - "query": [ - { - "key": "start", - "value": "2022-09-06 11:00:00" - }, - { - "key": "end", - "value": "2022-09-06 12:00:00" - }, - { - "key": "uri", - "value": "/events/3" - }, - { - "key": "unique", - "value": "false" - } - ] - } - }, - "response": [] - }, - { - "name": "Список статистики unique true", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{baseUrl}}/stats?start=2022-09-06 11:00:00&end=2022-09-06 12:00:00&uri=/events/3&unique=true", - "host": [ - "{{baseUrl}}" - ], - "path": [ - "stats" - ], - "query": [ - { - "key": "start", - "value": "2022-09-06 11:00:00" - }, - { - "key": "end", - "value": "2022-09-06 12:00:00" - }, - { - "key": "uri", - "value": "/events/3" - }, - { - "key": "unique", - "value": "true" - } - ] - } - }, - "response": [] - } - ], - "event": [ - { - "listen": "prerequest", - "script": { - "type": "text/javascript", - "exec": [ - "" - ] - } - }, - { - "listen": "test", - "script": { - "type": "text/javascript", - "exec": [ - "" - ] - } - } - ], - "variable": [ - { - "key": "baseUrl", - "value": "http://localhost:9090" - } - ] -} \ No newline at end of file diff --git a/README.md b/README.md index 18a246e..88e2636 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # java-explore-with-me Template repository for ExploreWithMe project. +--- +https://github.com/SugarFoxy/java-explore-with-me/pull/3 diff --git a/main-service/src/main/java/ru/practicum/category/dto/CategoryDto.java b/main-service/src/main/java/ru/practicum/category/dto/CategoryDto.java index 2a0f27b..05fb041 100644 --- a/main-service/src/main/java/ru/practicum/category/dto/CategoryDto.java +++ b/main-service/src/main/java/ru/practicum/category/dto/CategoryDto.java @@ -7,8 +7,6 @@ @Setter @Getter -@AllArgsConstructor -@NoArgsConstructor @Builder public class CategoryDto { private Long id; diff --git a/main-service/src/main/java/ru/practicum/category/dto/NewCategoryDto.java b/main-service/src/main/java/ru/practicum/category/dto/NewCategoryDto.java index 364e2d0..6447a91 100644 --- a/main-service/src/main/java/ru/practicum/category/dto/NewCategoryDto.java +++ b/main-service/src/main/java/ru/practicum/category/dto/NewCategoryDto.java @@ -9,7 +9,6 @@ @Getter @AllArgsConstructor @NoArgsConstructor -@Builder public class NewCategoryDto { @NotNull(message = "Название категории не может быть пустым") @NotBlank(message = "Название категории не может быть пустым") diff --git a/main-service/src/main/java/ru/practicum/category/mapper/CategoryMapper.java b/main-service/src/main/java/ru/practicum/category/mapper/CategoryMapper.java index 2f8cb81..3ffeadb 100644 --- a/main-service/src/main/java/ru/practicum/category/mapper/CategoryMapper.java +++ b/main-service/src/main/java/ru/practicum/category/mapper/CategoryMapper.java @@ -4,7 +4,11 @@ import ru.practicum.category.dto.NewCategoryDto; import ru.practicum.category.model.Category; -public class CategoryMapper { +public final class CategoryMapper { + private CategoryMapper() { + + } + public static Category toCategory(NewCategoryDto dto) { return Category.builder() .name(dto.getName()) diff --git a/main-service/src/main/java/ru/practicum/events/comments/controller/ControllerPrivateComment.java b/main-service/src/main/java/ru/practicum/events/comments/controller/ControllerPrivateComment.java new file mode 100644 index 0000000..a2050d3 --- /dev/null +++ b/main-service/src/main/java/ru/practicum/events/comments/controller/ControllerPrivateComment.java @@ -0,0 +1,57 @@ +package ru.practicum.events.comments.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; +import ru.practicum.events.comments.dto.InCommentDto; +import ru.practicum.events.comments.dto.OutCommentDto; +import ru.practicum.events.comments.service.CommentPrivateService; +import ru.practicum.util.exception.handler.CustomExceptionHandler; + +@RestController +@RequestMapping("/users/{userId}/comments") +@CustomExceptionHandler +public class ControllerPrivateComment { + private final CommentPrivateService service; + + @Autowired + public ControllerPrivateComment(CommentPrivateService service) { + this.service = service; + } + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public OutCommentDto createComment(@PathVariable Long userId, + @RequestBody InCommentDto dto) { + return service.createComment(userId, dto); + } + + @PatchMapping("/{commentId}") + public OutCommentDto updateComment(@PathVariable Long userId, + @PathVariable Long commentId, + @RequestBody InCommentDto dto) { + return service.updateComment(userId, commentId, dto); + } + + @DeleteMapping("/{commentId}") + @ResponseStatus(HttpStatus.NO_CONTENT) + public void deleteComment(@PathVariable Long userId, + @PathVariable Long commentId) { + service.deleteComment(userId, commentId); + } + + @PostMapping("/{commentId}/like") + @ResponseStatus(HttpStatus.CREATED) + public OutCommentDto leaveRating(@PathVariable Long userId, + @PathVariable Long commentId, + @RequestParam Boolean grade) { + return service.leaveRating(userId, commentId, grade); + } + + @DeleteMapping("/{commentId}/like") + @ResponseStatus(HttpStatus.NO_CONTENT) + public void deleteRating(@PathVariable Long userId, + @PathVariable Long commentId) { + service.deleteRating(userId, commentId); + } +} diff --git a/main-service/src/main/java/ru/practicum/events/comments/controller/ControllerPublicComment.java b/main-service/src/main/java/ru/practicum/events/comments/controller/ControllerPublicComment.java new file mode 100644 index 0000000..ba27960 --- /dev/null +++ b/main-service/src/main/java/ru/practicum/events/comments/controller/ControllerPublicComment.java @@ -0,0 +1,35 @@ +package ru.practicum.events.comments.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import ru.practicum.events.comments.dto.OutCommentDto; +import ru.practicum.events.comments.service.CommentPublicService; +import ru.practicum.util.exception.handler.CustomExceptionHandler; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Positive; +import javax.validation.constraints.PositiveOrZero; +import java.util.List; + +@RestController +@RequestMapping("/comment") +@CustomExceptionHandler +public class ControllerPublicComment { + private final CommentPublicService service; + + @Autowired + public ControllerPublicComment(CommentPublicService service) { + this.service = service; + } + + @GetMapping + public List getCommentByEvent(@NotNull @RequestParam Long eventId, + @RequestParam(defaultValue = "false") Boolean rating, + @PositiveOrZero @RequestParam(defaultValue = "0") Integer from, + @Positive @RequestParam(defaultValue = "10") Integer size) { + return service.getCommentByEvent(eventId, rating, from, size); + } +} diff --git a/main-service/src/main/java/ru/practicum/events/comments/dto/InCommentDto.java b/main-service/src/main/java/ru/practicum/events/comments/dto/InCommentDto.java new file mode 100644 index 0000000..dacc62f --- /dev/null +++ b/main-service/src/main/java/ru/practicum/events/comments/dto/InCommentDto.java @@ -0,0 +1,17 @@ +package ru.practicum.events.comments.dto; + +import lombok.*; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +@Setter +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class InCommentDto { + @NotNull + @NotBlank + private String text; + private Long eventId; +} diff --git a/main-service/src/main/java/ru/practicum/events/comments/dto/OutCommentDto.java b/main-service/src/main/java/ru/practicum/events/comments/dto/OutCommentDto.java new file mode 100644 index 0000000..1d4aec6 --- /dev/null +++ b/main-service/src/main/java/ru/practicum/events/comments/dto/OutCommentDto.java @@ -0,0 +1,17 @@ +package ru.practicum.events.comments.dto; + +import lombok.*; +import ru.practicum.users.dto.UserShortDto; + +import java.time.LocalDateTime; + +@Setter +@Getter +@Builder +public class OutCommentDto { + private Long id; + private UserShortDto commentator; + private String text; + private LocalDateTime commentTime; + private Long rating; +} diff --git a/main-service/src/main/java/ru/practicum/events/comments/mapper/CommentMapper.java b/main-service/src/main/java/ru/practicum/events/comments/mapper/CommentMapper.java new file mode 100644 index 0000000..6ec697a --- /dev/null +++ b/main-service/src/main/java/ru/practicum/events/comments/mapper/CommentMapper.java @@ -0,0 +1,44 @@ +package ru.practicum.events.comments.mapper; + +import ru.practicum.events.comments.dto.InCommentDto; +import ru.practicum.events.comments.dto.OutCommentDto; +import ru.practicum.events.comments.model.Comment; +import ru.practicum.events.event.model.Event; +import ru.practicum.users.mapper.UserMapper; +import ru.practicum.users.model.User; + +import java.time.LocalDateTime; + +public final class CommentMapper { + private CommentMapper() { + + } + + public static OutCommentDto toDto(Comment comment) { + return OutCommentDto.builder() + .commentator(UserMapper.toShortDto(comment.getCommentator())) + .commentTime(comment.getCommentTime()) + .id(comment.getId()) + .text(comment.getText()) + .build(); + } + + public static OutCommentDto toDto(Comment comment, Long rating) { + return OutCommentDto.builder() + .commentator(UserMapper.toShortDto(comment.getCommentator())) + .commentTime(comment.getCommentTime()) + .id(comment.getId()) + .text(comment.getText()) + .rating(rating) + .build(); + } + + public static Comment toComment(InCommentDto dto, LocalDateTime time, User commentator, Event event) { + return Comment.builder() + .commentator(commentator) + .text(dto.getText()) + .commentTime(time) + .event(event) + .build(); + } +} diff --git a/main-service/src/main/java/ru/practicum/events/comments/model/Comment.java b/main-service/src/main/java/ru/practicum/events/comments/model/Comment.java new file mode 100644 index 0000000..a7f222d --- /dev/null +++ b/main-service/src/main/java/ru/practicum/events/comments/model/Comment.java @@ -0,0 +1,31 @@ +package ru.practicum.events.comments.model; + +import lombok.*; +import ru.practicum.events.event.model.Event; +import ru.practicum.users.model.User; + +import javax.persistence.*; +import java.time.LocalDateTime; + +@Setter +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Entity +@Table(name = "comments") +public class Comment { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + @Column(name = "comment_text") + private String text; + @ManyToOne() + @JoinColumn(name = "user_id") + private User commentator; + @ManyToOne() + @JoinColumn(name = "event_id") + private Event event; + @Column(name = "comment_time") + private LocalDateTime commentTime; +} diff --git a/main-service/src/main/java/ru/practicum/events/comments/rating/model/Grade.java b/main-service/src/main/java/ru/practicum/events/comments/rating/model/Grade.java new file mode 100644 index 0000000..1c7baae --- /dev/null +++ b/main-service/src/main/java/ru/practicum/events/comments/rating/model/Grade.java @@ -0,0 +1,27 @@ +package ru.practicum.events.comments.rating.model; + +import lombok.*; +import ru.practicum.events.comments.model.Comment; +import ru.practicum.users.model.User; + +import javax.persistence.*; + +@Setter +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Entity +@Table(name = "rating") +public class Grade { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + @ManyToOne() + @JoinColumn(name = "user_id") + private User rater; + @ManyToOne() + @JoinColumn(name = "comment_id") + private Comment comment; + private Boolean grade; +} diff --git a/main-service/src/main/java/ru/practicum/events/comments/rating/storage/RatingRepository.java b/main-service/src/main/java/ru/practicum/events/comments/rating/storage/RatingRepository.java new file mode 100644 index 0000000..16c86f4 --- /dev/null +++ b/main-service/src/main/java/ru/practicum/events/comments/rating/storage/RatingRepository.java @@ -0,0 +1,14 @@ +package ru.practicum.events.comments.rating.storage; + +import org.springframework.data.jpa.repository.JpaRepository; +import ru.practicum.events.comments.model.Comment; +import ru.practicum.events.comments.rating.model.Grade; +import ru.practicum.users.model.User; + +public interface RatingRepository extends JpaRepository { + Long countGradeByCommentAndGrade(Comment comment, Boolean grade); + + Boolean existsByCommentAndRater(Comment comment, User rater); + + void deleteByCommentAndRater(Comment comment, User user); +} diff --git a/main-service/src/main/java/ru/practicum/events/comments/service/CommentPrivateService.java b/main-service/src/main/java/ru/practicum/events/comments/service/CommentPrivateService.java new file mode 100644 index 0000000..8c0457b --- /dev/null +++ b/main-service/src/main/java/ru/practicum/events/comments/service/CommentPrivateService.java @@ -0,0 +1,16 @@ +package ru.practicum.events.comments.service; + +import ru.practicum.events.comments.dto.InCommentDto; +import ru.practicum.events.comments.dto.OutCommentDto; + +public interface CommentPrivateService { + OutCommentDto createComment(Long userId, InCommentDto dto); + + OutCommentDto updateComment(Long userId, Long commentId, InCommentDto dto); + + void deleteComment(Long userId, Long commentId); + + OutCommentDto leaveRating(Long userId, Long commentId, Boolean grade); + + void deleteRating(Long userId, Long commentId); +} diff --git a/main-service/src/main/java/ru/practicum/events/comments/service/CommentPrivateServiceImpl.java b/main-service/src/main/java/ru/practicum/events/comments/service/CommentPrivateServiceImpl.java new file mode 100644 index 0000000..15340b8 --- /dev/null +++ b/main-service/src/main/java/ru/practicum/events/comments/service/CommentPrivateServiceImpl.java @@ -0,0 +1,106 @@ +package ru.practicum.events.comments.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import ru.practicum.events.comments.dto.InCommentDto; +import ru.practicum.events.comments.dto.OutCommentDto; +import ru.practicum.events.comments.mapper.CommentMapper; +import ru.practicum.events.comments.model.Comment; +import ru.practicum.events.comments.rating.model.Grade; +import ru.practicum.events.comments.rating.storage.RatingRepository; +import ru.practicum.events.comments.storage.CommentRepository; +import ru.practicum.events.event.model.Event; +import ru.practicum.users.model.User; +import ru.practicum.util.RepositoryObjectCreator; +import ru.practicum.util.exception.BadRequestException; +import ru.practicum.util.exception.ConflictException; + +import java.time.LocalDateTime; + +@Service +public class CommentPrivateServiceImpl implements CommentPrivateService { + private final CommentRepository commentRepository; + private final RepositoryObjectCreator objectCreator; + private final RatingRepository ratingRepository; + + @Autowired + public CommentPrivateServiceImpl(CommentRepository commentRepository, + RepositoryObjectCreator objectCreator, + RatingRepository ratingRepository) { + this.commentRepository = commentRepository; + this.objectCreator = objectCreator; + this.ratingRepository = ratingRepository; + } + + @Override + public OutCommentDto createComment(Long userId, InCommentDto dto) { + Event event = objectCreator.getEventById(dto.getEventId()); + if (!event.getCommentAvailable()) { + throw new ConflictException("Невозможно добавить комментарий! У события отключены комментарии!"); + } + return CommentMapper.toDto(commentRepository.save(CommentMapper.toComment( + dto, + LocalDateTime.now(), + objectCreator.getUserById(userId), + event) + )); + } + + @Override + public OutCommentDto updateComment(Long userId, Long commentId, InCommentDto dto) { + Comment comment = objectCreator.getCommentById(commentId); + + if (!comment.getCommentator().getId().equals(userId)) { + throw new BadRequestException(String + .format("Только комментатор может изменить коментарий id = %d ", commentId)); + } + if (!comment.getEvent().getId().equals(dto.getEventId())) { + throw new BadRequestException(String + .format("У события id = %d отсутствует коментарий id = %d", userId, commentId)); + } + + comment.setText(dto.getText()); + return CommentMapper.toDto(commentRepository.save(comment)); + } + + @Override + public void deleteComment(Long userId, Long commId) { + Comment comment = objectCreator.getCommentById(commId); + + if (!comment.getCommentator().getId().equals(userId)) { + throw new BadRequestException(String + .format("Только комментатор может удалить коментарий id = %d ", commId)); + } + commentRepository.deleteById(commId); + } + + @Override + public OutCommentDto leaveRating(Long userId, Long commentId, Boolean grade) { + if (ratingRepository + .existsByCommentAndRater(objectCreator.getCommentById(commentId), objectCreator.getUserById(userId))) { + throw new ConflictException("Отавить оценку комментарию можно один раз"); + } + ratingRepository.save(Grade.builder() + .comment(objectCreator.getCommentById(commentId)) + .rater(objectCreator.getUserById(userId)) + .grade(grade) + .build()); + Comment comment = objectCreator.getCommentById(commentId); + return CommentMapper.toDto(comment, ratingRepository.countGradeByCommentAndGrade(comment, true) + - ratingRepository.countGradeByCommentAndGrade(comment, false)); + } + + @Override + @Transactional + public void deleteRating(Long userId, Long commentId) { + Comment comment = objectCreator.getCommentById(commentId); + User user = objectCreator.getUserById(userId); + if (!ratingRepository.existsByCommentAndRater(comment, user)) { + throw new BadRequestException(String.format("Невозможно удалеть лайк! " + + "Пользователь id = %d не ставил оценку комментарию id = %d", userId, commentId)); + } + ratingRepository + .deleteByCommentAndRater(comment, user); + } +} diff --git a/main-service/src/main/java/ru/practicum/events/comments/service/CommentPublicService.java b/main-service/src/main/java/ru/practicum/events/comments/service/CommentPublicService.java new file mode 100644 index 0000000..14ce1bc --- /dev/null +++ b/main-service/src/main/java/ru/practicum/events/comments/service/CommentPublicService.java @@ -0,0 +1,9 @@ +package ru.practicum.events.comments.service; + +import ru.practicum.events.comments.dto.OutCommentDto; + +import java.util.List; + +public interface CommentPublicService { + List getCommentByEvent(Long eventId, Boolean rating, int from, int size); +} diff --git a/main-service/src/main/java/ru/practicum/events/comments/service/CommentPublicServiceImpl.java b/main-service/src/main/java/ru/practicum/events/comments/service/CommentPublicServiceImpl.java new file mode 100644 index 0000000..7a7a84b --- /dev/null +++ b/main-service/src/main/java/ru/practicum/events/comments/service/CommentPublicServiceImpl.java @@ -0,0 +1,58 @@ +package ru.practicum.events.comments.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import ru.practicum.events.comments.dto.OutCommentDto; +import ru.practicum.events.comments.mapper.CommentMapper; +import ru.practicum.events.comments.model.Comment; +import ru.practicum.events.comments.rating.storage.RatingRepository; +import ru.practicum.events.comments.storage.CommentRepository; +import ru.practicum.events.event.model.Event; +import ru.practicum.util.RepositoryObjectCreator; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.springframework.data.domain.Sort.Direction.DESC; + +@Service +public class CommentPublicServiceImpl implements CommentPublicService { + private final CommentRepository commentRepository; + private final RepositoryObjectCreator objectCreator; + private final RatingRepository ratingRepository; + + @Autowired + public CommentPublicServiceImpl(CommentRepository commentRepository, + RepositoryObjectCreator objectCreator, + RatingRepository ratingRepository) { + this.commentRepository = commentRepository; + this.objectCreator = objectCreator; + this.ratingRepository = ratingRepository; + } + + @Override + public List getCommentByEvent(Long eventId, Boolean rating, int from, int size) { + Event event = objectCreator.getEventById(eventId); + if (!event.getCommentAvailable()) { + return new ArrayList<>(); + } + Sort sort = Sort.by(DESC, "commentTime"); + List comments = commentRepository + .findByEvent(event, PageRequest.of(from, size, sort)); + Stream commentDtoStream = comments + .stream() + .map(comment -> CommentMapper + .toDto(comment, + ratingRepository.countGradeByCommentAndGrade(comment, true) + - ratingRepository.countGradeByCommentAndGrade(comment, false))); + if (rating) { + commentDtoStream = commentDtoStream.sorted(Comparator.comparingLong(OutCommentDto::getRating).reversed()); + } + return commentDtoStream.collect(Collectors.toList()); + } +} diff --git a/main-service/src/main/java/ru/practicum/events/comments/storage/CommentRepository.java b/main-service/src/main/java/ru/practicum/events/comments/storage/CommentRepository.java new file mode 100644 index 0000000..ea0028c --- /dev/null +++ b/main-service/src/main/java/ru/practicum/events/comments/storage/CommentRepository.java @@ -0,0 +1,12 @@ +package ru.practicum.events.comments.storage; + +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import ru.practicum.events.comments.model.Comment; +import ru.practicum.events.event.model.Event; + +import java.util.List; + +public interface CommentRepository extends JpaRepository { + List findByEvent(Event event, Pageable pageable); +} diff --git a/main-service/src/main/java/ru/practicum/events/compilation/controller/ControllerPublicCompilation.java b/main-service/src/main/java/ru/practicum/events/compilation/controller/ControllerPublicCompilation.java index 9b84cbf..c3c333b 100644 --- a/main-service/src/main/java/ru/practicum/events/compilation/controller/ControllerPublicCompilation.java +++ b/main-service/src/main/java/ru/practicum/events/compilation/controller/ControllerPublicCompilation.java @@ -23,8 +23,8 @@ public ControllerPublicCompilation(CompilationPublicService service) { @GetMapping public List getAllCompilations(@RequestParam(required = false) Boolean pinned, - @RequestParam(defaultValue = "0") int from, - @RequestParam(defaultValue = "10") int size) { + @RequestParam(defaultValue = "0") Integer from, + @RequestParam(defaultValue = "10") Integer size) { log.info("Получен запрос на получение подборок событий"); return service.getAllCompilations(pinned, from, size); } diff --git a/main-service/src/main/java/ru/practicum/events/compilation/dto/CompilationDto.java b/main-service/src/main/java/ru/practicum/events/compilation/dto/CompilationDto.java index 4a9c1c2..04dab08 100644 --- a/main-service/src/main/java/ru/practicum/events/compilation/dto/CompilationDto.java +++ b/main-service/src/main/java/ru/practicum/events/compilation/dto/CompilationDto.java @@ -7,8 +7,6 @@ @Setter @Getter -@NoArgsConstructor -@AllArgsConstructor @Builder public class CompilationDto { private Long id; diff --git a/main-service/src/main/java/ru/practicum/events/compilation/dto/NewCompilationDto.java b/main-service/src/main/java/ru/practicum/events/compilation/dto/NewCompilationDto.java index b8373a1..a8472fd 100644 --- a/main-service/src/main/java/ru/practicum/events/compilation/dto/NewCompilationDto.java +++ b/main-service/src/main/java/ru/practicum/events/compilation/dto/NewCompilationDto.java @@ -9,7 +9,6 @@ @Getter @AllArgsConstructor @NoArgsConstructor -@Builder public class NewCompilationDto { private List events; @NotNull(message = "pinned не может быть пустым") diff --git a/main-service/src/main/java/ru/practicum/events/compilation/dto/UpdateCompilationRequest.java b/main-service/src/main/java/ru/practicum/events/compilation/dto/UpdateCompilationRequest.java index f8f9771..04d3d9d 100644 --- a/main-service/src/main/java/ru/practicum/events/compilation/dto/UpdateCompilationRequest.java +++ b/main-service/src/main/java/ru/practicum/events/compilation/dto/UpdateCompilationRequest.java @@ -8,7 +8,6 @@ @Getter @AllArgsConstructor @NoArgsConstructor -@Builder public class UpdateCompilationRequest { private List events; private Boolean pinned; diff --git a/main-service/src/main/java/ru/practicum/events/compilation/mapper/CompilationMapper.java b/main-service/src/main/java/ru/practicum/events/compilation/mapper/CompilationMapper.java index 832b97d..212875d 100644 --- a/main-service/src/main/java/ru/practicum/events/compilation/mapper/CompilationMapper.java +++ b/main-service/src/main/java/ru/practicum/events/compilation/mapper/CompilationMapper.java @@ -10,7 +10,11 @@ import java.util.List; import java.util.stream.Collectors; -public class CompilationMapper { +public final class CompilationMapper { + private CompilationMapper() { + + } + public static Compilation toCompilation(NewCompilationDto compilationDto, List collect) { return Compilation.builder() .events(new HashSet<>(collect)) diff --git a/main-service/src/main/java/ru/practicum/events/event/controller/ControllerEventPrivate.java b/main-service/src/main/java/ru/practicum/events/event/controller/ControllerEventPrivate.java index 9d2bca9..22c919e 100644 --- a/main-service/src/main/java/ru/practicum/events/event/controller/ControllerEventPrivate.java +++ b/main-service/src/main/java/ru/practicum/events/event/controller/ControllerEventPrivate.java @@ -47,6 +47,14 @@ public EventFullDto updateEvent(@Positive @PathVariable Long userId, return service.update(userId, eventId, dto); } + @PatchMapping("/{eventId}/comment") + public EventFullDto enableComment(@Positive @PathVariable Long userId, + @Positive @PathVariable Long eventId, + @RequestParam(defaultValue = "false") Boolean disable) { + log.info("Получен запрос на вкдючение и выключении комментариев"); + return service.enableComment(userId, eventId, disable); + } + @GetMapping("/{eventId}") public EventFullDto getEventByIdWhereUserIsOwner(@Positive @PathVariable Long userId, @Positive @PathVariable Long eventId) { diff --git a/main-service/src/main/java/ru/practicum/events/event/dto/EventFullDto.java b/main-service/src/main/java/ru/practicum/events/event/dto/EventFullDto.java index 0ca97b7..5433c29 100644 --- a/main-service/src/main/java/ru/practicum/events/event/dto/EventFullDto.java +++ b/main-service/src/main/java/ru/practicum/events/event/dto/EventFullDto.java @@ -12,8 +12,6 @@ @Setter @Getter @Builder -@NoArgsConstructor -@AllArgsConstructor public class EventFullDto { private Long id; private String annotation; @@ -34,4 +32,5 @@ public class EventFullDto { private EventState state; private String title; private Long views; + private Boolean commentAvailable; } diff --git a/main-service/src/main/java/ru/practicum/events/event/dto/EventShortDto.java b/main-service/src/main/java/ru/practicum/events/event/dto/EventShortDto.java index 9cdaac5..c1f4e24 100644 --- a/main-service/src/main/java/ru/practicum/events/event/dto/EventShortDto.java +++ b/main-service/src/main/java/ru/practicum/events/event/dto/EventShortDto.java @@ -1,37 +1,26 @@ package ru.practicum.events.event.dto; import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.*; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; import ru.practicum.category.dto.CategoryDto; import ru.practicum.users.dto.UserShortDto; -import javax.validation.constraints.Future; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; import java.time.LocalDateTime; @Setter @Getter @Builder -@NoArgsConstructor -@AllArgsConstructor public class EventShortDto { private Long id; - @NotNull(message = "annotation не должно быть пустым") - @NotBlank(message = "annotation не должно быть пустым") private String annotation; - @NotNull(message = "category не должно быть пустым") private CategoryDto category; private Long confirmedRequests; @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss") - @Future() private LocalDateTime eventDate; - @NotNull(message = "initiator не должно быть пустым") private UserShortDto initiator; - @NotNull(message = "paid не должно быть пустым") private Boolean paid; - @NotNull(message = "title не должно быть пустым") - @NotBlank(message = "title не должно быть пустым") private String title; private Long views; } diff --git a/main-service/src/main/java/ru/practicum/events/event/dto/NewEventDto.java b/main-service/src/main/java/ru/practicum/events/event/dto/NewEventDto.java index bab074f..630b603 100644 --- a/main-service/src/main/java/ru/practicum/events/event/dto/NewEventDto.java +++ b/main-service/src/main/java/ru/practicum/events/event/dto/NewEventDto.java @@ -11,7 +11,6 @@ @Setter @Getter -@Builder @AllArgsConstructor @NoArgsConstructor public class NewEventDto { diff --git a/main-service/src/main/java/ru/practicum/events/event/dto/UpdateEventRequest.java b/main-service/src/main/java/ru/practicum/events/event/dto/UpdateEventRequest.java index a3c68b3..6ecd28d 100644 --- a/main-service/src/main/java/ru/practicum/events/event/dto/UpdateEventRequest.java +++ b/main-service/src/main/java/ru/practicum/events/event/dto/UpdateEventRequest.java @@ -13,7 +13,6 @@ @Setter @Getter -@Builder @NoArgsConstructor @AllArgsConstructor public class UpdateEventRequest { diff --git a/main-service/src/main/java/ru/practicum/events/event/mapper/EventMapper.java b/main-service/src/main/java/ru/practicum/events/event/mapper/EventMapper.java index 92276a0..75cb5d8 100644 --- a/main-service/src/main/java/ru/practicum/events/event/mapper/EventMapper.java +++ b/main-service/src/main/java/ru/practicum/events/event/mapper/EventMapper.java @@ -14,7 +14,11 @@ import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; -public class EventMapper { +public final class EventMapper { + private EventMapper() { + + } + public static EventShortDto toShortDto(Event event) { return EventShortDto.builder() .id(event.getId()) @@ -75,6 +79,7 @@ public static EventFullDto toEventFullDto(Event event) { .state(event.getState()) .title(event.getTitle()) .views(event.getViews()) + .commentAvailable(event.getCommentAvailable()) .build(); } @@ -114,6 +119,7 @@ public static Event toEvent(Event event, UpdateEventRequest eventRequest, Catego eventRequest.getTitle() : event.getTitle()) .views(event.getViews()) + .commentAvailable(event.getCommentAvailable()) .build(); } @@ -135,6 +141,7 @@ public static Event toEvent(EventFullDto eventDto, User initiator) { .state(eventDto.getState()) .title(eventDto.getTitle()) .views(eventDto.getViews()) + .commentAvailable(eventDto.getCommentAvailable()) .build(); } } diff --git a/main-service/src/main/java/ru/practicum/events/event/model/Event.java b/main-service/src/main/java/ru/practicum/events/event/model/Event.java index b6ef0ac..88ac831 100644 --- a/main-service/src/main/java/ru/practicum/events/event/model/Event.java +++ b/main-service/src/main/java/ru/practicum/events/event/model/Event.java @@ -45,4 +45,6 @@ public class Event { @Column(unique = true) private String title; private Long views; + @Column(name = "comment_switch") + private Boolean commentAvailable; } diff --git a/main-service/src/main/java/ru/practicum/events/event/service/EventPrivateService.java b/main-service/src/main/java/ru/practicum/events/event/service/EventPrivateService.java index 0dbac1f..c117fdf 100644 --- a/main-service/src/main/java/ru/practicum/events/event/service/EventPrivateService.java +++ b/main-service/src/main/java/ru/practicum/events/event/service/EventPrivateService.java @@ -1,9 +1,6 @@ package ru.practicum.events.event.service; -import ru.practicum.events.event.dto.EventFullDto; -import ru.practicum.events.event.dto.EventShortDto; -import ru.practicum.events.event.dto.NewEventDto; -import ru.practicum.events.event.dto.UpdateEventRequest; +import ru.practicum.events.event.dto.*; import ru.practicum.events.request.dto.EventRequestStatusUpdateRequest; import ru.practicum.events.request.dto.EventRequestStatusUpdateResult; import ru.practicum.events.request.dto.RequestDto; @@ -24,4 +21,6 @@ public interface EventPrivateService { EventRequestStatusUpdateResult updateRequestStatus(Long userId, Long eventId, EventRequestStatusUpdateRequest updateRequest); + + EventFullDto enableComment(Long userId, Long eventId, Boolean disable); } diff --git a/main-service/src/main/java/ru/practicum/events/event/service/impl/EventPrivateServiceImp.java b/main-service/src/main/java/ru/practicum/events/event/service/impl/EventPrivateServiceImp.java index 64012f2..eba1f76 100644 --- a/main-service/src/main/java/ru/practicum/events/event/service/impl/EventPrivateServiceImp.java +++ b/main-service/src/main/java/ru/practicum/events/event/service/impl/EventPrivateServiceImp.java @@ -59,9 +59,11 @@ public List getEventsByUser(Long userId, Integer from, Integer si @Override public EventFullDto addNewEvent(Long userId, NewEventDto newEventDto) { CheckTime.checkTemporaryValidation(newEventDto.getEventDate(), LocalDateTime.now(), 2); - return toEventFullDto(eventRepository.save(toEvent(newEventDto, + Event event = toEvent(newEventDto, objectCreator.getUserById(userId), - objectCreator.getCategoryById(newEventDto.getCategory()), 0L, 0L))); + objectCreator.getCategoryById(newEventDto.getCategory()), 0L, 0L); + event.setCommentAvailable(true); + return toEventFullDto(eventRepository.save(event)); } @Override @@ -147,6 +149,17 @@ public EventRequestStatusUpdateResult updateRequestStatus(Long userId, } } + @Override + public EventFullDto enableComment(Long userId, Long eventId, Boolean disable) { + User user = objectCreator.getUserById(userId); + Event event = objectCreator.getEventById(eventId); + if (!event.getInitiator().equals(user)) { + throw new BadRequestException("Включать и выключать коментарии может только инициализатор события"); + } + event.setCommentAvailable(disable); + return toEventFullDto(eventRepository.save(event)); + } + private EventRequestStatusUpdateResult getUpdateResultConfirmed(List requests, Event event) { List confirmed = new ArrayList<>(); List rejected = new ArrayList<>(); diff --git a/main-service/src/main/java/ru/practicum/events/request/dto/EventRequestStatusUpdateRequest.java b/main-service/src/main/java/ru/practicum/events/request/dto/EventRequestStatusUpdateRequest.java index af012ec..250abc1 100644 --- a/main-service/src/main/java/ru/practicum/events/request/dto/EventRequestStatusUpdateRequest.java +++ b/main-service/src/main/java/ru/practicum/events/request/dto/EventRequestStatusUpdateRequest.java @@ -9,7 +9,6 @@ @Getter @AllArgsConstructor @NoArgsConstructor -@Builder public class EventRequestStatusUpdateRequest { List requestIds; RequestStatus status; diff --git a/main-service/src/main/java/ru/practicum/events/request/dto/EventRequestStatusUpdateResult.java b/main-service/src/main/java/ru/practicum/events/request/dto/EventRequestStatusUpdateResult.java index 6371f4e..bf6d87f 100644 --- a/main-service/src/main/java/ru/practicum/events/request/dto/EventRequestStatusUpdateResult.java +++ b/main-service/src/main/java/ru/practicum/events/request/dto/EventRequestStatusUpdateResult.java @@ -7,8 +7,6 @@ @Setter @Getter @Builder -@NoArgsConstructor -@AllArgsConstructor public class EventRequestStatusUpdateResult { private List confirmedRequests; private List rejectedRequests; diff --git a/main-service/src/main/java/ru/practicum/events/request/dto/RequestDto.java b/main-service/src/main/java/ru/practicum/events/request/dto/RequestDto.java index 8e8d7ad..7b88712 100644 --- a/main-service/src/main/java/ru/practicum/events/request/dto/RequestDto.java +++ b/main-service/src/main/java/ru/practicum/events/request/dto/RequestDto.java @@ -5,8 +5,6 @@ @Setter @Getter -@AllArgsConstructor -@NoArgsConstructor @Builder public class RequestDto { private String created; diff --git a/main-service/src/main/java/ru/practicum/events/request/mapper/RequestMapper.java b/main-service/src/main/java/ru/practicum/events/request/mapper/RequestMapper.java index 5b79a7c..b65ffac 100644 --- a/main-service/src/main/java/ru/practicum/events/request/mapper/RequestMapper.java +++ b/main-service/src/main/java/ru/practicum/events/request/mapper/RequestMapper.java @@ -5,7 +5,11 @@ import java.time.format.DateTimeFormatter; -public class RequestMapper { +public final class RequestMapper { + private RequestMapper() { + + } + public static RequestDto toDto(Request request) { return RequestDto.builder() .id(request.getId()) diff --git a/main-service/src/main/java/ru/practicum/users/controller/UserController.java b/main-service/src/main/java/ru/practicum/users/controller/UserController.java index f64a878..12aaa22 100644 --- a/main-service/src/main/java/ru/practicum/users/controller/UserController.java +++ b/main-service/src/main/java/ru/practicum/users/controller/UserController.java @@ -35,7 +35,7 @@ public UserDto createUser(@Valid @RequestBody UserCreateDto dto) { @DeleteMapping("/{id}") @ResponseStatus(HttpStatus.NO_CONTENT) - public void deleteUser(@PathVariable long id) { + public void deleteUser(@PathVariable Long id) { log.info("Получен запрос на удаление пользователя id = {}",id); service.deleteUser(id); } diff --git a/main-service/src/main/java/ru/practicum/users/mapper/UserMapper.java b/main-service/src/main/java/ru/practicum/users/mapper/UserMapper.java index edd0034..ef6e224 100644 --- a/main-service/src/main/java/ru/practicum/users/mapper/UserMapper.java +++ b/main-service/src/main/java/ru/practicum/users/mapper/UserMapper.java @@ -5,7 +5,11 @@ import ru.practicum.users.dto.UserShortDto; import ru.practicum.users.model.User; -public class UserMapper { +public final class UserMapper { + private UserMapper() { + + } + public static User toUser(UserCreateDto dto) { return User.builder() .name(dto.getName()) diff --git a/main-service/src/main/java/ru/practicum/util/RepositoryObjectCreator.java b/main-service/src/main/java/ru/practicum/util/RepositoryObjectCreator.java index 6f22614..489e3cc 100644 --- a/main-service/src/main/java/ru/practicum/util/RepositoryObjectCreator.java +++ b/main-service/src/main/java/ru/practicum/util/RepositoryObjectCreator.java @@ -4,6 +4,8 @@ import org.springframework.stereotype.Service; import ru.practicum.category.model.Category; import ru.practicum.category.storage.CategoryRepository; +import ru.practicum.events.comments.model.Comment; +import ru.practicum.events.comments.storage.CommentRepository; import ru.practicum.events.compilation.model.Compilation; import ru.practicum.events.compilation.storage.CompilationRepository; import ru.practicum.events.event.model.Event; @@ -21,18 +23,21 @@ public class RepositoryObjectCreator { private final EventRepository eventRepository; private final RequestRepository requestRepository; private final CompilationRepository compilationRepository; + private final CommentRepository commentRepository; @Autowired public RepositoryObjectCreator(UserRepository userRepository, CategoryRepository categoryRepository, EventRepository eventRepository, RequestRepository requestRepository, - CompilationRepository compilationRepository) { + CompilationRepository compilationRepository, + CommentRepository commentRepository) { this.userRepository = userRepository; this.categoryRepository = categoryRepository; this.eventRepository = eventRepository; this.requestRepository = requestRepository; this.compilationRepository = compilationRepository; + this.commentRepository = commentRepository; } public User getUserById(Long id) { @@ -60,6 +65,11 @@ public Compilation getCompilationById(Long compId) { .orElseThrow(() -> new NotFoundException(getMassage("Подборка", compId))); } + public Comment getCommentById(Long commId) { + return commentRepository.findById(commId) + .orElseThrow(() -> new NotFoundException(getMassage("Комментарий", commId))); + } + public Boolean isRelatedCategory(Long id) { return eventRepository.existsByCategory(getCategoryById(id)); } @@ -67,4 +77,6 @@ public Boolean isRelatedCategory(Long id) { private String getMassage(String model, Long id) { return String.format("%s id = %d отсутствует", model, id); } + + } diff --git a/main-service/src/main/resources/schema.sql b/main-service/src/main/resources/schema.sql index 4926654..4d211f9 100644 --- a/main-service/src/main/resources/schema.sql +++ b/main-service/src/main/resources/schema.sql @@ -1,10 +1,8 @@ -DROP TABLE IF EXISTS compilation_events,compilations,requests,events,categories,users; - CREATE TABLE IF NOT EXISTS users ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, name VARCHAR(255) NOT NULL, - email VARCHAR(512) NOT NULL, + email VARCHAR(320) NOT NULL, CONSTRAINT pk_user PRIMARY KEY (id), CONSTRAINT UQ_USER_EMAIL UNIQUE (email) ); @@ -36,6 +34,7 @@ CREATE TABLE IF NOT EXISTS events state VARCHAR, title VARCHAR(255) NOT NULL, views BIGINT, + comment_switch BOOLEAN NOT NULL DEFAULT TRUE, CONSTRAINT pk_events PRIMARY KEY (id), FOREIGN KEY (initiator_id) REFERENCES users (id) ON DELETE CASCADE, @@ -70,4 +69,28 @@ CREATE TABLE IF NOT EXISTS compilation_events CONSTRAINT pk_comp_event PRIMARY KEY (compilation_id, event_id), FOREIGN KEY (event_id) REFERENCES events (id) ON DELETE CASCADE, FOREIGN KEY (compilation_id) REFERENCES compilations (id) ON DELETE CASCADE -); \ No newline at end of file +); + +CREATE TABLE IF NOT EXISTS comments +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + comment_text VARCHAR(2000) NOT NULL, + user_id BIGINT NOT NULL, + event_id BIGINT NOT NULL, + comment_time TIMESTAMP WITHOUT TIME ZONE NOT NULL, + CONSTRAINT pk_comments PRIMARY KEY (id), + FOREIGN KEY (event_id) REFERENCES events (id) ON DELETE CASCADE, + FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS rating +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + user_id BIGINT NOT NULL, + comment_id BIGINT NOT NULL, + grade BOOLEAN NOT NULL, + CONSTRAINT pk_rating PRIMARY KEY (id), + FOREIGN KEY (comment_id) REFERENCES comments (id) ON DELETE CASCADE, + FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE +); + diff --git a/postman/feature.json b/postman/feature.json new file mode 100644 index 0000000..03887aa --- /dev/null +++ b/postman/feature.json @@ -0,0 +1,1922 @@ +{ + "info": { + "_postman_id": "03d1335b-c8f7-47ae-932a-f045f280625b", + "name": "Test Explore With Me - future comments", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "23645999" + }, + "item": [ + { + "name": "Коректные запросы", + "item": [ + { + "name": "Оценка", + "item": [ + { + "name": "Поставить положительную оценку", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " try {\r", + " const user = await api.addUser(rnd.getUser());\r", + " pm.collectionVariables.set(\"uid\", user.id)\r", + " const category = await api.addCategory(rnd.getCategory());\r", + " const event = await api.addEvent(user.id, rnd.getEvent(category.id));\r", + " pm.collectionVariables.set(\"eid\", event.id)\r", + " const comment = await api.addComment(user.id, rnd.getComment(event.id));\r", + " pm.collectionVariables.set(\"cid\", comment.id)\r", + "} catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " // выполняем наш скрипт\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Ответ должен содержать код статуса 201\", function () {\r", + " pm.response.to.have.status(201);\r", + "});\r", + "const commId = pm.collectionVariables.get('cid');\r", + "\r", + "let body\r", + "const req = {\r", + " url: \"http://localhost:8080/comment?eventId=\" + pm.collectionVariables.get(\"eid\"),\r", + " method: \"GET\",\r", + " body: body == null ? \"\" : JSON.stringify(body),\r", + " header: { \"Content-Type\": \"application/json\" },\r", + " };\r", + "pm.sendRequest(req, (error, response) => {\r", + " pm.test(\"Рейтинг должен быть польжительный\", function(){\r", + " pm.expect(response.json()[0]).to.have.property('rating');\r", + " pm.expect(response.json()[0].rating).equals(1);\r", + " });\r", + " ;\r", + "}) " + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{baseUrl}}/users/:userId/comments/:commentId/like?grade=true", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users", + ":userId", + "comments", + ":commentId", + "like" + ], + "query": [ + { + "key": "grade", + "value": "true" + } + ], + "variable": [ + { + "key": "userId", + "value": "{{uid}}" + }, + { + "key": "commentId", + "value": "{{cid}}" + } + ] + } + }, + "response": [] + }, + { + "name": "Поставить отрицательную оценку", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " try {\r", + " const user = await api.addUser(rnd.getUser());\r", + " pm.collectionVariables.set(\"uid\", user.id)\r", + " const category = await api.addCategory(rnd.getCategory());\r", + " const event = await api.addEvent(user.id, rnd.getEvent(category.id));\r", + " pm.collectionVariables.set(\"eid\", event.id)\r", + " const comment = await api.addComment(user.id, rnd.getComment(event.id));\r", + " pm.collectionVariables.set(\"cid\", comment.id)\r", + "} catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " // выполняем наш скрипт\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Ответ должен содержать код статуса 201\", function () {\r", + " pm.response.to.have.status(201);\r", + "});\r", + "const commId = pm.collectionVariables.get('cid');\r", + "\r", + "let body\r", + "const req = {\r", + " url: \"http://localhost:8080/comment?eventId=\" + pm.collectionVariables.get(\"eid\"),\r", + " method: \"GET\",\r", + " body: body == null ? \"\" : JSON.stringify(body),\r", + " header: { \"Content-Type\": \"application/json\" },\r", + " };\r", + "pm.sendRequest(req, (error, response) => {\r", + " pm.test(\"Рейтинг должен быть отрицательный\", function(){\r", + " pm.expect(response.json()[0]).to.have.property('rating');\r", + " pm.expect(response.json()[0].rating).equals(-1);\r", + " });\r", + " ;\r", + "}) " + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{baseUrl}}/users/:userId/comments/:commentId/like?grade=false", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users", + ":userId", + "comments", + ":commentId", + "like" + ], + "query": [ + { + "key": "grade", + "value": "false" + } + ], + "variable": [ + { + "key": "userId", + "value": "{{uid}}" + }, + { + "key": "commentId", + "value": "{{cid}}" + } + ] + } + }, + "response": [] + }, + { + "name": "Удалить польжительную оцеку", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " try {\r", + " const user = await api.addUser(rnd.getUser());\r", + " pm.collectionVariables.set(\"uid\", user.id);\r", + " const category = await api.addCategory(rnd.getCategory());\r", + " const event = await api.addEvent(user.id, rnd.getEvent(category.id));\r", + " pm.collectionVariables.set(\"eid\", event.id);\r", + " const comment = await api.addComment(user.id, rnd.getComment(event.id));\r", + " pm.collectionVariables.set(\"cid\", comment.id);\r", + " await api.addLike(user.id, comment.id);\r", + " const foundedComment = await api.findComments(event.id);\r", + " pm.collectionVariables.set('response', foundedComment); \r", + "} catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " // выполняем наш скрипт\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Ответ должен содержать код статуса 204 и данные в формате json\", function () {\r", + " pm.response.to.have.status(204);\r", + "});\r", + "\r", + "const source = pm.collectionVariables.get('response');\r", + "const commentId = pm.collectionVariables.get('cid');\r", + "\r", + "pm.test(\"Рейтин должен быть положительным до выполнения запроса\", function(){\r", + " pm.expect(source.length).to.eql(1);\r", + " pm.expect(source[0].id).to.eql(commentId);\r", + " pm.expect(source[0].rating).to.eql(1);\r", + "});\r", + "\r", + "let body\r", + "const req = {\r", + " url: \"http://localhost:8080/comment?eventId=\" + pm.collectionVariables.get(\"eid\"),\r", + " method: \"GET\",\r", + " body: body == null ? \"\" : JSON.stringify(body),\r", + " header: { \"Content-Type\": \"application/json\" },\r", + " };\r", + "pm.sendRequest(req, (error, response) => {\r", + " pm.test(\"После удаления рейтинг должен отсутствовать\", function(){\r", + " pm.expect(response.json()[0]).to.have.property('rating');\r", + " pm.expect(response.json()[0].rating).equals(0);\r", + " });\r", + " ;\r", + "}) \r", + "\r", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{baseUrl}}/users/:userId/comments/:commentId/like", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users", + ":userId", + "comments", + ":commentId", + "like" + ], + "variable": [ + { + "key": "userId", + "value": "{{uid}}" + }, + { + "key": "commentId", + "value": "{{cid}}" + } + ] + } + }, + "response": [] + }, + { + "name": "Удалить отрицательную оцеку", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " try {\r", + " const user = await api.addUser(rnd.getUser());\r", + " pm.collectionVariables.set(\"uid\", user.id);\r", + " const category = await api.addCategory(rnd.getCategory());\r", + " const event = await api.addEvent(user.id, rnd.getEvent(category.id));\r", + " pm.collectionVariables.set(\"eid\", event.id);\r", + " const comment = await api.addComment(user.id, rnd.getComment(event.id));\r", + " pm.collectionVariables.set(\"cid\", comment.id);\r", + " await api.addDislike(user.id, comment.id);\r", + " const foundedComment = await api.findComments(event.id);\r", + " pm.collectionVariables.set('response', foundedComment); \r", + "} catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " // выполняем наш скрипт\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Ответ должен содержать код статуса 204 и данные в формате json\", function () {\r", + " pm.response.to.have.status(204);\r", + "});\r", + "\r", + "const source = pm.collectionVariables.get('response');\r", + "const commentId = pm.collectionVariables.get('cid');\r", + "\r", + "pm.test(\"Рейтин должен быть отрицательным до выполнения запроса\", function(){\r", + " pm.expect(source.length).to.eql(1);\r", + " pm.expect(source[0].id).to.eql(commentId);\r", + " pm.expect(source[0].rating).to.eql(-1);\r", + "});\r", + "\r", + "let body\r", + "const req = {\r", + " url: \"http://localhost:8080/comment?eventId=\" + pm.collectionVariables.get(\"eid\"),\r", + " method: \"GET\",\r", + " body: body == null ? \"\" : JSON.stringify(body),\r", + " header: { \"Content-Type\": \"application/json\" },\r", + " };\r", + "pm.sendRequest(req, (error, response) => {\r", + " pm.test(\"После удаления рейтинг должен отсутствовать\", function(){\r", + " pm.expect(response.json()[0]).to.have.property('rating');\r", + " pm.expect(response.json()[0].rating).equals(0);\r", + " });\r", + " ;\r", + "}) \r", + "\r", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{baseUrl}}/users/:userId/comments/:commentId/like", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users", + ":userId", + "comments", + ":commentId", + "like" + ], + "variable": [ + { + "key": "userId", + "value": "{{uid}}" + }, + { + "key": "commentId", + "value": "{{cid}}" + } + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Добавление комментария", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let comment;\r", + " try {\r", + " const user = await api.addUser(rnd.getUser());\r", + " pm.collectionVariables.set(\"uid\", user.id)\r", + " const category = await api.addCategory(rnd.getCategory());\r", + " const event = await api.addEvent(user.id, rnd.getEvent(category.id));\r", + " comment = rnd.getComment(event.id);\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + " pm.request.body.update({\r", + " mode: 'raw',\r", + " raw: JSON.stringify(comment),\r", + " options: { raw: { language: 'json' } }\r", + " });\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Ответ должен содержать код статуса 201 и данные в формате json\", function () {\r", + " pm.response.to.have.status(201); \r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "\r", + "const source = JSON.parse(pm.request.body.raw);\r", + "const target = pm.response.json();\r", + "\r", + "pm.test(\"Комментарий должен содержать поля: id, commentator, text, category, commentTime\", function () {\r", + " pm.expect(target).to.have.property('id');\r", + " pm.expect(target).to.have.property('commentator');\r", + " pm.expect(target).to.have.property('text');\r", + " pm.expect(target).to.have.property('commentTime');\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + }, + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{{request_body}}" + }, + "url": { + "raw": "{{baseUrl}}/users/:userId/comments", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users", + ":userId", + "comments" + ], + "variable": [ + { + "key": "userId", + "value": "{{uid}}", + "description": "(Required) id текущего пользователя" + } + ] + } + }, + "response": [] + }, + { + "name": "Изменить комментарий", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + " const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " try {\r", + " const user = await api.addUser(rnd.getUser());\r", + " pm.collectionVariables.set(\"uid\", user.id)\r", + " const category = await api.addCategory(rnd.getCategory());\r", + " const event = await api.addEvent(user.id, rnd.getEvent(category.id));\r", + " let comment = await api.addComment(user.id, rnd.getComment(event.id));\r", + " let comment2 = rnd.getComment(event.id);\r", + " pm.collectionVariables.set('response', comment2);\r", + " pm.collectionVariables.set(\"cid\", comment.id)\r", + " pm.request.body.update({\r", + " mode: 'raw',\r", + " raw: comment2,\r", + " options: { raw: { language: 'json' } }\r", + " });\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " // выполняем наш скрипт\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");\r", + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Ответ должен содержать код статуса 200 и данные в формате json\", function () {\r", + " pm.response.to.be.ok; \r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "\r", + "const source = pm.collectionVariables.get('response');\r", + "const target = pm.response.json();\r", + "console.log(source)\r", + "console.log(target)\r", + "\r", + "pm.test(\"Комментарий должен содержать поля: id, commentator, text, commentTime\", function () {\r", + "pm.expect(target).to.have.property('id');\r", + "pm.expect(target).to.have.property('commentator');\r", + "pm.expect(target).to.have.property('text');\r", + "pm.expect(target).to.have.property('commentTime');\r", + "});\r", + "\r", + "pm.test(\"Данные в ответе должны соответствовать данным в запросе\", function () {\r", + " pm.expect(source.text).equal(target.text, 'Текст комментария должен соответствовать искомому событию');\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{{request_body}}" + }, + "url": { + "raw": "{{baseUrl}}/users/:userId/comments/:commentId", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users", + ":userId", + "comments", + ":commentId" + ], + "variable": [ + { + "key": "userId", + "value": "{{uid}}" + }, + { + "key": "commentId", + "value": "{{cid}}" + } + ] + } + }, + "response": [] + }, + { + "name": "Удалить комментарий", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + " const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " try {\r", + " const user = await api.addUser(rnd.getUser());\r", + " pm.collectionVariables.set(\"uid\", user.id);\r", + " const category = await api.addCategory(rnd.getCategory());\r", + " const event = await api.addEvent(user.id, rnd.getEvent(category.id));\r", + " pm.collectionVariables.set(\"eid\", event.id);\r", + " const comment = await api.addComment(user.id, rnd.getComment(event.id));\r", + " pm.collectionVariables.set(\"cid\", comment.id)\r", + " const foundedComment = await api.findComments(event.id);\r", + " pm.collectionVariables.set('response', foundedComment); \r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " // выполняем наш скрипт\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");\r", + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Ответ должен содержать код статуса 204\", function () {\r", + " pm.response.to.have.status(204);\r", + "});\r", + "const source = pm.collectionVariables.get('response');\r", + "const commentId = pm.collectionVariables.get('cid');\r", + "\r", + "pm.test(\"Комментарий должен быть найден до выполнения запроса\", function(){\r", + " pm.expect(source.length).to.eql(1);\r", + " pm.expect(source[0].id).to.eql(commentId);\r", + "});\r", + "\r", + "let body\r", + "const req = {\r", + " url: \"http://localhost:8080/comment?eventId=\" + pm.collectionVariables.get(\"eid\"),\r", + " method: \"GET\",\r", + " body: body == null ? \"\" : JSON.stringify(body),\r", + " header: { \"Content-Type\": \"application/json\" },\r", + " };\r", + "pm.sendRequest(req, (error, response) => {\r", + " pm.test(\"Комментарий должен быть удалён после выполнения запроса\", function(){\r", + " pm.expect(response.json().length).to.eql(0);\r", + " });\r", + "}) " + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "{{baseUrl}}/users/:userId/comments/:commentId", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users", + ":userId", + "comments", + ":commentId" + ], + "variable": [ + { + "key": "userId", + "value": "{{uid}}" + }, + { + "key": "commentId", + "value": "{{cid}}" + } + ] + } + }, + "response": [] + }, + { + "name": "Получение списка комментариев события сортировка по дате", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " try {\r", + " const user = await api.addUser(rnd.getUser());\r", + " const user2 = await api.addUser(rnd.getUser());\r", + " pm.collectionVariables.set(\"uid\", user.id);\r", + " const category = await api.addCategory(rnd.getCategory());\r", + " const event = await api.addEvent(user.id, rnd.getEvent(category.id));\r", + " pm.collectionVariables.set(\"eid\", event.id);\r", + " const comment = await api.addComment(user.id, rnd.getComment(event.id));\r", + " const comment2 = await api.addComment(user2.id, rnd.getComment(event.id));\r", + " pm.collectionVariables.set(\"cid\", comment.id);\r", + " await api.addLike(user.id, comment.id);\r", + " await api.addLike(user2.id, comment.id);\r", + " await api.addDislike(user.id, comment2.id);\r", + "} catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " // выполняем наш скрипт\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Ответ должен содержать код статуса 200 и данные в формате json\", function () {\r", + " pm.response.to.be.ok; \r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "\r", + "const target = pm.response.json();\r", + "\r", + "\r", + "pm.test(\"Коментарии должны содержать поля: id, commentator, text, commentTime, rating\", function () {\r", + " pm.expect(target[0]).to.have.all.keys('id', 'commentator', 'text', 'commentTime', 'rating');\r", + " pm.expect(target[1]).to.have.all.keys('id', 'commentator', 'text', 'commentTime', 'rating');\r", + "});\r", + "\r", + "\r", + "\r", + "pm.test(\"В теле ответа должна соблюдаться сортировка по убыванию времени\", function(){\r", + " pm.expect(new Date(target[0].commentTime)).to.be.above(new Date(target[1].commentTime));\r", + "});\r", + "\r", + "\r", + "pm.test(\"Проверка соответствия рейтинга\", function(){\r", + " pm.expect(target[0].rating).equal(-1);\r", + " pm.expect(target[1].rating).equal(2);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{baseUrl}}/comment?rating=false&from=0&size=1000&eventId={{eid}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "comment" + ], + "query": [ + { + "key": "rating", + "value": "false" + }, + { + "key": "from", + "value": "0" + }, + { + "key": "size", + "value": "1000" + }, + { + "key": "eventId", + "value": "{{eid}}" + } + ] + } + }, + "response": [] + }, + { + "name": "Получение списка комментариев комметарии отключены", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " try {\r", + " const user = await api.addUser(rnd.getUser());\r", + " const user2 = await api.addUser(rnd.getUser());\r", + " pm.collectionVariables.set(\"uid\", user.id);\r", + " const category = await api.addCategory(rnd.getCategory());\r", + " const event = await api.addEvent(user.id, rnd.getEvent(category.id));\r", + " pm.collectionVariables.set(\"eid\", event.id);\r", + " const comment = await api.addComment(user.id, rnd.getComment(event.id));\r", + " const comment2 = await api.addComment(user2.id, rnd.getComment(event.id));\r", + " pm.collectionVariables.set(\"cid\", comment.id);\r", + " await api.addLike(user.id, comment.id);\r", + " await api.addLike(user2.id, comment.id);\r", + " await api.addDislike(user.id, comment2.id);\r", + " await api.disableComments(user.id, event.id);\r", + "} catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " // выполняем наш скрипт\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Ответ должен содержать код статуса 200 и данные в формате json\", function () {\r", + " pm.response.to.be.ok; \r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "\r", + "const target = pm.response.json();\r", + "\r", + "\r", + "pm.test(\"Список должен быть пуст\", function () {\r", + " pm.expect(target).to.be.empty;\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{baseUrl}}/comment?rating=true&from=0&size=1000&eventId={{eid}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "comment" + ], + "query": [ + { + "key": "rating", + "value": "true" + }, + { + "key": "from", + "value": "0" + }, + { + "key": "size", + "value": "1000" + }, + { + "key": "eventId", + "value": "{{eid}}" + } + ] + } + }, + "response": [] + }, + { + "name": "Получение списка комментариев события сортировка по рейтингу", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " try {\r", + " const user = await api.addUser(rnd.getUser());\r", + " const user2 = await api.addUser(rnd.getUser());\r", + " pm.collectionVariables.set(\"uid\", user.id);\r", + " const category = await api.addCategory(rnd.getCategory());\r", + " const event = await api.addEvent(user.id, rnd.getEvent(category.id));\r", + " pm.collectionVariables.set(\"eid\", event.id);\r", + " const comment = await api.addComment(user.id, rnd.getComment(event.id));\r", + " const comment2 = await api.addComment(user2.id, rnd.getComment(event.id));\r", + " pm.collectionVariables.set(\"cid\", comment.id);\r", + " await api.addLike(user.id, comment.id);\r", + " await api.addLike(user2.id, comment.id);\r", + " await api.addDislike(user.id, comment2.id);\r", + "} catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " // выполняем наш скрипт\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Ответ должен содержать код статуса 200 и данные в формате json\", function () {\r", + " pm.response.to.be.ok; \r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "\r", + "const target = pm.response.json();\r", + "\r", + "\r", + "pm.test(\"Коментарии должны содержать поля: id, commentator, text, commentTime, rating\", function () {\r", + " pm.expect(target[0]).to.have.all.keys('id', 'commentator', 'text', 'commentTime', 'rating');\r", + " pm.expect(target[1]).to.have.all.keys('id', 'commentator', 'text', 'commentTime', 'rating');\r", + "});\r", + "\r", + "\r", + "\r", + "pm.test(\"В теле ответа должна соблюдаться сортировка по рейтинга\", function(){\r", + " pm.expect(new Date(target[0].commentTime)).to.be.below(new Date(target[1].commentTime));\r", + "});\r", + "\r", + "\r", + "pm.test(\"Проверка соответствия рейтинга\", function(){\r", + " pm.expect(target[0].rating).equal(2);\r", + " pm.expect(target[1].rating).equal(-1);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{baseUrl}}/comment?rating=true&from=0&size=1000&eventId={{eid}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "comment" + ], + "query": [ + { + "key": "rating", + "value": "true" + }, + { + "key": "from", + "value": "0" + }, + { + "key": "size", + "value": "1000" + }, + { + "key": "eventId", + "value": "{{eid}}" + } + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Некорректные запросы", + "item": [ + { + "name": "Изменить комментарий не коментатором", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + " const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " try {\r", + " const user = await api.addUser(rnd.getUser());\r", + " const user2 = await api.addUser(rnd.getUser());\r", + " pm.collectionVariables.set(\"uid\", user.id)\r", + " const category = await api.addCategory(rnd.getCategory());\r", + " const event = await api.addEvent(user.id, rnd.getEvent(category.id));\r", + " let comment = await api.addComment(user2.id, rnd.getComment(event.id));\r", + " let comment2 = rnd.getComment(event.id);\r", + " pm.collectionVariables.set(\"cid\", comment.id)\r", + " pm.request.body.update({\r", + " mode: 'raw',\r", + " raw: comment2,\r", + " options: { raw: { language: 'json' } }\r", + " });\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " // выполняем наш скрипт\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");\r", + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Ответ должен содержать код статуса 400 и данные в формате json\", function () {\r", + " pm.response.to.be.badRequest; \r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{{request_body}}" + }, + "url": { + "raw": "{{baseUrl}}/users/:userId/comments/:commentId", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users", + ":userId", + "comments", + ":commentId" + ], + "variable": [ + { + "key": "userId", + "value": "{{uid}}" + }, + { + "key": "commentId", + "value": "{{cid}}" + } + ] + } + }, + "response": [] + }, + { + "name": "Добавить при отключенных комметариях", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let comment;\r", + " try {\r", + " const user = await api.addUser(rnd.getUser());\r", + " pm.collectionVariables.set(\"uid\", user.id)\r", + " const category = await api.addCategory(rnd.getCategory());\r", + " let event = await api.addEvent(user.id, rnd.getEvent(category.id));\r", + " event = await api.disableComments(user.id, event.id);\r", + " comment = rnd.getComment(event.id);\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + " pm.request.body.update({\r", + " mode: 'raw',\r", + " raw: JSON.stringify(comment),\r", + " options: { raw: { language: 'json' } }\r", + " });\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Ответ должен содержать код статуса 409 и данные в формате json\", function () {\r", + " pm.response.to.have.status(409);\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + }, + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{{request_body}}", + "options": { + "raw": { + "language": "text" + } + } + }, + "url": { + "raw": "{{baseUrl}}/users/:userId/comments", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users", + ":userId", + "comments" + ], + "variable": [ + { + "key": "userId", + "value": "{{uid}}" + } + ] + } + }, + "response": [] + }, + { + "name": "Изменить комментарий непринадлижащего событию", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + " const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " try {\r", + " const user = await api.addUser(rnd.getUser());\r", + " pm.collectionVariables.set(\"uid\", user.id)\r", + " const category = await api.addCategory(rnd.getCategory());\r", + " const event = await api.addEvent(user.id, rnd.getEvent(category.id));\r", + " const event2 = await api.addEvent(user.id, rnd.getEvent(category.id));\r", + " let comment = await api.addComment(user.id, rnd.getComment(event.id));\r", + " let comment2 = rnd.getComment(event2.id);\r", + " pm.collectionVariables.set(\"cid\", comment.id)\r", + " pm.request.body.update({\r", + " mode: 'raw',\r", + " raw: comment2,\r", + " options: { raw: { language: 'json' } }\r", + " });\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " // выполняем наш скрипт\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");\r", + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Ответ должен содержать код статуса 400 и данные в формате json\", function () {\r", + " pm.response.to.be.badRequest; \r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{{request_body}}" + }, + "url": { + "raw": "{{baseUrl}}/users/:userId/comments/:commentId", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users", + ":userId", + "comments", + ":commentId" + ], + "variable": [ + { + "key": "userId", + "value": "{{uid}}" + }, + { + "key": "commentId", + "value": "{{cid}}" + } + ] + } + }, + "response": [] + }, + { + "name": "Не коментатор удаляет коментатор", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + " const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " try {\r", + " const user = await api.addUser(rnd.getUser());\r", + " const user2 = await api.addUser(rnd.getUser());\r", + " pm.collectionVariables.set(\"uid\", user2.id)\r", + " const category = await api.addCategory(rnd.getCategory());\r", + " const event = await api.addEvent(user.id, rnd.getEvent(category.id));\r", + " pm.collectionVariables.set(\"eid\", event.id)\r", + " const comment = await api.addComment(user.id, rnd.getComment(event.id));\r", + " pm.collectionVariables.set(\"cid\", comment.id)\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " // выполняем наш скрипт\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");\r", + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Ответ должен содержать код статуса 400\", function () {\r", + " pm.response.to.have.status(400);\r", + "});\r", + " " + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "{{baseUrl}}/users/:userId/comments/:commentId", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users", + ":userId", + "comments", + ":commentId" + ], + "variable": [ + { + "key": "userId", + "value": "{{uid}}" + }, + { + "key": "commentId", + "value": "{{cid}}" + } + ] + } + }, + "response": [] + }, + { + "name": "Удалить оцеку другого пользователя", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " try {\r", + " const user = await api.addUser(rnd.getUser());\r", + " const user2 = await api.addUser(rnd.getUser());\r", + " pm.collectionVariables.set(\"uid\", user.id);\r", + " const category = await api.addCategory(rnd.getCategory());\r", + " const event = await api.addEvent(user.id, rnd.getEvent(category.id));\r", + " pm.collectionVariables.set(\"eid\", event.id);\r", + " const comment = await api.addComment(user.id, rnd.getComment(event.id));\r", + " pm.collectionVariables.set(\"cid\", comment.id);\r", + " await api.addLike(user2.id, comment.id);\r", + "} catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " // выполняем наш скрипт\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Ответ должен содержать код статуса 400 и данные в формате json\", function () {\r", + " pm.response.to.have.status(400);\r", + "});\r", + " \r", + "\r", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{baseUrl}}/users/:userId/comments/:commentId/like", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users", + ":userId", + "comments", + ":commentId", + "like" + ], + "variable": [ + { + "key": "userId", + "value": "{{uid}}" + }, + { + "key": "commentId", + "value": "{{cid}}" + } + ] + } + }, + "response": [] + }, + { + "name": "Повтор оценки", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " try {\r", + " const user = await api.addUser(rnd.getUser());\r", + " pm.collectionVariables.set(\"uid\", user.id)\r", + " const category = await api.addCategory(rnd.getCategory());\r", + " const event = await api.addEvent(user.id, rnd.getEvent(category.id));\r", + " pm.collectionVariables.set(\"eid\", event.id)\r", + " const comment = await api.addComment(user.id, rnd.getComment(event.id));\r", + " pm.collectionVariables.set(\"cid\", comment.id)\r", + " await api.addLike(user.id,comment.id);\r", + "} catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " // выполняем наш скрипт\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Ответ должен содержать код статуса 409\", function () {\r", + " pm.response.to.have.status(409);\r", + "});\r", + " " + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "{{baseUrl}}/users/:userId/comments/:commentId/like?grade=true", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users", + ":userId", + "comments", + ":commentId", + "like" + ], + "query": [ + { + "key": "grade", + "value": "true" + } + ], + "variable": [ + { + "key": "userId", + "value": "{{uid}}" + }, + { + "key": "commentId", + "value": "{{cid}}" + } + ] + } + }, + "response": [] + } + ] + } + ], + "auth": { + "type": "edgegrid" + }, + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "API = class {", + " constructor(postman, verbose = false, baseUrl = \"http://localhost:8080\") {", + " this.baseUrl = baseUrl;", + " this.pm = postman;", + " this._verbose = verbose;", + " }", + "", + " async addUser(user, verbose=null) {", + " return this.post(\"/admin/users\", user, \"Ошибка при добавлении нового пользователя: \", verbose);", + " }", + "", + " async addCategory(category, verbose=null) {", + " return this.post(\"/admin/categories\", category, \"Ошибка при добавлении новой категории: \", verbose);", + " }", + "", + " async addEvent(userId, event, verbose=null) {", + " return this.post(\"/users/\" + userId + \"/events\", event, \"Ошибка при добавлении нового события: \", verbose);", + " }", + "", + " async addCompilation(compilation, verbose=null) {", + " return this.post(\"/admin/compilations\", compilation, \"Ошибка при добавлении новой подборки: \", verbose);", + " }", + "", + " async addComment(userId, comment, verbose=null) {", + " return this.post(\"/users/\" + userId + \"/comments\", comment, \"Ошибка при добавлении нового коментария: \", verbose)", + " }", + "", + " async addLike(userId, commentId, verbose=null) {", + " return this.post(\"/users/\" + userId + \"/comments/\" + commentId+ \"/like?grade=true\", null,\"Ошибка при добавлении лайка: \", verbose )", + " }", + "", + " async addDislike(userId, commentId, verbose=null){", + " return this.post(\"/users/\" + userId + \"/comments/\" + commentId + \"/like?grade=false\", null,\"Ошибка при добавлении дизлайка: \", verbose )", + " }", + "", + " async publishParticipationRequest(eventId, userId, verbose=null) {", + " return this.post('/users/' + userId + '/requests?eventId=' + eventId, null, \"Ошибка при добавлении нового запроса на участие в событии\", verbose);", + " }", + "", + " async publishEvent(eventId, verbose=null) {", + " return this.patch('/admin/events/' + eventId, {stateAction: \"PUBLISH_EVENT\"}, \"Ошибка при публикации события\", verbose);", + " }", + "", + " async disableComments(userId, eventId, verbose=null) {", + " return this.patch('/users/' + userId + '/events/' + eventId + '/comment', null, \"Ошибка при отключении комментариев\", verbose);", + " }", + " ", + " async rejectEvent(eventId, verbose=null) {", + " return this.patch('/admin/events/' + eventId, {stateAction: \"REJECT_EVENT\"}, \"Ошибка при отмене события\", verbose);", + " }", + "", + " async acceptParticipationRequest(eventId, userId, reqId, verbose=null) {", + " return this.patch('/users/' + userId + '/events/' + eventId + '/requests/', {requestIds:[reqId], status: \"CONFIRMED\"}, \"Ошибка при принятии заявки на участие в событии\", verbose);", + " }", + "", + " async findCategory(catId, verbose=null) {", + " return this.get('/categories/' + catId, null, \"Ошибка при поиске категории по id\", verbose);", + " }", + "", + " async findComments(eventId, verbose=null) {", + " return this.get('/comment?eventId=' + eventId, null, \"Ошибка при поиске комментария по id события\", verbose);", + " }", + "", + " async findCompilation(compId, verbose=null) {", + " return this.get('/compilations/' + compId, null, \"Ошибка при поиске подборки по id\", verbose);", + " }", + "", + " async findUser(userId, verbose=null) {", + " return this.get('/admin/users?ids=' + userId, null, \"Ошибка при поиске пользователя по id\", verbose);", + " }", + "", + " async post(path, body, errorText = \"Ошибка при выполнении post-запроса: \", verbose=null) {", + " return this.sendRequest(\"POST\", path, body, errorText, verbose);", + " }", + "", + " async patch(path, body = null, errorText = \"Ошибка при выполнении patch-запроса: \", verbose=null) {", + " return this.sendRequest(\"PATCH\", path, body, errorText, verbose);", + " }", + "", + " async get(path, body = null, errorText = \"Ошибка при выполнении get-запроса: \", verbose=null) {", + " return this.sendRequest(\"GET\", path, body, errorText, verbose);", + " }", + " async sendRequest(method, path, body=null, errorText = \"Ошибка при выполнении запроса: \", verbose=null) {", + " return new Promise((resolve, reject) => {", + " verbose = verbose == null ? this._verbose : verbose;", + "", + " const request = {", + " url: this.baseUrl + path,", + " method: method,", + " body: body == null ? \"\" : JSON.stringify(body),", + " header: { \"Content-Type\": \"application/json\" },", + " };", + "", + " if(verbose) {", + " console.log(\"Отправляю запрос: \", request);", + " }", + "", + " try {", + " this.pm.sendRequest(request, (error, response) => {", + " if(error || (response.code >= 400 && response.code <= 599)) {", + " let err = error ? error : JSON.stringify(response.json());", + " console.error(\"При выполнении запроса к серверу возникла ошика.\\n\", err,", + " \"\\nДля отладки проблемы повторите такой же запрос к вашей программе \" + ", + " \"на локальном компьютере. Данные запроса:\\n\", JSON.stringify(request));", + "", + " reject(new Error(errorText + err));", + " }", + "", + " if(verbose) {", + " console.log(\"Результат обработки запроса: код состояния - \", response.code, \", тело: \", response.json());", + " }", + " resolve(response.json());", + " });", + " } catch(err) {", + " if(verbose) {", + " console.error(errorText, err);", + " }", + " return Promise.reject(err);", + " }", + " });", + " }", + "};", + "", + "RandomUtils = class {", + " constructor() {}", + "", + " getUser() {", + " return {", + " name: pm.variables.replaceIn('{{$randomFullName}}'),", + " email: pm.variables.replaceIn('{{$randomEmail}}')", + " };", + " }", + "", + " getCategory() {", + " return {", + " name: pm.variables.replaceIn('{{$randomWord}}') + Math.floor(Math.random() * 100).toString()", + " };", + " }", + "", + " getEvent(categoryId) {", + " return {", + " annotation: pm.variables.replaceIn('{{$randomLoremParagraph}}'),", + " category: categoryId,", + " description: pm.variables.replaceIn('{{$randomLoremParagraphs}}'),", + " eventDate: this.getFutureDateTime(),", + " location: {", + " lat: parseFloat(pm.variables.replaceIn('{{$randomLatitude}}')),", + " lon: parseFloat(pm.variables.replaceIn('{{$randomLongitude}}')),", + " },", + " paid: pm.variables.replaceIn('{{$randomBoolean}}'),", + " participantLimit: pm.variables.replaceIn('{{$randomInt}}'),", + " requestModeration: pm.variables.replaceIn('{{$randomBoolean}}'),", + " title: pm.variables.replaceIn('{{$randomLoremSentence}}'),", + " }", + " }", + "", + " getComment(eventId) {", + " return {", + " text: pm.variables.replaceIn('{{$randomLoremSentence}}'),", + " eventId: eventId,", + " }", + " }", + "", + " getFutureDateTime(hourShift = 5, minuteShift=0, yearShift=0) {", + " let moment = require('moment');", + "", + " let m = moment();", + " m.add(hourShift, 'hour');", + " m.add(minuteShift, 'minute');", + " m.add(yearShift, 'year');", + "", + " return m.format('YYYY-MM-DD HH:mm:ss');", + " }", + "}" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "variable": [ + { + "key": "baseUrl", + "value": "http://localhost:8080", + "type": "string" + }, + { + "key": "request_body", + "value": "", + "type": "string" + }, + { + "key": "uid", + "value": "1", + "type": "string" + }, + { + "key": "eid", + "value": "" + }, + { + "key": "response", + "value": "" + }, + { + "key": "cid", + "value": "1" + } + ] +} \ No newline at end of file