update statement download

This commit is contained in:
2025-07-29 12:40:46 +00:00
parent 9dd55543e9
commit b9317484bf
2 changed files with 91 additions and 46 deletions

View File

@@ -107,49 +107,65 @@ tap.test('should default to last month when no date options provided', async ()
}); });
tap.test('should create and download PDF statement', async () => { tap.test('should create and download PDF statement', async () => {
try { console.log('Creating PDF statement export...');
const exportBuilder = primaryAccount.getAccountStatement({
monthlyIndexedFrom1: 1, const exportBuilder = primaryAccount.getAccountStatement({
includeTransactionAttachments: false monthlyIndexedFrom1: 1,
}); includeTransactionAttachments: false
});
// Configure as PDF
exportBuilder.asPdf();
// Create the export
const bunqExport = await exportBuilder.create();
expect(bunqExport).toBeInstanceOf(bunq.BunqExport);
expect(bunqExport.id).toBeTypeofNumber();
console.log('Created PDF export with ID:', bunqExport.id);
// Wait for completion with status updates
console.log('Waiting for PDF export to complete...');
const maxWaitTime = 180000; // 3 minutes
const startTime = Date.now();
while (true) {
const status = await bunqExport.get();
console.log(`Export status: ${status.status}`);
// Configure as PDF if (status.status === 'COMPLETED') {
exportBuilder.asPdf(); break;
// Create the export
const bunqExport = await exportBuilder.create();
expect(bunqExport).toBeInstanceOf(bunq.BunqExport);
expect(bunqExport.id).toBeTypeofNumber();
// Wait for completion with longer timeout for PDF
await bunqExport.waitForCompletion(120000);
// Download to test directory
const testFilePath = '.nogit/teststatements/test-statement.pdf';
await bunqExport.saveToFile(testFilePath);
// Verify file exists
const fileExists = await plugins.smartfile.fs.fileExists(testFilePath);
expect(fileExists).toBeTrue();
console.log(`Statement downloaded to: ${testFilePath}`);
} catch (error) {
if (error.message && error.message.includes('timed out')) {
console.log('PDF export timed out - sandbox may not support PDF exports');
// Try CSV instead
const exportBuilder = primaryAccount.getAccountStatement({
monthlyIndexedFrom1: 1,
includeTransactionAttachments: false
});
const csvExport = await exportBuilder.asCsv().create();
console.log('Created CSV export instead with ID:', csvExport.id);
} else {
throw error;
} }
if (status.status === 'FAILED') {
throw new Error('Export failed: ' + JSON.stringify(status));
}
if (Date.now() - startTime > maxWaitTime) {
throw new Error(`Export timed out after ${maxWaitTime/1000} seconds. Last status: ${status.status}`);
}
await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds
} }
// Download to test directory
console.log('Downloading PDF statement...');
const testFilePath = '.nogit/teststatements/test-statement.pdf';
await bunqExport.saveToFile(testFilePath);
// Verify file exists and has content
const fileExists = await plugins.smartfile.fs.fileExists(testFilePath);
expect(fileExists).toBeTrue();
const fileStats = await plugins.smartfile.fs.stat(testFilePath);
console.log(`PDF Statement downloaded to: ${testFilePath} (${fileStats.size} bytes)`);
expect(fileStats.size).toBeGreaterThan(0);
}); });
tap.test('should create CSV statement with custom date range', async () => { tap.test('should create CSV statement with custom date range', async () => {
// Wait to avoid rate limiting
await new Promise(resolve => setTimeout(resolve, 3500));
console.log('Creating CSV statement export...');
// Use last month's date range to ensure it's in the past // Use last month's date range to ensure it's in the past
const now = new Date(); const now = new Date();
const startOfMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1); const startOfMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);
@@ -163,19 +179,31 @@ tap.test('should create CSV statement with custom date range', async () => {
// Configure as CSV // Configure as CSV
const csvExport = await exportBuilder.asCsv().create(); const csvExport = await exportBuilder.asCsv().create();
await csvExport.waitForCompletion(30000); console.log('Created CSV export with ID:', csvExport.id);
// Wait for completion
console.log('Waiting for CSV export to complete...');
await csvExport.waitForCompletion(60000);
// Download to test directory
console.log('Downloading CSV statement...');
const testFilePath = '.nogit/teststatements/test-statement.csv'; const testFilePath = '.nogit/teststatements/test-statement.csv';
await csvExport.saveToFile(testFilePath); await csvExport.saveToFile(testFilePath);
// Verify file exists // Verify file exists and has content
const fileExists = await plugins.smartfile.fs.fileExists(testFilePath); const fileExists = await plugins.smartfile.fs.fileExists(testFilePath);
expect(fileExists).toBeTrue(); expect(fileExists).toBeTrue();
console.log(`CSV statement downloaded to: ${testFilePath}`); const fileStats = await plugins.smartfile.fs.stat(testFilePath);
console.log(`CSV statement downloaded to: ${testFilePath} (${fileStats.size} bytes)`);
expect(fileStats.size).toBeGreaterThan(0);
}); });
tap.test('should create MT940 statement', async () => { tap.test('should create MT940 statement', async () => {
// Wait to avoid rate limiting
await new Promise(resolve => setTimeout(resolve, 3500));
console.log('Creating MT940 statement export...');
const exportBuilder = primaryAccount.getAccountStatement({ const exportBuilder = primaryAccount.getAccountStatement({
monthlyIndexedFrom0: 1, // Last month monthlyIndexedFrom0: 1, // Last month
includeTransactionAttachments: false includeTransactionAttachments: false
@@ -183,16 +211,24 @@ tap.test('should create MT940 statement', async () => {
// Configure as MT940 // Configure as MT940
const mt940Export = await exportBuilder.asMt940().create(); const mt940Export = await exportBuilder.asMt940().create();
await mt940Export.waitForCompletion(30000); console.log('Created MT940 export with ID:', mt940Export.id);
// Wait for completion
console.log('Waiting for MT940 export to complete...');
await mt940Export.waitForCompletion(60000);
// Download to test directory
console.log('Downloading MT940 statement...');
const testFilePath = '.nogit/teststatements/test-statement.txt'; const testFilePath = '.nogit/teststatements/test-statement.txt';
await mt940Export.saveToFile(testFilePath); await mt940Export.saveToFile(testFilePath);
// Verify file exists // Verify file exists and has content
const fileExists = await plugins.smartfile.fs.fileExists(testFilePath); const fileExists = await plugins.smartfile.fs.fileExists(testFilePath);
expect(fileExists).toBeTrue(); expect(fileExists).toBeTrue();
console.log(`MT940 statement downloaded to: ${testFilePath}`); const fileStats = await plugins.smartfile.fs.stat(testFilePath);
console.log(`MT940 statement downloaded to: ${testFilePath} (${fileStats.size} bytes)`);
expect(fileStats.size).toBeGreaterThan(0);
}); });
tap.test('should handle edge cases for date calculations', async () => { tap.test('should handle edge cases for date calculations', async () => {

View File

@@ -111,18 +111,27 @@ export class BunqExport {
throw new Error('Export ID not set'); throw new Error('Export ID not set');
} }
// Ensure the export is complete before downloading
const status = await this.get();
if (status.status !== 'COMPLETED') {
throw new Error(`Export is not ready for download. Status: ${status.status}`);
}
// For PDF statements, use the /content endpoint directly // For PDF statements, use the /content endpoint directly
const downloadUrl = `${this.bunqAccount.apiContext.getBaseUrl()}/v1/user/${this.bunqAccount.userId}/monetary-account/${this.monetaryAccount.id}/customer-statement/${this.id}/content`; const downloadUrl = `${this.bunqAccount.apiContext.getBaseUrl()}/v1/user/${this.bunqAccount.userId}/monetary-account/${this.monetaryAccount.id}/customer-statement/${this.id}/content`;
const response = await fetch(downloadUrl, { const response = await fetch(downloadUrl, {
method: 'GET', method: 'GET',
headers: { headers: {
'X-Bunq-Client-Authentication': this.bunqAccount.apiContext.getSession().getContext().sessionToken 'X-Bunq-Client-Authentication': this.bunqAccount.apiContext.getSession().getContext().sessionToken,
'User-Agent': 'bunq-api-client/1.0.0',
'Cache-Control': 'no-cache'
} }
}); });
if (!response.ok) { if (!response.ok) {
throw new Error(`Failed to download export: HTTP ${response.status}`); const responseText = await response.text();
throw new Error(`Failed to download export: HTTP ${response.status} - ${responseText}`);
} }
const arrayBuffer = await response.arrayBuffer(); const arrayBuffer = await response.arrayBuffer();
@@ -146,7 +155,7 @@ export class BunqExport {
while (true) { while (true) {
const details = await this.get(); const details = await this.get();
if (details.status === 'COMPLETE') { if (details.status === 'COMPLETED') {
return; return;
} }