195 lines
5.9 KiB
JavaScript
195 lines
5.9 KiB
JavaScript
const {
|
|
test: it, expect
|
|
} = require('@playwright/test')
|
|
const { describe } = it
|
|
const { listWidgets } = require('../../src/app/widgets/load-widget')
|
|
const { widgetRun } = require('../../src/app/widgets/widget-rename')
|
|
const fs = require('fs/promises')
|
|
const path = require('path')
|
|
|
|
it.setTimeout(100000)
|
|
|
|
describe('rename-widget', function () {
|
|
let testDir = null
|
|
|
|
async function createTestFiles () {
|
|
testDir = path.join(process.cwd(), 'temp-rename-test-' + Date.now())
|
|
await fs.mkdir(testDir)
|
|
|
|
// Create test files
|
|
await fs.writeFile(path.join(testDir, 'file1.txt'), 'Content 1')
|
|
await fs.writeFile(path.join(testDir, 'file2.txt'), 'Content 2')
|
|
await fs.writeFile(path.join(testDir, 'file3.jpg'), 'Image content')
|
|
|
|
// Create a subdirectory with a file
|
|
const subDir = path.join(testDir, 'subfolder')
|
|
await fs.mkdir(subDir)
|
|
await fs.writeFile(path.join(subDir, 'subfile.txt'), 'Sub content')
|
|
}
|
|
|
|
async function cleanup () {
|
|
if (testDir) {
|
|
try {
|
|
await fs.rm(testDir, { recursive: true, force: true })
|
|
} catch (err) {
|
|
console.error('Cleanup error:', err)
|
|
}
|
|
}
|
|
}
|
|
|
|
it.beforeEach(async () => {
|
|
await createTestFiles()
|
|
})
|
|
|
|
it.afterEach(async () => {
|
|
await cleanup()
|
|
})
|
|
|
|
it('should have rename widget available', async function () {
|
|
const widgets = listWidgets()
|
|
expect(Array.isArray(widgets)).toBe(true)
|
|
|
|
const renameWidget = widgets.find(w => w.id === 'rename')
|
|
expect(renameWidget).toBeTruthy()
|
|
expect(renameWidget.info.name).toBe('File Renamer')
|
|
})
|
|
|
|
it('should rename files with simple pattern', async function () {
|
|
const renameResult = await widgetRun({
|
|
directory: testDir,
|
|
template: '{name}-renamed.{ext}',
|
|
fileTypes: '*',
|
|
includeSubfolders: false
|
|
})
|
|
|
|
expect(renameResult.success).toBe(true)
|
|
expect(renameResult.totalRenamed).toBe(3) // Should rename 3 files in the main directory
|
|
|
|
// Check if files were renamed correctly
|
|
const renamedFiles = await fs.readdir(testDir)
|
|
expect(renamedFiles).toContain('file1-renamed.txt')
|
|
expect(renamedFiles).toContain('file2-renamed.txt')
|
|
expect(renamedFiles).toContain('file3-renamed.jpg')
|
|
})
|
|
|
|
it('should rename with sequential numbers', async function () {
|
|
const renameResult = await widgetRun({
|
|
directory: testDir,
|
|
template: 'myfile-{n:3}.{ext}',
|
|
fileTypes: '*',
|
|
startNumber: 10,
|
|
includeSubfolders: false
|
|
})
|
|
|
|
expect(renameResult.success).toBe(true)
|
|
|
|
const renamedFiles = await fs.readdir(testDir)
|
|
expect(renamedFiles).toContain('myfile-010.txt')
|
|
expect(renamedFiles).toContain('myfile-011.txt')
|
|
expect(renamedFiles).toContain('myfile-012.jpg')
|
|
})
|
|
|
|
it('should filter by file type', async function () {
|
|
const renameResult = await widgetRun({
|
|
directory: testDir,
|
|
template: '{name}-{n}.{ext}',
|
|
fileTypes: 'txt',
|
|
includeSubfolders: false
|
|
})
|
|
|
|
expect(renameResult.success).toBe(true)
|
|
expect(renameResult.totalRenamed).toBe(2) // Should only rename .txt files
|
|
|
|
const renamedFiles = await fs.readdir(testDir)
|
|
// file3.jpg should remain unchanged
|
|
expect(renamedFiles).toContain('file3.jpg')
|
|
})
|
|
|
|
it('should include subfolders when enabled', async function () {
|
|
const renameResult = await widgetRun({
|
|
directory: testDir,
|
|
template: '{parent}-{name}-{n}.{ext}',
|
|
fileTypes: '*',
|
|
includeSubfolders: true
|
|
})
|
|
|
|
expect(renameResult.success).toBe(true)
|
|
expect(renameResult.totalRenamed).toBe(4) // All files including subfolder file
|
|
|
|
// Check subfolder file was renamed
|
|
const subFiles = await fs.readdir(path.join(testDir, 'subfolder'))
|
|
expect(subFiles[0]).toMatch(/subfolder-subfile-\d\.txt/)
|
|
})
|
|
|
|
it('should handle template with dates and random', async function () {
|
|
const renameResult = await widgetRun({
|
|
directory: testDir,
|
|
template: '{name}-{date}-{random}.{ext}',
|
|
fileTypes: '*',
|
|
includeSubfolders: false
|
|
})
|
|
|
|
expect(renameResult.success).toBe(true)
|
|
|
|
// Verify that files were renamed with date and random pattern
|
|
const renamedFiles = await fs.readdir(testDir)
|
|
const datePattern = /\d{4}-\d{2}-\d{2}/
|
|
|
|
for (const file of renamedFiles) {
|
|
// If it's a directory, skip
|
|
const stats = await fs.stat(path.join(testDir, file))
|
|
if (stats.isDirectory()) continue
|
|
|
|
// Each renamed file should have a date pattern and a random substring
|
|
expect(file).toMatch(datePattern)
|
|
expect(file).toMatch(/[a-z0-9]{6}/)
|
|
}
|
|
})
|
|
|
|
it('should preserve filename case when enabled', async function () {
|
|
// Create a file with mixed case
|
|
await fs.writeFile(path.join(testDir, 'MixedCase.txt'), 'Mixed case content')
|
|
|
|
const renameResult = await widgetRun({
|
|
directory: testDir,
|
|
template: '{name}-renamed.{ext}',
|
|
fileTypes: '*',
|
|
preserveCase: true,
|
|
includeSubfolders: false
|
|
})
|
|
|
|
expect(renameResult.success).toBe(true)
|
|
|
|
const renamedFiles = await fs.readdir(testDir)
|
|
expect(renamedFiles).toContain('MixedCase-renamed.txt')
|
|
})
|
|
|
|
it('should handle error when directory does not exist', async function () {
|
|
const renameResult = await widgetRun({
|
|
directory: '/path/that/does/not/exist',
|
|
template: '{name}-renamed.{ext}',
|
|
fileTypes: '*'
|
|
})
|
|
|
|
expect(renameResult.success).toBe(false)
|
|
expect(renameResult.error).toBeTruthy()
|
|
})
|
|
|
|
it('should reject templates that escape the source directory', async function () {
|
|
const escapedPath = path.join(path.dirname(testDir), 'escaped-1.txt')
|
|
const renameResult = await widgetRun({
|
|
directory: testDir,
|
|
template: '../escaped-{n}.{ext}',
|
|
fileTypes: 'txt',
|
|
includeSubfolders: false
|
|
})
|
|
|
|
expect(renameResult.success).toBe(false)
|
|
expect(renameResult.error).toContain('path separators')
|
|
|
|
const renamedFiles = await fs.readdir(testDir)
|
|
expect(renamedFiles).toContain('file1.txt')
|
|
await expect(fs.stat(escapedPath)).rejects.toThrow()
|
|
})
|
|
})
|