| 1 | import { describe, expect, it } from "@effect/vitest"; |
| 2 | import { |
| 3 | AuthOrchestrationOperateScope, |
| 4 | EnvironmentId, |
| 5 | ExecutionEnvironmentDescriptor, |
| 6 | type ServerConfig, |
| 7 | } from "@t3tools/contracts"; |
| 8 | import * as Effect from "effect/Effect"; |
| 9 | import * as Fiber from "effect/Fiber"; |
| 10 | import * as Layer from "effect/Layer"; |
| 11 | import * as Schema from "effect/Schema"; |
| 12 | import * as SubscriptionRef from "effect/SubscriptionRef"; |
| 13 | import { Atom, AtomRegistry } from "effect/reactivity"; |
| 14 | |
| 15 | import { HubConnection, type HubConnectionState } from "../connection/hub.ts"; |
| 16 | import { createHubConnectionAtoms, createHubEnvironmentCapabilitiesAtom } from "./hub.ts"; |
| 17 | |
| 18 | const hubId = EnvironmentId.make("hub"); |
| 19 | const id = EnvironmentId.make("offline"); |
| 20 | const descriptor = Schema.decodeUnknownSync(ExecutionEnvironmentDescriptor)({ |
| 21 | environmentId: id, |
| 22 | label: "Offline machine", |
| 23 | platform: { os: "darwin", arch: "arm64" }, |
| 24 | serverVersion: "test", |
| 25 | capabilities: {}, |
| 26 | }); |
| 27 | const initial = { |
| 28 | connection: { environmentId: hubId, label: "Hub", httpBaseUrl: "https://hub.example/" }, |
| 29 | directory: { |
| 30 | hubEnvironmentId: hubId, |
| 31 | environments: [ |
| 32 | { |
| 33 | environmentId: id, |
| 34 | label: "Offline machine", |
| 35 | httpBaseUrl: "https://hub.example/environments/offline/", |
| 36 | scopes: [AuthOrchestrationOperateScope], |
| 37 | descriptor, |
| 38 | }, |
| 39 | ], |
| 40 | }, |
| 41 | inbox: { |
| 42 | environments: [ |
| 43 | { |
| 44 | environmentId: id, |
| 45 | pendingThreadIds: [], |
| 46 | snapshot: { |
| 47 | schemaVersion: 1, |
| 48 | snapshotSequence: 0, |
| 49 | projects: [], |
| 50 | threads: [], |
| 51 | archivedThreads: [], |
| 52 | }, |
| 53 | }, |
| 54 | ], |
| 55 | }, |
| 56 | refreshing: false, |
| 57 | error: null, |
| 58 | } satisfies HubConnectionState; |
| 59 | |
| 60 | describe("central organization availability", () => { |
| 61 | it.effect( |
| 62 | "permits offline organization from the directory grant without a source configuration", |
| 63 | () => |
| 64 | Effect.gen(function* () { |
| 65 | const state = yield* SubscriptionRef.make<HubConnectionState>(initial); |
| 66 | const runtime = Atom.runtime( |
| 67 | Layer.succeed(HubConnection, { |
| 68 | state, |
| 69 | connect: () => Effect.void, |
| 70 | connectAuthenticated: () => Effect.void, |
| 71 | headers: Effect.succeed({}), |
| 72 | refresh: Effect.void, |
| 73 | refreshInbox: Effect.void, |
| 74 | disconnect: Effect.void, |
| 75 | organize: () => Effect.succeedNone, |
| 76 | }), |
| 77 | ); |
| 78 | const hub = createHubConnectionAtoms(runtime); |
| 79 | const configs = Atom.make<ReadonlyMap<EnvironmentId, ServerConfig>>(new Map()); |
| 80 | const capabilities = createHubEnvironmentCapabilitiesAtom(configs, hub); |
| 81 | const registry = AtomRegistry.make(); |
| 82 | yield* Effect.addFinalizer(() => Effect.sync(() => registry.dispose())); |
| 83 | registry.mount(hub.organizationPermissionAtom(id)); |
| 84 | yield* AtomRegistry.getResult(registry, hub.stateAtom); |
| 85 | |
| 86 | expect(registry.get(hub.organizationPermissionAtom(id))).toBe(true); |
| 87 | expect(registry.get(hub.organizationPermissionAtom(EnvironmentId.make("other")))).toBe( |
| 88 | false, |
| 89 | ); |
| 90 | expect(registry.get(configs).size).toBe(0); |
| 91 | expect(registry.get(capabilities).get(id)).toMatchObject({ |
| 92 | threadSettlement: true, |
| 93 | threadSnooze: true, |
| 94 | threadPinning: true, |
| 95 | threadPinReorder: true, |
| 96 | threadActiveReorder: true, |
| 97 | threadAutoSettleOptOut: true, |
| 98 | }); |
| 99 | |
| 100 | expect(registry.get(capabilities).get(id)?.threadTitleRegeneration).not.toBe(true); |
| 101 | const revoked = yield* Effect.forkChild( |
| 102 | Effect.callback<void>((resume) => { |
| 103 | const unsubscribe = registry.subscribe( |
| 104 | hub.organizationPermissionAtom(id), |
| 105 | () => { |
| 106 | if (!registry.get(hub.organizationPermissionAtom(id))) resume(Effect.void); |
| 107 | }, |
| 108 | { immediate: true }, |
| 109 | ); |
| 110 | return Effect.sync(unsubscribe); |
| 111 | }), |
| 112 | ); |
| 113 | yield* SubscriptionRef.set(state, { |
| 114 | ...initial, |
| 115 | directory: { |
| 116 | ...initial.directory, |
| 117 | environments: initial.directory.environments.map((entry) => ({ ...entry, scopes: [] })), |
| 118 | }, |
| 119 | }); |
| 120 | yield* Fiber.join(revoked); |
| 121 | expect(registry.get(hub.organizationPermissionAtom(id))).toBe(false); |
| 122 | expect(registry.get(capabilities).get(id)?.threadSettlement).not.toBe(true); |
| 123 | }).pipe(Effect.scoped), |
| 124 | ); |
| 125 | }); |