download-validation.test.js

 1import { describe, expect, test } from 'bun:test';
 2import path from 'path';
 3import {
 4  ALLOWED_BUNDLE_PROVIDERS,
 5  ALLOWED_FILE_PROVIDERS,
 6  isAllowedBundleProvider,
 7  isAllowedFileProvider,
 8  isAllowedProvider,
 9} from '../../server/lib/validation.js';
10import { getFilePath, handleFileDownload } from '../../server/lib/api-handlers.js';
11
12describe('download provider validation', () => {
13  test('allows opencode and pi as individual download providers', () => {
14    expect(ALLOWED_FILE_PROVIDERS).toContain('opencode');
15    expect(ALLOWED_FILE_PROVIDERS).toContain('pi');
16    expect(isAllowedFileProvider('opencode')).toBe(true);
17    expect(isAllowedFileProvider('pi')).toBe(true);
18  });
19
20  test('separates file downloads from bundle downloads', () => {
21    expect(ALLOWED_BUNDLE_PROVIDERS).toContain('universal');
22    expect(ALLOWED_BUNDLE_PROVIDERS).toContain('universal-prefixed');
23    expect(isAllowedBundleProvider('universal')).toBe(true);
24    expect(isAllowedProvider('universal')).toBe(true);
25    expect(isAllowedFileProvider('universal')).toBe(false);
26  });
27});
28
29describe('download file paths', () => {
30  test('maps opencode skills into the .opencode config directory', () => {
31    expect(getFilePath('skill', 'opencode', 'impeccable')).toBe(
32      path.join(process.cwd(), 'dist', 'opencode', '.opencode', 'skills', 'impeccable', 'SKILL.md')
33    );
34  });
35
36  test('maps pi commands into the .pi config directory', () => {
37    expect(getFilePath('command', 'pi', 'audit')).toBe(
38      path.join(process.cwd(), 'dist', 'pi', '.pi', 'skills', 'audit', 'SKILL.md')
39    );
40  });
41
42  test('rejects bundle-only providers on the individual download route', async () => {
43    const response = await handleFileDownload('skill', 'universal', 'impeccable');
44    expect(response.status).toBe(400);
45  });
46});