From df51f45c76d0c97ca06c76000c7c19452197cd72 Mon Sep 17 00:00:00 2001 From: mxchbot Date: Wed, 21 Jan 2026 15:29:07 +0300 Subject: [PATCH 1/8] Init --- README.MD | 28 ------ pom.xml | 25 +---- .../com/javarush/chebotarev/IndexServlet.java | 19 ++++ .../java/com/javarush/chebotarev/Path.java | 7 ++ .../com/javarush/khmelov/cmd/Command.java | 37 -------- .../com/javarush/khmelov/cmd/EditUser.java | 52 ----------- .../com/javarush/khmelov/cmd/ListUser.java | 26 ------ .../com/javarush/khmelov/cmd/StartPage.java | 6 -- .../com/javarush/khmelov/config/Winter.java | 29 ------ .../khmelov/controller/FrontController.java | 43 --------- .../khmelov/controller/HttpResolver.java | 41 --------- .../com/javarush/khmelov/entity/Role.java | 5 - .../com/javarush/khmelov/entity/User.java | 26 ------ .../khmelov/repository/Repository.java | 19 ---- .../khmelov/repository/UserRepository.java | 50 ---------- .../javarush/khmelov/service/UserService.java | 36 -------- src/main/webapp/WEB-INF/edit-user.jsp | 73 --------------- src/main/webapp/WEB-INF/head.jsp | 11 --- src/main/webapp/WEB-INF/index.jsp | 44 +++++++++ src/main/webapp/WEB-INF/list-user.jsp | 9 -- src/main/webapp/WEB-INF/start-page.jsp | 8 -- src/main/webapp/WEB-INF/web.xml | 6 -- src/main/webapp/images/cat.png | Bin 98607 -> 0 bytes src/main/webapp/static/style.css | 87 ++++++++++++++++++ 24 files changed, 160 insertions(+), 527 deletions(-) delete mode 100644 README.MD create mode 100644 src/main/java/com/javarush/chebotarev/IndexServlet.java create mode 100644 src/main/java/com/javarush/chebotarev/Path.java delete mode 100644 src/main/java/com/javarush/khmelov/cmd/Command.java delete mode 100644 src/main/java/com/javarush/khmelov/cmd/EditUser.java delete mode 100644 src/main/java/com/javarush/khmelov/cmd/ListUser.java delete mode 100644 src/main/java/com/javarush/khmelov/cmd/StartPage.java delete mode 100644 src/main/java/com/javarush/khmelov/config/Winter.java delete mode 100644 src/main/java/com/javarush/khmelov/controller/FrontController.java delete mode 100644 src/main/java/com/javarush/khmelov/controller/HttpResolver.java delete mode 100644 src/main/java/com/javarush/khmelov/entity/Role.java delete mode 100644 src/main/java/com/javarush/khmelov/entity/User.java delete mode 100644 src/main/java/com/javarush/khmelov/repository/Repository.java delete mode 100644 src/main/java/com/javarush/khmelov/repository/UserRepository.java delete mode 100644 src/main/java/com/javarush/khmelov/service/UserService.java delete mode 100644 src/main/webapp/WEB-INF/edit-user.jsp delete mode 100644 src/main/webapp/WEB-INF/head.jsp create mode 100644 src/main/webapp/WEB-INF/index.jsp delete mode 100644 src/main/webapp/WEB-INF/list-user.jsp delete mode 100644 src/main/webapp/WEB-INF/start-page.jsp delete mode 100644 src/main/webapp/WEB-INF/web.xml delete mode 100644 src/main/webapp/images/cat.png create mode 100644 src/main/webapp/static/style.css diff --git a/README.MD b/README.MD deleted file mode 100644 index 1bf1eca..0000000 --- a/README.MD +++ /dev/null @@ -1,28 +0,0 @@ -# Quest Pantera - -### Ребята и девчата, всем привет! - -На этот раз у нас более сложный проект, который будет трудно объединить в один общий проект со всем зависимостями. -Поэтому поступим просто. Тут первоначально лежит наш учебный проект. -Заготовка, такая же как может быть сгенерирована в IDEA. -Договоримся, что Java у нас будет 21-я. У всех. Привыкайте использовать только LTS. -Из зависимостей есть jakarta.servlet-api + jstl, JUnit5 и Lombok, -так что POM.xml возможно надо будет заменить на свой. - -### Что нужно сделать. - -1. Сделайте форк и затем клон этого репозитория. -2. **СРАЗУ** создайте в нем ветку со своей фамилией, например, ivanov. -3. Размещайте в своей ветке свое решение (если мои примеры мешают их можно просто удалить - ветвление же). -4. В конце вам нужно будет сделать **Pull Request** из своей ветки (в своем форке) в такую же точно ветку (в этом удаленном - репозитории), если вы не найдете - тогда в **main** ну и затем ОБЯЗАТЕЛЬНО заполнить форму проектов. -5. Я положу в ветку **khmelov** тот пример, который буду параллельно с вами разрабатывать на факультативах. Полезнее будет - не копипастить, смотрите видео, разбирайтесь, что, почему, где и как сделано. Не копируйте, нужно ВАШЕ решение. Но мы уже и - не совсем зеленые, правда ведь ;). -6. Проверять проекты по итогам третьего модуля я буду с **code review**, и скорее всего быстро не получится, так что за - сроки сдачи можно не волноваться. -7. Планируйте время так, первые три консультации - основной функционал. Последняя консультация - плюшки, рефакторинг, - тесты, красоты. -8. Если будут какие-то моменты - я обновлю это README. Поглядывайте периодически. - -#### _2026 JRU Pantera, Александр Хмелев._ diff --git a/pom.xml b/pom.xml index 78ee59d..7aee296 100644 --- a/pom.xml +++ b/pom.xml @@ -4,17 +4,16 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.javarush.khmelov - project-ledzeppelin + com.javarush.chebotarev + project-pantera 1.0-SNAPSHOT - ProjectLedzeppelin + ProjectPantera war UTF-8 21 21 - 5.10.2 @@ -50,11 +49,6 @@ jakarta.servlet.jsp.jstl - - org.projectlombok - lombok - provided - org.junit.jupiter junit-jupiter-api @@ -75,19 +69,6 @@ maven-war-plugin 3.4.0 - - org.apache.maven.plugins - maven-compiler-plugin - - - - org.projectlombok - lombok - 1.18.34 - - - - diff --git a/src/main/java/com/javarush/chebotarev/IndexServlet.java b/src/main/java/com/javarush/chebotarev/IndexServlet.java new file mode 100644 index 0000000..43310c1 --- /dev/null +++ b/src/main/java/com/javarush/chebotarev/IndexServlet.java @@ -0,0 +1,19 @@ +package com.javarush.chebotarev; + +import jakarta.servlet.ServletException; +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; + +@WebServlet("") +public class IndexServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + req.getRequestDispatcher(Path.INDEX) + .forward(req, resp); + } +} diff --git a/src/main/java/com/javarush/chebotarev/Path.java b/src/main/java/com/javarush/chebotarev/Path.java new file mode 100644 index 0000000..491826f --- /dev/null +++ b/src/main/java/com/javarush/chebotarev/Path.java @@ -0,0 +1,7 @@ +package com.javarush.chebotarev; + +public interface Path { + + String WEB_INF = "/WEB-INF/"; + String INDEX = WEB_INF + "index.jsp"; +} diff --git a/src/main/java/com/javarush/khmelov/cmd/Command.java b/src/main/java/com/javarush/khmelov/cmd/Command.java deleted file mode 100644 index fd4035b..0000000 --- a/src/main/java/com/javarush/khmelov/cmd/Command.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.javarush.khmelov.cmd; - -import jakarta.servlet.http.HttpServletRequest; - -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public interface Command { - - default String doGet(HttpServletRequest request) { - return getView(); - } - - default String doPost(HttpServletRequest request) { - return getView(); - } - - default String getView() { - String simpleName = this.getClass().getSimpleName(); - return convertCamelCaseToKebabStyle(simpleName); - } - - private static String convertCamelCaseToKebabStyle(String string) { - String snakeName = string.chars() - .mapToObj(s -> String.valueOf((char) s)) - .flatMap(s -> s.matches("[A-Z]") - ? Stream.of("-", s) - : Stream.of(s)) - .collect(Collectors.joining()) - .toLowerCase(); - return snakeName.startsWith("-") - ? snakeName.substring(1) - : snakeName; - } - - -} diff --git a/src/main/java/com/javarush/khmelov/cmd/EditUser.java b/src/main/java/com/javarush/khmelov/cmd/EditUser.java deleted file mode 100644 index ae191b4..0000000 --- a/src/main/java/com/javarush/khmelov/cmd/EditUser.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.javarush.khmelov.cmd; - -import com.javarush.khmelov.entity.Role; -import com.javarush.khmelov.entity.User; -import com.javarush.khmelov.service.UserService; -import jakarta.servlet.http.HttpServletRequest; - -import java.util.Optional; - - -@SuppressWarnings("unused") -public class EditUser implements Command { - - private final UserService userService; - - public EditUser(UserService userService) { - this.userService = userService; - } - - - @Override - public String doGet(HttpServletRequest req) { - String stringId = req.getParameter("id"); - if (stringId != null) { - long id = Long.parseLong(stringId); - Optional optionalUser = userService.get(id); - if (optionalUser.isPresent()) { - User user = optionalUser.get(); - req.setAttribute("user", user); - } - } - return getView(); - } - - @Override - public String doPost(HttpServletRequest req) { - User user = User.builder() - .login(req.getParameter("login")) - .password(req.getParameter("password")) - .role(Role.valueOf(req.getParameter("role"))) - .build(); - if (req.getParameter("create") != null) { - userService.create(user); - } else if (req.getParameter("update") != null) { - user.setId(Long.parseLong(req.getParameter("id"))); - userService.update(user); - } - return getView() + "?id=" + user.getId(); - } - - -} \ No newline at end of file diff --git a/src/main/java/com/javarush/khmelov/cmd/ListUser.java b/src/main/java/com/javarush/khmelov/cmd/ListUser.java deleted file mode 100644 index 9257917..0000000 --- a/src/main/java/com/javarush/khmelov/cmd/ListUser.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.javarush.khmelov.cmd; - -import com.javarush.khmelov.entity.User; -import com.javarush.khmelov.service.UserService; -import jakarta.servlet.http.HttpServletRequest; - -import java.util.Collection; - -@SuppressWarnings("unused") -public class ListUser implements Command { - - private final UserService userService; - - public ListUser(UserService userService) { - this.userService = userService; - } - - @Override - public String doGet(HttpServletRequest request) { - Collection users = userService.getAll(); - request.setAttribute("users", users); - return getView(); - } - - -} \ No newline at end of file diff --git a/src/main/java/com/javarush/khmelov/cmd/StartPage.java b/src/main/java/com/javarush/khmelov/cmd/StartPage.java deleted file mode 100644 index d268f93..0000000 --- a/src/main/java/com/javarush/khmelov/cmd/StartPage.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.javarush.khmelov.cmd; - -@SuppressWarnings("unused") -public class StartPage implements Command { - -} diff --git a/src/main/java/com/javarush/khmelov/config/Winter.java b/src/main/java/com/javarush/khmelov/config/Winter.java deleted file mode 100644 index 48bd8a7..0000000 --- a/src/main/java/com/javarush/khmelov/config/Winter.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.javarush.khmelov.config; - -import lombok.SneakyThrows; - -import java.lang.reflect.Constructor; -import java.util.concurrent.ConcurrentHashMap; - -public class Winter { - - public static ConcurrentHashMap, Object> components = new ConcurrentHashMap<>(); - - - @SuppressWarnings("unchecked") - @SneakyThrows - public static T find(Class aClass) { - Object component = components.get(aClass); - if (component == null) { - Constructor constructor = aClass.getConstructors()[0]; - Class[] parameterTypes = constructor.getParameterTypes(); - Object[] parameters = new Object[parameterTypes.length]; - for (int i = 0; i < parameters.length; i++) { - parameters[i] = Winter.find(parameterTypes[i]); - } - Object newInstance = constructor.newInstance(parameters); - components.put(aClass, newInstance); - } - return (T) components.get(aClass); - } -} diff --git a/src/main/java/com/javarush/khmelov/controller/FrontController.java b/src/main/java/com/javarush/khmelov/controller/FrontController.java deleted file mode 100644 index 33242b2..0000000 --- a/src/main/java/com/javarush/khmelov/controller/FrontController.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.javarush.khmelov.controller; - -import com.javarush.khmelov.cmd.Command; -import com.javarush.khmelov.config.Winter; -import com.javarush.khmelov.entity.Role; -import jakarta.servlet.ServletConfig; -import jakarta.servlet.ServletException; -import jakarta.servlet.annotation.WebServlet; -import jakarta.servlet.http.HttpServlet; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - -import java.io.IOException; - -@WebServlet({"", "/home", "/list-user", "/edit-user"}) -public class FrontController extends HttpServlet { - - private final HttpResolver httpResolver = Winter.find(HttpResolver.class); - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - Command command = httpResolver.resolve(req); - String view = command.doGet(req); - String jsp = getJsp(view); - req.getRequestDispatcher(jsp).forward(req, resp); - } - - @Override - public void init(ServletConfig config) { - config.getServletContext().setAttribute("roles", Role.values()); - } - - private static String getJsp(String view) { - return "/WEB-INF/" + view + ".jsp"; - } - - @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - Command command = httpResolver.resolve(req); - String redirect = command.doPost(req); - resp.sendRedirect(redirect); - } -} diff --git a/src/main/java/com/javarush/khmelov/controller/HttpResolver.java b/src/main/java/com/javarush/khmelov/controller/HttpResolver.java deleted file mode 100644 index 18bb761..0000000 --- a/src/main/java/com/javarush/khmelov/controller/HttpResolver.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.javarush.khmelov.controller; - -import com.javarush.khmelov.cmd.Command; -import com.javarush.khmelov.config.Winter; -import jakarta.servlet.http.HttpServletRequest; - -public class HttpResolver { - - public Command resolve(HttpServletRequest request) { - // /cmd-example - try { - String requestURI = request.getRequestURI(); - requestURI = requestURI.equals("/") ? "/start-page" : requestURI; - String kebabName = requestURI.split("[?#/]")[1]; - String simpleName = convertKebabStyleToCamelCase(kebabName); - String fullName = Command.class.getPackageName() + "." + simpleName; - Class aClass = Class.forName(fullName); - return (Command) Winter.find(aClass); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } - } - - private String convertKebabStyleToCamelCase(String input) { - StringBuilder result = new StringBuilder(); - boolean capitalizeNext = true; - for (char c : input.toCharArray()) { - if (c == '-') { - capitalizeNext = true; - } else { - if (capitalizeNext) { - result.append(Character.toUpperCase(c)); - capitalizeNext = false; - } else { - result.append(Character.toLowerCase(c)); - } - } - } - return result.toString(); - } -} diff --git a/src/main/java/com/javarush/khmelov/entity/Role.java b/src/main/java/com/javarush/khmelov/entity/Role.java deleted file mode 100644 index 5ae365f..0000000 --- a/src/main/java/com/javarush/khmelov/entity/Role.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.javarush.khmelov.entity; - -public enum Role { - USER, ADMIN, GUEST -} diff --git a/src/main/java/com/javarush/khmelov/entity/User.java b/src/main/java/com/javarush/khmelov/entity/User.java deleted file mode 100644 index f7fa2d6..0000000 --- a/src/main/java/com/javarush/khmelov/entity/User.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.javarush.khmelov.entity; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class User { - - private Long id; - - private String login; - - private String password; - - private Role role; - - public String getImage() { //TODO move to DTO - return "image-" + id; - } - -} diff --git a/src/main/java/com/javarush/khmelov/repository/Repository.java b/src/main/java/com/javarush/khmelov/repository/Repository.java deleted file mode 100644 index f1abdac..0000000 --- a/src/main/java/com/javarush/khmelov/repository/Repository.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.javarush.khmelov.repository; - -import com.javarush.khmelov.entity.User; - -import java.util.Collection; -import java.util.Optional; - -public interface Repository { - - Collection getAll(); - - Optional get(long id); - - void create(T entity); - - void update(T entity); - - void delete(T entity); -} diff --git a/src/main/java/com/javarush/khmelov/repository/UserRepository.java b/src/main/java/com/javarush/khmelov/repository/UserRepository.java deleted file mode 100644 index 58b32ea..0000000 --- a/src/main/java/com/javarush/khmelov/repository/UserRepository.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.javarush.khmelov.repository; - -import com.javarush.khmelov.entity.Role; -import com.javarush.khmelov.entity.User; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.atomic.AtomicLong; - -public class UserRepository implements Repository { - - private final Map map = new HashMap<>(); - - public static final AtomicLong id = new AtomicLong(System.currentTimeMillis()); - - public UserRepository() { - map.put(1L, new User(1L, "Alisa", "qwerty", Role.USER)); - map.put(2L, new User(2L, "Bob", "", Role.GUEST)); - map.put(3L, new User(3L, "Carl", "admin", Role.ADMIN)); - map.put(4L, new User(4L, "Khmelov", "admin", Role.ADMIN)); - } - - @Override - public Collection getAll() { - return map.values(); - } - - @Override - public Optional get(long id) { - return Optional.ofNullable(map.get(id)); - } - - @Override - public void create(User entity) { - entity.setId(id.incrementAndGet()); - update(entity); - } - - @Override - public void update(User entity) { - map.put(entity.getId(), entity); - } - - @Override - public void delete(User entity) { - map.remove(entity.getId()); - } -} diff --git a/src/main/java/com/javarush/khmelov/service/UserService.java b/src/main/java/com/javarush/khmelov/service/UserService.java deleted file mode 100644 index b17527c..0000000 --- a/src/main/java/com/javarush/khmelov/service/UserService.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.javarush.khmelov.service; - -import com.javarush.khmelov.entity.User; -import com.javarush.khmelov.repository.UserRepository; - -import java.util.Collection; -import java.util.Optional; - -public class UserService { - - private final UserRepository userRepository; - - public UserService(UserRepository userRepository) { - this.userRepository = userRepository; - } - - public void create(User user) { - userRepository.create(user); - } - - public void update(User user) { - userRepository.update(user); - } - - public void delete(User user) { - userRepository.delete(user); - } - - public Collection getAll() { - return userRepository.getAll(); - } - - public Optional get(long id) { - return userRepository.get(id); - } -} diff --git a/src/main/webapp/WEB-INF/edit-user.jsp b/src/main/webapp/WEB-INF/edit-user.jsp deleted file mode 100644 index f274104..0000000 --- a/src/main/webapp/WEB-INF/edit-user.jsp +++ /dev/null @@ -1,73 +0,0 @@ -<%@ page contentType="text/html;charset=UTF-8" language="java" %> -<%@include file="head.jsp" %> - -
-
-
- - - Edit user: - - -
- -
- - min 3 symbols -
-
- - -
- -
- - min 8 symb -
-
- - - -
- -
- -
-
- - -
- -
- - - - - - - -
-
- -
-
-
- - diff --git a/src/main/webapp/WEB-INF/head.jsp b/src/main/webapp/WEB-INF/head.jsp deleted file mode 100644 index 2f7b9f2..0000000 --- a/src/main/webapp/WEB-INF/head.jsp +++ /dev/null @@ -1,11 +0,0 @@ -<%@ page contentType="text/html;charset=UTF-8" language="java" %> -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> - - - Title - - - \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/index.jsp b/src/main/webapp/WEB-INF/index.jsp new file mode 100644 index 0000000..cf8bd50 --- /dev/null +++ b/src/main/webapp/WEB-INF/index.jsp @@ -0,0 +1,44 @@ +<%@ page contentType="text/html;charset=UTF-8"%> + + + + + + Главное меню — Квесты + + + +
+

Выберите квест

+
+
+ +
+ + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/list-user.jsp b/src/main/webapp/WEB-INF/list-user.jsp deleted file mode 100644 index dd52c55..0000000 --- a/src/main/webapp/WEB-INF/list-user.jsp +++ /dev/null @@ -1,9 +0,0 @@ -<%@ page contentType="text/html;charset=UTF-8" language="java" %> -<%@include file="head.jsp"%> - - - ${user.login} - - - - diff --git a/src/main/webapp/WEB-INF/start-page.jsp b/src/main/webapp/WEB-INF/start-page.jsp deleted file mode 100644 index 0531c1c..0000000 --- a/src/main/webapp/WEB-INF/start-page.jsp +++ /dev/null @@ -1,8 +0,0 @@ -<%@ page contentType="text/html;charset=UTF-8" language="java" %> -<%@include file="head.jsp"%> - -

<%= "Hello World!" %> -

-
-List Users - diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 0bf2fcb..0000000 --- a/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - \ No newline at end of file diff --git a/src/main/webapp/images/cat.png b/src/main/webapp/images/cat.png deleted file mode 100644 index 41771a150e8b04624df7697882a13e789b48af7d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 98607 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%0Aj+deS- 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 Date: Fri, 23 Jan 2026 21:02:40 +0300 Subject: [PATCH 2/8] ADD pages: main menu, editor --- .../javarush/chebotarev/EditorServlet.java | 19 ++ src/main/java/com/javarush/chebotarev/Go.java | 8 + .../com/javarush/chebotarev/IndexServlet.java | 4 +- .../javarush/chebotarev/MainMenuServlet.java | 19 ++ .../java/com/javarush/chebotarev/Path.java | 6 +- src/main/webapp/WEB-INF/editor.jsp | 315 ++++++++++++++++++ .../WEB-INF/{index.jsp => main-menu.jsp} | 2 +- src/main/webapp/static/editor.css | 231 +++++++++++++ 8 files changed, 599 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/javarush/chebotarev/EditorServlet.java create mode 100644 src/main/java/com/javarush/chebotarev/Go.java create mode 100644 src/main/java/com/javarush/chebotarev/MainMenuServlet.java create mode 100644 src/main/webapp/WEB-INF/editor.jsp rename src/main/webapp/WEB-INF/{index.jsp => main-menu.jsp} (94%) create mode 100644 src/main/webapp/static/editor.css diff --git a/src/main/java/com/javarush/chebotarev/EditorServlet.java b/src/main/java/com/javarush/chebotarev/EditorServlet.java new file mode 100644 index 0000000..bf22362 --- /dev/null +++ b/src/main/java/com/javarush/chebotarev/EditorServlet.java @@ -0,0 +1,19 @@ +package com.javarush.chebotarev; + +import jakarta.servlet.ServletException; +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; + +@WebServlet(Go.EDITOR) +public class EditorServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + req.getRequestDispatcher(Path.EDITOR) + .forward(req, resp); + } +} diff --git a/src/main/java/com/javarush/chebotarev/Go.java b/src/main/java/com/javarush/chebotarev/Go.java new file mode 100644 index 0000000..a288011 --- /dev/null +++ b/src/main/java/com/javarush/chebotarev/Go.java @@ -0,0 +1,8 @@ +package com.javarush.chebotarev; + +public interface Go { + + String INDEX = ""; + String MAIN_MENU = "/main-menu"; + String EDITOR = "/editor"; +} diff --git a/src/main/java/com/javarush/chebotarev/IndexServlet.java b/src/main/java/com/javarush/chebotarev/IndexServlet.java index 43310c1..8c3f1b0 100644 --- a/src/main/java/com/javarush/chebotarev/IndexServlet.java +++ b/src/main/java/com/javarush/chebotarev/IndexServlet.java @@ -8,12 +8,12 @@ import java.io.IOException; -@WebServlet("") +@WebServlet(Go.INDEX) public class IndexServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - req.getRequestDispatcher(Path.INDEX) + req.getRequestDispatcher(Path.MAIN_MENU) .forward(req, resp); } } diff --git a/src/main/java/com/javarush/chebotarev/MainMenuServlet.java b/src/main/java/com/javarush/chebotarev/MainMenuServlet.java new file mode 100644 index 0000000..127e499 --- /dev/null +++ b/src/main/java/com/javarush/chebotarev/MainMenuServlet.java @@ -0,0 +1,19 @@ +package com.javarush.chebotarev; + +import jakarta.servlet.ServletException; +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; + +@WebServlet(Go.MAIN_MENU) +public class MainMenuServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + req.getRequestDispatcher(Path.MAIN_MENU) + .forward(req, resp); + } +} diff --git a/src/main/java/com/javarush/chebotarev/Path.java b/src/main/java/com/javarush/chebotarev/Path.java index 491826f..b9c1a8c 100644 --- a/src/main/java/com/javarush/chebotarev/Path.java +++ b/src/main/java/com/javarush/chebotarev/Path.java @@ -2,6 +2,8 @@ public interface Path { - String WEB_INF = "/WEB-INF/"; - String INDEX = WEB_INF + "index.jsp"; + String WEB_INF = "/WEB-INF"; + String JSP = ".jsp"; + String MAIN_MENU = WEB_INF + Go.MAIN_MENU + JSP; + String EDITOR = WEB_INF + Go.EDITOR + JSP; } diff --git a/src/main/webapp/WEB-INF/editor.jsp b/src/main/webapp/WEB-INF/editor.jsp new file mode 100644 index 0000000..9c7c656 --- /dev/null +++ b/src/main/webapp/WEB-INF/editor.jsp @@ -0,0 +1,315 @@ +<%@ page contentType="text/html;charset=UTF-8" %> + + + + + + Quest Editor + + + + + +
+ + +
+ +
+
+
+
100%
+
+
+ + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/index.jsp b/src/main/webapp/WEB-INF/main-menu.jsp similarity index 94% rename from src/main/webapp/WEB-INF/index.jsp rename to src/main/webapp/WEB-INF/main-menu.jsp index cf8bd50..b0948fc 100644 --- a/src/main/webapp/WEB-INF/index.jsp +++ b/src/main/webapp/WEB-INF/main-menu.jsp @@ -12,7 +12,7 @@

Выберите квест

- + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/new-quest.jsp b/src/main/webapp/WEB-INF/new-quest.jsp new file mode 100644 index 0000000..a952d88 --- /dev/null +++ b/src/main/webapp/WEB-INF/new-quest.jsp @@ -0,0 +1,46 @@ +<%@ page contentType="text/html;charset=UTF-8"%> + + + + + + Пролог + + <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> + + +
Вернуться в меню +

+ +

+
+

Пролог

+

+ + +
+ + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/quest.jsp b/src/main/webapp/WEB-INF/quest.jsp new file mode 100644 index 0000000..896397a --- /dev/null +++ b/src/main/webapp/WEB-INF/quest.jsp @@ -0,0 +1,61 @@ +<%@ page contentType="text/html;charset=UTF-8"%> + + + + + + Игра + + <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> + + + Вернуться в меню +
+

+ +

+ + + + + + +
+ 🕯️ Свечи: + + + +
+
+ + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/quests/quest_1769284972559.json b/src/main/webapp/WEB-INF/quests/quest_1769284972559.json deleted file mode 100644 index 49a14d5..0000000 --- a/src/main/webapp/WEB-INF/quests/quest_1769284972559.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "title" : "Имя2", - "prologue" : "AboutAbout", - "nodes" : [ { - "id" : 1, - "text" : "SituationSituation", - "type" : "common", - "options" : [ { - "id" : 0, - "text" : "ActionAction1", - "nextNodeId" : 2 - }, { - "id" : 1, - "text" : "ActionAction2", - "nextNodeId" : 3 - } ] - }, { - "id" : 2, - "text" : "SituationSituation2", - "type" : "common", - "options" : [ { - "id" : 0, - "text" : "ActionAction1", - "nextNodeId" : 3 - }, { - "id" : 1, - "text" : "ActionAction2", - "nextNodeId" : 4 - } ] - }, { - "id" : 3, - "text" : "WIN", - "type" : "victory", - "options" : [ ] - }, { - "id" : 4, - "text" : "LOST", - "type" : "defeat", - "options" : [ ] - } ] -} \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/quests/quest_1769457940149.json b/src/main/webapp/WEB-INF/quests/quest_1769457940149.json new file mode 100644 index 0000000..ae988b5 --- /dev/null +++ b/src/main/webapp/WEB-INF/quests/quest_1769457940149.json @@ -0,0 +1,158 @@ +{ + "title" : "Объект 404", + "prologue" : "Вы — корпоративный шпион, запертый в серверной враждебной компании. Система безопасности начала протокол «Стерилизация» (заполнение отсека газом). У вас есть только планшет-дешифратор и пара минут.", + "nodes" : [ { + "id" : 1, + "text" : "Газ начинает шипеть из вентиляции. Перед вами три выхода.", + "type" : "common", + "options" : [ { + "id" : 0, + "text" : "Взломать терминал управления лифтом", + "nextNodeId" : 4 + }, { + "id" : 1, + "text" : "Броситься в технический туннель для кабелей", + "nextNodeId" : 2 + }, { + "id" : 2, + "text" : "Попытаться отключить подачу газа напрямую", + "nextNodeId" : 3 + }, { + "id" : 3, + "text" : "Забиться в угол и надеть респиратор", + "nextNodeId" : 5 + } ], + "commonType" : true, + "victory" : false + }, { + "id" : 2, + "text" : "Здесь темно и пахнет озоном. Вы слышите шаги охраны.", + "type" : "common", + "options" : [ { + "id" : 0, + "text" : "Затаиться за стеллажами", + "nextNodeId" : 3 + }, { + "id" : 1, + "text" : "Атаковать охранника в надежде забрать его пропуск", + "nextNodeId" : 4 + }, { + "id" : 2, + "text" : "Выпрыгнуть в окно (вы на 40-м этаже)", + "nextNodeId" : 6 + } ], + "commonType" : true, + "victory" : false + }, { + "id" : 5, + "text" : "Респиратор оказывается неисправным.", + "type" : "defeat", + "options" : [ ], + "commonType" : false, + "victory" : false + }, { + "id" : 6, + "text" : "Гравитация — жестокая штука.", + "type" : "defeat", + "options" : [ ], + "commonType" : false, + "victory" : false + }, { + "id" : 3, + "text" : "Вы у сердца системы. Здесь можно либо спастись самому, либо уничтожить данные врага.", + "type" : "common", + "options" : [ { + "id" : 0, + "text" : "Перегрузить реактор, чтобы вызвать хаос", + "nextNodeId" : 7 + }, { + "id" : 1, + "text" : "Сдаться охране в обмен на информацию", + "nextNodeId" : 8 + }, { + "id" : 2, + "text" : "Использовать вентиль, чтобы направить газ обратно в казармы охраны", + "nextNodeId" : 4 + } ], + "commonType" : true, + "victory" : false + }, { + "id" : 7, + "text" : "Эпический взрыв, вы улетаете на фоне огня.", + "type" : "victory", + "options" : [ ], + "commonType" : false, + "victory" : true + }, { + "id" : 8, + "text" : "Корпорации не ведут переговоры с предателями.", + "type" : "defeat", + "options" : [ ], + "commonType" : false, + "victory" : false + }, { + "id" : 4, + "text" : "Вертолет корпорации уже заходит на посадку, чтобы забрать вас (или пристрелить).", + "type" : "common", + "options" : [ { + "id" : 0, + "text" : "Перехватить управление вертолетом через планшет", + "nextNodeId" : 9 + }, { + "id" : 1, + "text" : "Прыгнуть на вертолет вручную", + "nextNodeId" : 10 + }, { + "id" : 2, + "text" : "Уничтожить планшет и поднять руки", + "nextNodeId" : 11 + } ], + "commonType" : true, + "victory" : false + }, { + "id" : 9, + "text" : "Вы улетаете с данными.", + "type" : "victory", + "options" : [ ], + "commonType" : false, + "victory" : true + }, { + "id" : 10, + "text" : "Вы соскальзываете с обледенелого полоза.", + "type" : "defeat", + "options" : [ ], + "commonType" : false, + "victory" : false + }, { + "id" : 11, + "text" : "Вас устраняют как ненужного свидетеля.", + "type" : "defeat", + "options" : [ ], + "commonType" : false, + "victory" : false + } ], + "firstNode" : { + "id" : 1, + "text" : "Газ начинает шипеть из вентиляции. Перед вами три выхода.", + "type" : "common", + "options" : [ { + "id" : 0, + "text" : "Взломать терминал управления лифтом", + "nextNodeId" : 4 + }, { + "id" : 1, + "text" : "Броситься в технический туннель для кабелей", + "nextNodeId" : 2 + }, { + "id" : 2, + "text" : "Попытаться отключить подачу газа напрямую", + "nextNodeId" : 3 + }, { + "id" : 3, + "text" : "Забиться в угол и надеть респиратор", + "nextNodeId" : 5 + } ], + "commonType" : true, + "victory" : false + } +} \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/quests/quest_1769458945287.json b/src/main/webapp/WEB-INF/quests/quest_1769458945287.json new file mode 100644 index 0000000..afd465d --- /dev/null +++ b/src/main/webapp/WEB-INF/quests/quest_1769458945287.json @@ -0,0 +1,151 @@ +{ + "title" : "Побег из хижины ведьмы", + "prologue" : "Вы очнулись в огромном котле. К счастью, вода еще холодная, а старуха ушла в лес за мухоморами. У вас есть шанс сбежать, пока огонь не разгорелся.", + "nodes" : [ { + "id" : 1, + "text" : "Кухня. Вокруг развешаны пучки трав, а на столе спит черный кот размером с собаку.", + "type" : "common", + "options" : [ { + "id" : 0, + "text" : "Тихо вылезти из котла и шмыгнуть в приоткрытую дверь", + "nextNodeId" : 3 + }, { + "id" : 1, + "text" : "Пошарить по полкам в поиске сонного зелья для кота", + "nextNodeId" : 2 + }, { + "id" : 2, + "text" : "Попробовать договориться с котом, предложив ему свою колбасу из кармана", + "nextNodeId" : 4 + }, { + "id" : 3, + "text" : "Спрятаться в печи", + "nextNodeId" : 5 + } ], + "commonType" : true, + "victory" : false + }, { + "id" : 5, + "text" : "Ведьма вернулась и разожгла огонь. Вы становитесь главным ингредиентом вечернего супа.", + "type" : "defeat", + "options" : [ ], + "commonType" : false, + "victory" : false + }, { + "id" : 2, + "text" : "Кладовая: тут полно странных банок. Одна из них светится странным синим светом.", + "type" : "common", + "options" : [ { + "id" : 0, + "text" : "Выпить синее зелье", + "nextNodeId" : 4 + }, { + "id" : 1, + "text" : "Разбить банки, чтобы поднять шум и выманить ведьму", + "nextNodeId" : 6 + }, { + "id" : 2, + "text" : "Взять метлу и попытаться на ней взлететь", + "nextNodeId" : 3 + } ], + "commonType" : true, + "victory" : false + }, { + "id" : 6, + "text" : "Ведьма заходит и превращает вас в жабу. Вы становитесь главным ингредиентом вечернего супа.", + "type" : "defeat", + "options" : [ ], + "commonType" : false, + "victory" : false + }, { + "id" : 3, + "text" : "Заколдованный двор: забор из костей не пускает вас, а калитка требует загадку.", + "type" : "common", + "options" : [ { + "id" : 0, + "text" : "Попробовать перелезть через забор", + "nextNodeId" : 7 + }, { + "id" : 1, + "text" : "Ответить на загадку калитки", + "nextNodeId" : 8 + }, { + "id" : 2, + "text" : "Вернуться в дом, чтобы найти ключ", + "nextNodeId" : 1 + } ], + "commonType" : true, + "victory" : false + }, { + "id" : 7, + "text" : "Кости начинают кусаться. Вы становитесь главным ингредиентом вечернего супа.", + "type" : "defeat", + "options" : [ ], + "commonType" : false, + "victory" : false + }, { + "id" : 8, + "text" : "Вы свободны.", + "type" : "victory", + "options" : [ ], + "commonType" : false, + "victory" : true + }, { + "id" : 4, + "text" : "Тайный лаз: вы нашли лазейку, которая ведет прямо за пределы участка, под корнями старого дуба.", + "type" : "common", + "options" : [ { + "id" : 0, + "text" : "Проползти по туннелю до конца", + "nextNodeId" : 9 + }, { + "id" : 1, + "text" : "Забрать по пути мешок с золотом ведьмы", + "nextNodeId" : 10 + }, { + "id" : 2, + "text" : "Использовать лаз, чтобы устроить подкоп под забор", + "nextNodeId" : 3 + } ], + "commonType" : true, + "victory" : false + }, { + "id" : 9, + "text" : "Вы в лесу, далеко от хижины.", + "type" : "victory", + "options" : [ ], + "commonType" : false, + "victory" : true + }, { + "id" : 10, + "text" : "Золото оказывается проклятым и примагничивает вас к полу. Вы становитесь главным ингредиентом вечернего супа.", + "type" : "defeat", + "options" : [ ], + "commonType" : false, + "victory" : false + } ], + "firstNode" : { + "id" : 1, + "text" : "Кухня. Вокруг развешаны пучки трав, а на столе спит черный кот размером с собаку.", + "type" : "common", + "options" : [ { + "id" : 0, + "text" : "Тихо вылезти из котла и шмыгнуть в приоткрытую дверь", + "nextNodeId" : 3 + }, { + "id" : 1, + "text" : "Пошарить по полкам в поиске сонного зелья для кота", + "nextNodeId" : 2 + }, { + "id" : 2, + "text" : "Попробовать договориться с котом, предложив ему свою колбасу из кармана", + "nextNodeId" : 4 + }, { + "id" : 3, + "text" : "Спрятаться в печи", + "nextNodeId" : 5 + } ], + "commonType" : true, + "victory" : false + } +} \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/result.jsp b/src/main/webapp/WEB-INF/result.jsp new file mode 100644 index 0000000..0e15a48 --- /dev/null +++ b/src/main/webapp/WEB-INF/result.jsp @@ -0,0 +1,31 @@ +<%@ page contentType="text/html;charset=UTF-8"%> + + + + + + Результат + + <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> + + + Вернуться в меню +
+

+ + + You WIN! + + + You LOST! + + +

+

+ +

+ +
+ + \ No newline at end of file diff --git a/src/main/webapp/static/style.css b/src/main/webapp/static/style.css index fc51f6e..94a29d3 100644 --- a/src/main/webapp/static/style.css +++ b/src/main/webapp/static/style.css @@ -14,6 +14,7 @@ body { /* Контейнер для контента */ .container { + margin-top: 20px; max-width: 600px; width: 90%; text-align: center; @@ -24,6 +25,17 @@ body { position: relative; } +.quest-title { + font-size: 2.5em; + letter-spacing: 4px; + text-transform: uppercase; + color: #ffd54f; /* Золотистый цвет, как у счетчика свечей */ + text-shadow: 0 0 15px rgba(255, 213, 79, 0.4), 2px 2px 4px #000; + margin-bottom: 30px; + text-align: center; + font-weight: 700; +} + /* Стили кнопок */ .btn { display: block; From 3e22677185e1c784f72ccb6427195a24f961f6fb Mon Sep 17 00:00:00 2001 From: mxchbot Date: Fri, 30 Jan 2026 18:09:01 +0300 Subject: [PATCH 5/8] ADD statistics --- .../chebotarev/component/Statistics.java | 27 +++++++++++++++++ .../javarush/chebotarev/component/Utils.java | 29 ++++++++++++++----- .../chebotarev/servlet/MainMenuServlet.java | 14 ++++++--- .../chebotarev/servlet/NextStageServlet.java | 18 +++++++++++- src/main/webapp/WEB-INF/main-menu.jsp | 9 ++++++ src/main/webapp/WEB-INF/new-quest.jsp | 2 +- src/main/webapp/static/style.css | 26 ++++++++++++++++- 7 files changed, 111 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/javarush/chebotarev/component/Statistics.java diff --git a/src/main/java/com/javarush/chebotarev/component/Statistics.java b/src/main/java/com/javarush/chebotarev/component/Statistics.java new file mode 100644 index 0000000..d6e2f9f --- /dev/null +++ b/src/main/java/com/javarush/chebotarev/component/Statistics.java @@ -0,0 +1,27 @@ +package com.javarush.chebotarev.component; + +public class Statistics { + + private int victoriesCount = 0; + private int defeatsCount = 0; + + public int getVictoriesCount() { + return victoriesCount; + } + + public int getDefeatsCount() { + return defeatsCount; + } + + public int getGamesCount() { + return (victoriesCount + defeatsCount); + } + + public void incVictories() { + victoriesCount++; + } + + public void incDefeats() { + defeatsCount++; + } +} diff --git a/src/main/java/com/javarush/chebotarev/component/Utils.java b/src/main/java/com/javarush/chebotarev/component/Utils.java index c74f7e8..09d34a1 100644 --- a/src/main/java/com/javarush/chebotarev/component/Utils.java +++ b/src/main/java/com/javarush/chebotarev/component/Utils.java @@ -8,17 +8,32 @@ private Utils() { } @SuppressWarnings("unchecked") - public static T extractAttribute(HttpSession currentSession, - String attributeName, - Class attributeType) { + public static T tryExtractAttribute(HttpSession currentSession, + String attributeName, + Class attributeClass) { Object attribute = currentSession.getAttribute(attributeName); if (attribute != null) { - Class attributeClass = attribute.getClass(); - if (attributeClass.equals(attributeType)) { + Class extractedAttributeClass = attribute.getClass(); + if (extractedAttributeClass.equals(attributeClass)) { return (T) attribute; } } - currentSession.invalidate(); - throw new RuntimeException("Session is broken, try one more time"); + return null; + } + + public static T extractAttribute(HttpSession currentSession, + String attributeName, + Class attributeClass) { + T attribute = tryExtractAttribute( + currentSession, + attributeName, + attributeClass + ); + if (attribute != null) { + return attribute; + } else { + currentSession.invalidate(); + throw new RuntimeException("Session is broken, try one more time"); + } } } diff --git a/src/main/java/com/javarush/chebotarev/servlet/MainMenuServlet.java b/src/main/java/com/javarush/chebotarev/servlet/MainMenuServlet.java index 8cd7ae8..584004d 100644 --- a/src/main/java/com/javarush/chebotarev/servlet/MainMenuServlet.java +++ b/src/main/java/com/javarush/chebotarev/servlet/MainMenuServlet.java @@ -1,9 +1,6 @@ package com.javarush.chebotarev.servlet; -import com.javarush.chebotarev.component.Go; -import com.javarush.chebotarev.component.ObjectRepository; -import com.javarush.chebotarev.component.Path; -import com.javarush.chebotarev.component.QuestService; +import com.javarush.chebotarev.component.*; import com.javarush.chebotarev.quest.QuestMetadata; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; @@ -24,6 +21,15 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws Se QuestService questService = ObjectRepository.getQuestService(); List availableQuests = questService.obtainAvailableQuests(getServletContext()); currentSession.setAttribute("availableQuests", availableQuests); + Statistics statistics = Utils.tryExtractAttribute( + currentSession, + "statistics", + Statistics.class + ); + if (statistics == null) { + statistics = new Statistics(); + currentSession.setAttribute("statistics", statistics); + } req.getRequestDispatcher(Path.MAIN_MENU) .forward(req, resp); } diff --git a/src/main/java/com/javarush/chebotarev/servlet/NextStageServlet.java b/src/main/java/com/javarush/chebotarev/servlet/NextStageServlet.java index 2c98319..65712c5 100644 --- a/src/main/java/com/javarush/chebotarev/servlet/NextStageServlet.java +++ b/src/main/java/com/javarush/chebotarev/servlet/NextStageServlet.java @@ -2,6 +2,7 @@ import com.javarush.chebotarev.component.Go; import com.javarush.chebotarev.component.Path; +import com.javarush.chebotarev.component.Statistics; import com.javarush.chebotarev.component.Utils; import com.javarush.chebotarev.quest.CurrentQuest; import jakarta.servlet.ServletException; @@ -26,7 +27,22 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws Se ); int nextNodeId = getSelectedNextNodeId(req); currentQuest.nextStage(nextNodeId); - String path = currentQuest.isDone() ? Path.RESULT : Path.QUEST; + String path; + if (currentQuest.isDone()) { + path = Path.RESULT; + Statistics statistics = Utils.extractAttribute( + currentSession, + "statistics", + Statistics.class + ); + if (currentQuest.isVictory()) { + statistics.incVictories(); + } else { + statistics.incDefeats(); + } + } else { + path = Path.QUEST; + } req.getRequestDispatcher(path) .forward(req, resp); } diff --git a/src/main/webapp/WEB-INF/main-menu.jsp b/src/main/webapp/WEB-INF/main-menu.jsp index 3dd498e..6c6138a 100644 --- a/src/main/webapp/WEB-INF/main-menu.jsp +++ b/src/main/webapp/WEB-INF/main-menu.jsp @@ -25,6 +25,15 @@ +
+
+
Статистика игрока
+
+

Игр всего:

+

Побед:

+

Поражений:

+
+
\ No newline at end of file diff --git a/src/main/webapp/WEB-INF/new-quest.jsp b/src/main/webapp/WEB-INF/new-quest.jsp index a952d88..a90d0a1 100644 --- a/src/main/webapp/WEB-INF/new-quest.jsp +++ b/src/main/webapp/WEB-INF/new-quest.jsp @@ -23,7 +23,7 @@ -
-
@@ -65,7 +54,6 @@
100%
- \ No newline at end of file diff --git a/src/main/webapp/static/editor.css b/src/main/webapp/static/editor.css index b9f4d73..bcc75c9 100644 --- a/src/main/webapp/static/editor.css +++ b/src/main/webapp/static/editor.css @@ -23,7 +23,6 @@ html, body { height: 100vh; } -/* САЙДБАР */ .editor-sidebar { width: 380px; min-width: 380px; @@ -106,7 +105,6 @@ input, textarea, select { margin-top: 20px; } -/* ХОЛСТ */ .nodes-canvas-area { flex-grow: 1; position: relative; @@ -130,7 +128,6 @@ input, textarea, select { will-change: transform; } -/* КАРТОЧКИ */ .node-card { background: #333; border: 2px solid var(--accent-blue); @@ -147,21 +144,17 @@ input, textarea, select { .node-card.victory { border-color: var(--accent-green); } .node-card.defeat { border-color: var(--accent-red); } -/* КАРТОЧКИ - обновляем стили текста */ .node-text-display { font-size: 0.95rem; line-height: 1.5; margin-bottom: 15px; color: #ddd; - - /* ИСПРАВЛЕНИЕ: */ - white-space: pre-wrap; /* Учитывает переносы строк и пробелы */ - word-wrap: break-word; /* Разрывает длинные слова, если они не лезут */ + white-space: pre-wrap; + word-wrap: break-word; overflow-wrap: break-word; - max-width: 100%; /* Чтобы текст не выходил за границы */ + max-width: 100%; } -/* ПРЕВЬЮ ДЕЙСТВИЙ (кнопки внутри карточки) */ .option-preview { background: rgba(0,0,0,0.4); margin-top: 8px; @@ -169,8 +162,6 @@ input, textarea, select { border-radius: 6px; border-left: 4px solid #ffd54f; font-size: 0.85rem; - - /* ИСПРАВЛЕНИЕ: */ white-space: pre-wrap; word-wrap: break-word; } @@ -199,7 +190,6 @@ input, textarea, select { z-index: 200; } -/* Стили для новых кнопок внизу */ .sidebar-footer { margin-top: auto; display: flex; diff --git a/src/main/webapp/static/style.css b/src/main/webapp/static/style.css index 3246b3a..7a12c85 100644 --- a/src/main/webapp/static/style.css +++ b/src/main/webapp/static/style.css @@ -1,4 +1,3 @@ -/* Общие настройки фона и шрифтов */ body { background-color: #1a1a1a; color: #e0e0e0; @@ -12,7 +11,6 @@ body { overflow-x: hidden; } -/* Контейнер для контента */ .container { margin-top: 20px; max-width: 600px; @@ -29,14 +27,13 @@ body { font-size: 2.5em; letter-spacing: 4px; text-transform: uppercase; - color: #ffd54f; /* Золотистый цвет, как у счетчика свечей */ + color: #ffd54f; text-shadow: 0 0 15px rgba(255, 213, 79, 0.4), 2px 2px 4px #000; margin-bottom: 30px; text-align: center; font-weight: 700; } -/* Стили кнопок */ .btn { display: block; width: 100%; @@ -62,11 +59,10 @@ body { transform: translateY(0); } -/* Специальные цвета для кнопок */ -.btn-continue { background-color: #2e7d32; } /* Зеленый */ +.btn-continue { background-color: #2e7d32; } .btn-continue:hover { background-color: #388e3c; } -.btn-create { background-color: #1565c0; } /* Синий */ +.btn-create { background-color: #1565c0; } .btn-create:hover { background-color: #1976d2; } .btn-back { @@ -76,11 +72,10 @@ body { width: auto; padding: 10px 20px; font-size: 0.9em; - background-color: #c62828; /* Красный */ + background-color: #c62828; z-index: 100; } -/* Счётчик свечей */ .candles-info { color: #ffd54f; font-size: 1.2em; @@ -92,7 +87,6 @@ body { gap: 10px; } -/* Заголовки */ h1, h2 { color: #ffffff; margin-top: 0; From 6f2c0e11b4eea8055051edf4d5ca96be2c9b2372 Mon Sep 17 00:00:00 2001 From: mxchbot Date: Tue, 3 Feb 2026 15:59:17 +0300 Subject: [PATCH 8/8] ADD tests --- pom.xml | 67 ++++++++++++++- .../com/javarush/chebotarev/cmd/Command.java | 2 +- .../chebotarev/component/QuestService.java | 26 ++++-- .../controller/FrontController.java | 2 +- .../java/com/javarush/chebotarev/Base.java | 69 ++++++++++++++++ .../java/com/javarush/chebotarev/BaseIT.java | 51 ++++++++++++ .../chebotarev/cmd/ContinueQuestIT.java | 70 ++++++++++++++++ .../com/javarush/chebotarev/cmd/EditorIT.java | 76 +++++++++++++++++ .../javarush/chebotarev/cmd/MainMenuIT.java | 39 +++++++++ .../javarush/chebotarev/cmd/NewQuestIT.java | 58 +++++++++++++ .../javarush/chebotarev/cmd/NextStageIT.java | 82 +++++++++++++++++++ .../chebotarev/cmd/PreviousStageIT.java | 45 ++++++++++ .../javarush/chebotarev/cmd/StartQuestIT.java | 40 +++++++++ .../chebotarev/quest/CurrentQuestTest.java | 45 ++++++++++ 14 files changed, 664 insertions(+), 8 deletions(-) create mode 100644 src/test/java/com/javarush/chebotarev/Base.java create mode 100644 src/test/java/com/javarush/chebotarev/BaseIT.java create mode 100644 src/test/java/com/javarush/chebotarev/cmd/ContinueQuestIT.java create mode 100644 src/test/java/com/javarush/chebotarev/cmd/EditorIT.java create mode 100644 src/test/java/com/javarush/chebotarev/cmd/MainMenuIT.java create mode 100644 src/test/java/com/javarush/chebotarev/cmd/NewQuestIT.java create mode 100644 src/test/java/com/javarush/chebotarev/cmd/NextStageIT.java create mode 100644 src/test/java/com/javarush/chebotarev/cmd/PreviousStageIT.java create mode 100644 src/test/java/com/javarush/chebotarev/cmd/StartQuestIT.java create mode 100644 src/test/java/com/javarush/chebotarev/quest/CurrentQuestTest.java diff --git a/pom.xml b/pom.xml index 5cbaf98..0b97e9d 100644 --- a/pom.xml +++ b/pom.xml @@ -59,6 +59,16 @@ junit-jupiter-engine test
+ + org.mockito + mockito-core + test + + + org.mockito + mockito-junit-jupiter + test + com.fasterxml.jackson.core @@ -75,7 +85,62 @@ maven-war-plugin 3.4.0 + + + org.apache.maven.plugins + maven-surefire-plugin + 3.2.5 + + + **/*IT.java + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 3.2.5 + + + integration-test + + integration-test + + + + verify + + verify + + + + + + **/*IT.java + + + + + + org.jacoco + jacoco-maven-plugin + 0.8.11 + + + + prepare-agent + + + + report + verify + + report + + + + - \ No newline at end of file diff --git a/src/main/java/com/javarush/chebotarev/cmd/Command.java b/src/main/java/com/javarush/chebotarev/cmd/Command.java index 01f2e87..87ae2f1 100644 --- a/src/main/java/com/javarush/chebotarev/cmd/Command.java +++ b/src/main/java/com/javarush/chebotarev/cmd/Command.java @@ -18,7 +18,7 @@ public String doPost(HttpServletRequest req) { protected String getView() { String simpleName = this.getClass().getSimpleName(); - return convertCamelCaseToKebabStyle(simpleName); + return "/" + convertCamelCaseToKebabStyle(simpleName); } private static String convertCamelCaseToKebabStyle(String string) { diff --git a/src/main/java/com/javarush/chebotarev/component/QuestService.java b/src/main/java/com/javarush/chebotarev/component/QuestService.java index 65f7e60..86f10a4 100644 --- a/src/main/java/com/javarush/chebotarev/component/QuestService.java +++ b/src/main/java/com/javarush/chebotarev/component/QuestService.java @@ -28,11 +28,13 @@ public QuestService() { } } - public void saveQuest(Quest quest) { + public String saveQuest(Quest quest) { + String filepath; File file; do { String filename = "quest_" + System.currentTimeMillis() + ".json"; file = new File(userQuestsPath, filename); + filepath = userQuestsPath + File.separator + filename; } while (file.exists()); ObjectMapper mapper = ObjectRepository.find(ObjectMapper.class); try { @@ -40,20 +42,21 @@ public void saveQuest(Quest quest) { } catch (IOException e) { throw new RuntimeException(e); } + return filepath; } public Quest loadQuest(QuestMetadata questMetadata, ServletContext servletContext) { Quest quest; - ObjectMapper mapper = ObjectRepository.find(ObjectMapper.class); if (questMetadata.isServerQuest()) { InputStream inputStream = servletContext.getResourceAsStream(questMetadata.getPath()); + quest = loadQuest(inputStream); try { - quest = mapper.readValue(inputStream, Quest.class); inputStream.close(); } catch (IOException e) { throw new RuntimeException(e); } } else { + ObjectMapper mapper = ObjectRepository.find(ObjectMapper.class); File file = new File(questMetadata.getPath()); try { quest = mapper.readValue(file, Quest.class); @@ -64,6 +67,17 @@ public Quest loadQuest(QuestMetadata questMetadata, ServletContext servletContex return quest; } + public Quest loadQuest(InputStream inputStream) { + Quest quest; + ObjectMapper mapper = ObjectRepository.find(ObjectMapper.class); + try { + quest = mapper.readValue(inputStream, Quest.class); + } catch (IOException e) { + throw new RuntimeException(e); + } + return quest; + } + public List obtainAvailableQuests(ServletContext servletContext) { List availableQuests = new ArrayList<>(); Set resourcePaths = servletContext.getResourcePaths(SERVER_QUESTS_PATH); @@ -77,9 +91,11 @@ public List obtainAvailableQuests(ServletContext servletContext) } catch (IOException e) { throw new RuntimeException(e); } - QuestMetadata questMetadata = new QuestMetadata(quest.getTitle(), + QuestMetadata questMetadata = new QuestMetadata( + quest.getTitle(), path, - true); + true + ); availableQuests.add(questMetadata); } File dir = new File(userQuestsPath); diff --git a/src/main/java/com/javarush/chebotarev/controller/FrontController.java b/src/main/java/com/javarush/chebotarev/controller/FrontController.java index a203e84..9397506 100644 --- a/src/main/java/com/javarush/chebotarev/controller/FrontController.java +++ b/src/main/java/com/javarush/chebotarev/controller/FrontController.java @@ -42,6 +42,6 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I } private static String getJsp(String view) { - return "/WEB-INF/" + view + ".jsp"; + return "/WEB-INF" + view + ".jsp"; } } diff --git a/src/test/java/com/javarush/chebotarev/Base.java b/src/test/java/com/javarush/chebotarev/Base.java new file mode 100644 index 0000000..f23da13 --- /dev/null +++ b/src/test/java/com/javarush/chebotarev/Base.java @@ -0,0 +1,69 @@ +package com.javarush.chebotarev; + +import com.javarush.chebotarev.component.ObjectRepository; +import com.javarush.chebotarev.component.QuestService; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; + +public class Base { + + protected final QuestService questService = ObjectRepository.find(QuestService.class); + + protected InputStream createInputStream() { + String quest = + """ + { + "title" : "Title", + "prologue" : "About", + "nodes" : [ { + "id" : 1, + "text" : "Text.", + "type" : "common", + "options" : [ { + "id" : 0, + "text" : "Action1", + "nextNodeId" : 2 + }, { + "id" : 1, + "text" : "Action2", + "nextNodeId" : 3 + }, { + "id" : 2, + "text" : "Action3", + "nextNodeId" : 4 + } ], + "victory" : false, + "commonType" : true + }, { + "id" : 2, + "text" : "Text.", + "type" : "victory", + "options" : [ ], + "victory" : true, + "commonType" : false + }, { + "id" : 3, + "text" : "Text.", + "type" : "defeat", + "options" : [ ], + "victory" : false, + "commonType" : false + }, { + "id" : 4, + "text" : "Text.", + "type" : "common", + "options" : [ { + "id" : 0, + "text" : "Action1", + "nextNodeId" : 1 + } ], + "victory" : false, + "commonType" : true + } ] + } + """; + return new ByteArrayInputStream(quest.getBytes(StandardCharsets.UTF_8)); + } +} diff --git a/src/test/java/com/javarush/chebotarev/BaseIT.java b/src/test/java/com/javarush/chebotarev/BaseIT.java new file mode 100644 index 0000000..73fb572 --- /dev/null +++ b/src/test/java/com/javarush/chebotarev/BaseIT.java @@ -0,0 +1,51 @@ +package com.javarush.chebotarev; + +import com.javarush.chebotarev.quest.Quest; +import jakarta.servlet.ServletContext; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.*; + +public class BaseIT extends Base { + + protected final HttpServletRequest req; + protected final HttpSession session; + protected final HttpServlet servlet; + protected final ServletContext servletContext; + + protected BaseIT() { + req = mock(HttpServletRequest.class); + session = mock(HttpSession.class); + when(req.getSession()).thenReturn(session); + doNothing().when(session).setAttribute(anyString(), any()); + servlet = mock(HttpServlet.class); + servletContext = mock(ServletContext.class); + when(servlet.getServletContext()).thenReturn(servletContext); + } + + protected String createQuestFile() { + String filepath; + try (InputStream inputStream = createInputStream()) { + Quest quest = questService.loadQuest(inputStream); + filepath = questService.saveQuest(quest); + } catch (IOException e) { + throw new RuntimeException(e); + } + return filepath; + } + + protected void deleteQuestFile(String filepath) { + File file = new File(filepath); + if (!file.delete()) { + throw new RuntimeException(filepath + " not deleted"); + } + } +} diff --git a/src/test/java/com/javarush/chebotarev/cmd/ContinueQuestIT.java b/src/test/java/com/javarush/chebotarev/cmd/ContinueQuestIT.java new file mode 100644 index 0000000..252b851 --- /dev/null +++ b/src/test/java/com/javarush/chebotarev/cmd/ContinueQuestIT.java @@ -0,0 +1,70 @@ +package com.javarush.chebotarev.cmd; + +import com.javarush.chebotarev.BaseIT; +import com.javarush.chebotarev.component.Attribute; +import com.javarush.chebotarev.component.Go; +import com.javarush.chebotarev.component.ObjectRepository; +import com.javarush.chebotarev.component.Utils; +import com.javarush.chebotarev.quest.CurrentQuest; +import com.javarush.chebotarev.quest.Quest; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import java.io.IOException; +import java.io.InputStream; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +class ContinueQuestIT extends BaseIT { + + @Test + void whenPageIsOpened_thenCommandReturnsJspPage() { + try (InputStream inputStream = createInputStream()) { + Quest quest = questService.loadQuest(inputStream); + try (MockedStatic utils = Mockito.mockStatic(Utils.class)) { + CurrentQuest currentQuest = new CurrentQuest(quest); + when(Utils.extractAttribute( + eq(session), + eq(Attribute.CURRENT_QUEST), + any() + )).thenReturn(currentQuest); + + ContinueQuest continueQuest = ObjectRepository.find(ContinueQuest.class); + String view = continueQuest.doGet(req, servlet); + + assertEquals(Go.NEW_QUEST, view); + + currentQuest = new CurrentQuest(quest); + currentQuest.start(); + when(Utils.extractAttribute( + eq(session), + eq(Attribute.CURRENT_QUEST), + any() + )).thenReturn(currentQuest); + + view = continueQuest.doGet(req, servlet); + + assertEquals(Go.QUEST, view); + + currentQuest = new CurrentQuest(quest); + currentQuest.start(); + currentQuest.nextStage(2); + when(Utils.extractAttribute( + eq(session), + eq(Attribute.CURRENT_QUEST), + any() + )).thenReturn(currentQuest); + + view = continueQuest.doGet(req, servlet); + + assertEquals(Go.RESULT, view); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/javarush/chebotarev/cmd/EditorIT.java b/src/test/java/com/javarush/chebotarev/cmd/EditorIT.java new file mode 100644 index 0000000..fba9343 --- /dev/null +++ b/src/test/java/com/javarush/chebotarev/cmd/EditorIT.java @@ -0,0 +1,76 @@ +package com.javarush.chebotarev.cmd; + +import com.javarush.chebotarev.BaseIT; +import com.javarush.chebotarev.component.Go; +import com.javarush.chebotarev.component.ObjectRepository; +import com.javarush.chebotarev.quest.Quest; +import org.junit.jupiter.api.Test; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.Objects; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.when; + +class EditorIT extends BaseIT { + + private final Editor editor = ObjectRepository.find(Editor.class); + + @Test + void whenPageIsOpened_thenCommandReturnsJspPage() { + String view = editor.doGet(req, servlet); + + assertEquals(Go.EDITOR, view); + } + + @Test + void whenPublishQuest_thenCommandCreatesNewQuestFileAndRetursJspPage() { + try (InputStream inputStream1 = createInputStream(); + InputStream inputStream2 = createInputStream()) { + BufferedReader bufferedReader = new BufferedReader( + new InputStreamReader( + inputStream1, + StandardCharsets.UTF_8 + )); + doNothing().when(req).setCharacterEncoding(anyString()); + when(req.getReader()).thenReturn(bufferedReader); + Quest dummyQuest = questService.loadQuest(inputStream2); + String dummyQuestFilepath = questService.saveQuest(dummyQuest); + File dummyQuestFile = new File(dummyQuestFilepath); + File[] filesBeforePost = dummyQuestFile.getParentFile().listFiles(); + int fileCountBeforePost = Objects.requireNonNull(filesBeforePost).length; + + String view = editor.doPost(req); + File[] filesAfterPost = dummyQuestFile.getParentFile().listFiles(); + int fileCountAfterPost = Objects.requireNonNull(filesAfterPost).length; + boolean equalFilenames; + for (File fileAP : filesAfterPost) { + equalFilenames = false; + for (File fileBP : filesBeforePost) { + String filenameAP = fileAP.getName(); + String filenameBP = fileBP.getName(); + if (filenameAP.equals(filenameBP)) { + equalFilenames = true; + break; + } + } + if (!equalFilenames) { + if (!fileAP.delete()) { + throw new RuntimeException("Could not delete file: " + fileAP.getAbsolutePath()); + } + } + } + if (!dummyQuestFile.delete()) { + throw new RuntimeException("Could not delete file: " + dummyQuestFile.getAbsolutePath()); + } + + assertEquals(Go.ROOT, view); + assertEquals((fileCountBeforePost + 1), fileCountAfterPost); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/javarush/chebotarev/cmd/MainMenuIT.java b/src/test/java/com/javarush/chebotarev/cmd/MainMenuIT.java new file mode 100644 index 0000000..cada428 --- /dev/null +++ b/src/test/java/com/javarush/chebotarev/cmd/MainMenuIT.java @@ -0,0 +1,39 @@ +package com.javarush.chebotarev.cmd; + +import com.javarush.chebotarev.BaseIT; +import com.javarush.chebotarev.component.Go; +import com.javarush.chebotarev.component.ObjectRepository; +import com.javarush.chebotarev.component.Utils; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import java.io.InputStream; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.*; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.*; + +class MainMenuIT extends BaseIT { + + @Test + void whenPageIsOpened_thenCommandReturnsJspPage() { + InputStream inputStream = createInputStream(); + when(servletContext.getResourcePaths(anyString())) + .thenReturn(Set.of("")); + when(servletContext.getResourceAsStream(anyString())) + .thenReturn(inputStream); + try (MockedStatic utils = Mockito.mockStatic(Utils.class)) { + when(Utils.tryExtractAttribute(eq(session), anyString(), any())) + .thenReturn(null); + + MainMenu mainMenu = ObjectRepository.find(MainMenu.class); + String view = mainMenu.doGet(req, servlet); + + assertEquals(Go.MAIN_MENU, view); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/javarush/chebotarev/cmd/NewQuestIT.java b/src/test/java/com/javarush/chebotarev/cmd/NewQuestIT.java new file mode 100644 index 0000000..78467c9 --- /dev/null +++ b/src/test/java/com/javarush/chebotarev/cmd/NewQuestIT.java @@ -0,0 +1,58 @@ +package com.javarush.chebotarev.cmd; + +import com.javarush.chebotarev.BaseIT; +import com.javarush.chebotarev.component.Go; +import com.javarush.chebotarev.component.ObjectRepository; +import com.javarush.chebotarev.component.Utils; +import com.javarush.chebotarev.quest.QuestMetadata; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.when; + +class NewQuestIT extends BaseIT { + + @Test + void whenPageIsOpened_thenCommandLoadsQuestAndReturnsJspPage() { + when(req.getParameter(anyString())).thenReturn("0"); + try (InputStream inputStream = createInputStream()) { + when(servletContext.getResourceAsStream(anyString())) + .thenReturn(inputStream); + try (MockedStatic utils = Mockito.mockStatic(Utils.class)) { + when(Utils.extractAttribute(eq(session), anyString(), any())) + .thenReturn(List.of(new QuestMetadata( + "Title", + "", + true + ))); + + NewQuest newQuest = ObjectRepository.find(NewQuest.class); + String view = newQuest.doGet(req, servlet); + + assertEquals(Go.NEW_QUEST, view); + + String filepath = createQuestFile(); + when(Utils.extractAttribute(eq(session), anyString(), any())) + .thenReturn(List.of(new QuestMetadata( + "Title", + filepath, + false + ))); + + view = newQuest.doGet(req, servlet); + deleteQuestFile(filepath); + + assertEquals(Go.NEW_QUEST, view); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/javarush/chebotarev/cmd/NextStageIT.java b/src/test/java/com/javarush/chebotarev/cmd/NextStageIT.java new file mode 100644 index 0000000..fe9425d --- /dev/null +++ b/src/test/java/com/javarush/chebotarev/cmd/NextStageIT.java @@ -0,0 +1,82 @@ +package com.javarush.chebotarev.cmd; + +import com.javarush.chebotarev.BaseIT; +import com.javarush.chebotarev.component.*; +import com.javarush.chebotarev.quest.CurrentQuest; +import com.javarush.chebotarev.quest.Quest; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import java.io.IOException; +import java.io.InputStream; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.when; + +class NextStageIT extends BaseIT { + + @Test + void whenPageIsOpened_thenCommandSwitchesStageAndReturnsJspPage() { + try (InputStream inputStream = createInputStream()) { + Quest quest = questService.loadQuest(inputStream); + CurrentQuest currentQuest = new CurrentQuest(quest); + currentQuest.start(); + Statistics statistics = new Statistics(); + try (MockedStatic utils = Mockito.mockStatic(Utils.class)) { + when(Utils.extractAttribute( + eq(session), + eq(Attribute.STATISTICS), + any() + )).thenReturn(statistics); + + when(Utils.extractAttribute( + eq(session), + eq(Attribute.CURRENT_QUEST), + any() + )).thenReturn(currentQuest); + when(req.getParameter(anyString())).thenReturn("2"); + + NextStage nextStage = ObjectRepository.find(NextStage.class); + String view = nextStage.doGet(req, servlet); + + assertEquals(Go.RESULT, view); + assertEquals(1, statistics.getVictoriesCount()); + assertEquals(0, statistics.getDefeatsCount()); + + currentQuest = new CurrentQuest(quest); + currentQuest.start(); + when(Utils.extractAttribute( + eq(session), + eq(Attribute.CURRENT_QUEST), + any() + )).thenReturn(currentQuest); + when(req.getParameter(anyString())).thenReturn("3"); + + view = nextStage.doGet(req, servlet); + + assertEquals(Go.RESULT, view); + assertEquals(1, statistics.getVictoriesCount()); + assertEquals(1, statistics.getDefeatsCount()); + + currentQuest = new CurrentQuest(quest); + currentQuest.start(); + when(Utils.extractAttribute( + eq(session), + eq(Attribute.CURRENT_QUEST), + any() + )).thenReturn(currentQuest); + when(req.getParameter(anyString())).thenReturn("4"); + + view = nextStage.doGet(req, servlet); + + assertEquals(Go.QUEST, view); + assertEquals(1, statistics.getVictoriesCount()); + assertEquals(1, statistics.getDefeatsCount()); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/javarush/chebotarev/cmd/PreviousStageIT.java b/src/test/java/com/javarush/chebotarev/cmd/PreviousStageIT.java new file mode 100644 index 0000000..3034162 --- /dev/null +++ b/src/test/java/com/javarush/chebotarev/cmd/PreviousStageIT.java @@ -0,0 +1,45 @@ +package com.javarush.chebotarev.cmd; + +import com.javarush.chebotarev.BaseIT; +import com.javarush.chebotarev.component.Go; +import com.javarush.chebotarev.component.ObjectRepository; +import com.javarush.chebotarev.component.Utils; +import com.javarush.chebotarev.quest.CurrentQuest; +import com.javarush.chebotarev.quest.Quest; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import java.io.IOException; +import java.io.InputStream; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.when; + +class PreviousStageIT extends BaseIT { + + @Test + void whenPageIsOpened_thenCommandSwitchesStageAndReturnsJspPage() { + try (InputStream inputStream = createInputStream()) { + Quest quest = questService.loadQuest(inputStream); + CurrentQuest currentQuest = new CurrentQuest(quest); + currentQuest.start(); + currentQuest.nextStage(4); + try (MockedStatic utils = Mockito.mockStatic(Utils.class)) { + when(Utils.extractAttribute( + eq(session), + anyString(), + any() + )).thenReturn(currentQuest); + + PreviousStage previousStage = ObjectRepository.find(PreviousStage.class); + String view = previousStage.doGet(req, servlet); + + assertEquals(Go.QUEST, view); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/javarush/chebotarev/cmd/StartQuestIT.java b/src/test/java/com/javarush/chebotarev/cmd/StartQuestIT.java new file mode 100644 index 0000000..530d1ae --- /dev/null +++ b/src/test/java/com/javarush/chebotarev/cmd/StartQuestIT.java @@ -0,0 +1,40 @@ +package com.javarush.chebotarev.cmd; + +import com.javarush.chebotarev.BaseIT; +import com.javarush.chebotarev.component.Go; +import com.javarush.chebotarev.component.ObjectRepository; +import com.javarush.chebotarev.component.Utils; +import com.javarush.chebotarev.quest.CurrentQuest; +import com.javarush.chebotarev.quest.Quest; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import java.io.IOException; +import java.io.InputStream; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.when; + +class StartQuestIT extends BaseIT { + + @Test + void whenPageIsOpened_thenCommandReturnsJspPage() { + try (InputStream inputStream = createInputStream()) { + Quest quest = questService.loadQuest(inputStream); + CurrentQuest currentQuest = new CurrentQuest(quest); + try (MockedStatic utils = Mockito.mockStatic(Utils.class)) { + when(Utils.extractAttribute(eq(session), anyString(), any())) + .thenReturn(currentQuest); + + StartQuest startQuest = ObjectRepository.find(StartQuest.class); + String view = startQuest.doGet(req, servlet); + + assertEquals(Go.QUEST, view); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/javarush/chebotarev/quest/CurrentQuestTest.java b/src/test/java/com/javarush/chebotarev/quest/CurrentQuestTest.java new file mode 100644 index 0000000..1faa442 --- /dev/null +++ b/src/test/java/com/javarush/chebotarev/quest/CurrentQuestTest.java @@ -0,0 +1,45 @@ +package com.javarush.chebotarev.quest; + +import com.javarush.chebotarev.Base; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.io.InputStream; + +import static org.junit.jupiter.api.Assertions.*; + +class CurrentQuestTest extends Base { + + private CurrentQuest currentQuest; + + @BeforeEach + void createCurrentQuest() { + try (InputStream inputStream = createInputStream()) { + Quest quest = questService.loadQuest(inputStream); + currentQuest = new CurrentQuest(quest); + currentQuest.start(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Test + void whenCurrentNodeIsCommonType_thenMethodIsVictoryThrowsExceptionWithMessage() { + RuntimeException exception = assertThrows(RuntimeException.class, () -> currentQuest.isVictory()); + assertEquals("Current node is common type", exception.getMessage()); + } + + @Test + void whenMethodNextStageIsCalledWithUnknownNodeId_thenTheMethodThrowsExceptionWithMessage() { + int unknownNodeId = Integer.MAX_VALUE; + RuntimeException exception = assertThrows(RuntimeException.class, () -> currentQuest.nextStage(unknownNodeId)); + assertEquals("nextNodeId " + unknownNodeId + " not found", exception.getMessage()); + } + + @Test + void whenThereIsNoPreviousStage_thenMethodPreviousStageThrowsExceptionWithMessage() { + RuntimeException exception = assertThrows(RuntimeException.class, () -> currentQuest.previousStage()); + assertEquals("No previous stage found", exception.getMessage()); + } +} \ No newline at end of file