/** * Copyright (c) 2026, Salesforce, Inc., * All rights reserved. * For full license text, see the LICENSE.txt file */ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; import { buildSchema } from "graphql"; import { afterEach, beforeEach, describe, expect, it } from "vitest"; import { makeNoopPrimeDeps } from "../../__tests__/helpers/prime-deps.js"; import { type PrimeDeps, SchemaRefreshError } from "../../lib/prime-schema.js"; import { buildConnect } from "../build-connect.js"; const ORG = "test-connect"; const ORG_URL = "https://test-connect.my.salesforce.com"; const SCHEMA = buildSchema(`type Query { x: Int }`); function failingPrimeDeps(err: unknown): PrimeDeps { return { getOrgAuth: async () => ({ alias: ORG, username: "u", instanceUrl: ORG_URL, accessToken: "t", orgId: "00D", }), downloadSchema: async () => { throw err; }, }; } describe("intent/build-connect", () => { let tmpRoot: string; beforeEach(() => { tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), "graphiti-build-connect-")); process.env.GRAPHITI_HOME = tmpRoot; }); afterEach(() => { delete process.env.GRAPHITI_HOME; fs.rmSync(tmpRoot, { recursive: true, force: true }); }); it("lazily primes on first connect (cached: false, refreshed: false)", async () => { const out = await buildConnect( { org: ORG }, { primeDeps: makeNoopPrimeDeps(ORG, ORG_URL, SCHEMA) }, ); expect(out.cached).toBe(false); expect(out.refreshed).toBe(false); expect(out.instanceUrl).toBe(ORG_URL); expect(out.warnings).toBeUndefined(); }); it("returns cached when a connect finds an existing schema and forceRefresh is omitted", async () => { const primeDeps = makeNoopPrimeDeps(ORG, ORG_URL, SCHEMA); await buildConnect({ org: ORG }, { primeDeps }); // prime const out = await buildConnect({ org: ORG }, { primeDeps }); expect(out.cached).toBe(true); expect(out.refreshed).toBe(false); }); it("forceRefresh re-downloads and reports refreshed: true", async () => { const primeDeps = makeNoopPrimeDeps(ORG, ORG_URL, SCHEMA); await buildConnect({ org: ORG }, { primeDeps }); // prime const out = await buildConnect({ org: ORG, forceRefresh: true }, { primeDeps }); expect(out.refreshed).toBe(true); expect(out.cached).toBe(false); }); it("refresh failure with a surviving cache returns a soft staleness warning", async () => { // Prime a real cache first, then fail the refresh. await buildConnect({ org: ORG }, { primeDeps: makeNoopPrimeDeps(ORG, ORG_URL, SCHEMA) }); const out = await buildConnect( { org: ORG, forceRefresh: true }, { primeDeps: failingPrimeDeps(new Error("introspection failed")), }, ); expect(out.refreshed).toBe(false); expect(out.cached).toBe(true); expect(out.instanceUrl).toBe(ORG_URL); expect(out.durationMs).toBe(0); expect(out.warnings?.[0]).toMatch(/keeping the previously cached schema/i); }); it("refresh failure with no prior cache propagates the error", async () => { await expect( buildConnect( { org: ORG, forceRefresh: true }, { primeDeps: failingPrimeDeps(new Error("introspection failed")), }, ), ).rejects.toBeInstanceOf(SchemaRefreshError); }); });