diff --git a/.docker/selfhost/schema.json b/.docker/selfhost/schema.json index bdc7be1399..46ae6a40c5 100644 --- a/.docker/selfhost/schema.json +++ b/.docker/selfhost/schema.json @@ -550,9 +550,17 @@ "path": { "type": "string" } - } + }, + "required": [ + "path" + ] } - } + }, + "required": [ + "provider", + "bucket", + "config" + ] } ], "default": { @@ -771,9 +779,17 @@ "path": { "type": "string" } - } + }, + "required": [ + "path" + ] } - } + }, + "required": [ + "provider", + "bucket", + "config" + ] } ], "default": { @@ -1435,9 +1451,17 @@ "path": { "type": "string" } - } + }, + "required": [ + "path" + ] } - } + }, + "required": [ + "provider", + "bucket", + "config" + ] } ], "default": { diff --git a/packages/backend/server/src/__tests__/copilot/copilot-provider.spec.ts b/packages/backend/server/src/__tests__/copilot/copilot-provider.spec.ts index 9f163af18b..0325d29a69 100644 --- a/packages/backend/server/src/__tests__/copilot/copilot-provider.spec.ts +++ b/packages/backend/server/src/__tests__/copilot/copilot-provider.spec.ts @@ -1,13 +1,16 @@ import { randomUUID } from 'node:crypto'; +import { Global, Module } from '@nestjs/common'; import type { Prisma } from '@prisma/client'; import type { ExecutionContext, TestFn } from 'ava'; import ava from 'ava'; import Sinon from 'sinon'; import { z } from 'zod'; +import { AppModuleBuilder, FunctionalityModules } from '../../app.module'; +import { JobModule, JobQueue } from '../../base'; import { ServerFeature, ServerService } from '../../core'; -import { AuthService } from '../../core/auth'; +import { AuthModule, AuthService } from '../../core/auth'; import { QuotaModule } from '../../core/quota'; import { Models } from '../../models'; import { llmImageDispatchPlan } from '../../native'; @@ -25,6 +28,7 @@ import { ChatSession, ChatSessionService } from '../../plugins/copilot/session'; import { TranscriptPayloadSchema } from '../../plugins/copilot/transcript/schema'; import { CopilotTranscriptionService } from '../../plugins/copilot/transcript/service'; import { TestingPromptService } from '../mocks/prompt-service.mock'; +import { MockJobQueue } from '../mocks/queue.mock'; import { createTestingModule, TestingModule } from '../utils'; import { TestAssets } from '../utils/copilot'; import { @@ -48,6 +52,13 @@ type Tester = { const test = ava as TestFn; +@Global() +@Module({ + providers: [{ provide: JobQueue, useClass: MockJobQueue }], + exports: [JobQueue], +}) +class MockJobModule {} + let isCopilotConfigured = false; const runIfCopilotConfigured = test.macro( async ( @@ -64,8 +75,20 @@ const runIfCopilotConfigured = test.macro( ); test.serial.before(async t => { + const appModule = new AppModuleBuilder() + .use( + ...FunctionalityModules.filter(module => { + const moduleType = 'module' in module ? module.module : module; + return moduleType !== JobModule; + }), + MockJobModule, + AuthModule, + QuotaModule, + CopilotModule + ) + .compile(); const module = await createTestingModule({ - imports: [QuotaModule, CopilotModule], + imports: [appModule], tapModule: builder => { builder.overrideProvider(PromptService).useClass(TestingPromptService); }, diff --git a/packages/backend/server/src/base/redis/instances.ts b/packages/backend/server/src/base/redis/instances.ts index 506d2cb7fb..d9cd447434 100644 --- a/packages/backend/server/src/base/redis/instances.ts +++ b/packages/backend/server/src/base/redis/instances.ts @@ -8,6 +8,13 @@ import { Redis as IORedis, RedisOptions } from 'ioredis'; import { Config } from '../config'; +function redisOptions(options: RedisOptions) { + return { + ...(env.testing ? { lazyConnect: true } : {}), + ...options, + }; +} + class Redis extends IORedis implements OnModuleInit, OnModuleDestroy { private readonly logger = new Logger(this.constructor.name); @@ -47,41 +54,47 @@ class Redis extends IORedis implements OnModuleInit, OnModuleDestroy { @Injectable() export class CacheRedis extends Redis { constructor(config: Config) { - super({ ...config.redis, ...config.redis.ioredis }); + super(redisOptions({ ...config.redis, ...config.redis.ioredis })); } } @Injectable() export class SessionRedis extends Redis { constructor(config: Config) { - super({ - ...config.redis, - ...config.redis.ioredis, - db: (config.redis.db ?? 0) + 2, - }); + super( + redisOptions({ + ...config.redis, + ...config.redis.ioredis, + db: (config.redis.db ?? 0) + 2, + }) + ); } } @Injectable() export class SocketIoRedis extends Redis { constructor(config: Config) { - super({ - ...config.redis, - ...config.redis.ioredis, - db: (config.redis.db ?? 0) + 3, - }); + super( + redisOptions({ + ...config.redis, + ...config.redis.ioredis, + db: (config.redis.db ?? 0) + 3, + }) + ); } } @Injectable() export class QueueRedis extends Redis { constructor(config: Config) { - super({ - ...config.redis, - ...config.redis.ioredis, - db: (config.redis.db ?? 0) + 4, - // required explicitly set to `null` by bullmq - maxRetriesPerRequest: null, - }); + super( + redisOptions({ + ...config.redis, + ...config.redis.ioredis, + db: (config.redis.db ?? 0) + 4, + // required explicitly set to `null` by bullmq + maxRetriesPerRequest: null, + }) + ); } }