Skip to content

Golikov do#2

Open
Golikov-DO wants to merge 8 commits intodemologin:mainfrom
Golikov-DO:golikovDO
Open

Golikov do#2
Golikov-DO wants to merge 8 commits intodemologin:mainfrom
Golikov-DO:golikovDO

Conversation

@Golikov-DO
Copy link

No description provided.

Fixed the display of the Admin Panel. No tests.
Moved the logic of the JS into admin.js.
Fixed a bug with an empty password. Found a bug with quest selection during a quest. Needs fixing.
The project is ready.
@demologin
Copy link
Owner

Общий вывод по проекту

Проект демонстрирует хорошее владение базовыми принципами Java и архитектурой веб-приложений на базе сервлетов. Видно стремление к структурированию кода: выделены слои репозиториев, сервисов и моделей, что соответствует классическим паттернам. Использование современных текстовых блоков в тестах и Java 21 фич (хотя и не в полной мере) говорит о прогрессивном подходе к обучению.

Основные точки роста:

Инверсия управления (IoC): Сейчас проект сильно опирается на статические методы и глобальные состояния (особенно в репозиториях). Переход к созданию экземпляров классов и их внедрению через конструкторы сделает код гибким и профессиональным.

Обработка исключений и логирование: Замена System.out.println на полноценный логгер и использование Optional вместо возврата null значительно повысит надежность приложения.

Безопасность и валидация: Стоит уделить внимание защите данных (пароли) и проверке того, что приходит от пользователя в сервлеты.

Итоговая оценка: A

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

class QuestRepositoryTest {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Использование модификатора public в тестовых классах JUnit 5 избыточно. Пакетная видимость является предпочтительной для чистоты кода.


@BeforeEach
void clearRepositoryBeforeEachTest() {
QuestRepository.clear();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Метод QuestRepository.clear() намекает на наличие глобального состояния. Для тестов лучше использовать внедрение зависимостей (Dependency Injection), чтобы изолировать тесты друг от друга.

@DisplayName("Test loadTxt stores quest and get returns it")
void testLoadTxtStoresQuestAndGetReturnsIt() throws Exception {

String data = """
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Текстовые блоки (Text Blocks) — отличная фича Java 15+. Стоит убедиться, что отступы внутри блока соответствуют ожидаемому формату парсера.


ServletContext ctx = mock(ServletContext.class);

when(ctx.getResourcePaths("/WEB-INF/classes/quests/"))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Использование магических строк вроде '/WEB-INF/classes/quests/' дублируется в тестах. Рекомендуется вынести их в константы для соблюдения принципа DRY.


import com.javarush.golikov.quest.auth.Role;
import com.javarush.golikov.quest.model.User;
import org.junit.jupiter.api.*;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Использование импортов со звездочкой (wildcard imports) затрудняет чтение зависимостей. Лучше импортировать конкретные классы: @test, @beforeeach и т.д.

import com.javarush.golikov.quest.repository.UserRepository;
import jakarta.servlet.http.HttpSession;

public class AuthService {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Класс не помечен как final. Если наследование не предполагается, хорошей практикой является закрытие класса для изменений.


import java.util.Map;

public class Quest {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Отсутствует конструктор по умолчанию или конструктор со всеми полями. Стоит явно определить инициализацию объекта.

public User login(String login, String password) {
User user = UserRepository.find(login);
if (user != null && user.password().equals(password)) {
return user;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Пароли хранятся или передаются в открытом виде. С точки зрения безопасности, это критическая уязвимость.

Choice choice = node.choices().stream()
.filter(c -> c.next().equals(next))
.findFirst()
.orElseThrow();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Метод возвращает null в случае ошибки. Лучше использовать Optional или выбрасывать кастомное исключение.


try (MockedStatic<UserRepository> repoMock = mockStatic(UserRepository.class)) {
repoMock.when(() -> UserRepository.find("admin"))
.thenReturn(user);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тест проверяет сразу несколько сценариев (успешный вход и неверный пароль). Лучше разделить их на разные тестовые методы.

@Test
void testRemoveUnknownIdDoesNothing() {
QuestRepository.remove("unknown");
assertTrue(QuestRepository.all().isEmpty());
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ассерты в тестах не содержат описания ошибки. Добавление сообщения в assertEquals поможет быстрее понять причину падения теста.

@demologin
Copy link
Owner

Pingbot

@demologin demologin self-requested a review January 31, 2026 16:29
GDGo added a commit to GDGo/ProjectPantera that referenced this pull request Feb 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants