Skip to content

Commit 3304558

Browse files
test: add session-ingress and worker-events route tests
7 additional route tests covering session-ingress HTTP POST, worker events publishing, worker state updates, and no-op endpoints. Total: 211 tests, 374 assertions across 9 test files. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 333ea0b commit 3304558

1 file changed

Lines changed: 135 additions & 0 deletions

File tree

packages/remote-control-server/src/__tests__/routes.test.ts

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ import { issueToken } from "../auth/token";
2626
import v1Sessions from "../routes/v1/sessions";
2727
import v1Environments from "../routes/v1/environments";
2828
import v1EnvironmentsWork from "../routes/v1/environments.work";
29+
import v1SessionIngress from "../routes/v1/session-ingress";
2930
import v2CodeSessions from "../routes/v2/code-sessions";
3031
import v2Worker from "../routes/v2/worker";
32+
import v2WorkerEvents from "../routes/v2/worker-events";
3133
import webAuth from "../routes/web/auth";
3234
import webSessions from "../routes/web/sessions";
3335
import webControl from "../routes/web/control";
@@ -38,8 +40,10 @@ function createApp() {
3840
app.route("/v1/sessions", v1Sessions);
3941
app.route("/v1/environments", v1Environments);
4042
app.route("/v1/environments", v1EnvironmentsWork);
43+
app.route("/v2/session_ingress", v1SessionIngress);
4144
app.route("/v1/code/sessions", v2CodeSessions);
4245
app.route("/v1/code/sessions", v2Worker);
46+
app.route("/v1/code/sessions", v2WorkerEvents);
4347
app.route("/web", webAuth);
4448
app.route("/web", webSessions);
4549
app.route("/web", webControl);
@@ -627,3 +631,134 @@ describe("Web Environment Routes", () => {
627631
expect(res.status).toBe(401);
628632
});
629633
});
634+
635+
describe("V1 Session Ingress Routes (HTTP)", () => {
636+
let app: Hono;
637+
638+
beforeEach(() => {
639+
storeReset();
640+
for (const [key] of getAllEventBuses()) {
641+
removeEventBus(key);
642+
}
643+
process.env.RCS_API_KEYS = "test-api-key";
644+
app = createApp();
645+
});
646+
647+
test("POST /v2/session_ingress/session/:sessionId/events — ingests events with API key", async () => {
648+
// Create session first
649+
const sessRes = await app.request("/v1/sessions", {
650+
method: "POST",
651+
headers: { ...AUTH_HEADERS, "Content-Type": "application/json" },
652+
body: JSON.stringify({}),
653+
});
654+
const { id } = await sessRes.json();
655+
656+
const res = await app.request(`/v2/session_ingress/session/${id}/events`, {
657+
method: "POST",
658+
headers: { ...AUTH_HEADERS, "Content-Type": "application/json" },
659+
body: JSON.stringify({ events: [{ type: "assistant", content: "response" }] }),
660+
});
661+
expect(res.status).toBe(200);
662+
const body = await res.json();
663+
expect(body.status).toBe("ok");
664+
});
665+
666+
test("POST /v2/session_ingress/session/:sessionId/events — rejects without auth", async () => {
667+
const res = await app.request("/v2/session_ingress/session/nope/events", {
668+
method: "POST",
669+
headers: { "Content-Type": "application/json" },
670+
body: JSON.stringify({ events: [] }),
671+
});
672+
expect(res.status).toBe(401);
673+
});
674+
675+
test("POST /v2/session_ingress/session/:sessionId/events — 404 for unknown session", async () => {
676+
const res = await app.request("/v2/session_ingress/session/nope/events", {
677+
method: "POST",
678+
headers: { ...AUTH_HEADERS, "Content-Type": "application/json" },
679+
body: JSON.stringify({ events: [{ type: "user", content: "hi" }] }),
680+
});
681+
expect(res.status).toBe(404);
682+
});
683+
});
684+
685+
describe("V2 Worker Events Routes", () => {
686+
let app: Hono;
687+
688+
beforeEach(() => {
689+
storeReset();
690+
for (const [key] of getAllEventBuses()) {
691+
removeEventBus(key);
692+
}
693+
process.env.RCS_API_KEYS = "test-api-key";
694+
app = createApp();
695+
});
696+
697+
test("POST /v1/code/sessions/:id/worker/events — publishes worker events", async () => {
698+
// Create session
699+
const sessRes = await app.request("/v1/sessions", {
700+
method: "POST",
701+
headers: { ...AUTH_HEADERS, "Content-Type": "application/json" },
702+
body: JSON.stringify({}),
703+
});
704+
const { id } = await sessRes.json();
705+
706+
const res = await app.request(`/v1/code/sessions/${id}/worker/events`, {
707+
method: "POST",
708+
headers: { ...AUTH_HEADERS, "Content-Type": "application/json" },
709+
body: JSON.stringify([{ type: "assistant", content: "response" }]),
710+
});
711+
expect(res.status).toBe(200);
712+
const body = await res.json();
713+
expect(body.status).toBe("ok");
714+
expect(body.count).toBe(1);
715+
});
716+
717+
test("PUT /v1/code/sessions/:id/worker/state — updates session status", async () => {
718+
const sessRes = await app.request("/v1/sessions", {
719+
method: "POST",
720+
headers: { ...AUTH_HEADERS, "Content-Type": "application/json" },
721+
body: JSON.stringify({}),
722+
});
723+
const { id } = await sessRes.json();
724+
725+
const res = await app.request(`/v1/code/sessions/${id}/worker/state`, {
726+
method: "PUT",
727+
headers: { ...AUTH_HEADERS, "Content-Type": "application/json" },
728+
body: JSON.stringify({ status: "running" }),
729+
});
730+
expect(res.status).toBe(200);
731+
});
732+
733+
test("PUT /v1/code/sessions/:id/worker/external_metadata — no-op", async () => {
734+
const sessRes = await app.request("/v1/sessions", {
735+
method: "POST",
736+
headers: { ...AUTH_HEADERS, "Content-Type": "application/json" },
737+
body: JSON.stringify({}),
738+
});
739+
const { id } = await sessRes.json();
740+
741+
const res = await app.request(`/v1/code/sessions/${id}/worker/external_metadata`, {
742+
method: "PUT",
743+
headers: { ...AUTH_HEADERS, "Content-Type": "application/json" },
744+
body: JSON.stringify({ meta: "data" }),
745+
});
746+
expect(res.status).toBe(200);
747+
});
748+
749+
test("POST /v1/code/sessions/:id/worker/events/:eventId/delivery — no-op", async () => {
750+
const sessRes = await app.request("/v1/sessions", {
751+
method: "POST",
752+
headers: { ...AUTH_HEADERS, "Content-Type": "application/json" },
753+
body: JSON.stringify({}),
754+
});
755+
const { id } = await sessRes.json();
756+
757+
const res = await app.request(`/v1/code/sessions/${id}/worker/events/evt123/delivery`, {
758+
method: "POST",
759+
headers: { ...AUTH_HEADERS, "Content-Type": "application/json" },
760+
body: JSON.stringify({ status: "received" }),
761+
});
762+
expect(res.status).toBe(200);
763+
});
764+
});

0 commit comments

Comments
 (0)