diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..869c305
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/gson_2_9_0.xml b/.idea/libraries/gson_2_9_0.xml
new file mode 100644
index 0000000..2377008
--- /dev/null
+++ b/.idea/libraries/gson_2_9_0.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/java-kanban.iml b/java-kanban.iml
index 635e7f3..6982687 100644
--- a/java-kanban.iml
+++ b/java-kanban.iml
@@ -40,5 +40,6 @@
+
\ No newline at end of file
diff --git a/src/Main.java b/src/Main.java
index a17bfa5..b3a2f0a 100644
--- a/src/Main.java
+++ b/src/Main.java
@@ -9,7 +9,7 @@
public class Main {
- public static void main(String[] args) {
+ public static void main(String[] args) throws InterruptedException {
final long MINUTES_IN_DAY = 60 * 24;
final LocalDateTime TASK_START_TIME = LocalDateTime.now();
System.out.println("Поехали!");
diff --git a/src/tracker/adapter/LocalDateAdapter.java b/src/tracker/adapter/LocalDateAdapter.java
new file mode 100644
index 0000000..976e3a5
--- /dev/null
+++ b/src/tracker/adapter/LocalDateAdapter.java
@@ -0,0 +1,23 @@
+package tracker.adapter;
+
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+public class LocalDateAdapter extends TypeAdapter {
+ private static final DateTimeFormatter dtf = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
+
+ @Override
+ public void write(final JsonWriter jsonWriter, final LocalDateTime localDate) throws IOException {
+ jsonWriter.value(localDate.format(dtf));
+ }
+
+ @Override
+ public LocalDateTime read(final JsonReader jsonReader) throws IOException {
+ return LocalDateTime.parse(jsonReader.nextString(), dtf);
+ }
+}
diff --git a/src/tracker/controllers/InMemoryTaskManager.java b/src/tracker/controllers/InMemoryTaskManager.java
index 4c6e9c5..794aaf3 100644
--- a/src/tracker/controllers/InMemoryTaskManager.java
+++ b/src/tracker/controllers/InMemoryTaskManager.java
@@ -1,5 +1,6 @@
package tracker.controllers;
+import tracker.exceptions.OverlapsException;
import tracker.model.Epic;
import tracker.model.Status;
import tracker.model.Subtask;
@@ -134,26 +135,20 @@ public ArrayList getEpicsSubtasks(int epicId) {
// Создание. Сам объект должен передаваться в качестве параметра.
@Override
public void createTask(Task task) {
- if (noIntersectionWithTasks(task)) {
- tasks.put(taskId, task);
- sortedTasks.add(task);
- taskId++;
- } else {
- System.out.println("Пересечение с текущими задачами");
- }
+ hasIntersectionWithTasks(task);
+ tasks.put(taskId, task);
+ sortedTasks.add(task);
+ taskId++;
}
@Override
public void createSubtask(Subtask task) {
- if (noIntersectionWithTasks(task)) {
- subtasks.put(taskId, task);
- sortedTasks.add(task);
- updateEpicStatus(task.getEpic());
- updateEpicEndTimeAndDuration(task.getEpic());
- taskId++;
- } else {
- System.out.println("Пересечение с текущими задачами.");
- }
+ hasIntersectionWithTasks(task);
+ subtasks.put(taskId, task);
+ sortedTasks.add(task);
+ updateEpicStatus(task.getEpic());
+ updateEpicEndTimeAndDuration(task.getEpic());
+ taskId++;
}
@Override
@@ -169,13 +164,10 @@ public void updateTask(Task task) {
if (updatedTask == null) {
System.out.println("Задача с id = " + task.getId() + " не найдена");
}
- if (noIntersectionWithTasks(task)) {
- sortedTasks.remove(updatedTask);
- tasks.put(task.getId(), task);
- sortedTasks.add(task);
- } else {
- System.out.println("Пересечение с текущими задачами");
- }
+ hasIntersectionWithTasks(task);
+ sortedTasks.remove(updatedTask);
+ tasks.put(task.getId(), task);
+ sortedTasks.add(task);
}
@Override
@@ -184,15 +176,12 @@ public void updateSubtask(Subtask task) {
if (updatedTask == null) {
System.out.println("Задача с id = " + task.getId() + " не найдена");
}
- if (noIntersectionWithTasks(task)) {
- sortedTasks.remove(updatedTask);
- subtasks.put(task.getId(), task);
- sortedTasks.add(task);
- updateEpicStatus(task.getEpic());
- updateEpicEndTimeAndDuration(task.getEpic());
- } else {
- System.out.println("Пересечение с текущими задачами");
- }
+ hasIntersectionWithTasks(task);
+ sortedTasks.remove(updatedTask);
+ subtasks.put(task.getId(), task);
+ sortedTasks.add(task);
+ updateEpicStatus(task.getEpic());
+ updateEpicEndTimeAndDuration(task.getEpic());
}
@Override
@@ -303,12 +292,14 @@ private boolean intersectionChecked(T task1, T task2) {
&& (endTime1.isAfter(endTime2) || endTime1.isEqual(endTime2));
}
- private boolean noIntersectionWithTasks(T task) {
+ private void hasIntersectionWithTasks(T task) {
List intersectedTasks = sortedTasks.stream()
.filter(currentTask -> !currentTask.equals(task))
.filter(currentTask -> intersectionChecked(task, currentTask))
.toList();
- return intersectedTasks.isEmpty();
+ if (!intersectedTasks.isEmpty()) {
+ throw new OverlapsException("Есть пересечение с текущими задачами");
+ }
}
}
diff --git a/src/tracker/exceptions/OverlapsException.java b/src/tracker/exceptions/OverlapsException.java
new file mode 100644
index 0000000..887d7a0
--- /dev/null
+++ b/src/tracker/exceptions/OverlapsException.java
@@ -0,0 +1,7 @@
+package tracker.exceptions;
+
+public class OverlapsException extends RuntimeException {
+ public OverlapsException(final String message) {
+ super(message);
+ }
+}
diff --git a/src/tracker/handler/BaseHttpHandler.java b/src/tracker/handler/BaseHttpHandler.java
new file mode 100644
index 0000000..c3a310d
--- /dev/null
+++ b/src/tracker/handler/BaseHttpHandler.java
@@ -0,0 +1,44 @@
+package tracker.handler;
+
+import com.google.gson.Gson;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import tracker.controllers.TaskManager;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+
+public abstract class BaseHttpHandler implements HttpHandler {
+ protected final Gson gson;
+ protected final TaskManager taskManager;
+ protected final Charset charset = StandardCharsets.UTF_8;
+
+ public BaseHttpHandler(Gson gson, TaskManager taskManager) {
+ this.gson = gson;
+ this.taskManager = taskManager;
+ }
+
+ public static void sendText(HttpExchange httpExchange, String text, int code) throws IOException {
+ byte[] response = text.getBytes(StandardCharsets.UTF_8);
+ httpExchange.getResponseHeaders().add("Content-Type", "application/json;charset=utf-8");
+ httpExchange.sendResponseHeaders(code, response.length);
+ httpExchange.getResponseBody().write(response);
+ httpExchange.close();
+ }
+
+ public static void sendNotFound(HttpExchange httpExchange) throws IOException {
+ httpExchange.sendResponseHeaders(404, 0);
+ httpExchange.close();
+ }
+
+ public static void sendHasOverlaps(HttpExchange httpExchange) throws IOException {
+ httpExchange.sendResponseHeaders(406, 0);
+ httpExchange.close();
+ }
+
+ public static void sendServerError(HttpExchange httpExchange) throws IOException {
+ httpExchange.sendResponseHeaders(500, 0);
+ httpExchange.close();
+ }
+}
diff --git a/src/tracker/handler/EpicsHandler.java b/src/tracker/handler/EpicsHandler.java
new file mode 100644
index 0000000..5b450fa
--- /dev/null
+++ b/src/tracker/handler/EpicsHandler.java
@@ -0,0 +1,82 @@
+package tracker.handler;
+
+import com.google.gson.Gson;
+import com.sun.net.httpserver.HttpExchange;
+import tracker.controllers.TaskManager;
+import tracker.model.Epic;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class EpicsHandler extends BaseHttpHandler {
+ public EpicsHandler(Gson gson, TaskManager taskManager) {
+ super(gson, taskManager);
+ }
+
+ @Override
+ public void handle(HttpExchange httpExchange) throws IOException {
+ String method = httpExchange.getRequestMethod();
+ String path = httpExchange.getRequestURI().getPath();
+ String[] partsOfPath = path.split("/");
+ switch (method) {
+ case "GET" -> {
+ if (partsOfPath.length == 2) {
+ BaseHttpHandler.sendText(httpExchange, gson.toJson(taskManager.getEpics()), 200);
+ return;
+ } else if (partsOfPath.length == 3) {
+ int id = Integer.parseInt(partsOfPath[2]);
+ Epic epic = taskManager.getEpicById(id);
+ if (epic == null) {
+ BaseHttpHandler.sendNotFound(httpExchange);
+ } else {
+ BaseHttpHandler.sendText(httpExchange, gson.toJson(epic), 200);
+ }
+ } else if (partsOfPath.length == 4 && partsOfPath[3].equals("subtasks")) {
+ int id = Integer.parseInt(partsOfPath[2]);
+ Epic epic = taskManager.getEpicById(id);
+ if (epic == null) {
+ BaseHttpHandler.sendNotFound(httpExchange);
+ } else {
+ BaseHttpHandler.sendText(httpExchange, gson.toJson(taskManager.getEpicsSubtasks(id)),
+ 200);
+ }
+ } else {
+ BaseHttpHandler.sendServerError(httpExchange);
+ }
+ httpExchange.close();
+ }
+ case "POST" -> {
+ if (partsOfPath.length == 2) {
+ InputStream inputStream = httpExchange.getRequestBody();
+ String body = new String(inputStream.readAllBytes(), charset);
+ if (body.isEmpty()) {
+ BaseHttpHandler.sendServerError(httpExchange);
+ } else {
+ Epic epic = gson.fromJson(body, Epic.class);
+ taskManager.createEpic(epic);
+ BaseHttpHandler.sendText(httpExchange, gson.toJson(epic), 201);
+ }
+ } else {
+ BaseHttpHandler.sendServerError(httpExchange);
+ }
+ httpExchange.close();
+ }
+ case "DELETE" -> {
+ if (partsOfPath.length == 3) {
+ int id = Integer.parseInt(partsOfPath[2]);
+ Epic epic = taskManager.getEpicById(id);
+ if (epic == null) {
+ BaseHttpHandler.sendNotFound(httpExchange);
+ } else {
+ taskManager.deleteEpic(epic);
+ BaseHttpHandler.sendText(httpExchange, gson.toJson(epic), 200);
+ }
+ } else {
+ BaseHttpHandler.sendServerError(httpExchange);
+ }
+ httpExchange.close();
+ }
+ default -> BaseHttpHandler.sendServerError(httpExchange);
+ }
+ }
+}
diff --git a/src/tracker/handler/HistoryHandler.java b/src/tracker/handler/HistoryHandler.java
new file mode 100644
index 0000000..d863443
--- /dev/null
+++ b/src/tracker/handler/HistoryHandler.java
@@ -0,0 +1,31 @@
+package tracker.handler;
+
+import com.google.gson.Gson;
+import com.sun.net.httpserver.HttpExchange;
+import tracker.controllers.TaskManager;
+
+import java.io.IOException;
+
+public class HistoryHandler extends BaseHttpHandler {
+ public HistoryHandler(Gson gson, TaskManager taskManager) {
+ super(gson, taskManager);
+ }
+
+ @Override
+ public void handle(HttpExchange httpExchange) throws IOException {
+ String method = httpExchange.getRequestMethod();
+ String path = httpExchange.getRequestURI().getPath();
+ String[] partsOfPath = path.split("/");
+ if (method.equals("GET")) {
+ if (partsOfPath.length == 2) {
+ BaseHttpHandler.sendText(httpExchange, gson.toJson(taskManager.getHistory()), 200);
+ return;
+ } else {
+ BaseHttpHandler.sendServerError(httpExchange);
+ }
+ httpExchange.close();
+ } else {
+ BaseHttpHandler.sendServerError(httpExchange);
+ }
+ }
+}
diff --git a/src/tracker/handler/PrioritizedHandler.java b/src/tracker/handler/PrioritizedHandler.java
new file mode 100644
index 0000000..3615b4d
--- /dev/null
+++ b/src/tracker/handler/PrioritizedHandler.java
@@ -0,0 +1,31 @@
+package tracker.handler;
+
+import com.google.gson.Gson;
+import com.sun.net.httpserver.HttpExchange;
+import tracker.controllers.TaskManager;
+
+import java.io.IOException;
+
+public class PrioritizedHandler extends BaseHttpHandler {
+ public PrioritizedHandler(Gson gson, TaskManager taskManager) {
+ super(gson, taskManager);
+ }
+
+ @Override
+ public void handle(HttpExchange httpExchange) throws IOException {
+ String method = httpExchange.getRequestMethod();
+ String path = httpExchange.getRequestURI().getPath();
+ String[] partsOfPath = path.split("/");
+ if (method.equals("GET")) {
+ if (partsOfPath.length == 2) {
+ BaseHttpHandler.sendText(httpExchange, gson.toJson(taskManager.getPrioritizedTasks()), 200);
+ return;
+ } else {
+ BaseHttpHandler.sendServerError(httpExchange);
+ }
+ httpExchange.close();
+ } else {
+ BaseHttpHandler.sendServerError(httpExchange);
+ }
+ }
+}
diff --git a/src/tracker/handler/SubtasksHandler.java b/src/tracker/handler/SubtasksHandler.java
new file mode 100644
index 0000000..0016dcb
--- /dev/null
+++ b/src/tracker/handler/SubtasksHandler.java
@@ -0,0 +1,93 @@
+package tracker.handler;
+
+import com.google.gson.Gson;
+import com.sun.net.httpserver.HttpExchange;
+import tracker.controllers.TaskManager;
+import tracker.exceptions.OverlapsException;
+import tracker.model.Subtask;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class SubtasksHandler extends BaseHttpHandler {
+ public SubtasksHandler(Gson gson, TaskManager taskManager) {
+ super(gson, taskManager);
+ }
+
+ @Override
+ public void handle(HttpExchange httpExchange) throws IOException {
+ String method = httpExchange.getRequestMethod();
+ String path = httpExchange.getRequestURI().getPath();
+ String[] partsOfPath = path.split("/");
+ switch (method) {
+ case "GET" -> {
+ if (partsOfPath.length == 2) {
+ BaseHttpHandler.sendText(httpExchange, gson.toJson(taskManager.getSubtasks()), 200);
+ return;
+ } else if (partsOfPath.length == 3) {
+ int id = Integer.parseInt(partsOfPath[2]);
+ Subtask task = taskManager.getSubtaskById(id);
+ if (task == null) {
+ BaseHttpHandler.sendNotFound(httpExchange);
+ } else {
+ BaseHttpHandler.sendText(httpExchange, gson.toJson(task), 200);
+ }
+ } else {
+ BaseHttpHandler.sendServerError(httpExchange);
+ }
+ httpExchange.close();
+ }
+ case "POST" -> {
+ if (partsOfPath.length == 2) {
+ InputStream inputStream = httpExchange.getRequestBody();
+ String body = new String(inputStream.readAllBytes(), charset);
+ Subtask task = gson.fromJson(body, Subtask.class);
+ if (body.isEmpty()) {
+ BaseHttpHandler.sendServerError(httpExchange);
+ } else {
+ if (task.getId() != 0) {
+ try {
+ taskManager.updateSubtask(task);
+ } catch (OverlapsException e) {
+ BaseHttpHandler.sendHasOverlaps(httpExchange);
+ }
+ } else {
+ try {
+ taskManager.createSubtask(new Subtask(task.getName(), task.getDescription(),
+ taskManager.getTaskId(), task.getStatus(), task.getEpic(), task.getDuration(),
+ task.getStartTime()));
+ } catch (OverlapsException e) {
+ BaseHttpHandler.sendHasOverlaps(httpExchange);
+ }
+ }
+ BaseHttpHandler.sendText(httpExchange, gson.toJson(task), 201);
+ }
+ try {
+ taskManager.createSubtask(task);
+ } catch (OverlapsException e) {
+ BaseHttpHandler.sendHasOverlaps(httpExchange);
+ }
+ } else {
+ BaseHttpHandler.sendHasOverlaps(httpExchange);
+ }
+ httpExchange.close();
+ }
+ case "DELETE" -> {
+ if (partsOfPath.length == 3) {
+ int id = Integer.parseInt(partsOfPath[2]);
+ Subtask task = taskManager.getSubtaskById(id);
+ if (task == null) {
+ BaseHttpHandler.sendNotFound(httpExchange);
+ } else {
+ taskManager.deleteSubtask(task);
+ BaseHttpHandler.sendText(httpExchange, gson.toJson(task), 200);
+ }
+ } else {
+ BaseHttpHandler.sendServerError(httpExchange);
+ }
+ httpExchange.close();
+ }
+ default -> BaseHttpHandler.sendServerError(httpExchange);
+ }
+ }
+}
diff --git a/src/tracker/handler/TasksHandler.java b/src/tracker/handler/TasksHandler.java
new file mode 100644
index 0000000..0f08596
--- /dev/null
+++ b/src/tracker/handler/TasksHandler.java
@@ -0,0 +1,88 @@
+package tracker.handler;
+
+import com.google.gson.Gson;
+import com.sun.net.httpserver.HttpExchange;
+import tracker.controllers.TaskManager;
+import tracker.exceptions.OverlapsException;
+import tracker.model.Task;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class TasksHandler extends BaseHttpHandler {
+ public TasksHandler(Gson gson, TaskManager taskManager) {
+ super(gson, taskManager);
+ }
+
+ @Override
+ public void handle(HttpExchange httpExchange) throws IOException {
+ String method = httpExchange.getRequestMethod();
+ String path = httpExchange.getRequestURI().getPath();
+ String[] partsOfPath = path.split("/");
+ switch (method) {
+ case "GET" -> {
+ if (partsOfPath.length == 2) {
+ BaseHttpHandler.sendText(httpExchange, gson.toJson(taskManager.getTasks()), 200);
+ return;
+ } else if (partsOfPath.length == 3) {
+ int id = Integer.parseInt(partsOfPath[2]);
+ Task task = taskManager.getTaskById(id);
+ if (task == null) {
+ BaseHttpHandler.sendNotFound(httpExchange);
+ } else {
+ BaseHttpHandler.sendText(httpExchange, gson.toJson(task), 200);
+ }
+ } else {
+ BaseHttpHandler.sendServerError(httpExchange);
+ }
+ httpExchange.close();
+ }
+ case "POST" -> {
+ if (partsOfPath.length == 2) {
+ InputStream inputStream = httpExchange.getRequestBody();
+ String body = new String(inputStream.readAllBytes(), charset);
+ if (body.isEmpty()) {
+ BaseHttpHandler.sendServerError(httpExchange);
+ } else {
+ Task task = gson.fromJson(body, Task.class);
+ if (task.getId() != 0) {
+ try {
+ taskManager.updateTask(task);
+ } catch (OverlapsException e) {
+ BaseHttpHandler.sendHasOverlaps(httpExchange);
+ }
+ } else {
+ try {
+ taskManager.createTask(new Task(task.getName(), task.getDescription(),
+ taskManager.getTaskId(), task.getStatus(), task.getDuration(),
+ task.getStartTime()));
+ } catch (OverlapsException e) {
+ BaseHttpHandler.sendHasOverlaps(httpExchange);
+ }
+ }
+ BaseHttpHandler.sendText(httpExchange, gson.toJson(task), 201);
+ }
+ } else {
+ BaseHttpHandler.sendServerError(httpExchange);
+ }
+ httpExchange.close();
+ }
+ case "DELETE" -> {
+ if (partsOfPath.length == 3) {
+ int id = Integer.parseInt(partsOfPath[2]);
+ Task task = taskManager.getTaskById(id);
+ if (task == null) {
+ BaseHttpHandler.sendNotFound(httpExchange);
+ } else {
+ taskManager.deleteTask(task);
+ BaseHttpHandler.sendText(httpExchange, gson.toJson(task), 200);
+ }
+ } else {
+ BaseHttpHandler.sendServerError(httpExchange);
+ }
+ httpExchange.close();
+ }
+ default -> BaseHttpHandler.sendNotFound(httpExchange);
+ }
+ }
+}
diff --git a/src/tracker/server/HttpTaskServer.java b/src/tracker/server/HttpTaskServer.java
new file mode 100644
index 0000000..1508e8e
--- /dev/null
+++ b/src/tracker/server/HttpTaskServer.java
@@ -0,0 +1,76 @@
+package tracker.server;
+
+import com.google.gson.*;
+import com.sun.net.httpserver.HttpServer;
+import tracker.controllers.Managers;
+import tracker.controllers.TaskManager;
+import tracker.handler.*;
+import tracker.model.Epic;
+import tracker.adapter.LocalDateAdapter;
+import tracker.model.Subtask;
+import tracker.model.Task;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.time.LocalDateTime;
+
+public class HttpTaskServer {
+ final TaskManager taskManager;
+
+ private final HttpServer httpServer;
+
+ public HttpTaskServer(int port, TaskManager taskManager) throws IOException {
+ this.taskManager = taskManager;
+ Gson gson = new GsonBuilder()
+ .serializeNulls()
+ .registerTypeAdapter(LocalDateTime.class, new LocalDateAdapter())
+ .create();
+
+ httpServer = HttpServer.create();
+ httpServer.bind(new InetSocketAddress(port), 0);
+ httpServer.createContext("/tasks", new TasksHandler(gson, taskManager));
+ httpServer.createContext("/subtasks", new SubtasksHandler(gson, taskManager));
+ httpServer.createContext("/epics", new EpicsHandler(gson, taskManager));
+ httpServer.createContext("/history", new HistoryHandler(gson, taskManager));
+ httpServer.createContext("/prioritized", new PrioritizedHandler(gson, taskManager));
+ }
+
+ public static void main(String[] args) throws IOException {
+ final long MINUTES_IN_DAY = 60 * 24;
+ final LocalDateTime TASK_START_TIME = LocalDateTime.now();
+ TaskManager inMemoryTaskManager = Managers.getDefault();
+ HttpTaskServer taskServer = new HttpTaskServer(8080, inMemoryTaskManager);
+ taskServer.start();
+
+ // Создайте две задачи, а также эпик с двумя подзадачами и эпик с одной подзадачей
+ Task task1 = new Task("tracker.model.Task 1", "Do task 1", inMemoryTaskManager.getTaskId(),
+ MINUTES_IN_DAY, TASK_START_TIME.minusDays(4));
+ inMemoryTaskManager.createTask(task1);
+ Task task2 = new Task("tracker.model.Task 2", "Do task 2", inMemoryTaskManager.getTaskId(),
+ MINUTES_IN_DAY, TASK_START_TIME.minusDays(3));
+ inMemoryTaskManager.createTask(task2);
+ Epic epic1 = new Epic("tracker.model.Epic 1", "Do all subtasks from epic 1",
+ inMemoryTaskManager.getTaskId());
+ inMemoryTaskManager.createEpic(epic1);
+ Epic epic2 = new Epic("tracker.model.Epic 2", "Do all subtasks from epic 2",
+ inMemoryTaskManager.getTaskId());
+ inMemoryTaskManager.createEpic(epic2);
+ Subtask subtask1 = new Subtask("tracker.model.Subtask 1", "Do subtask 1", inMemoryTaskManager.getTaskId(),
+ epic1, MINUTES_IN_DAY, TASK_START_TIME.minusDays(2));
+ inMemoryTaskManager.createSubtask(subtask1);
+ Subtask subtask2 = new Subtask("tracker.model.Subtask 2", "Do subtask 2", inMemoryTaskManager.getTaskId(),
+ epic1, MINUTES_IN_DAY, TASK_START_TIME.minusDays(1));
+ inMemoryTaskManager.createSubtask(subtask2);
+ Subtask subtask3 = new Subtask("tracker.model.Subtask 3", "Do subtask 3", inMemoryTaskManager.getTaskId(),
+ epic2, MINUTES_IN_DAY, TASK_START_TIME);
+ inMemoryTaskManager.createSubtask(subtask3);
+ }
+
+ public void start() {
+ httpServer.start();
+ }
+
+ public void stop() {
+ httpServer.stop(0);
+ }
+}
diff --git a/test/tracker/HttpTaskManagerTasksTest.java b/test/tracker/HttpTaskManagerTasksTest.java
new file mode 100644
index 0000000..a737518
--- /dev/null
+++ b/test/tracker/HttpTaskManagerTasksTest.java
@@ -0,0 +1,217 @@
+package tracker;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+import tracker.controllers.InMemoryTaskManager;
+import tracker.controllers.TaskManager;
+import tracker.model.Epic;
+import tracker.model.Subtask;
+import tracker.model.Task;
+import tracker.server.HttpTaskServer;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.time.LocalDateTime;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class HttpTaskManagerTasksTest {
+
+ TaskManager taskManager = new InMemoryTaskManager();
+ HttpTaskServer taskServer = new HttpTaskServer(8080, taskManager);
+
+ final long MINUTES_IN_DAY = 60 * 24;
+ final LocalDateTime TASK_START_TIME = LocalDateTime.now();
+
+ public HttpTaskManagerTasksTest() throws IOException {
+ }
+
+ @BeforeEach
+ public void setUp() {
+ taskServer.start();
+ }
+
+ @AfterEach
+ public void shutDown() {
+ taskServer.stop();
+ }
+
+ @Test
+ public void testTasks() throws IOException, InterruptedException {
+ String task1Json = "{\"name\":\"Task 1\",\"description\":\"Do task 1\",\"status\":\"NEW\"" +
+ ",\"duration\":" + MINUTES_IN_DAY + ",\"startTime\": \"" + TASK_START_TIME.minusDays(4) + "\"}";
+ String task2Json = "{\"name\":\"Task 2\",\"description\":\"Do task 2\",\"status\":\"NEW\"" +
+ ",\"duration\":" + MINUTES_IN_DAY + ",\"startTime\": \"" + TASK_START_TIME.minusDays(4) + "\"}";
+ URI urlTasks = URI.create("http://localhost:8080/tasks");
+
+ HttpResponse response;
+ HttpRequest request;
+
+ // 1. создаем 1 задачу
+ HttpClient client = HttpClient.newHttpClient();
+ request = HttpRequest.newBuilder().uri(urlTasks).POST(HttpRequest.BodyPublishers.ofString(task1Json)).build();
+ response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(201, response.statusCode());
+ List tasksFromManager = taskManager.getTasks();
+
+ assertNotNull(tasksFromManager, "Список задач пуст");
+ assertEquals(1, tasksFromManager.size(), "Некорректное количество задач");
+ assertEquals("Task 1", tasksFromManager.get(0).getName(), "Некорректное имя задачи");
+
+ // 2. создаем 2 задачу
+ request = HttpRequest.newBuilder().uri(urlTasks).POST(HttpRequest.BodyPublishers.ofString(task2Json)).build();
+ response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(406, response.statusCode());
+
+ task2Json = "{\"name\":\"Task 2\",\"description\":\"Do task 2\",\"status\":\"NEW\"" +
+ ",\"duration\":" + MINUTES_IN_DAY + ",\"startTime\": \"" + TASK_START_TIME.minusDays(3) + "\"}";
+ request = HttpRequest.newBuilder().uri(urlTasks).POST(HttpRequest.BodyPublishers.ofString(task2Json)).build();
+ response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(201, response.statusCode());
+
+ tasksFromManager = taskManager.getTasks();
+ assertNotNull(tasksFromManager, "Список задач пуст");
+ assertEquals(2, tasksFromManager.size(), "Некорректное количество задач");
+ assertEquals("Task 1", tasksFromManager.get(0).getName(), "Некорректное имя задачи");
+ assertEquals("Task 2", tasksFromManager.get(1).getName(), "Некорректное имя задачи");
+
+ // 3. удаляем 1 задачу
+ request = HttpRequest.newBuilder().uri(URI.create("http://localhost:8080/tasks/1")).DELETE()
+ .build();
+ response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(200, response.statusCode());
+
+ tasksFromManager = taskManager.getTasks();
+ assertNotNull(tasksFromManager, "Список задач пуст");
+ assertEquals(1, tasksFromManager.size(), "Некорректное количество задач");
+ assertEquals("Task 2", tasksFromManager.get(0).getName(), "Некорректное имя задачи");
+
+ // 4. удаляем 2 задачу
+ request = HttpRequest.newBuilder().uri(URI.create("http://localhost:8080/tasks/2")).DELETE()
+ .build();
+ response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(200, response.statusCode());
+
+ tasksFromManager = taskManager.getTasks();
+ assertEquals(0, tasksFromManager.size(), "Некорректное количество задач");
+ }
+
+ @Test
+ public void checkEpicsAndSubtasks() throws IOException, InterruptedException {
+ String epic1Json = "{\"endTime\":\"1970-01-01T00:00:00\",\"emptyDateTime\":\"1970-01-01T00:00:00\"" +
+ ",\"name\":\"Epic 1\",\"description\":\"Do all subtasks from epic 1\",\"id\":1,\"status\":null" +
+ ",\"duration\":0,\"startTime\":\"1970-01-01T00:00:00\"}";
+ String epic2Json = "{\"endTime\":\"1970-01-01T00:00:00\",\"emptyDateTime\":\"1970-01-01T00:00:00\"" +
+ ",\"name\":\"Epic 2\",\"description\":\"Do all subtasks from epic 2\",\"id\":2,\"status\":null" +
+ ",\"duration\":0,\"startTime\":\"1970-01-01T00:00:00\"}";
+ String subtask1Json = "{\"epic\":{\"endTime\":\"1970-01-01T00:00:00\",\"emptyDateTime\":\"1970-01-01T00:00:00\"" +
+ ",\"name\":\"Epic 1\",\"description\":\"Do all subtasks from epic 1\",\"id\":1,\"status\":null" +
+ ",\"duration\":0,\"startTime\":\"1970-01-01T00:00:00\"},\"name\":\"Subtask 1\"" +
+ ",\"description\":\"Do subtask 1\",\"status\":\"NEW\",\"duration\":" + MINUTES_IN_DAY +
+ ",\"startTime\":\"" + TASK_START_TIME.minusDays(3) + "\"}";
+ String subtask2Json = "{\"epic\":{\"endTime\":\"1970-01-01T00:00:00\",\"emptyDateTime\":\"1970-01-01T00:00:00\"" +
+ ",\"name\":\"Epic 1\",\"description\":\"Do all subtasks from epic 1\",\"id\":1,\"status\":null" +
+ ",\"duration\":0,\"startTime\":\"1970-01-01T00:00:00\"},\"name\":\"Subtask 2\"" +
+ ",\"description\":\"Do subtask 2\",\"status\":\"NEW\",\"duration\":" + MINUTES_IN_DAY +
+ ",\"startTime\":\"" + TASK_START_TIME.minusDays(2) + "\"}";
+ String subtask3Json = "{\"epic\":{\"endTime\":\"1970-01-01T00:00:00\",\"emptyDateTime\":\"1970-01-01T00:00:00\"" +
+ ",\"name\":\"Epic 2\",\"description\":\"Do all subtasks from epic 2\",\"id\":2,\"status\":null" +
+ ",\"duration\":0,\"startTime\":\"1970-01-01T00:00:00\"},\"name\":\"Subtask 3\"" +
+ ",\"description\":\"Do subtask 3\",\"status\":\"NEW\",\"duration\":" + MINUTES_IN_DAY +
+ ",\"startTime\":\"" + TASK_START_TIME.minusDays(2) + "\"}";
+
+ URI urlEpics = URI.create("http://localhost:8080/epics");
+ URI urlSubtasks = URI.create("http://localhost:8080/subtasks");
+
+ HttpRequest request;
+ HttpResponse response;
+ // 1. Создаем эпики
+ HttpClient client = HttpClient.newHttpClient();
+ request = HttpRequest.newBuilder().uri(urlEpics).POST(HttpRequest.BodyPublishers.ofString(epic1Json)).build();
+ response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(201, response.statusCode());
+
+ request = HttpRequest.newBuilder().uri(urlEpics).POST(HttpRequest.BodyPublishers.ofString(epic2Json)).build();
+ response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(201, response.statusCode());
+
+ List epicsFromManager = taskManager.getEpics();
+
+ assertNotNull(epicsFromManager, "Список задач пуст");
+ assertEquals(2, epicsFromManager.size(), "Некорректное количество эпиков");
+ assertEquals("Epic 1", epicsFromManager.get(0).getName(), "Некорректное имя эпика");
+ assertEquals("Epic 2", epicsFromManager.get(1).getName(), "Некорректное имя эпика");
+
+ // 2. Создаем подзадачи
+ request = HttpRequest.newBuilder().uri(urlSubtasks).POST(HttpRequest.BodyPublishers.ofString(subtask1Json))
+ .build();
+ response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(201, response.statusCode());
+
+ request = HttpRequest.newBuilder().uri(urlSubtasks).POST(HttpRequest.BodyPublishers.ofString(subtask2Json)).
+ build();
+ response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(201, response.statusCode());
+
+ request = HttpRequest.newBuilder().uri(urlSubtasks).POST(HttpRequest.BodyPublishers.ofString(subtask3Json))
+ .build();
+ response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(406, response.statusCode());
+
+ subtask3Json = "{\"epic\":{\"endTime\":\"1970-01-01T00:00:00\",\"emptyDateTime\":\"1970-01-01T00:00:00\"" +
+ ",\"name\":\"Epic 2\",\"description\":\"Do all subtasks from epic 2\",\"id\":2,\"status\":null" +
+ ",\"duration\":0,\"startTime\":\"1970-01-01T00:00:00\"},\"name\":\"Subtask 3\"" +
+ ",\"description\":\"Do subtask 3\",\"status\":\"NEW\",\"duration\":" + MINUTES_IN_DAY +
+ ",\"startTime\":\"" + TASK_START_TIME.minusDays(1) + "\"}";
+ request = HttpRequest.newBuilder().uri(urlSubtasks).POST(HttpRequest.BodyPublishers.ofString(subtask3Json))
+ .build();
+ response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(201, response.statusCode());
+
+ List subtasksFromManager = taskManager.getSubtasks();
+
+ assertNotNull(subtasksFromManager, "Список задач пуст");
+ assertEquals(3, subtasksFromManager.size(), "Некорректное количество подзадач");
+ assertEquals("Subtask 1", subtasksFromManager.get(0).getName(), "Некорректное имя подзадачи");
+ assertEquals("Subtask 2", subtasksFromManager.get(1).getName(), "Некорректное имя подзадачи");
+ assertEquals("Subtask 3", subtasksFromManager.get(2).getName(), "Некорректное имя подзадачи");
+
+ // 3. удаляем подзадачи
+ request = HttpRequest.newBuilder().uri(URI.create("http://localhost:8080/subtasks/3"))
+ .DELETE().build();
+ response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(200, response.statusCode());
+
+ request = HttpRequest.newBuilder().uri(URI.create("http://localhost:8080/subtasks/4"))
+ .DELETE().build();
+ response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(200, response.statusCode());
+
+ request = HttpRequest.newBuilder().uri(URI.create("http://localhost:8080/subtasks/5"))
+ .DELETE().build();
+ response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(200, response.statusCode());
+
+ subtasksFromManager = taskManager.getSubtasks();
+ assertEquals(0, subtasksFromManager.size(), "Некорректное количество задач");
+
+ // 4. удаляем эпики
+ request = HttpRequest.newBuilder().uri(URI.create("http://localhost:8080/epics/1"))
+ .DELETE().build();
+ response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(200, response.statusCode());
+
+ request = HttpRequest.newBuilder().uri(URI.create("http://localhost:8080/epics/2"))
+ .DELETE().build();
+ response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ assertEquals(200, response.statusCode());
+
+ epicsFromManager = taskManager.getEpics();
+ assertEquals(0, epicsFromManager.size(), "Некорректное количество задач");
+ }
+}
\ No newline at end of file
diff --git a/test/tracker/controllers/FileBackedTaskManagerTest.java b/test/tracker/controllers/FileBackedTaskManagerTest.java
index 63e270a..317a05a 100644
--- a/test/tracker/controllers/FileBackedTaskManagerTest.java
+++ b/test/tracker/controllers/FileBackedTaskManagerTest.java
@@ -31,7 +31,7 @@ void initializeTask() {
@Override
@Test
- void checkEpic() {
+ void checkEpic() throws InterruptedException {
super.checkEpic();
}
@@ -44,7 +44,7 @@ void checkImportFromEmptyFile() {
}
@Test
- void checkImportFromFile() {
+ void checkImportFromFile() throws InterruptedException {
Task task1 = new Task("task 1", "task 1", 1, Status.NEW, MINUTES_IN_DAY,
TASK_START_TIME.minusDays(4));
Task task2 = new Task("task 2", "task 2", 2, Status.NEW, MINUTES_IN_DAY,
diff --git a/test/tracker/controllers/InMemoryHistoryManagerTest.java b/test/tracker/controllers/InMemoryHistoryManagerTest.java
index 1e883d4..7e5d3e4 100644
--- a/test/tracker/controllers/InMemoryHistoryManagerTest.java
+++ b/test/tracker/controllers/InMemoryHistoryManagerTest.java
@@ -20,7 +20,7 @@ void initializeTask() {
taskManager = Managers.getDefault();
}
@Test
- void checkInMemoryHistoryManager() {
+ void checkInMemoryHistoryManager() throws InterruptedException {
Task task1 = new Task("Task 1", "Do task 1", taskManager.getTaskId(), MINUTES_IN_DAY,
TASK_START_TIME.minusDays(4));
taskManager.createTask(task1);
diff --git a/test/tracker/controllers/TaskManagerTest.java b/test/tracker/controllers/TaskManagerTest.java
index 1db1a53..1383f47 100644
--- a/test/tracker/controllers/TaskManagerTest.java
+++ b/test/tracker/controllers/TaskManagerTest.java
@@ -1,6 +1,7 @@
package tracker.controllers;
import org.junit.jupiter.api.Test;
+import tracker.exceptions.OverlapsException;
import tracker.model.Epic;
import tracker.model.Status;
import tracker.model.Subtask;
@@ -17,7 +18,7 @@ abstract class TaskManagerTest {
final LocalDateTime TASK_START_TIME = LocalDateTime.now();
@Test
- void checkEpic() {
+ void checkEpic() throws InterruptedException {
Task task1 = new Task("Task 1", "Do task 1", taskManager.getTaskId(), MINUTES_IN_DAY,
TASK_START_TIME.minusDays(4));
taskManager.createTask(task1);
@@ -48,7 +49,7 @@ void checkEpic() {
}
@Test
- void checkEpicStatus() {
+ void checkEpicStatus() throws OverlapsException {
// Все подзадачи со статусом NEW.
Epic epic1 = new Epic("Epic 1", "Do all subtasks from epic 1", taskManager.getTaskId());
taskManager.createEpic(epic1);
@@ -88,17 +89,20 @@ void checkEpicStatus() {
}
@Test
- void checkTaskIntersection() {
+ void checkTaskIntersection() throws OverlapsException {
// При наличии пересечения по времени выполнения задача не будет создана
Task task1 = new Task("Task 1", "Do task 1", taskManager.getTaskId(), MINUTES_IN_DAY,
TASK_START_TIME);
taskManager.createTask(task1);
Task task2 = new Task("Task 2", "Do task 2", taskManager.getTaskId(), MINUTES_IN_DAY,
TASK_START_TIME);
- taskManager.createTask(task2);
- assertEquals(1, taskManager.getTaskById(task1.getId()).getId(), "Неверный Id");
- assertEquals(1, taskManager.getTasks().size(), "Неверное количество задач");
- task2.setStartTime(TASK_START_TIME.plusDays(1));
+ try {
+ taskManager.createTask(task2);
+ } catch (OverlapsException e) {
+ assertEquals(1, taskManager.getTaskById(task1.getId()).getId(), "Неверный Id");
+ assertEquals(1, taskManager.getTasks().size(), "Неверное количество задач");
+ task2.setStartTime(TASK_START_TIME.plusDays(1));
+ }
taskManager.createTask(task2);
assertEquals(2, taskManager.getTaskById(task2.getId()).getId(), "Неверный Id");
}
diff --git a/test/tracker/model/SubtaskTest.java b/test/tracker/model/SubtaskTest.java
index eb685ba..89a8f2f 100644
--- a/test/tracker/model/SubtaskTest.java
+++ b/test/tracker/model/SubtaskTest.java
@@ -20,7 +20,7 @@ void initializeTask() {
}
@Test
- void checkSubtask() {
+ void checkSubtask() throws InterruptedException {
Epic epic1 = new Epic("Epic 1", "Do all subtasks from epic 1",
inMemoryTaskManager.getTaskId());
inMemoryTaskManager.createEpic(epic1);
diff --git a/test/tracker/model/TaskTest.java b/test/tracker/model/TaskTest.java
index 103526d..0177174 100644
--- a/test/tracker/model/TaskTest.java
+++ b/test/tracker/model/TaskTest.java
@@ -16,7 +16,7 @@ void initializeTask() {
}
@Test
- void checkTask() {
+ void checkTask() throws InterruptedException {
Task task1 = new Task("Task 1", "Do task 1", 1);
inMemoryTaskManager.createTask(task1);
Task task2 = new Task("Task 2", "Do task 2", 1);