UNPKG

@rivetkit/core

Version:

262 lines (204 loc) 8 kB
import { describe, expect, test } from "vitest"; import type { DriverTestConfig } from "../mod"; import { setupDriverTest } from "../utils"; export function runActorConnTests(driverTestConfig: DriverTestConfig) { describe("Actor Connection Tests", () => { describe("Connection Methods", () => { test("should connect using .get().connect()", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); // Create actor await client.counter.create(["test-get"]); // Get a handle and connect const handle = client.counter.get(["test-get"]); const connection = handle.connect(); // Verify connection by performing an action const count = await connection.increment(5); expect(count).toBe(5); // Clean up await connection.dispose(); }); test("should connect using .getForId().connect()", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); // Create a actor first to get its ID const handle = client.counter.getOrCreate(["test-get-for-id"]); await handle.increment(3); const actorId = await handle.resolve(); // Get a new handle using the actor ID and connect const idHandle = client.counter.getForId(actorId); const connection = idHandle.connect(); // Verify connection works and state is preserved const count = await connection.getCount(); expect(count).toBe(3); // Clean up await connection.dispose(); }); test("should connect using .getOrCreate().connect()", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); // Get or create actor and connect const handle = client.counter.getOrCreate(["test-get-or-create"]); const connection = handle.connect(); // Verify connection works const count = await connection.increment(7); expect(count).toBe(7); // Clean up await connection.dispose(); }); test("should connect using (await create()).connect()", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); // Create actor and connect const handle = await client.counter.create(["test-create"]); const connection = handle.connect(); // Verify connection works const count = await connection.increment(9); expect(count).toBe(9); // Clean up await connection.dispose(); }); }); describe("Event Communication", () => { test("should mix RPC calls and WebSocket events", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); // Create actor const handle = client.counter.getOrCreate(["test-mixed-rpc-ws"]); const connection = handle.connect(); // Set up event listener const receivedEvents: number[] = []; connection.on("newCount", (count: number) => { receivedEvents.push(count); }); // Send one RPC call over the connection to ensure it's open await connection.increment(1); // Now use stateless RPC calls through the handle (no connection) // These should still trigger events that the connection receives await handle.increment(5); await handle.increment(3); // Verify events were received from both connection and handle calls expect(receivedEvents).toContain(1); // From connection call expect(receivedEvents).toContain(6); // From first handle call (1+5) expect(receivedEvents).toContain(9); // From second handle call (6+3) // Clean up await connection.dispose(); }); test("should receive events via broadcast", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); // Create actor and connect const handle = client.counter.getOrCreate(["test-broadcast"]); const connection = handle.connect(); // Set up event listener const receivedEvents: number[] = []; connection.on("newCount", (count: number) => { receivedEvents.push(count); }); // Trigger broadcast events await connection.increment(5); await connection.increment(3); // Verify events were received expect(receivedEvents).toContain(5); expect(receivedEvents).toContain(8); // Clean up await connection.dispose(); }); test("should handle one-time events with once()", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); // Create actor and connect const handle = client.counter.getOrCreate(["test-once"]); const connection = handle.connect(); // Set up one-time event listener const receivedEvents: number[] = []; connection.once("newCount", (count: number) => { receivedEvents.push(count); }); // Trigger multiple events, but should only receive the first one await connection.increment(5); await connection.increment(3); // Verify only the first event was received expect(receivedEvents).toEqual([5]); expect(receivedEvents).not.toContain(8); // Clean up await connection.dispose(); }); test("should unsubscribe from events", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); // Create actor and connect const handle = client.counter.getOrCreate(["test-unsubscribe"]); const connection = handle.connect(); // Set up event listener with unsubscribe const receivedEvents: number[] = []; const unsubscribe = connection.on("newCount", (count: number) => { receivedEvents.push(count); }); // Trigger first event await connection.increment(5); // Unsubscribe unsubscribe(); // Trigger second event, should not be received await connection.increment(3); // Verify only the first event was received expect(receivedEvents).toEqual([5]); expect(receivedEvents).not.toContain(8); // Clean up await connection.dispose(); }); }); describe("Connection Parameters", () => { test("should pass connection parameters", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); // Create two connections with different params const handle1 = client.counterWithParams.getOrCreate(["test-params"], { params: { name: "user1" }, }); const handle2 = client.counterWithParams.getOrCreate(["test-params"], { params: { name: "user2" }, }); const conn1 = handle1.connect(); const conn2 = handle2.connect(); // HACK: Call an action to wait for the connections to be established await conn1.getInitializers(); await conn2.getInitializers(); // Get initializers to verify connection params were used const initializers = await conn1.getInitializers(); // Verify both connection names were recorded expect(initializers).toContain("user1"); expect(initializers).toContain("user2"); // Clean up await conn1.dispose(); await conn2.dispose(); }); }); describe("Lifecycle Hooks", () => { test("should trigger lifecycle hooks", async (c) => { const { client } = await setupDriverTest(c, driverTestConfig); // Create and connect const connHandle = client.counterWithLifecycle.getOrCreate( ["test-lifecycle"], { params: { trackLifecycle: true }, }, ); const connection = connHandle.connect(); // Verify lifecycle events were triggered const events = await connection.getEvents(); expect(events).toEqual(["onStart", "onBeforeConnect", "onConnect"]); // Disconnect should trigger onDisconnect await connection.dispose(); // Reconnect to check if onDisconnect was called const handle = client.counterWithLifecycle.getOrCreate([ "test-lifecycle", ]); const finalEvents = await handle.getEvents(); expect(finalEvents).toBeOneOf([ // Still active ["onStart", "onBeforeConnect", "onConnect", "onDisconnect"], // Went to sleep and woke back up [ "onStart", "onBeforeConnect", "onConnect", "onDisconnect", "onStart", ], ]); }); }); }); }