fix: close marketplace client review findings

This commit is contained in:
brother7 committed 2026-08-28 21:05:54 +08:00
1 parent 8dfa542860
commit 1614f7efc1
25 files changed
+1224 -143

No files matched your search

+18 -1
View File
@@ -5,6 +5,8 @@ import type { IncomingMessage, ServerResponse } from 'node:http';
import { describe, expect, it, vi } from 'vitest';
import type { HostApiContext } from '../../electron/api/context';
import { handlePluginMarketplaceRoutes } from '../../electron/api/routes/plugin-marketplace';
import { MarketplaceClientError } from '../../electron/coding-plugins/marketplace-client';
import { PluginPackageStoreError } from '../../electron/coding-plugins/package-store';
function request(method: string, body?: unknown): IncomingMessage {
const req = new EventEmitter();
@@ -85,21 +87,24 @@ describe('Main-owned plugin Marketplace routes', () => {
const acquire = vi.fn().mockResolvedValue({ items: [] });
const remove = vi.fn().mockResolvedValue({ items: [] });
const install = vi.fn().mockResolvedValue({ status: 'installed', pluginId: 'notes' });
const installBeta = vi.fn().mockResolvedValue({ status: 'installed', pluginId: 'notes', version: '2.0.0-beta.1' });
const update = vi.fn().mockResolvedValue({ status: 'installed', pluginId: 'notes' });
const uninstall = vi.fn().mockResolvedValue({ status: 'removed', pluginId: 'notes' });
const ctx = { codingProducts: { pluginMarketplace: {
acquire, remove, install, update, uninstall,
acquire, remove, install, installBeta, update, uninstall,
readCatalog: vi.fn(), readDetail: vi.fn(), readLibrary: vi.fn(),
} } } as unknown as HostApiContext;
expect((await invoke(ctx, 'PUT', '/api/coding/plugin-marketplace/library/notes')).status).toBe(200);
expect((await invoke(ctx, 'DELETE', '/api/coding/plugin-marketplace/library/notes')).status).toBe(200);
expect((await invoke(ctx, 'POST', '/api/coding/plugin-marketplace/install/notes')).status).toBe(200);
expect((await invoke(ctx, 'POST', '/api/coding/plugin-marketplace/install/notes/beta')).status).toBe(200);
expect((await invoke(ctx, 'POST', '/api/coding/plugin-marketplace/update/notes')).status).toBe(200);
expect((await invoke(ctx, 'DELETE', '/api/coding/plugin-marketplace/install/notes')).status).toBe(200);
expect(acquire).toHaveBeenCalledWith('notes');
expect(remove).toHaveBeenCalledWith('notes');
expect(install).toHaveBeenCalledWith('notes');
expect(installBeta).toHaveBeenCalledWith('notes');
expect(update).toHaveBeenCalledWith('notes');
expect(uninstall).toHaveBeenCalledWith('notes');
});
@@ -117,4 +122,16 @@ describe('Main-owned plugin Marketplace routes', () => {
expect(forged).toMatchObject({ status: 400, payload: { code: 'plugin_request_invalid' } });
expect(acquire).not.toHaveBeenCalled();
});
it.each([
{ error: new MarketplaceClientError('plugin_release_yanked', 409), status: 409, code: 'plugin_release_yanked' },
{ error: new PluginPackageStoreError('plugin_incompatible_client'), status: 409, code: 'plugin_incompatible_client' },
{ error: new PluginPackageStoreError('plugin_signature_invalid'), status: 422, code: 'plugin_signature_invalid' },
])('keeps bounded release status $code visible through the Main route', async ({ error, status, code }) => {
const install = vi.fn().mockRejectedValue(error);
const ctx = { codingProducts: { pluginMarketplace: { install } } } as unknown as HostApiContext;
const result = await invoke(ctx, 'POST', '/api/coding/plugin-marketplace/install/notes');
expect(result).toMatchObject({ status, payload: { success: false, code } });
expect(JSON.stringify(result.payload)).not.toMatch(/path|token|private|secret|stack/i);
});
});