Skip to content

Commit

Permalink
Fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
harishmohanraj committed Sep 2, 2024
1 parent 2064f18 commit a81d16b
Show file tree
Hide file tree
Showing 5 changed files with 558 additions and 500 deletions.
381 changes: 381 additions & 0 deletions app/src/client/tests/BuildPage-e2e.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,381 @@
import React from 'react';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { screen, waitFor, RenderResult, within } from '@testing-library/react';
import userEvent, { UserEvent } from '@testing-library/user-event';
import { renderInContext } from 'wasp/client/test';
import { useQuery } from 'wasp/client/operations';
import { mockProps } from './mocks';

// Types
interface MockData {
uuid: string;
user_uuid: string;
type_name: string;
model_name: string;
json_str: Record<string, any>;
created_at: string;
updated_at: string;
}

// Mock setup
let mockData: MockData[] = [];
let mockIsLoading = false;
const mockRefetch = vi.fn();
const mockGetModels = vi.fn();
const mockValidateForm = vi.fn();
const mockAddUserModels = vi.fn();

vi.mock('wasp/client/operations', () => ({
useQuery: vi.fn(() => ({
data: mockData,
isLoading: mockIsLoading,
refetch: mockRefetch,
})),
getModels: (...args: any[]) => mockGetModels(...args),
validateForm: (...args: any[]) => mockValidateForm(...args),
addUserModels: (...args: any[]) => mockAddUserModels(...args),
}));

function getActiveTabPanel(): HTMLElement {
const activeTab = screen.getByRole('tab', { selected: true });
const activeTabPanel = screen.getByRole('tabpanel', { hidden: false });
return activeTabPanel;
}

// Helper functions
const setupComponent = async (): Promise<{ user: UserEvent; container: HTMLElement }> => {
const user = userEvent.setup();
const { BuildPageTab } = await import('../components/buildPage/BuildPageTab');
const renderResult = renderInContext(<BuildPageTab {...mockProps} activeProperty='agent' />);
const activePanel = getActiveTabPanel();
await user.click(within(activePanel).getByText('ADD AGENT'));
await waitFor(() => {
expect(within(activePanel).getByText('AssistantAgent')).toBeInTheDocument();
expect(within(activePanel).getByText('LLM')).toBeInTheDocument();
});
return { user, ...renderResult };
};

const createSecret = async (user: UserEvent): Promise<void> => {
const activePanel = getActiveTabPanel();
await user.click(within(activePanel).getAllByRole('combobox')[2]);
await user.click(within(activePanel).getByText('Add new "Secret"'));
await waitFor(() => expect(within(activePanel).getByText('Select Secret')).toBeInTheDocument());
expect(within(activePanel).getByText('AnthropicAPIKey')).toBeInTheDocument();

const nameInput = within(activePanel).getByPlaceholderText('The name of the item');
await user.type(nameInput, 'My AnthropicAPIKey Secret');

const apiKeyInput = within(activePanel).getByPlaceholderText('The API Key from Anthropic');
await user.type(apiKeyInput, 'My Api Key');

mockValidateForm.mockResolvedValue({
name: 'My AnthropicAPIKey Secret',
api_key: 'test-api-key-12345', // pragma: allowlist secret
uuid: 'test-uuid-secret-123',
});

mockData = [
{
uuid: 'test-uuid-secret-123',
user_uuid: 'test-user-uuid-563ec0df-3ecd-4d2a',
type_name: 'secret',
model_name: 'AnthropicAPIKey',
json_str: {
name: 'My AnthropicAPIKey Secret',
api_key: 'test-api-key-12345', // pragma: allowlist secret
},
created_at: '2024-08-19T11:28:32.875000Z',
updated_at: '2024-08-19T11:28:32.875000Z',
},
];

mockRefetch.mockResolvedValue({ data: mockData });

// Check if the breadcrumbs are displayed correctly
expect(within(activePanel).getByTestId('breadcrumb-link-Agent')).toBeInTheDocument();
expect(within(activePanel).getByTestId('breadcrumb-link-LLM')).toBeInTheDocument();
expect(within(activePanel).getByTestId('breadcrumb-link-Secret')).toBeInTheDocument();

// Save the form
await user.click(within(activePanel).getByRole('button', { name: 'Save' }));

await waitFor(() => {
expect(mockRefetch).toHaveBeenCalled();
});

// Wait for the refetch to be called and check if the data is updated
await waitFor(() => {
expect(mockRefetch).toHaveBeenCalled();
expect(within(activePanel).getByText('Anthropic')).toBeInTheDocument();

const nameInput = within(activePanel).getByPlaceholderText('The name of the item');
expect(nameInput).toHaveValue('My Anthropic LLM');

expect(within(activePanel).getByText('My AnthropicAPIKey Secret')).toBeInTheDocument();
});
};

const createLLM = async (user: UserEvent): Promise<void> => {
const activePanel = getActiveTabPanel();
await user.click(within(activePanel).getAllByRole('combobox')[1]);
await user.click(within(activePanel).getByText('Add new "LLM"'));
await waitFor(() => expect(within(activePanel).getByText('Select LLM')).toBeInTheDocument());
const nameInput = within(activePanel).getByPlaceholderText('The name of the item');
await user.type(nameInput, 'My Anthropic LLM');

await createSecret(user);

mockValidateForm.mockResolvedValue({
name: 'My Anthropic LLM',
model: 'claude-3-5-sonnet-20240620',
api_key: {
name: 'My AnthropicAPIKey Secret',
type: 'secret',
uuid: 'test-uuid-secret-123',
},
api_type: 'anthropic',
base_url: 'https://api.anthropic.com/v1',
temperature: 0.8,
uuid: 'test-uuid-llm-456',
});

mockData.push({
uuid: 'test-uuid-llm-456',
user_uuid: 'test-user-uuid-563ec0df-3ecd-4d2a',
type_name: 'llm',
model_name: 'Anthropic',
json_str: {
name: 'My Anthropic LLM',
model: 'claude-3-5-sonnet-20240620',
api_key: {
name: 'My AnthropicAPIKey Secret',
type: 'secret',
uuid: 'test-uuid-secret-123',
},
api_type: 'anthropic',
base_url: 'https://api.anthropic.com/v1',
temperature: 0.8,
},
created_at: '2024-08-19T11:30:40.194000Z',
updated_at: '2024-08-19T11:30:40.194000Z',
});

mockRefetch.mockResolvedValue({ data: mockData });

// Check if the breadcrumbs are displayed correctly
expect(within(activePanel).getByTestId('breadcrumb-link-Agent')).toBeInTheDocument();
expect(within(activePanel).getByTestId('breadcrumb-link-LLM')).toBeInTheDocument();

// Save the form
await user.click(within(activePanel).getByRole('button', { name: 'Save' }));

await waitFor(async () => {
expect(within(activePanel).getByText('AssistantAgent')).toBeInTheDocument();
expect(within(activePanel).getByText('LLM')).toBeInTheDocument();

const nameInput = within(activePanel).getByPlaceholderText('The name of the item');
expect(nameInput).toHaveValue('My Anthropic Agent');
expect(within(activePanel).getByText('My Anthropic LLM')).toBeInTheDocument();
await user.click(within(activePanel).getAllByRole('combobox')[1]);
expect(within(activePanel).getByRole('listbox').children.length).toBe(2);
});
};

const createToolbox = async (user: UserEvent): Promise<void> => {
const activePanel = getActiveTabPanel();
await user.click(within(activePanel).getAllByRole('combobox')[2]);
await user.click(within(activePanel).getByText('Add new "Toolbox"'));

const nameInput = within(activePanel).getByPlaceholderText('The name of the item');
await user.type(nameInput, 'My Toolbox Name');

const OpenAPIURLInput = within(activePanel).getByPlaceholderText('The URL of OpenAPI specification file');
await user.type(OpenAPIURLInput, 'https://api.mytoolbox.com/openapi.json');

mockValidateForm.mockResolvedValue({
name: 'My Toolbox Name',
openapi_url: 'https://api.mytoolbox.com/openapi.json',
openapi_auth: null,
uuid: 'test-uuid-toolbox-789',
});

mockData.push({
uuid: 'test-uuid-toolbox-789',
user_uuid: 'test-user-uuid-563ec0df-3ecd-4d2a',
type_name: 'toolbox',
model_name: 'Toolbox',
json_str: {
name: 'My Toolbox Name',
openapi_url: 'https://api.mytoolbox.com/openapi.json',
openapi_auth: null,
},
created_at: '2024-08-20T08:02:57.112000Z',
updated_at: '2024-08-20T08:02:57.112000Z',
});

mockRefetch.mockResolvedValue({ data: mockData });
await user.click(within(activePanel).getByRole('button', { name: 'Save' }));

await waitFor(async () => {
// check if the previous form is able to presist the user input
const nameInput = within(activePanel).getByPlaceholderText('The name of the item');
expect(nameInput).toHaveValue('My Anthropic Agent');
expect(within(activePanel).getByText('My Anthropic LLM')).toBeInTheDocument();
expect(within(activePanel).getByText('My Toolbox Name')).toBeInTheDocument();
});
};

describe('UserProperty Component Tests', () => {
beforeEach(() => {
vi.clearAllMocks();
mockData = [];
mockIsLoading = false;
mockRefetch.mockReset().mockResolvedValue({ data: mockData });
mockGetModels.mockReset().mockResolvedValue([]);
mockValidateForm.mockReset();
mockAddUserModels.mockReset();
});

it('should persist user-filled form data when pressing cancel in the resume flow', async () => {
const { user } = await setupComponent();
const activePanel = getActiveTabPanel();

const nameInput = within(activePanel).getByPlaceholderText('The name of the item');
await user.type(nameInput, 'Test Name');
await user.click(within(activePanel).getAllByRole('combobox')[1]);
await user.click(within(activePanel).getByText('Add new "LLM"'));

await waitFor(() => expect(within(activePanel).getByText('Select LLM')).toBeInTheDocument());

await user.click(within(activePanel).getByRole('button', { name: 'Cancel' }));

await waitFor(() => {
expect(within(activePanel).getByText('AssistantAgent')).toBeInTheDocument();
expect(within(activePanel).getByText('LLM')).toBeInTheDocument();
expect(nameInput).toHaveValue('Test Name');
});
});

it('should create an agent with dependent properties', async () => {
const { user } = await setupComponent();
const activePanel = getActiveTabPanel();

const nameInput = within(activePanel).getByPlaceholderText('The name of the item');
await user.type(nameInput, 'My Anthropic Agent');

await createLLM(user);
await createToolbox(user);

// Create Agent
mockValidateForm.mockResolvedValue({
name: 'My Anthropic Agent',
llm: {
type: 'llm',
name: 'My Anthropic LLM',
uuid: 'test-uuid-llm-456',
},
toolbox_1: {
type: 'toolbox',
name: 'My Toolbox Name',
uuid: 'test-uuid-toolbox-789',
},
toolbox_2: null,
toolbox_3: null,
system_message: 'You are a helpful assistant.',
uuid: 'test-uuid-agent-101',
});

mockData.push({
uuid: 'test-uuid-agent-101',
user_uuid: 'test-user-uuid-563ec0df-3ecd-4d2a',
type_name: 'agent',
model_name: 'AssistantAgent',
json_str: {
name: 'My Anthropic Agent',
llm: {
name: 'My Anthropic LLM',
uuid: 'test-uuid-llm-456',
},
toolbox_1: {
name: 'My Toolbox Name',
uuid: 'test-uuid-toolbox-789',
},
toolbox_2: null,
toolbox_3: null,
system_message: 'You are a helpful assistant.',
},
created_at: '2024-08-20T10:15:30.000000Z',
updated_at: '2024-08-20T10:15:30.000000Z',
});

mockRefetch.mockResolvedValue({ data: mockData });
await user.click(within(activePanel).getByRole('button', { name: 'Save' }));

await waitFor(() => {
expect(within(activePanel).getByText('ADD AGENT')).toBeInTheDocument();
expect(within(activePanel).getByText('My Anthropic Agent')).toBeInTheDocument();
expect(within(activePanel).queryByText('No Agents found. Please add one.')).not.toBeInTheDocument();
});

await user.click(within(activePanel).getByText('My Anthropic Agent'));

await waitFor(() => {
expect(nameInput).toHaveValue('My Anthropic Agent');
expect(within(activePanel).getByText('My Anthropic LLM')).toBeInTheDocument();
expect(within(activePanel).getByText('My Toolbox Name')).toBeInTheDocument();
});
}, 10000);

it('should show correct form when clicking the breadcrumbs', async () => {
const { user } = await setupComponent();
const activePanel = getActiveTabPanel();

// Enter name for Agent
const agentNameInput = within(activePanel).getByPlaceholderText('The name of the item');
await user.type(agentNameInput, 'My Anthropic Agent');

// Create LLM but do not save the form
await user.click(within(activePanel).getAllByRole('combobox')[1]);
await user.click(within(activePanel).getByText('Add new "LLM"'));
await waitFor(() => expect(within(activePanel).getByText('Select LLM')).toBeInTheDocument());
const llmNameInput = within(activePanel).getByPlaceholderText('The name of the item');
await user.type(llmNameInput, 'My Anthropic LLM');

// Check if the breadcrumbs are displayed correctly
expect(within(activePanel).getByTestId('breadcrumb-link-Agent')).toBeInTheDocument();
expect(within(activePanel).getByTestId('breadcrumb-link-LLM')).toBeInTheDocument();

// Create Secret but do not save the form
await user.click(within(activePanel).getAllByRole('combobox')[2]);
await user.click(within(activePanel).getByText('Add new "Secret"'));
await waitFor(() => expect(within(activePanel).getByText('Select Secret')).toBeInTheDocument());
expect(within(activePanel).getByText('AnthropicAPIKey')).toBeInTheDocument();

const secretNameInput = within(activePanel).getByPlaceholderText('The name of the item');
await user.type(secretNameInput, 'My AnthropicAPIKey Secret');

const apiKeyInput = within(activePanel).getByPlaceholderText('The API Key from Anthropic');
await user.type(apiKeyInput, 'My Api Key');

// Check if the breadcrumbs are displayed correctly
expect(within(activePanel).getByTestId('breadcrumb-link-Agent')).toBeInTheDocument();
expect(within(activePanel).getByTestId('breadcrumb-link-LLM')).toBeInTheDocument();
expect(within(activePanel).getByTestId('breadcrumb-link-Secret')).toBeInTheDocument();

// Click the last item in the breadcrumb and nothing should change in the UI
await user.click(within(activePanel).getByTestId('breadcrumb-link-Secret'));

await waitFor(() => {
expect(secretNameInput).toHaveValue('My AnthropicAPIKey Secret');
expect(apiKeyInput).toHaveValue('My Api Key');
});

// Click on the first item the user should be taken back to the Agent within(activePanel)
await user.click(within(activePanel).getByTestId('breadcrumb-link-Agent'));

await waitFor(() => {
expect(agentNameInput).toHaveValue('My Anthropic Agent');
});
});
});
Loading

0 comments on commit a81d16b

Please sign in to comment.