added mcp tests for media

This commit is contained in:
dswbx
2025-08-12 20:57:13 +02:00
parent bd3d2ea900
commit a6ed74d904
5 changed files with 112 additions and 14 deletions

View File

@@ -1,19 +1,23 @@
import { describe, it, expect, beforeAll } from "bun:test";
import { type App, createApp } from "core/test/utils";
import { describe, test, expect, beforeAll, beforeEach, afterAll } from "bun:test";
import { type App, createApp, createMcpToolCaller } from "core/test/utils";
import { getSystemMcp } from "modules/mcp/system-mcp";
import { registries } from "index";
import { StorageLocalAdapter } from "adapter/node/storage/StorageLocalAdapter";
import { disableConsoleLog, enableConsoleLog } from "core/utils";
beforeAll(disableConsoleLog);
afterAll(enableConsoleLog);
/**
* - [ ] config_media_get
* - [ ] config_media_update
* - [ ] config_media_adapter_get
* - [ ] config_media_adapter_update
* - [x] config_media_get
* - [x] config_media_update
* - [x] config_media_adapter_get
* - [x] config_media_adapter_update
*/
describe("mcp media", async () => {
let app: App;
let server: ReturnType<typeof getSystemMcp>;
beforeAll(async () => {
beforeEach(async () => {
registries.media.register("local", StorageLocalAdapter);
app = createApp({
initialConfig: {
@@ -35,5 +39,79 @@ describe("mcp media", async () => {
});
await app.build();
server = getSystemMcp(app);
server.setLogLevel("error");
server.onNotification((message) => {
console.dir(message, { depth: null });
});
});
const tool = createMcpToolCaller();
test("config_media_{get,update}", async () => {
const result = await tool(server, "config_media_get", {});
expect(result).toEqual({
path: "",
secrets: false,
partial: false,
value: app.toJSON().media,
});
// partial
expect((await tool(server, "config_media_get", { path: "adapter" })).value).toEqual({
type: "local",
config: {
path: "./",
},
});
// update
await tool(server, "config_media_update", {
value: {
storage: {
body_max_size: 1024 * 1024 * 10,
},
},
return_config: true,
});
expect(app.toJSON().media.storage.body_max_size).toBe(1024 * 1024 * 10);
});
test("config_media_adapter_{get,update}", async () => {
const result = await tool(server, "config_media_adapter_get", {});
expect(result).toEqual({
secrets: false,
value: app.toJSON().media.adapter,
});
// update
await tool(server, "config_media_adapter_update", {
value: {
type: "local",
config: {
path: "./subdir",
},
},
});
const adapter = app.toJSON().media.adapter as any;
expect(adapter.config.path).toBe("./subdir");
expect(adapter.type).toBe("local");
// set to s3
{
await tool(server, "config_media_adapter_update", {
value: {
type: "s3",
config: {
access_key: "123",
secret_access_key: "456",
url: "https://example.com/what",
},
},
});
const adapter = app.toJSON(true).media.adapter as any;
expect(adapter.type).toBe("s3");
expect(adapter.config.url).toBe("https://example.com/what");
}
});
});

View File

@@ -177,7 +177,6 @@ export class SchemaObject<Schema extends TSchema = TSchema> {
this.throwIfRestricted(partial);
// overwrite arrays and primitives, only deep merge objects
// @ts-ignore
const config = set(current, path, value);

View File

@@ -39,6 +39,7 @@ export function buildMediaSchema() {
},
{ default: {} },
),
// @todo: currently cannot be updated partially using mcp
adapter: $schema(
"config_media_adapter",
s.anyOf(Object.values(adapterSchemaObject)),

View File

@@ -50,12 +50,28 @@ export const $schema = <
{
...mcp.getToolOptions("update"),
inputSchema: s.strictObject({
full: s.boolean({ default: false }).optional(),
value: schema as any,
return_config: s.boolean({ default: false }).optional(),
secrets: s.boolean({ default: false }).optional(),
}),
},
async (params, ctx: AppToolHandlerCtx) => {
return ctx.json(params);
const { value, return_config, secrets } = params;
const [module_name, ...rest] = node.instancePath;
await ctx.context.app.mutateConfig(module_name as any).overwrite(rest, value);
let config: any = undefined;
if (return_config) {
const configs = ctx.context.app.toJSON(secrets);
config = getPath(configs, node.instancePath);
}
return ctx.json({
success: true,
module: module_name,
config,
});
},
);
};

View File

@@ -2910,10 +2910,6 @@
"type": "object",
"additionalProperties": false,
"properties": {
"full": {
"type": "boolean",
"default": false
},
"value": {
"anyOf": [
{
@@ -3028,6 +3024,14 @@
]
}
]
},
"return_config": {
"type": "boolean",
"default": false
},
"secrets": {
"type": "boolean",
"default": false
}
}
},