Files
clean-architecture-frontend…/tests/unit/browser-rpc/fixture.ts
T

242 lines
7.5 KiB
TypeScript

import {
defineBrowserRpcOperation,
defineBrowserRpcProviderProfile,
defineBrowserRpcRequestEncoder,
type BrowserRpcOperationV3,
type BrowserRpcProviderProfile,
} from "../../../src/contracts/browser-rpc.ts";
import {
mappingSuccess,
type InstalledBoundaryMapper,
} from "../../../src/contracts/boundary-mapper.ts";
import type { RuntimeSchemaCodec } from "../../../src/contracts/schema-registry.ts";
export const DESCRIPTOR_DIGEST = "a".repeat(64);
export const RUNTIME_DIGEST = "b".repeat(64);
export type ResourceView = Readonly<{ id: string; label: string }>;
export function unaryProfile(
overrides: Partial<BrowserRpcProviderProfile> = {},
): BrowserRpcProviderProfile {
return defineBrowserRpcProviderProfile({
runtimeProfileId: "CONNECT_REFERENCE_UNARY",
providerId: "REFERENCE_RPC",
fixedBaseUrl: "https://rpc.example.test/base/",
runtimeId: "connect-es-web",
runtimeVersion: "2.1.0",
runtimeDigest: RUNTIME_DIGEST,
protocol: "CONNECT_HTTP",
runtimeKind: "CONNECT_WEB_FETCH",
clientApiKind: "PROMISE_UNARY",
rpcKind: "UNARY",
messageEncoding: "PROTO",
framing: "CONNECT_BARE",
requestMethod: "POST",
descriptorArtifactId: "buf.example.resource.v1",
descriptorDigest: DESCRIPTOR_DIGEST,
allowedProcedures: ["example.resource.v1.ResourceService/GetResource"],
authProfileId: "REFERENCE_EXTERNAL_BEARER",
csrfProfileId: "NO_CSRF_BEARER",
corsProfileId: "SAME_ORIGIN_RPC",
errorProfileId: "CONNECT_ERROR_V1",
deadlineProfileId: "RPC_TOTAL_5S",
retryProfileId: "RPC_RETRY_NONE",
retryOwner: "NONE",
maxAttempts: 1,
backoffMs: [],
retryableFailures: [],
maxRetryAfterMs: 0,
deadlineDialect: "CONNECT_TIMEOUT_MS",
cancelDialect: "ABORT_SIGNAL",
rawByteCeilingOwner: "EDGE_AND_TRANSPORT",
streamMessageCompression: "IDENTITY_ONLY",
...overrides,
});
}
export function unaryOperation(
overrides: Partial<BrowserRpcOperationV3> = {},
): BrowserRpcOperationV3 {
return defineBrowserRpcOperation({
contractVersion: 3,
operationId: "GET_RPC_RESOURCE",
owner: "feature-browser-rpc-test",
protocol: "CONNECT_HTTP",
semantics: "QUERY",
replayPolicy: "SAFE",
idempotencyKeyPolicy: "NONE",
idempotencyLevel: "IDEMPOTENT",
dataClassification: "INTERNAL",
runtimeProfileId: "CONNECT_REFERENCE_UNARY",
providerId: "REFERENCE_RPC",
fullyQualifiedService: "example.resource.v1.ResourceService",
method: "GetResource",
rpcKind: "UNARY",
requestMessageId: "example.resource.v1.GetResourceRequest",
responseMessageId: "example.resource.v1.Resource",
descriptorArtifactId: "buf.example.resource.v1",
descriptorDigest: DESCRIPTOR_DIGEST,
requestSchemaId: "RpcResourceRequest",
responseSchemaId: "RpcResourceResponse",
requestEncoderId: "RpcResourceRequestEncoder",
mapperId: "RpcResourceMapper",
authProfileId: "REFERENCE_EXTERNAL_BEARER",
csrfProfileId: "NO_CSRF_BEARER",
errorProfileId: "CONNECT_ERROR_V1",
deadlineProfileId: "RPC_TOTAL_5S",
retryProfileId: "RPC_RETRY_NONE",
serverStateProfileId: "RpcResourceQuery",
maxRequestMessageBytes: 1_024,
maxResponseMessageBytes: 4_096,
maxResponseMessages: 1,
maxTotalResponseBytes: 4_096,
maxBufferedBytes: 4_096,
idleDeadlineMs: null,
totalDeadlineMs: 5_000,
...overrides,
});
}
export function streamProfile(
overrides: Partial<BrowserRpcProviderProfile> = {},
): BrowserRpcProviderProfile {
return defineBrowserRpcProviderProfile({
...unaryProfile(),
runtimeProfileId: "CONNECT_REFERENCE_STREAM",
clientApiKind: "ASYNC_ITERABLE",
rpcKind: "SERVER_STREAM",
framing: "CONNECT_ENVELOPE",
allowedProcedures: [
"example.resource.v1.ResourceService/WatchResources",
],
retryProfileId: "RPC_STREAM_RETRY_NONE",
...overrides,
});
}
export function streamOperation(
overrides: Partial<BrowserRpcOperationV3> = {},
): BrowserRpcOperationV3 {
return defineBrowserRpcOperation({
...unaryOperation(),
operationId: "WATCH_RPC_RESOURCES",
semantics: "SERVER_STREAM",
runtimeProfileId: "CONNECT_REFERENCE_STREAM",
method: "WatchResources",
rpcKind: "SERVER_STREAM",
requestEncoderId: "RpcResourceStreamRequestEncoder",
retryProfileId: "RPC_STREAM_RETRY_NONE",
serverStateProfileId: null,
maxResponseMessages: 4,
maxTotalResponseBytes: 16_384,
maxBufferedBytes: 8_192,
idleDeadlineMs: 1_000,
totalDeadlineMs: 10_000,
...overrides,
});
}
export const SCHEMA_CODECS = Object.freeze({
RpcResourceRequest: Object.freeze({
schemaId: "RpcResourceRequest",
parse(value: unknown) {
if (
value &&
typeof value === "object" &&
typeof (value as { resourceId?: unknown }).resourceId === "string"
) {
return Object.freeze({
success: true,
data: Object.freeze({
resourceId: (value as { resourceId: string }).resourceId,
}),
});
}
return Object.freeze({
success: false,
issues: Object.freeze([
Object.freeze({ path: "resourceId", code: "INVALID_STRING" }),
]),
});
},
}),
RpcResourceResponse: Object.freeze({
schemaId: "RpcResourceResponse",
parse(value: unknown) {
if (
value &&
typeof value === "object" &&
typeof (value as { id?: unknown }).id === "string" &&
typeof (value as { name?: unknown }).name === "string"
) {
return Object.freeze({
success: true,
data: Object.freeze({
id: (value as { id: string }).id,
name: (value as { name: string }).name,
}),
});
}
return Object.freeze({
success: false,
issues: Object.freeze([
Object.freeze({ path: "", code: "INVALID_RESOURCE" }),
]),
});
},
}),
} satisfies Readonly<Record<string, RuntimeSchemaCodec>>);
export const MAPPERS = Object.freeze({
RpcResourceMapper: Object.freeze({
mapperId: "RpcResourceMapper",
mapperVersion: 1,
inputSchemaId: "RpcResourceResponse",
outputContractId: "ResourceView",
owner: "feature-browser-rpc-test",
maxOutputItems: 1,
map(input: unknown) {
const resource = input as Readonly<{ id: string; name: string }>;
return mappingSuccess<ResourceView>(
Object.freeze({ id: resource.id, label: resource.name }),
);
},
}),
} satisfies Readonly<Record<string, InstalledBoundaryMapper>>);
export const UNARY_ENCODER = defineBrowserRpcRequestEncoder({
encoderId: "RpcResourceRequestEncoder",
operationId: "GET_RPC_RESOURCE",
encode(value) {
const request = value as Readonly<{ resourceId: string }>;
return Object.freeze({
ok: true,
value: Object.freeze({ resourceId: request.resourceId }),
encodedBytes: request.resourceId.length,
});
},
});
export const STREAM_ENCODER = defineBrowserRpcRequestEncoder({
encoderId: "RpcResourceStreamRequestEncoder",
operationId: "WATCH_RPC_RESOURCES",
encode(value) {
const request = value as Readonly<{ resourceId: string }>;
return Object.freeze({
ok: true,
value: Object.freeze({ resourceId: request.resourceId }),
encodedBytes: request.resourceId.length,
});
},
});
export function isResourceView(value: unknown): value is ResourceView {
return (
!!value &&
typeof value === "object" &&
typeof (value as { id?: unknown }).id === "string" &&
typeof (value as { label?: unknown }).label === "string"
);
}