Phase 4 red: ApiClient tests and stub

19 tests covering ApiClient's full public surface: default and custom
origins, X-Client-Package and X-Auth-Token headers, getJSON with query
params, postJSON with JSON body, ApiError on 4xx/5xx, streaming file
and thumbnail downloads, and self-hosted origin routing.

Tests inject a recording fetch via the constructor, so nothing hits the
network. The test file is documented to serve as canonical usage
reference per the development workflow.
This commit is contained in:
2026-05-11 01:01:34 -07:00
parent d8466be0a7
commit ef3f10fecc
2 changed files with 442 additions and 0 deletions

57
src/api/client.ts Normal file
View File

@@ -0,0 +1,57 @@
// Stub: see the README "Development workflow" section for TDD policy.
export interface ApiClientOptions {
apiOrigin?: string;
filesOrigin?: string;
thumbsOrigin?: string;
authToken?: string;
fetch?: typeof globalThis.fetch;
userAgent?: string;
}
export class ApiError extends Error {
readonly status: number;
readonly code?: string;
readonly requestID?: string;
readonly body?: unknown;
constructor(
_message: string,
_status: number,
_opts?: { code?: string; requestID?: string; body?: unknown },
) {
super(_message);
this.status = _status;
this.code = _opts?.code;
this.requestID = _opts?.requestID;
this.body = _opts?.body;
}
}
export class ApiClient {
constructor(_opts?: ApiClientOptions) {
throw new Error("ApiClient not implemented");
}
setAuthToken(_token: string): void {
throw new Error("not implemented");
}
clearAuthToken(): void {
throw new Error("not implemented");
}
async getJSON<T>(
_path: string,
_query?: Record<string, string | number | undefined>,
): Promise<T> {
throw new Error("not implemented");
}
async postJSON<T>(_path: string, _body: unknown): Promise<T> {
throw new Error("not implemented");
}
async getFileStream(_fileID: number): Promise<ReadableStream<Uint8Array>> {
throw new Error("not implemented");
}
async getThumbnailStream(
_fileID: number,
): Promise<ReadableStream<Uint8Array>> {
throw new Error("not implemented");
}
}