From 423fc246e0b5bf38505390f217ae5be8f6d065fc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 20 Jan 2026 20:22:42 +0000 Subject: [PATCH 1/2] Initial plan From f8320a62d70ed1e08c4b00af78fbaf2498306277 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 20 Jan 2026 20:29:00 +0000 Subject: [PATCH 2/2] Fix plugin test context mocks to include all required fields Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- packages/spec/src/system/plugin.test.ts | 217 ++++++++++++++++++++++-- 1 file changed, 199 insertions(+), 18 deletions(-) diff --git a/packages/spec/src/system/plugin.test.ts b/packages/spec/src/system/plugin.test.ts index d69c503..821108f 100644 --- a/packages/spec/src/system/plugin.test.ts +++ b/packages/spec/src/system/plugin.test.ts @@ -11,11 +11,38 @@ import { describe('PluginContextSchema', () => { it('should accept valid plugin context', () => { const context: PluginContextData = { - ql: {}, - os: {}, - logger: {}, + ql: { + object: () => ({}), + query: async () => ({}) + }, + os: { + getCurrentUser: async () => ({ id: 'test-user' }), + getConfig: async () => 'test-config' + }, + logger: { + debug: () => {}, + info: () => {}, + warn: () => {}, + error: () => {} + }, + storage: { + get: async () => null, + set: async () => {}, + delete: async () => {} + }, + i18n: { + t: () => '', + getLocale: () => 'en' + }, metadata: {}, events: {}, + app: { + router: { + get: () => {}, + post: () => {}, + use: () => {} + } + } }; expect(() => PluginContextSchema.parse(context)).not.toThrow(); @@ -23,11 +50,38 @@ describe('PluginContextSchema', () => { it('should accept context with all required properties', () => { const completeContext = { - ql: {}, - os: {}, - logger: {}, + ql: { + object: () => ({}), + query: async () => ({}) + }, + os: { + getCurrentUser: async () => ({ id: 'test-user' }), + getConfig: async () => 'test-config' + }, + logger: { + debug: () => {}, + info: () => {}, + warn: () => {}, + error: () => {} + }, + storage: { + get: async () => null, + set: async () => {}, + delete: async () => {} + }, + i18n: { + t: () => '', + getLocale: () => 'en' + }, metadata: {}, events: {}, + app: { + router: { + get: () => {}, + post: () => {}, + use: () => {} + } + } }; const result = PluginContextSchema.safeParse(completeContext); @@ -41,15 +95,27 @@ describe('PluginContextSchema', () => { find: async () => [], create: async (data: any) => data, }), + query: async (soql: string) => ({ records: [] }) }, os: { getCurrentUser: async () => ({ id: 'user123' }), getConfig: async (key: string) => 'value', }, logger: { + debug: (message: string) => console.log(message), info: (message: string) => console.log(message), + warn: (message: string) => console.warn(message), error: (message: string, error?: any) => console.error(message, error), }, + storage: { + get: async (key: string) => null, + set: async (key: string, value: any) => {}, + delete: async (key: string) => {} + }, + i18n: { + t: (key: string, params?: any) => key, + getLocale: () => 'en-US' + }, metadata: { getObject: async (name: string) => ({}), getFields: async (object: string) => [], @@ -58,6 +124,13 @@ describe('PluginContextSchema', () => { on: (event: string, handler: Function) => {}, emit: (event: string, data?: any) => {}, }, + app: { + router: { + get: (path: string, handler: Function) => {}, + post: (path: string, handler: Function) => {}, + use: (pathOrHandler: string | Function, handler?: Function) => {} + } + } }; expect(() => PluginContextSchema.parse(context)).not.toThrow(); @@ -216,11 +289,38 @@ describe('Plugin Lifecycle Scenarios', () => { // Simulate installation if (parsed.onInstall) { await parsed.onInstall({ - ql: { object: () => ({ syncSchema: async () => {} }) }, - os: {}, - logger: { info: () => {}, error: () => {} }, + ql: { + object: () => ({ syncSchema: async () => {} }), + query: async () => ({}) + }, + os: { + getCurrentUser: async () => ({ id: 'test-user' }), + getConfig: async () => 'test-config' + }, + logger: { + debug: () => {}, + info: () => {}, + warn: () => {}, + error: () => {} + }, + storage: { + get: async () => null, + set: async () => {}, + delete: async () => {} + }, + i18n: { + t: () => '', + getLocale: () => 'en' + }, metadata: {}, events: {}, + app: { + router: { + get: () => {}, + post: () => {}, + use: () => {} + } + } } as any); } @@ -246,11 +346,38 @@ describe('Plugin Lifecycle Scenarios', () => { const parsed = PluginSchema.parse(plugin); const mockContext = { - ql: {}, - os: {}, - logger: { info: () => {}, error: () => {} }, + ql: { + object: () => ({}), + query: async () => ({}) + }, + os: { + getCurrentUser: async () => ({ id: 'test-user' }), + getConfig: async () => 'test-config' + }, + logger: { + debug: () => {}, + info: () => {}, + warn: () => {}, + error: () => {} + }, + storage: { + get: async () => null, + set: async () => {}, + delete: async () => {} + }, + i18n: { + t: () => '', + getLocale: () => 'en' + }, metadata: {}, events: {}, + app: { + router: { + get: () => {}, + post: () => {}, + use: () => {} + } + } } as any; // Enable @@ -286,11 +413,38 @@ describe('Plugin Lifecycle Scenarios', () => { if (parsed.onUpgrade) { await parsed.onUpgrade( { - ql: {}, - os: {}, - logger: { info: () => {}, error: () => {} }, + ql: { + object: () => ({}), + query: async () => ({}) + }, + os: { + getCurrentUser: async () => ({ id: 'test-user' }), + getConfig: async () => 'test-config' + }, + logger: { + debug: () => {}, + info: () => {}, + warn: () => {}, + error: () => {} + }, + storage: { + get: async () => null, + set: async () => {}, + delete: async () => {} + }, + i18n: { + t: () => '', + getLocale: () => 'en' + }, metadata: {}, events: {}, + app: { + router: { + get: () => {}, + post: () => {}, + use: () => {} + } + } } as any, '1.0.0', '2.0.0' @@ -318,11 +472,38 @@ describe('Plugin Lifecycle Scenarios', () => { if (parsed.onUninstall) { await parsed.onUninstall({ - ql: { object: () => ({ dropTable: async () => {} }) }, - os: {}, - logger: { info: () => {}, error: () => {} }, + ql: { + object: () => ({ dropTable: async () => {} }), + query: async () => ({}) + }, + os: { + getCurrentUser: async () => ({ id: 'test-user' }), + getConfig: async () => 'test-config' + }, + logger: { + debug: () => {}, + info: () => {}, + warn: () => {}, + error: () => {} + }, + storage: { + get: async () => null, + set: async () => {}, + delete: async () => {} + }, + i18n: { + t: () => '', + getLocale: () => 'en' + }, metadata: {}, events: {}, + app: { + router: { + get: () => {}, + post: () => {}, + use: () => {} + } + } } as any); }