fix(projects): use fallback icon MIME (#1197)
Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
This commit is contained in:
committed by
GitHub
co-authored by
Isaac Sanchez
parent
75d78b6113
commit
51356b4195
@@ -204,7 +204,9 @@ export const registerProjectIconRoutes = (app, dependencies) => {
|
||||
try {
|
||||
const data = await fsPromises.readFile(iconPath);
|
||||
const ext = path.extname(iconPath).slice(1).toLowerCase();
|
||||
const resolvedMime = metadataMime || projectIconExtensionToMime[ext] || 'application/octet-stream';
|
||||
const resolvedMime = iconPath === preferredPath && metadataMime
|
||||
? metadataMime
|
||||
: projectIconExtensionToMime[ext] || 'application/octet-stream';
|
||||
const contentType = resolvedMime === 'image/svg+xml' ? 'image/svg+xml; charset=utf-8' : resolvedMime;
|
||||
|
||||
if (resolvedMime === 'image/svg+xml' && requestedThemeVariant) {
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
import crypto from 'crypto';
|
||||
import path from 'path';
|
||||
|
||||
import { registerProjectIconRoutes } from './project-icon-routes.js';
|
||||
|
||||
const createRouteRegistry = () => {
|
||||
const routes = new Map();
|
||||
|
||||
return {
|
||||
app: {
|
||||
get(routePath, handler) {
|
||||
routes.set(`GET ${routePath}`, handler);
|
||||
},
|
||||
post(routePath, handler) {
|
||||
routes.set(`POST ${routePath}`, handler);
|
||||
},
|
||||
put(routePath, handler) {
|
||||
routes.set(`PUT ${routePath}`, handler);
|
||||
},
|
||||
delete(routePath, handler) {
|
||||
routes.set(`DELETE ${routePath}`, handler);
|
||||
},
|
||||
},
|
||||
getRoute(method, routePath) {
|
||||
return routes.get(`${method} ${routePath}`);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const createMockResponse = () => {
|
||||
const headers = new Map();
|
||||
let statusCode = 200;
|
||||
let body = null;
|
||||
|
||||
return {
|
||||
setHeader(name, value) {
|
||||
headers.set(name.toLowerCase(), value);
|
||||
},
|
||||
getHeader(name) {
|
||||
return headers.get(name.toLowerCase());
|
||||
},
|
||||
status(code) {
|
||||
statusCode = code;
|
||||
return this;
|
||||
},
|
||||
json(payload) {
|
||||
body = payload;
|
||||
return this;
|
||||
},
|
||||
send(payload) {
|
||||
body = payload;
|
||||
return this;
|
||||
},
|
||||
get statusCode() {
|
||||
return statusCode;
|
||||
},
|
||||
get body() {
|
||||
return body;
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
describe('project icon routes', () => {
|
||||
it('uses fallback file extension MIME when metadata points to a missing icon', async () => {
|
||||
const { app, getRoute } = createRouteRegistry();
|
||||
const jpgBytes = Buffer.from('jpg-bytes');
|
||||
const enoent = Object.assign(new Error('missing'), { code: 'ENOENT' });
|
||||
const fsPromises = {
|
||||
readFile: vi.fn(async (iconPath) => {
|
||||
if (iconPath.endsWith('.jpg')) {
|
||||
return jpgBytes;
|
||||
}
|
||||
throw enoent;
|
||||
}),
|
||||
};
|
||||
|
||||
registerProjectIconRoutes(app, {
|
||||
fsPromises,
|
||||
path,
|
||||
crypto,
|
||||
openchamberDataDir: '/tmp/openchamber-test',
|
||||
sanitizeProjects: (projects) => projects,
|
||||
readSettingsFromDiskMigrated: async () => ({
|
||||
projects: [{
|
||||
id: 'proj-1',
|
||||
path: '/repo',
|
||||
iconImage: { mime: 'image/png', updatedAt: 1, source: 'custom' },
|
||||
}],
|
||||
}),
|
||||
persistSettings: async () => ({}),
|
||||
createFsSearchRuntime: () => ({ searchFilesystemFiles: async () => [] }),
|
||||
spawn: vi.fn(),
|
||||
resolveGitBinaryForSpawn: vi.fn(),
|
||||
});
|
||||
|
||||
const res = createMockResponse();
|
||||
await getRoute('GET', '/api/projects/:projectId/icon')({
|
||||
params: { projectId: 'proj-1' },
|
||||
query: {},
|
||||
}, res);
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(res.getHeader('Content-Type')).toBe('image/jpeg');
|
||||
expect(res.body).toBe(jpgBytes);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user