-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add description field to wallet (#151)
Enable users to add an optional summary to transfer requests. Summary data is stored in Proposal::summary. Updated create transfer form, it is also prepared to load and show an existing transfer along with the summary from its proposal. To support this I added the proposal_id to the Transfer DTO. ![image](https://github.com/dfinity/orbit-wallet/assets/9403182/fafa7ec4-6ff5-432e-88d0-dba340a9d939) Display the summary on the Proposal details dialog: ![image](https://github.com/dfinity/orbit-wallet/assets/9403182/f0094810-1599-4613-9f30-8ddf295dd77d)
- Loading branch information
Showing
12 changed files
with
282 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
167 changes: 167 additions & 0 deletions
167
canisters/ui/src/components/accounts/TransferDialog.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
import { describe, expect, it, vi } from 'vitest'; | ||
import { mount } from '~/test.utils'; | ||
import TransferDialog from './TransferDialog.vue'; | ||
import { Account, GetProposalResult, Proposal, Transfer } from '~/generated/wallet/wallet.did'; | ||
import DataLoaderVue from '../DataLoader.vue'; | ||
import { flushPromises } from '@vue/test-utils'; | ||
import { services } from '~/plugins/services.plugin'; | ||
import { ExtractOk } from '~/types/helper.types'; | ||
|
||
vi.mock('~/services/wallet.service', () => ({ | ||
WalletService: vi.fn().mockImplementation(() => { | ||
return { | ||
transfer: vi.fn(() => { | ||
return Promise.resolve({} as Proposal); | ||
}), | ||
}; | ||
}), | ||
})); | ||
|
||
describe('TransferDialog', () => { | ||
it('renders correctly', () => { | ||
const wrapper = mount(TransferDialog, { | ||
props: { | ||
account: { | ||
id: '1', | ||
decimals: 1, | ||
} as Account, | ||
open: true, | ||
}, | ||
}); | ||
expect(wrapper.exists()).toBe(true); | ||
}); | ||
|
||
it('shows empty form when transferId not specified', async () => { | ||
const wrapper = mount(TransferDialog, { | ||
props: { | ||
account: { | ||
id: '1', | ||
decimals: 1, | ||
} as Account, | ||
open: true, | ||
}, | ||
}); | ||
await wrapper.vm.$nextTick(); | ||
await flushPromises(); | ||
await wrapper.vm.$nextTick(); | ||
|
||
const dataLoader = wrapper.findComponent(DataLoaderVue); | ||
const form = dataLoader.find(`[data-test-id="transfer-dialog-form"]`); | ||
|
||
const transferId = form.find(`[data-test-id="transfer-form-transfer-id"]`); | ||
const amount = form.find(`[data-test-id="transfer-form-amount"]`); | ||
const destination = form.find(`[data-test-id="transfer-form-destination-address"]`); | ||
const summary = form.find(`[data-test-id="transfer-dialog-proposal-summary"]`); | ||
|
||
// transferId should not be visible when not specified as a prop | ||
expect(transferId.exists()).toBe(false); | ||
|
||
expect(amount.exists()).toBe(true); | ||
expect(destination.exists()).toBe(true); | ||
expect(summary.exists()).toBe(true); | ||
|
||
// amount field should be empty | ||
expect(amount.find('input').element.value).toBe(''); | ||
|
||
// destination field should be empty | ||
expect(destination.find('input').element.value).toBe(''); | ||
|
||
// summary should be empty | ||
expect(summary.find('input').element.value).toBe(''); | ||
}); | ||
|
||
it('creates transfer proposal with summary', async () => { | ||
const wrapper = mount(TransferDialog, { | ||
props: { | ||
account: { | ||
id: '1', | ||
decimals: 1, | ||
} as Account, | ||
open: true, | ||
}, | ||
}); | ||
await wrapper.vm.$nextTick(); | ||
await flushPromises(); | ||
await wrapper.vm.$nextTick(); | ||
|
||
const dataLoader = wrapper.findComponent(DataLoaderVue); | ||
const form = dataLoader.find(`[data-test-id="transfer-dialog-form"]`); | ||
|
||
const amount = form.find(`[data-test-id="transfer-form-amount"]`); | ||
const destination = form.find(`[data-test-id="transfer-form-destination-address"]`); | ||
const summary = form.find(`[data-test-id="transfer-dialog-proposal-summary"]`); | ||
|
||
const submitButton = form.find(`[data-test-id="transfer-dialog-save-button"]`); | ||
|
||
amount.find('input').setValue('1'); | ||
destination.find('input').setValue('destination address'); | ||
summary.find('input').setValue('test summary'); | ||
|
||
await flushPromises(); | ||
|
||
await submitButton.trigger('click'); | ||
|
||
await wrapper.vm.$nextTick(); | ||
await flushPromises(); | ||
|
||
expect(services().wallet.transfer).toHaveBeenCalledWith( | ||
expect.objectContaining({ | ||
amount: 10n, | ||
to: 'destination address', | ||
}), | ||
'test summary', | ||
); | ||
}); | ||
|
||
it('loads the corresponding objects to display the transfer and summary if transferId is specified', async () => { | ||
services().wallet.getProposal = vi.fn(() => | ||
Promise.resolve({ | ||
proposal: { | ||
summary: ['test summary'], // it's an opt | ||
} as unknown as Proposal, | ||
} as ExtractOk<GetProposalResult>), | ||
); | ||
services().wallet.getTransfer = vi.fn(() => | ||
Promise.resolve({ | ||
id: 'transfer-id', | ||
to: 'destination address', | ||
amount: 123n, | ||
proposal_id: 'proposal-id', | ||
} as Transfer), | ||
); | ||
|
||
const wrapper = mount(TransferDialog, { | ||
props: { | ||
account: { | ||
id: '1', | ||
decimals: 2, | ||
} as Account, | ||
open: true, | ||
transferId: 'transfer-id', | ||
}, | ||
}); | ||
await wrapper.vm.$nextTick(); | ||
await flushPromises(); | ||
await wrapper.vm.$nextTick(); | ||
|
||
expect(services().wallet.getTransfer).toHaveBeenCalledWith('transfer-id'); | ||
expect(services().wallet.getProposal).toHaveBeenCalledWith({ | ||
proposal_id: 'proposal-id', | ||
}); | ||
|
||
const dataLoader = wrapper.findComponent(DataLoaderVue); | ||
const form = dataLoader.find(`[data-test-id="transfer-dialog-form"]`); | ||
|
||
const transferId = form.find(`[data-test-id="transfer-form-transfer-id"]`); | ||
const amount = form.find(`[data-test-id="transfer-form-amount"]`); | ||
const destination = form.find(`[data-test-id="transfer-form-destination-address"]`); | ||
const summary = form.find(`[data-test-id="transfer-dialog-proposal-summary"]`); | ||
|
||
expect(transferId.exists()).toBe(true); | ||
expect(transferId.find('input').element.value).toBe('transfer-id'); | ||
|
||
expect(amount.find('input').element.value).toBe('1.23'); | ||
expect(destination.find('input').element.value).toBe('destination address'); | ||
expect(summary.find('input').element.value).toBe('test summary'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.