diff --git a/src/modules/clipboard/application/usecases/tests/clipboardUseCases.test.ts b/src/modules/clipboard/application/usecases/tests/clipboardUseCases.test.ts new file mode 100644 index 000000000..051ceb618 --- /dev/null +++ b/src/modules/clipboard/application/usecases/tests/clipboardUseCases.test.ts @@ -0,0 +1,138 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest' + +vi.mock('~/modules/clipboard/ui/PasteConfirmModal', () => ({ + openPasteConfirmModal: vi.fn(), +})) + +import { createClipboardStore } from '~/modules/clipboard/application/store/clipboardStore' +import { createClipboardUseCases } from '~/modules/clipboard/application/usecases/clipboardUseCases' +import { openPasteConfirmModal } from '~/modules/clipboard/ui/PasteConfirmModal' +import { createItem, itemSchema } from '~/modules/diet/item/schema/itemSchema' +import { createMacroNutrients } from '~/modules/diet/macro-nutrients/domain/macroNutrients' +import { createNewMeal, promoteMeal } from '~/modules/diet/meal/domain/meal' +import { parseWithStack } from '~/shared/utils/parseWithStack' + +describe('clipboardUseCases.confirmPaste', () => { + const showError = vi.fn() + + beforeEach(() => { + vi.clearAllMocks() + }) + + function createValidItemPayload() { + return createItem({ + id: 1, + name: 'Banana', + quantity: 100, + reference: { + type: 'food', + id: 1, + macros: createMacroNutrients({ + proteinInGrams: 1.2, + carbsInGrams: 22.8, + fatInGrams: 0.3, + }), + }, + }) + } + + it('opens the paste confirmation modal with the parsed payload', () => { + const clipboardStore = createClipboardStore() + const payload = createValidItemPayload() + const parsedPayload = parseWithStack(itemSchema, payload) + const onPasteConfirmed = vi.fn() + const useCases = createClipboardUseCases({ + clipboardStore, + showError, + }) + + clipboardStore.copy(payload) + + useCases.confirmPaste(itemSchema, onPasteConfirmed) + + expect(openPasteConfirmModal).toHaveBeenCalledTimes(1) + expect(openPasteConfirmModal).toHaveBeenCalledWith( + parsedPayload, + onPasteConfirmed, + ) + expect(showError).not.toHaveBeenCalled() + }) + + it('passes the confirmed payload to the paste handler on valid clipboard data', () => { + const clipboardStore = createClipboardStore() + const payload = createValidItemPayload() + const onPasteConfirmed = vi.fn() + const useCases = createClipboardUseCases({ + clipboardStore, + showError, + }) + + clipboardStore.copy(payload) + + useCases.confirmPaste(itemSchema, onPasteConfirmed) + + const modalCall = vi.mocked(openPasteConfirmModal).mock.calls[0] + + expect(modalCall).toBeDefined() + if (!modalCall) { + throw new Error('Expected openPasteConfirmModal to be called') + } + + const [modalPayload, modalHandler] = modalCall + + modalHandler(modalPayload) + + expect(onPasteConfirmed).toHaveBeenCalledTimes(1) + expect(onPasteConfirmed).toHaveBeenCalledWith(modalPayload) + }) + + it('shows an error and does not open the modal when the clipboard is empty', () => { + const clipboardStore = createClipboardStore() + const onPasteConfirmed = vi.fn() + const useCases = createClipboardUseCases({ + clipboardStore, + showError, + }) + + useCases.confirmPaste(itemSchema, onPasteConfirmed) + + expect(openPasteConfirmModal).not.toHaveBeenCalled() + expect(onPasteConfirmed).not.toHaveBeenCalled() + expect(showError).toHaveBeenCalledTimes(1) + expect(showError).toHaveBeenCalledWith( + 'A área de transferência está vazia ou o conteúdo é inválido.', + ) + }) + + it('shows validation errors and does not open the modal when clipboard data is incompatible', () => { + const clipboardStore = createClipboardStore() + const onPasteConfirmed = vi.fn() + const useCases = createClipboardUseCases({ + clipboardStore, + showError, + }) + + clipboardStore.copy( + promoteMeal( + createNewMeal({ name: 'Meal clipboard payload', items: [] }), + { + id: 999, + }, + ), + ) + + useCases.confirmPaste(itemSchema, onPasteConfirmed) + + expect(openPasteConfirmModal).not.toHaveBeenCalled() + expect(onPasteConfirmed).not.toHaveBeenCalled() + expect(showError).toHaveBeenCalledTimes(2) + expect(showError).toHaveBeenNthCalledWith( + 1, + 'O conteúdo da área de transferência não é compatível.', + ) + expect(showError).toHaveBeenNthCalledWith( + 2, + 'A área de transferência está vazia ou o conteúdo é inválido.', + ) + }) +})