mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-22 19:30:15 +01:00
WIP: fix tests
This commit is contained in:
parent
f7ea232760
commit
62b4d29967
5 changed files with 103 additions and 212 deletions
|
|
@ -1,43 +1,9 @@
|
||||||
const DALLE3 = require('../DALLE3');
|
const DALLE3 = require('../DALLE3');
|
||||||
const { ProxyAgent } = require('undici');
|
const { ProxyAgent } = require('undici');
|
||||||
|
|
||||||
|
jest.mock('tiktoken');
|
||||||
const processFileURL = jest.fn();
|
const processFileURL = jest.fn();
|
||||||
|
|
||||||
jest.mock('~/server/services/Files/images', () => ({
|
|
||||||
getImageBasename: jest.fn().mockImplementation((url) => {
|
|
||||||
const parts = url.split('/');
|
|
||||||
const lastPart = parts.pop();
|
|
||||||
const imageExtensionRegex = /\.(jpg|jpeg|png|gif|bmp|tiff|svg)$/i;
|
|
||||||
if (imageExtensionRegex.test(lastPart)) {
|
|
||||||
return lastPart;
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('fs', () => {
|
|
||||||
return {
|
|
||||||
existsSync: jest.fn(),
|
|
||||||
mkdirSync: jest.fn(),
|
|
||||||
promises: {
|
|
||||||
writeFile: jest.fn(),
|
|
||||||
readFile: jest.fn(),
|
|
||||||
unlink: jest.fn(),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
jest.mock('path', () => {
|
|
||||||
return {
|
|
||||||
resolve: jest.fn(),
|
|
||||||
join: jest.fn(),
|
|
||||||
relative: jest.fn(),
|
|
||||||
extname: jest.fn().mockImplementation((filename) => {
|
|
||||||
return filename.slice(filename.lastIndexOf('.'));
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('DALLE3 Proxy Configuration', () => {
|
describe('DALLE3 Proxy Configuration', () => {
|
||||||
let originalEnv;
|
let originalEnv;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
const OpenAI = require('openai');
|
const OpenAI = require('openai');
|
||||||
|
const { logger } = require('@librechat/data-schemas');
|
||||||
const DALLE3 = require('../DALLE3');
|
const DALLE3 = require('../DALLE3');
|
||||||
const logger = require('~/config/winston');
|
|
||||||
|
|
||||||
jest.mock('openai');
|
jest.mock('openai');
|
||||||
|
|
||||||
jest.mock('@librechat/data-schemas', () => {
|
jest.mock('@librechat/data-schemas', () => {
|
||||||
return {
|
return {
|
||||||
logger: {
|
logger: {
|
||||||
|
|
@ -26,25 +25,6 @@ jest.mock('tiktoken', () => {
|
||||||
|
|
||||||
const processFileURL = jest.fn();
|
const processFileURL = jest.fn();
|
||||||
|
|
||||||
jest.mock('~/server/services/Files/images', () => ({
|
|
||||||
getImageBasename: jest.fn().mockImplementation((url) => {
|
|
||||||
// Split the URL by '/'
|
|
||||||
const parts = url.split('/');
|
|
||||||
|
|
||||||
// Get the last part of the URL
|
|
||||||
const lastPart = parts.pop();
|
|
||||||
|
|
||||||
// Check if the last part of the URL matches the image extension regex
|
|
||||||
const imageExtensionRegex = /\.(jpg|jpeg|png|gif|bmp|tiff|svg)$/i;
|
|
||||||
if (imageExtensionRegex.test(lastPart)) {
|
|
||||||
return lastPart;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the regex test fails, return an empty string
|
|
||||||
return '';
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
|
|
||||||
const generate = jest.fn();
|
const generate = jest.fn();
|
||||||
OpenAI.mockImplementation(() => ({
|
OpenAI.mockImplementation(() => ({
|
||||||
images: {
|
images: {
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,4 @@
|
||||||
jest.mock('~/models', () => ({
|
jest.mock('@librechat/data-schemas', () => ({
|
||||||
initializeRoles: jest.fn(),
|
|
||||||
seedDefaultRoles: jest.fn(),
|
|
||||||
ensureDefaultCategories: jest.fn(),
|
|
||||||
}));
|
|
||||||
jest.mock('~/models/Role', () => ({
|
|
||||||
updateAccessPermissions: jest.fn(),
|
|
||||||
getRoleByName: jest.fn().mockResolvedValue(null),
|
|
||||||
updateRoleByName: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('~/config', () => ({
|
|
||||||
logger: {
|
logger: {
|
||||||
info: jest.fn(),
|
info: jest.fn(),
|
||||||
warn: jest.fn(),
|
warn: jest.fn(),
|
||||||
|
|
@ -17,10 +6,11 @@ jest.mock('~/config', () => ({
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('./start/interface', () => ({
|
jest.mock('@librechat/api', () => ({
|
||||||
|
...jest.requireActual('@librechat/api'),
|
||||||
loadDefaultInterface: jest.fn(),
|
loadDefaultInterface: jest.fn(),
|
||||||
}));
|
}));
|
||||||
jest.mock('./ToolService', () => ({
|
jest.mock('./start/tools', () => ({
|
||||||
loadAndFormatTools: jest.fn().mockReturnValue({}),
|
loadAndFormatTools: jest.fn().mockReturnValue({}),
|
||||||
}));
|
}));
|
||||||
jest.mock('./start/checks', () => ({
|
jest.mock('./start/checks', () => ({
|
||||||
|
|
@ -31,33 +21,27 @@ jest.mock('./start/checks', () => ({
|
||||||
checkWebSearchConfig: jest.fn(),
|
checkWebSearchConfig: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('./Config', () => ({
|
jest.mock('./Config/loadCustomConfig', () => jest.fn());
|
||||||
setAppConfig: jest.fn(),
|
|
||||||
getAppConfig: jest.fn(),
|
|
||||||
setCachedTools: jest.fn(),
|
|
||||||
loadCustomConfig: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
const AppService = require('./AppService');
|
const AppService = require('./AppService');
|
||||||
const { loadDefaultInterface } = require('./start/interface');
|
const { loadDefaultInterface } = require('@librechat/api');
|
||||||
|
|
||||||
describe('AppService interface configuration', () => {
|
describe('AppService interface configuration', () => {
|
||||||
let mockLoadCustomConfig;
|
let mockLoadCustomConfig;
|
||||||
const { setAppConfig } = require('./Config');
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.resetModules();
|
jest.resetModules();
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
({ loadCustomConfig: mockLoadCustomConfig } = require('./Config'));
|
mockLoadCustomConfig = require('./Config/loadCustomConfig');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set prompts and bookmarks to true when loadDefaultInterface returns true for both', async () => {
|
it('should set prompts and bookmarks to true when loadDefaultInterface returns true for both', async () => {
|
||||||
mockLoadCustomConfig.mockResolvedValue({});
|
mockLoadCustomConfig.mockResolvedValue({});
|
||||||
loadDefaultInterface.mockResolvedValue({ prompts: true, bookmarks: true });
|
loadDefaultInterface.mockResolvedValue({ prompts: true, bookmarks: true });
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
interfaceConfig: expect.objectContaining({
|
interfaceConfig: expect.objectContaining({
|
||||||
prompts: true,
|
prompts: true,
|
||||||
|
|
@ -72,9 +56,9 @@ describe('AppService interface configuration', () => {
|
||||||
mockLoadCustomConfig.mockResolvedValue({ interface: { prompts: false, bookmarks: false } });
|
mockLoadCustomConfig.mockResolvedValue({ interface: { prompts: false, bookmarks: false } });
|
||||||
loadDefaultInterface.mockResolvedValue({ prompts: false, bookmarks: false });
|
loadDefaultInterface.mockResolvedValue({ prompts: false, bookmarks: false });
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
interfaceConfig: expect.objectContaining({
|
interfaceConfig: expect.objectContaining({
|
||||||
prompts: false,
|
prompts: false,
|
||||||
|
|
@ -89,18 +73,17 @@ describe('AppService interface configuration', () => {
|
||||||
mockLoadCustomConfig.mockResolvedValue({});
|
mockLoadCustomConfig.mockResolvedValue({});
|
||||||
loadDefaultInterface.mockResolvedValue({});
|
loadDefaultInterface.mockResolvedValue({});
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
interfaceConfig: expect.anything(),
|
interfaceConfig: expect.anything(),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Verify that prompts and bookmarks are undefined when not provided
|
// Verify that prompts and bookmarks are undefined when not provided
|
||||||
const initCall = setAppConfig.mock.calls[0][0];
|
expect(result.interfaceConfig.prompts).toBeUndefined();
|
||||||
expect(initCall.interfaceConfig.prompts).toBeUndefined();
|
expect(result.interfaceConfig.bookmarks).toBeUndefined();
|
||||||
expect(initCall.interfaceConfig.bookmarks).toBeUndefined();
|
|
||||||
expect(loadDefaultInterface).toHaveBeenCalled();
|
expect(loadDefaultInterface).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -108,9 +91,9 @@ describe('AppService interface configuration', () => {
|
||||||
mockLoadCustomConfig.mockResolvedValue({ interface: { prompts: true, bookmarks: false } });
|
mockLoadCustomConfig.mockResolvedValue({ interface: { prompts: true, bookmarks: false } });
|
||||||
loadDefaultInterface.mockResolvedValue({ prompts: true, bookmarks: false });
|
loadDefaultInterface.mockResolvedValue({ prompts: true, bookmarks: false });
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
interfaceConfig: expect.objectContaining({
|
interfaceConfig: expect.objectContaining({
|
||||||
prompts: true,
|
prompts: true,
|
||||||
|
|
@ -139,9 +122,9 @@ describe('AppService interface configuration', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
interfaceConfig: expect.objectContaining({
|
interfaceConfig: expect.objectContaining({
|
||||||
peoplePicker: expect.objectContaining({
|
peoplePicker: expect.objectContaining({
|
||||||
|
|
@ -173,9 +156,9 @@ describe('AppService interface configuration', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
interfaceConfig: expect.objectContaining({
|
interfaceConfig: expect.objectContaining({
|
||||||
peoplePicker: expect.objectContaining({
|
peoplePicker: expect.objectContaining({
|
||||||
|
|
@ -198,9 +181,9 @@ describe('AppService interface configuration', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
interfaceConfig: expect.objectContaining({
|
interfaceConfig: expect.objectContaining({
|
||||||
peoplePicker: expect.objectContaining({
|
peoplePicker: expect.objectContaining({
|
||||||
|
|
|
||||||
|
|
@ -10,25 +10,24 @@ const {
|
||||||
conflictingAzureVariables,
|
conflictingAzureVariables,
|
||||||
} = require('librechat-data-provider');
|
} = require('librechat-data-provider');
|
||||||
|
|
||||||
|
jest.mock('@librechat/data-schemas', () => ({
|
||||||
|
...jest.requireActual('@librechat/data-schemas'),
|
||||||
|
logger: {
|
||||||
|
info: jest.fn(),
|
||||||
|
warn: jest.fn(),
|
||||||
|
error: jest.fn(),
|
||||||
|
debug: jest.fn(),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
const AppService = require('./AppService');
|
const AppService = require('./AppService');
|
||||||
|
|
||||||
jest.mock('./Files/Firebase/initialize', () => ({
|
jest.mock('./Files/Firebase/initialize', () => ({
|
||||||
initializeFirebase: jest.fn(),
|
initializeFirebase: jest.fn(),
|
||||||
}));
|
}));
|
||||||
jest.mock('~/models', () => ({
|
|
||||||
initializeRoles: jest.fn(),
|
jest.mock('./Config/loadCustomConfig', () =>
|
||||||
seedDefaultRoles: jest.fn(),
|
jest.fn(() =>
|
||||||
ensureDefaultCategories: jest.fn(),
|
|
||||||
}));
|
|
||||||
jest.mock('~/models/Role', () => ({
|
|
||||||
updateAccessPermissions: jest.fn(),
|
|
||||||
getRoleByName: jest.fn().mockResolvedValue(null),
|
|
||||||
}));
|
|
||||||
jest.mock('./Config', () => ({
|
|
||||||
setAppConfig: jest.fn(),
|
|
||||||
getAppConfig: jest.fn(),
|
|
||||||
setCachedTools: jest.fn(),
|
|
||||||
loadCustomConfig: jest.fn(() =>
|
|
||||||
Promise.resolve({
|
Promise.resolve({
|
||||||
registration: { socialLogins: ['testLogin'] },
|
registration: { socialLogins: ['testLogin'] },
|
||||||
fileStrategy: 'testStrategy',
|
fileStrategy: 'testStrategy',
|
||||||
|
|
@ -37,25 +36,9 @@ jest.mock('./Config', () => ({
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
getCachedTools: jest.fn().mockResolvedValue({
|
);
|
||||||
ExampleTool: {
|
|
||||||
type: 'function',
|
|
||||||
function: {
|
|
||||||
description: 'Example tool function',
|
|
||||||
name: 'exampleFunction',
|
|
||||||
parameters: {
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
param1: { type: 'string', description: 'An example parameter' },
|
|
||||||
},
|
|
||||||
required: ['param1'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('./ToolService', () => ({
|
jest.mock('./start/tools', () => ({
|
||||||
loadAndFormatTools: jest.fn().mockReturnValue({
|
loadAndFormatTools: jest.fn().mockReturnValue({
|
||||||
ExampleTool: {
|
ExampleTool: {
|
||||||
type: 'function',
|
type: 'function',
|
||||||
|
|
@ -117,12 +100,17 @@ const azureGroups = [
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
jest.mock('./start/checks', () => ({
|
||||||
|
...jest.requireActual('./start/checks'),
|
||||||
|
checkHealth: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
describe('AppService', () => {
|
describe('AppService', () => {
|
||||||
const mockedTurnstileConfig = {
|
const mockedTurnstileConfig = {
|
||||||
siteKey: 'default-site-key',
|
siteKey: 'default-site-key',
|
||||||
options: {},
|
options: {},
|
||||||
};
|
};
|
||||||
const { setAppConfig, loadCustomConfig } = require('./Config');
|
const loadCustomConfig = require('./Config/loadCustomConfig');
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
process.env.CDN_PROVIDER = undefined;
|
process.env.CDN_PROVIDER = undefined;
|
||||||
|
|
@ -130,11 +118,11 @@ describe('AppService', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should correctly assign process.env and initialize app config based on custom config', async () => {
|
it('should correctly assign process.env and initialize app config based on custom config', async () => {
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
expect(process.env.CDN_PROVIDER).toEqual('testStrategy');
|
expect(process.env.CDN_PROVIDER).toEqual('testStrategy');
|
||||||
|
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
config: expect.objectContaining({
|
config: expect.objectContaining({
|
||||||
fileStrategy: 'testStrategy',
|
fileStrategy: 'testStrategy',
|
||||||
|
|
@ -196,7 +184,7 @@ describe('AppService', () => {
|
||||||
|
|
||||||
await AppService();
|
await AppService();
|
||||||
|
|
||||||
const { logger } = require('~/config');
|
const { logger } = require('@librechat/data-schemas');
|
||||||
expect(logger.info).toHaveBeenCalledWith(expect.stringContaining('Outdated Config version'));
|
expect(logger.info).toHaveBeenCalledWith(expect.stringContaining('Outdated Config version'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -208,8 +196,8 @@ describe('AppService', () => {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
imageOutputType: EImageOutputType.WEBP,
|
imageOutputType: EImageOutputType.WEBP,
|
||||||
}),
|
}),
|
||||||
|
|
@ -223,8 +211,8 @@ describe('AppService', () => {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
imageOutputType: EImageOutputType.PNG,
|
imageOutputType: EImageOutputType.PNG,
|
||||||
}),
|
}),
|
||||||
|
|
@ -234,8 +222,8 @@ describe('AppService', () => {
|
||||||
it('should default to `PNG` `imageOutputType` with no provided config', async () => {
|
it('should default to `PNG` `imageOutputType` with no provided config', async () => {
|
||||||
loadCustomConfig.mockImplementationOnce(() => Promise.resolve(undefined));
|
loadCustomConfig.mockImplementationOnce(() => Promise.resolve(undefined));
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
imageOutputType: EImageOutputType.PNG,
|
imageOutputType: EImageOutputType.PNG,
|
||||||
}),
|
}),
|
||||||
|
|
@ -259,9 +247,8 @@ describe('AppService', () => {
|
||||||
|
|
||||||
it('should load and format tools accurately with defined structure', async () => {
|
it('should load and format tools accurately with defined structure', async () => {
|
||||||
const { loadAndFormatTools } = require('./ToolService');
|
const { loadAndFormatTools } = require('./ToolService');
|
||||||
const { setCachedTools, getCachedTools } = require('./Config');
|
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
expect(loadAndFormatTools).toHaveBeenCalledWith({
|
expect(loadAndFormatTools).toHaveBeenCalledWith({
|
||||||
adminFilter: undefined,
|
adminFilter: undefined,
|
||||||
|
|
@ -271,31 +258,9 @@ describe('AppService', () => {
|
||||||
fileStrategy: expect.any(String),
|
fileStrategy: expect.any(String),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Verify setCachedTools was called with the tools
|
// Verify tools are included in the returned config
|
||||||
expect(setCachedTools).toHaveBeenCalledWith(
|
expect(result.availableTools).toBeDefined();
|
||||||
{
|
expect(result.availableTools.ExampleTool).toEqual({
|
||||||
ExampleTool: {
|
|
||||||
type: 'function',
|
|
||||||
function: {
|
|
||||||
description: 'Example tool function',
|
|
||||||
name: 'exampleFunction',
|
|
||||||
parameters: {
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
param1: { type: 'string', description: 'An example parameter' },
|
|
||||||
},
|
|
||||||
required: ['param1'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{ isGlobal: true },
|
|
||||||
);
|
|
||||||
|
|
||||||
// Verify we can retrieve the tools from cache
|
|
||||||
const cachedTools = await getCachedTools({ includeGlobal: true });
|
|
||||||
expect(cachedTools.ExampleTool).toBeDefined();
|
|
||||||
expect(cachedTools.ExampleTool).toEqual({
|
|
||||||
type: 'function',
|
type: 'function',
|
||||||
function: {
|
function: {
|
||||||
description: 'Example tool function',
|
description: 'Example tool function',
|
||||||
|
|
@ -326,9 +291,9 @@ describe('AppService', () => {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
endpoints: expect.objectContaining({
|
endpoints: expect.objectContaining({
|
||||||
[EModelEndpoint.assistants]: expect.objectContaining({
|
[EModelEndpoint.assistants]: expect.objectContaining({
|
||||||
|
|
@ -358,9 +323,9 @@ describe('AppService', () => {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
endpoints: expect.objectContaining({
|
endpoints: expect.objectContaining({
|
||||||
[EModelEndpoint.agents]: expect.objectContaining({
|
[EModelEndpoint.agents]: expect.objectContaining({
|
||||||
|
|
@ -381,9 +346,9 @@ describe('AppService', () => {
|
||||||
it('should configure Agents endpoint with defaults when no config is provided', async () => {
|
it('should configure Agents endpoint with defaults when no config is provided', async () => {
|
||||||
loadCustomConfig.mockImplementationOnce(() => Promise.resolve({}));
|
loadCustomConfig.mockImplementationOnce(() => Promise.resolve({}));
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
endpoints: expect.objectContaining({
|
endpoints: expect.objectContaining({
|
||||||
[EModelEndpoint.agents]: expect.objectContaining({
|
[EModelEndpoint.agents]: expect.objectContaining({
|
||||||
|
|
@ -406,9 +371,9 @@ describe('AppService', () => {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
endpoints: expect.objectContaining({
|
endpoints: expect.objectContaining({
|
||||||
[EModelEndpoint.agents]: expect.objectContaining({
|
[EModelEndpoint.agents]: expect.objectContaining({
|
||||||
|
|
@ -439,8 +404,8 @@ describe('AppService', () => {
|
||||||
process.env.WESTUS_API_KEY = 'westus-key';
|
process.env.WESTUS_API_KEY = 'westus-key';
|
||||||
process.env.EASTUS_API_KEY = 'eastus-key';
|
process.env.EASTUS_API_KEY = 'eastus-key';
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
endpoints: expect.objectContaining({
|
endpoints: expect.objectContaining({
|
||||||
[EModelEndpoint.azureAssistants]: expect.objectContaining({
|
[EModelEndpoint.azureAssistants]: expect.objectContaining({
|
||||||
|
|
@ -469,10 +434,10 @@ describe('AppService', () => {
|
||||||
process.env.WESTUS_API_KEY = 'westus-key';
|
process.env.WESTUS_API_KEY = 'westus-key';
|
||||||
process.env.EASTUS_API_KEY = 'eastus-key';
|
process.env.EASTUS_API_KEY = 'eastus-key';
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
const { modelNames, modelGroupMap, groupMap } = validateAzureGroups(azureGroups);
|
const { modelNames, modelGroupMap, groupMap } = validateAzureGroups(azureGroups);
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
endpoints: expect.objectContaining({
|
endpoints: expect.objectContaining({
|
||||||
[EModelEndpoint.azureOpenAI]: expect.objectContaining({
|
[EModelEndpoint.azureOpenAI]: expect.objectContaining({
|
||||||
|
|
@ -629,9 +594,9 @@ describe('AppService', () => {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
endpoints: expect.objectContaining({
|
endpoints: expect.objectContaining({
|
||||||
// Check OpenAI endpoint configuration
|
// Check OpenAI endpoint configuration
|
||||||
|
|
@ -679,9 +644,9 @@ describe('AppService', () => {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
endpoints: expect.objectContaining({
|
endpoints: expect.objectContaining({
|
||||||
[EModelEndpoint.agents]: expect.objectContaining({
|
[EModelEndpoint.agents]: expect.objectContaining({
|
||||||
|
|
@ -714,9 +679,9 @@ describe('AppService', () => {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
endpoints: expect.objectContaining({
|
endpoints: expect.objectContaining({
|
||||||
[EModelEndpoint.openAI]: expect.objectContaining({
|
[EModelEndpoint.openAI]: expect.objectContaining({
|
||||||
|
|
@ -727,10 +692,9 @@ describe('AppService', () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Verify that optional fields are not set when not provided
|
// Verify that optional fields are not set when not provided
|
||||||
const initCall = setAppConfig.mock.calls[0][0];
|
expect(result.endpoints[EModelEndpoint.openAI].titlePrompt).toBeUndefined();
|
||||||
expect(initCall.endpoints[EModelEndpoint.openAI].titlePrompt).toBeUndefined();
|
expect(result.endpoints[EModelEndpoint.openAI].titlePromptTemplate).toBeUndefined();
|
||||||
expect(initCall.endpoints[EModelEndpoint.openAI].titlePromptTemplate).toBeUndefined();
|
expect(result.endpoints[EModelEndpoint.openAI].titleMethod).toBeUndefined();
|
||||||
expect(initCall.endpoints[EModelEndpoint.openAI].titleMethod).toBeUndefined();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should correctly configure titleEndpoint when specified', async () => {
|
it('should correctly configure titleEndpoint when specified', async () => {
|
||||||
|
|
@ -751,9 +715,9 @@ describe('AppService', () => {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
endpoints: expect.objectContaining({
|
endpoints: expect.objectContaining({
|
||||||
// Check OpenAI endpoint has titleEndpoint
|
// Check OpenAI endpoint has titleEndpoint
|
||||||
|
|
@ -794,9 +758,9 @@ describe('AppService', () => {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
// Check that 'all' endpoint config is loaded
|
// Check that 'all' endpoint config is loaded
|
||||||
endpoints: expect.objectContaining({
|
endpoints: expect.objectContaining({
|
||||||
|
|
@ -822,7 +786,7 @@ describe('AppService', () => {
|
||||||
|
|
||||||
describe('AppService updating app config and issuing warnings', () => {
|
describe('AppService updating app config and issuing warnings', () => {
|
||||||
let initialEnv;
|
let initialEnv;
|
||||||
const { setAppConfig, loadCustomConfig } = require('./Config');
|
const loadCustomConfig = require('./Config/loadCustomConfig');
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// Store initial environment variables to restore them after each test
|
// Store initial environment variables to restore them after each test
|
||||||
|
|
@ -841,9 +805,9 @@ describe('AppService updating app config and issuing warnings', () => {
|
||||||
// Mock loadCustomConfig to return undefined
|
// Mock loadCustomConfig to return undefined
|
||||||
loadCustomConfig.mockImplementationOnce(() => Promise.resolve(undefined));
|
loadCustomConfig.mockImplementationOnce(() => Promise.resolve(undefined));
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
paths: expect.anything(),
|
paths: expect.anything(),
|
||||||
config: {},
|
config: {},
|
||||||
|
|
@ -875,9 +839,9 @@ describe('AppService updating app config and issuing warnings', () => {
|
||||||
};
|
};
|
||||||
loadCustomConfig.mockImplementationOnce(() => Promise.resolve(customConfig));
|
loadCustomConfig.mockImplementationOnce(() => Promise.resolve(customConfig));
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
paths: expect.anything(),
|
paths: expect.anything(),
|
||||||
config: customConfig,
|
config: customConfig,
|
||||||
|
|
@ -903,9 +867,9 @@ describe('AppService updating app config and issuing warnings', () => {
|
||||||
};
|
};
|
||||||
loadCustomConfig.mockImplementationOnce(() => Promise.resolve(mockConfig));
|
loadCustomConfig.mockImplementationOnce(() => Promise.resolve(mockConfig));
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
endpoints: expect.objectContaining({
|
endpoints: expect.objectContaining({
|
||||||
assistants: expect.objectContaining({
|
assistants: expect.objectContaining({
|
||||||
|
|
@ -919,8 +883,7 @@ describe('AppService updating app config and issuing warnings', () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Verify excludedIds is undefined when not provided
|
// Verify excludedIds is undefined when not provided
|
||||||
const initCall = setAppConfig.mock.calls[0][0];
|
expect(result.endpoints.assistants.excludedIds).toBeUndefined();
|
||||||
expect(initCall.endpoints.assistants.excludedIds).toBeUndefined();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log a warning when both supportedIds and excludedIds are provided', async () => {
|
it('should log a warning when both supportedIds and excludedIds are provided', async () => {
|
||||||
|
|
@ -939,7 +902,7 @@ describe('AppService updating app config and issuing warnings', () => {
|
||||||
|
|
||||||
await AppService();
|
await AppService();
|
||||||
|
|
||||||
const { logger } = require('~/config');
|
const { logger } = require('@librechat/data-schemas');
|
||||||
expect(logger.warn).toHaveBeenCalledWith(
|
expect(logger.warn).toHaveBeenCalledWith(
|
||||||
expect.stringContaining(
|
expect.stringContaining(
|
||||||
"The 'assistants' endpoint has both 'supportedIds' and 'excludedIds' defined.",
|
"The 'assistants' endpoint has both 'supportedIds' and 'excludedIds' defined.",
|
||||||
|
|
@ -960,7 +923,7 @@ describe('AppService updating app config and issuing warnings', () => {
|
||||||
|
|
||||||
await AppService();
|
await AppService();
|
||||||
|
|
||||||
const { logger } = require('~/config');
|
const { logger } = require('@librechat/data-schemas');
|
||||||
expect(logger.warn).toHaveBeenCalledWith(
|
expect(logger.warn).toHaveBeenCalledWith(
|
||||||
expect.stringContaining(
|
expect.stringContaining(
|
||||||
"The 'assistants' endpoint has both 'privateAssistants' and 'supportedIds' or 'excludedIds' defined.",
|
"The 'assistants' endpoint has both 'privateAssistants' and 'supportedIds' or 'excludedIds' defined.",
|
||||||
|
|
@ -985,7 +948,7 @@ describe('AppService updating app config and issuing warnings', () => {
|
||||||
|
|
||||||
await AppService();
|
await AppService();
|
||||||
|
|
||||||
const { logger } = require('~/config');
|
const { logger } = require('@librechat/data-schemas');
|
||||||
deprecatedAzureVariables.forEach(({ key, description }) => {
|
deprecatedAzureVariables.forEach(({ key, description }) => {
|
||||||
expect(logger.warn).toHaveBeenCalledWith(
|
expect(logger.warn).toHaveBeenCalledWith(
|
||||||
`The \`${key}\` environment variable (related to ${description}) should not be used in combination with the \`azureOpenAI\` endpoint configuration, as you will experience conflicts and errors.`,
|
`The \`${key}\` environment variable (related to ${description}) should not be used in combination with the \`azureOpenAI\` endpoint configuration, as you will experience conflicts and errors.`,
|
||||||
|
|
@ -1010,7 +973,7 @@ describe('AppService updating app config and issuing warnings', () => {
|
||||||
|
|
||||||
await AppService();
|
await AppService();
|
||||||
|
|
||||||
const { logger } = require('~/config');
|
const { logger } = require('@librechat/data-schemas');
|
||||||
conflictingAzureVariables.forEach(({ key }) => {
|
conflictingAzureVariables.forEach(({ key }) => {
|
||||||
expect(logger.warn).toHaveBeenCalledWith(
|
expect(logger.warn).toHaveBeenCalledWith(
|
||||||
`The \`${key}\` environment variable should not be used in combination with the \`azureOpenAI\` endpoint configuration, as you may experience with the defined placeholders for mapping to the current model grouping using the same name.`,
|
`The \`${key}\` environment variable should not be used in combination with the \`azureOpenAI\` endpoint configuration, as you may experience with the defined placeholders for mapping to the current model grouping using the same name.`,
|
||||||
|
|
@ -1035,10 +998,10 @@ describe('AppService updating app config and issuing warnings', () => {
|
||||||
process.env.OCR_API_KEY_CUSTOM_VAR_NAME = 'actual-api-key';
|
process.env.OCR_API_KEY_CUSTOM_VAR_NAME = 'actual-api-key';
|
||||||
process.env.OCR_BASEURL_CUSTOM_VAR_NAME = 'https://actual-ocr-url.com';
|
process.env.OCR_BASEURL_CUSTOM_VAR_NAME = 'https://actual-ocr-url.com';
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
// Verify that the raw string references were preserved and not interpolated
|
// Verify that the raw string references were preserved and not interpolated
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
ocr: expect.objectContaining({
|
ocr: expect.objectContaining({
|
||||||
apiKey: '${OCR_API_KEY_CUSTOM_VAR_NAME}',
|
apiKey: '${OCR_API_KEY_CUSTOM_VAR_NAME}',
|
||||||
|
|
@ -1063,10 +1026,10 @@ describe('AppService updating app config and issuing warnings', () => {
|
||||||
|
|
||||||
loadCustomConfig.mockImplementationOnce(() => Promise.resolve(mockConfig));
|
loadCustomConfig.mockImplementationOnce(() => Promise.resolve(mockConfig));
|
||||||
|
|
||||||
await AppService();
|
const result = await AppService();
|
||||||
|
|
||||||
// Check that interface config includes the permissions
|
// Check that interface config includes the permissions
|
||||||
expect(setAppConfig).toHaveBeenCalledWith(
|
expect(result).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
interfaceConfig: expect.objectContaining({
|
interfaceConfig: expect.objectContaining({
|
||||||
peoplePicker: expect.objectContaining({
|
peoplePicker: expect.objectContaining({
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
// Mock librechat-data-provider
|
|
||||||
jest.mock('librechat-data-provider', () => ({
|
jest.mock('librechat-data-provider', () => ({
|
||||||
...jest.requireActual('librechat-data-provider'),
|
...jest.requireActual('librechat-data-provider'),
|
||||||
extractVariableName: jest.fn(),
|
extractVariableName: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Mock the config logger
|
jest.mock('@librechat/data-schemas', () => ({
|
||||||
jest.mock('~/config', () => ({
|
...jest.requireActual('@librechat/data-schemas'),
|
||||||
logger: {
|
logger: {
|
||||||
debug: jest.fn(),
|
debug: jest.fn(),
|
||||||
warn: jest.fn(),
|
warn: jest.fn(),
|
||||||
|
|
@ -13,7 +12,7 @@ jest.mock('~/config', () => ({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const { checkWebSearchConfig } = require('./checks');
|
const { checkWebSearchConfig } = require('./checks');
|
||||||
const { logger } = require('~/config');
|
const { logger } = require('@librechat/data-schemas');
|
||||||
const { extractVariableName } = require('librechat-data-provider');
|
const { extractVariableName } = require('librechat-data-provider');
|
||||||
|
|
||||||
describe('checkWebSearchConfig', () => {
|
describe('checkWebSearchConfig', () => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue