@itwin/object-storage-tests-backend
Version:
Tests for generic storage packages
325 lines • 19.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
const crypto_1 = require("crypto");
const fs_1 = require("fs");
const path = require("path");
const chai_1 = require("chai");
const chaiAsPromised = require("chai-as-promised");
const object_storage_core_1 = require("@itwin/object-storage-core");
const Config_1 = require("./Config");
const Global_test_1 = require("./Global.test");
const utils_1 = require("./utils");
chai_1.use(chaiAsPromised);
const { serverStorage } = Config_1.config;
describe(`${object_storage_core_1.ServerStorage.name}: ${serverStorage.constructor.name}`, () => {
describe(`${serverStorage.createBaseDirectory.name}()`, () => {
it("should create directory", async () => {
const testDirectory = {
baseDirectory: `test-create-directory-${crypto_1.randomUUID()}`,
};
Global_test_1.testDirectoryManager.addForDelete(testDirectory);
await serverStorage.createBaseDirectory(testDirectory);
const exists = await serverStorage.baseDirectoryExists(testDirectory);
chai_1.expect(exists).to.be.equal(true);
});
});
describe(`${serverStorage.upload.name}()`, () => {
const contentBuffer = Buffer.from("server-upload-content");
const uploadTestCases = [
{
caseName: "Buffer",
objectName: "test-upload-buffer.txt",
dataCallback: (_sourcePath) => contentBuffer,
},
{
caseName: "Stream",
objectName: "test-upload-stream.txt",
dataCallback: (sourcePath) => fs_1.createReadStream(sourcePath),
},
{
caseName: "path",
objectName: "test-upload-local.txt",
dataCallback: (sourcePath) => sourcePath,
},
];
for (const testCase of uploadTestCases) {
const { caseName, objectName, dataCallback } = testCase;
it(`should upload a file from ${caseName}`, async () => {
const fileToUploadPath = await Global_test_1.testLocalFileManager.createAndWriteFile("test-server-upload.txt", contentBuffer);
const testBaseDirectory = (await Global_test_1.testDirectoryManager.createNew()).baseDirectory;
const reference = {
baseDirectory: testBaseDirectory.baseDirectory,
objectName,
};
await serverStorage.upload(reference, dataCallback(fileToUploadPath));
await utils_1.checkUploadedFileValidity(reference, contentBuffer);
});
it(`should upload a file with relative directory from ${caseName}`, async () => {
const fileToUploadPath = await Global_test_1.testLocalFileManager.createAndWriteFile("test-server-upload-relative-dir.txt", contentBuffer);
const testBaseDirectory = (await Global_test_1.testDirectoryManager.createNew()).baseDirectory;
const reference = {
baseDirectory: testBaseDirectory.baseDirectory,
relativeDirectory: "relative-1/relative-2",
objectName,
};
const metadata = {
test: "test-metadata",
};
await serverStorage.upload(reference, dataCallback(fileToUploadPath), metadata);
await utils_1.checkUploadedFileValidity(reference, contentBuffer);
});
it(`should upload a file from ${caseName} with metadata`, async () => {
const fileToUploadPath = await Global_test_1.testLocalFileManager.createAndWriteFile("test-server-upload-metadata.txt", contentBuffer);
const testBaseDirectory = (await Global_test_1.testDirectoryManager.createNew()).baseDirectory;
const reference = {
baseDirectory: testBaseDirectory.baseDirectory,
objectName,
};
const metadata = {
test: "test-metadata",
};
await serverStorage.upload(reference, dataCallback(fileToUploadPath), metadata);
await utils_1.checkUploadedFileValidity(reference, contentBuffer);
await utils_1.queryAndAssertMetadata(reference, metadata);
});
}
it("should fail to upload if specified path contains empty file", async () => {
const emptyFilePath = await Global_test_1.testLocalFileManager.createAndWriteFile("test-empty-file.txt");
const uploadPromise = serverStorage.upload({
baseDirectory: "test-directory",
objectName: "test-object-name",
}, emptyFilePath);
await chai_1.expect(uploadPromise).to.eventually.be.rejectedWith(Error, "Provided path is an empty file.");
});
});
describe(`${serverStorage.uploadInMultipleParts.name}()`, function () {
const contentBuffer = Buffer.from("server-multipart-upload-content");
const uploadTestCases = [
{
caseName: "Stream",
objectName: "test-multipart-upload-stream.txt",
dataCallback: (sourcePath) => fs_1.createReadStream(sourcePath),
},
{
caseName: "path",
objectName: "test-multipart-upload-local.txt",
dataCallback: (sourcePath) => sourcePath,
},
];
for (const testCase of uploadTestCases) {
const { caseName, objectName, dataCallback } = testCase;
it(`should upload a file from ${caseName}`, async () => {
const fileToUploadPath = await Global_test_1.testLocalFileManager.createAndWriteFile("test-multipart-server-upload.txt", contentBuffer);
const testBaseDirectory = (await Global_test_1.testDirectoryManager.createNew()).baseDirectory;
const reference = {
baseDirectory: testBaseDirectory.baseDirectory,
objectName,
};
await serverStorage.uploadInMultipleParts(reference, dataCallback(fileToUploadPath));
await utils_1.checkUploadedFileValidity(reference, contentBuffer);
});
it(`should upload a file with relative directory from ${caseName}`, async () => {
const fileToUploadPath = await Global_test_1.testLocalFileManager.createAndWriteFile("test-multipart-server-upload-relative-dir.txt", contentBuffer);
const testBaseDirectory = (await Global_test_1.testDirectoryManager.createNew()).baseDirectory;
const reference = {
baseDirectory: testBaseDirectory.baseDirectory,
relativeDirectory: "relative-1/relative-2",
objectName,
};
await serverStorage.uploadInMultipleParts(reference, dataCallback(fileToUploadPath));
await utils_1.checkUploadedFileValidity(reference, contentBuffer);
});
it(`should upload a file from ${caseName} with metadata`, async () => {
const fileToUploadPath = await Global_test_1.testLocalFileManager.createAndWriteFile("test-multipart-server-upload-metadata.txt", contentBuffer);
const testBaseDirectory = (await Global_test_1.testDirectoryManager.createNew()).baseDirectory;
const reference = {
baseDirectory: testBaseDirectory.baseDirectory,
objectName,
};
const metadata = {
test: "test-metadata",
};
await serverStorage.uploadInMultipleParts(reference, dataCallback(fileToUploadPath), { metadata });
await utils_1.checkUploadedFileValidity(reference, contentBuffer);
await utils_1.queryAndAssertMetadata(reference, metadata);
});
}
it("should fail to upload in multiple parts if specified path contains empty file", async () => {
const emptyFilePath = await Global_test_1.testLocalFileManager.createAndWriteFile("test-empty-file.txt");
const uploadPromise = serverStorage.uploadInMultipleParts({
baseDirectory: "test-directory",
objectName: "test-object-name",
}, emptyFilePath);
await chai_1.expect(uploadPromise).to.eventually.be.rejectedWith(Error, "Provided path is an empty file.");
});
});
describe(`${serverStorage.list.name}()`, () => {
it("should list objects", async () => {
const testDirectory = await Global_test_1.testDirectoryManager.createNew();
const reference1 = await testDirectory.uploadFile({ objectName: "reference1" }, undefined, undefined);
const reference2 = await testDirectory.uploadFile({ objectName: "reference2" }, undefined, undefined);
const queriedReferences = await serverStorage.list(testDirectory.baseDirectory);
chai_1.expect(queriedReferences.length).to.be.equal(2);
const queriedReference1 = queriedReferences.find((ref) => ref.objectName === reference1.objectName);
chai_1.expect(queriedReference1).to.be.deep.equal(reference1);
const queriedReference2 = queriedReferences.find((ref) => ref.objectName === reference2.objectName);
chai_1.expect(queriedReference2).to.be.deep.equal(reference2);
});
});
describe(`${serverStorage.deleteBaseDirectory.name}()`, () => {
it("should delete directory with files", async () => {
const testDirectory = await Global_test_1.testDirectoryManager.createNew();
const tempFiles = ["temp-1", "temp-2", "temp-3"];
await Promise.all(tempFiles.map(async (file) => testDirectory.uploadFile({ objectName: file }, Buffer.from(file), undefined)));
await serverStorage.deleteBaseDirectory(testDirectory.baseDirectory);
const doesDirectoryExist = await serverStorage.baseDirectoryExists(testDirectory.baseDirectory);
chai_1.expect(doesDirectoryExist).to.be.equal(false);
});
it("should not throw if base directory does not exist", async () => {
const deletePromise = serverStorage.deleteBaseDirectory({
baseDirectory: crypto_1.randomUUID(),
});
await chai_1.expect(deletePromise).to.eventually.be.fulfilled;
});
});
describe(`${serverStorage.deleteObject.name}()`, async () => {
it("should delete object", async () => {
const testDirectory = await Global_test_1.testDirectoryManager.createNew();
const reference = await testDirectory.uploadFile({ objectName: "test-delete.txt" }, undefined, undefined);
await serverStorage.deleteObject(reference);
const objectExists = await serverStorage.objectExists(reference);
chai_1.expect(objectExists).to.be.false;
});
it("should not throw if file does not exist", async () => {
const testBaseDirectory = (await Global_test_1.testDirectoryManager.createNew()).baseDirectory;
const deletePromise = serverStorage.deleteObject({
baseDirectory: testBaseDirectory.baseDirectory,
objectName: crypto_1.randomUUID(),
});
await chai_1.expect(deletePromise).to.eventually.be.fulfilled;
});
it("should not throw if the whole path does not exist", async () => {
const deletePromise = serverStorage.deleteObject({
baseDirectory: crypto_1.randomUUID(),
relativeDirectory: crypto_1.randomUUID(),
objectName: crypto_1.randomUUID(),
});
await chai_1.expect(deletePromise).to.eventually.be.fulfilled;
});
it("should retain the directory after all files from it have been deleted", async () => {
const testBaseDirectory = (await Global_test_1.testDirectoryManager.createNew()).baseDirectory;
const testFileToUpload = {
baseDirectory: testBaseDirectory.baseDirectory,
objectName: "test-delete-object.txt",
};
const contentBuffer = Buffer.from("test-delete-object");
await serverStorage.upload(testFileToUpload, contentBuffer);
await serverStorage.deleteObject(testFileToUpload);
const exists = await serverStorage.baseDirectoryExists(testBaseDirectory);
chai_1.expect(exists).to.be.true;
});
});
describe(`${serverStorage.baseDirectoryExists.name}()`, () => {
it("should return true if base directory exists", async () => {
const testBaseDirectory = (await Global_test_1.testDirectoryManager.createNew()).baseDirectory;
const exists = await serverStorage.baseDirectoryExists({
baseDirectory: testBaseDirectory.baseDirectory,
});
chai_1.expect(exists).to.be.true;
});
it("should return false if base directory does not exist", async () => {
const exists = await serverStorage.baseDirectoryExists({
baseDirectory: crypto_1.randomUUID(),
});
chai_1.expect(exists).to.be.false;
});
});
describe(`${serverStorage.objectExists.name}()`, () => {
it("should return true if file exists", async () => {
const testDirectory = await Global_test_1.testDirectoryManager.createNew();
const reference = await testDirectory.uploadFile({ objectName: "test-exists.txt" }, undefined, undefined);
const exists = await serverStorage.objectExists(reference);
chai_1.expect(exists).to.be.true;
});
it("should return false if file does not exist", async () => {
const testBaseDirectory = (await Global_test_1.testDirectoryManager.createNew()).baseDirectory;
const exists = await serverStorage.objectExists({
baseDirectory: testBaseDirectory.baseDirectory,
objectName: crypto_1.randomUUID(),
});
chai_1.expect(exists).to.be.false;
});
it("should return false if the whole path does not exist", async () => {
const exists = await serverStorage.objectExists({
baseDirectory: crypto_1.randomUUID(),
relativeDirectory: crypto_1.randomUUID(),
objectName: crypto_1.randomUUID(),
});
chai_1.expect(exists).to.be.false;
});
});
describe(`${serverStorage.download.name}()`, () => {
const contentBuffer = Buffer.from("test-download");
it("should download a file to buffer", async () => {
const testDirectory = await Global_test_1.testDirectoryManager.createNew();
const uploadedFile = await testDirectory.uploadFile({ objectName: "file-to-download.txt" }, contentBuffer, undefined);
const response = await serverStorage.download(uploadedFile, "buffer");
utils_1.assertBuffer(response, contentBuffer);
});
it("should download a file to stream", async () => {
const testDirectory = await Global_test_1.testDirectoryManager.createNew();
const uploadedFile = await testDirectory.uploadFile({ objectName: "file-to-download.txt" }, contentBuffer, undefined);
const response = await serverStorage.download(uploadedFile, "stream");
await utils_1.assertStream(response, contentBuffer);
});
it("should download a file to path", async () => {
const testDownloadFolder = await Global_test_1.testLocalFileManager.getDownloadsDir();
const testDirectory = await Global_test_1.testDirectoryManager.createNew();
const uploadedFile = await testDirectory.uploadFile({ objectName: "file-to-download.txt" }, contentBuffer, undefined);
const response = await serverStorage.download(uploadedFile, "local", path.join(testDownloadFolder, "download.txt"));
await utils_1.assertLocalFile(response, contentBuffer);
});
});
describe(`${serverStorage.getObjectProperties.name}()`, () => {
it("should get correct object properties", async () => {
const data = Buffer.from("test-properties");
const testDirectory = await Global_test_1.testDirectoryManager.createNew();
const uploadMetadata = {
test: "test-metadata",
};
const uploadedFile = await testDirectory.uploadFile({ objectName: "test-object-properties.txt" }, data, uploadMetadata);
const { lastModified, reference: queriedReference, size, metadata, } = await serverStorage.getObjectProperties(uploadedFile);
chai_1.expect(Date.now() - lastModified.getTime() < 60 * 1000).to.be.true; // not older than 1 minute
chai_1.expect(queriedReference).to.equal(uploadedFile);
chai_1.expect(size === data.byteLength);
chai_1.expect(metadata === null || metadata === void 0 ? void 0 : metadata.test).to.be.equal("test-metadata");
});
});
describe(`${serverStorage.updateMetadata.name}()`, () => {
it("should update metadata", async () => {
const testDirectory = await Global_test_1.testDirectoryManager.createNew();
const initialMetadata = {
test1: "test-metadata-1",
test2: "test-metadata-2",
};
const uploadedFile = await testDirectory.uploadFile({ objectName: "update-metadata-test.txt" }, Buffer.from("test-metadata"), initialMetadata);
await utils_1.queryAndAssertMetadata(uploadedFile, initialMetadata);
const updatedMetadata1 = {
test1: "test-metadata-1",
test2: "update-test-metadata-2",
};
await serverStorage.updateMetadata(uploadedFile, updatedMetadata1);
await utils_1.queryAndAssertMetadata(uploadedFile, updatedMetadata1);
const updatedMetadata2 = {
test3: "test-metadata-3",
};
await serverStorage.updateMetadata(uploadedFile, updatedMetadata2);
await utils_1.queryAndAssertMetadata(uploadedFile, updatedMetadata2);
});
});
});
//# sourceMappingURL=ServerStorage.test.js.map