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 @@ -94,7 +94,10 @@ export const AssetManagementApplication: FunctionComponent<
// reject transfer owner holder
rejectTransferOwnerHolder,
rejectTransferOwnerHolderState,
// reset providers
resetProviders,
//errorMessage
errorMessage,
} = useTokenInformationContext()
const [assetManagementAction, setAssetManagementAction] =
useState<AssetManagementActions>(AssetManagementActions.None)
Expand Down Expand Up @@ -193,6 +196,7 @@ export const AssetManagementApplication: FunctionComponent<
onRestoreToken={onRestoreToken}
restoreTokenState={restoreTokenState}
isExpired={isExpired}
errorMessage={errorMessage}
/>
) : (
isExpired && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,29 @@ describe('AssetManagementForm', () => {
)
})

it('enables reject holdership only for token registry v5 after holder transfer context', () => {
it('disables reject holdership when holder and beneficiary are the same account (isHolderAndBeneficiary)', () => {
mockUseTokenRegistryVersion.mockReturnValue(TokenRegistryVersions.V5)
// baseProps has beneficiary === holder === account, so isHolderAndBeneficiary=true
render(<AssetManagementForm {...baseProps} prevBeneficiary={undefined} />)

expect(mockActionSelectionForm).toHaveBeenCalledWith(
expect.objectContaining({
canRejectHolderTransfer: false,
})
)
})

it('enables reject holdership for token registry v5 when holder differs from beneficiary', () => {
mockUseTokenRegistryVersion.mockReturnValue(TokenRegistryVersions.V5)
// Different beneficiary means isHolderAndBeneficiary=false, so canRejectHolderTransfer can be true
render(
<AssetManagementForm
{...baseProps}
beneficiary="0xDEADBEEFdeadbeefdeadbeefdeadbeefdeadbeef"
prevBeneficiary={undefined}
/>
)

expect(mockActionSelectionForm).toHaveBeenCalledWith(
expect.objectContaining({
canRejectHolderTransfer: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ interface AssetManagementFormProps
onSetFormAction: (nextFormAction: AssetManagementActions) => void
setShowEndorsementChain: (payload: boolean) => void
refreshEndorsementChain?: () => void
errorMessage?: string
}

export const AssetManagementForm: FunctionComponent<
Expand Down Expand Up @@ -133,6 +134,7 @@ export const AssetManagementForm: FunctionComponent<
destroyTokenState,
onRestoreToken,
restoreTokenState,
errorMessage,
}) => {
const tokenRegistryVersion = useTokenRegistryVersion()
const isTokenRegistryV5 = tokenRegistryVersion === TokenRegistryVersions.V5
Expand Down Expand Up @@ -170,15 +172,16 @@ export const AssetManagementForm: FunctionComponent<
hasPreviousHolder &&
hasPreviousBeneficiary &&
canRejectAfterTransferOwners
const canRejectHolderTransfer = // Allow reject after holder is transferred back to original owner
(isHolderAndBeneficiary ? !hasPreviousBeneficiary : true) &&
const canRejectHolderTransfer =
!isHolderAndBeneficiary &&
isTokenRegistryV5 &&
isActiveTitleEscrow &&
isHolder &&
hasPreviousHolder &&
!(isBeneficiary && hasPreviousBeneficiary)
const canRejectOwnerTransfer =
!isHolderAndBeneficiary &&
isTokenRegistryV5 &&
isActiveTitleEscrow &&
isBeneficiary &&
hasPreviousBeneficiary &&
Expand Down Expand Up @@ -296,6 +299,8 @@ export const AssetManagementForm: FunctionComponent<
// reject return to issuer
handleRestoreToken={onRestoreToken}
restoreTokenState={restoreTokenState}
//error message
errorMessage={errorMessage}
/>
)}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1854,3 +1854,167 @@ describe('ActionForm - EndorseBeneficiary', () => {
})
})
})

describe('ActionForm - errorMessage prop passthrough', () => {
beforeEach(() => {
vi.clearAllMocks()
})

it('passes errorMessage to overlay when TransferHolder fails', async () => {
const mockHandleTransfer = vi.fn()

renderWithOverlay(
<ActionForm
{...defaultProps}
type={AssetManagementActions.TransferHolder}
handleTransfer={mockHandleTransfer}
holderTransferringState={FormState.ERROR}
errorMessage="User Rejected Transaction"
/>
)

await waitFor(() => {
expect(mockShowOverlay).toHaveBeenCalled()
})

const overlayNode = mockShowOverlay.mock.calls[0][0] as any
expect(overlayNode.props.title).toBe('Transfer Holder Failed')
expect(overlayNode.props.isSuccess).toBe(false)
expect(overlayNode.props.errorMessage).toBe('User Rejected Transaction')
})

it('passes errorMessage to overlay when TransferOwnerHolder fails', async () => {
const mockHandleTransferOwnerHolder = vi.fn()

renderWithOverlay(
<ActionForm
{...defaultProps}
type={AssetManagementActions.TransferOwnerHolder}
handleTransferOwnerHolder={mockHandleTransferOwnerHolder}
transferOwnerHoldersState={FormState.ERROR}
errorMessage="Insufficient Funds"
/>
)

await waitFor(() => {
expect(mockShowOverlay).toHaveBeenCalled()
})

const overlayNode = mockShowOverlay.mock.calls[0][0] as any
expect(overlayNode.props.title).toBe('Transfer Ownership/Holdership Failed')
expect(overlayNode.props.errorMessage).toBe('Insufficient Funds')
})

it('passes errorMessage to overlay when NominateBeneficiary fails', async () => {
const mockHandleNomination = vi.fn()

renderWithOverlay(
<ActionForm
{...defaultProps}
type={AssetManagementActions.NominateBeneficiary}
handleNomination={mockHandleNomination}
nominationState={FormState.ERROR}
errorMessage="Network Error"
/>
)

await waitFor(() => {
expect(mockShowOverlay).toHaveBeenCalled()
})

const overlayNode = mockShowOverlay.mock.calls[0][0] as any
expect(overlayNode.props.title).toBe('Nomination Failed')
expect(overlayNode.props.errorMessage).toBe('Network Error')
})

it('passes errorMessage to overlay when RejectTransferOwnerHolder fails', async () => {
const mockHandleRejectTransferOwnerHolder = vi.fn()

renderWithOverlay(
<ActionForm
{...defaultProps}
prevBeneficiary="0xabcdefabcdefabcdefabcdefabcdefabcdefabcd"
prevHolder="0x1111111111111111111111111111111111111111"
type={AssetManagementActions.RejectTransferOwnerHolder}
handleRejectTransferOwnerHolder={mockHandleRejectTransferOwnerHolder}
rejectTransferOwnerHolderState={FormState.ERROR}
errorMessage="Transaction Rejected"
/>
)

await waitFor(() => {
expect(mockShowOverlay).toHaveBeenCalled()
})

const overlayNode = mockShowOverlay.mock.calls[0][0] as any
expect(overlayNode.props.title).toBe(
'Holdership/Ownership Rejection Failed'
)
expect(overlayNode.props.errorMessage).toBe('Transaction Rejected')
})

it('passes errorMessage to overlay when ReturnToIssuer fails', async () => {
const mockHandleReturnToIssuer = vi.fn()

renderWithOverlay(
<ActionForm
{...defaultProps}
type={AssetManagementActions.ReturnToIssuer}
handleReturnToIssuer={mockHandleReturnToIssuer}
returnToIssuerState={FormState.ERROR}
errorMessage="Contract Call Failed"
/>
)

await waitFor(() => {
expect(mockShowOverlay).toHaveBeenCalled()
})

const overlayNode = mockShowOverlay.mock.calls[0][0] as any
expect(overlayNode.props.title).toBe('Return of ETR Failed')
expect(overlayNode.props.errorMessage).toBe('Contract Call Failed')
})

it('passes errorMessage to overlay on successful TransferOwner', async () => {
const mockHandleBeneficiaryTransfer = vi.fn()

renderWithOverlay(
<ActionForm
{...defaultProps}
type={AssetManagementActions.TransferOwner}
handleBeneficiaryTransfer={mockHandleBeneficiaryTransfer}
transferOwnersState={FormState.CONFIRMED}
errorMessage="Some Error"
/>
)

await waitFor(() => {
expect(mockShowOverlay).toHaveBeenCalled()
})

const overlayNode = mockShowOverlay.mock.calls[0][0] as any
expect(overlayNode.props.title).toBe('Transfer Owner Success')
expect(overlayNode.props.isSuccess).toBe(true)
expect(overlayNode.props.errorMessage).toBe('Some Error')
})

it('passes undefined errorMessage when prop is not provided', async () => {
const mockHandleTransfer = vi.fn()

renderWithOverlay(
<ActionForm
{...defaultProps}
type={AssetManagementActions.TransferHolder}
handleTransfer={mockHandleTransfer}
holderTransferringState={FormState.ERROR}
/>
)

await waitFor(() => {
expect(mockShowOverlay).toHaveBeenCalled()
})

const overlayNode = mockShowOverlay.mock.calls[0][0] as any
expect(overlayNode.props.errorMessage).toBeUndefined()
})
})
Loading
Loading