Task 3-2: Integration Test - Listing, Cancel, Burn Ticket
Phase: 3 Priority: Medium Module:
marketplaceDepends on: Không có Reference: docs/bountyhunter-blockchain-p2/details/feature-marketplace/SPEC.md
Background
Các luồng Listing NFT, Cancel Listing, và Burn Ticket chưa có integration test. Mỗi luồng hỗ trợ nhiều chain (EVM, Solana, ImmutableX) với logic phân kỳ. Cần đảm bảo mỗi chain path được route đúng và webhook được gọi với payload chính xác. ImmutableX path sử dụng ImmutableUtil riêng biệt cần được mock độc lập.
Tasks
Note: Mock
ImmutableUtilthông qua NestJS dependency injection — override provider trong test module. Dùngjest.spyOncho SolanaConnectionmethods. Mỗi test case nên verify đúng queue name được dùng (LISTING_NFT,CANCEL_LISTING_NFT,BURN_TICKET). Đảm bảopostWithRetryđược mock để không gọi thật lên Backend.
- [ ] Test case 1 — Listing NFT (EVM):
it('POST /marketplace/listing-nft (EVM) → LISTING_NFT queue → processor → webhook', async () => { const res = await request(app.getHttpServer()) .post('/marketplace/listing-nft') .send({ chainId: EVM_CHAIN_ID, ...listingPayload }); expect(res.status).toBe(201); const jobs = await listingNftQueue.getJobs(['waiting']); expect(jobs).toHaveLength(1); await waitForJobCompletion('LISTING_NFT'); expect(mockWebhook).toHaveBeenCalledWith( expect.any(String), expect.objectContaining({ status: 'SUCCESS' }) ); }); - [ ] Test case 2 — Cancel Listing NFT (EVM):
- Job vào
CANCEL_LISTING_NFTqueue - On-chain cancellation executed
- Webhook success called
- [ ] Test case 3 — Burn Ticket (ERC1155):
it('POST /marketplace/burn-ticket → ERC1155 burn → webhook', async () => { mockErc1155.burn.mockResolvedValue({ hash: '0xburn123' }); // ...verify flow... expect(mockWebhook).toHaveBeenCalledWith( expect.any(String), expect.objectContaining({ status: 'SUCCESS', txHash: '0xburn123' }) ); }); - [ ] Test case 4 — ImmutableX path (mock
ImmutableUtil):it('Listing NFT on ImmutableX → ImmutableUtil.listNft called', async () => { const mockImxListNft = jest.spyOn(immutableUtil, 'listNft').mockResolvedValue({ orderId: '123' }); await request(app.getHttpServer()) .post('/marketplace/listing-nft') .send({ chainId: IMX_CHAIN_ID, ...listingPayload }); await waitForJobCompletion('LISTING_NFT'); expect(mockImxListNft).toHaveBeenCalled(); expect(mockWebhook).toHaveBeenCalledWith( expect.any(String), expect.objectContaining({ status: 'SUCCESS', orderId: '123' }) ); }); - [ ] Test case 5 — Cancel path khi ImmutableX cancellation fails → failure webhook
Verification / Acceptance Criteria
- [ ] Listing NFT: job vào đúng queue
LISTING_NFT, webhook success sau processor completion - [ ] Cancel Listing: on-chain cancellation được gọi, webhook success với txHash
- [ ] Burn Ticket: ERC1155
burn()được gọi với đúng tokenId và amount - [ ] ImmutableX path:
ImmutableUtil.listNft()được gọi thay vìethers.js - [ ] ImmutableX failure → failure webhook với
errorCode(liên quan task-2-2) - [ ] Test pass khi chạy
npm run test
Files to Modify
src/marketplace/tests/marketplace-listing.integration.spec.ts(tạo mới)src/marketplace/tests/marketplace-burn.integration.spec.ts(tạo mới)