From 2ccc3bbf8e820c620ef411c2f1e93f6eba75785a Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Sat, 30 May 2026 12:33:53 -0400 Subject: [PATCH] test: Restore dropped github.spec tenant-context tests The previous commit's github.spec.ts edit did not apply (anchor mismatch), so the getTenantId import remained unused and failed eslint --max-warnings=0. Add the two tenant tests that use it: a tenant-scoped run stamps tenantId and executes inside the tenant ALS context, and a no-tenant run stays ambient. --- packages/api/src/skills/sync/github.spec.ts | 54 +++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/packages/api/src/skills/sync/github.spec.ts b/packages/api/src/skills/sync/github.spec.ts index f4ab1c4e7a..6639a0c66e 100644 --- a/packages/api/src/skills/sync/github.spec.ts +++ b/packages/api/src/skills/sync/github.spec.ts @@ -251,6 +251,60 @@ describe('createGitHubSkillSyncRunner', () => { ); }); + it('runs a tenant-scoped source inside its tenant context and stamps the skill tenantId', async () => { + let observedTenantId: string | undefined = 'unset'; + const deps = createDeps({ + getConfig: () => ({ + github: { + enabled: true, + intervalMinutes: 60, + runOnStartup: false, + sources: [ + { + id: 'librechat-skills', + owner: 'LibreChat', + repo: 'skills', + ref: 'main', + paths: ['skills'], + credentialKey: 'github-skills-prod', + tenantId: 'tenant-a', + }, + ], + }, + }), + createSkill: jest.fn(async (input: CreateSkillInput): Promise => { + observedTenantId = getTenantId(); + return { skill: makeSkill(input), warnings: [] }; + }), + }); + const runner = createGitHubSkillSyncRunner(deps); + const result = await runner.runOnce(); + + expect(result.status).toBe('completed'); + expect(observedTenantId).toBe('tenant-a'); + expect(deps.createSkill).toHaveBeenCalledWith( + expect.objectContaining({ name: 'research', tenantId: 'tenant-a' }), + ); + }); + + it('runs in the ambient context when a source has no configured tenantId', async () => { + let observedTenantId: string | undefined = 'unset'; + const deps = createDeps({ + createSkill: jest.fn(async (input: CreateSkillInput): Promise => { + observedTenantId = getTenantId(); + return { skill: makeSkill(input), warnings: [] }; + }), + }); + const runner = createGitHubSkillSyncRunner(deps); + const result = await runner.runOnce(); + + expect(result.status).toBe('completed'); + expect(observedTenantId).toBeUndefined(); + expect(deps.createSkill).toHaveBeenCalledWith( + expect.objectContaining({ name: 'research', tenantId: undefined }), + ); + }); + it('uses distinct synthetic authors so same-named skills can sync from different sources', async () => { const seenNamesByAuthor = new Set(); const deps = createDeps({