/**
* File Operations Integration Tests
*
* Tests end-to-end file operations with real file system
*/
import { FileOperationsService } from '../../src/services/file-operations-service.js';
import { ElementorService } from '../../src/services/elementor/elementor-service.js';
import { WordPressService } from '../../src/services/wordpress/wordpress-service.js';
import { getWordPressConfig } from '../../src/config/wordpress-config.js';
import { WordPressClient } from '../../src/services/wordpress-client.js';
import fs from 'fs';
import path from 'path';
describe('File Operations Integration Tests', () => {
let fileOpsService: FileOperationsService;
let elementorService: ElementorService | null = null;
let wpService: WordPressService | null = null;
let testPageId: number | null = null;
const testDir = './test-data';
beforeAll(() => {
// Initialize file operations service
fileOpsService = new FileOperationsService(testDir);
// Initialize WordPress services if configured
const config = getWordPressConfig();
if (config) {
const client = new WordPressClient(config);
elementorService = new ElementorService(client.getAxiosInstance());
wpService = new WordPressService(config);
}
// Create test directory if it doesn't exist
if (!fs.existsSync(testDir)) {
fs.mkdirSync(testDir, { recursive: true });
}
});
afterAll(() => {
// Clean up test directory
if (fs.existsSync(testDir)) {
fs.rmSync(testDir, { recursive: true, force: true });
}
// Clean up test page if created
if (wpService && testPageId) {
wpService.pages.deletePage(testPageId, true).catch(() => {});
}
});
describe('Export Operations', () => {
it('should export Elementor data to file', async () => {
const elementorData = [
{
id: 'export-section',
elType: 'section',
settings: {
background_color: '#ffffff'
},
elements: [
{
id: 'export-column',
elType: 'column',
settings: {
_column_size: 100
},
elements: [
{
id: 'export-heading',
elType: 'widget',
widgetType: 'heading',
settings: {
title: 'Export Test Heading'
}
}
]
}
]
}
];
const result = await fileOpsService.exportElementorData(123, elementorData, {
includeMetadata: true,
compress: false
});
expect(result).toBeDefined();
expect(result.success).toBe(true);
expect(result.filePath).toBeDefined();
expect(fs.existsSync(result.filePath)).toBe(true);
});
it('should export with compression', async () => {
const elementorData = [
{
id: 'compress-section',
elType: 'section',
settings: {},
elements: []
}
];
const result = await fileOpsService.exportElementorData(456, elementorData, {
includeMetadata: true,
compress: true
});
expect(result).toBeDefined();
expect(result.success).toBe(true);
expect(result.compressed).toBe(true);
});
});
describe('Import Operations', () => {
it('should import Elementor data from file', async () => {
// First export data
const exportData = [
{
id: 'import-section',
elType: 'section',
settings: {},
elements: []
}
];
const exportResult = await fileOpsService.exportElementorData(789, exportData);
// Then import it
const importResult = await fileOpsService.importElementorData(exportResult.filePath);
expect(importResult).toBeDefined();
expect(importResult.success).toBe(true);
expect(importResult.data).toBeDefined();
expect(Array.isArray(importResult.data)).toBe(true);
expect(importResult.data.length).toBe(1);
expect(importResult.data[0].id).toBe('import-section');
});
it('should validate imported data', async () => {
const exportData = [
{
id: 'validate-section',
elType: 'section',
settings: {},
elements: []
}
];
const exportResult = await fileOpsService.exportElementorData(101, exportData);
const importResult = await fileOpsService.importElementorData(exportResult.filePath, {
validate: true
});
expect(importResult.success).toBe(true);
expect(importResult.validated).toBe(true);
});
});
describe('Backup Operations', () => {
it('should create backup', async () => {
const elementorData = [
{
id: 'backup-section',
elType: 'section',
settings: {},
elements: []
}
];
const result = await fileOpsService.backupPageData(202, elementorData, 'Test Backup');
expect(result).toBeDefined();
expect(result.success).toBe(true);
expect(result.backupId).toBeDefined();
expect(result.filePath).toBeDefined();
expect(fs.existsSync(result.filePath)).toBe(true);
});
it('should list backups', async () => {
// Create a backup first
await fileOpsService.backupPageData(303, [], 'List Test Backup');
const result = await fileOpsService.listBackups();
expect(result).toBeDefined();
expect(Array.isArray(result)).toBe(true);
expect(result.length).toBeGreaterThan(0);
});
it('should restore from backup', async () => {
const backupData = [
{
id: 'restore-section',
elType: 'section',
settings: {},
elements: []
}
];
const backupResult = await fileOpsService.backupPageData(404, backupData, 'Restore Test');
const restoreResult = await fileOpsService.restorePageData(backupResult.backupId);
expect(restoreResult).toBeDefined();
expect(restoreResult.success).toBe(true);
expect(restoreResult.data).toBeDefined();
expect(restoreResult.data.length).toBe(1);
expect(restoreResult.data[0].id).toBe('restore-section');
});
});
describe('File Management', () => {
it('should get file info', async () => {
// Create a file first
const exportResult = await fileOpsService.exportElementorData(505, []);
const result = await fileOpsService.getFileInfo(exportResult.filePath);
expect(result).toBeDefined();
expect(result.exists).toBe(true);
expect(result.size).toBeGreaterThan(0);
expect(result.created).toBeDefined();
expect(result.modified).toBeDefined();
});
it('should validate file', async () => {
const exportResult = await fileOpsService.exportElementorData(606, [
{
id: 'validate-file-section',
elType: 'section',
settings: {},
elements: []
}
]);
const result = await fileOpsService.validateFile(exportResult.filePath);
expect(result).toBeDefined();
expect(result.valid).toBe(true);
expect(result.checksum).toBeDefined();
});
it('should cleanup old backups', async () => {
// Create multiple backups
await fileOpsService.backupPageData(707, [], 'Cleanup Test 1');
await fileOpsService.backupPageData(707, [], 'Cleanup Test 2');
await fileOpsService.backupPageData(707, [], 'Cleanup Test 3');
const beforeCleanup = await fileOpsService.listBackups();
const initialCount = beforeCleanup.length;
const result = await fileOpsService.cleanupOldBackups(1); // Keep only 1 backup
expect(result).toBeDefined();
expect(result.success).toBe(true);
expect(result.deletedCount).toBeGreaterThan(0);
const afterCleanup = await fileOpsService.listBackups();
expect(afterCleanup.length).toBeLessThan(initialCount);
});
});
describe('Complete Workflow with WordPress', () => {
const testIfWordPress = process.env.WORDPRESS_BASE_URL ? it : it.skip;
testIfWordPress('should export, backup, and restore real WordPress page', async () => {
if (!wpService || !elementorService) {
throw new Error('WordPress not configured');
}
// Step 1: Create test page
const page = await wpService.pages.createPage({
title: 'File Operations Test - ' + Date.now(),
content: '',
status: 'draft'
});
testPageId = page.id;
// Step 2: Create Elementor data
const elementorData = [
{
id: 'workflow-section',
elType: 'section',
settings: {
background_color: '#f0f0f0'
},
elements: [
{
id: 'workflow-column',
elType: 'column',
settings: {
_column_size: 100
},
elements: [
{
id: 'workflow-heading',
elType: 'widget',
widgetType: 'heading',
settings: {
title: 'File Operations Workflow Test'
}
}
]
}
]
}
];
// Step 3: Save to WordPress
await elementorService.data.updateElementorData(testPageId, elementorData);
// Step 4: Export from WordPress
const savedData = await elementorService.data.getElementorData(testPageId);
const exportResult = await fileOpsService.exportElementorData(testPageId, savedData);
expect(exportResult.success).toBe(true);
expect(fs.existsSync(exportResult.filePath)).toBe(true);
// Step 5: Create backup
const backupResult = await fileOpsService.backupPageData(
testPageId,
savedData,
'Workflow Test Backup'
);
expect(backupResult.success).toBe(true);
// Step 6: Import from file
const importResult = await fileOpsService.importElementorData(exportResult.filePath);
expect(importResult.success).toBe(true);
expect(importResult.data.length).toBe(1);
// Step 7: Restore from backup
const restoreResult = await fileOpsService.restorePageData(backupResult.backupId);
expect(restoreResult.success).toBe(true);
expect(restoreResult.data).toEqual(savedData);
// Step 8: Verify file info
const fileInfo = await fileOpsService.getFileInfo(exportResult.filePath);
expect(fileInfo.exists).toBe(true);
expect(fileInfo.size).toBeGreaterThan(0);
// Step 9: Validate file
const validation = await fileOpsService.validateFile(exportResult.filePath);
expect(validation.valid).toBe(true);
}, 45000);
});
describe('Error Handling', () => {
it('should handle non-existent file import', async () => {
await expect(
fileOpsService.importElementorData('/non/existent/file.json')
).rejects.toThrow();
});
it('should handle invalid file format', async () => {
const invalidFile = path.join(testDir, 'invalid.json');
fs.writeFileSync(invalidFile, 'invalid json content');
await expect(
fileOpsService.importElementorData(invalidFile)
).rejects.toThrow();
});
it('should handle non-existent backup restore', async () => {
await expect(
fileOpsService.restorePageData('non-existent-backup-id')
).rejects.toThrow();
});
});
});