mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-02-23 19:04:10 +01:00
chore: fix ESLint issues and Test Mocks
This commit is contained in:
parent
a17826fe39
commit
cec1ec0c79
7 changed files with 119 additions and 17 deletions
|
|
@ -11,7 +11,6 @@ let File;
|
||||||
let Agent;
|
let Agent;
|
||||||
let AclEntry;
|
let AclEntry;
|
||||||
let User;
|
let User;
|
||||||
let AccessRole;
|
|
||||||
let modelsToCleanup = [];
|
let modelsToCleanup = [];
|
||||||
|
|
||||||
describe('File Access Control', () => {
|
describe('File Access Control', () => {
|
||||||
|
|
@ -36,7 +35,6 @@ describe('File Access Control', () => {
|
||||||
Agent = dbModels.Agent;
|
Agent = dbModels.Agent;
|
||||||
AclEntry = dbModels.AclEntry;
|
AclEntry = dbModels.AclEntry;
|
||||||
User = dbModels.User;
|
User = dbModels.User;
|
||||||
AccessRole = dbModels.AccessRole;
|
|
||||||
|
|
||||||
// Seed default roles
|
// Seed default roles
|
||||||
await seedDefaultRoles();
|
await seedDefaultRoles();
|
||||||
|
|
@ -149,7 +147,7 @@ describe('File Access Control', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create agent
|
// Create agent
|
||||||
const agent = await createAgent({
|
await createAgent({
|
||||||
id: agentId,
|
id: agentId,
|
||||||
name: 'Test Agent',
|
name: 'Test Agent',
|
||||||
author: authorId,
|
author: authorId,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ const express = require('express');
|
||||||
const request = require('supertest');
|
const request = require('supertest');
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const { v4: uuidv4 } = require('uuid');
|
const { v4: uuidv4 } = require('uuid');
|
||||||
const { PERMISSION_BITS } = require('librechat-data-provider');
|
|
||||||
const { MongoMemoryServer } = require('mongodb-memory-server');
|
const { MongoMemoryServer } = require('mongodb-memory-server');
|
||||||
const { createMethods } = require('@librechat/data-schemas');
|
const { createMethods } = require('@librechat/data-schemas');
|
||||||
const { createAgent } = require('~/models/Agent');
|
const { createAgent } = require('~/models/Agent');
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,11 @@ describe('loadDefaultInterface', () => {
|
||||||
expect(updateAccessPermissions).toHaveBeenCalledWith(SystemRoles.USER, {
|
expect(updateAccessPermissions).toHaveBeenCalledWith(SystemRoles.USER, {
|
||||||
[PermissionTypes.PROMPTS]: { [Permissions.USE]: true },
|
[PermissionTypes.PROMPTS]: { [Permissions.USE]: true },
|
||||||
[PermissionTypes.BOOKMARKS]: { [Permissions.USE]: true },
|
[PermissionTypes.BOOKMARKS]: { [Permissions.USE]: true },
|
||||||
[PermissionTypes.MEMORIES]: { [Permissions.USE]: true, [Permissions.OPT_OUT]: undefined, [Permissions.OPT_OUT]: undefined },
|
[PermissionTypes.MEMORIES]: {
|
||||||
|
[Permissions.USE]: true,
|
||||||
|
[Permissions.OPT_OUT]: undefined,
|
||||||
|
[Permissions.OPT_OUT]: undefined,
|
||||||
|
},
|
||||||
[PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true },
|
[PermissionTypes.MULTI_CONVO]: { [Permissions.USE]: true },
|
||||||
[PermissionTypes.AGENTS]: { [Permissions.USE]: true },
|
[PermissionTypes.AGENTS]: { [Permissions.USE]: true },
|
||||||
[PermissionTypes.TEMPORARY_CHAT]: { [Permissions.USE]: true },
|
[PermissionTypes.TEMPORARY_CHAT]: { [Permissions.USE]: true },
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
import React, { useMemo } from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { EModelEndpoint } from 'librechat-data-provider';
|
|
||||||
|
|
||||||
import { ChatContext } from '~/Providers';
|
import { ChatContext } from '~/Providers';
|
||||||
import { useChatHelpers } from '~/hooks';
|
import { useChatHelpers } from '~/hooks';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-require-imports */
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render, screen, waitFor } from '@testing-library/react';
|
import { render, screen, waitFor } from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
|
|
@ -6,10 +7,10 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||||
import { RecoilRoot } from 'recoil';
|
import { RecoilRoot } from 'recoil';
|
||||||
|
|
||||||
import type t from 'librechat-data-provider';
|
import type t from 'librechat-data-provider';
|
||||||
|
import { Constants, EModelEndpoint } from 'librechat-data-provider';
|
||||||
|
|
||||||
import AgentDetail from '../AgentDetail';
|
import AgentDetail from '../AgentDetail';
|
||||||
import { useToast } from '~/hooks';
|
import { useToast } from '~/hooks';
|
||||||
import useLocalize from '~/hooks/useLocalize';
|
|
||||||
|
|
||||||
// Mock dependencies
|
// Mock dependencies
|
||||||
jest.mock('react-router-dom', () => ({
|
jest.mock('react-router-dom', () => ({
|
||||||
|
|
@ -20,11 +21,7 @@ jest.mock('react-router-dom', () => ({
|
||||||
jest.mock('~/hooks', () => ({
|
jest.mock('~/hooks', () => ({
|
||||||
useToast: jest.fn(),
|
useToast: jest.fn(),
|
||||||
useMediaQuery: jest.fn(() => false), // Mock as desktop by default
|
useMediaQuery: jest.fn(() => false), // Mock as desktop by default
|
||||||
}));
|
useLocalize: jest.fn(),
|
||||||
|
|
||||||
jest.mock('~/hooks/useLocalize', () => ({
|
|
||||||
__esModule: true,
|
|
||||||
default: jest.fn(),
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('~/utils/agents', () => ({
|
jest.mock('~/utils/agents', () => ({
|
||||||
|
|
@ -33,6 +30,15 @@ jest.mock('~/utils/agents', () => ({
|
||||||
)),
|
)),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
jest.mock('~/Providers', () => ({
|
||||||
|
useChatContext: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock('@tanstack/react-query', () => ({
|
||||||
|
...jest.requireActual('@tanstack/react-query'),
|
||||||
|
useQueryClient: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
// Mock clipboard API
|
// Mock clipboard API
|
||||||
const mockWriteText = jest.fn();
|
const mockWriteText = jest.fn();
|
||||||
|
|
||||||
|
|
@ -96,8 +102,24 @@ describe('AgentDetail', () => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
(useNavigate as jest.Mock).mockReturnValue(mockNavigate);
|
(useNavigate as jest.Mock).mockReturnValue(mockNavigate);
|
||||||
(useToast as jest.Mock).mockReturnValue({ showToast: mockShowToast });
|
(useToast as jest.Mock).mockReturnValue({ showToast: mockShowToast });
|
||||||
|
const { useLocalize } = require('~/hooks');
|
||||||
(useLocalize as jest.Mock).mockReturnValue(mockLocalize);
|
(useLocalize as jest.Mock).mockReturnValue(mockLocalize);
|
||||||
|
|
||||||
|
// Mock useChatContext
|
||||||
|
const { useChatContext } = require('~/Providers');
|
||||||
|
(useChatContext as jest.Mock).mockReturnValue({
|
||||||
|
conversation: { conversationId: 'test-convo-id' },
|
||||||
|
newConversation: jest.fn(),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Mock useQueryClient
|
||||||
|
const { useQueryClient } = require('@tanstack/react-query');
|
||||||
|
(useQueryClient as jest.Mock).mockReturnValue({
|
||||||
|
getQueryData: jest.fn(),
|
||||||
|
setQueryData: jest.fn(),
|
||||||
|
invalidateQueries: jest.fn(),
|
||||||
|
});
|
||||||
|
|
||||||
// Setup clipboard mock if it doesn't exist
|
// Setup clipboard mock if it doesn't exist
|
||||||
if (!navigator.clipboard) {
|
if (!navigator.clipboard) {
|
||||||
Object.defineProperty(navigator, 'clipboard', {
|
Object.defineProperty(navigator, 'clipboard', {
|
||||||
|
|
@ -176,12 +198,36 @@ describe('AgentDetail', () => {
|
||||||
describe('Interactions', () => {
|
describe('Interactions', () => {
|
||||||
it('should navigate to chat when Start Chat button is clicked', async () => {
|
it('should navigate to chat when Start Chat button is clicked', async () => {
|
||||||
const user = userEvent.setup();
|
const user = userEvent.setup();
|
||||||
|
const mockNewConversation = jest.fn();
|
||||||
|
const mockQueryClient = {
|
||||||
|
getQueryData: jest.fn().mockReturnValue(null),
|
||||||
|
setQueryData: jest.fn(),
|
||||||
|
invalidateQueries: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update mocks for this test
|
||||||
|
const { useChatContext } = require('~/Providers');
|
||||||
|
(useChatContext as jest.Mock).mockReturnValue({
|
||||||
|
conversation: { conversationId: 'test-convo-id' },
|
||||||
|
newConversation: mockNewConversation,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { useQueryClient } = require('@tanstack/react-query');
|
||||||
|
(useQueryClient as jest.Mock).mockReturnValue(mockQueryClient);
|
||||||
|
|
||||||
renderWithProviders(<AgentDetail {...defaultProps} />);
|
renderWithProviders(<AgentDetail {...defaultProps} />);
|
||||||
|
|
||||||
const startChatButton = screen.getByRole('button', { name: 'com_agents_start_chat' });
|
const startChatButton = screen.getByRole('button', { name: 'com_agents_start_chat' });
|
||||||
await user.click(startChatButton);
|
await user.click(startChatButton);
|
||||||
|
|
||||||
expect(mockNavigate).toHaveBeenCalledWith('/c/new?agent_id=test-agent-id');
|
expect(mockNewConversation).toHaveBeenCalledWith({
|
||||||
|
template: {
|
||||||
|
conversationId: Constants.NEW_CONVO,
|
||||||
|
endpoint: EModelEndpoint.agents,
|
||||||
|
agent_id: 'test-agent-id',
|
||||||
|
title: 'Chat with Test Agent',
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not navigate when agent is null', async () => {
|
it('should not navigate when agent is null', async () => {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-require-imports */
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render, screen } from '@testing-library/react';
|
import { render, screen } from '@testing-library/react';
|
||||||
import '@testing-library/jest-dom';
|
import '@testing-library/jest-dom';
|
||||||
|
|
@ -17,6 +18,11 @@ jest.mock('~/Providers', () => ({
|
||||||
useChatContext: jest.fn(),
|
useChatContext: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// Mock useChatHelpers to avoid Recoil dependency
|
||||||
|
jest.mock('~/hooks', () => ({
|
||||||
|
useChatHelpers: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
const mockedUseChatContext = useChatContext as jest.MockedFunction<typeof useChatContext>;
|
const mockedUseChatContext = useChatContext as jest.MockedFunction<typeof useChatContext>;
|
||||||
|
|
||||||
// Test component that consumes the context
|
// Test component that consumes the context
|
||||||
|
|
@ -35,6 +41,16 @@ const TestConsumer: React.FC = () => {
|
||||||
describe('MarketplaceProvider', () => {
|
describe('MarketplaceProvider', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mockedUseChatContext.mockClear();
|
mockedUseChatContext.mockClear();
|
||||||
|
|
||||||
|
// Mock useChatHelpers return value
|
||||||
|
const { useChatHelpers } = require('~/hooks');
|
||||||
|
(useChatHelpers as jest.Mock).mockReturnValue({
|
||||||
|
conversation: {
|
||||||
|
endpoint: EModelEndpoint.agents,
|
||||||
|
conversationId: 'marketplace',
|
||||||
|
title: 'Agent Marketplace',
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('provides correct marketplace context values', () => {
|
it('provides correct marketplace context values', () => {
|
||||||
|
|
@ -46,7 +62,7 @@ describe('MarketplaceProvider', () => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
mockedUseChatContext.mockReturnValue(mockContext);
|
mockedUseChatContext.mockReturnValue(mockContext as ReturnType<typeof useChatContext>);
|
||||||
|
|
||||||
render(
|
render(
|
||||||
<MarketplaceProvider>
|
<MarketplaceProvider>
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ jest.mock('react-router-dom', () => ({
|
||||||
|
|
||||||
jest.mock('@tanstack/react-query', () => ({
|
jest.mock('@tanstack/react-query', () => ({
|
||||||
useQueryClient: jest.fn(),
|
useQueryClient: jest.fn(),
|
||||||
|
useQuery: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('~/Providers', () => ({
|
jest.mock('~/Providers', () => ({
|
||||||
|
|
@ -51,6 +52,15 @@ jest.mock('~/hooks/Conversations/useDefaultConvo', () => ({
|
||||||
default: jest.fn(),
|
default: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
jest.mock('~/hooks/AuthContext', () => ({
|
||||||
|
useAuthContext: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock('~/hooks/Agents/useAgentsMap', () => ({
|
||||||
|
__esModule: true,
|
||||||
|
default: jest.fn(() => ({})),
|
||||||
|
}));
|
||||||
|
|
||||||
jest.mock('~/utils', () => ({
|
jest.mock('~/utils', () => ({
|
||||||
getConvoSwitchLogic: jest.fn(() => ({
|
getConvoSwitchLogic: jest.fn(() => ({
|
||||||
template: {},
|
template: {},
|
||||||
|
|
@ -63,6 +73,8 @@ jest.mock('~/utils', () => ({
|
||||||
getModelSpecIconURL: jest.fn(() => 'icon-url'),
|
getModelSpecIconURL: jest.fn(() => 'icon-url'),
|
||||||
removeUnavailableTools: jest.fn((preset) => preset),
|
removeUnavailableTools: jest.fn((preset) => preset),
|
||||||
logger: { log: jest.fn() },
|
logger: { log: jest.fn() },
|
||||||
|
getInitialTheme: jest.fn(() => 'light'),
|
||||||
|
applyFontSize: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Mock the tQueryParamsSchema
|
// Mock the tQueryParamsSchema
|
||||||
|
|
@ -82,6 +94,21 @@ jest.mock('librechat-data-provider', () => ({
|
||||||
EModelEndpoint: { custom: 'custom', assistants: 'assistants', agents: 'agents' },
|
EModelEndpoint: { custom: 'custom', assistants: 'assistants', agents: 'agents' },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// Mock data-provider hooks
|
||||||
|
jest.mock('~/data-provider', () => ({
|
||||||
|
useGetAgentByIdQuery: jest.fn(() => ({
|
||||||
|
data: null,
|
||||||
|
isLoading: false,
|
||||||
|
error: null,
|
||||||
|
})),
|
||||||
|
useAgentListingDefaultPermissionLevel: jest.fn(() => 'view'),
|
||||||
|
useListAgentsQuery: jest.fn(() => ({
|
||||||
|
data: null,
|
||||||
|
isLoading: false,
|
||||||
|
error: null,
|
||||||
|
})),
|
||||||
|
}));
|
||||||
|
|
||||||
// Mock global window.history
|
// Mock global window.history
|
||||||
global.window = Object.create(window);
|
global.window = Object.create(window);
|
||||||
global.window.history = {
|
global.window.history = {
|
||||||
|
|
@ -103,6 +130,14 @@ describe('useQueryParams', () => {
|
||||||
// Reset mock for window.history.replaceState
|
// Reset mock for window.history.replaceState
|
||||||
jest.spyOn(window.history, 'replaceState').mockClear();
|
jest.spyOn(window.history, 'replaceState').mockClear();
|
||||||
|
|
||||||
|
// Reset data-provider mocks
|
||||||
|
const dataProvider = jest.requireMock('~/data-provider');
|
||||||
|
(dataProvider.useGetAgentByIdQuery as jest.Mock).mockReturnValue({
|
||||||
|
data: null,
|
||||||
|
isLoading: false,
|
||||||
|
error: null,
|
||||||
|
});
|
||||||
|
|
||||||
// Create mocks for all dependencies
|
// Create mocks for all dependencies
|
||||||
const mockSearchParams = new URLSearchParams();
|
const mockSearchParams = new URLSearchParams();
|
||||||
(useSearchParams as jest.Mock).mockReturnValue([mockSearchParams, jest.fn()]);
|
(useSearchParams as jest.Mock).mockReturnValue([mockSearchParams, jest.fn()]);
|
||||||
|
|
@ -147,6 +182,13 @@ describe('useQueryParams', () => {
|
||||||
|
|
||||||
const mockGetDefaultConversation = jest.fn().mockReturnValue({});
|
const mockGetDefaultConversation = jest.fn().mockReturnValue({});
|
||||||
(useDefaultConvo as jest.Mock).mockReturnValue(mockGetDefaultConversation);
|
(useDefaultConvo as jest.Mock).mockReturnValue(mockGetDefaultConversation);
|
||||||
|
|
||||||
|
// Mock useAuthContext
|
||||||
|
const { useAuthContext } = jest.requireMock('~/hooks/AuthContext');
|
||||||
|
(useAuthContext as jest.Mock).mockReturnValue({
|
||||||
|
user: { id: 'test-user-id' },
|
||||||
|
isAuthenticated: true,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue