Files
2026-07-13 12:46:20 +08:00

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()
})
})