Files
bunq/test/test.advanced.ts

415 lines
12 KiB
TypeScript

import { expect, tap } from '@git.zone/tstest/tapbundle';
import * as bunq from '../ts/index.js';
let testBunqAccount: bunq.BunqAccount;
let sandboxApiKey: string;
let primaryAccount: bunq.BunqMonetaryAccount;
tap.test('should setup advanced test environment', async () => {
// Create sandbox user
const tempAccount = new bunq.BunqAccount({
apiKey: '',
deviceName: 'bunq-advanced-test',
environment: 'SANDBOX',
});
sandboxApiKey = await tempAccount.createSandboxUser();
// Initialize bunq account
testBunqAccount = new bunq.BunqAccount({
apiKey: sandboxApiKey,
deviceName: 'bunq-advanced-test',
environment: 'SANDBOX',
});
await testBunqAccount.init();
// Get primary account
const accounts = await testBunqAccount.getAccounts();
primaryAccount = accounts[0];
console.log('Advanced test environment setup complete');
});
tap.test('should test joint account functionality', async () => {
// Test joint account creation
try {
const jointAccountId = await bunq.BunqMonetaryAccount.createJoint(testBunqAccount, {
currency: 'EUR',
description: 'Test Joint Account',
daily_limit: {
value: '500.00',
currency: 'EUR'
},
overdraft_limit: {
value: '0.00',
currency: 'EUR'
},
alias: {
type: 'EMAIL',
value: 'joint-test@example.com',
name: 'Joint Account Test'
},
co_owner_invite: {
type: 'EMAIL',
value: 'co-owner@example.com'
}
});
expect(jointAccountId).toBeTypeofNumber();
console.log(`Created joint account with ID: ${jointAccountId}`);
// List all accounts to verify
const allAccounts = await testBunqAccount.getAccounts();
const jointAccount = allAccounts.find(acc => acc.id === jointAccountId);
expect(jointAccount).toBeDefined();
expect(jointAccount?.accountType).toEqual('joint');
} catch (error) {
console.log('Joint account creation not supported in sandbox:', error.message);
}
});
tap.test('should test card operations', async () => {
const cardManager = new bunq.BunqCard(testBunqAccount);
try {
// Create a virtual card
const cardId = await cardManager.create({
type: 'MASTERCARD',
sub_type: 'VIRTUAL',
product_type: 'MASTERCARD_DEBIT',
primary_account_numbers: [{
monetary_account_id: primaryAccount.id,
status: 'ACTIVE'
}],
pin_code_assignment: [{
type: 'PRIMARY',
pin_code: '1234' // Note: In production, use secure PIN
}]
});
expect(cardId).toBeTypeofNumber();
console.log(`Created virtual card with ID: ${cardId}`);
// Get card details
const card = await cardManager.get(cardId);
expect(card.id).toEqual(cardId);
expect(card.type).toEqual('MASTERCARD');
expect(card.status).toBeOneOf(['ACTIVE', 'PENDING_ACTIVATION']);
// Update card status
await cardManager.update(cardId, {
status: 'DEACTIVATED'
});
console.log('Card deactivated successfully');
} catch (error) {
console.log('Card operations not fully supported in sandbox:', error.message);
}
});
tap.test('should test savings goals', async () => {
try {
// Create a savings goal
const savingsGoal = await bunq.BunqMonetaryAccount.create(testBunqAccount, {
currency: 'EUR',
description: 'Vacation Savings',
daily_limit: '0.00',
savings_goal: {
currency: 'EUR',
value: '1000.00',
end_date: '2025-12-31'
}
});
expect(savingsGoal.id).toBeTypeofNumber();
console.log('Savings goal account created');
// Transfer to savings
const payment = await bunq.BunqPayment.builder(testBunqAccount, primaryAccount)
.amount('50.00', 'EUR')
.toAccount(savingsGoal.id)
.description('Monthly savings deposit')
.create();
console.log('Savings deposit completed');
} catch (error) {
console.log('Savings goals not supported in sandbox:', error.message);
}
});
tap.test('should test bunq.me functionality', async () => {
// Create bunq.me link
try {
const bunqMeTab = {
amount_inquired: {
currency: 'EUR',
value: '10.00'
},
description: 'Coffee money',
redirect_url: 'https://example.com/thanks'
};
const httpClient = testBunqAccount['apiContext'].getHttpClient();
const tabResponse = await httpClient.post(
`/v1/user/${testBunqAccount.userId}/monetary-account/${primaryAccount.id}/bunqme-tab`,
{ bunqme_tab_entry: bunqMeTab }
);
if (tabResponse.Response && tabResponse.Response[0]) {
const bunqMeUrl = tabResponse.Response[0].BunqMeTab?.bunqme_tab_share_url;
expect(bunqMeUrl).toBeTypeofString();
expect(bunqMeUrl).toInclude('bunq.me');
console.log(`Created bunq.me link: ${bunqMeUrl}`);
}
} catch (error) {
console.log('bunq.me functionality error:', error.message);
}
});
tap.test('should test OAuth functionality', async () => {
// Test OAuth client registration
try {
const oauthClient = {
status: 'ACTIVE',
redirect_uri: ['https://example.com/oauth/callback'],
display_name: 'Test OAuth App',
description: 'OAuth integration test'
};
const httpClient = testBunqAccount['apiContext'].getHttpClient();
const oauthResponse = await httpClient.post(
`/v1/user/${testBunqAccount.userId}/oauth-client`,
oauthClient
);
if (oauthResponse.Response && oauthResponse.Response[0]) {
const clientId = oauthResponse.Response[0].OAuthClient?.id;
expect(clientId).toBeTypeofNumber();
console.log(`Created OAuth client with ID: ${clientId}`);
}
} catch (error) {
console.log('OAuth functionality not available in sandbox:', error.message);
}
});
tap.test('should test QR code functionality', async () => {
// Test QR code generation for payments
try {
const qrCodeContent = {
amount: {
currency: 'EUR',
value: '5.00'
},
description: 'QR Code Payment Test'
};
// In a real implementation, you would generate QR code content
// that follows the bunq QR code format
const qrData = JSON.stringify({
bunq: {
request: {
amount: qrCodeContent.amount,
description: qrCodeContent.description,
merchant: 'Test Merchant'
}
}
});
expect(qrData).toBeTypeofString();
console.log('QR code data generated for payment request');
} catch (error) {
console.log('QR code generation error:', error.message);
}
});
tap.test('should test auto-accept settings', async () => {
// Test auto-accept for small payments
try {
const settings = {
auto_accept_small_payments: true,
auto_accept_max_amount: {
currency: 'EUR',
value: '10.00'
}
};
// Update account settings
await bunq.BunqMonetaryAccount.update(testBunqAccount, primaryAccount.id, {
setting: settings
});
console.log('Auto-accept settings updated');
} catch (error) {
console.log('Auto-accept settings error:', error.message);
}
});
tap.test('should test export functionality', async () => {
// Test statement export
try {
const exportRequest = {
statement_format: 'PDF',
date_start: '2025-01-01',
date_end: '2025-07-31',
regional_format: 'EUROPEAN'
};
const httpClient = testBunqAccount['apiContext'].getHttpClient();
const exportResponse = await httpClient.post(
`/v1/user/${testBunqAccount.userId}/monetary-account/${primaryAccount.id}/customer-statement`,
exportRequest
);
if (exportResponse.Response && exportResponse.Response[0]) {
const statementId = exportResponse.Response[0].CustomerStatement?.id;
expect(statementId).toBeTypeofNumber();
console.log(`Statement export requested with ID: ${statementId}`);
}
} catch (error) {
console.log('Export functionality error:', error.message);
}
});
tap.test('should test multi-currency support', async () => {
// Test creating account with different currency
try {
const usdAccount = await bunq.BunqMonetaryAccount.create(testBunqAccount, {
currency: 'USD',
description: 'USD Account',
daily_limit: '1000.00'
});
expect(usdAccount.id).toBeTypeofNumber();
console.log('Multi-currency account created');
// Test currency conversion
const conversionQuote = {
amount_from: {
currency: 'EUR',
value: '100.00'
},
amount_to: {
currency: 'USD'
}
};
// In production, you would get real-time conversion rates
console.log('Currency conversion quote requested');
} catch (error) {
console.log('Multi-currency not fully supported in sandbox:', error.message);
}
});
tap.test('should test tab payments (split bills)', async () => {
// Test creating a tab for splitting bills
try {
const tab = {
description: 'Dinner bill split',
amount_total: {
currency: 'EUR',
value: '120.00'
},
tab_items: [
{
description: 'Pizza',
amount: {
currency: 'EUR',
value: '40.00'
}
},
{
description: 'Drinks',
amount: {
currency: 'EUR',
value: '80.00'
}
}
]
};
const httpClient = testBunqAccount['apiContext'].getHttpClient();
const tabResponse = await httpClient.post(
`/v1/user/${testBunqAccount.userId}/monetary-account/${primaryAccount.id}/tab-usage-multiple`,
tab
);
if (tabResponse.Response && tabResponse.Response[0]) {
console.log('Tab payment created for bill splitting');
}
} catch (error) {
console.log('Tab payments not supported in sandbox:', error.message);
}
});
tap.test('should test connect functionality', async () => {
// Test bunq Connect (open banking)
try {
const connectRequest = {
counterparty_bank: 'INGBNL2A',
counterparty_iban: 'NL91INGB0417164300',
consent_type: 'ACCOUNTS_INFORMATION',
valid_until: '2025-12-31'
};
const httpClient = testBunqAccount['apiContext'].getHttpClient();
const connectResponse = await httpClient.post(
`/v1/user/${testBunqAccount.userId}/open-banking-connect`,
connectRequest
);
console.log('Open banking connect request created');
} catch (error) {
console.log('Connect functionality not available in sandbox:', error.message);
}
});
tap.test('should test travel mode', async () => {
// Test travel mode settings
try {
const travelSettings = {
travel_mode: true,
travel_regions: ['EUROPE', 'NORTH_AMERICA'],
travel_end_date: '2025-12-31'
};
// Update user travel settings
const httpClient = testBunqAccount['apiContext'].getHttpClient();
await httpClient.put(
`/v1/user/${testBunqAccount.userId}`,
{ travel_settings: travelSettings }
);
console.log('Travel mode activated');
} catch (error) {
console.log('Travel mode settings error:', error.message);
}
});
tap.test('should cleanup advanced test resources', async () => {
// Clean up any created resources
const accounts = await testBunqAccount.getAccounts();
// Close any test accounts created (except primary)
for (const account of accounts) {
if (account.id !== primaryAccount.id && account.description.includes('Test')) {
try {
await bunq.BunqMonetaryAccount.update(testBunqAccount, account.id, {
status: 'CANCELLED',
sub_status: 'REDEMPTION_VOLUNTARY',
reason: 'OTHER',
reason_description: 'Test cleanup'
});
console.log(`Closed test account: ${account.description}`);
} catch (error) {
// Ignore cleanup errors
}
}
}
await testBunqAccount.stop();
console.log('Advanced test cleanup completed');
});
export default tap.start();