n8n/packages/frontend/@n8n/stores/src/useAgentRequestStore.test.ts
Elias Meire ab2c8b56ab
feat(core): Generate HITL tool nodes for sendAndWait operations (#22315)
Co-authored-by: yehorkardash <yehor.kardash@n8n.io>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-01-23 10:04:11 +00:00

190 lines
5.6 KiB
TypeScript

import { setActivePinia, createPinia } from 'pinia';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { nextTick } from 'vue';
import {
type IAgentRequestStoreState,
type IAgentRequest,
useAgentRequestStore,
} from './useAgentRequestStore';
// Mock localStorage
let mockLocalStorageValue: IAgentRequestStoreState = {};
const NODE_NAME = 'Test Node';
const NODE_ID_1 = '123e4567-e89b-12d3-a456-426614174000';
const NODE_ID_2 = '987fcdeb-51a2-43d7-b654-987654321000';
const NODE_ID_3 = '456abcde-f789-12d3-a456-426614174000';
vi.mock('@vueuse/core', () => ({
useLocalStorage: vi.fn((_key, defaultValue) => {
if (Object.keys(mockLocalStorageValue).length === 0) {
Object.assign(mockLocalStorageValue, structuredClone(defaultValue));
}
return {
value: mockLocalStorageValue,
};
}),
}));
describe('agentRequest.store', () => {
beforeEach(() => {
mockLocalStorageValue = {};
setActivePinia(createPinia());
});
describe('Initialization', () => {
it('initializes with empty state when localStorage is empty', () => {
const store = useAgentRequestStore();
expect(store.agentRequests.value).toEqual({});
});
it('initializes with data from localStorage', () => {
const mockData: IAgentRequestStoreState = {
'workflow-1': {
[NODE_ID_1]: { query: { [NODE_NAME]: { param1: 'value1' } } },
},
};
mockLocalStorageValue = mockData;
const store = useAgentRequestStore();
expect(store.agentRequests.value).toEqual(mockData);
});
});
describe('Getters', () => {
it('gets parameter overrides for a node', () => {
const store = useAgentRequestStore();
store.setAgentRequestForNode('workflow-1', NODE_ID_1, {
query: { [NODE_NAME]: { param1: 'value1', param2: 'value2' } },
});
const overrides = store.getAgentRequests('workflow-1', NODE_ID_1);
expect(overrides).toEqual({ [NODE_NAME]: { param1: 'value1', param2: 'value2' } });
});
it('returns empty object for non-existent workflow/node', () => {
const store = useAgentRequestStore();
const overrides = store.getAgentRequests('non-existent', NODE_ID_1);
expect(overrides).toEqual({});
});
it('gets a specific parameter override', () => {
const store = useAgentRequestStore();
store.setAgentRequestForNode('workflow-1', NODE_ID_1, {
query: { [NODE_NAME]: { param1: 'value1', param2: 'value2' } },
});
const override = store.getQueryValue('workflow-1', NODE_ID_1, NODE_NAME, 'param1');
expect(override).toBe('value1');
});
it('returns undefined for non-existent parameter', () => {
const store = useAgentRequestStore();
store.setAgentRequestForNode('workflow-1', NODE_ID_1, {
query: { [NODE_NAME]: { param1: 'value1' } },
});
const override = store.getQueryValue('workflow-1', NODE_ID_1, NODE_NAME, 'non-existent');
expect(override).toBeUndefined();
});
});
describe('Actions', () => {
it('sets parameter overrides for a node', () => {
const store = useAgentRequestStore();
store.setAgentRequestForNode('workflow-1', NODE_ID_1, {
query: { [NODE_NAME]: { param1: 'value1', param2: 'value2' } },
});
expect(
(store.agentRequests.value['workflow-1'] as unknown as { [key: string]: IAgentRequest })[
NODE_ID_1
].query,
).toEqual({
[NODE_NAME]: { param1: 'value1', param2: 'value2' },
});
});
it('clears parameter overrides for a node', () => {
const store = useAgentRequestStore();
store.setAgentRequestForNode('workflow-1', NODE_ID_1, {
query: { [NODE_NAME]: { param1: 'value1', param2: 'value2' } },
});
store.setAgentRequestForNode('workflow-1', NODE_ID_2, {
query: { [NODE_NAME]: { param3: 'value3' } },
});
store.clearAgentRequests('workflow-1', NODE_ID_1);
expect(
(store.agentRequests.value['workflow-1'] as unknown as { [key: string]: IAgentRequest })[
NODE_ID_1
].query,
).toEqual({});
expect(
(store.agentRequests.value['workflow-1'] as unknown as { [key: string]: IAgentRequest })[
NODE_ID_2
].query,
).toEqual({
[NODE_NAME]: { param3: 'value3' },
});
});
it('clears all parameter overrides for a workflow', () => {
const store = useAgentRequestStore();
store.setAgentRequestForNode('workflow-1', NODE_ID_1, {
query: { [NODE_NAME]: { param1: 'value1' } },
});
store.setAgentRequestForNode('workflow-1', NODE_ID_2, {
query: { [NODE_NAME]: { param2: 'value2' } },
});
store.setAgentRequestForNode('workflow-2', NODE_ID_3, {
query: { [NODE_NAME]: { param3: 'value3' } },
});
store.clearAllAgentRequests('workflow-1');
expect(store.agentRequests.value['workflow-1']).toEqual({});
expect(store.agentRequests.value['workflow-2']).toEqual({
[NODE_ID_3]: { query: { [NODE_NAME]: { param3: 'value3' } } },
});
});
it('clears all parameter overrides when no workflowId is provided', () => {
const store = useAgentRequestStore();
store.setAgentRequestForNode('workflow-1', NODE_ID_1, {
query: { [NODE_NAME]: { param1: 'value1' } },
});
store.setAgentRequestForNode('workflow-2', NODE_ID_2, {
query: { [NODE_NAME]: { param2: 'value2' } },
});
store.clearAllAgentRequests();
expect(store.agentRequests.value).toEqual({});
});
});
describe('Persistence', () => {
it('saves to localStorage when state changes', async () => {
const store = useAgentRequestStore();
store.setAgentRequestForNode('workflow-1', NODE_ID_1, {
query: { [NODE_NAME]: { param1: 'value1' } },
});
await nextTick();
expect(mockLocalStorageValue).toEqual({
'workflow-1': {
[NODE_ID_1]: { query: { [NODE_NAME]: { param1: 'value1' } } },
},
});
});
});
});