hub-image-upload-route.test.mjs
73 lines 2.8 KB
Raw
sha256:65ccb454656ea5acdea0a10e559b78bcde1eb6ff753ecc2911bc99d1c3d7cadd feat(calendar): enforce agent context tiers in retrieval AP… Human minor ⚠ breaking 1 day ago
1 /**
2 * Tests for Phase 18D: Hub image upload route validation logic.
3 * Tests the validation layer (extension, content-type, magic bytes) without starting the server.
4 */
5 import { describe, it } from 'node:test';
6 import assert from 'node:assert';
7 import { validateImageExtension, validateMagicBytes, parseGitHubRepoUrl } from '../lib/github-commit-image.mjs';
8
9 describe('upload-image route validation', () => {
10 it('rejects file with bad extension', () => {
11 assert.throws(() => validateImageExtension('script.txt'), /not allowed/);
12 });
13
14 it('rejects .exe disguised upload', () => {
15 assert.throws(() => validateImageExtension('payload.exe'), /not allowed/);
16 });
17
18 it('accepts valid image extensions used in upload', () => {
19 for (const name of ['photo.jpg', 'screen.png', 'anim.gif', 'modern.webp', 'scan.jpeg']) {
20 assert.ok(typeof validateImageExtension(name) === 'string');
21 }
22 });
23
24 it('magic bytes check catches mismatch (jpg extension, png content)', () => {
25 const pngBytes = Buffer.from([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]);
26 assert.strictEqual(validateMagicBytes(pngBytes, 'jpg'), false);
27 });
28
29 it('magic bytes check passes valid JPEG', () => {
30 const jpegBytes = Buffer.from([0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10]);
31 assert.strictEqual(validateMagicBytes(jpegBytes, 'jpg'), true);
32 });
33
34 it('upload path format is correct', () => {
35 const now = new Date();
36 const yearMonth = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`;
37 const safeName = 'test-photo.jpg'.replace(/[^a-zA-Z0-9._-]/g, '_').slice(0, 128);
38 const uniqueName = `${Date.now()}-${safeName}`;
39 const repoFilePath = `media/images/${yearMonth}/${uniqueName}`;
40
41 assert.ok(repoFilePath.startsWith('media/images/'));
42 assert.ok(repoFilePath.includes(yearMonth));
43 assert.ok(repoFilePath.endsWith(safeName));
44 });
45
46 it('inserted markdown format is correct', () => {
47 const url = 'https://raw.githubusercontent.com/user/repo/main/media/images/2026-04/photo.jpg';
48 const safeName = 'photo.jpg';
49 const md = `![${safeName}](${url})`;
50 assert.ok(md.startsWith('!['));
51 assert.ok(md.includes(']('));
52 assert.ok(md.endsWith(')'));
53 assert.ok(md.includes('raw.githubusercontent.com'));
54 });
55 });
56
57 describe('upload route prerequisite checks', () => {
58 it('github connection check', () => {
59 const conn = null;
60 assert.ok(!conn?.access_token, 'No connection should fail check');
61 });
62
63 it('remote URL required', () => {
64 const config = { vault_git: {} };
65 assert.ok(!config.vault_git?.remote, 'No remote should fail check');
66 });
67
68 it('repo URL parsing for upload', () => {
69 const { owner, repo } = parseGitHubRepoUrl('https://github.com/myuser/my-vault.git');
70 assert.strictEqual(owner, 'myuser');
71 assert.strictEqual(repo, 'my-vault');
72 });
73 });
File History 2 commits
sha256:65ccb454656ea5acdea0a10e559b78bcde1eb6ff753ecc2911bc99d1c3d7cadd feat(calendar): enforce agent context tiers in retrieval AP… Human minor 1 day ago
sha256:9103f98c89257ed2b01c237cea895dabb3e85ea337dccb1161c175e4422355b6 docs: accept Calendar Events v0 spec with Phase 0 security … Human 1 day ago