import { describe, it, expect, vi, beforeEach } from 'vitest' import { useDepositData } from '../use-deposit-data' import { DepositMethodEnum, EWalletTypeEnum, ResponseStatus } from '#lib/enums' import { EWALLET_OPTIONS, PRIORITY_BANKS } from '#lib/constants' import { BankListItem, CryptoItem, EWalletItem, FastpayItem } from '#lib/types' import type { PaymentBankListResponseData, PaymentBankScheduleResponseData, } from '@kira-dancer/nadal' // Mock dependencies const mockDepositStore = { phoneCardProviders: [], setPhoneCardProviders: vi.fn(), setMaintainedPhoneCardWithdraw: vi.fn(), setCryptos: vi.fn(), setWithdrawBanks: vi.fn(), setFastpayCode: vi.fn(), setDepositFastPays: vi.fn(), setPaywinBanks: vi.fn(), setEWallet: vi.fn(), setEWalletCode: vi.fn(), setBankSchedules: vi.fn(), isFetchData: false, setIsFetchData: vi.fn(), paywinBanks: [] as BankListItem[], depositFastPays: [] as FastpayItem[], bankSchedules: [] as PaymentBankScheduleResponseData[], cryptos: [] as CryptoItem[], fastpayCode: '', eWalletCode: '', eWallets: [] as EWalletItem[], withdrawBanks: [] as PaymentBankListResponseData[], } const mockBankStore = { setBanks: vi.fn(), } const mockNadal = { payment: { cryptoList: vi.fn(), withdrawBankList: vi.fn(), payCode: vi.fn(), codePayList: vi.fn(), paywinList: vi.fn(), bankList: vi.fn(), bankAccount: vi.fn(), bankSchedule: vi.fn(), }, } const mockDepositService = { fetchEWalletsService: vi.fn(), fetchEWalletCodeService: vi.fn(), } const mockRuntimeConfig = { public: { DEPOSIT_PAYWIN_DISABLE: '0', }, } vi.mock('#lib/stores/payment', () => ({ usePaymentStore: () => mockDepositStore, })) vi.mock('#lib/stores', () => ({ useUserBankStore: () => mockBankStore, })) vi.mock('nuxt/app', () => ({ useRuntimeConfig: () => mockRuntimeConfig, })) vi.mock('#lib/composables', () => ({ useDepositService: () => mockDepositService, useNadal: () => mockNadal, })) vi.mock('#lib/composables/service/use-api-fetch', () => ({ useApiFetch: () => { return { request: vi.fn(), } }, })) describe('useDepositData composable', () => { beforeEach(() => { vi.clearAllMocks() }) // Testing error handling in async functions it('should handle error when fetching phone card providers', async () => { const { fetchPhoneCardProviders } = useDepositData() await fetchPhoneCardProviders() expect(mockDepositStore.setPhoneCardProviders).not.toHaveBeenCalled() }) it('should handle error when fetching withdraw banks', async () => { mockNadal.payment.withdrawBankList.mockRejectedValue(null) const { fetchWithdrawBanks } = useDepositData() await fetchWithdrawBanks() expect(mockDepositStore.setWithdrawBanks).not.toHaveBeenCalled() }) it('should handle error when fetching e-wallets', async () => { mockDepositService.fetchEWalletsService.mockRejectedValue(null) const { fetchEWallets } = useDepositData() await fetchEWallets() expect(mockDepositStore.setEWallet).not.toHaveBeenCalled() }) // Covering all cases for isMaintenance function it('should return true for isMaintenance with FastPay when no data is present', () => { const { isMaintenance, isShowMenuLabel } = useDepositData() isShowMenuLabel.value = true expect(isMaintenance(DepositMethodEnum.FastPay)).toBe(true) }) it('should return false for isMaintenance with valid data for FastPay', () => { mockDepositStore.depositFastPays = [{}] mockDepositStore.fastpayCode = 'code123' const { isMaintenance } = useDepositData() expect(isMaintenance(DepositMethodEnum.FastPay)).toBe(false) }) it('should return true for isMaintenance with Paywin when no data is present', () => { const { isMaintenance, isShowMenuLabel } = useDepositData() isShowMenuLabel.value = true expect(isMaintenance(DepositMethodEnum.Paywin)).toBe(true) }) it('should return true for isMaintenance with ViettelPay', () => { const { isMaintenance, isShowMenuLabel } = useDepositData() isShowMenuLabel.value = true expect(isMaintenance(DepositMethodEnum.ViettelPay)).toBe(true) }) it('should return true for isMaintenance with Momo', () => { const { isMaintenance, isShowMenuLabel } = useDepositData() isShowMenuLabel.value = true expect(isMaintenance(DepositMethodEnum.Momo)).toBe(true) }) // Testing complex behavior in fetchDepositEWalletsData it('should fetch e-wallet and crypto data if not already fetched', async () => { mockDepositStore.isFetchData = false vi.mocked(mockDepositService.fetchEWalletCodeService).mockResolvedValue({ status: ResponseStatus.OK, data: [], }) const { fetchDepositEWalletsData } = useDepositData() await fetchDepositEWalletsData() expect(mockDepositService.fetchEWalletsService).toHaveBeenCalled() expect(mockDepositService.fetchEWalletCodeService).toHaveBeenCalled() expect(mockNadal.payment.cryptoList).toHaveBeenCalled() expect(mockDepositStore.setIsFetchData).toHaveBeenCalledWith(true) }) it('should not fetch e-wallet and crypto data if already fetched', async () => { const { fetchDepositEWalletsData } = useDepositData() mockDepositStore.isFetchData = true await fetchDepositEWalletsData() expect(mockDepositService.fetchEWalletsService).not.toHaveBeenCalled() expect(mockDepositService.fetchEWalletCodeService).not.toHaveBeenCalled() expect(mockNadal.payment.cryptoList).not.toHaveBeenCalled() expect(mockDepositStore.setIsFetchData).not.toHaveBeenCalled() }) it('should check if a bank has a schedule', () => { const mockBankSchedules: PaymentBankScheduleResponseData[] = [ { bank_code: 'VCB', timeSchedule: [ { note: 'baotri', status: true, start_time: '08:00', end_time: '17:00', }, { note: 'saoke', status: true, start_time: '08:00', end_time: '17:00', }, ], last_updated_time: '2021-09-01T00:00:00', created_time: '2021-09-01T00:00:00', _id: '123', }, ] mockDepositStore.bankSchedules = mockBankSchedules const { getScheduleBanks } = useDepositData() const result = getScheduleBanks('VCB') expect(result).toBe(true) }) it('should check if a bank does not have a schedule', () => { mockDepositStore.bankSchedules = [] const { getScheduleBanks } = useDepositData() const result = getScheduleBanks('VCB') expect(result).toBe(false) }) it('should find the first available priority bank', () => { const mockBanks = [ { bank_code: PRIORITY_BANKS[2].bank_code, isMaintained: false, isScheduleBank: false, }, { bank_code: 'VCB', isMaintained: true, isScheduleBank: false }, ] const { findAvailablePriorityBank } = useDepositData() const result = findAvailablePriorityBank(mockBanks) expect(result.bank_code).toBe(PRIORITY_BANKS[2].bank_code) }) it('should return null if no priority bank is available', () => { const mockBanks = [ { bank_code: 'BIDV', isMaintained: true, isScheduleBank: true }, { bank_code: 'VCB', isMaintained: true, isScheduleBank: true }, ] const { findAvailablePriorityBank } = useDepositData() const result = findAvailablePriorityBank(mockBanks) expect(result).toBeNull() }) it('should format and sort bank list correctly', () => { const mockBanks = [ { bank_code: 'BIDV', bankName: 'BIDV Bank', isMaintained: false, isScheduleBank: false, }, { bank_code: 'VCB', bankName: 'VCB Bank', isMaintained: true, isScheduleBank: false, }, { bank_code: 'TCB', bankName: 'TCB Bank', isMaintained: false, isScheduleBank: true, }, ] const { formatBankList } = useDepositData() const formattedBanks = formatBankList(mockBanks) expect(formattedBanks[0].bankName).toBe('BIDV Bank') expect(formattedBanks[1].bankName).toBe('TCB Bank') expect(formattedBanks[2].bankName).toBe('VCB Bank') }) it('should correctly format and sort bank list considering schedule and maintenance status', () => { const mockBanks = [ { bank_code: 'BIDV', bankName: 'BIDV Bank', isMaintained: false }, { bank_code: 'VCB', bankName: 'VCB Bank', isMaintained: true }, { bank_code: 'TCB', bankName: 'TCB Bank', isMaintained: false }, ] const mockBankSchedules: PaymentBankScheduleResponseData[] = [ { bank_code: 'TCB', timeSchedule: [ { note: 'baotri', status: true, start_time: '08:00', end_time: '17:00', }, ], last_updated_time: '2021-09-01T00:00:00', created_time: '2021-09-01T00:00:00', _id: '123', }, ] mockDepositStore.bankSchedules = mockBankSchedules const { formatBankList } = useDepositData() const formattedBanks = formatBankList(mockBanks) expect(formattedBanks[0].bankName).toBe('BIDV Bank') expect(formattedBanks[1].bankName).toBe('TCB Bank (Sao kê)') expect(formattedBanks[2].bankName).toBe('VCB Bank') }) it('should correctly identify and return the first available priority bank considering schedule and maintenance status', () => { const mockBanks = [ { bank_code: 'BIDV', isMaintained: true, isScheduleBank: false }, { bank_code: PRIORITY_BANKS[0].bank_code, isMaintained: false, isScheduleBank: false, }, { bank_code: PRIORITY_BANKS[1].bank_code, isMaintained: false, isScheduleBank: true, }, ] const mockBankSchedules: PaymentBankScheduleResponseData[] = [ { bank_code: 'TCB', timeSchedule: [ { note: 'baotri', status: true, start_time: '08:00', end_time: '17:00', }, ], last_updated_time: '2021-09-01T00:00:00', created_time: '2021-09-01T00:00:00', _id: '123', }, ] mockDepositStore.bankSchedules = mockBankSchedules const { findAvailablePriorityBank } = useDepositData() const result = findAvailablePriorityBank(mockBanks) expect(result.bank_code).toBe(PRIORITY_BANKS[0].bank_code) }) it('should return null when no available priority bank is found considering schedule and maintenance status', () => { const mockBanks = [ { bank_code: PRIORITY_BANKS[0].bank_code, isMaintained: true, isScheduleBank: false, }, { bank_code: PRIORITY_BANKS[1].bank_code, isMaintained: false, isScheduleBank: true, }, ] const mockBankSchedules: PaymentBankScheduleResponseData[] = [ { bank_code: PRIORITY_BANKS[1].bank_code, timeSchedule: [ { note: 'baotri', status: true, start_time: '08:00', end_time: '17:00', }, ], last_updated_time: '2021-09-01T00:00:00', created_time: '2021-09-01T00:00:00', _id: '123', }, ] mockDepositStore.bankSchedules = mockBankSchedules const { findAvailablePriorityBank } = useDepositData() const result = findAvailablePriorityBank(mockBanks) expect(result).toBeNull() }) it('should get bank info correctly based on bankCode', async () => { const mockBankInfo = { bank_name: 'VCB', bank_code: 'VCB123' } mockNadal.payment.bankAccount.mockResolvedValue(mockBankInfo) const { getBankInfo } = useDepositData() const result = await getBankInfo('VCB') expect(result).toEqual(mockBankInfo) expect(mockNadal.payment.bankAccount).toHaveBeenCalledWith({ bank_code: 'VCB', is_auto: 0, }) }) it('should fetch all deposit data and call fetchPaywinBanks when DEPOSIT_PAYWIN_DISABLE is 0', async () => { mockRuntimeConfig.public.DEPOSIT_PAYWIN_DISABLE = '0' const mockPaywinList = [ { bank_name: 'VCB', bank_code: 'VCB123', isMaintained: false }, { bank_name: 'BIDV', bank_code: 'BIDV123', isMaintained: true }, ] mockNadal.payment.paywinList.mockResolvedValue(mockPaywinList) const { fetchAllDepositData } = useDepositData() await fetchAllDepositData() expect(mockNadal.payment.paywinList).toHaveBeenCalled() //... continue for other expected fetch calls }) it('should fetch all deposit data and call fetchBankList', async () => { const mockFastpays = [ { name: 'VCB', bank_code: 'VCB123', isMaintained: false, status: true }, { name: 'BIDV', bank_code: 'BIDV123', isMaintained: true, status: true }, ] mockNadal.payment.codePayList.mockResolvedValue(mockFastpays) const { fetchAllDepositData } = useDepositData() await fetchAllDepositData() expect(mockNadal.payment.codePayList).toHaveBeenCalled() const expectedFastpays = mockFastpays.map((bank) => ({ ...bank, bankName: `${bank.name}${bank.isMaintained ? ' (Bảo trì)' : ''}`, })) expect(mockDepositStore.setDepositFastPays).toHaveBeenCalledWith( expectedFastpays, ) }) it('should fetch all deposit data and call fetchBankList', async () => { const mockBankList = [ { name: 'VCB', bank_name: 'VCB123', isMaintained: false }, { name: 'BIDV', bank_name: 'BIDV123', isMaintained: true }, ] mockNadal.payment.bankList.mockResolvedValue(mockBankList) const { fetchAllDepositData } = useDepositData() await fetchAllDepositData() expect(mockNadal.payment.bankList).toHaveBeenCalled() const expectedBanks = mockBankList.map((bank) => ({ ...bank, name: bank.bank_name, bankName: `${bank.bank_name}${bank.isMaintained ? ' (Bảo trì)' : ''}`, })) expect(mockBankStore.setBanks).toHaveBeenCalledWith(expectedBanks) }) it('should fetch all deposit data and call fetchEWallets', async () => { const mockEWallets = { data: { value: { status: ResponseStatus.OK, data: [ { bank_code: EWalletTypeEnum.Momo, account_no: '123-456-789' }, { bank_code: EWalletTypeEnum.ViettelPay, account_no: '987-654-321', }, ], }, }, } vi.mocked(mockDepositService.fetchEWalletsService).mockResolvedValue( mockEWallets, ) const { fetchAllDepositData } = useDepositData() await fetchAllDepositData() expect(mockDepositService.fetchEWalletsService).toHaveBeenCalled() const expectedData = EWALLET_OPTIONS.map((item) => { const items = mockEWallets.data.value.data .filter( (eWallet) => eWallet.bank_code.toLocaleLowerCase() === item.value.toLocaleLowerCase(), ) .map((eWallet) => ({ ...eWallet, account_no: eWallet.account_no.replace(/[^0-9]/g, ''), })) return { ...item, items, isMaintainance: !items.length, } }) expect(mockDepositStore.setEWallet).toHaveBeenCalledWith(expectedData) }) })