@julesl23/s5js
Version:
Enhanced TypeScript SDK for S5 decentralized storage with path-based API, media processing, and directory utilities
266 lines • 11.2 kB
JavaScript
import { describe, test, expect, beforeEach } from "vitest";
import { FS5 } from "../../src/fs/fs5.js";
// Mock classes for testing
class MockAPI {
}
class MockIdentity {
fsRootKey = new Uint8Array(32).fill(42);
}
// Test class that exposes private methods for testing
class TestableFS5 extends FS5 {
// Expose private methods for testing
testGetOldestTimestamp(dir) {
return this._getOldestTimestamp(dir);
}
testGetNewestTimestamp(dir) {
return this._getNewestTimestamp(dir);
}
testExtractFileMetadata(file) {
return this._extractFileMetadata(file);
}
testExtractDirMetadata(dir) {
return this._extractDirMetadata(dir);
}
}
describe("Metadata Extraction", () => {
let fs5;
const now = Math.floor(Date.now() / 1000);
beforeEach(() => {
fs5 = new TestableFS5(new MockAPI(), new MockIdentity());
});
describe("_getOldestTimestamp", () => {
test("should find oldest timestamp from files", () => {
const dir = {
magic: "S5.pro",
header: {},
dirs: new Map(),
files: new Map([
["file1.txt", { hash: new Uint8Array(32).fill(1), size: 100n, timestamp: now - 3600 }],
["file2.txt", { hash: new Uint8Array(32).fill(1), size: 200n, timestamp: now - 7200 }], // oldest
["file3.txt", { hash: new Uint8Array(32).fill(1), size: 300n, timestamp: now - 1800 }]
])
};
const oldest = fs5.testGetOldestTimestamp(dir);
expect(oldest).toBe(now - 7200);
});
test("should find oldest timestamp from directories", () => {
const dir = {
magic: "S5.pro",
header: {},
dirs: new Map([
["dir1", { link: { type: 'fixed_hash_blake3', hash: new Uint8Array(32) }, ts_seconds: now - 1000 }],
["dir2", { link: { type: 'fixed_hash_blake3', hash: new Uint8Array(32) }, ts_seconds: now - 5000 }], // oldest
["dir3", { link: { type: 'fixed_hash_blake3', hash: new Uint8Array(32) }, ts_seconds: now - 2000 }]
]),
files: new Map()
};
const oldest = fs5.testGetOldestTimestamp(dir);
expect(oldest).toBe(now - 5000);
});
test("should find oldest timestamp from mixed content", () => {
const dir = {
magic: "S5.pro",
header: {},
dirs: new Map([
["dir1", { link: { type: 'fixed_hash_blake3', hash: new Uint8Array(32) }, ts_seconds: now - 3000 }]
]),
files: new Map([
["file1.txt", { hash: new Uint8Array(32).fill(1), size: 100n, timestamp: now - 4000 }] // oldest
])
};
const oldest = fs5.testGetOldestTimestamp(dir);
expect(oldest).toBe(now - 4000);
});
test("should return undefined for empty directory", () => {
const dir = {
magic: "S5.pro",
header: {},
dirs: new Map(),
files: new Map()
};
const oldest = fs5.testGetOldestTimestamp(dir);
expect(oldest).toBeUndefined();
});
test("should handle missing timestamps", () => {
const dir = {
magic: "S5.pro",
header: {},
dirs: new Map([
["dir1", { link: { type: 'fixed_hash_blake3', hash: new Uint8Array(32) } }] // no timestamp
]),
files: new Map([
["file1.txt", { hash: new Uint8Array(32).fill(1), size: 100n }], // no timestamp
["file2.txt", { hash: new Uint8Array(32).fill(1), size: 200n, timestamp: now - 1000 }]
])
};
const oldest = fs5.testGetOldestTimestamp(dir);
expect(oldest).toBe(now - 1000);
});
});
describe("_getNewestTimestamp", () => {
test("should find newest timestamp from files", () => {
const dir = {
magic: "S5.pro",
header: {},
dirs: new Map(),
files: new Map([
["file1.txt", { hash: new Uint8Array(32).fill(1), size: 100n, timestamp: now - 3600 }],
["file2.txt", { hash: new Uint8Array(32).fill(1), size: 200n, timestamp: now - 600 }], // newest
["file3.txt", { hash: new Uint8Array(32).fill(1), size: 300n, timestamp: now - 1800 }]
])
};
const newest = fs5.testGetNewestTimestamp(dir);
expect(newest).toBe(now - 600);
});
test("should find newest timestamp from directories", () => {
const dir = {
magic: "S5.pro",
header: {},
dirs: new Map([
["dir1", { link: { type: 'fixed_hash_blake3', hash: new Uint8Array(32) }, ts_seconds: now - 1000 }],
["dir2", { link: { type: 'fixed_hash_blake3', hash: new Uint8Array(32) }, ts_seconds: now - 500 }], // newest
["dir3", { link: { type: 'fixed_hash_blake3', hash: new Uint8Array(32) }, ts_seconds: now - 2000 }]
]),
files: new Map()
};
const newest = fs5.testGetNewestTimestamp(dir);
expect(newest).toBe(now - 500);
});
test("should return undefined for directory without timestamps", () => {
const dir = {
magic: "S5.pro",
header: {},
dirs: new Map([
["dir1", { link: { type: 'fixed_hash_blake3', hash: new Uint8Array(32) } }]
]),
files: new Map([
["file1.txt", { hash: new Uint8Array(32).fill(1), size: 100n }]
])
};
const newest = fs5.testGetNewestTimestamp(dir);
expect(newest).toBeUndefined();
});
});
describe("_extractFileMetadata", () => {
test("should extract basic file metadata", () => {
const file = {
hash: new Uint8Array(32).fill(1),
size: 12345n,
media_type: "text/plain",
timestamp: now
};
const metadata = fs5.testExtractFileMetadata(file);
expect(metadata).toEqual({
size: 12345,
mediaType: "text/plain",
timestamp: new Date(now * 1000).toISOString(),
custom: undefined
});
});
test("should handle missing media type", () => {
const file = {
hash: new Uint8Array(32).fill(1),
size: 12345n
};
const metadata = fs5.testExtractFileMetadata(file);
expect(metadata.mediaType).toBe("application/octet-stream");
});
test("should extract location data", () => {
const file = {
hash: new Uint8Array(32).fill(1),
size: 12345n,
locations: [
{ type: 'multihash_blake3', hash: new Uint8Array(32) }
]
};
const metadata = fs5.testExtractFileMetadata(file);
expect(metadata.locations).toBeDefined();
expect(metadata.locations).toHaveLength(1);
});
test("should detect history", () => {
const file = {
hash: new Uint8Array(32).fill(1),
size: 12345n,
prev: {
hash: new Uint8Array(32).fill(2),
size: 10000n,
timestamp: now - 3600
}
};
const metadata = fs5.testExtractFileMetadata(file);
expect(metadata.hasHistory).toBe(true);
});
test("should extract custom metadata", () => {
const file = {
hash: new Uint8Array(32).fill(1),
size: 12345n,
extra: new Map([
["author", "John Doe"],
["version", "1.0.0"]
])
};
const metadata = fs5.testExtractFileMetadata(file);
expect(metadata.custom).toEqual({
author: "John Doe",
version: "1.0.0"
});
});
test("should handle file without timestamp", () => {
const file = {
hash: new Uint8Array(32).fill(1),
size: 12345n
};
const metadata = fs5.testExtractFileMetadata(file);
expect(metadata.timestamp).toBeUndefined();
});
});
describe("_extractDirMetadata", () => {
test("should extract directory metadata with timestamp", () => {
const dir = {
link: { type: 'fixed_hash_blake3', hash: new Uint8Array(32) },
ts_seconds: now
};
const metadata = fs5.testExtractDirMetadata(dir);
expect(metadata).toEqual({
timestamp: new Date(now * 1000).toISOString(),
extra: undefined
});
});
test("should handle directory without timestamp", () => {
const dir = {
link: { type: 'fixed_hash_blake3', hash: new Uint8Array(32) }
};
const metadata = fs5.testExtractDirMetadata(dir);
expect(metadata.timestamp).toBeUndefined();
});
test("should extract extra metadata", () => {
const dir = {
link: { type: 'fixed_hash_blake3', hash: new Uint8Array(32) },
ts_seconds: now,
extra: new Map([
["description", "Test directory"],
["tags", ["important", "backup"]]
])
};
const metadata = fs5.testExtractDirMetadata(dir);
expect(metadata.extra).toBeInstanceOf(Map);
expect(metadata.extra.get("description")).toBe("Test directory");
expect(metadata.extra.get("tags")).toEqual(["important", "backup"]);
});
});
describe("Integration: getMetadata with new extraction", () => {
test("should return enriched file metadata", async () => {
// This test would require mocking _loadDirectory method
// Due to the complexity of mocking the full file system,
// we'll focus on unit tests for the individual extraction methods
expect(true).toBe(true);
});
test("should return enriched directory metadata with timestamps", async () => {
// This test would require mocking _loadDirectory method
// Due to the complexity of mocking the full file system,
// we'll focus on unit tests for the individual extraction methods
expect(true).toBe(true);
});
});
});
//# sourceMappingURL=metadata-extraction.test.js.map