1import { expect, it } from "@effect/vitest";
2import * as Cause from "effect/Cause";
3import * as Effect from "effect/Effect";
4import * as Layer from "effect/Layer";
5import { vi } from "vite-plus/test";
6
7import { layerRemoteHttpClient } from "@t3tools/client-runtime/rpc";
8import { withRelayClientTracing } from "@t3tools/shared/relayTracing";
9
10import * as Tracing from "./tracing";
11
12vi.mock("expo-constants", () => ({
13 default: {
14 expoConfig: {
15 extra: {},
16 },
17 },
18}));
19
20it.effect("does not let OTLP serialization failures alter application effects", () => {
21 const fetchFn = vi.fn<typeof fetch>(async () => new Response(null, { status: 202 }));
22 const layerTracing = Tracing.layerFromConfig(
23 {
24 tracesUrl: "https://api.axiom.test/v1/traces",
25 tracesDataset: "mobile-traces",
26 tracesToken: "public-ingest-token",
27 },
28 {
29 appVariant: "test",
30 serviceInstanceId: "test-instance",
31 serviceVersion: "1.2.3",
32 },
33 ).pipe(Layer.provide(layerRemoteHttpClient(fetchFn)));
34 const failure = { durationNanos: 1n };
35 const layerTracedApplication = Layer.effectDiscard(
36 Effect.fail(failure).pipe(
37 Effect.withSpan("mobile.test.failed-span"),
38 withRelayClientTracing,
39 Effect.exit,
40 Effect.flatMap((exit) => {
41 const reason = exit._tag === "Failure" ? exit.cause.reasons[0] : undefined;
42 return reason && Cause.isFailReason(reason)
43 ? Effect.sync(() => {
44 expect(reason.error).toBe(failure);
45 })
46 : Effect.die(new Error("Expected the original typed failure."));
47 }),
48 ),
49 ).pipe(Layer.provide(layerTracing));
50
51 return Layer.build(layerTracedApplication).pipe(
52 Effect.scoped,
53 Effect.andThen(
54 Effect.sync(() => {
55 expect(fetchFn).toHaveBeenCalledOnce();
56 expect(new TextDecoder().decode(fetchFn.mock.calls[0]?.[1]?.body as Uint8Array)).toContain(
57 "mobile.test.failed-span",
58 );
59 }),
60 ),
61 );
62});