159 lines
3.9 KiB
JavaScript
159 lines
3.9 KiB
JavaScript
// ftp-transfer.spec.js
|
|
const { test, expect } = require('@playwright/test')
|
|
const { spawn } = require('child_process')
|
|
const path = require('path')
|
|
const fs = require('fs')
|
|
const { Transfer } = require('../../src/app/server/ftp-transfer')
|
|
const { Ftp } = require('../../src/app/server/session-ftp')
|
|
|
|
test.describe('FtpTransfer Class', () => {
|
|
let ftpServer
|
|
let ftp
|
|
|
|
test.beforeAll(async () => {
|
|
// Start the FTP test server
|
|
const serverPath = path.join(__dirname, '../e2e/common/ftp.js')
|
|
ftpServer = spawn('node', [serverPath])
|
|
await new Promise((resolve, reject) => {
|
|
const timeout = setTimeout(() => {
|
|
reject(new Error('FTP server start timeout'))
|
|
}, 5000)
|
|
ftpServer.stdout.on('data', (data) => {
|
|
if (data.toString().includes('FTP server is running at port 21')) {
|
|
clearTimeout(timeout)
|
|
resolve()
|
|
}
|
|
})
|
|
})
|
|
})
|
|
|
|
test.afterAll(async () => {
|
|
ftpServer.kill()
|
|
await new Promise((resolve) => ftpServer.on('close', resolve))
|
|
})
|
|
|
|
test.beforeEach(async () => {
|
|
const initOptions = {
|
|
host: 'localhost',
|
|
port: 21,
|
|
user: 'test',
|
|
password: 'test123'
|
|
}
|
|
ftp = new Ftp(initOptions)
|
|
await ftp.connect(initOptions)
|
|
})
|
|
|
|
test.afterEach(() => {
|
|
if (ftp) {
|
|
ftp.kill()
|
|
}
|
|
})
|
|
|
|
test('should handle file transfer events', async () => {
|
|
const localPath = path.join(__dirname, 'test-upload.txt')
|
|
const remotePath = '/test-upload.txt'
|
|
const testContent = 'x'.repeat(1024 * 1024) // 1MB file
|
|
let dataEventCalled = false
|
|
let endEventCalled = false
|
|
|
|
await fs.promises.writeFile(localPath, testContent)
|
|
|
|
const transfer = new Transfer({
|
|
remotePath,
|
|
localPath,
|
|
type: 'upload',
|
|
sftp: ftp.client,
|
|
sftpId: '1',
|
|
sessionId: '1',
|
|
id: '1',
|
|
options: {
|
|
ftp: true
|
|
},
|
|
ws: {
|
|
s: (event) => {
|
|
if (event.id.startsWith('transfer:data:')) {
|
|
dataEventCalled = true
|
|
}
|
|
if (event.id.startsWith('transfer:end:')) {
|
|
endEventCalled = true
|
|
}
|
|
},
|
|
close: () => {}
|
|
}
|
|
})
|
|
console.log('transfer', transfer)
|
|
await transfer.start()
|
|
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
|
|
expect(dataEventCalled).toBe(true)
|
|
expect(endEventCalled).toBe(true)
|
|
|
|
await ftp.rm(remotePath)
|
|
await fs.promises.unlink(localPath)
|
|
})
|
|
|
|
test('should pause and resume transfer', async () => {
|
|
const transfer = new Transfer({
|
|
remotePath: '/test.txt',
|
|
localPath: 'test.txt',
|
|
type: 'upload',
|
|
sftp: ftp.client,
|
|
id: '1',
|
|
ws: {
|
|
s: () => {},
|
|
close: () => {}
|
|
}
|
|
})
|
|
|
|
transfer.pause()
|
|
expect(transfer.pausing).toBe(true)
|
|
|
|
transfer.resume()
|
|
expect(transfer.pausing).toBe(false)
|
|
})
|
|
|
|
test('should properly destroy transfer', async () => {
|
|
const transfer = new Transfer({
|
|
remotePath: '/test.txt',
|
|
localPath: 'test.txt',
|
|
type: 'upload',
|
|
sftp: ftp.client,
|
|
id: '1',
|
|
ws: {
|
|
s: () => {},
|
|
close: () => {}
|
|
}
|
|
})
|
|
|
|
transfer.destroy()
|
|
await new Promise(resolve => setTimeout(resolve, 300))
|
|
expect(transfer.onDestroy).toBe(true)
|
|
expect(transfer.src).toBe(null)
|
|
expect(transfer.dst).toBe(null)
|
|
expect(transfer.ftpClient).toBe(null)
|
|
})
|
|
|
|
test('should handle transfer errors', async () => {
|
|
let errorCalled = false
|
|
const transfer = new Transfer({
|
|
remotePath: '/nonexistent/path/test.txt',
|
|
localPath: 'test.txt',
|
|
type: 'upload',
|
|
sftp: ftp.client,
|
|
id: '1',
|
|
ws: {
|
|
s: (event) => {
|
|
if (event.id.startsWith('transfer:err:')) {
|
|
errorCalled = true
|
|
}
|
|
},
|
|
close: () => {}
|
|
}
|
|
})
|
|
|
|
await transfer.start()
|
|
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
expect(errorCalled).toBe(true)
|
|
})
|
|
})
|