diff --git a/.env.local.default b/.env.local.default index 65b64b68b7..cd3663302a 100644 --- a/.env.local.default +++ b/.env.local.default @@ -31,6 +31,7 @@ VITE_APP_HOST=localhost VITE_APP_PORT=3000 # Use following value for minio s3 provider VITE_FILE_SERVER=https://localhost:9000/etherealengine-static-resources +VITE_TEST_FILE_SERVER=https://localhost:9000/etherealengine-static-resources-test # Use following value for local file server #VITE_FILE_SERVER=https://localhost:8642 VITE_SERVER_HOST=localhost diff --git a/packages/common/src/config.ts b/packages/common/src/config.ts index 2f469d7fae..63921ab7cb 100644 --- a/packages/common/src/config.ts +++ b/packages/common/src/config.ts @@ -61,7 +61,10 @@ const client = { localBuildOrDev && globalThis.process.env['VITE_LOCAL_NGINX'] !== 'true' ? `https://${globalThis.process.env['VITE_INSTANCESERVER_HOST']}:${globalThis.process.env['VITE_INSTANCESERVER_PORT']}` : `https://${globalThis.process.env['VITE_INSTANCESERVER_HOST']}`, - fileServer: globalThis.process.env['VITE_FILE_SERVER'] ?? 'https://localhost:8642', + fileServer: + globalThis.process.env['TEST'] === 'true' + ? globalThis.process.env['VITE_TEST_FILE_SERVER'] + : globalThis.process.env['VITE_FILE_SERVER'] ?? 'https://localhost:8642', mediatorServer: globalThis.process.env['VITE_MEDIATOR_SERVER'], cors: { proxyUrl: diff --git a/packages/server-core/package.json b/packages/server-core/package.json index 73d4bae932..c64cd7fe49 100755 --- a/packages/server-core/package.json +++ b/packages/server-core/package.json @@ -139,4 +139,4 @@ "@types/pug": "2.0.6" }, "gitHead": "2313453697ca7c6b8d36b3b166b5a6445fe1c851" -} +} \ No newline at end of file diff --git a/packages/server-core/src/media/file-browser/file-browser.test.ts b/packages/server-core/src/media/file-browser/file-browser.test.ts index 10b677bd97..fb58f2b152 100644 --- a/packages/server-core/src/media/file-browser/file-browser.test.ts +++ b/packages/server-core/src/media/file-browser/file-browser.test.ts @@ -24,22 +24,11 @@ Ethereal Engine. All Rights Reserved. */ import assert from 'assert' -import fs from 'fs' -import path from 'path/posix' import { destroyEngine } from '@etherealengine/engine/src/ecs/classes/Engine' import { Application } from '../../../declarations' -import config from '../../appconfig' import { createFeathersKoaApp } from '../../createApp' -import LocalStorage from '../storageprovider/local.storage' -import { getStorageProvider } from '../storageprovider/storageprovider' -import { projectsRootFolder } from './file-browser.class' - -const TEST_PROJECT = 'test-project' -const PROJECT_PATH = path.join(projectsRootFolder, TEST_PROJECT) -let STORAGE_PATH = '' -let STORAGE_ROOT = '' const getRandomizedName = (name: string, suffix = '', prefix = 'test') => `${prefix}-${name}-${(Math.random() + 1).toString(36).substring(7)}${suffix}` @@ -48,506 +37,221 @@ const getRandomizedName = (name: string, suffix = '', prefix = 'test') => const getDirectoryPath = (name: string) => name + '/' describe('file browser service', () => { - describe('s3 storage provider', () => { - let app: Application - before(async () => { - config.server.storageProvider = 's3' - app = createFeathersKoaApp() - await app.setup() - }) - after(() => { - return destroyEngine() - }) - - it('should register the service', () => { - const service = app.service('file-browser') - assert.ok(service, 'Registered the service') - }) - - it('find service', () => { - assert.doesNotThrow(async () => await app.service('file-browser').find()) - }) - - let testDirectoryName: string - it('creates a directory', async () => { - testDirectoryName = getRandomizedName('directory') + let app: Application + before(async () => { + app = createFeathersKoaApp() + await app.setup() + }) + after(() => { + return destroyEngine() + }) - const createdDirectory = await app.service('file-browser').create(testDirectoryName) - assert.ok(createdDirectory) - }) + it('should register the service', () => { + const service = app.service('file-browser') + assert.ok(service, 'Registered the service') + }) - it('gets the directory', async () => { - const foundDirectories = await app.service('file-browser').get(getDirectoryPath(testDirectoryName)) - assert.equal(foundDirectories.total, 0) - }) + it('find service', () => { + assert.doesNotThrow(async () => await app.service('file-browser').find()) + }) - let testFileFullName: string - let testFileName: string - it('creates a file', async () => { - testFileFullName = getRandomizedName('file', '.txt') - testFileName = testFileFullName.split('.')[0] + let testDirectoryName: string + it('creates a directory', async () => { + testDirectoryName = getRandomizedName('directory') - const newData = getRandomizedName('new data') + const createdDirectory = await app.service('file-browser').create(testDirectoryName) + assert.ok(createdDirectory) + }) - const createdURL = await app.service('file-browser').patch(null, { - fileName: testFileFullName, - path: testDirectoryName, - body: Buffer.from(newData, 'utf-8'), - contentType: 'any' - }) + it('gets the directory', async () => { + const foundDirectories = await app.service('file-browser').get(getDirectoryPath(testDirectoryName)) + assert.equal(foundDirectories.total, 0) + }) - assert.ok(createdURL) - }) + let testFileFullName: string + let testFileName: string + it('creates a file', async () => { + testFileFullName = getRandomizedName('file', '.txt') + testFileName = testFileFullName.split('.')[0] - it('gets the file', async () => { - const directoryContents = await app.service('file-browser').get(getDirectoryPath(testDirectoryName)) - const foundFile = directoryContents.data.find((file) => file.key.match(testFileFullName)) + const newData = getRandomizedName('new data') - assert.ok(foundFile) + const createdURL = await app.service('file-browser').patch(null, { + fileName: testFileFullName, + path: testDirectoryName, + body: Buffer.from(newData, 'utf-8'), + contentType: 'any' }) - describe('update service', () => { - let testDirectoryName2: string - let testFileName2: string - let testFileName3: string - before(async () => { - testDirectoryName2 = getRandomizedName('directory2') - - testFileName2 = getRandomizedName('file2', '.md') - const newData2 = getRandomizedName('new data 2') - - await app.service('file-browser').patch(null, { - fileName: testFileName2, - path: testDirectoryName2, - body: Buffer.from(newData2, 'utf-8'), - contentType: 'any' - }) - - testFileName3 = getRandomizedName('file3', '.mdx') - const newData3 = getRandomizedName('new data 3') - - await app.service('file-browser').patch(null, { - fileName: testFileName3, - path: testDirectoryName2, - body: Buffer.from(newData3, 'utf-8'), - contentType: 'any' - }) - }) - - it('copies file', async () => { - const copyFileResult = await app.service('file-browser').update(null, { - oldName: testFileName2, - newName: testFileName2, - oldPath: getDirectoryPath(testDirectoryName2), - newPath: getDirectoryPath(testDirectoryName), - isCopy: true - }) - - assert.ok(Array.isArray(copyFileResult) ? copyFileResult.length > 0 : copyFileResult) - - const directoryContents = await app.service('file-browser').get(getDirectoryPath(testDirectoryName)) - const foundFile = directoryContents.data.find((file) => file.key.match(testFileName2)) - - assert.ok(foundFile) - }) - - it('copies directory', async () => { - const copyDirectoryResult = await app.service('file-browser').update(null, { - oldName: testDirectoryName, - newName: testDirectoryName, - oldPath: '', - newPath: testDirectoryName2, - isCopy: true - }) - - assert.ok(Array.isArray(copyDirectoryResult) ? copyDirectoryResult.length > 0 : copyDirectoryResult) - - const directoryContents = await app.service('file-browser').get(getDirectoryPath(testDirectoryName2)) - const foundDirectory = directoryContents.data.find((dir) => dir.name.match(testDirectoryName)) - assert.ok(foundDirectory) - }) - - it('moves file', async () => { - const moveFileResult = await app.service('file-browser').update(null, { - oldName: testFileName3, - newName: testFileName3, - oldPath: getDirectoryPath(testDirectoryName2), - newPath: getDirectoryPath(testDirectoryName) - }) - - assert.ok(Array.isArray(moveFileResult) ? moveFileResult.length > 0 : moveFileResult) - - const toMovedDirectoryContents = await app.service('file-browser').get(getDirectoryPath(testDirectoryName)) - const foundFile = toMovedDirectoryContents.data.find((file) => file.key.match(testFileName3)) - - assert.ok(foundFile) + assert.ok(createdURL) + }) - const fromMovedDirectoryContents = await app.service('file-browser').get(getDirectoryPath(testDirectoryName2)) - const notFoundFile = fromMovedDirectoryContents.data.find((file) => file.key.match(testFileName3)) - assert.ok(!notFoundFile) - }) + it('gets the file', async () => { + const directoryContents = await app.service('file-browser').get(getDirectoryPath(testDirectoryName)) + const foundFile = directoryContents.data.find((file) => file.key.match(testFileFullName)) - it('moves directory', async () => { - const copyDirectoryResult = await app.service('file-browser').update(null, { - oldName: testDirectoryName2, - newName: testDirectoryName2, - oldPath: '', - newPath: testDirectoryName - }) + assert.ok(foundFile) + }) - assert.ok(Array.isArray(copyDirectoryResult) ? copyDirectoryResult.length > 0 : copyDirectoryResult) + describe('update service', () => { + let testDirectoryName2: string + let testFileName2: string + let testFileName3: string + before(async () => { + testDirectoryName2 = getRandomizedName('directory2') - const directoryContents = await app.service('file-browser').get(getDirectoryPath(testDirectoryName)) - const toMovedDirectoryContents = directoryContents.data.find((dir) => dir.name.match(testDirectoryName2)) - assert.ok(toMovedDirectoryContents) + testFileName2 = getRandomizedName('file2', '.md') + const newData2 = getRandomizedName('new data 2') - const fromMovedDirectoryContents = await app.service('file-browser').get('/') - const notFoundDirectory = fromMovedDirectoryContents.data.find((dir) => dir.name.match(testDirectoryName2)) - assert.ok(!notFoundDirectory) + await app.service('file-browser').patch(null, { + fileName: testFileName2, + path: testDirectoryName2, + body: Buffer.from(newData2, 'utf-8'), + contentType: 'any' }) - it('increment file name if file already exists', async () => { - const copyDirectoryResult = await app.service('file-browser').update(null, { - oldName: testFileFullName, - newName: testFileFullName, - oldPath: testDirectoryName, - newPath: testDirectoryName, - isCopy: true - }) - - assert.ok(Array.isArray(copyDirectoryResult) ? copyDirectoryResult.length > 0 : copyDirectoryResult) - - const directoryContents = await app.service('file-browser').get(getDirectoryPath(testDirectoryName)) - const foundIncrementedFile = directoryContents.data.filter( - (file) => file.name.match(testFileName) && file.name.match('(1)') - ) + testFileName3 = getRandomizedName('file3', '.mdx') + const newData3 = getRandomizedName('new data 3') - assert.equal(foundIncrementedFile.length, 1) - }) - - it('updates file with new content', async () => { - const newData = getRandomizedName('new data 2 updated') - const updateResult = await app.service('file-browser').patch(null, { - fileName: testFileName2, - path: testDirectoryName, - body: Buffer.from(newData, 'utf-8'), - contentType: 'any' - }) - assert.ok(updateResult) - - const testDirectoryContents = await app.service('file-browser').get(getDirectoryPath(testDirectoryName)) - const updatedFile = testDirectoryContents.data.find((file) => file.key.match(testFileName2)) - assert.ok(updatedFile) + await app.service('file-browser').patch(null, { + fileName: testFileName3, + path: testDirectoryName2, + body: Buffer.from(newData3, 'utf-8'), + contentType: 'any' }) }) - describe('remove service', () => { - it('removes file', async () => { - let directoryContents = await app.service('file-browser').get(getDirectoryPath(testDirectoryName)) - let foundFile = directoryContents.data.find((file) => file.key.match(testFileFullName)) - assert.ok(foundFile) - const removeResult = await app.service('file-browser').remove(foundFile.key) - assert.ok(removeResult) - - directoryContents = await app.service('file-browser').get(getDirectoryPath(testDirectoryName)) - foundFile = directoryContents.data.find((file) => file.key.match(testFileFullName)) - assert.ok(!foundFile) + it('copies file', async () => { + const copyFileResult = await app.service('file-browser').update(null, { + oldName: testFileName2, + newName: testFileName2, + oldPath: getDirectoryPath(testDirectoryName2), + newPath: getDirectoryPath(testDirectoryName), + isCopy: true }) - it('removes directory', async () => { - let directoryContents = await app.service('file-browser').get('/') - let foundDirectory = directoryContents.data.find((dir) => dir.key.match(testDirectoryName)) - assert.ok(foundDirectory) - - const removeResult = await app.service('file-browser').remove(testDirectoryName) - assert.ok(removeResult) - - directoryContents = await app.service('file-browser').get('/') - foundDirectory = directoryContents.data.find((dir) => dir.key.match(testDirectoryName)) - assert.ok(!foundDirectory) - }) - }) - }) - - describe('local storage provider', () => { - let app: Application - before(async () => { - config.server.storageProvider = 'local' - app = createFeathersKoaApp() - await app.setup() - - STORAGE_ROOT = (getStorageProvider() as LocalStorage).PATH_PREFIX - STORAGE_PATH = path.join(STORAGE_ROOT, TEST_PROJECT) - - if (fs.existsSync(PROJECT_PATH)) fs.rmSync(PROJECT_PATH, { force: true, recursive: true }) - if (fs.existsSync(STORAGE_PATH)) fs.rmSync(STORAGE_PATH, { force: true, recursive: true }) - - fs.mkdirSync(PROJECT_PATH) - fs.mkdirSync(STORAGE_PATH) - }) - after(() => { - return destroyEngine() - }) + assert.ok(Array.isArray(copyFileResult) ? copyFileResult.length > 0 : copyFileResult) - it('should register the service', async () => { - const service = app.service('file-browser') - assert.ok(service, 'Registered the service') - }) - - it('find service', () => { - assert.doesNotThrow(async () => await app.service('file-browser').find()) - }) - - it('gets directory content list', async () => { - const dirName = 'Get_Dir_Content_Test_' + Math.round(Math.random() * 100) - const dirStoragePath = path.join(STORAGE_PATH, dirName) - - fs.mkdirSync(dirStoragePath) - - const fileNames = [ - 'Get_Dir_Content_Test_File_1.txt', - 'Get_Dir_Content_Test_File_2.txt', - 'Get_Dir_Content_Test_File_3.txt', - 'Get_Dir_Content_Test_File_4.txt', - 'Get_Dir_Content_Test_File_5.txt' - ] - fileNames.forEach((n) => fs.writeFileSync(path.join(dirStoragePath, n), 'Hello world')) - - let result = await app.service('file-browser').get(path.join(TEST_PROJECT, dirName)) - result.data.forEach((r, i) => assert(r && r.key === path.join(TEST_PROJECT, dirName, fileNames[i]))) - - // If name starts with '/' - result = await app.service('file-browser').get('/' + path.join(TEST_PROJECT, dirName)) - result.data.forEach((r, i) => assert(r && r.key === path.join(TEST_PROJECT, dirName, fileNames[i]))) + const directoryContents = await app.service('file-browser').get(getDirectoryPath(testDirectoryName)) + const foundFile = directoryContents.data.find((file) => file.key.match(testFileName2)) - fs.rmSync(dirStoragePath, { force: true, recursive: true }) + assert.ok(foundFile) }) - it('create project directory service', async () => { - const dirName = 'Test_Project_' + Math.round(Math.random() * 100) - let result = await app.service('file-browser').create(dirName) - - assert(result) - - assert(fs.existsSync(path.join(STORAGE_ROOT, dirName))) - - fs.rmdirSync(path.join(STORAGE_ROOT, dirName)) - - // If name starts with '/' - result = await app.service('file-browser').create('/' + dirName) + it('copies directory', async () => { + const copyDirectoryResult = await app.service('file-browser').update(null, { + oldName: testDirectoryName, + newName: testDirectoryName, + oldPath: '', + newPath: testDirectoryName2, + isCopy: true + }) - assert(result) - assert(fs.existsSync(path.join(STORAGE_ROOT, dirName))) + assert.ok(Array.isArray(copyDirectoryResult) ? copyDirectoryResult.length > 0 : copyDirectoryResult) - fs.rmdirSync(path.join(STORAGE_ROOT, dirName)) + const directoryContents = await app.service('file-browser').get(getDirectoryPath(testDirectoryName2)) + const foundDirectory = directoryContents.data.find((dir) => dir.name.match(testDirectoryName)) + assert.ok(foundDirectory) }) - describe('update service', () => { - it('copies file', async () => { - const fileName = 'Update_Service_Copy_File_Test_' + Math.round(Math.random() * 100) + '.txt' - const newFileName = 'Update_Service_Copy_File_Test_' + Math.round(Math.random() * 1000) + '.txt' - fs.writeFileSync(path.join(STORAGE_PATH, fileName), 'Hello world') - - const result = await app.service('file-browser').update(null, { - oldName: fileName, - newName: newFileName, - oldPath: TEST_PROJECT, - newPath: TEST_PROJECT, - isCopy: true - }) - - assert(result) - - assert(fs.existsSync(path.join(STORAGE_PATH, fileName)), 'Old file should not be removed on copy') - - assert(fs.existsSync(path.join(STORAGE_PATH, newFileName))) - - fs.unlinkSync(path.join(STORAGE_PATH, fileName)) - fs.unlinkSync(path.join(STORAGE_PATH, newFileName)) + it('moves file', async () => { + const moveFileResult = await app.service('file-browser').update(null, { + oldName: testFileName3, + newName: testFileName3, + oldPath: getDirectoryPath(testDirectoryName2), + newPath: getDirectoryPath(testDirectoryName) }) - it('copies directory', async () => { - const dir = 'Update_Service_Copy_Dir_' + Math.round(Math.random() * 100) - const newDirName = 'Update_Service_Copy_Dir_' + Math.round(Math.random() * 1000) + '.txt' - const fileName = 'Update_Service_Copy_Dir_Test_File_' + Math.round(Math.random() * 100) + '.txt' - - const dirStoragePath = path.join(STORAGE_PATH, dir) - const dirFileStoragePath = path.join(dirStoragePath, fileName) - const nweDirStoragePath = path.join(STORAGE_PATH, newDirName) - - fs.mkdirSync(dirStoragePath) - fs.writeFileSync(dirFileStoragePath, 'Hello world') - - const result = await app.service('file-browser').update(null, { - oldName: dir, - newName: newDirName, - oldPath: TEST_PROJECT, - newPath: TEST_PROJECT, - isCopy: true - }) + assert.ok(Array.isArray(moveFileResult) ? moveFileResult.length > 0 : moveFileResult) - assert(result) + const toMovedDirectoryContents = await app.service('file-browser').get(getDirectoryPath(testDirectoryName)) + const foundFile = toMovedDirectoryContents.data.find((file) => file.key.match(testFileName3)) - assert(fs.existsSync(dirStoragePath), 'Old directory should not be removed on copy') - assert(fs.existsSync(dirFileStoragePath), 'Old file should not be removed on copy') + assert.ok(foundFile) - assert(fs.existsSync(nweDirStoragePath) && fs.lstatSync(nweDirStoragePath).isDirectory()) - assert(fs.existsSync(path.join(nweDirStoragePath, fileName))) + const fromMovedDirectoryContents = await app.service('file-browser').get(getDirectoryPath(testDirectoryName2)) + const notFoundFile = fromMovedDirectoryContents.data.find((file) => file.key.match(testFileName3)) + assert.ok(!notFoundFile) + }) - fs.rmSync(dirStoragePath, { force: true, recursive: true }) - fs.rmSync(nweDirStoragePath, { force: true, recursive: true }) + it('moves directory', async () => { + const copyDirectoryResult = await app.service('file-browser').update(null, { + oldName: testDirectoryName2, + newName: testDirectoryName2, + oldPath: '', + newPath: testDirectoryName }) - it('moves file', async () => { - const fileName = 'Update_Service_Move_File_Test+' + Math.round(Math.random() * 100) + '.txt' - const newFileName = 'Update_Service_Move_File_Test_' + Math.round(Math.random() * 1000) + '.txt' - fs.writeFileSync(path.join(STORAGE_PATH, fileName), 'Hello world') - - const result = await app.service('file-browser').update(null, { - oldName: fileName, - newName: newFileName, - oldPath: TEST_PROJECT, - newPath: TEST_PROJECT - }) - - assert(result) + assert.ok(Array.isArray(copyDirectoryResult) ? copyDirectoryResult.length > 0 : copyDirectoryResult) - assert(!fs.existsSync(path.join(STORAGE_PATH, fileName)), 'Old file should not exist on move') + const directoryContents = await app.service('file-browser').get(getDirectoryPath(testDirectoryName)) + const toMovedDirectoryContents = directoryContents.data.find((dir) => dir.name.match(testDirectoryName2)) + assert.ok(toMovedDirectoryContents) - assert(fs.existsSync(path.join(STORAGE_PATH, newFileName))) + const fromMovedDirectoryContents = await app.service('file-browser').get('/') + const notFoundDirectory = fromMovedDirectoryContents.data.find((dir) => dir.name.match(testDirectoryName2)) + assert.ok(!notFoundDirectory) + }) - fs.unlinkSync(path.join(STORAGE_PATH, newFileName)) + it('increment file name if file already exists', async () => { + const copyDirectoryResult = await app.service('file-browser').update(null, { + oldName: testFileFullName, + newName: testFileFullName, + oldPath: testDirectoryName, + newPath: testDirectoryName, + isCopy: true }) - it('moves directory', async () => { - const dir = 'Update_Service_Move_Dir_' + Math.round(Math.random() * 100) - const newDirName = 'Update_Service_Move_Dir_' + Math.round(Math.random() * 1000) + '.txt' - const fileName = 'Update_Service_Move_Dir_Test_File_' + Math.round(Math.random() * 100) + '.txt' - - const dirStoragePath = path.join(STORAGE_PATH, dir) - const dirFileStoragePath = path.join(dirStoragePath, fileName) - const nweDirStoragePath = path.join(STORAGE_PATH, newDirName) + assert.ok(Array.isArray(copyDirectoryResult) ? copyDirectoryResult.length > 0 : copyDirectoryResult) - fs.mkdirSync(dirStoragePath) - fs.writeFileSync(dirFileStoragePath, 'Hello world') - - const result = await app.service('file-browser').update(null, { - oldName: dir, - newName: newDirName, - oldPath: TEST_PROJECT, - newPath: TEST_PROJECT - }) - - assert(result) - - assert(!fs.existsSync(dirStoragePath), 'Old directory should not exists on Move') - assert(!fs.existsSync(dirFileStoragePath), 'Old file should not exists on Move') - - assert(fs.existsSync(nweDirStoragePath) && fs.lstatSync(nweDirStoragePath).isDirectory()) - assert(fs.existsSync(path.join(nweDirStoragePath, fileName))) - - fs.rmSync(nweDirStoragePath, { force: true, recursive: true }) - }) + const directoryContents = await app.service('file-browser').get(getDirectoryPath(testDirectoryName)) + const foundIncrementedFile = directoryContents.data.filter( + (file) => file.name.match(testFileName) && file.name.match('(1)') + ) - it('increment file name if file already exists', async () => { - const fileName = 'Update_Service_File_Name_Increment_Test.txt' - const incrementedFileName = 'Update_Service_File_Name_Increment_Test(1).txt' - const incrementedFileName_2 = 'Update_Service_File_Name_Increment_Test(2).txt' - fs.writeFileSync(path.join(STORAGE_PATH, fileName), 'Hello world') - - const result = await app.service('file-browser').update(null, { - oldName: fileName, - newName: fileName, - oldPath: TEST_PROJECT, - newPath: TEST_PROJECT, - isCopy: true - }) - - assert(result) - - assert(fs.existsSync(path.join(STORAGE_PATH, incrementedFileName))) - - await app.service('file-browser').update(null, { - oldName: fileName, - newName: fileName, - oldPath: TEST_PROJECT, - newPath: TEST_PROJECT, - isCopy: true - }) - - assert(fs.existsSync(path.join(STORAGE_PATH, incrementedFileName_2))) - - fs.unlinkSync(path.join(STORAGE_PATH, fileName)) - fs.unlinkSync(path.join(STORAGE_PATH, incrementedFileName)) - fs.unlinkSync(path.join(STORAGE_PATH, incrementedFileName_2)) - }) + assert.equal(foundIncrementedFile.length, 1) }) - it('patch file with new data', async () => { - const fileName = 'Patch_Service_File_Test_' + Math.round(Math.random() * 100) + '.txt' - const fileStoragePath = path.join(STORAGE_PATH, fileName) - const newData = 'New Data ' + Math.random() - - fs.writeFileSync(fileStoragePath, 'Hello world') - - const result = await app.service('file-browser').patch(null, { - fileName, - path: TEST_PROJECT, + it('updates file with new content', async () => { + const newData = getRandomizedName('new data 2 updated') + const updateResult = await app.service('file-browser').patch(null, { + fileName: testFileName2, + path: testDirectoryName, body: Buffer.from(newData, 'utf-8'), contentType: 'any' }) + assert.ok(updateResult) - assert.equal(result, `https://${getStorageProvider().cacheDomain}/${path.join(TEST_PROJECT, fileName)}`) - - assert(fs.existsSync(fileStoragePath)) - - assert.equal(fs.readFileSync(fileStoragePath).toString(), newData) - - fs.unlinkSync(path.join(STORAGE_PATH, fileName)) + const testDirectoryContents = await app.service('file-browser').get(getDirectoryPath(testDirectoryName)) + const updatedFile = testDirectoryContents.data.find((file) => file.key.match(testFileName2)) + assert.ok(updatedFile) }) + }) - describe('remove service', () => { - it('removes file', async () => { - const fileName = 'Remove_Service_File_Test_' + Math.round(Math.random() * 100) + '.txt' - const fileStoragePath = path.join(STORAGE_PATH, fileName) - - fs.writeFileSync(fileStoragePath, 'Hello world') - - const result = await app.service('file-browser').remove(path.join(TEST_PROJECT, fileName)) - - result.forEach((r) => assert(r)) - - assert(!fs.existsSync(fileStoragePath)) - }) - - it('removes dir recursively', async () => { - const dirName = 'Remove_Service_Dir_Test_' + Math.round(Math.random() * 100) + '.txt' - const fileName = 'Remove_Service_Dir_File_Test_' + Math.round(Math.random() * 100) + '.txt' - const subdirName = 'Remove_Service_Dir_Subdir_Test_' + Math.round(Math.random() * 100) - const dirStoragePath = path.join(STORAGE_PATH, dirName) - - fs.mkdirSync(dirStoragePath) - - fs.mkdirSync(path.join(dirStoragePath, subdirName)) - - fs.writeFileSync(path.join(dirStoragePath, fileName), 'Hello world') - - fs.writeFileSync(path.join(dirStoragePath, subdirName, fileName), 'Hello world sub directory') + describe('remove service', () => { + it('removes file', async () => { + let directoryContents = await app.service('file-browser').get(getDirectoryPath(testDirectoryName)) + let foundFile = directoryContents.data.find((file) => file.key.match(testFileFullName)) + assert.ok(foundFile) + const removeResult = await app.service('file-browser').remove(foundFile.key) + assert.ok(removeResult) - const result = await app.service('file-browser').remove(path.join(TEST_PROJECT, dirName)) + directoryContents = await app.service('file-browser').get(getDirectoryPath(testDirectoryName)) + foundFile = directoryContents.data.find((file) => file.key.match(testFileFullName)) + assert.ok(!foundFile) + }) - result.forEach((r) => assert(r)) + it('removes directory', async () => { + let directoryContents = await app.service('file-browser').get('/') + let foundDirectory = directoryContents.data.find((dir) => dir.key.match(testDirectoryName)) + assert.ok(foundDirectory) - assert(!fs.existsSync(dirStoragePath)) - assert(!fs.existsSync(path.join(dirStoragePath, subdirName))) - assert(!fs.existsSync(path.join(dirStoragePath, subdirName, fileName))) - assert(!fs.existsSync(path.join(dirStoragePath, fileName))) - }) - }) + const removeResult = await app.service('file-browser').remove(testDirectoryName) + assert.ok(removeResult) - after(() => { - fs.rmSync(PROJECT_PATH, { force: true, recursive: true }) - fs.rmSync(STORAGE_PATH, { force: true, recursive: true }) + directoryContents = await app.service('file-browser').get('/') + foundDirectory = directoryContents.data.find((dir) => dir.key.match(testDirectoryName)) + assert.ok(!foundDirectory) }) }) }) diff --git a/packages/server-core/src/media/storageprovider/local.storage.ts b/packages/server-core/src/media/storageprovider/local.storage.ts index 3715aab781..51b97d07ee 100755 --- a/packages/server-core/src/media/storageprovider/local.storage.ts +++ b/packages/server-core/src/media/storageprovider/local.storage.ts @@ -259,7 +259,7 @@ export class LocalStorage implements StorageProviderInterface { */ getSignedUrl = (key: string, _expiresAfter: number, _conditions): any => { return { - fields: { Key: key }, + fields: { key }, url: `https://${this.cacheDomain}`, local: true, cacheDomain: this.cacheDomain diff --git a/packages/server-core/src/media/storageprovider/s3.storage.ts b/packages/server-core/src/media/storageprovider/s3.storage.ts index 3f74450132..83ab941ef7 100755 --- a/packages/server-core/src/media/storageprovider/s3.storage.ts +++ b/packages/server-core/src/media/storageprovider/s3.storage.ts @@ -324,7 +324,9 @@ export class S3Provider implements StorageProviderInterface { reject(err) } } else if (config.aws.s3.s3DevMode === 'local') { - const response = await this.minioClient?.putObject(args.Bucket, args.Key, args.Body) + const response = await this.minioClient?.putObject(args.Bucket, args.Key, args.Body, { + 'Content-Type': args.ContentType + }) return response } else if (data.Body.length > MULTIPART_CUTOFF_SIZE) { const multiPartStartArgs = { diff --git a/packages/server-core/tests/storageprovider/storageprovider.test.ts b/packages/server-core/tests/storageprovider/storageprovider.test.ts index 0fb629b8f1..5d2caad827 100644 --- a/packages/server-core/tests/storageprovider/storageprovider.test.ts +++ b/packages/server-core/tests/storageprovider/storageprovider.test.ts @@ -56,133 +56,135 @@ describe('storageprovider', () => { } storageProviders.forEach((providerType) => { - let provider - before(async function () { - createEngine() - provider = new providerType() - await providerBeforeTest(provider, testFolderName, folderKeyTemp, folderKeyTemp2) - }) + describe(`tests for ${providerType.name}`, () => { + let provider + before(async function () { + createEngine() + provider = new providerType() + await providerBeforeTest(provider, testFolderName, folderKeyTemp, folderKeyTemp2) + }) - it(`should put object in ${providerType.name}`, async function () { - const fileKey = path.join(testFolderName, testFileName) - const data = Buffer.from(testFileContent) - await provider.putObject({ - Body: data, - Key: fileKey, - ContentType: getContentType(fileKey) + it(`should put object in ${providerType.name}`, async function () { + const fileKey = path.join(testFolderName, testFileName) + const data = Buffer.from(testFileContent) + await provider.putObject({ + Body: data, + Key: fileKey, + ContentType: getContentType(fileKey) + }) }) - }) - it(`should have object in ${providerType.name}`, async function () { - assert(await provider.doesExist(testFileName, testFolderName)) - }) + it(`should have object in ${providerType.name}`, async function () { + assert(await provider.doesExist(testFileName, testFolderName)) + }) - it(`should get object in ${providerType.name}`, async function () { - const fileKey = path.join(testFolderName, testFileName) - const file = await provider.getObject(fileKey) - assert.ok(file.Body.toString() === testFileContent) - }) + it(`should get object in ${providerType.name}`, async function () { + const fileKey = path.join(testFolderName, testFileName) + const file = await provider.getObject(fileKey) + assert.ok(file.Body.toString() === testFileContent) + }) - it(`should list object in ${providerType.name}`, async function () { - const res = await provider.listFolderContent(testFolderName, true) + it(`should list object in ${providerType.name}`, async function () { + const res = await provider.listFolderContent(testFolderName, true) - let haveObject = false - for (let i = 0; i < res.length; i++) { - if (res[i].name === 'TestFile' && res[i].type === 'txt') { - haveObject = true - break + let haveObject = false + for (let i = 0; i < res.length; i++) { + if (res[i].name === 'TestFile' && res[i].type === 'txt') { + haveObject = true + break + } } - } - assert.ok(haveObject) - }) + assert.ok(haveObject) + }) - it(`should return valid object url in ${providerType.name}`, async function () { - const fileKey = path.join('/', testFolderName, testFileName) - const signedUrl = await provider.getSignedUrl(fileKey, 20000, []) - const httpAgent = new https.Agent({ - rejectUnauthorized: false, - timeout: 1000 + it(`should return valid object url in ${providerType.name}`, async function () { + const fileKey = path.join('/', testFolderName, testFileName) + const signedUrl = await provider.getSignedUrl(fileKey, 20000, []) + const httpAgent = new https.Agent({ + rejectUnauthorized: false, + timeout: 1000 + }) + let res + try { + res = await fetch(signedUrl.url + signedUrl.fields.key, { agent: httpAgent }) + } catch (err) { + console.log(err) + } + if (!res) console.log('Make sure server is running') + assert.ok(res?.ok) }) - let res - try { - res = await fetch(signedUrl.url + signedUrl.fields.Key, { agent: httpAgent }) - } catch (err) { - console.log(err) - } - if (!res) console.log('Make sure server is running') - assert.ok(res?.ok) - }) - // Unable to perform move/copy and rename test cases because Fleek storage doesn't implemented those methods + // Unable to perform move/copy and rename test cases because Fleek storage doesn't implemented those methods - it(`should be able to move/copy object in ${providerType.name}`, async function () { - const newFolder1 = path.join(testFolderName, 'temp') - const newFolder2 = path.join(testFolderName, 'temp2') + it(`should be able to move/copy object in ${providerType.name}`, async function () { + const newFolder1 = path.join(testFolderName, 'temp') + const newFolder2 = path.join(testFolderName, 'temp2') - //check copy functionality - await provider.moveObject(testFileName, testFileName, testFolderName, newFolder1, true) - assert(await provider.doesExist(testFileName, testFolderName)) - assert(await provider.doesExist(testFileName, newFolder1)) + //check copy functionality + await provider.moveObject(testFileName, testFileName, testFolderName, newFolder1, true) + assert(await provider.doesExist(testFileName, testFolderName)) + assert(await provider.doesExist(testFileName, newFolder1)) - //check move functionality - await provider.moveObject(testFileName, testFileName, newFolder1, newFolder2, false) - assert(await provider.doesExist(testFileName, newFolder2)) - assert(!(await provider.doesExist(testFileName, newFolder1))) - }) + //check move functionality + await provider.moveObject(testFileName, testFileName, newFolder1, newFolder2, false) + assert(await provider.doesExist(testFileName, newFolder2)) + assert(!(await provider.doesExist(testFileName, newFolder1))) + }) - it(`should be able to rename object in ${providerType.name}`, async function () { - const temp2Folder = path.join(testFolderName, 'temp2') - await provider.moveObject(testFileName, 'Renamed.txt', testFolderName, temp2Folder, false) - const res = await provider.listFolderContent(temp2Folder, true) + it(`should be able to rename object in ${providerType.name}`, async function () { + const temp2Folder = path.join(testFolderName, 'temp2') + await provider.moveObject(testFileName, 'Renamed.txt', testFolderName, temp2Folder, false) + const res = await provider.listFolderContent(temp2Folder, true) - assert.equal(res[0]?.name, 'Renamed') - }) + assert.equal(res[0]?.name, 'Renamed') + }) - it(`should delete object in ${providerType.name}`, async function () { - const fileKey = path.join(testFolderName, testFileName) - assert.ok(await provider.deleteResources([fileKey])) - }) + it(`should delete object in ${providerType.name}`, async function () { + const fileKey = path.join(testFolderName, testFileName) + assert.ok(await provider.deleteResources([fileKey])) + }) - it(`should put and get same data for glbs in ${providerType.name}`, async function () { - const glbTestPath = 'packages/projects/default-project/assets/collisioncube.glb' - const filePath = path.join(approot.path, glbTestPath) - const fileData = fs.readFileSync(filePath) - const contentType = getContentType(filePath) - const key = path.join(testFolderName, glbTestPath) - await provider.putObject({ - Body: fileData, - Key: key, - ContentType: contentType + it(`should put and get same data for glbs in ${providerType.name}`, async function () { + const glbTestPath = 'packages/projects/default-project/assets/collisioncube.glb' + const filePath = path.join(approot.path, glbTestPath) + const fileData = fs.readFileSync(filePath) + const contentType = getContentType(filePath) + const key = path.join(testFolderName, glbTestPath) + await provider.putObject({ + Body: fileData, + Key: key, + ContentType: contentType + }) + const ret = await provider.getObject(key) + assert.strictEqual(contentType, ret.ContentType) + assert.deepStrictEqual(fileData, ret.Body) }) - const ret = await provider.getObject(key) - assert.strictEqual(contentType, ret.ContentType) - assert.deepStrictEqual(fileData, ret.Body) - }) - it(`should put over 1000 objects in ${providerType.name}`, async function () { - const promises: any[] = [] - for (let i = 0; i < 1010; i++) { - const fileKey = path.join(testFolderName, `${i}-${testFileName}`) - const data = Buffer.from([]) - promises.push( - provider.putObject({ - Body: data, - Key: fileKey, - ContentType: getContentType(fileKey) - }) - ) - } - await Promise.all(promises) - }) + it(`should put over 1000 objects in ${providerType.name}`, async function () { + const promises: any[] = [] + for (let i = 0; i < 1010; i++) { + const fileKey = path.join(testFolderName, `${i}-${testFileName}`) + const data = Buffer.from([]) + promises.push( + provider.putObject({ + Body: data, + Key: fileKey, + ContentType: getContentType(fileKey) + }) + ) + } + await Promise.all(promises) + }) - it(`should list over 1000 objects in ${providerType.name}`, async function () { - const res = await provider.listFolderContent(testFolderName, true) - assert(res.length > 1000) - }) + it(`should list over 1000 objects in ${providerType.name}`, async function () { + const res = await provider.listFolderContent(testFolderName, true) + assert(res.length > 1000) + }) - after(async function () { - await providerAfterTest(provider, testFolderName) - destroyEngine() + after(async function () { + destroyEngine() + await providerAfterTest(provider, testFolderName) + }) }) }) })