@aj-archipelago/cortex 1.3.58 → 1.3.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/helper-apps/cortex-file-handler/INTERFACE.md +20 -9
- package/helper-apps/cortex-file-handler/package-lock.json +2 -2
- package/helper-apps/cortex-file-handler/package.json +1 -1
- package/helper-apps/cortex-file-handler/scripts/setup-azure-container.js +17 -17
- package/helper-apps/cortex-file-handler/scripts/setup-test-containers.js +35 -35
- package/helper-apps/cortex-file-handler/src/blobHandler.js +1010 -909
- package/helper-apps/cortex-file-handler/src/constants.js +98 -98
- package/helper-apps/cortex-file-handler/src/docHelper.js +27 -27
- package/helper-apps/cortex-file-handler/src/fileChunker.js +224 -214
- package/helper-apps/cortex-file-handler/src/helper.js +93 -93
- package/helper-apps/cortex-file-handler/src/index.js +584 -550
- package/helper-apps/cortex-file-handler/src/localFileHandler.js +86 -86
- package/helper-apps/cortex-file-handler/src/redis.js +186 -90
- package/helper-apps/cortex-file-handler/src/services/ConversionService.js +301 -273
- package/helper-apps/cortex-file-handler/src/services/FileConversionService.js +55 -55
- package/helper-apps/cortex-file-handler/src/services/storage/AzureStorageProvider.js +174 -154
- package/helper-apps/cortex-file-handler/src/services/storage/GCSStorageProvider.js +239 -223
- package/helper-apps/cortex-file-handler/src/services/storage/LocalStorageProvider.js +161 -159
- package/helper-apps/cortex-file-handler/src/services/storage/StorageFactory.js +73 -71
- package/helper-apps/cortex-file-handler/src/services/storage/StorageProvider.js +46 -45
- package/helper-apps/cortex-file-handler/src/services/storage/StorageService.js +256 -213
- package/helper-apps/cortex-file-handler/src/start.js +4 -1
- package/helper-apps/cortex-file-handler/src/utils/filenameUtils.js +59 -25
- package/helper-apps/cortex-file-handler/tests/FileConversionService.test.js +119 -116
- package/helper-apps/cortex-file-handler/tests/blobHandler.test.js +257 -257
- package/helper-apps/cortex-file-handler/tests/cleanup.test.js +676 -0
- package/helper-apps/cortex-file-handler/tests/conversionResilience.test.js +124 -124
- package/helper-apps/cortex-file-handler/tests/fileChunker.test.js +249 -208
- package/helper-apps/cortex-file-handler/tests/fileUpload.test.js +439 -380
- package/helper-apps/cortex-file-handler/tests/getOperations.test.js +299 -263
- package/helper-apps/cortex-file-handler/tests/postOperations.test.js +265 -239
- package/helper-apps/cortex-file-handler/tests/start.test.js +1230 -1201
- package/helper-apps/cortex-file-handler/tests/storage/AzureStorageProvider.test.js +110 -105
- package/helper-apps/cortex-file-handler/tests/storage/GCSStorageProvider.test.js +201 -175
- package/helper-apps/cortex-file-handler/tests/storage/LocalStorageProvider.test.js +128 -125
- package/helper-apps/cortex-file-handler/tests/storage/StorageFactory.test.js +78 -73
- package/helper-apps/cortex-file-handler/tests/storage/StorageService.test.js +99 -99
- package/helper-apps/cortex-file-handler/tests/testUtils.helper.js +74 -70
- package/package.json +1 -1
- package/pathways/translate_subtitle.js +15 -8
|
@@ -1,120 +1,125 @@
|
|
|
1
|
-
import test from
|
|
2
|
-
import fs from
|
|
3
|
-
import path from
|
|
4
|
-
import { fileURLToPath } from
|
|
5
|
-
import { AzureStorageProvider } from
|
|
1
|
+
import test from "ava";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
import { AzureStorageProvider } from "../../src/services/storage/AzureStorageProvider.js";
|
|
6
6
|
|
|
7
7
|
const __filename = fileURLToPath(import.meta.url);
|
|
8
8
|
const __dirname = path.dirname(__filename);
|
|
9
9
|
|
|
10
10
|
test.before(() => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
test('should create provider with valid credentials', (t) => {
|
|
18
|
-
if (!process.env.AZURE_STORAGE_CONNECTION_STRING) {
|
|
19
|
-
t.pass('Skipping test - Azure not configured');
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const provider = new AzureStorageProvider(
|
|
24
|
-
process.env.AZURE_STORAGE_CONNECTION_STRING,
|
|
25
|
-
'test-container'
|
|
11
|
+
// Ensure we have the required environment variables
|
|
12
|
+
if (!process.env.AZURE_STORAGE_CONNECTION_STRING) {
|
|
13
|
+
console.warn(
|
|
14
|
+
"Skipping Azure tests - AZURE_STORAGE_CONNECTION_STRING not set",
|
|
26
15
|
);
|
|
27
|
-
|
|
16
|
+
}
|
|
28
17
|
});
|
|
29
18
|
|
|
30
|
-
test(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
19
|
+
test("should create provider with valid credentials", (t) => {
|
|
20
|
+
if (!process.env.AZURE_STORAGE_CONNECTION_STRING) {
|
|
21
|
+
t.pass("Skipping test - Azure not configured");
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const provider = new AzureStorageProvider(
|
|
26
|
+
process.env.AZURE_STORAGE_CONNECTION_STRING,
|
|
27
|
+
"test-container",
|
|
28
|
+
);
|
|
29
|
+
t.truthy(provider);
|
|
34
30
|
});
|
|
35
31
|
|
|
36
|
-
test(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
process.env.AZURE_STORAGE_CONNECTION_STRING,
|
|
44
|
-
'test-container'
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
// Create test file
|
|
48
|
-
const testContent = 'Hello World!';
|
|
49
|
-
const testFile = path.join(__dirname, 'test.txt');
|
|
50
|
-
fs.writeFileSync(testFile, testContent);
|
|
51
|
-
|
|
52
|
-
try {
|
|
53
|
-
// Upload file
|
|
54
|
-
const requestId = 'test-upload';
|
|
55
|
-
const result = await provider.uploadFile({}, testFile, requestId);
|
|
56
|
-
|
|
57
|
-
t.truthy(result.url);
|
|
58
|
-
t.truthy(result.blobName);
|
|
59
|
-
t.true(result.url.includes('test-container'));
|
|
60
|
-
t.true(result.blobName.startsWith(requestId));
|
|
61
|
-
|
|
62
|
-
// Verify file exists
|
|
63
|
-
const exists = await provider.fileExists(result.url);
|
|
64
|
-
t.true(exists);
|
|
65
|
-
|
|
66
|
-
// Delete file
|
|
67
|
-
const deleted = await provider.deleteFiles(requestId);
|
|
68
|
-
t.true(deleted.length > 0);
|
|
69
|
-
t.true(deleted[0].startsWith(requestId));
|
|
70
|
-
|
|
71
|
-
// Verify file is gone
|
|
72
|
-
const existsAfterDelete = await provider.fileExists(result.url);
|
|
73
|
-
t.false(existsAfterDelete);
|
|
74
|
-
} finally {
|
|
75
|
-
// Cleanup test file
|
|
76
|
-
if (fs.existsSync(testFile)) {
|
|
77
|
-
fs.unlinkSync(testFile);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
32
|
+
test("should throw error with missing credentials", (t) => {
|
|
33
|
+
t.throws(
|
|
34
|
+
() => {
|
|
35
|
+
new AzureStorageProvider(null, "test-container");
|
|
36
|
+
},
|
|
37
|
+
{ message: "Missing Azure Storage connection string or container name" },
|
|
38
|
+
);
|
|
80
39
|
});
|
|
81
40
|
|
|
82
|
-
test(
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
41
|
+
test("should upload and delete file", async (t) => {
|
|
42
|
+
if (!process.env.AZURE_STORAGE_CONNECTION_STRING) {
|
|
43
|
+
t.pass("Skipping test - Azure not configured");
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const provider = new AzureStorageProvider(
|
|
48
|
+
process.env.AZURE_STORAGE_CONNECTION_STRING,
|
|
49
|
+
"test-container",
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
// Create test file
|
|
53
|
+
const testContent = "Hello World!";
|
|
54
|
+
const testFile = path.join(__dirname, "test.txt");
|
|
55
|
+
fs.writeFileSync(testFile, testContent);
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
// Upload file
|
|
59
|
+
const requestId = "test-upload";
|
|
60
|
+
const result = await provider.uploadFile({}, testFile, requestId);
|
|
61
|
+
|
|
62
|
+
t.truthy(result.url);
|
|
63
|
+
t.truthy(result.blobName);
|
|
64
|
+
t.true(result.url.includes("test-container"));
|
|
65
|
+
t.true(result.blobName.startsWith(requestId));
|
|
66
|
+
|
|
67
|
+
// Verify file exists
|
|
68
|
+
const exists = await provider.fileExists(result.url);
|
|
69
|
+
t.true(exists);
|
|
70
|
+
|
|
71
|
+
// Delete file
|
|
72
|
+
const deleted = await provider.deleteFiles(requestId);
|
|
73
|
+
t.true(deleted.length > 0);
|
|
74
|
+
t.true(deleted[0].startsWith(requestId));
|
|
75
|
+
|
|
76
|
+
// Verify file is gone
|
|
77
|
+
const existsAfterDelete = await provider.fileExists(result.url);
|
|
78
|
+
t.false(existsAfterDelete);
|
|
79
|
+
} finally {
|
|
80
|
+
// Cleanup test file
|
|
81
|
+
if (fs.existsSync(testFile)) {
|
|
82
|
+
fs.unlinkSync(testFile);
|
|
86
83
|
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
87
86
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
87
|
+
test("should handle file download", async (t) => {
|
|
88
|
+
if (!process.env.AZURE_STORAGE_CONNECTION_STRING) {
|
|
89
|
+
t.pass("Skipping test - Azure not configured");
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const provider = new AzureStorageProvider(
|
|
94
|
+
process.env.AZURE_STORAGE_CONNECTION_STRING,
|
|
95
|
+
"test-container",
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
// Create test file
|
|
99
|
+
const testContent = "Hello World!";
|
|
100
|
+
const testFile = path.join(__dirname, "test.txt");
|
|
101
|
+
fs.writeFileSync(testFile, testContent);
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
// Upload file
|
|
105
|
+
const requestId = "test-download";
|
|
106
|
+
const result = await provider.uploadFile({}, testFile, requestId);
|
|
107
|
+
|
|
108
|
+
// Download to new location
|
|
109
|
+
const downloadPath = path.join(__dirname, "downloaded.txt");
|
|
110
|
+
await provider.downloadFile(result.url, downloadPath);
|
|
111
|
+
|
|
112
|
+
// Verify content
|
|
113
|
+
const downloadedContent = fs.readFileSync(downloadPath, "utf8");
|
|
114
|
+
t.is(downloadedContent, testContent);
|
|
115
|
+
|
|
116
|
+
// Cleanup
|
|
117
|
+
await provider.deleteFiles(requestId);
|
|
118
|
+
fs.unlinkSync(downloadPath);
|
|
119
|
+
} finally {
|
|
120
|
+
// Cleanup test file
|
|
121
|
+
if (fs.existsSync(testFile)) {
|
|
122
|
+
fs.unlinkSync(testFile);
|
|
119
123
|
}
|
|
120
|
-
}
|
|
124
|
+
}
|
|
125
|
+
});
|
|
@@ -1,193 +1,219 @@
|
|
|
1
|
-
import test from
|
|
2
|
-
import fs from
|
|
3
|
-
import path from
|
|
4
|
-
import { fileURLToPath } from
|
|
5
|
-
import { GCSStorageProvider } from
|
|
6
|
-
import { sanitizeFilename } from '../../src/utils/filenameUtils.js';
|
|
1
|
+
import test from "ava";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
import { GCSStorageProvider } from "../../src/services/storage/GCSStorageProvider.js";
|
|
7
6
|
|
|
8
7
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
8
|
const __dirname = path.dirname(__filename);
|
|
10
9
|
|
|
11
10
|
test.before(() => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
// Ensure we have the required environment variables
|
|
12
|
+
if (
|
|
13
|
+
!process.env.GCP_SERVICE_ACCOUNT_KEY_BASE64 &&
|
|
14
|
+
!process.env.GCP_SERVICE_ACCOUNT_KEY
|
|
15
|
+
) {
|
|
16
|
+
console.warn("Skipping GCS tests - GCP credentials not set");
|
|
17
|
+
}
|
|
16
18
|
});
|
|
17
19
|
|
|
18
|
-
test(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
20
|
+
test("should create provider with valid credentials", (t) => {
|
|
21
|
+
if (
|
|
22
|
+
!process.env.GCP_SERVICE_ACCOUNT_KEY_BASE64 &&
|
|
23
|
+
!process.env.GCP_SERVICE_ACCOUNT_KEY
|
|
24
|
+
) {
|
|
25
|
+
t.pass("Skipping test - GCS not configured");
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const credentials = {
|
|
30
|
+
project_id: "test-project",
|
|
31
|
+
client_email: "test@test.com",
|
|
32
|
+
private_key: "test-key",
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const provider = new GCSStorageProvider(credentials, "test-bucket");
|
|
36
|
+
t.truthy(provider);
|
|
32
37
|
});
|
|
33
38
|
|
|
34
|
-
test(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
test("should throw error with missing credentials", (t) => {
|
|
40
|
+
t.throws(
|
|
41
|
+
() => {
|
|
42
|
+
new GCSStorageProvider(null, "test-bucket");
|
|
43
|
+
},
|
|
44
|
+
{ message: "Missing GCS credentials or bucket name" },
|
|
45
|
+
);
|
|
38
46
|
});
|
|
39
47
|
|
|
40
|
-
test(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
48
|
+
test("should upload and delete file", async (t) => {
|
|
49
|
+
if (
|
|
50
|
+
!process.env.GCP_SERVICE_ACCOUNT_KEY_BASE64 &&
|
|
51
|
+
!process.env.GCP_SERVICE_ACCOUNT_KEY
|
|
52
|
+
) {
|
|
53
|
+
t.pass("Skipping test - GCS not configured");
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const credentials = JSON.parse(
|
|
58
|
+
process.env.GCP_SERVICE_ACCOUNT_KEY_BASE64
|
|
59
|
+
? Buffer.from(
|
|
60
|
+
process.env.GCP_SERVICE_ACCOUNT_KEY_BASE64,
|
|
61
|
+
"base64",
|
|
62
|
+
).toString()
|
|
63
|
+
: process.env.GCP_SERVICE_ACCOUNT_KEY,
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
const provider = new GCSStorageProvider(
|
|
67
|
+
credentials,
|
|
68
|
+
process.env.GCS_BUCKETNAME || "cortextempfiles",
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
// Create test file
|
|
72
|
+
const testContent = "Hello World!";
|
|
73
|
+
const testFile = path.join(__dirname, "test.txt");
|
|
74
|
+
fs.writeFileSync(testFile, testContent);
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
// Upload file
|
|
78
|
+
const requestId = "test-upload";
|
|
79
|
+
const result = await provider.uploadFile({}, testFile, requestId);
|
|
80
|
+
|
|
81
|
+
t.truthy(result.url);
|
|
82
|
+
t.truthy(result.blobName);
|
|
83
|
+
t.true(result.url.startsWith("gs://"));
|
|
84
|
+
t.true(result.blobName.startsWith(requestId));
|
|
85
|
+
|
|
86
|
+
// Verify file exists
|
|
87
|
+
const exists = await provider.fileExists(result.url);
|
|
88
|
+
t.true(exists);
|
|
89
|
+
|
|
90
|
+
// Delete file
|
|
91
|
+
const deleted = await provider.deleteFiles(requestId);
|
|
92
|
+
t.true(deleted.length > 0);
|
|
93
|
+
t.true(deleted[0].startsWith(requestId));
|
|
94
|
+
|
|
95
|
+
// Verify file is gone
|
|
96
|
+
const existsAfterDelete = await provider.fileExists(result.url);
|
|
97
|
+
t.false(existsAfterDelete);
|
|
98
|
+
} finally {
|
|
99
|
+
// Cleanup test file
|
|
100
|
+
if (fs.existsSync(testFile)) {
|
|
101
|
+
fs.unlinkSync(testFile);
|
|
89
102
|
}
|
|
103
|
+
}
|
|
90
104
|
});
|
|
91
105
|
|
|
92
|
-
test(
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
106
|
+
test("should handle file download", async (t) => {
|
|
107
|
+
if (
|
|
108
|
+
!process.env.GCP_SERVICE_ACCOUNT_KEY_BASE64 &&
|
|
109
|
+
!process.env.GCP_SERVICE_ACCOUNT_KEY
|
|
110
|
+
) {
|
|
111
|
+
t.pass("Skipping test - GCS not configured");
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const credentials = JSON.parse(
|
|
116
|
+
process.env.GCP_SERVICE_ACCOUNT_KEY_BASE64
|
|
117
|
+
? Buffer.from(
|
|
118
|
+
process.env.GCP_SERVICE_ACCOUNT_KEY_BASE64,
|
|
119
|
+
"base64",
|
|
120
|
+
).toString()
|
|
121
|
+
: process.env.GCP_SERVICE_ACCOUNT_KEY,
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
const provider = new GCSStorageProvider(
|
|
125
|
+
credentials,
|
|
126
|
+
process.env.GCS_BUCKETNAME || "cortextempfiles",
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
// Create test file
|
|
130
|
+
const testContent = "Hello World!";
|
|
131
|
+
const testFile = path.join(__dirname, "test.txt");
|
|
132
|
+
fs.writeFileSync(testFile, testContent);
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
// Upload file
|
|
136
|
+
const requestId = "test-download";
|
|
137
|
+
const result = await provider.uploadFile({}, testFile, requestId);
|
|
138
|
+
|
|
139
|
+
// Download to new location
|
|
140
|
+
const downloadPath = path.join(__dirname, "downloaded.txt");
|
|
141
|
+
await provider.downloadFile(result.url, downloadPath);
|
|
142
|
+
|
|
143
|
+
// Verify content
|
|
144
|
+
const downloadedContent = fs.readFileSync(downloadPath, "utf8");
|
|
145
|
+
t.is(downloadedContent, testContent);
|
|
146
|
+
|
|
147
|
+
// Cleanup
|
|
148
|
+
await provider.deleteFiles(requestId);
|
|
149
|
+
fs.unlinkSync(downloadPath);
|
|
150
|
+
} finally {
|
|
151
|
+
// Cleanup test file
|
|
152
|
+
if (fs.existsSync(testFile)) {
|
|
153
|
+
fs.unlinkSync(testFile);
|
|
135
154
|
}
|
|
155
|
+
}
|
|
136
156
|
});
|
|
137
157
|
|
|
138
|
-
test(
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
158
|
+
test("should handle file existence check with spaces and special characters", async (t) => {
|
|
159
|
+
if (
|
|
160
|
+
!process.env.GCP_SERVICE_ACCOUNT_KEY_BASE64 &&
|
|
161
|
+
!process.env.GCP_SERVICE_ACCOUNT_KEY
|
|
162
|
+
) {
|
|
163
|
+
t.pass("Skipping test - GCS not configured");
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const credentials = JSON.parse(
|
|
168
|
+
process.env.GCP_SERVICE_ACCOUNT_KEY_BASE64
|
|
169
|
+
? Buffer.from(
|
|
170
|
+
process.env.GCP_SERVICE_ACCOUNT_KEY_BASE64,
|
|
171
|
+
"base64",
|
|
172
|
+
).toString()
|
|
173
|
+
: process.env.GCP_SERVICE_ACCOUNT_KEY,
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
const provider = new GCSStorageProvider(
|
|
177
|
+
credentials,
|
|
178
|
+
process.env.GCS_BUCKETNAME || "cortextempfiles",
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
// Create test file with spaces and special characters in name
|
|
182
|
+
const testContent = "Hello World!";
|
|
183
|
+
const testFileName = "test file with spaces & special chars!.txt";
|
|
184
|
+
const testFile = path.join(__dirname, testFileName);
|
|
185
|
+
fs.writeFileSync(testFile, testContent);
|
|
186
|
+
|
|
187
|
+
try {
|
|
188
|
+
// Upload file
|
|
189
|
+
const requestId = "test-special-chars";
|
|
190
|
+
const result = await provider.uploadFile({}, testFile, requestId);
|
|
191
|
+
|
|
192
|
+
t.truthy(result.url);
|
|
193
|
+
// With LLM-friendly naming, the URL should contain a short ID, not the original filename
|
|
194
|
+
t.true(result.url.includes(".txt")); // Should still have the extension
|
|
195
|
+
t.true(result.url.startsWith("gs://"));
|
|
196
|
+
t.true(result.url.includes(requestId)); // Should contain the requestId
|
|
197
|
+
|
|
198
|
+
// Verify file exists with original URL
|
|
199
|
+
const exists = await provider.fileExists(result.url);
|
|
200
|
+
t.true(exists, "File should exist with original URL");
|
|
201
|
+
|
|
202
|
+
// Verify file exists with encoded URL
|
|
203
|
+
const encodedUrl = result.url.replace(/ /g, "%20");
|
|
204
|
+
const existsEncoded = await provider.fileExists(encodedUrl);
|
|
205
|
+
t.true(existsEncoded, "File should exist with encoded URL");
|
|
206
|
+
|
|
207
|
+
// Cleanup
|
|
208
|
+
await provider.deleteFiles(requestId);
|
|
209
|
+
|
|
210
|
+
// Verify file is gone
|
|
211
|
+
const existsAfterDelete = await provider.fileExists(result.url);
|
|
212
|
+
t.false(existsAfterDelete, "File should not exist after deletion");
|
|
213
|
+
} finally {
|
|
214
|
+
// Cleanup test file
|
|
215
|
+
if (fs.existsSync(testFile)) {
|
|
216
|
+
fs.unlinkSync(testFile);
|
|
142
217
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
process.env.GCP_SERVICE_ACCOUNT_KEY_BASE64
|
|
146
|
-
? Buffer.from(process.env.GCP_SERVICE_ACCOUNT_KEY_BASE64, 'base64').toString()
|
|
147
|
-
: process.env.GCP_SERVICE_ACCOUNT_KEY
|
|
148
|
-
);
|
|
149
|
-
|
|
150
|
-
const provider = new GCSStorageProvider(
|
|
151
|
-
credentials,
|
|
152
|
-
process.env.GCS_BUCKETNAME || 'cortextempfiles'
|
|
153
|
-
);
|
|
154
|
-
|
|
155
|
-
// Create test file with spaces and special characters in name
|
|
156
|
-
const testContent = 'Hello World!';
|
|
157
|
-
const testFileName = 'test file with spaces & special chars!.txt';
|
|
158
|
-
const testFile = path.join(__dirname, testFileName);
|
|
159
|
-
fs.writeFileSync(testFile, testContent);
|
|
160
|
-
|
|
161
|
-
try {
|
|
162
|
-
// Upload file
|
|
163
|
-
const requestId = 'test-special-chars';
|
|
164
|
-
const result = await provider.uploadFile({}, testFile, requestId);
|
|
165
|
-
|
|
166
|
-
t.truthy(result.url);
|
|
167
|
-
// Compare against sanitized filename instead of original
|
|
168
|
-
const sanitizedFileName = sanitizeFilename(testFileName);
|
|
169
|
-
t.true(result.url.includes(sanitizedFileName));
|
|
170
|
-
t.true(result.url.startsWith('gs://'));
|
|
171
|
-
|
|
172
|
-
// Verify file exists with original URL
|
|
173
|
-
const exists = await provider.fileExists(result.url);
|
|
174
|
-
t.true(exists, 'File should exist with original URL');
|
|
175
|
-
|
|
176
|
-
// Verify file exists with encoded URL
|
|
177
|
-
const encodedUrl = result.url.replace(/ /g, '%20');
|
|
178
|
-
const existsEncoded = await provider.fileExists(encodedUrl);
|
|
179
|
-
t.true(existsEncoded, 'File should exist with encoded URL');
|
|
180
|
-
|
|
181
|
-
// Cleanup
|
|
182
|
-
await provider.deleteFiles(requestId);
|
|
183
|
-
|
|
184
|
-
// Verify file is gone
|
|
185
|
-
const existsAfterDelete = await provider.fileExists(result.url);
|
|
186
|
-
t.false(existsAfterDelete, 'File should not exist after deletion');
|
|
187
|
-
} finally {
|
|
188
|
-
// Cleanup test file
|
|
189
|
-
if (fs.existsSync(testFile)) {
|
|
190
|
-
fs.unlinkSync(testFile);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
});
|
|
218
|
+
}
|
|
219
|
+
});
|