mirror of
https://github.com/kmc7468/arkvault.git
synced 2026-11-04 08:10:28 +09:00
서버 코드를 Router, Service, Repository 계층으로 분리하고 오류 처리 및 파일 삭제 로직 개선
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ed732be999
commit
6a6aa1765b
72 files changed
+1928
-1509
No files matched your search
@@ -1,5 +1,8 @@
|
||||
import { createHash } from "crypto";
|
||||
import { Readable } from "stream";
|
||||
import { beforeEach, describe, expect, it } from "vitest";
|
||||
import { UploadRepo } from "#lib/server/db/index.js";
|
||||
import { FileService, UploadService } from "#lib/server/services/index.js";
|
||||
import { isChunkUploaded } from "#lib/server/services/upload.js";
|
||||
import { ciphertext, createUser, newEntryParams, resetDatabase } from "../helpers/database";
|
||||
|
||||
@@ -33,3 +36,66 @@ describe("upload session bitmap", () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("upload completion", () => {
|
||||
it("registers the file only once when completed concurrently", async () => {
|
||||
const { userId } = await createUser();
|
||||
const { uploadId } = await UploadService.startFileUpload({
|
||||
...newEntryParams(userId, "root"),
|
||||
totalChunks: 1,
|
||||
hskVersion: null,
|
||||
contentType: "image/png",
|
||||
encCreatedAt: null,
|
||||
encLastModifiedAt: ciphertext(),
|
||||
});
|
||||
|
||||
const chunk = Buffer.alloc(100, 1);
|
||||
await UploadService.uploadChunk(userId, uploadId, 1, Readable.from([chunk]));
|
||||
const hash = createHash("sha256").update(chunk).digest("base64");
|
||||
|
||||
const results = await Promise.allSettled([
|
||||
UploadService.completeFileUpload(userId, uploadId, null, hash),
|
||||
UploadService.completeFileUpload(userId, uploadId, null, hash),
|
||||
]);
|
||||
|
||||
expect(results.filter(({ status }) => status === "fulfilled")).toHaveLength(1);
|
||||
expect(results.find(({ status }) => status === "rejected")).toMatchObject({
|
||||
reason: { code: "NOT_FOUND" },
|
||||
});
|
||||
expect(await FileService.getAllFileIds(userId)).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("discards corrupted uploads", async () => {
|
||||
const { userId } = await createUser();
|
||||
const { uploadId } = await UploadService.startFileUpload({
|
||||
...newEntryParams(userId, "root"),
|
||||
totalChunks: 1,
|
||||
hskVersion: null,
|
||||
contentType: "image/png",
|
||||
encCreatedAt: null,
|
||||
encLastModifiedAt: ciphertext(),
|
||||
});
|
||||
await UploadService.uploadChunk(userId, uploadId, 1, Readable.from([Buffer.alloc(100)]));
|
||||
|
||||
await expect(
|
||||
UploadService.completeFileUpload(userId, uploadId, null, "invalid"),
|
||||
).rejects.toMatchObject({ code: "CONFLICT" });
|
||||
expect(await UploadRepo.getUploadSession(uploadId, userId)).toBeNull();
|
||||
});
|
||||
|
||||
it("rejects chunks of invalid sizes", async () => {
|
||||
const { userId } = await createUser();
|
||||
const { uploadId } = await UploadService.startFileUpload({
|
||||
...newEntryParams(userId, "root"),
|
||||
totalChunks: 2,
|
||||
hskVersion: null,
|
||||
contentType: "image/png",
|
||||
encCreatedAt: null,
|
||||
encLastModifiedAt: ciphertext(),
|
||||
});
|
||||
|
||||
await expect(
|
||||
UploadService.uploadChunk(userId, uploadId, 1, Readable.from([Buffer.alloc(100)])),
|
||||
).rejects.toMatchObject({ code: "BAD_REQUEST" });
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user