chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,535 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
vi.mock("~/db.server", () => ({
|
||||
prisma: {},
|
||||
$replica: {},
|
||||
}));
|
||||
|
||||
import { findRunByIdWithMollifierFallback } from "~/v3/mollifier/readFallback.server";
|
||||
import type { MollifierBuffer, BufferEntry } from "@trigger.dev/redis-worker";
|
||||
import { RunId } from "@trigger.dev/core/v3/isomorphic";
|
||||
|
||||
function fakeBuffer(entry: BufferEntry | null): MollifierBuffer {
|
||||
return {
|
||||
getEntry: vi.fn(async () => entry),
|
||||
} as unknown as MollifierBuffer;
|
||||
}
|
||||
|
||||
const NOW = new Date("2026-05-11T12:00:00Z");
|
||||
|
||||
describe("findRunByIdWithMollifierFallback", () => {
|
||||
it("returns null when buffer is unavailable (mollifier disabled)", async () => {
|
||||
const result = await findRunByIdWithMollifierFallback(
|
||||
{ runId: "run_1", environmentId: "env_a", organizationId: "org_1" },
|
||||
{ getBuffer: () => null }
|
||||
);
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it("returns null when no buffer entry exists", async () => {
|
||||
const result = await findRunByIdWithMollifierFallback(
|
||||
{ runId: "run_1", environmentId: "env_a", organizationId: "org_1" },
|
||||
{ getBuffer: () => fakeBuffer(null) }
|
||||
);
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it("returns null when buffer entry envId does not match caller (auth mismatch)", async () => {
|
||||
const entry: BufferEntry = {
|
||||
runId: "run_1",
|
||||
envId: "env_OTHER",
|
||||
orgId: "org_1",
|
||||
payload: JSON.stringify({ taskIdentifier: "t" }),
|
||||
status: "QUEUED",
|
||||
attempts: 0,
|
||||
createdAt: NOW,
|
||||
};
|
||||
const result = await findRunByIdWithMollifierFallback(
|
||||
{ runId: "run_1", environmentId: "env_a", organizationId: "org_1" },
|
||||
{ getBuffer: () => fakeBuffer(entry) }
|
||||
);
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it("returns null when buffer entry orgId does not match caller (auth mismatch)", async () => {
|
||||
const entry: BufferEntry = {
|
||||
runId: "run_1",
|
||||
envId: "env_a",
|
||||
orgId: "org_OTHER",
|
||||
payload: JSON.stringify({ taskIdentifier: "t" }),
|
||||
status: "QUEUED",
|
||||
attempts: 0,
|
||||
createdAt: NOW,
|
||||
};
|
||||
const result = await findRunByIdWithMollifierFallback(
|
||||
{ runId: "run_1", environmentId: "env_a", organizationId: "org_1" },
|
||||
{ getBuffer: () => fakeBuffer(entry) }
|
||||
);
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it("returns synthesised QUEUED run when entry exists with matching auth", async () => {
|
||||
const entry: BufferEntry = {
|
||||
runId: "run_1",
|
||||
envId: "env_a",
|
||||
orgId: "org_1",
|
||||
payload: JSON.stringify({ taskIdentifier: "my-task" }),
|
||||
status: "QUEUED",
|
||||
attempts: 0,
|
||||
createdAt: NOW,
|
||||
};
|
||||
const result = await findRunByIdWithMollifierFallback(
|
||||
{ runId: "run_1", environmentId: "env_a", organizationId: "org_1" },
|
||||
{ getBuffer: () => fakeBuffer(entry) }
|
||||
);
|
||||
expect(result).not.toBeNull();
|
||||
expect(result!.friendlyId).toBe("run_1");
|
||||
expect(result!.status).toBe("QUEUED");
|
||||
expect(result!.taskIdentifier).toBe("my-task");
|
||||
expect(result!.createdAt).toEqual(NOW);
|
||||
});
|
||||
|
||||
it("returns synthesised QUEUED for DRAINING (internal state same externally)", async () => {
|
||||
const entry: BufferEntry = {
|
||||
runId: "run_1",
|
||||
envId: "env_a",
|
||||
orgId: "org_1",
|
||||
payload: JSON.stringify({ taskIdentifier: "t" }),
|
||||
status: "DRAINING",
|
||||
attempts: 1,
|
||||
createdAt: NOW,
|
||||
};
|
||||
const result = await findRunByIdWithMollifierFallback(
|
||||
{ runId: "run_1", environmentId: "env_a", organizationId: "org_1" },
|
||||
{ getBuffer: () => fakeBuffer(entry) }
|
||||
);
|
||||
expect(result!.status).toBe("QUEUED");
|
||||
});
|
||||
|
||||
it("returns FAILED state with structured error for FAILED entries", async () => {
|
||||
const entry: BufferEntry = {
|
||||
runId: "run_1",
|
||||
envId: "env_a",
|
||||
orgId: "org_1",
|
||||
payload: JSON.stringify({ taskIdentifier: "t" }),
|
||||
status: "FAILED",
|
||||
attempts: 3,
|
||||
createdAt: NOW,
|
||||
lastError: { code: "VALIDATION", message: "task not found" },
|
||||
};
|
||||
const result = await findRunByIdWithMollifierFallback(
|
||||
{ runId: "run_1", environmentId: "env_a", organizationId: "org_1" },
|
||||
{ getBuffer: () => fakeBuffer(entry) }
|
||||
);
|
||||
expect(result!.status).toBe("FAILED");
|
||||
expect(result!.error).toEqual({ code: "VALIDATION", message: "task not found" });
|
||||
});
|
||||
|
||||
it("extracts snapshot-derived fields from the buffered payload", async () => {
|
||||
const entry: BufferEntry = {
|
||||
runId: "run_1",
|
||||
envId: "env_a",
|
||||
orgId: "org_1",
|
||||
payload: JSON.stringify({
|
||||
taskIdentifier: "my-task",
|
||||
payload: '{"foo":"bar"}',
|
||||
payloadType: "application/json",
|
||||
metadata: '{"customer":"acme"}',
|
||||
metadataType: "application/json",
|
||||
idempotencyKey: "client-abc",
|
||||
idempotencyKeyOptions: { key: "client-abc", scope: "run" },
|
||||
isTest: true,
|
||||
depth: 2,
|
||||
ttl: "1h",
|
||||
tags: ["tag-a", "tag-b"],
|
||||
// The engine.trigger snapshot stores the locked version string under
|
||||
// `taskVersion` (see triggerTask.server.ts#buildEngineTriggerInput).
|
||||
taskVersion: "20260511.1",
|
||||
resumeParentOnCompletion: false,
|
||||
parentTaskRunId: "run_parent",
|
||||
}),
|
||||
status: "QUEUED",
|
||||
attempts: 0,
|
||||
createdAt: NOW,
|
||||
};
|
||||
const result = await findRunByIdWithMollifierFallback(
|
||||
{ runId: "run_1", environmentId: "env_a", organizationId: "org_1" },
|
||||
{ getBuffer: () => fakeBuffer(entry) }
|
||||
);
|
||||
expect(result).not.toBeNull();
|
||||
expect(result!.payloadType).toBe("application/json");
|
||||
expect(result!.metadata).toBe('{"customer":"acme"}');
|
||||
expect(result!.metadataType).toBe("application/json");
|
||||
expect(result!.idempotencyKey).toBe("client-abc");
|
||||
expect(result!.idempotencyKeyOptions).toEqual({ key: "client-abc", scope: "run" });
|
||||
expect(result!.isTest).toBe(true);
|
||||
expect(result!.depth).toBe(2);
|
||||
expect(result!.ttl).toBe("1h");
|
||||
expect(result!.tags).toEqual(["tag-a", "tag-b"]);
|
||||
expect(result!.lockedToVersion).toBe("20260511.1");
|
||||
expect(result!.resumeParentOnCompletion).toBe(false);
|
||||
expect(result!.parentTaskRunId).toBe("run_parent");
|
||||
});
|
||||
|
||||
it("extracts gate-allocated trace context from the snapshot", async () => {
|
||||
const entry: BufferEntry = {
|
||||
runId: "run_1",
|
||||
envId: "env_a",
|
||||
orgId: "org_1",
|
||||
payload: JSON.stringify({
|
||||
taskIdentifier: "t",
|
||||
traceId: "trace_abc",
|
||||
spanId: "span_xyz",
|
||||
parentSpanId: "span_parent",
|
||||
}),
|
||||
status: "QUEUED",
|
||||
attempts: 0,
|
||||
createdAt: NOW,
|
||||
};
|
||||
const result = await findRunByIdWithMollifierFallback(
|
||||
{ runId: "run_1", environmentId: "env_a", organizationId: "org_1" },
|
||||
{ getBuffer: () => fakeBuffer(entry) }
|
||||
);
|
||||
expect(result!.traceId).toBe("trace_abc");
|
||||
expect(result!.spanId).toBe("span_xyz");
|
||||
expect(result!.parentSpanId).toBe("span_parent");
|
||||
});
|
||||
|
||||
it("parses idempotencyKeyOptions in the canonical { key, scope } object shape (regression for the buffered-vs-PG API contract divergence)", async () => {
|
||||
// Regression for the bug where `readFallback` parsed
|
||||
// `idempotencyKeyOptions` via Array.isArray and rejected the
|
||||
// canonical object shape. The SDK and Prisma both serialise this
|
||||
// as `{ key, scope }`; the legacy array check would reject it,
|
||||
// returning `undefined` here, which downstream demoted the API's
|
||||
// `idempotencyKey` field to surface the *hash* (server-side
|
||||
// generated) instead of the user-supplied key — diverging from
|
||||
// how materialised runs render the same field, and creating a
|
||||
// silent contract flip at the drainer-materialisation boundary.
|
||||
// Pin the schema-parse path so the buffered response matches
|
||||
// PG-resident behaviour from the moment the run is buffered.
|
||||
const entry: BufferEntry = {
|
||||
runId: "run_1",
|
||||
envId: "env_a",
|
||||
orgId: "org_1",
|
||||
payload: JSON.stringify({
|
||||
taskIdentifier: "t",
|
||||
idempotencyKey: "<hashed>",
|
||||
idempotencyKeyOptions: { key: "user-supplied-key", scope: "global" },
|
||||
}),
|
||||
status: "QUEUED",
|
||||
attempts: 0,
|
||||
createdAt: NOW,
|
||||
};
|
||||
const result = await findRunByIdWithMollifierFallback(
|
||||
{ runId: "run_1", environmentId: "env_a", organizationId: "org_1" },
|
||||
{ getBuffer: () => fakeBuffer(entry) }
|
||||
);
|
||||
expect(result).not.toBeNull();
|
||||
expect(result!.idempotencyKeyOptions).toEqual({
|
||||
key: "user-supplied-key",
|
||||
scope: "global",
|
||||
});
|
||||
});
|
||||
|
||||
it("returns undefined for idempotencyKeyOptions when the snapshot carries a legacy/invalid shape", async () => {
|
||||
// The Zod schema parse rejects:
|
||||
// - array shape (the legacy bug we just fixed)
|
||||
// - object without required fields
|
||||
// - missing field entirely
|
||||
// In all these cases the field is left `undefined`. Downstream
|
||||
// `getUserProvidedIdempotencyKey` then falls back to the
|
||||
// `idempotencyKey` field, matching how PG-resident runs handle
|
||||
// malformed/missing options.
|
||||
const entry: BufferEntry = {
|
||||
runId: "run_1",
|
||||
envId: "env_a",
|
||||
orgId: "org_1",
|
||||
payload: JSON.stringify({
|
||||
taskIdentifier: "t",
|
||||
idempotencyKey: "<hashed>",
|
||||
// Legacy array shape — must NOT be accepted.
|
||||
idempotencyKeyOptions: ["payload"],
|
||||
}),
|
||||
status: "QUEUED",
|
||||
attempts: 0,
|
||||
createdAt: NOW,
|
||||
};
|
||||
const result = await findRunByIdWithMollifierFallback(
|
||||
{ runId: "run_1", environmentId: "env_a", organizationId: "org_1" },
|
||||
{ getBuffer: () => fakeBuffer(entry) }
|
||||
);
|
||||
expect(result).not.toBeNull();
|
||||
expect(result!.idempotencyKeyOptions).toBeUndefined();
|
||||
});
|
||||
|
||||
it("defaults snapshot-derived fields to safe values when absent", async () => {
|
||||
const entry: BufferEntry = {
|
||||
runId: "run_1",
|
||||
envId: "env_a",
|
||||
orgId: "org_1",
|
||||
payload: JSON.stringify({ taskIdentifier: "t" }),
|
||||
status: "QUEUED",
|
||||
attempts: 0,
|
||||
createdAt: NOW,
|
||||
};
|
||||
const result = await findRunByIdWithMollifierFallback(
|
||||
{ runId: "run_1", environmentId: "env_a", organizationId: "org_1" },
|
||||
{ getBuffer: () => fakeBuffer(entry) }
|
||||
);
|
||||
expect(result!.payloadType).toBeUndefined();
|
||||
expect(result!.metadata).toBeUndefined();
|
||||
expect(result!.idempotencyKey).toBeUndefined();
|
||||
expect(result!.isTest).toBe(false);
|
||||
expect(result!.depth).toBe(0);
|
||||
expect(result!.tags).toEqual([]);
|
||||
expect(result!.resumeParentOnCompletion).toBe(false);
|
||||
expect(result!.traceId).toBeUndefined();
|
||||
expect(result!.spanId).toBeUndefined();
|
||||
});
|
||||
|
||||
it("populates replay-relevant fields from the snapshot", async () => {
|
||||
const entry: BufferEntry = {
|
||||
runId: "run_1",
|
||||
envId: "env_a",
|
||||
orgId: "org_1",
|
||||
payload: JSON.stringify({
|
||||
taskIdentifier: "my-task",
|
||||
environment: { id: "env_a" },
|
||||
workerQueue: "default",
|
||||
queue: "task/my-task",
|
||||
concurrencyKey: "tenant-42",
|
||||
machine: "medium-1x",
|
||||
realtimeStreamsVersion: "v2",
|
||||
seedMetadata: '{"k":"v"}',
|
||||
seedMetadataType: "application/json",
|
||||
tags: ["t1", "t2"],
|
||||
}),
|
||||
status: "QUEUED",
|
||||
attempts: 0,
|
||||
createdAt: NOW,
|
||||
};
|
||||
const result = await findRunByIdWithMollifierFallback(
|
||||
{ runId: "run_1", environmentId: "env_a", organizationId: "org_1" },
|
||||
{ getBuffer: () => fakeBuffer(entry) }
|
||||
);
|
||||
expect(result).not.toBeNull();
|
||||
expect(result!.id).toBeTypeOf("string");
|
||||
expect(result!.id.length).toBeGreaterThan(0);
|
||||
expect(result!.engine).toBe("V2");
|
||||
expect(result!.runtimeEnvironmentId).toBe("env_a");
|
||||
expect(result!.workerQueue).toBe("default");
|
||||
expect(result!.queue).toBe("task/my-task");
|
||||
expect(result!.concurrencyKey).toBe("tenant-42");
|
||||
expect(result!.machinePreset).toBe("medium-1x");
|
||||
expect(result!.realtimeStreamsVersion).toBe("v2");
|
||||
expect(result!.seedMetadata).toBe('{"k":"v"}');
|
||||
expect(result!.seedMetadataType).toBe("application/json");
|
||||
expect(result!.runTags).toEqual(["t1", "t2"]);
|
||||
});
|
||||
|
||||
it("extracts batchId from the snapshot's nested batch object (engine.trigger shape)", async () => {
|
||||
const entry: BufferEntry = {
|
||||
runId: "run_1",
|
||||
envId: "env_a",
|
||||
orgId: "org_1",
|
||||
payload: JSON.stringify({
|
||||
taskIdentifier: "t",
|
||||
// The engine.trigger input nests the batch as `{ id, index }`,
|
||||
// where `id` is the batch's internal cuid (not a flat `batchId`).
|
||||
batch: { id: "batch_internal_cuid", index: 3 },
|
||||
}),
|
||||
status: "QUEUED",
|
||||
attempts: 0,
|
||||
createdAt: NOW,
|
||||
};
|
||||
const result = await findRunByIdWithMollifierFallback(
|
||||
{ runId: "run_1", environmentId: "env_a", organizationId: "org_1" },
|
||||
{ getBuffer: () => fakeBuffer(entry) }
|
||||
);
|
||||
expect(result!.batchId).toBe("batch_internal_cuid");
|
||||
});
|
||||
|
||||
it("leaves batchId undefined when the snapshot has no batch (non-batched run)", async () => {
|
||||
const entry: BufferEntry = {
|
||||
runId: "run_1",
|
||||
envId: "env_a",
|
||||
orgId: "org_1",
|
||||
payload: JSON.stringify({ taskIdentifier: "t" }),
|
||||
status: "QUEUED",
|
||||
attempts: 0,
|
||||
createdAt: NOW,
|
||||
};
|
||||
const result = await findRunByIdWithMollifierFallback(
|
||||
{ runId: "run_1", environmentId: "env_a", organizationId: "org_1" },
|
||||
{ getBuffer: () => fakeBuffer(entry) }
|
||||
);
|
||||
expect(result!.batchId).toBeUndefined();
|
||||
});
|
||||
|
||||
it("treats invalid date strings as undefined and does not mis-classify status as CANCELED", async () => {
|
||||
const entry: BufferEntry = {
|
||||
runId: "run_1",
|
||||
envId: "env_a",
|
||||
orgId: "org_1",
|
||||
payload: JSON.stringify({
|
||||
taskIdentifier: "t",
|
||||
cancelledAt: "not-a-date",
|
||||
cancelReason: "user requested",
|
||||
delayUntil: "also-not-a-date",
|
||||
}),
|
||||
status: "QUEUED",
|
||||
attempts: 0,
|
||||
createdAt: NOW,
|
||||
};
|
||||
const result = await findRunByIdWithMollifierFallback(
|
||||
{ runId: "run_1", environmentId: "env_a", organizationId: "org_1" },
|
||||
{ getBuffer: () => fakeBuffer(entry) }
|
||||
);
|
||||
expect(result).not.toBeNull();
|
||||
expect(result!.status).toBe("QUEUED");
|
||||
expect(result!.cancelledAt).toBeUndefined();
|
||||
expect(result!.delayUntil).toBeUndefined();
|
||||
});
|
||||
|
||||
it("parses valid ISO date strings on cancelledAt and delayUntil", async () => {
|
||||
const cancelledAtIso = "2026-05-11T13:00:00.000Z";
|
||||
const delayUntilIso = "2026-05-11T14:00:00.000Z";
|
||||
const entry: BufferEntry = {
|
||||
runId: "run_1",
|
||||
envId: "env_a",
|
||||
orgId: "org_1",
|
||||
payload: JSON.stringify({
|
||||
taskIdentifier: "t",
|
||||
cancelledAt: cancelledAtIso,
|
||||
cancelReason: "user requested",
|
||||
delayUntil: delayUntilIso,
|
||||
}),
|
||||
status: "QUEUED",
|
||||
attempts: 0,
|
||||
createdAt: NOW,
|
||||
};
|
||||
const result = await findRunByIdWithMollifierFallback(
|
||||
{ runId: "run_1", environmentId: "env_a", organizationId: "org_1" },
|
||||
{ getBuffer: () => fakeBuffer(entry) }
|
||||
);
|
||||
expect(result!.status).toBe("CANCELED");
|
||||
expect(result!.cancelledAt).toEqual(new Date(cancelledAtIso));
|
||||
expect(result!.cancelReason).toBe("user requested");
|
||||
expect(result!.delayUntil).toEqual(new Date(delayUntilIso));
|
||||
});
|
||||
|
||||
it("falls back to entry.envId for runtimeEnvironmentId when snapshot lacks environment.id", async () => {
|
||||
const entry: BufferEntry = {
|
||||
runId: "run_1",
|
||||
envId: "env_a",
|
||||
orgId: "org_1",
|
||||
payload: JSON.stringify({ taskIdentifier: "t" }),
|
||||
status: "QUEUED",
|
||||
attempts: 0,
|
||||
createdAt: NOW,
|
||||
};
|
||||
const result = await findRunByIdWithMollifierFallback(
|
||||
{ runId: "run_1", environmentId: "env_a", organizationId: "org_1" },
|
||||
{ getBuffer: () => fakeBuffer(entry) }
|
||||
);
|
||||
expect(result!.runtimeEnvironmentId).toBe("env_a");
|
||||
expect(result!.workerQueue).toBeUndefined();
|
||||
expect(result!.queue).toBeUndefined();
|
||||
});
|
||||
|
||||
it("extracts batchId from the nested snapshot.batch object (not the flat key)", async () => {
|
||||
// Regression for the field-name mismatch Devin flagged:
|
||||
// #buildEngineTriggerInput writes batch info as
|
||||
// `batch: { id, index }`, never as a flat `batchId`. readFallback
|
||||
// must read the nested key, otherwise SyntheticRun.batchId is always
|
||||
// undefined for buffered runs.
|
||||
const entry: BufferEntry = {
|
||||
runId: "run_1",
|
||||
envId: "env_a",
|
||||
orgId: "org_1",
|
||||
payload: JSON.stringify({
|
||||
taskIdentifier: "t",
|
||||
batch: { id: "batch_internal_xyz", index: 3 },
|
||||
}),
|
||||
status: "QUEUED",
|
||||
attempts: 0,
|
||||
createdAt: NOW,
|
||||
};
|
||||
const result = await findRunByIdWithMollifierFallback(
|
||||
{ runId: "run_1", environmentId: "env_a", organizationId: "org_1" },
|
||||
{ getBuffer: () => fakeBuffer(entry) }
|
||||
);
|
||||
expect(result!.batchId).toBe("batch_internal_xyz");
|
||||
});
|
||||
|
||||
it("does NOT read a flat `batchId` key — only the nested batch.id", async () => {
|
||||
// Belt-and-braces: a payload with the wrong-shaped flat key should
|
||||
// resolve to undefined, not silently pick up the bogus value.
|
||||
const entry: BufferEntry = {
|
||||
runId: "run_1",
|
||||
envId: "env_a",
|
||||
orgId: "org_1",
|
||||
payload: JSON.stringify({
|
||||
taskIdentifier: "t",
|
||||
batchId: "should-be-ignored",
|
||||
}),
|
||||
status: "QUEUED",
|
||||
attempts: 0,
|
||||
createdAt: NOW,
|
||||
};
|
||||
const result = await findRunByIdWithMollifierFallback(
|
||||
{ runId: "run_1", environmentId: "env_a", organizationId: "org_1" },
|
||||
{ getBuffer: () => fakeBuffer(entry) }
|
||||
);
|
||||
expect(result!.batchId).toBeUndefined();
|
||||
});
|
||||
|
||||
it("converts internal parent/root IDs in the snapshot to friendlyIds", async () => {
|
||||
// Regression for Devin's structural-unfillable finding: the snapshot
|
||||
// only carries INTERNAL parent/root ids (engine.trigger consumes the
|
||||
// internal shape), while SyntheticRun exposes friendlyIds. Convert
|
||||
// here so consumers don't have to special-case the buffered path.
|
||||
// The conversion is deterministic via RunId.toFriendlyId — we drive
|
||||
// it through `RunId.generate()` to get a matching internal+friendly
|
||||
// pair and assert the round-trip.
|
||||
const parent = RunId.generate();
|
||||
const root = RunId.generate();
|
||||
const entry: BufferEntry = {
|
||||
runId: "run_1",
|
||||
envId: "env_a",
|
||||
orgId: "org_1",
|
||||
payload: JSON.stringify({
|
||||
taskIdentifier: "t",
|
||||
parentTaskRunId: parent.id,
|
||||
rootTaskRunId: root.id,
|
||||
}),
|
||||
status: "QUEUED",
|
||||
attempts: 0,
|
||||
createdAt: NOW,
|
||||
};
|
||||
const result = await findRunByIdWithMollifierFallback(
|
||||
{ runId: "run_1", environmentId: "env_a", organizationId: "org_1" },
|
||||
{ getBuffer: () => fakeBuffer(entry) }
|
||||
);
|
||||
expect(result!.parentTaskRunFriendlyId).toBe(parent.friendlyId);
|
||||
expect(result!.rootTaskRunFriendlyId).toBe(root.friendlyId);
|
||||
});
|
||||
|
||||
it("leaves parent/root friendlyIds undefined when the snapshot carries no parent context", async () => {
|
||||
const entry: BufferEntry = {
|
||||
runId: "run_1",
|
||||
envId: "env_a",
|
||||
orgId: "org_1",
|
||||
payload: JSON.stringify({ taskIdentifier: "t" }),
|
||||
status: "QUEUED",
|
||||
attempts: 0,
|
||||
createdAt: NOW,
|
||||
};
|
||||
const result = await findRunByIdWithMollifierFallback(
|
||||
{ runId: "run_1", environmentId: "env_a", organizationId: "org_1" },
|
||||
{ getBuffer: () => fakeBuffer(entry) }
|
||||
);
|
||||
expect(result!.parentTaskRunFriendlyId).toBeUndefined();
|
||||
expect(result!.rootTaskRunFriendlyId).toBeUndefined();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user