/* eslint-disable */ // TODO: Make these more compatible with eslint naughtyStrings = [ "文件.txt", // Chinese characters "файл.txt", // Cyrillic characters "ファイル.txt", // Japanese characters "파일.txt", // Korean characters "ملف.txt", // Arabic characters "फ़ाइल.txt", // Hindi characters "archivo.txt", // Spanish characters "fichier.txt", // French characters "αρχείο.txt", // Greek characters "datei.txt", // German characters "fil.txt", // Swedish characters "קובץ.txt", // Hebrew characters "文件名.txt", // Chinese characters "файлы.txt", // Russian characters "फ़ाइलें.txt", // Hindi characters "📄_emoji.txt", // Emoji "file name with spaces.txt", "file-name-with-dashes.txt", "file_name_with_underscores.txt", "file.name.with.periods.txt", "file,name,with,commas.txt", "file;name;with;semicolons.txt", "file(name)with(parentheses).txt", "file[name]with[brackets].txt", "file{name}with{braces}.txt", "file!name!with!exclamations!.txt", "file@name@with@ats.txt", "file#name#with#hashes#.txt", "file$name$with$dollars$.txt", "file%name%with%percentages%.txt", "file^name^with^carats^.txt", "file&name&with&s&.txt", "file*name*with*asterisks*.txt", "file_name_with_long_name_exceeding_255_characters_abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.txt", "file👍name👍with👍thumbs👍up.txt", "invisible\u200Bname.txt", // Invisible Unicode character (Zero Width Space) "invisible\u200Cname.txt", // Invisible Unicode character (Zero Width Non-Joiner) "invisible\u200Dname.txt", // Invisible Unicode character (Zero Width Joiner) "invisible\uFEFFname.txt", // Invisible Unicode character (Zero Width No-Break Space) "invisible\u180Ename.txt", // Invisible Unicode character (Mongolian Vowel Separator) "hash#tag.txt", "percent%20encoded.txt", "plus+sign.txt", "ampersand&symbol.txt", "at@symbol.txt", "parentheses(1).txt", "brackets[1].txt", "curly{braces}.txt", "angle.txt", "exclamation!point.txt", "question?mark.txt", "colon:separated.txt", "semicolon;separated.txt", "single'quote.txt", "double\"quote.txt", "backtick`char.txt", "tilde~sign.txt", "underscore_character.txt", "hyphen-character.txt", "equal=sign.txt", "plus+sign.txt", "asterisk*char.txt", "caret^char.txt", "percent%sign.txt", "dollar$sign.txt", "pound#sign.txt", "at@sign.txt", "exclamation!mark.txt", "question?mark.txt", "backslash\\char.txt", "pipe|char.txt", "colon:char.txt", "semicolon;char.txt", "quote'char.txt", "double\"quote.txt", "backtick`char.txt", "braces{char}.txt", "brackets[char].txt", "parentheses(char).txt", "angle.txt", "ellipsis….txt", "accentué.txt", "ümlaut.txt", "tildeñ.txt", "çedilla.txt", "špecial.txt", "russianЯ.txt", "chinese中文.txt", "arabicعربى.txt", "hebrewעברית.txt", "japanese日本語.txt", "korean한국어.txt", "vietnameseTiếng Việt.txt", ] window.fsTests = [ { name: "testFSWrite", description: "Test writing text content to a new file and verify it returns a valid UID", test: async function() { try { let randName = puter.randName(); const result = await puter.fs.write(randName, 'testValue'); assert(result.uid, "Failed to write to file"); pass("testFSWrite passed"); // delete the file try { await puter.fs.delete(randName); } catch (error) { throw("testFSWrite failed to delete file:", error); } } catch (error) { if(puter.debugMode) console.log(error); throw("testFSWrite failed:", error); } } }, { name: "testFSRead", description: "Test reading text content from a file and verify it matches the written content", test: async function() { try { let randName = puter.randName(); await puter.fs.write(randName, 'testValue'); const result = await (await puter.fs.read(randName)).text(); assert(result === 'testValue', "Failed to read from file"); pass("testFSRead passed"); // delete the file try { await puter.fs.delete(randName); } catch (error) { fail("testFSRead failed to delete file:", error); } } catch (error) { fail("testFSRead failed:", error); } } }, { name: "testFSWriteWithoutData", description: "Test creating an empty file without providing content data", test: async function() { try { let randName = puter.randName(); const result = await puter.fs.write(randName); assert(result.uid, "Failed to write to file"); pass("testFSWriteWithoutData passed"); if(randName !== result.name) { fail(`testFSWriteWithoutData failed: Names do not match ${randName} ${result.name}`); } // delete the file try { await puter.fs.delete(randName); } catch (error) { fail("testFSWriteWithoutData failed to delete file:", error); } } catch (error) { fail("testFSWriteWithoutData failed:", error); } } }, { name: "testFSReadWithoutData", description: "Test reading from an empty file and verify it returns an empty string", test: async function() { try { let randName = puter.randName(); await puter.fs.write(randName); const result = await (await puter.fs.read(randName)).text(); assert(result === '', "Failed to read from file"); pass("testFSReadWithoutData passed"); // delete the file try { await puter.fs.delete(randName); } catch (error) { fail("testFSReadWithoutData failed to delete file:", error); } } catch (error) { fail("testFSReadWithoutData failed:", error); } } }, { name: "testFSWriteToExistingFile", description: "Test overwriting an existing file with new content", test: async function() { try { let randName = puter.randName(); await puter.fs.write(randName, 'testValue'); const result = await puter.fs.write(randName, 'updatedValue'); assert(result.uid, "Failed to write to file"); pass("testFSWriteToExistingFile passed"); // delete the file try { await puter.fs.delete(randName); } catch (error) { fail("testFSWriteToExistingFile failed to delete file:", error); } } catch (error) { fail("testFSWriteToExistingFile failed:", error); } } }, { name: "testFSWriteToExistingFileWithoutOverwriteAndDedupe", description: "Test writing to an existing file with overwrite and dedupe disabled - should fail", test: async function() { try { let randName = puter.randName(); await puter.fs.write(randName, 'testValue'); const result = await puter.fs.write(randName, 'updatedValue', { overwrite: false, dedupeName: false }); assert(!result.uid, "Failed to write to file"); fail("testFSWriteToExistingFileWithoutOverwriteAndDedupe failed"); // delete the file try { await puter.fs.delete(randName); } catch (error) { fail("testFSWriteToExistingFileWithoutOverwriteAndDedupe failed to delete file:", error); } } catch (error) { pass("testFSWriteToExistingFileWithoutOverwriteAndDedupe passed"); } } }, { name: "testFSWriteToExistingFileWithoutOverwriteButWithDedupe", description: "Test writing to an existing file with overwrite disabled but dedupe enabled - should create new file", test: async function() { try { let randName = puter.randName(); await puter.fs.write(randName, 'testValue'); const result = await puter.fs.write(randName, 'updatedValue', { overwrite: false, dedupeName: true }); assert(result.uid, "Failed to write to file"); pass("testFSWriteToExistingFileWithoutOverwriteButWithDedupe passed"); // delete the file try { await puter.fs.delete(randName); } catch (error) { fail("testFSWriteToExistingFileWithoutOverwriteButWithDedupe failed to delete file:", error); } } catch (error) { fail("testFSWriteToExistingFileWithoutOverwriteButWithDedupe failed:", error); } } }, { name: "testFSWriteToExistingFileWithOverwriteButWithoutDedupe", description: "Test writing to an existing file with overwrite enabled but dedupe disabled - should overwrite", test: async function() { try { let randName = puter.randName(); await puter.fs.write(randName, 'testValue'); const result = await puter.fs.write(randName, 'updatedValue', { overwrite: true, dedupeName: false }); assert(result.uid, "Failed to write to file"); pass("testFSWriteToExistingFileWithOverwriteButWithoutDedupe passed"); // delete the file try { await puter.fs.delete(randName); } catch (error) { fail("testFSWriteToExistingFileWithOverwriteButWithoutDedupe failed to delete file:", error); } } catch (error) { fail("testFSWriteToExistingFileWithOverwriteButWithoutDedupe failed:", error); } } }, { name: "testFSCreateDir", description: "Test creating a new directory and verify it returns a valid UID", test: async function() { try { let randName = puter.randName(); const result = await puter.fs.mkdir(randName); assert(result.uid, "Failed to create directory"); pass("testFSCreateDir passed"); } catch (error) { fail("testFSCreateDir failed:", error); } } }, { name: "testFSReadDir", description: "Test reading directory contents after creating multiple files within it", test: async function() { try { let randName = puter.randName(); await puter.fs.mkdir(randName); await puter.fs.write(randName + '/file1', 'testValue'); await puter.fs.write(randName + '/file2', 'testValue'); await puter.fs.write(randName + '/file3', 'testValue'); const result = await puter.fs.readdir(randName); assert(result.length === 3, "Failed to read directory"); pass("testFSReadDir passed"); } catch (error) { fail("testFSReadDir failed:", error); } } }, { name: "testFSDelete", description: "Test deleting a file and verify it no longer exists", test: async function() { try { let randName = puter.randName(); await puter.fs.write(randName, 'testValue'); const result = await puter.fs.delete(randName); assert(!result.uid, "Failed to delete file"); pass("testFSDelete passed"); } catch (error) { fail("testFSDelete failed:", error); } } }, { name: "testFSDeleteDir", description: "Test deleting a directory containing multiple files", test: async function() { try { let randName = puter.randName(); await puter.fs.mkdir(randName); await puter.fs.write(randName + '/file1', 'testValue'); await puter.fs.write(randName + '/file2', 'testValue'); await puter.fs.write(randName + '/file3', 'testValue'); const result = await puter.fs.delete(randName); assert(!result.uid, "Failed to delete directory"); pass("testFSDeleteDir passed"); } catch (error) { fail("testFSDeleteDir failed:", error); } } }, { name: "testFSDeleteNonExistentFile", description: "Test attempting to delete a non-existent file and verify it returns a valid response", test: async function() { try { let randName = puter.randName(); const result = await puter.fs.delete(randName); assert(!result.uid, "Failed to delete non-existent file"); pass("testFSDeleteNonExistentFile passed"); } catch (error) { if(error.code !== "subject_does_not_exist") fail("testFSDeleteNonExistentFile failed:", error); else pass("testFSDeleteNonExistentFile passed"); } } }, { name: "testFSReadNonExistentFile", description: "Test attempting to read from a non-existent file and verify it returns a valid response", test: async function() { try { let randName = puter.randName(); const result = await puter.fs.read(randName); fail("testFSReadNonExistentFile failed"); } catch (error) { if(error.code !== "subject_does_not_exist") fail("testFSReadNonExistentFile failed:", error); else pass("testFSReadNonExistentFile passed"); } } }, { name: "testFSWriteWithSpecialCharacters", description: "Test writing text content to a file with special characters and verify it returns a valid UID", test: async function() { let randName try { randName = 'testFileWithSpecialCharacte rs!@#$%^&*()_+{}|:"<>?`~' const result = await puter.fs.write(randName, 'testValue', { specialCharacters: true }); assert(result.uid, "Failed to write to file"); pass("testFSWriteWithSpecialCharacters passed"); } catch (error) { fail("testFSWriteWithSpecialCharacters failed:", error); } // delete the file try { await puter.fs.delete(randName); } catch (error) { fail("testFSWriteWithSpecialCharacters failed to delete file:", error); } } }, { name: "testFSReadWithSpecialCharacters", description: "Test reading text content from a file with special characters and verify it matches the written content", test: async function() { try { let randName = 'testFileWithSpecialCharacte rs!@#$%^&*()_+{}|:"<>?`~' await puter.fs.write(randName, 'testValue'); const result = await (await puter.fs.read(randName)).text(); assert(result === 'testValue', "Failed to read from file"); pass("testFSReadWithSpecialCharacters passed"); } catch (error) { fail("testFSReadWithSpecialCharacters failed:", error); } } }, { name: "testFSWriteLargeFile", description: "Test writing large text content to a file and verify it returns a valid UID", test: async function() { try { let randName = puter.randName(); const result = await puter.fs.write(randName, 'testValue'.repeat(100000)); assert(result.uid, "Failed to write to file"); pass("testFSWriteLargeFile passed"); } catch (error) { fail("testFSWriteLargeFile failed:", error); } } }, { name: "testFSReadLargeFile", description: "Test reading large text content from a file and verify it matches the written content", test: async function() { try { let randName = puter.randName(); await puter.fs.write(randName, 'testValue'.repeat(100000)); const result = await (await puter.fs.read(randName)).text(); assert(result === 'testValue'.repeat(100000), "Failed to read from file"); pass("testFSReadLargeFile passed"); } catch (error) { fail("testFSReadLargeFile failed:", error); } } }, { name: "testFSRenameFile", description: "Test renaming a file and verify the old file is gone", test: async function() { try { let randName = puter.randName(); let randName2 = puter.randName(); await puter.fs.write(randName, 'testValue'); const result = await puter.fs.rename(randName, randName2); assert(result.name, "Failed to rename file"); pass("testFSRenameFile passed"); // check that the old file is gone try { await puter.fs.read(randName); fail("testFSRenameFile failed to delete old file"); } catch (error) { if(error.code !== "subject_does_not_exist") fail("testFSRenameFile failed to delete old file:", error); else pass("testFSRenameFile passed"); } } catch (error) { fail("testFSRenameFile failed:", error); } } }, { name: "testFSMoveFile", description: "Test moving a file to a new directory and verify the old file is gone", test: async function() { try { let randName = puter.randName(); let randName2 = puter.randName(); await puter.fs.write(randName, 'testValue'); await puter.fs.mkdir(randName2); let result = await puter.fs.move(randName, randName2); assert(result.moved, "Failed to move file"); // check that the old file is gone try { await puter.fs.read(randName); fail("testFSMoveFile failed to delete old file"); } catch (error) { if(error.code !== "subject_does_not_exist") fail("testFSMoveFile failed to delete old file:", error); else pass("testFSMoveFile passed"); } } catch (error) { fail("testFSMoveFile failed:", error); } } }, { name: "testFSCopyFile", description: "Test copying a file to a new directory and verify the old file is still there", test: async function() { try { let randName = puter.randName(); let randName2 = puter.randName(); await puter.fs.write(randName, 'testValue'); await puter.fs.mkdir(randName2); let result = await puter.fs.copy(randName, randName2); assert(Array.isArray(result) && result[0].copied.uid, "Failed to copy file"); // check that the old file is still there try { await puter.fs.read(randName); pass("testFSCopyFile passed"); } catch (error) { fail("testFSCopyFile failed to keep old file:", error); } } catch (error) { fail("testFSCopyFile failed:", error); } } }, { name: "testFSCopyFileWithNewName", description: "Test copying a file to a new directory with a new name and verify the old file is still there", test: async function() { try { let randName = puter.randName(); let randName2 = puter.randName(); await puter.fs.write(randName, 'testValue'); await puter.fs.mkdir(randName2); let result = await puter.fs.copy(randName, randName2, { newName: 'newName' }); assert(Array.isArray(result) && result[0].copied.uid, "Failed to copy file"); // check file name assert(result[0].copied.name === 'newName', "Failed to copy file with new name"); // check that the old file is still there try { await puter.fs.read(randName); pass("testFSCopyFileWithNewName passed"); } catch (error) { fail("testFSCopyFileWithNewName failed to keep old file:", error); } } catch (error) { fail("testFSCopyFileWithNewName failed:", error); } } }, { name: "testFSStat", description: "Test getting file metadata and verify it returns a valid UID", test: async function() { try { let randName = puter.randName(); await puter.fs.write(randName, 'testValue'); let result = await puter.fs.stat(randName); assert(result.uid, "Failed to stat file"); pass("testFSStat passed"); } catch (error) { fail("testFSStat failed:", error); } } }, { name: "testFSStatDir", description: "Test getting directory metadata and verify it returns a valid UID", test: async function() { try { let randName = puter.randName(); await puter.fs.mkdir(randName); let result = await puter.fs.stat(randName); assert(result.uid, "Failed to stat directory"); pass("testFSStatDir passed"); } catch (error) { fail("testFSStatDir failed:", error); } } }, { name: "testFSStatNonExistent", description: "Test attempting to get metadata from a non-existent file or directory and verify it returns a valid response", test: async function() { try { let randName = puter.randName(); let result = await puter.fs.stat(randName); fail("testFSStatNonExistent failed"); } catch (error) { if(error.code !== "subject_does_not_exist") fail("testFSStatNonExistent failed:", error); else pass("testFSStatNonExistent passed"); } } }, { name: "testFSDeleteDirWithFiles", description: "Test deleting a directory containing multiple files and verify it no longer exists", test: async function() { try { let randName = puter.randName(); await puter.fs.mkdir(randName); await puter.fs.write(randName + '/file1', 'testValue'); await puter.fs.write(randName + '/file2', 'testValue'); await puter.fs.write(randName + '/file3', 'testValue'); const result = await puter.fs.delete(randName, { recursive: true }); assert(!result.uid, "Failed to delete directory"); pass("testFSDeleteDirWithFiles passed"); } catch (error) { fail("testFSDeleteDirWithFiles failed:", error); } } }, { name: "testFSStatDirReturnsAttrs", description: "Test getting directory metadata and verifying it returns the expected attributes", test: async function() { try { let randName = puter.randName(); await puter.fs.mkdir(randName); let result = await puter.fs.stat(randName); assert(result.name && typeof result.name === 'string', "Failed to stat directory (name)"); assert(result.path && typeof result.path === 'string', "Failed to stat directory (path)"); assert(result.immutable !== undefined, "Failed to stat directory (immutable)"); assert(result.metadata !== undefined, "Failed to stat directory (metadata)"); assert(result.modified !== undefined, "Failed to stat directory (modified)"); assert(result.created !== undefined, "Failed to stat directory (created)"); assert(result.accessed !== undefined, "Failed to stat directory (accessed)"); assert(result.size !== undefined, "Failed to stat directory (size)"); assert(result.layout !== undefined, "Failed to stat directory (layout)"); assert(result.owner !== undefined && typeof result.owner === 'object', "Failed to stat directory (owner)"); assert(result.dirname !== undefined && typeof result.dirname === 'string', "Failed to stat directory (dirname)"); assert(result.parent_id !== undefined && typeof result.parent_id === 'string', "Failed to stat directory (parent_id)"); // todo this will fail for now until is_dir is turned into boolean assert(result.is_dir !== undefined && typeof result.is_dir === 'boolean' && result.is_dir === true, "Failed to stat directory (is_dir)"); assert(result.is_empty !== undefined && typeof result.is_empty === 'boolean', "Failed to stat directory (is_empty)"); pass("testFSStatDirReturnsAttrs passed"); } catch (error) { throw("testFSStatDirReturnsAttrs failed:", error); } } }, { name: "testFSReadWithWriteResult", description: "Test reading text content from a file using the object returned by write()", test: async function() { try { let randName = puter.randName(); let writeResult = await puter.fs.write(randName, 'testValue'); let result = await (await puter.fs.read(writeResult)).text(); assert(result === 'testValue', "Failed to read from file"); pass("testFSReadWithWriteResult passed"); // delete the file try { await puter.fs.delete(randName); } catch (error) { fail("testFSReadWithWriteResult failed to delete file:", error); } } catch (error) { fail("testFSReadWithWriteResult failed:", error); } } }, { name: "testFSStatWithWriteResult", description: "Test getting file metadata using the object returned by write()", test: async function() { try { let randName = puter.randName(); let writeResult = await puter.fs.write(randName, 'testValue'); let result = await puter.fs.stat(writeResult); assert(result.uid, "Failed to stat file"); pass("testFSStatWithWriteResult passed"); // delete the file try { await puter.fs.delete(randName); } catch (error) { fail("testFSStatWithWriteResult failed to delete file:", error); } } catch (error) { fail("testFSStatWithWriteResult failed:", error); } } }, { name: "testFSWriteWithNaughtyStrings", description: "Test writing text content to files with names from naughtyStrings and verify it returns a valid UID", test: async function() { try { let randName = puter.randName(); for(let i = 0; i < naughtyStrings.length; i++) { let filename = randName + naughtyStrings[i]; let result = await puter.fs.write(filename, 'testValue'); assert(result.uid, "Failed to write to file"); // check name assert(result.name === filename, "Failed to write to file with naughty name: " + filename); // delete the file try { await puter.fs.delete(filename); } catch (error) { fail("testFSWriteWithNaughtyStrings failed to delete file: " + filename, error); } } pass("testFSWriteWithNaughtyStrings passed"); } catch (error) { console.log(error); fail("testFSWriteWithNaughtyStrings failed:", error); } } }, { name: "testFSWriteReadBinaryFile", description: "Test writing and reading binary file data and verify it remains intact", test: async function() { try { let randName = puter.randName() + '.webp'; // Create some binary data - a simple byte array representing a small binary file const binaryData = new Uint8Array([ 0x52, 0x49, 0x46, 0x46, 0x24, 0x00, 0x00, 0x00, 0x57, 0x45, 0x42, 0x50, 0x56, 0x50, 0x38, 0x20, 0x18, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x9D, 0x01, 0x2A, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x34, 0x25, 0xA4, 0x00, 0x03, 0x70, 0x00, 0xFE, 0xFB, 0xFD, 0x50, 0x00 ]); // Write the binary data to a file const writeResult = await puter.fs.write(randName, binaryData); assert(writeResult.uid, "Failed to write binary file"); // Read the binary data back const readResult = await puter.fs.read(randName); const readBinaryData = new Uint8Array(await readResult.arrayBuffer()); // Verify the binary data is identical assert(readBinaryData.length === binaryData.length, "Binary data length mismatch"); for (let i = 0; i < binaryData.length; i++) { assert(readBinaryData[i] === binaryData[i], `Binary data mismatch at byte ${i}: expected ${binaryData[i]}, got ${readBinaryData[i]}`); } pass("testFSWriteReadBinaryFile passed"); // Clean up - delete the test file try { await puter.fs.delete(randName); } catch (error) { fail("testFSWriteReadBinaryFile failed to delete file:", error); } } catch (error) { fail("testFSWriteReadBinaryFile failed:", error); } } }, { name: "testFSAppDirectoryIsolation", description: "Test that filesystem operations are properly sandboxed to the app directory and cannot access files outside of it", test: async function() { try { // Test 1: Try to access parent directory with ../ try { await puter.fs.readdir('~/Desktop'); fail("testFSAppDirectoryIsolation failed: Should not be able to read Desktop directory"); } catch (error) { if (error.code !== "subject_does_not_exist") { fail("testFSAppDirectoryIsolation failed: Wrong error code for Desktop directory access: " + error.code); } } // Test 2: Try to access absolute path outside app directory try { await puter.fs.read('/some/absolute/path.txt'); fail("testFSAppDirectoryIsolation failed: Should not be able to read absolute paths"); } catch (error) { if (error.code !== "access_denied" && error.code !== "invalid_path" && error.code !== "subject_does_not_exist") { fail("testFSAppDirectoryIsolation failed: Wrong error code for absolute path access: " + error.code); } } // Test 3: Try to write outside app directory try { await puter.fs.write('../escape_file.txt', 'should not work'); fail("testFSAppDirectoryIsolation failed: Should not be able to write outside app directory"); } catch (error) { if (error.code !== "subject_does_not_exist") { fail("testFSAppDirectoryIsolation failed: Wrong error code for writing outside directory: " + error.code); } } // Test 4: Try to create directory outside app directory try { await puter.fs.mkdir('../escape_dir'); fail("testFSAppDirectoryIsolation failed: Should not be able to create directory outside app directory"); } catch (error) { if (error.code !== "subject_does_not_exist") { fail("testFSAppDirectoryIsolation failed: Wrong error code for creating directory outside: " + error.code); } } // Test 5: Try to access home directory directly try { await puter.fs.read('~/some_file.txt'); fail("testFSAppDirectoryIsolation failed: Should not be able to read from home directory"); } catch (error) { if (error.code !== "access_denied" && error.code !== "invalid_path" && error.code !== "subject_does_not_exist") { fail("testFSAppDirectoryIsolation failed: Wrong error code for home directory access: " + error.code); } } pass("testFSAppDirectoryIsolation passed"); } catch (error) { fail("testFSAppDirectoryIsolation failed:", error); } } }, ];