182 lines
4.4 KiB
TypeScript
182 lines
4.4 KiB
TypeScript
import type {
|
|
ElyAnalyticsDataPoint,
|
|
ElyD1Database,
|
|
ElyD1PreparedStatement,
|
|
ElyR2PutOptions,
|
|
Env,
|
|
} from "../src/bindings.js";
|
|
|
|
export const ACCESS_TOKEN = "D".repeat(48);
|
|
export const PUBLIC_KEY = "a".repeat(64);
|
|
|
|
export interface TestEnvOptions {
|
|
auditEvents?: ElyAnalyticsDataPoint[];
|
|
diagnosticEvents?: ElyAnalyticsDataPoint[];
|
|
d1?: RecordedD1Database;
|
|
kvEntries?: [string, string][];
|
|
kvDeletes?: string[];
|
|
kvReads?: string[];
|
|
r2Deletes?: string[];
|
|
r2Gets?: string[];
|
|
r2Objects?: [string, ArrayBuffer][];
|
|
r2Puts?: RecordedR2Put[];
|
|
}
|
|
|
|
export interface RecordedD1Database extends ElyD1Database {
|
|
batches: number[];
|
|
binds: unknown[][];
|
|
queries: string[];
|
|
}
|
|
|
|
export interface RecordedR2Put {
|
|
key: string;
|
|
payload: ArrayBuffer;
|
|
options: ElyR2PutOptions;
|
|
}
|
|
|
|
interface TestD1DatabaseOptions {
|
|
allRows?: unknown[];
|
|
firstRows?: unknown[];
|
|
}
|
|
|
|
export function testEnv(options: TestEnvOptions): Env {
|
|
const values = new Map(options.kvEntries ?? []);
|
|
return {
|
|
ELY_ENVIRONMENT: "local",
|
|
ELY_AUTH_BASE_URL: "https://elydora.test",
|
|
ELY_AUTH_SECRET: "test-auth-secret-for-worker-routes",
|
|
ELY_DB: options.d1 ?? testD1Database([]),
|
|
ELY_KV: {
|
|
get(key: string): Promise<string | null> {
|
|
options.kvReads?.push(key);
|
|
return Promise.resolve(values.get(key) ?? null);
|
|
},
|
|
delete(key: string): Promise<void> {
|
|
options.kvDeletes?.push(key);
|
|
values.delete(key);
|
|
return Promise.resolve();
|
|
},
|
|
},
|
|
ELY_STORAGE: testR2Bucket(
|
|
options.r2Puts,
|
|
options.r2Objects,
|
|
options.r2Gets,
|
|
options.r2Deletes,
|
|
),
|
|
ELY_RATE_LIMITER: {
|
|
limit(): Promise<{ success: boolean }> {
|
|
return Promise.resolve({ success: true });
|
|
},
|
|
},
|
|
ELY_API_AUDIT: {
|
|
writeDataPoint(event?: ElyAnalyticsDataPoint): void {
|
|
if (event !== undefined) {
|
|
options.auditEvents?.push(event);
|
|
}
|
|
},
|
|
},
|
|
ELY_DIAGNOSTICS: {
|
|
writeDataPoint(event?: ElyAnalyticsDataPoint): void {
|
|
if (event !== undefined) {
|
|
options.diagnosticEvents?.push(event);
|
|
}
|
|
},
|
|
},
|
|
};
|
|
}
|
|
|
|
export function testD1Database(rows: unknown[] | TestD1DatabaseOptions): RecordedD1Database {
|
|
const binds: unknown[][] = [];
|
|
const batches: number[] = [];
|
|
const queries: string[] = [];
|
|
const allRows = Array.isArray(rows) ? rows : rows.allRows ?? [];
|
|
const firstRows = Array.isArray(rows) ? rows : rows.firstRows ?? [];
|
|
let firstIndex = 0;
|
|
return {
|
|
batches,
|
|
binds,
|
|
queries,
|
|
prepare(query: string) {
|
|
queries.push(query);
|
|
return testD1PreparedStatement(allRows, firstRows, () => firstIndex++, binds);
|
|
},
|
|
batch(statements: ElyD1PreparedStatement[]) {
|
|
batches.push(statements.length);
|
|
return Promise.resolve([]);
|
|
},
|
|
exec() {
|
|
return Promise.resolve({});
|
|
},
|
|
};
|
|
}
|
|
|
|
export function sessionDocument(deviceId = "device-01"): string {
|
|
return JSON.stringify({
|
|
version: 1,
|
|
user_id: "user-01",
|
|
session_id: "session-01",
|
|
device_id: deviceId,
|
|
expires_at: "2099-01-01T00:00:00.000Z",
|
|
});
|
|
}
|
|
|
|
function testD1PreparedStatement(
|
|
allRows: unknown[],
|
|
firstRows: unknown[],
|
|
nextFirstIndex: () => number,
|
|
binds: unknown[][],
|
|
): ElyD1PreparedStatement {
|
|
return {
|
|
bind(...values: unknown[]) {
|
|
binds.push(values);
|
|
return this;
|
|
},
|
|
first<T>() {
|
|
return Promise.resolve((firstRows[nextFirstIndex()] as T | undefined) ?? null);
|
|
},
|
|
all<T>() {
|
|
return Promise.resolve({ results: allRows as T[] });
|
|
},
|
|
run() {
|
|
return Promise.resolve({});
|
|
},
|
|
};
|
|
}
|
|
|
|
function testR2Bucket(
|
|
puts: RecordedR2Put[] = [],
|
|
objects: [string, ArrayBuffer][] = [],
|
|
gets: string[] = [],
|
|
deletes: string[] = [],
|
|
): Env["ELY_STORAGE"] {
|
|
const values = new Map(objects);
|
|
return {
|
|
get(key: string) {
|
|
gets.push(key);
|
|
const value = values.get(key);
|
|
if (value === undefined) {
|
|
return Promise.resolve(null);
|
|
}
|
|
return Promise.resolve({
|
|
arrayBuffer() {
|
|
return Promise.resolve(value);
|
|
},
|
|
});
|
|
},
|
|
put(key: string, value: ArrayBuffer, options: ElyR2PutOptions = {}) {
|
|
puts.push({ key, payload: value, options });
|
|
values.set(key, value);
|
|
return Promise.resolve({
|
|
arrayBuffer() {
|
|
return Promise.resolve(value);
|
|
},
|
|
});
|
|
},
|
|
delete(key: string) {
|
|
deletes.push(key);
|
|
values.delete(key);
|
|
return Promise.resolve();
|
|
},
|
|
};
|
|
}
|