diff --git a/resources/js/components/accounts/edit-account-dialog.test.tsx b/resources/js/components/accounts/edit-account-dialog.test.tsx new file mode 100644 index 00000000..bc6d20aa --- /dev/null +++ b/resources/js/components/accounts/edit-account-dialog.test.tsx @@ -0,0 +1,103 @@ +import type { Account } from '@/types/account'; +import { fireEvent, render, screen } from '@testing-library/react'; +import { describe, expect, it, vi } from 'vitest'; +import { EditAccountDialog } from './edit-account-dialog'; + +vi.mock('@inertiajs/react', () => ({ + router: { + patch: vi.fn(), + visit: vi.fn(), + }, +})); + +vi.mock('@/actions/App/Http/Controllers/Settings/AccountController', () => ({ + update: { + url: (id: string) => `/settings/accounts/${id}`, + }, +})); + +vi.mock('@/actions/App/Http/Controllers/Settings/BankController', () => ({ + store: { + url: () => '/settings/banks', + }, +})); + +vi.mock('./account-form', () => ({ + AccountForm: () =>
, +})); + +vi.mock('./delete-account-dialog', () => ({ + DeleteAccountDialog: ({ + open, + redirectTo, + }: { + open: boolean; + redirectTo?: string; + }) => + open ? ( +
+ Delete Account confirmation +
+ ) : null, +})); + +function makeAccount(): Account { + return { + id: 'account-1', + name: 'Checking', + name_iv: null, + encrypted: false, + bank: { + id: 'bank-1', + user_id: null, + name: 'Test Bank', + logo: null, + }, + type: 'checking', + currency_code: 'USD', + banking_connection_id: null, + external_account_id: null, + linked_at: null, + }; +} + +describe('EditAccountDialog', () => { + it('shows account deletion inside edit modal with confirmation dialog', () => { + render( + , + ); + + fireEvent.click(screen.getByRole('button', { name: 'Delete account' })); + + expect( + screen.getByTestId('delete-account-dialog').textContent, + ).toContain('Delete Account confirmation'); + expect( + screen + .getByTestId('delete-account-dialog') + .getAttribute('data-redirect-to'), + ).toBe('/accounts'); + }); + + it('hides account deletion when no delete redirect is provided', () => { + render( + , + ); + + expect( + screen.queryByRole('button', { name: 'Delete account' }), + ).toBeNull(); + }); +}); diff --git a/resources/js/components/accounts/edit-account-dialog.tsx b/resources/js/components/accounts/edit-account-dialog.tsx index 0bc1ce5d..7cfede50 100644 --- a/resources/js/components/accounts/edit-account-dialog.tsx +++ b/resources/js/components/accounts/edit-account-dialog.tsx @@ -20,6 +20,7 @@ import { LoanFormData, RealEstateFormData, } from './account-form'; +import { DeleteAccountDialog } from './delete-account-dialog'; interface AccountWithDetails extends Account { loan_detail?: LoanDetail | null; @@ -32,6 +33,7 @@ interface EditAccountDialogProps { onOpenChange: (open: boolean) => void; onSuccess?: () => void; redirectTo?: string; + deleteRedirectTo?: string; } export function EditAccountDialog({ @@ -40,8 +42,10 @@ export function EditAccountDialog({ onOpenChange, onSuccess, redirectTo, + deleteRedirectTo, }: EditAccountDialogProps) { const [decryptedName, setDecryptedName] = useState(''); + const [deleteOpen, setDeleteOpen] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false); const [errors, setErrors] = useState>({}); const formDataRef = useRef({ @@ -91,6 +95,7 @@ export function EditAccountDialog({ loanTermMonths: detail.loan_term_months?.toString() ?? '', startDate: detail.start_date?.slice(0, 10) ?? '', originalAmount: detail.original_amount ?? 0, + linkedRealEstateAccountId: null, }; }, [account.loan_detail]); @@ -328,23 +333,48 @@ export function EditAccountDialog({
)} -
- - +
+ {deleteRedirectTo ? ( + + ) : ( + + )} + +
+ + +
+ + {deleteRedirectTo && ( + + )} ); diff --git a/resources/js/pages/Accounts/Show.tsx b/resources/js/pages/Accounts/Show.tsx index 475f7ec6..e68e3f15 100644 --- a/resources/js/pages/Accounts/Show.tsx +++ b/resources/js/pages/Accounts/Show.tsx @@ -7,7 +7,6 @@ import { type ChartComputedData, } from '@/components/accounts/account-balance-chart'; import { BalancesModal } from '@/components/accounts/balances-modal'; -import { DeleteAccountDialog } from '@/components/accounts/delete-account-dialog'; import { EditAccountDialog } from '@/components/accounts/edit-account-dialog'; import { EditLoanDetailDialog } from '@/components/accounts/edit-loan-detail-dialog'; import { ImportBalancesDrawer } from '@/components/accounts/import-balances-drawer'; @@ -92,7 +91,6 @@ export default function AccountShow({ automationRules = [], }: Props) { const [editOpen, setEditOpen] = useState(false); - const [deleteOpen, setDeleteOpen] = useState(false); const [updateBalanceOpen, setUpdateBalanceOpen] = useState(false); const [updateLoanBalanceOpen, setUpdateLoanBalanceOpen] = useState(false); const [importBalancesOpen, setImportBalancesOpen] = useState(false); @@ -253,13 +251,6 @@ export default function AccountShow({ > {__('Edit loan details')} - - setDeleteOpen(true)} - variant="destructive" - > - {__('Delete')} - @@ -304,13 +295,6 @@ export default function AccountShow({ > {__('Edit account')} - - setDeleteOpen(true)} - variant="destructive" - > - {__('Delete')} - @@ -396,13 +380,7 @@ export default function AccountShow({ open={editOpen} onOpenChange={setEditOpen} redirectTo={show.url(account.id)} - /> - -