import { searchExerciseTranslations } from "@/components/Exercises/api/exerciseTranslation"; import { useDeleteExerciseQuery, useDeleteExerciseTranslationQuery, useFetchExerciseQuery, useLanguageQuery, useSearchExerciseTranslationsQuery, } from "@/components/Exercises/queries"; import { ExerciseDeleteDialog } from "@/components/Exercises/screens/Detail/Head/ExerciseDeleteDialog"; import { searchResponse } from "@/tests/exercises/searchResponse"; import { testExerciseBenchPress, testExerciseSquats, testLanguageGerman, testLanguages } from "@/tests/exerciseTestdata"; import { render, screen, waitFor, within } from '@testing-library/react'; import userEvent from "@testing-library/user-event"; import React from 'react'; import { MemoryRouter, Route, Routes } from "react-router-dom"; import type { Mock } from 'vitest'; vi.mock("@/components/Exercises/api/exerciseTranslation"); vi.mock("@/components/Exercises/queries"); describe("Test the ExerciseDeleteDialog component", () => { const onCloseMock = vi.fn(); const onChangeLanguageMock = vi.fn(); let deleteExerciseMock: Mock; let deleteTranslationMock: Mock; let fetchExerciseMock: Mock; // Arrange beforeEach(() => { vi.resetAllMocks(); (searchExerciseTranslations as Mock).mockImplementation(() => Promise.resolve(searchResponse)); deleteExerciseMock = vi.fn().mockResolvedValue(204); deleteTranslationMock = vi.fn().mockResolvedValue(204); fetchExerciseMock = vi.fn().mockResolvedValue(testExerciseBenchPress); (useDeleteExerciseQuery as Mock).mockImplementation(() => ({ mutateAsync: deleteExerciseMock })); (useDeleteExerciseTranslationQuery as Mock).mockImplementation(() => ({ mutateAsync: deleteTranslationMock })); (useFetchExerciseQuery as Mock).mockImplementation(() => fetchExerciseMock); (useSearchExerciseTranslationsQuery as Mock).mockImplementation(() => searchExerciseTranslations); (useLanguageQuery as Mock).mockImplementation(() => ({ isSuccess: true, data: testLanguages })); }); function renderWidget() { render( } /> ); } test('correctly deletes the current translation', async () => { // Arrange const user = userEvent.setup(); // Act renderWidget(); // Assert await user.click(screen.getByTestId('button-delete-translation')); expect(deleteTranslationMock).toHaveBeenCalledWith(9); expect(deleteExerciseMock).not.toHaveBeenCalled(); }); test('correctly deletes the whole exercise', async () => { // Arrange const user = userEvent.setup(); // Act renderWidget(); // Assert await user.click(screen.getByTestId('button-delete-all')); // No replacement options — mutateAsync() called with no arg. expect(deleteExerciseMock).toHaveBeenCalledWith(); expect(deleteTranslationMock).not.toHaveBeenCalled(); }); test('correctly sets a replacement with the autocompleter', async () => { // Arrange const user = userEvent.setup(); // Act renderWidget(); const autocomplete = screen.getByTestId('autocomplete'); const input = within(autocomplete).getByRole('combobox'); // Assert expect(searchExerciseTranslations).not.toHaveBeenCalled(); await user.type(input, 'Cru'); expect(screen.getByText("exercises.noReplacementSelected")).toBeInTheDocument(); await waitFor(() => expect(searchExerciseTranslations).toHaveBeenCalled()); await user.click(screen.getByTestId('autocompleter-result-998')); expect(fetchExerciseMock).toHaveBeenCalledWith(998); expect(screen.queryByText("exercises.noReplacementSelected")).not.toBeInTheDocument(); expect(screen.getByText("Benchpress")).toBeInTheDocument(); expect(screen.getByText("2 (abcdef-150a-4ac7-97ef-84643c6419bf)")).toBeInTheDocument(); await user.click(screen.getByTestId('button-delete-and-replace')); expect(deleteExerciseMock).toHaveBeenCalledWith({ replacementUUID: "abcdef-150a-4ac7-97ef-84643c6419bf", transferMedia: true, transferTranslations: true, }); expect(deleteTranslationMock).not.toHaveBeenCalled(); }); test('passes both transfer flags as false when both checkboxes are unchecked', async () => { const user = userEvent.setup(); renderWidget(); await user.type(screen.getByRole('textbox'), '111'); await user.click(screen.getByText("exercises.noReplacementSelected")); await user.click(screen.getByLabelText("exercises.transferMediaLabel")); await user.click(screen.getByLabelText("exercises.transferTranslationsLabel")); await user.click(screen.getByTestId('button-delete-and-replace')); expect(deleteExerciseMock).toHaveBeenCalledWith({ replacementUUID: "abcdef-150a-4ac7-97ef-84643c6419bf", transferMedia: false, transferTranslations: false, }); }); test('correctly sets a replacement manually setting the ID', async () => { // Arrange const user = userEvent.setup(); // Act renderWidget(); // Assert await user.type(screen.getByRole('textbox'), '111'); expect(screen.getByText("exercises.noReplacementSelected")).toBeInTheDocument(); await user.click(screen.getByText("exercises.noReplacementSelected")); expect(fetchExerciseMock).toHaveBeenCalledWith(111); expect(screen.queryByText("exercises.noReplacementSelected")).not.toBeInTheDocument(); expect(screen.getByText("Benchpress")).toBeInTheDocument(); expect(screen.getByText("2 (abcdef-150a-4ac7-97ef-84643c6419bf)")).toBeInTheDocument(); await user.click(screen.getByTestId('button-delete-and-replace')); expect(deleteExerciseMock).toHaveBeenCalledWith({ replacementUUID: "abcdef-150a-4ac7-97ef-84643c6419bf", transferMedia: true, transferTranslations: true, }); expect(deleteTranslationMock).not.toHaveBeenCalled(); }); test('rejects the exercise being deleted as its own replacement', async () => { // Arrange const user = userEvent.setup(); // Act renderWidget(); // testExerciseSquats (the current exercise) has id 345 await user.type(screen.getByRole('textbox'), '345'); await user.click(screen.getByText("exercises.noReplacementSelected")); // Assert expect(screen.getByText("exercises.replacementCannotBeSame")).toBeInTheDocument(); expect(fetchExerciseMock).not.toHaveBeenCalled(); expect(screen.getByTestId('button-delete-and-replace')).toBeDisabled(); }); });