mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-03-22 10:23:08 +00:00
fix: resolve 5 bugs in n8n_manage_datatable (#651)
This commit is contained in:
committed by
GitHub
parent
be3d07dbdc
commit
c5665632af
@@ -429,12 +429,12 @@ describe('Data Table Handlers (n8n_manage_datatable)', () => {
|
||||
|
||||
expect(mockApiClient.getDataTableRows).toHaveBeenCalledWith('dt-1', {
|
||||
limit: 50,
|
||||
sortBy: 'name:asc',
|
||||
sortBy: encodeURIComponent('name:asc'),
|
||||
search: 'john',
|
||||
});
|
||||
});
|
||||
|
||||
it('should serialize object filter to JSON string', async () => {
|
||||
it('should serialize object filter to URL-encoded JSON string', async () => {
|
||||
mockApiClient.getDataTableRows.mockResolvedValue({ data: [], nextCursor: null });
|
||||
|
||||
const objectFilter = {
|
||||
@@ -448,20 +448,21 @@ describe('Data Table Handlers (n8n_manage_datatable)', () => {
|
||||
});
|
||||
|
||||
expect(mockApiClient.getDataTableRows).toHaveBeenCalledWith('dt-1', {
|
||||
filter: JSON.stringify(objectFilter),
|
||||
filter: encodeURIComponent(JSON.stringify(objectFilter)),
|
||||
});
|
||||
});
|
||||
|
||||
it('should pass through string filter as-is', async () => {
|
||||
it('should URL-encode string filter', async () => {
|
||||
mockApiClient.getDataTableRows.mockResolvedValue({ data: [], nextCursor: null });
|
||||
|
||||
const filterStr = '{"type":"and","filters":[]}';
|
||||
await handlers.handleGetRows({
|
||||
tableId: 'dt-1',
|
||||
filter: '{"type":"and","filters":[]}',
|
||||
filter: filterStr,
|
||||
});
|
||||
|
||||
expect(mockApiClient.getDataTableRows).toHaveBeenCalledWith('dt-1', {
|
||||
filter: '{"type":"and","filters":[]}',
|
||||
filter: encodeURIComponent(filterStr),
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -680,11 +681,11 @@ describe('Data Table Handlers (n8n_manage_datatable)', () => {
|
||||
message: 'Rows deleted successfully',
|
||||
});
|
||||
expect(mockApiClient.deleteDataTableRows).toHaveBeenCalledWith('dt-1', {
|
||||
filter: JSON.stringify({ type: 'and', ...filter }),
|
||||
filter: encodeURIComponent(JSON.stringify({ type: 'and', ...filter })),
|
||||
});
|
||||
});
|
||||
|
||||
it('should serialize filter object to JSON string for API call', async () => {
|
||||
it('should URL-encode serialized filter for API call', async () => {
|
||||
mockApiClient.deleteDataTableRows.mockResolvedValue({ deletedCount: 1 });
|
||||
|
||||
const filter = {
|
||||
@@ -698,7 +699,7 @@ describe('Data Table Handlers (n8n_manage_datatable)', () => {
|
||||
await handlers.handleDeleteRows({ tableId: 'dt-1', filter });
|
||||
|
||||
expect(mockApiClient.deleteDataTableRows).toHaveBeenCalledWith('dt-1', {
|
||||
filter: JSON.stringify(filter),
|
||||
filter: encodeURIComponent(JSON.stringify(filter)),
|
||||
});
|
||||
});
|
||||
|
||||
@@ -719,7 +720,7 @@ describe('Data Table Handlers (n8n_manage_datatable)', () => {
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.message).toBe('Dry run: rows matched for deletion (no changes applied)');
|
||||
expect(mockApiClient.deleteDataTableRows).toHaveBeenCalledWith('dt-1', {
|
||||
filter: JSON.stringify({ type: 'and', ...filter }),
|
||||
filter: encodeURIComponent(JSON.stringify({ type: 'and', ...filter })),
|
||||
dryRun: true,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -100,6 +100,16 @@ describe('handlers-n8n-manager', () => {
|
||||
listExecutions: vi.fn(),
|
||||
deleteExecution: vi.fn(),
|
||||
healthCheck: vi.fn(),
|
||||
createDataTable: vi.fn(),
|
||||
listDataTables: vi.fn(),
|
||||
getDataTable: vi.fn(),
|
||||
updateDataTable: vi.fn(),
|
||||
deleteDataTable: vi.fn(),
|
||||
getDataTableRows: vi.fn(),
|
||||
insertDataTableRows: vi.fn(),
|
||||
updateDataTableRows: vi.fn(),
|
||||
upsertDataTableRow: vi.fn(),
|
||||
deleteDataTableRows: vi.fn(),
|
||||
};
|
||||
|
||||
// Setup mock repository
|
||||
|
||||
@@ -297,7 +297,7 @@ describe('N8nApiClient', () => {
|
||||
expect.fail('Should have thrown an error');
|
||||
} catch (err) {
|
||||
expect(err).toBeInstanceOf(N8nNotFoundError);
|
||||
expect((err as N8nNotFoundError).message).toContain('not found');
|
||||
expect((err as N8nNotFoundError).message.toLowerCase()).toContain('not found');
|
||||
expect((err as N8nNotFoundError).statusCode).toBe(404);
|
||||
}
|
||||
});
|
||||
@@ -380,7 +380,7 @@ describe('N8nApiClient', () => {
|
||||
expect.fail('Should have thrown an error');
|
||||
} catch (err) {
|
||||
expect(err).toBeInstanceOf(N8nNotFoundError);
|
||||
expect((err as N8nNotFoundError).message).toContain('not found');
|
||||
expect((err as N8nNotFoundError).message.toLowerCase()).toContain('not found');
|
||||
expect((err as N8nNotFoundError).statusCode).toBe(404);
|
||||
}
|
||||
});
|
||||
@@ -432,7 +432,7 @@ describe('N8nApiClient', () => {
|
||||
expect.fail('Should have thrown an error');
|
||||
} catch (err) {
|
||||
expect(err).toBeInstanceOf(N8nNotFoundError);
|
||||
expect((err as N8nNotFoundError).message).toContain('not found');
|
||||
expect((err as N8nNotFoundError).message.toLowerCase()).toContain('not found');
|
||||
expect((err as N8nNotFoundError).statusCode).toBe(404);
|
||||
}
|
||||
});
|
||||
@@ -501,7 +501,7 @@ describe('N8nApiClient', () => {
|
||||
expect.fail('Should have thrown an error');
|
||||
} catch (err) {
|
||||
expect(err).toBeInstanceOf(N8nNotFoundError);
|
||||
expect((err as N8nNotFoundError).message).toContain('not found');
|
||||
expect((err as N8nNotFoundError).message.toLowerCase()).toContain('not found');
|
||||
expect((err as N8nNotFoundError).statusCode).toBe(404);
|
||||
}
|
||||
});
|
||||
@@ -1278,7 +1278,7 @@ describe('N8nApiClient', () => {
|
||||
expect.fail('Should have thrown an error');
|
||||
} catch (err) {
|
||||
expect(err).toBeInstanceOf(N8nNotFoundError);
|
||||
expect((err as N8nNotFoundError).message).toContain('not found');
|
||||
expect((err as N8nNotFoundError).message.toLowerCase()).toContain('not found');
|
||||
expect((err as N8nNotFoundError).statusCode).toBe(404);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user