Merge branch 'dev' into 79-students-tags-generation

# Conflicts:
#	src/main/java/ru/ulstu/students/service/TaskService.java
This commit is contained in:
ASH 2019-05-16 00:14:05 +04:00
commit cd1caa559e
32 changed files with 656 additions and 62 deletions

View File

@ -74,12 +74,9 @@ public class ConferenceController {
@PostMapping(value = "/conference", params = "save")
public String save(@Valid ConferenceDto conferenceDto, Errors errors) throws IOException {
conferenceService.filterEmptyDeadlines(conferenceDto);
conferenceService.checkEmptyFieldsOfDeadline(conferenceDto, errors);
if (errors.hasErrors()) {
if (!conferenceService.save(conferenceDto, errors)) {
return CONFERENCE_PAGE;
}
conferenceService.save(conferenceDto);
return String.format(REDIRECT_TO, CONFERENCES_PAGE);
}

View File

@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.format.annotation.DateTimeFormat;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.name.NameContainer;
import ru.ulstu.paper.model.Paper;
import javax.persistence.Temporal;
@ -16,7 +17,7 @@ import java.util.List;
import static ru.ulstu.core.util.StreamApiUtils.convert;
public class ConferenceDto {
public class ConferenceDto extends NameContainer {
private final static String BEGIN_DATE = "Начало: ";
private final static String END_DATE = "Конец: ";

View File

@ -5,12 +5,13 @@ import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import ru.ulstu.conference.model.Conference;
import ru.ulstu.name.BaseRepository;
import ru.ulstu.user.model.User;
import java.util.Date;
import java.util.List;
public interface ConferenceRepository extends JpaRepository<Conference, Integer> {
public interface ConferenceRepository extends JpaRepository<Conference, Integer>, BaseRepository {
@Query("SELECT c FROM Conference c LEFT JOIN c.users u WHERE (:user IS NULL OR u.user = :user) " +
"AND (YEAR(c.beginDate) = :year OR :year IS NULL) ORDER BY begin_date DESC")
List<Conference> findByUserAndYear(@Param("user") User user, @Param("year") Integer year);
@ -24,4 +25,8 @@ public interface ConferenceRepository extends JpaRepository<Conference, Integer>
@Modifying
@Query("UPDATE Conference c SET c.ping = (c.ping + 1) WHERE c.id = :id")
int updatePingConference(@Param("id") Integer id);
@Override
@Query("SELECT title FROM Conference c WHERE (c.title = :name) AND (:id IS NULL OR c.id != :id) ")
String findByNameAndNotId(@Param("name") String name, @Param("id") Integer id);
}

View File

@ -13,6 +13,7 @@ import ru.ulstu.conference.model.ConferenceUser;
import ru.ulstu.conference.repository.ConferenceRepository;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.deadline.service.DeadlineService;
import ru.ulstu.name.BaseService;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.paper.service.PaperService;
import ru.ulstu.ping.service.PingService;
@ -31,7 +32,7 @@ import static org.springframework.util.ObjectUtils.isEmpty;
import static ru.ulstu.core.util.StreamApiUtils.convert;
@Service
public class ConferenceService {
public class ConferenceService extends BaseService {
private final static int MAX_DISPLAY_SIZE = 40;
private final ConferenceRepository conferenceRepository;
@ -51,6 +52,7 @@ public class ConferenceService {
PingService pingService,
ConferenceNotificationService conferenceNotificationService,
EventService eventService) {
this.baseRepository = conferenceRepository;
this.conferenceRepository = conferenceRepository;
this.conferenceUserService = conferenceUserService;
this.deadlineService = deadlineService;
@ -89,12 +91,26 @@ public class ConferenceService {
return new ConferenceDto(conferenceRepository.findOne(id));
}
public void save(ConferenceDto conferenceDto) throws IOException {
public boolean save(ConferenceDto conferenceDto, Errors errors) throws IOException {
conferenceDto.setName(conferenceDto.getTitle());
filterEmptyDeadlines(conferenceDto);
checkEmptyFieldsOfDeadline(conferenceDto, errors);
checkUniqueName(conferenceDto,
errors,
conferenceDto.getId(),
"title",
"Конференция с таким именем уже существует");
if (errors.hasErrors()) {
return false;
}
if (isEmpty(conferenceDto.getId())) {
create(conferenceDto);
} else {
update(conferenceDto);
}
return true;
}
@Transactional
@ -127,6 +143,7 @@ public class ConferenceService {
@Transactional
public void delete(Integer conferenceId) {
if (conferenceRepository.exists(conferenceId)) {
eventService.removeConferencesEvent(conferenceRepository.findOne(conferenceId));
conferenceRepository.delete(conferenceId);
}
}
@ -280,7 +297,6 @@ public class ConferenceService {
}
}
public void filterEmptyDeadlines(ConferenceDto conferenceDto) {
conferenceDto.setDeadlines(conferenceDto.getDeadlines().stream()
.filter(dto -> dto.getDate() != null || !org.springframework.util.StringUtils.isEmpty(dto.getDescription()))

View File

@ -13,7 +13,7 @@ import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.grant.model.Grant;
import ru.ulstu.grant.model.GrantDto;
import ru.ulstu.grant.service.GrantService;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.paper.model.PaperDto;
import ru.ulstu.user.model.User;
import springfox.documentation.annotations.ApiIgnore;
@ -104,7 +104,6 @@ public class GrantController {
return GRANT_PAGE;
}
@PostMapping(value = "/grant", params = "createProject")
public String createProject(@Valid GrantDto grantDto, Errors errors) throws IOException {
if (errors.hasErrors()) {
@ -131,7 +130,7 @@ public class GrantController {
}
@ModelAttribute("allPapers")
public List<Paper> getAllPapers() {
public List<PaperDto> getAllPapers() {
return grantService.getAllUncompletedPapers();
}

View File

@ -74,7 +74,6 @@ public class Grant extends BaseEntity implements UserContainer {
@Fetch(FetchMode.SUBSELECT)
private List<FileData> files = new ArrayList<>();
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "project_id")
private Project project;

View File

@ -6,7 +6,7 @@ import org.apache.commons.lang3.StringUtils;
import org.hibernate.validator.constraints.NotEmpty;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.file.model.FileDataDto;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.paper.model.PaperDto;
import ru.ulstu.project.model.ProjectDto;
import ru.ulstu.user.model.UserDto;
@ -37,7 +37,7 @@ public class GrantDto {
private boolean hasBAKPapers;
private boolean hasScopusPapers;
private List<Integer> paperIds = new ArrayList<>();
private List<Paper> papers = new ArrayList<>();
private List<PaperDto> papers = new ArrayList<>();
private List<Integer> removedDeadlineIds = new ArrayList<>();
public GrantDto() {
@ -54,12 +54,12 @@ public class GrantDto {
@JsonProperty("project") ProjectDto project,
@JsonProperty("authorIds") Set<Integer> authorIds,
@JsonProperty("authors") Set<UserDto> authors,
@JsonProperty("leader") Integer leaderId,
@JsonProperty("leaderId") Integer leaderId,
@JsonProperty("wasLeader") boolean wasLeader,
@JsonProperty("hasAge") boolean hasAge,
@JsonProperty("hasDegree") boolean hasDegree,
@JsonProperty("paperIds") List<Integer> paperIds,
@JsonProperty("papers") List<Paper> papers) {
@JsonProperty("papers") List<PaperDto> papers) {
this.id = id;
this.title = title;
this.status = status;
@ -92,7 +92,7 @@ public class GrantDto {
this.hasAge = false;
this.hasDegree = false;
this.paperIds = convert(grant.getPapers(), paper -> paper.getId());
this.papers = grant.getPapers();
this.papers = convert(grant.getPapers(), PaperDto::new);
}
public Integer getId() {
@ -214,11 +214,11 @@ public class GrantDto {
this.paperIds = paperIds;
}
public List<Paper> getPapers() {
public List<PaperDto> getPapers() {
return papers;
}
public void setPapers(List<Paper> papers) {
public void setPapers(List<PaperDto> papers) {
this.papers = papers;
}

View File

@ -11,6 +11,7 @@ import ru.ulstu.grant.model.Grant;
import ru.ulstu.grant.model.GrantDto;
import ru.ulstu.grant.repository.GrantRepository;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.paper.model.PaperDto;
import ru.ulstu.paper.service.PaperService;
import ru.ulstu.project.model.Project;
import ru.ulstu.project.model.ProjectDto;
@ -34,7 +35,7 @@ import static ru.ulstu.grant.model.Grant.GrantStatus.APPLICATION;
@Service
public class GrantService {
private final static int MAX_DISPLAY_SIZE = 40;
private final static int MAX_DISPLAY_SIZE = 50;
private final GrantRepository grantRepository;
private final ProjectService projectService;
@ -210,17 +211,16 @@ public class GrantService {
.collect(toList());
}
public List<Paper> getGrantPapers(List<Integer> paperIds) {
public List<PaperDto> getGrantPapers(List<Integer> paperIds) {
return paperService.findAllSelect(paperIds);
}
public List<Paper> getAllPapers() {
return paperService.findAll();
}
public List<Paper> getAllUncompletedPapers() {
return paperService.findAllNotCompleted();
public List<PaperDto> getAllUncompletedPapers() {
List<PaperDto> papers = paperService.findAllNotCompleted();
papers.stream()
.forEach(paper ->
paper.setTitle(StringUtils.abbreviate(paper.getTitle(), MAX_DISPLAY_SIZE)));
return papers;
}
public void attachPaper(GrantDto grantDto) {

View File

@ -0,0 +1,7 @@
package ru.ulstu.name;
import org.springframework.data.repository.query.Param;
public interface BaseRepository {
String findByNameAndNotId(@Param("name") String name, @Param("id") Integer id);
}

View File

@ -0,0 +1,16 @@
package ru.ulstu.name;
import org.springframework.stereotype.Service;
import org.springframework.validation.Errors;
@Service
public abstract class BaseService {
public BaseRepository baseRepository;
public void checkUniqueName(NameContainer nameContainer, Errors errors, Integer id, String checkField, String errorMessage) {
if (nameContainer.getName().equals(baseRepository.findByNameAndNotId(nameContainer.getName(), id))) {
errors.rejectValue(checkField, "errorCode", errorMessage);
}
}
}

View File

@ -0,0 +1,14 @@
package ru.ulstu.name;
public abstract class NameContainer {
private String name = "";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -248,12 +248,12 @@ public class PaperService {
}
}
public List<Paper> findAllNotCompleted() {
return paperRepository.findByStatusNot(COMPLETED);
public List<PaperDto> findAllNotCompleted() {
return convert(paperRepository.findByStatusNot(COMPLETED), PaperDto::new);
}
public List<Paper> findAllSelect(List<Integer> paperIds) {
return sortPapers(paperRepository.findAllByIdIn(paperIds));
public List<PaperDto> findAllSelect(List<Integer> paperIds) {
return convert(paperRepository.findAllByIdIn(paperIds), PaperDto::new);
}
public List<User> getPaperAuthors() {

View File

@ -67,6 +67,7 @@ public class Task extends BaseEntity {
private Date updateDate = new Date();
@ManyToMany(fetch = FetchType.EAGER)
@Fetch(FetchMode.SUBSELECT)
@JoinTable(name = "task_tags",
joinColumns = {@JoinColumn(name = "task_id")},
inverseJoinColumns = {@JoinColumn(name = "tag_id")})
@ -127,4 +128,5 @@ public class Task extends BaseEntity {
public void setTags(List<Tag> tags) {
this.tags = tags;
}
}

View File

@ -15,6 +15,7 @@ import ru.ulstu.students.repository.SchedulerRepository;
import ru.ulstu.students.repository.TaskRepository;
import ru.ulstu.tags.model.Tag;
import ru.ulstu.tags.service.TagService;
import ru.ulstu.timeline.service.EventService;
import java.io.IOException;
import java.util.ArrayList;
@ -40,13 +41,15 @@ public class TaskService {
private final SchedulerRepository schedulerRepository;
private final DeadlineService deadlineService;
private final TagService tagService;
private final EventService eventService;
public TaskService(TaskRepository taskRepository,
DeadlineService deadlineService, TagService tagService, SchedulerRepository schedulerRepository) {
DeadlineService deadlineService, TagService tagService, SchedulerRepository schedulerRepository, EventService eventService) {
this.taskRepository = taskRepository;
this.deadlineService = deadlineService;
this.tagService = tagService;
this.eventService = eventService;
this.schedulerRepository = schedulerRepository;
}
@ -80,6 +83,7 @@ public class TaskService {
public Integer create(TaskDto taskDto) throws IOException {
Task newTask = copyFromDto(new Task(), taskDto);
newTask = taskRepository.save(newTask);
eventService.createFromTask(newTask);
return newTask.getId();
}
@ -99,6 +103,7 @@ public class TaskService {
public Integer update(TaskDto taskDto) throws IOException {
Task task = taskRepository.findOne(taskDto.getId());
taskRepository.save(copyFromDto(task, taskDto));
eventService.updateTaskDeadlines(task);
return task.getId();
}
@ -173,13 +178,9 @@ public class TaskService {
private boolean equalsDate(Task task) {
Calendar taskDate = DateUtils.getCalendar(task.getCreateDate());
Calendar nowDate = DateUtils.getCalendar(new Date());
if (taskDate.get(Calendar.DAY_OF_MONTH) == nowDate.get(Calendar.DAY_OF_MONTH) &&
return (taskDate.get(Calendar.DAY_OF_MONTH) == nowDate.get(Calendar.DAY_OF_MONTH) &&
taskDate.get(Calendar.MONTH) + 1 == nowDate.get(Calendar.MONTH) + 1 &&
taskDate.get(Calendar.YEAR) + 1 == nowDate.get(Calendar.YEAR)) {
return true;
} else {
return false;
}
taskDate.get(Calendar.YEAR) + 1 == nowDate.get(Calendar.YEAR));
}
@Transactional

View File

@ -5,6 +5,7 @@ import ru.ulstu.conference.model.Conference;
import ru.ulstu.core.model.BaseEntity;
import ru.ulstu.grant.model.Grant;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.students.model.Task;
import ru.ulstu.user.model.User;
import javax.persistence.CascadeType;
@ -87,6 +88,10 @@ public class Event extends BaseEntity {
@JoinColumn(name = "grant_id")
private Grant grant;
@ManyToOne
@JoinColumn(name = "task_id")
private Task task;
public String getTitle() {
return title;
}
@ -190,4 +195,12 @@ public class Event extends BaseEntity {
public void setGrant(Grant grant) {
this.grant = grant;
}
public Task getTask() {
return task;
}
public void setTask(Task task) {
this.task = task;
}
}

View File

@ -6,6 +6,7 @@ import org.hibernate.validator.constraints.NotBlank;
import ru.ulstu.conference.model.ConferenceDto;
import ru.ulstu.grant.model.GrantDto;
import ru.ulstu.paper.model.PaperDto;
import ru.ulstu.students.model.TaskDto;
import ru.ulstu.user.model.UserDto;
import javax.validation.constraints.NotNull;
@ -29,6 +30,7 @@ public class EventDto {
private PaperDto paperDto;
private ConferenceDto conferenceDto;
private GrantDto grantDto;
private TaskDto taskDto;
@JsonCreator
public EventDto(@JsonProperty("id") Integer id,
@ -42,7 +44,8 @@ public class EventDto {
@JsonProperty("paperDto") PaperDto paperDto,
@JsonProperty("recipients") List<UserDto> recipients,
@JsonProperty("conferenceDto") ConferenceDto conferenceDto,
@JsonProperty("grantDto") GrantDto grantDto) {
@JsonProperty("grantDto") GrantDto grantDto,
@JsonProperty("taskDto") TaskDto taskDto) {
this.id = id;
this.title = title;
this.period = period;
@ -55,6 +58,7 @@ public class EventDto {
this.paperDto = paperDto;
this.conferenceDto = conferenceDto;
this.grantDto = grantDto;
this.taskDto = taskDto;
}
public EventDto(Event event) {
@ -76,6 +80,9 @@ public class EventDto {
if (grantDto != null) {
this.grantDto = new GrantDto(event.getGrant());
}
if (taskDto != null) {
this.taskDto = new TaskDto(event.getTask());
}
}
public Integer getId() {
@ -137,4 +144,12 @@ public class EventDto {
public void setGrantDto(GrantDto grantDto) {
this.grantDto = grantDto;
}
public TaskDto getTaskDto() {
return taskDto;
}
public void setTaskDto(TaskDto taskDto) {
this.taskDto = taskDto;
}
}

View File

@ -5,6 +5,7 @@ import org.springframework.data.jpa.repository.Query;
import ru.ulstu.conference.model.Conference;
import ru.ulstu.grant.model.Grant;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.students.model.Task;
import ru.ulstu.timeline.model.Event;
import java.util.List;
@ -21,4 +22,6 @@ public interface EventRepository extends JpaRepository<Event, Integer> {
List<Event> findAllByConference(Conference conference);
List<Event> findAllByGrant(Grant grant);
List<Event> findAllByTask(Task task);
}

View File

@ -8,6 +8,7 @@ import ru.ulstu.conference.model.Conference;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.grant.model.Grant;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.students.model.Task;
import ru.ulstu.timeline.model.Event;
import ru.ulstu.timeline.model.EventDto;
import ru.ulstu.timeline.model.Timeline;
@ -203,4 +204,38 @@ public class EventService {
eventRepository.delete(eventRepository.findAllByGrant(grant));
createFromGrant(grant);
}
public void removeConferencesEvent(Conference conference) {
List<Event> eventList = eventRepository.findAllByConference(conference);
eventList.forEach(event -> eventRepository.delete(event.getId()));
}
public void createFromTask(Task newTask) {
List<Timeline> timelines = timelineService.findAll();
Timeline timeline = timelines.isEmpty() ? new Timeline() : timelines.get(0);
for (Deadline deadline : newTask.getDeadlines()
.stream()
.filter(d -> d.getDate().after(new Date()) || DateUtils.isSameDay(d.getDate(), new Date()))
.collect(Collectors.toList())) {
Event newEvent = new Event();
newEvent.setTitle("Дедлайн задачи");
newEvent.setStatus(Event.EventStatus.NEW);
newEvent.setExecuteDate(deadline.getDate());
newEvent.setCreateDate(new Date());
newEvent.setUpdateDate(new Date());
newEvent.setDescription("Дедлайн '" + deadline.getDescription() + "' задачи '" + newTask.getTitle() + "'");
newEvent.getRecipients().add(userService.getCurrentUser());
newEvent.setTask(newTask);
eventRepository.save(newEvent);
timeline.getEvents().add(newEvent);
timelineService.save(timeline);
}
}
public void updateTaskDeadlines(Task task) {
eventRepository.delete(eventRepository.findAllByTask(task));
createFromTask(task);
}
}

View File

@ -0,0 +1,13 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet author="nastya" id="20190511_000000-1">
<addColumn tableName="event">
<column name="task_id" type="integer"></column>
</addColumn>
<addForeignKeyConstraint baseTableName="event" baseColumnNames="task_id"
constraintName="fk_event_task_id" referencedTableName="task"
referencedColumnNames="id"/>
</changeSet>
</databaseChangeLog>

View File

@ -41,4 +41,5 @@
<include file="db/changelog-20190505_000001-schema.xml"/>
<include file="db/changelog-20190507_000000-schema.xml"/>
<include file="db/changelog-20190507_000001-schema.xml"/>
<include file="db/changelog-20190511_000000-schema.xml"/>
</databaseChangeLog>

View File

@ -140,6 +140,7 @@ body {
.paper-name {
flex: 1;
overflow: hidden;
}
.paper-name:hover {
@ -156,6 +157,15 @@ body {
float: left;
}
.paper-name span:nth-child(2) {
max-width: 326px;
white-space: nowrap;
}
.dropdown-menu {
max-width: 445px;
}
.icon {

View File

@ -62,6 +62,42 @@
}
.task-row{
position: relative;
}
.task-row .col:hover{
background-color: #f8f9fa;
}
.task-row .col > a{
display: block;
text-decoration: none;
}
.task-row .col:hover .remove-task{
visibility: visible;
}
.remove-task{
visibility: hidden;
position: absolute;
right: -20px;
top: 50%;
transform: translate(-50%, -50%);
padding: 0 20px;
}
.remove-task:hover{
background-color: #ebebeb;
}
.tag {
display: inline-block;
padding: .2em .6em .3em;

View File

@ -25,4 +25,5 @@ $(document).ready(function () {
$('#dataConfirmModal').modal({show:true});
return false;
});
});

View File

@ -78,17 +78,17 @@ $(document).ready(function () {
});
$("span[data-role=remove]").click(removeTag);
$(".task-row").mouseenter(function (event) {
var taskRow = $(event.target).closest(".task-row");
$(taskRow).css("background-color", "#f8f9fa");
$(taskRow).find(".remove-task").removeClass("d-none");
});
$(".task-row").mouseleave(function (event) {
var taskRow = $(event.target).closest(".task-row");
$(taskRow).css("background-color", "white");
$(taskRow).closest(".task-row").find(".remove-task").addClass("d-none");
});
// $(".task-row").mouseenter(function (event) {
// var taskRow = $(event.target).closest(".task-row");
// $(taskRow).css("background-color", "#f8f9fa");
// $(taskRow).find(".remove-task").removeClass("d-none");
//
// });
// $(".task-row").mouseleave(function (event) {
// var taskRow = $(event.target).closest(".task-row");
// $(taskRow).css("background-color", "white");
// $(taskRow).closest(".task-row").find(".remove-task").addClass("d-none");
// });
$('a[data-confirm]').click(function(ev) {
var href = $(this).attr('href');

View File

@ -30,11 +30,12 @@
<label for="title">Название:</label>
<input class="form-control" th:field="*{title}" id="title" type="text"
placeholder="Название конференции"/>
<p th:if="${#fields.hasErrors('title')}" th:errors="*{title}"
class="alert alert-danger">Incorrect title</p>
<p class="help-block text-danger"></p>
</div>
<p th:if="${#fields.hasErrors('title')}" th:errors="*{title}"
class="alert alert-danger">Incorrect title</p>
<p class="help-block text-danger"></p>
<div class="form-group">
<label for="url">URL:</label>
<input class="form-control" th:field="*{url}" id="url" type="text"

View File

@ -184,9 +184,9 @@
value="Отобразить прикрепленную статью"/>
</div>
<div class="row">
<input th:type="hidden" th:field="*{papers}"/>
<div class="form-control list-group div-selected-papers" id="selected-papers">
<div th:each="paper, rowStat : *{papers}">
<input type="hidden" th:field="*{papers[__${rowStat.index}__].id}"/>
<div class="col">
<a th:href="@{'/papers/paper?id=' + *{papers[__${rowStat.index}__].id} + ''}">
<img class="icon-paper" src="/img/conference/paper.png"/>
@ -201,6 +201,7 @@
Статус статьи
</span>
</div>
<!--
<div class="col" th:unless="${#lists.isEmpty(paper.grants)}">
<label>Гранты: </label>
<div th:each="grant, grantRowStat : *{papers[__${rowStat.index}__].grants}"
@ -225,6 +226,7 @@
</li>
</div>
</div>
-->
</div>
</div>
</div>

View File

@ -6,15 +6,15 @@
<body>
<div th:fragment="taskLine (task)" class="row text-left task-row" style="background-color: white;">
<div class="col">
<span th:replace="students/fragments/taskStatusFragment :: taskStatus(taskStatus=${task.status})"/>
<a th:href="@{'task?id='+${task.id}}">
<span th:replace="students/fragments/taskStatusFragment :: taskStatus(taskStatus=${task.status})"/>
<span class="h6" th:text="${task.title}"></span>
<span class="text-muted" th:text="${task.tagsString}"/>
</a>
<input class="id-class" type="hidden" th:value="${task.id}"/>
<a class="remove-task pull-right d-none" th:href="@{'/students/delete/'+${task.id}}"
data-confirm="Удалить задачу?">
<i class="fa fa-trash" aria-hidden="true"></i>
<input class="id-class" type="hidden" th:value="${task.id}"/>
<a class="remove-task pull-right" th:href="@{'/students/delete/'+${task.id}}"
data-confirm="Удалить задачу?">
<i class="fa fa-trash" aria-hidden="true"></i>
</a>
</a>
</div>
</div>

View File

@ -0,0 +1,230 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import conference.ConferencePage;
import conference.ConferencesDashboardPage;
import conference.ConferencesPage;
import core.PageObject;
import core.TestTemplate;
import org.junit.Assert;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import ru.ulstu.NgTrackerApplication;
import ru.ulstu.configuration.ApplicationProperties;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
@RunWith(SpringRunner.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@SpringBootTest(classes = NgTrackerApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class IndexConferenceTest extends TestTemplate {
private final Map<PageObject, List<String>> navigationHolder = ImmutableMap.of(
new ConferencesPage(), Arrays.asList("КОНФЕРЕНЦИИ", "/conferences/conferences"),
new ConferencePage(), Arrays.asList("РЕДАКТИРОВАНИЕ КОНФЕРЕНЦИИ", "/conferences/conference?id=0"),
new ConferencesDashboardPage(), Arrays.asList("АКТУАЛЬНЫЕ КОНФЕРЕНЦИИ", "/conferences/dashboard")
);
@Autowired
private ApplicationProperties applicationProperties;
@Test
public void testACreateNewConference() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 1);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ConferencePage conferencePage = (ConferencePage) getContext().initPage(page.getKey());
ConferencesPage conferencesPage = (ConferencesPage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 0).getKey());
String newConferenceName = "test " + (new Date()).getTime();
conferencePage.setName(newConferenceName);
conferencePage.clickSaveBut();
Assert.assertTrue(conferencesPage.checkNameInList(newConferenceName));
}
@Test
public void testBChangeConferenceNameAndSave() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ConferencesPage conferencesPage = (ConferencesPage) getContext().initPage(page.getKey());
ConferencePage conferencePage = (ConferencePage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
conferencesPage.getFirstConference();
String newConferenceName = "test " + (new Date()).getTime();
conferencePage.clearName();
conferencePage.setName(newConferenceName);
conferencePage.clickSaveBut();
Assert.assertTrue(conferencesPage.checkNameInList(newConferenceName));
}
@Test
public void testCAddDeadlineAndSave() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ConferencesPage conferencesPage = (ConferencesPage) getContext().initPage(page.getKey());
ConferencePage conferencePage = (ConferencePage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
conferencesPage.getFirstConference();
String conferenceId = conferencePage.getId();
Integer deadlineCount = conferencePage.getDeadlineCount();
String description = "test";
String date = "09.09.2019";
String dateValue = "2019-09-09";
conferencePage.clickAddDeadlineBut();
conferencePage.setDeadlineDescription(description, deadlineCount);
conferencePage.setDeadlineDate(date, deadlineCount);
conferencePage.clickSaveBut();
getContext().goTo(applicationProperties.getBaseUrl() + String.format("/conferences/conference?id=%s", conferenceId));
Assert.assertTrue(conferencePage.checkDeadline(description, dateValue));
}
@Test
public void testDTakePartAndSave() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ConferencesPage conferencesPage = (ConferencesPage) getContext().initPage(page.getKey());
ConferencePage conferencePage = (ConferencePage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
conferencesPage.getFirstConference();
String conferenceId = conferencePage.getId();
Integer membersCount = conferencePage.getMemberCount();
conferencePage.clickTakePartBut();
conferencePage.clickSaveBut();
getContext().goTo(applicationProperties.getBaseUrl() + String.format("/conferences/conference?id=%s", conferenceId));
Assert.assertTrue(membersCount + 1 == conferencePage.getMemberCount()
&& conferencePage.isTakePartButDisabledValueTrue());
}
@Test
public void testEDeleteDeadlineAndSave() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ConferencesPage conferencesPage = (ConferencesPage) getContext().initPage(page.getKey());
ConferencePage conferencePage = (ConferencePage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
conferencesPage.getFirstConference();
String conferenceId = conferencePage.getId();
Integer deadlineCount = conferencePage.getDeadlineCount();
conferencePage.clickDeleteDeadlineBut();
conferencePage.clickSaveBut();
getContext().goTo(applicationProperties.getBaseUrl() + String.format("/conferences/conference?id=%s", conferenceId));
Assert.assertEquals(deadlineCount - 1, (int) conferencePage.getDeadlineCount());
}
@Test
public void testFAttachArticle() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ConferencesPage conferencesPage = (ConferencesPage) getContext().initPage(page.getKey());
ConferencePage conferencePage = (ConferencePage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
conferencesPage.getFirstConference();
String conferenceId = conferencePage.getId();
Integer paperCount = conferencePage.getArticlesCount();
conferencePage.showAllowToAttachArticles();
WebElement paper = conferencePage.selectArticle();
String paperName = paper.findElement(By.className("text")).getText();
conferencePage.clickSaveBut();
getContext().goTo(applicationProperties.getBaseUrl() + String.format("/conferences/conference?id=%s", conferenceId));
Assert.assertTrue(paperCount + 1 == conferencePage.getArticlesCount()
&& conferencePage.checkArticle(paperName));
}
@Test
public void testGAddArticle() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ConferencesPage conferencesPage = (ConferencesPage) getContext().initPage(page.getKey());
ConferencePage conferencePage = (ConferencePage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
conferencesPage.getFirstConference();
String conferenceId = conferencePage.getId();
Integer paperCount = conferencePage.getArticlesCount();
conferencePage.clickAddPaperBut();
List<WebElement> webElements = conferencePage.getArticles();
String paperName = webElements.get(webElements.size() - 1).findElements(By.tagName("input")).get(1).getAttribute("value");
conferencePage.clickSaveBut();
getContext().goTo(applicationProperties.getBaseUrl() + String.format("/conferences/conference?id=%s", conferenceId));
Assert.assertTrue(paperCount + 1 == conferencePage.getArticlesCount()
&& conferencePage.checkArticle(paperName));
}
@Test
public void testHUndockArticle() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ConferencesPage conferencesPage = (ConferencesPage) getContext().initPage(page.getKey());
ConferencePage conferencePage = (ConferencePage) getContext().initPage(Iterables.get(navigationHolder.entrySet(), 1).getKey());
conferencesPage.getFirstConference();
String conferenceId = conferencePage.getId();
Integer paperCount = conferencePage.getArticlesCount();
conferencePage.clickUndockArticleBut();
conferencePage.clickSaveBut();
getContext().goTo(applicationProperties.getBaseUrl() + String.format("/conferences/conference?id=%s", conferenceId));
Assert.assertEquals(paperCount - 1, (int) conferencePage.getArticlesCount());
}
@Test
public void testISortAndFilterConferenceList() {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ConferencesPage conferencesPage = (ConferencesPage) getContext().initPage(page.getKey());
conferencesPage.selectMember();
conferencesPage.selectYear();
Assert.assertEquals(1, conferencesPage.getConferencesList().size());
}
@Test
public void testJDeleteConf() throws InterruptedException {
Map.Entry<PageObject, List<String>> page = Iterables.get(navigationHolder.entrySet(), 0);
getContext().goTo(applicationProperties.getBaseUrl() + page.getValue().get(1));
ConferencesPage conferencesPage = (ConferencesPage) getContext().initPage(page.getKey());
Integer size = conferencesPage.getConferencesList().size();
conferencesPage.deleteFirst();
Thread.sleep(3000);
conferencesPage.clickConfirm();
Assert.assertEquals(size - 1, conferencesPage.getConferencesList().size());
}
}

View File

@ -0,0 +1,116 @@
package conference;
import core.PageObject;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import java.util.List;
public class ConferencePage extends PageObject {
public String getSubTitle() {
return driver.findElement(By.tagName("h3")).getText();
}
public String getId() {
return driver.findElement(By.id("id")).getAttribute("value");
}
public void setName(String name) {
driver.findElement(By.id("title")).sendKeys(name);
}
public String getName() {
return driver.findElement(By.id("title")).getAttribute("value");
}
public void clearName() {
driver.findElement(By.id("title")).clear();
}
public void clickSaveBut() {
driver.findElement(By.id("send-message-button")).click();
}
public void clickAddDeadlineBut() {
driver.findElement(By.id("addDeadline")).click();
}
public List<WebElement> getDeadlineList() {
return driver.findElements(By.className("deadline"));
}
public Integer getDeadlineCount() {
return driver.findElements(By.className("deadline")).size();
}
public void setDeadlineDescription(String description, Integer i) {
driver.findElement(By.id(String.format("deadlines%d.description", i))).sendKeys(description);
}
public void setDeadlineDate(String date, Integer i) {
driver.findElement(By.id(String.format("deadlines%d.date", i))).sendKeys(date);
}
public void clickTakePartBut() {
driver.findElement(By.id("take-part")).click();
}
public Boolean isTakePartButDisabledValueTrue() {
return driver.findElement(By.id("take-part")).getAttribute("disabled").equals("true");
}
public Integer getMemberCount() {
return driver.findElements(By.className("member")).size();
}
public void clickDeleteDeadlineBut() {
driver.findElement(By.xpath("//*[@id=\"deadlines\"]/div/input[4]")).click();
}
public void showAllowToAttachArticles() {
driver.findElement(By.cssSelector("button[data-id=\"paperIds\"]")).click();
}
public void clickAddPaperBut() {
driver.findElement(By.id("add-paper")).click();
}
public List<WebElement> getArticles() {
return driver.findElements(By.className("paper"));
}
public Integer getArticlesCount() {
return driver.findElements(By.className("paper")).size();
}
public WebElement selectArticle() {
WebElement webElement = driver.findElement(By.xpath("//*[@id=\"conference-form\"]/div/div[2]/div[5]/div/div/div[2]/ul/li[1]/a"));
webElement.click();
return webElement;
}
public void clickUndockArticleBut() {
driver.findElement(By.name("removePaper")).click();
}
public boolean checkDeadline(String description, String dateValue) {
return getDeadlineList()
.stream()
.anyMatch(webElement -> {
return webElement.findElement(By.className("deadline-text")).getAttribute("value").equals(description)
&& webElement.findElement(By.cssSelector("input[type=\"date\"]")).getAttribute("value").equals(dateValue);
});
}
public boolean checkArticle(String paperName) {
return getArticles()
.stream()
.anyMatch(webElement -> webElement
.findElements(By.tagName("input"))
.get(1).getAttribute("value")
.equals(paperName));
}
}

View File

@ -0,0 +1,11 @@
package conference;
import core.PageObject;
import org.openqa.selenium.By;
public class ConferencesDashboardPage extends PageObject {
public String getSubTitle() {
return driver.findElement(By.tagName("h2")).getText();
}
}

View File

@ -0,0 +1,47 @@
package conference;
import core.PageObject;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import java.util.List;
public class ConferencesPage extends PageObject {
public String getSubTitle() {
return driver.findElement(By.tagName("h3")).getText();
}
public List<WebElement> getConferencesList() {
return driver.findElements(By.cssSelector("span.h6.float-left.m-2"));
}
public void getFirstConference() {
driver.findElement(By.xpath("//*[@id=\"conferences\"]/div/div[2]/div[1]/div[1]/div/a")).click();
}
public void selectMember() {
driver.findElements(By.className("bootstrap-select")).get(0).findElement(By.className("btn")).click();
driver.findElements(By.className("bootstrap-select")).get(0).findElements(By.className("dropdown-item")).get(1).click();
}
public void selectYear() {
driver.findElements(By.className("bootstrap-select")).get(1).findElement(By.className("btn")).click();
driver.findElements(By.className("bootstrap-select")).get(1).findElements(By.className("dropdown-item")).get(1).click();
}
public void deleteFirst() {
js.executeScript("$('input[data-confirm]').click();");
}
public void clickConfirm() {
driver.findElement(By.id("deleteConference")).click();
}
public boolean checkNameInList(String newConferenceName) {
return getConferencesList()
.stream()
.anyMatch(webElement -> webElement.getText().equals(newConferenceName));
}
}

View File

@ -1,14 +1,17 @@
package core;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
public abstract class PageObject {
protected WebDriver driver;
protected JavascriptExecutor js;
public abstract String getSubTitle();
public PageObject setDriver(WebDriver driver) {
this.driver = driver;
js = (JavascriptExecutor) driver;
return this;
}
}