@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,13 +1,13 @@
|
|
|
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 XLSX from
|
|
9
|
-
import { port } from
|
|
10
|
-
import { cleanupHashAndFile, createTestMediaFile } from
|
|
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 XLSX from "xlsx";
|
|
9
|
+
import { port } from "../src/start.js";
|
|
10
|
+
import { cleanupHashAndFile, createTestMediaFile } from "./testUtils.helper.js";
|
|
11
11
|
|
|
12
12
|
const __filename = fileURLToPath(import.meta.url);
|
|
13
13
|
const __dirname = path.dirname(__filename);
|
|
@@ -15,293 +15,329 @@ const baseUrl = `http://localhost:${port}/api/CortexFileHandler`;
|
|
|
15
15
|
|
|
16
16
|
// Helper function to create test files
|
|
17
17
|
async function createTestFile(content, extension) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
const testDir = path.join(__dirname, "test-files");
|
|
19
|
+
if (!fs.existsSync(testDir)) {
|
|
20
|
+
fs.mkdirSync(testDir, { recursive: true });
|
|
21
|
+
}
|
|
22
|
+
// Use a shorter filename to avoid filesystem limits
|
|
23
|
+
const filename = path.join(
|
|
24
|
+
testDir,
|
|
25
|
+
`test-${uuidv4().slice(0, 8)}.${extension}`,
|
|
26
|
+
);
|
|
27
|
+
fs.writeFileSync(filename, content);
|
|
28
|
+
return filename;
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
// Helper function to upload file
|
|
29
32
|
async function uploadFile(filePath, requestId = null, hash = null) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
33
|
+
const form = new FormData();
|
|
34
|
+
form.append("file", fs.createReadStream(filePath));
|
|
35
|
+
if (requestId) form.append("requestId", requestId);
|
|
36
|
+
if (hash) form.append("hash", hash);
|
|
37
|
+
|
|
38
|
+
const response = await axios.post(baseUrl, form, {
|
|
39
|
+
headers: {
|
|
40
|
+
...form.getHeaders(),
|
|
41
|
+
"Content-Type": "multipart/form-data",
|
|
42
|
+
},
|
|
43
|
+
validateStatus: (status) => true,
|
|
44
|
+
timeout: 30000,
|
|
45
|
+
maxContentLength: Infinity,
|
|
46
|
+
maxBodyLength: Infinity,
|
|
47
|
+
});
|
|
45
48
|
|
|
46
|
-
|
|
49
|
+
return response;
|
|
47
50
|
}
|
|
48
51
|
|
|
49
52
|
// Setup: Create test directory
|
|
50
53
|
test.before(async (t) => {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
const testDir = path.join(__dirname, "test-files");
|
|
55
|
+
await fs.promises.mkdir(testDir, { recursive: true });
|
|
56
|
+
t.context = { testDir };
|
|
54
57
|
});
|
|
55
58
|
|
|
56
59
|
// Test: Document processing with save=true
|
|
57
|
-
test.serial(
|
|
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
|
-
|
|
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
|
-
|
|
60
|
+
test.serial("should process document with save=true", async (t) => {
|
|
61
|
+
// Create a minimal XLSX workbook in-memory
|
|
62
|
+
const workbook = XLSX.utils.book_new();
|
|
63
|
+
const worksheet = XLSX.utils.aoa_to_sheet([
|
|
64
|
+
["Name", "Score"],
|
|
65
|
+
["Alice", 10],
|
|
66
|
+
["Bob", 8],
|
|
67
|
+
]);
|
|
68
|
+
XLSX.utils.book_append_sheet(workbook, worksheet, "Sheet1");
|
|
69
|
+
|
|
70
|
+
// Write it to a temp file inside the test directory
|
|
71
|
+
const filePath = path.join(t.context.testDir, `${uuidv4()}.xlsx`);
|
|
72
|
+
XLSX.writeFile(workbook, filePath);
|
|
73
|
+
|
|
74
|
+
const requestId = uuidv4();
|
|
75
|
+
let response;
|
|
76
|
+
let convertedUrl;
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
// First upload the file
|
|
80
|
+
response = await uploadFile(filePath, requestId);
|
|
81
|
+
t.is(response.status, 200, "Upload should succeed");
|
|
82
|
+
|
|
83
|
+
// Then process with save=true
|
|
84
|
+
const processResponse = await axios.get(baseUrl, {
|
|
85
|
+
params: {
|
|
86
|
+
uri: response.data.url,
|
|
87
|
+
requestId,
|
|
88
|
+
save: true,
|
|
89
|
+
},
|
|
90
|
+
validateStatus: (status) => true,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
t.is(processResponse.status, 200, "Document processing should succeed");
|
|
94
|
+
t.truthy(processResponse.data.url, "Should return converted file URL");
|
|
95
|
+
t.true(
|
|
96
|
+
processResponse.data.url.includes(".csv"),
|
|
97
|
+
"Should return a CSV URL",
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
// Store the converted URL for cleanup
|
|
101
|
+
convertedUrl = processResponse.data.url;
|
|
102
|
+
|
|
103
|
+
// Verify the converted file is accessible immediately after conversion
|
|
104
|
+
const fileResponse = await axios.get(convertedUrl, {
|
|
105
|
+
validateStatus: (status) => true,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
t.is(fileResponse.status, 200, "Converted file should be accessible");
|
|
109
|
+
t.true(
|
|
110
|
+
fileResponse.data.includes("Name,Score"),
|
|
111
|
+
"CSV should contain headers",
|
|
112
|
+
);
|
|
113
|
+
t.true(fileResponse.data.includes("Alice,10"), "CSV should contain data");
|
|
114
|
+
} finally {
|
|
115
|
+
// Clean up both the original and converted files
|
|
116
|
+
if (response?.data?.url) {
|
|
117
|
+
await cleanupHashAndFile(null, response.data.url, baseUrl);
|
|
115
118
|
}
|
|
119
|
+
if (convertedUrl) {
|
|
120
|
+
await cleanupHashAndFile(null, convertedUrl, baseUrl);
|
|
121
|
+
}
|
|
122
|
+
// Clean up the local file last
|
|
123
|
+
fs.unlinkSync(filePath);
|
|
124
|
+
}
|
|
116
125
|
});
|
|
117
126
|
|
|
118
127
|
// Test: Document processing with save=false
|
|
119
|
-
test.serial(
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
128
|
+
test.serial("should process document with save=false", async (t) => {
|
|
129
|
+
const fileContent = "Test document content";
|
|
130
|
+
const filePath = await createTestFile(fileContent, "txt");
|
|
131
|
+
const requestId = uuidv4();
|
|
132
|
+
let response;
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
// First upload the file
|
|
136
|
+
response = await uploadFile(filePath, requestId);
|
|
137
|
+
t.is(response.status, 200, "Upload should succeed");
|
|
138
|
+
|
|
139
|
+
// Then process with save=false
|
|
140
|
+
const processResponse = await axios.get(baseUrl, {
|
|
141
|
+
params: {
|
|
142
|
+
uri: response.data.url,
|
|
143
|
+
requestId,
|
|
144
|
+
save: false,
|
|
145
|
+
},
|
|
146
|
+
validateStatus: (status) => true,
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
t.is(processResponse.status, 200, "Document processing should succeed");
|
|
150
|
+
t.true(
|
|
151
|
+
Array.isArray(processResponse.data),
|
|
152
|
+
"Should return array of chunks",
|
|
153
|
+
);
|
|
154
|
+
t.true(processResponse.data.length > 0, "Should return non-empty chunks");
|
|
155
|
+
// ensure the first chunk contains the right content
|
|
156
|
+
t.true(
|
|
157
|
+
processResponse.data[0].includes(fileContent),
|
|
158
|
+
"First chunk should contain the right content",
|
|
159
|
+
);
|
|
160
|
+
} finally {
|
|
161
|
+
fs.unlinkSync(filePath);
|
|
162
|
+
if (response?.data?.url) {
|
|
163
|
+
await cleanupHashAndFile(null, response.data.url, baseUrl);
|
|
150
164
|
}
|
|
165
|
+
}
|
|
151
166
|
});
|
|
152
167
|
|
|
153
168
|
// Test: Media file chunking
|
|
154
|
-
test.serial(
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
169
|
+
test.serial("should chunk media file", async (t) => {
|
|
170
|
+
// Create a proper 10-second test audio file (MP3)
|
|
171
|
+
const testDir = path.join(__dirname, "test-files");
|
|
172
|
+
if (!fs.existsSync(testDir)) {
|
|
173
|
+
fs.mkdirSync(testDir, { recursive: true });
|
|
174
|
+
}
|
|
175
|
+
const filePath = path.join(testDir, `test-${uuidv4()}.mp3`);
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
await createTestMediaFile(filePath, 10);
|
|
179
|
+
|
|
180
|
+
const requestId = uuidv4();
|
|
181
|
+
let response;
|
|
161
182
|
|
|
162
183
|
try {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
} finally {
|
|
192
|
-
if (response?.data?.url) {
|
|
193
|
-
await cleanupHashAndFile(null, response.data.url, baseUrl);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
184
|
+
// First upload the file
|
|
185
|
+
response = await uploadFile(filePath, requestId);
|
|
186
|
+
t.is(response.status, 200, "Upload should succeed");
|
|
187
|
+
|
|
188
|
+
// Then request chunking
|
|
189
|
+
const chunkResponse = await axios.get(baseUrl, {
|
|
190
|
+
params: {
|
|
191
|
+
uri: response.data.url,
|
|
192
|
+
requestId,
|
|
193
|
+
},
|
|
194
|
+
validateStatus: (status) => true,
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
t.is(chunkResponse.status, 200, "Chunking should succeed");
|
|
198
|
+
t.true(
|
|
199
|
+
Array.isArray(chunkResponse.data),
|
|
200
|
+
"Should return array of chunks",
|
|
201
|
+
);
|
|
202
|
+
t.true(chunkResponse.data.length > 0, "Should return non-empty chunks");
|
|
203
|
+
|
|
204
|
+
// Verify each chunk has required properties
|
|
205
|
+
chunkResponse.data.forEach((chunk) => {
|
|
206
|
+
t.truthy(chunk.uri, "Chunk should have URI");
|
|
207
|
+
t.true(
|
|
208
|
+
typeof chunk.offset === "number",
|
|
209
|
+
"Chunk should have a numeric offset",
|
|
210
|
+
);
|
|
211
|
+
});
|
|
196
212
|
} finally {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
213
|
+
if (response?.data?.url) {
|
|
214
|
+
await cleanupHashAndFile(null, response.data.url, baseUrl);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
} finally {
|
|
218
|
+
// Clean up the test file
|
|
219
|
+
if (fs.existsSync(filePath)) {
|
|
220
|
+
fs.unlinkSync(filePath);
|
|
201
221
|
}
|
|
222
|
+
}
|
|
202
223
|
});
|
|
203
224
|
|
|
204
225
|
// Test: Remote file fetching with fetch parameter
|
|
205
|
-
test.serial(
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
226
|
+
test.serial("should fetch remote file", async (t) => {
|
|
227
|
+
const requestId = uuidv4();
|
|
228
|
+
const remoteUrl = "https://example.com/test.txt";
|
|
229
|
+
|
|
230
|
+
const response = await axios.get(baseUrl, {
|
|
231
|
+
params: {
|
|
232
|
+
fetch: remoteUrl,
|
|
233
|
+
requestId,
|
|
234
|
+
},
|
|
235
|
+
validateStatus: (status) => true,
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
t.is(response.status, 400, "Should reject invalid URL");
|
|
239
|
+
t.is(
|
|
240
|
+
response.data,
|
|
241
|
+
"Invalid or inaccessible URL",
|
|
242
|
+
"Should return correct error message",
|
|
243
|
+
);
|
|
219
244
|
});
|
|
220
245
|
|
|
221
246
|
// Test: Redis caching behavior for remote files
|
|
222
|
-
test.serial(
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
+
test.serial("should cache remote files in Redis", async (t) => {
|
|
248
|
+
const requestId = uuidv4();
|
|
249
|
+
const hash = "test-cache-" + uuidv4();
|
|
250
|
+
|
|
251
|
+
// First request should cache the file
|
|
252
|
+
const firstResponse = await axios.get(baseUrl, {
|
|
253
|
+
params: {
|
|
254
|
+
fetch: "https://example.com/test.txt",
|
|
255
|
+
requestId,
|
|
256
|
+
hash,
|
|
257
|
+
timeout: 10000,
|
|
258
|
+
},
|
|
259
|
+
validateStatus: (status) => true,
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
// Second request should return cached result
|
|
263
|
+
const secondResponse = await axios.get(baseUrl, {
|
|
264
|
+
params: {
|
|
265
|
+
hash,
|
|
266
|
+
checkHash: true,
|
|
267
|
+
},
|
|
268
|
+
validateStatus: (status) => true,
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
t.is(secondResponse.status, 404, "Should return 404 for invalid URL");
|
|
247
272
|
});
|
|
248
273
|
|
|
249
274
|
// Test: Error cases for invalid URLs
|
|
250
|
-
test.serial(
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
275
|
+
test.serial("should handle invalid URLs", async (t) => {
|
|
276
|
+
const requestId = uuidv4();
|
|
277
|
+
const invalidUrls = [
|
|
278
|
+
"not-a-url",
|
|
279
|
+
"http://",
|
|
280
|
+
"https://",
|
|
281
|
+
"ftp://invalid",
|
|
282
|
+
"file:///nonexistent",
|
|
283
|
+
];
|
|
284
|
+
|
|
285
|
+
for (const url of invalidUrls) {
|
|
286
|
+
const response = await axios.get(baseUrl, {
|
|
287
|
+
params: {
|
|
288
|
+
uri: url,
|
|
289
|
+
requestId,
|
|
290
|
+
},
|
|
291
|
+
validateStatus: (status) => true,
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
t.is(response.status, 400, `Should reject invalid URL: ${url}`);
|
|
295
|
+
t.true(
|
|
296
|
+
response.data.includes("Invalid") || response.data.includes("Error"),
|
|
297
|
+
"Should return error message",
|
|
298
|
+
);
|
|
299
|
+
}
|
|
272
300
|
});
|
|
273
301
|
|
|
274
302
|
// Test: Long filename handling
|
|
275
|
-
test.serial(
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
303
|
+
test.serial("should handle long filenames", async (t) => {
|
|
304
|
+
const fileContent = "Test content";
|
|
305
|
+
const filePath = await createTestFile(fileContent, "txt");
|
|
306
|
+
const requestId = uuidv4();
|
|
307
|
+
let response;
|
|
308
|
+
|
|
309
|
+
try {
|
|
310
|
+
// First upload the file
|
|
311
|
+
response = await uploadFile(filePath, requestId);
|
|
312
|
+
t.is(response.status, 200, "Upload should succeed");
|
|
313
|
+
|
|
314
|
+
// Create a URL with a very long filename
|
|
315
|
+
const longFilename = "a".repeat(1100) + ".txt";
|
|
316
|
+
const longUrl = response.data.url.replace(/[^/]+$/, longFilename);
|
|
317
|
+
|
|
318
|
+
// Try to process the file with the long filename
|
|
319
|
+
const processResponse = await axios.get(baseUrl, {
|
|
320
|
+
params: {
|
|
321
|
+
uri: longUrl,
|
|
322
|
+
requestId,
|
|
323
|
+
},
|
|
324
|
+
validateStatus: (status) => true,
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
t.is(
|
|
328
|
+
processResponse.status,
|
|
329
|
+
400,
|
|
330
|
+
"Should reject URL with too long filename",
|
|
331
|
+
);
|
|
332
|
+
t.is(
|
|
333
|
+
processResponse.data,
|
|
334
|
+
"URL pathname is too long",
|
|
335
|
+
"Should return correct error message",
|
|
336
|
+
);
|
|
337
|
+
} finally {
|
|
338
|
+
fs.unlinkSync(filePath);
|
|
339
|
+
if (response?.data?.url) {
|
|
340
|
+
await cleanupHashAndFile(null, response.data.url, baseUrl);
|
|
306
341
|
}
|
|
307
|
-
}
|
|
342
|
+
}
|
|
343
|
+
});
|