mirror of
https://github.com/kmc7468/arkvault.git
synced 2026-11-04 08:10:28 +09:00
서버, 클라이언트, 서비스 워커 공용 코드를 lib/shared로 분리하고 브라우저 전용 모듈을 lib/client로 재구성
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6a6aa1765b
commit
aee87fd9b6
82 files changed
+326
-221
No files matched your search
@@ -1,7 +1,13 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { CHUNK_SIZE, ENCRYPTED_CHUNK_SIZE, ENCRYPTION_OVERHEAD } from "#lib/constants/index.js";
|
||||
import { getContentRangeHeader, parseRangeHeader } from "#lib/modules/http.js";
|
||||
import { getDecryptedSize, getEncryptedRange } from "../../src/service-worker/modules/crypto";
|
||||
import {
|
||||
CHUNK_SIZE,
|
||||
ENCRYPTED_CHUNK_SIZE,
|
||||
ENCRYPTION_OVERHEAD,
|
||||
getDecryptedSize,
|
||||
getEncryptedRange,
|
||||
getEncryptedSize,
|
||||
} from "#lib/shared/format/index.js";
|
||||
import { getContentRangeHeader, parseRangeHeader, resolveRange } from "#lib/shared/http.js";
|
||||
|
||||
describe("parseRangeHeader", () => {
|
||||
it("parses byte ranges", () => {
|
||||
@@ -9,6 +15,33 @@ describe("parseRangeHeader", () => {
|
||||
expect(parseRangeHeader("bytes=0-")).toEqual({ start: 0, end: undefined });
|
||||
expect(parseRangeHeader("bytes=10-20")).toEqual({ start: 10, end: 20 });
|
||||
expect(parseRangeHeader("bytes=10-20, 30-40")).toEqual({ start: 10, end: 20 });
|
||||
expect(parseRangeHeader("bytes=-500")).toEqual({ suffixLength: 500 });
|
||||
});
|
||||
|
||||
it("ignores invalid ranges", () => {
|
||||
expect(parseRangeHeader("bytes=-")).toBeUndefined();
|
||||
expect(parseRangeHeader("items=0-1")).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveRange", () => {
|
||||
it("resolves the whole content without a range", () => {
|
||||
expect(resolveRange(undefined, 100)).toEqual({ start: 0, end: 99, total: 100 });
|
||||
});
|
||||
|
||||
it("clamps the end to the content size", () => {
|
||||
expect(resolveRange({ start: 10, end: 1000 }, 100)).toEqual({ start: 10, end: 99, total: 100 });
|
||||
expect(resolveRange({ start: 10 }, 100)).toEqual({ start: 10, end: 99, total: 100 });
|
||||
});
|
||||
|
||||
it("resolves suffix ranges", () => {
|
||||
expect(resolveRange({ suffixLength: 10 }, 100)).toEqual({ start: 90, end: 99, total: 100 });
|
||||
expect(resolveRange({ suffixLength: 1000 }, 100)).toEqual({ start: 0, end: 99, total: 100 });
|
||||
});
|
||||
|
||||
it("rejects unsatisfiable ranges", () => {
|
||||
expect(resolveRange({ start: 100 }, 100)).toBeNull();
|
||||
expect(resolveRange({ start: 20, end: 10 }, 100)).toBeNull();
|
||||
});
|
||||
|
||||
it("formats Content-Range", () => {
|
||||
@@ -19,13 +52,13 @@ describe("parseRangeHeader", () => {
|
||||
});
|
||||
|
||||
describe("encrypted chunk layout", () => {
|
||||
const encryptedSizeOf = (size: number) =>
|
||||
size + Math.ceil(size / CHUNK_SIZE) * ENCRYPTION_OVERHEAD;
|
||||
|
||||
it.each([1, CHUNK_SIZE - 1, CHUNK_SIZE, CHUNK_SIZE + 1, 3 * CHUNK_SIZE + 12345])(
|
||||
"computes the decrypted size of %i bytes",
|
||||
(size) => {
|
||||
expect(getDecryptedSize(encryptedSizeOf(size), false)).toBe(size);
|
||||
expect(getEncryptedSize(size)).toBe(
|
||||
size + Math.ceil(size / CHUNK_SIZE) * ENCRYPTION_OVERHEAD,
|
||||
);
|
||||
expect(getDecryptedSize(getEncryptedSize(size), false)).toBe(size);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -35,7 +68,7 @@ describe("encrypted chunk layout", () => {
|
||||
|
||||
it("maps a plaintext range to whole encrypted chunks", () => {
|
||||
const totalSize = 3 * CHUNK_SIZE + 100;
|
||||
const totalEncryptedSize = encryptedSizeOf(totalSize);
|
||||
const totalEncryptedSize = getEncryptedSize(totalSize);
|
||||
|
||||
expect(getEncryptedRange(0, 10, totalEncryptedSize, false)).toEqual({
|
||||
firstChunkIndex: 0,
|
||||
|
||||
Reference in new issue
Block a user