File size: 2,206 Bytes
c1243f9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import { describe, expect, it } from "vitest";
import type { CronJob } from "../../cron/types.js";
import type { RuntimeEnv } from "../../runtime.js";
import { printCronList } from "./shared.js";

describe("printCronList", () => {
  it("handles job with undefined sessionTarget (#9649)", () => {
    const logs: string[] = [];
    const mockRuntime = {
      log: (msg: string) => logs.push(msg),
      error: () => {},
      exit: () => {},
    } as RuntimeEnv;

    // Simulate a job without sessionTarget (as reported in #9649)
    const jobWithUndefinedTarget = {
      id: "test-job-id",
      agentId: "main",
      name: "Test Job",
      enabled: true,
      createdAtMs: Date.now(),
      updatedAtMs: Date.now(),
      schedule: { kind: "at", at: new Date(Date.now() + 3600000).toISOString() },
      // sessionTarget is intentionally omitted to simulate the bug
      wakeMode: "next-heartbeat",
      payload: { kind: "systemEvent", text: "test" },
      state: { nextRunAtMs: Date.now() + 3600000 },
    } as CronJob;

    // This should not throw "Cannot read properties of undefined (reading 'trim')"
    expect(() => printCronList([jobWithUndefinedTarget], mockRuntime)).not.toThrow();

    // Verify output contains the job
    expect(logs.length).toBeGreaterThan(1);
    expect(logs.some((line) => line.includes("test-job-id"))).toBe(true);
  });

  it("handles job with defined sessionTarget", () => {
    const logs: string[] = [];
    const mockRuntime = {
      log: (msg: string) => logs.push(msg),
      error: () => {},
      exit: () => {},
    } as RuntimeEnv;

    const jobWithTarget: CronJob = {
      id: "test-job-id-2",
      agentId: "main",
      name: "Test Job 2",
      enabled: true,
      createdAtMs: Date.now(),
      updatedAtMs: Date.now(),
      schedule: { kind: "at", at: new Date(Date.now() + 3600000).toISOString() },
      sessionTarget: "isolated",
      wakeMode: "next-heartbeat",
      payload: { kind: "systemEvent", text: "test" },
      state: { nextRunAtMs: Date.now() + 3600000 },
    };

    expect(() => printCronList([jobWithTarget], mockRuntime)).not.toThrow();
    expect(logs.some((line) => line.includes("isolated"))).toBe(true);
  });
});