@aj-archipelago/cortex 1.3.57 → 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/README.md +6 -0
- package/config.js +22 -0
- 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_apptek.js +33 -0
- package/pathways/translate_subtitle.js +15 -8
- package/server/plugins/apptekTranslatePlugin.js +46 -91
- package/tests/apptekTranslatePlugin.test.js +0 -2
- package/tests/integration/apptekTranslatePlugin.integration.test.js +159 -93
- package/tests/translate_apptek.test.js +16 -0
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import test from
|
|
2
|
-
import fs from
|
|
3
|
-
import path from
|
|
4
|
-
import { fileURLToPath } from
|
|
5
|
-
import { v4 as uuidv4 } from
|
|
6
|
-
import axios from
|
|
7
|
-
import FormData from
|
|
8
|
-
import { port } from
|
|
9
|
-
import {
|
|
1
|
+
import test from "ava";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
import { v4 as uuidv4 } from "uuid";
|
|
6
|
+
import axios from "axios";
|
|
7
|
+
import FormData from "form-data";
|
|
8
|
+
import { port } from "../src/start.js";
|
|
9
|
+
import {
|
|
10
|
+
cleanupHashAndFile,
|
|
11
|
+
getFolderNameFromUrl,
|
|
12
|
+
} from "./testUtils.helper.js";
|
|
10
13
|
|
|
11
14
|
const __filename = fileURLToPath(import.meta.url);
|
|
12
15
|
const __dirname = path.dirname(__filename);
|
|
@@ -14,278 +17,301 @@ const baseUrl = `http://localhost:${port}/api/CortexFileHandler`;
|
|
|
14
17
|
|
|
15
18
|
// Helper function to determine if GCS is configured
|
|
16
19
|
function isGCSConfigured() {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
return (
|
|
21
|
+
process.env.GCP_SERVICE_ACCOUNT_KEY_BASE64 ||
|
|
22
|
+
process.env.GCP_SERVICE_ACCOUNT_KEY
|
|
23
|
+
);
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
// Helper function to create test files
|
|
24
27
|
async function createTestFile(content, extension) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
const testDir = path.join(__dirname, "test-files");
|
|
29
|
+
if (!fs.existsSync(testDir)) {
|
|
30
|
+
fs.mkdirSync(testDir, { recursive: true });
|
|
31
|
+
}
|
|
32
|
+
const filename = path.join(testDir, `${uuidv4()}.${extension}`);
|
|
33
|
+
fs.writeFileSync(filename, content);
|
|
34
|
+
return filename;
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
// Helper function to upload file
|
|
35
38
|
async function uploadFile(filePath, requestId = null, hash = null) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const response = await axios.post(baseUrl, form, {
|
|
42
|
-
headers: {
|
|
43
|
-
...form.getHeaders(),
|
|
44
|
-
'Content-Type': 'multipart/form-data',
|
|
45
|
-
},
|
|
46
|
-
validateStatus: (status) => true,
|
|
47
|
-
timeout: 30000,
|
|
48
|
-
maxContentLength: Infinity,
|
|
49
|
-
maxBodyLength: Infinity,
|
|
50
|
-
});
|
|
39
|
+
const form = new FormData();
|
|
40
|
+
form.append("file", fs.createReadStream(filePath));
|
|
41
|
+
if (requestId) form.append("requestId", requestId);
|
|
42
|
+
if (hash) form.append("hash", hash);
|
|
51
43
|
|
|
52
|
-
|
|
44
|
+
const response = await axios.post(baseUrl, form, {
|
|
45
|
+
headers: {
|
|
46
|
+
...form.getHeaders(),
|
|
47
|
+
"Content-Type": "multipart/form-data",
|
|
48
|
+
},
|
|
49
|
+
validateStatus: (status) => true,
|
|
50
|
+
timeout: 30000,
|
|
51
|
+
maxContentLength: Infinity,
|
|
52
|
+
maxBodyLength: Infinity,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
return response;
|
|
53
56
|
}
|
|
54
57
|
|
|
55
58
|
// Setup: Create test directory
|
|
56
59
|
test.before(async (t) => {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
const testDir = path.join(__dirname, "test-files");
|
|
61
|
+
await fs.promises.mkdir(testDir, { recursive: true });
|
|
62
|
+
t.context = { testDir };
|
|
60
63
|
});
|
|
61
64
|
|
|
62
65
|
// Test: Upload with hash and verify Redis storage
|
|
63
|
-
test.serial(
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
66
|
+
test.serial("should store file metadata in Redis with hash", async (t) => {
|
|
67
|
+
const fileContent = "test content";
|
|
68
|
+
const filePath = await createTestFile(fileContent, "txt");
|
|
69
|
+
const requestId = uuidv4();
|
|
70
|
+
const hash = "test-hash-" + uuidv4();
|
|
71
|
+
let response;
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
response = await uploadFile(filePath, requestId, hash);
|
|
75
|
+
t.is(response.status, 200, "Upload should succeed");
|
|
76
|
+
t.truthy(response.data.url, "Should have file URL");
|
|
77
|
+
t.is(response.data.hash, hash, "Should return correct hash");
|
|
78
|
+
|
|
79
|
+
// Wait for Redis operations to complete
|
|
80
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
81
|
+
|
|
82
|
+
// Verify hash exists in Redis
|
|
83
|
+
const checkResponse = await axios.get(baseUrl, {
|
|
84
|
+
params: {
|
|
85
|
+
hash,
|
|
86
|
+
checkHash: true,
|
|
87
|
+
},
|
|
88
|
+
validateStatus: (status) => true,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
t.is(checkResponse.status, 200, "Hash should exist in Redis");
|
|
92
|
+
t.truthy(checkResponse.data.url, "Hash check should return URL");
|
|
93
|
+
t.is(
|
|
94
|
+
checkResponse.data.url,
|
|
95
|
+
response.data.url,
|
|
96
|
+
"Hash check should return correct URL",
|
|
97
|
+
);
|
|
98
|
+
} finally {
|
|
99
|
+
fs.unlinkSync(filePath);
|
|
100
|
+
if (response?.data?.url) {
|
|
101
|
+
await cleanupHashAndFile(hash, response.data.url, baseUrl);
|
|
96
102
|
}
|
|
103
|
+
}
|
|
97
104
|
});
|
|
98
105
|
|
|
99
106
|
// Test: Upload with GCS backup verification
|
|
100
|
-
test.serial(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
107
|
+
test.serial("should create GCS backup when configured", async (t) => {
|
|
108
|
+
if (!isGCSConfigured()) {
|
|
109
|
+
t.pass("Skipping test - GCS not configured");
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const fileContent = "test content";
|
|
114
|
+
const filePath = await createTestFile(fileContent, "txt");
|
|
115
|
+
const requestId = uuidv4();
|
|
116
|
+
let response;
|
|
105
117
|
|
|
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
|
-
|
|
118
|
+
try {
|
|
119
|
+
response = await uploadFile(filePath, requestId);
|
|
120
|
+
t.is(response.status, 200, "Upload should succeed");
|
|
121
|
+
t.truthy(response.data.url, "Should have primary storage URL");
|
|
122
|
+
t.truthy(response.data.gcs, "Should have GCS backup URL");
|
|
123
|
+
t.true(
|
|
124
|
+
response.data.gcs.startsWith("gs://"),
|
|
125
|
+
"GCS URL should use gs:// protocol",
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
// Verify file exists in both storages
|
|
129
|
+
const primaryResponse = await axios.get(response.data.url);
|
|
130
|
+
t.is(primaryResponse.status, 200, "Primary file should be accessible");
|
|
131
|
+
t.is(
|
|
132
|
+
primaryResponse.data,
|
|
133
|
+
fileContent,
|
|
134
|
+
"Primary file content should match",
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
// GCS file should be accessible through the primary URL
|
|
138
|
+
// since we can't directly access gs:// URLs
|
|
139
|
+
const gcsResponse = await axios.get(response.data.url);
|
|
140
|
+
t.is(gcsResponse.status, 200, "GCS file should be accessible");
|
|
141
|
+
t.is(gcsResponse.data, fileContent, "GCS file content should match");
|
|
142
|
+
} finally {
|
|
143
|
+
fs.unlinkSync(filePath);
|
|
144
|
+
if (response?.data?.url) {
|
|
145
|
+
await cleanupHashAndFile(null, response.data.url, baseUrl);
|
|
133
146
|
}
|
|
147
|
+
}
|
|
134
148
|
});
|
|
135
149
|
|
|
136
150
|
// Test: Upload with large file
|
|
137
|
-
test.serial(
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
151
|
+
test.serial("should handle large file upload", async (t) => {
|
|
152
|
+
const largeContent = "x".repeat(10 * 1024 * 1024); // 10MB
|
|
153
|
+
const filePath = await createTestFile(largeContent, "txt");
|
|
154
|
+
const requestId = uuidv4();
|
|
155
|
+
let response;
|
|
156
|
+
|
|
157
|
+
try {
|
|
158
|
+
response = await uploadFile(filePath, requestId);
|
|
159
|
+
t.is(response.status, 200, "Large file upload should succeed");
|
|
160
|
+
t.truthy(response.data.url, "Should have file URL");
|
|
161
|
+
|
|
162
|
+
// Verify file content
|
|
163
|
+
const fileResponse = await axios.get(response.data.url);
|
|
164
|
+
t.is(fileResponse.status, 200, "File should be accessible");
|
|
165
|
+
t.is(
|
|
166
|
+
fileResponse.data.length,
|
|
167
|
+
largeContent.length,
|
|
168
|
+
"File size should match",
|
|
169
|
+
);
|
|
170
|
+
} finally {
|
|
171
|
+
fs.unlinkSync(filePath);
|
|
172
|
+
if (response?.data?.url) {
|
|
173
|
+
await cleanupHashAndFile(null, response.data.url, baseUrl);
|
|
157
174
|
}
|
|
175
|
+
}
|
|
158
176
|
});
|
|
159
177
|
|
|
160
178
|
// Test: Upload with special characters in filename
|
|
161
|
-
test(
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
}
|
|
179
|
+
test("should handle special characters in filename", async (t) => {
|
|
180
|
+
const fileContent = "test content";
|
|
181
|
+
const specialFilename = `test file with spaces and special chars !@#$%^&*()_+-=[]{}|;:,.<>?${uuidv4()}.txt`;
|
|
182
|
+
const filePath = await createTestFile(fileContent, specialFilename);
|
|
183
|
+
const requestId = uuidv4();
|
|
184
|
+
let response;
|
|
185
|
+
|
|
186
|
+
try {
|
|
187
|
+
response = await uploadFile(filePath, requestId);
|
|
188
|
+
t.is(response.status, 200, "Upload should succeed");
|
|
189
|
+
t.truthy(response.data.url, "Should have file URL");
|
|
190
|
+
t.truthy(response.data.filename, "Should have filename in response");
|
|
191
|
+
|
|
192
|
+
// Verify file is accessible
|
|
193
|
+
const fileResponse = await axios.get(response.data.url);
|
|
194
|
+
t.is(fileResponse.status, 200, "File should be accessible");
|
|
195
|
+
t.is(fileResponse.data, fileContent, "File content should match");
|
|
196
|
+
} finally {
|
|
197
|
+
fs.unlinkSync(filePath);
|
|
198
|
+
if (response?.data?.url) {
|
|
199
|
+
await cleanupHashAndFile(null, response.data.url, baseUrl);
|
|
183
200
|
}
|
|
201
|
+
}
|
|
184
202
|
});
|
|
185
203
|
|
|
186
204
|
// Test: Upload with concurrent requests
|
|
187
|
-
test.serial(
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
205
|
+
test.serial("should handle concurrent uploads", async (t) => {
|
|
206
|
+
const requestId = uuidv4();
|
|
207
|
+
const uploads = [];
|
|
208
|
+
const numUploads = 5;
|
|
209
|
+
let responses = []; // Move declaration outside try block
|
|
210
|
+
|
|
211
|
+
// Create and upload multiple files concurrently
|
|
212
|
+
for (let i = 0; i < numUploads; i++) {
|
|
213
|
+
const fileContent = `test content ${i}`;
|
|
214
|
+
const filePath = await createTestFile(fileContent, "txt");
|
|
215
|
+
uploads.push({
|
|
216
|
+
filePath,
|
|
217
|
+
promise: uploadFile(filePath, requestId),
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
try {
|
|
222
|
+
// Wait for all uploads to complete
|
|
223
|
+
responses = await Promise.all(uploads.map((u) => u.promise));
|
|
224
|
+
|
|
225
|
+
// Verify all uploads succeeded
|
|
226
|
+
responses.forEach((response, i) => {
|
|
227
|
+
t.is(response.status, 200, `Upload ${i} should succeed`);
|
|
228
|
+
t.truthy(response.data.url, `Upload ${i} should have URL`);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
// Verify all files are accessible
|
|
232
|
+
for (const response of responses) {
|
|
233
|
+
const fileResponse = await axios.get(response.data.url);
|
|
234
|
+
t.is(fileResponse.status, 200, "File should be accessible");
|
|
201
235
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
// Verify all uploads succeeded
|
|
208
|
-
responses.forEach((response, i) => {
|
|
209
|
-
t.is(response.status, 200, `Upload ${i} should succeed`);
|
|
210
|
-
t.truthy(response.data.url, `Upload ${i} should have URL`);
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
// Verify all files are accessible
|
|
214
|
-
for (const response of responses) {
|
|
215
|
-
const fileResponse = await axios.get(response.data.url);
|
|
216
|
-
t.is(fileResponse.status, 200, 'File should be accessible');
|
|
217
|
-
}
|
|
218
|
-
} finally {
|
|
219
|
-
// Cleanup all files
|
|
220
|
-
for (const upload of uploads) {
|
|
221
|
-
fs.unlinkSync(upload.filePath);
|
|
222
|
-
}
|
|
223
|
-
// Cleanup uploaded files
|
|
224
|
-
for (const response of responses) {
|
|
225
|
-
if (response?.data?.url) {
|
|
226
|
-
await cleanupHashAndFile(null, response.data.url, baseUrl);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
236
|
+
} finally {
|
|
237
|
+
// Cleanup all files
|
|
238
|
+
for (const upload of uploads) {
|
|
239
|
+
fs.unlinkSync(upload.filePath);
|
|
229
240
|
}
|
|
241
|
+
// Cleanup uploaded files
|
|
242
|
+
for (const response of responses) {
|
|
243
|
+
if (response?.data?.url) {
|
|
244
|
+
await cleanupHashAndFile(null, response.data.url, baseUrl);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
230
248
|
});
|
|
231
249
|
|
|
232
250
|
// Test: Upload with missing file
|
|
233
|
-
test.serial(
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
251
|
+
test.serial("should handle missing file in request", async (t) => {
|
|
252
|
+
const form = new FormData();
|
|
253
|
+
form.append("requestId", uuidv4());
|
|
254
|
+
|
|
255
|
+
const response = await axios.post(baseUrl, form, {
|
|
256
|
+
headers: {
|
|
257
|
+
...form.getHeaders(),
|
|
258
|
+
"Content-Type": "multipart/form-data",
|
|
259
|
+
},
|
|
260
|
+
validateStatus: (status) => true,
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
t.is(response.status, 400, "Should reject request without file");
|
|
264
|
+
t.is(
|
|
265
|
+
response.data,
|
|
266
|
+
"No file provided in request",
|
|
267
|
+
"Should return correct error message",
|
|
268
|
+
);
|
|
247
269
|
});
|
|
248
270
|
|
|
249
271
|
// Test: Upload with empty file
|
|
250
|
-
test.serial(
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
272
|
+
test.serial("should handle empty file upload", async (t) => {
|
|
273
|
+
const filePath = await createTestFile("", "txt");
|
|
274
|
+
const requestId = uuidv4();
|
|
275
|
+
let response;
|
|
276
|
+
|
|
277
|
+
try {
|
|
278
|
+
response = await uploadFile(filePath, requestId);
|
|
279
|
+
t.is(response.status, 400, "Should reject empty file");
|
|
280
|
+
t.is(
|
|
281
|
+
response.data,
|
|
282
|
+
"Invalid file: file is empty",
|
|
283
|
+
"Should return correct error message",
|
|
284
|
+
);
|
|
285
|
+
} finally {
|
|
286
|
+
fs.unlinkSync(filePath);
|
|
287
|
+
}
|
|
262
288
|
});
|
|
263
289
|
|
|
264
290
|
// Test: Upload without requestId should generate one
|
|
265
|
-
test.serial(
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
}
|
|
291
|
+
test.serial("should generate requestId when not provided", async (t) => {
|
|
292
|
+
const fileContent = "test content";
|
|
293
|
+
const filePath = await createTestFile(fileContent, "txt");
|
|
294
|
+
let response;
|
|
295
|
+
|
|
296
|
+
try {
|
|
297
|
+
response = await uploadFile(filePath);
|
|
298
|
+
t.is(response.status, 200, "Upload should succeed without requestId");
|
|
299
|
+
t.truthy(response.data.url, "Should have file URL");
|
|
300
|
+
|
|
301
|
+
// Extract requestId from the URL
|
|
302
|
+
const urlParts = response.data.url.split("/");
|
|
303
|
+
const requestId = urlParts[urlParts.length - 2]; // requestId is the second-to-last part of the URL
|
|
304
|
+
t.truthy(requestId, "URL should contain a requestId");
|
|
305
|
+
t.true(requestId.length > 0, "requestId should not be empty");
|
|
306
|
+
|
|
307
|
+
// Verify file is accessible
|
|
308
|
+
const fileResponse = await axios.get(response.data.url);
|
|
309
|
+
t.is(fileResponse.status, 200, "File should be accessible");
|
|
310
|
+
t.is(fileResponse.data, fileContent, "File content should match");
|
|
311
|
+
} finally {
|
|
312
|
+
fs.unlinkSync(filePath);
|
|
313
|
+
if (response?.data?.url) {
|
|
314
|
+
await cleanupHashAndFile(null, response.data.url, baseUrl);
|
|
290
315
|
}
|
|
291
|
-
}
|
|
316
|
+
}
|
|
317
|
+
});
|