Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
import com.DesktopApplicationClientJava.services.ServiceRegistry;
import com.DesktopApplicationClientJava.session.Session;
import com.DesktopApplicationClientJava.utils.ControllerWiring;
import io.qameta.allure.Epic;
import io.qameta.allure.Feature;
import io.qameta.allure.Story;
import java.io.File;
import java.nio.file.Path;
import java.time.LocalDateTime;
Expand All @@ -35,9 +38,14 @@
import javafx.stage.Window;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

@Epic("Ресурсы")
@Feature("№3 Просмотр метаданных ресурса")
@DisplayName("Детали ресурса")
class ResourceDetailsControllerTest {

private static final UUID RESOURCE_ID = UUID.randomUUID();
Expand Down Expand Up @@ -114,6 +122,8 @@ void setUp() {
}

@Test
@Tag("role:user")
@DisplayName("Загрузка показывает метаданные и файлы")
void successfulLoadShowsMetadataAndFiles() {
when(resourceService.getById(RESOURCE_ID)).thenReturn(resourceWithFiles());
controller.setResourceId(RESOURCE_ID);
Expand All @@ -129,6 +139,8 @@ void successfulLoadShowsMetadataAndFiles() {
}

@Test
@Tag("role:user")
@DisplayName("Отсутствующий ресурс: ошибка и пустая таблица")
void resourceNotFoundShowsErrorAndLeavesTableEmpty() {
when(resourceService.getById(RESOURCE_ID)).thenThrow(new ServiceException("Ресурс не найден"));
controller.setResourceId(RESOURCE_ID);
Expand All @@ -140,6 +152,9 @@ void resourceNotFoundShowsErrorAndLeavesTableEmpty() {
}

@Test
@Story("Скачивание")
@Tag("role:user")
@DisplayName("Скачивание сохраняет файл и показывает статус")
void downloadSavesFileAndShowsStatus(@TempDir Path tempDir) {
when(resourceService.getById(RESOURCE_ID)).thenReturn(resourceWithFiles());
controller.setResourceId(RESOURCE_ID);
Expand All @@ -156,6 +171,9 @@ void downloadSavesFileAndShowsStatus(@TempDir Path tempDir) {
}

@Test
@Story("Скачивание")
@Tag("role:user")
@DisplayName("Ошибка скачивания показывается в строке ошибки")
void downloadErrorShowsInErrorLabel(@TempDir Path tempDir) {
when(resourceService.getById(RESOURCE_ID)).thenReturn(resourceWithFiles());
controller.setResourceId(RESOURCE_ID);
Expand All @@ -172,6 +190,9 @@ void downloadErrorShowsInErrorLabel(@TempDir Path tempDir) {
}

@Test
@Story("Скачивание")
@Tag("role:user")
@DisplayName("Отмена выбора каталога не вызывает скачивание")
void cancelledDirectoryChooserDoesNotCallDownload() {
when(resourceService.getById(RESOURCE_ID)).thenReturn(resourceWithFiles());
controller.setResourceId(RESOURCE_ID);
Expand All @@ -185,12 +206,17 @@ void cancelledDirectoryChooserDoesNotCallDownload() {
}

@Test
@Tag("role:user")
@DisplayName("Кнопка «Назад» ведёт в список ресурсов")
void backNavigatesToResourceList() {
controller.onBack(new ActionEvent());
verify(navigator).goTo("/fxml/ResourceList.fxml");
}

@Test
@Story("Удаление с подтверждением")
@Tag("role:moder")
@DisplayName("Подтверждённое удаление вызывает сервис и ведёт в список")
void confirmedDeleteCallsServiceAndNavigatesToList() {
when(resourceService.getById(RESOURCE_ID)).thenReturn(resourceWithFiles());
controller.setResourceId(RESOURCE_ID);
Expand All @@ -204,6 +230,9 @@ void confirmedDeleteCallsServiceAndNavigatesToList() {
}

@Test
@Story("Удаление с подтверждением")
@Tag("role:moder")
@DisplayName("Отменённое удаление не вызывает сервис")
void cancelledDeleteDoesNotCallServiceNorNavigate() {
when(resourceService.getById(RESOURCE_ID)).thenReturn(resourceWithFiles());
controller.setResourceId(RESOURCE_ID);
Expand All @@ -217,6 +246,9 @@ void cancelledDeleteDoesNotCallServiceNorNavigate() {
}

@Test
@Story("Удаление с подтверждением")
@Tag("role:moder")
@DisplayName("Ошибка удаления показывается без перехода")
void deleteErrorShowsInErrorLabelWithoutNavigation() {
when(resourceService.getById(RESOURCE_ID)).thenReturn(resourceWithFiles());
controller.setResourceId(RESOURCE_ID);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import com.DesktopApplicationClientJava.services.ServiceRegistry;
import com.DesktopApplicationClientJava.session.Session;
import com.DesktopApplicationClientJava.utils.ControllerWiring;
import io.qameta.allure.Epic;
import io.qameta.allure.Feature;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
Expand All @@ -27,8 +29,14 @@
import javafx.scene.control.TextField;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

@Epic("Ресурсы")
@Feature("№4 Форма ресурса")
@Tag("role:moder")
@DisplayName("Форма ресурса")
class ResourceFormControllerTest {

private static final UUID RESOURCE_ID = UUID.randomUUID();
Expand Down Expand Up @@ -69,12 +77,14 @@ void setUp() {
}

@Test
@DisplayName("Режим создания показывает заголовок формы создания")
void createModeShowsNewDocumentTitle() {
assertEquals("Новый документ", controller.formTitleLabel.getText());
assertFalse(controller.errorLabel.isVisible());
}

@Test
@DisplayName("Пустое название: ошибка без сохранения")
void blankTitleShowsErrorAndDoesNotSave() {
controller.onSave(new ActionEvent());

Expand All @@ -85,6 +95,7 @@ void blankTitleShowsErrorAndDoesNotSave() {
}

@Test
@DisplayName("Короткое название: ошибка без сохранения")
void shortTitleShowsErrorAndDoesNotSave() {
controller.titleField.setText("ab");
controller.onSave(new ActionEvent());
Expand All @@ -95,6 +106,7 @@ void shortTitleShowsErrorAndDoesNotSave() {
}

@Test
@DisplayName("Длинное название: ошибка без сохранения")
void longTitleShowsErrorAndDoesNotSave() {
controller.titleField.setText("a".repeat(256));
controller.onSave(new ActionEvent());
Expand All @@ -106,6 +118,7 @@ void longTitleShowsErrorAndDoesNotSave() {
}

@Test
@DisplayName("Корректный ввод создаёт ресурс и ведёт в список")
void validInputCreatesAndNavigatesToList() {
controller.titleField.setText(TITLE);
controller.descriptionArea.setText(DESCRIPTION);
Expand All @@ -117,6 +130,7 @@ void validInputCreatesAndNavigatesToList() {
}

@Test
@DisplayName("Пустое описание сохраняется как null")
void blankDescriptionIsSavedAsNull() {
controller.titleField.setText(TITLE);
controller.onSave(new ActionEvent());
Expand All @@ -126,6 +140,7 @@ void blankDescriptionIsSavedAsNull() {
}

@Test
@DisplayName("Ошибка сервиса показывается без перехода")
void serviceErrorShowsInErrorLabelAndDoesNotNavigate() {
when(resourceService.create(anyString(), any()))
.thenThrow(new ServiceException("Не удалось сохранить"));
Expand All @@ -139,6 +154,7 @@ void serviceErrorShowsInErrorLabelAndDoesNotNavigate() {
}

@Test
@DisplayName("Отмена ведёт в список без сохранения")
void cancelNavigatesToListWithoutSaving() {
controller.titleField.setText(TITLE);
controller.onCancel(new ActionEvent());
Expand All @@ -149,6 +165,7 @@ void cancelNavigatesToListWithoutSaving() {
}

@Test
@DisplayName("Режим редактирования подставляет сохранённые значения")
void editModePrefillsExistingValues() {
when(resourceService.getById(RESOURCE_ID)).thenReturn(existingResource());
controller.setResourceId(RESOURCE_ID);
Expand All @@ -159,6 +176,7 @@ void editModePrefillsExistingValues() {
}

@Test
@DisplayName("Сохранение обновляет ресурс и ведёт в список")
void editModeSaveUpdatesAndNavigatesToList() {
when(resourceService.getById(RESOURCE_ID)).thenReturn(existingResource());
controller.setResourceId(RESOURCE_ID);
Expand All @@ -172,6 +190,7 @@ void editModeSaveUpdatesAndNavigatesToList() {
}

@Test
@DisplayName("Ошибка загрузки показывает ошибку")
void editModeLoadErrorShowsInErrorLabel() {
when(resourceService.getById(RESOURCE_ID)).thenThrow(new ServiceException("Ресурс не найден"));
controller.setResourceId(RESOURCE_ID);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
* Mock-backed UI flow: real pages wired to real in-memory mock services (no Mockito on services, no
* backend). Proves that MOCK_DATA mode renders actual data.
*/
@Epic("Ресурс")
@Feature("Просмотр метаданных ресурса")
@Epic("Ресурсы")
@Feature("№3 Просмотр метаданных ресурса")
@Tag("role:user")
@DisplayName("Просмотр ресурса на моках")
class MockFlowTest extends FxTestBase {
Expand Down Expand Up @@ -72,6 +72,7 @@ void start(Stage stage) throws Exception {
}

@Test
@DisplayName("Мок-вход кладёт пользователя в сессию")
void mockLoginPutsUserIntoSession() {
Session session = new Session();
ServiceRegistry registry = ServiceRegistry.mock(session);
Expand Down Expand Up @@ -99,6 +100,7 @@ void detailsPageRendersSeededMockResource() {

@Test
@SuppressWarnings("unchecked")
@DisplayName("Страница без id показывает первый мок-ресурс")
void detailsPageAutoSelectsFirstSeedWithoutId() {
robot.interact(() -> controller.load());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
import com.DesktopApplicationClientJava.services.ServiceRegistry;
import com.DesktopApplicationClientJava.session.Session;
import com.DesktopApplicationClientJava.utils.ControllerWiring;
import io.qameta.allure.Epic;
import io.qameta.allure.Feature;
import io.qameta.allure.Story;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
Expand All @@ -35,6 +38,8 @@
import javafx.scene.control.Label;
import javafx.stage.Stage;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.testfx.api.FxRobot;
import org.testfx.api.FxToolkit;
Expand All @@ -44,6 +49,9 @@
* Компонентные тесты страницы деталей ресурса: удаление через настоящую модалку подтверждения (роль
* МОДЕР).
*/
@Epic("Ресурсы")
@Feature("№3 Просмотр метаданных ресурса")
@DisplayName("Детали ресурса: удаление через модалку")
class ResourceDetailsControllerUiTest extends FxTestBase {

private static final UUID RESOURCE_ID = UUID.randomUUID();
Expand Down Expand Up @@ -115,12 +123,16 @@ private void loadPage() {
}

@Test
@Tag("role:moder")
@DisplayName("Модер видит кнопки редактирования и удаления")
void moderatorSeesEditAndDeleteButtons() {
assertTrue(robot.lookup("#editButton").queryAs(Button.class).isVisible());
assertTrue(robot.lookup("#deleteButton").queryAs(Button.class).isVisible());
}

@Test
@Tag("role:user")
@DisplayName("Пользователь не видит кнопок редактирования и удаления")
void plainUserSeesNeitherEditNorDeleteButtons() {
robot.interact(
() -> {
Expand All @@ -138,6 +150,9 @@ void plainUserSeesNeitherEditNorDeleteButtons() {
}

@Test
@Story("Удаление с подтверждением")
@Tag("role:moder")
@DisplayName("Клик модера открывает модалку подтверждения")
void moderatorDeleteClickOpensConfirmationModal() {
robot.interact(
() -> {
Expand All @@ -162,6 +177,9 @@ void moderatorDeleteClickOpensConfirmationModal() {
}

@Test
@Story("Удаление с подтверждением")
@Tag("role:moder")
@DisplayName("Подтверждение удаляет ресурс и ведёт в список")
void confirmingModalClosesItDeletesAndNavigatesToList() {
robot.interact(
() -> {
Expand All @@ -180,6 +198,9 @@ void confirmingModalClosesItDeletesAndNavigatesToList() {
}

@Test
@Story("Удаление с подтверждением")
@Tag("role:moder")
@DisplayName("Удаление отсутствующего ресурса показывает ошибку без перехода")
void confirmingDeleteOfGoneResourceShowsErrorWithoutNavigation() {
robot.interact(
() -> {
Expand Down
Loading
Loading