first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,753 @@
|
||||
import { mockDeep } from 'jest-mock-extended';
|
||||
import type {
|
||||
IExecuteFunctions,
|
||||
INode,
|
||||
INodeExecutionData,
|
||||
NodeExecutionWithMetadata,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import * as GenericFunctions from '../GenericFunctions';
|
||||
import { Telegram } from '../Telegram.node';
|
||||
|
||||
describe('Telegram node', () => {
|
||||
const executeFunctionsMock = mockDeep<IExecuteFunctions>();
|
||||
const apiRequestSpy = jest.spyOn(GenericFunctions, 'apiRequest');
|
||||
const node = new Telegram();
|
||||
|
||||
const legacyBinaryAccessHelper = (index: number, propertyName: string | any) => {
|
||||
const items = executeFunctionsMock.getInputData();
|
||||
return items[index].binary![propertyName as string];
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
executeFunctionsMock.getCredentials.mockResolvedValue({
|
||||
baseUrl: 'https://api.telegram.org',
|
||||
accessToken: 'test-token',
|
||||
});
|
||||
executeFunctionsMock.getNode.mockReturnValue({
|
||||
typeVersion: 1.2,
|
||||
} as INode);
|
||||
executeFunctionsMock.getInputData.mockReturnValue([{ json: {} }]);
|
||||
executeFunctionsMock.helpers.returnJsonArray.mockImplementation(
|
||||
(input) => input as INodeExecutionData[],
|
||||
);
|
||||
executeFunctionsMock.helpers.constructExecutionMetaData.mockImplementation(
|
||||
(input) => input as NodeExecutionWithMetadata[],
|
||||
);
|
||||
});
|
||||
|
||||
describe('file:get', () => {
|
||||
beforeEach(() => {
|
||||
executeFunctionsMock.getNodeParameter.mockImplementation((p) => {
|
||||
switch (p) {
|
||||
case 'resource':
|
||||
return 'file';
|
||||
case 'operation':
|
||||
return 'get';
|
||||
case 'download':
|
||||
return true;
|
||||
case 'fileId':
|
||||
return 'file-id';
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should determine the mime type of the file', async () => {
|
||||
apiRequestSpy.mockResolvedValueOnce({
|
||||
result: {
|
||||
file_id: 'file-id',
|
||||
file_path: 'documents/file_1.pdf',
|
||||
},
|
||||
});
|
||||
apiRequestSpy.mockResolvedValueOnce({
|
||||
body: Buffer.from('test-file'),
|
||||
});
|
||||
executeFunctionsMock.helpers.prepareBinaryData.mockResolvedValue({
|
||||
data: 'test-file',
|
||||
mimeType: 'application/pdf',
|
||||
});
|
||||
|
||||
const result = await node.execute.call(executeFunctionsMock);
|
||||
|
||||
expect(result).toEqual([
|
||||
[
|
||||
{
|
||||
json: {
|
||||
result: {
|
||||
file_id: 'file-id',
|
||||
file_path: 'documents/file_1.pdf',
|
||||
},
|
||||
},
|
||||
binary: {
|
||||
data: {
|
||||
data: 'test-file',
|
||||
mimeType: 'application/pdf',
|
||||
},
|
||||
},
|
||||
pairedItem: { item: 0 },
|
||||
},
|
||||
],
|
||||
]);
|
||||
expect(executeFunctionsMock.helpers.prepareBinaryData).toHaveBeenCalledWith(
|
||||
Buffer.from('test-file'),
|
||||
'file_1.pdf',
|
||||
'application/pdf',
|
||||
);
|
||||
});
|
||||
|
||||
it('should fallback to application/octet-stream if the mime type cannot be determined', async () => {
|
||||
apiRequestSpy.mockResolvedValueOnce({
|
||||
result: {
|
||||
file_id: 'file-id',
|
||||
file_path: 'documents/file_1.foo',
|
||||
},
|
||||
});
|
||||
apiRequestSpy.mockResolvedValueOnce({
|
||||
body: Buffer.from('test-file'),
|
||||
});
|
||||
executeFunctionsMock.helpers.prepareBinaryData.mockResolvedValue({
|
||||
data: 'test-file',
|
||||
mimeType: 'application/octet-stream',
|
||||
});
|
||||
|
||||
const result = await node.execute.call(executeFunctionsMock);
|
||||
|
||||
expect(result).toEqual([
|
||||
[
|
||||
{
|
||||
json: {
|
||||
result: {
|
||||
file_id: 'file-id',
|
||||
file_path: 'documents/file_1.foo',
|
||||
},
|
||||
},
|
||||
binary: {
|
||||
data: {
|
||||
data: 'test-file',
|
||||
mimeType: 'application/octet-stream',
|
||||
},
|
||||
},
|
||||
pairedItem: { item: 0 },
|
||||
},
|
||||
],
|
||||
]);
|
||||
expect(executeFunctionsMock.helpers.prepareBinaryData).toHaveBeenCalledWith(
|
||||
Buffer.from('test-file'),
|
||||
'file_1.foo',
|
||||
'application/octet-stream',
|
||||
);
|
||||
});
|
||||
|
||||
it('should use the provided mime type if it is specified', async () => {
|
||||
executeFunctionsMock.getNodeParameter.mockImplementation((p) => {
|
||||
switch (p) {
|
||||
case 'resource':
|
||||
return 'file';
|
||||
case 'operation':
|
||||
return 'get';
|
||||
case 'download':
|
||||
return true;
|
||||
case 'fileId':
|
||||
return 'file-id';
|
||||
case 'additionalFields':
|
||||
return { mimeType: 'image/jpeg' };
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
apiRequestSpy.mockResolvedValueOnce({
|
||||
result: {
|
||||
file_id: 'file-id',
|
||||
file_path: 'documents/file_1.pdf',
|
||||
},
|
||||
});
|
||||
apiRequestSpy.mockResolvedValueOnce({
|
||||
body: Buffer.from('test-file'),
|
||||
});
|
||||
executeFunctionsMock.helpers.prepareBinaryData.mockResolvedValue({
|
||||
data: 'test-file',
|
||||
mimeType: 'image/jpeg',
|
||||
});
|
||||
|
||||
const result = await node.execute.call(executeFunctionsMock);
|
||||
|
||||
expect(result).toEqual([
|
||||
[
|
||||
{
|
||||
json: {
|
||||
result: {
|
||||
file_id: 'file-id',
|
||||
file_path: 'documents/file_1.pdf',
|
||||
},
|
||||
},
|
||||
binary: {
|
||||
data: {
|
||||
data: 'test-file',
|
||||
mimeType: 'image/jpeg',
|
||||
},
|
||||
},
|
||||
pairedItem: { item: 0 },
|
||||
},
|
||||
],
|
||||
]);
|
||||
expect(executeFunctionsMock.helpers.prepareBinaryData).toHaveBeenCalledWith(
|
||||
Buffer.from('test-file'),
|
||||
'file_1.pdf',
|
||||
'image/jpeg',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('assertBinaryData usage', () => {
|
||||
beforeEach(() => {
|
||||
executeFunctionsMock.getNodeParameter.mockImplementation((paramName, _) => {
|
||||
switch (paramName) {
|
||||
case 'resource':
|
||||
return 'message';
|
||||
case 'operation':
|
||||
return 'sendPhoto';
|
||||
case 'binaryData':
|
||||
return true;
|
||||
case 'chatId':
|
||||
return 'chat-id';
|
||||
case 'binaryPropertyName':
|
||||
return 'data';
|
||||
case 'additionalFields.fileName':
|
||||
return '';
|
||||
case 'additionalFields':
|
||||
return {};
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should call assertBinaryData with correct parameters', async () => {
|
||||
executeFunctionsMock.getInputData.mockReturnValue([
|
||||
{
|
||||
json: {},
|
||||
binary: {
|
||||
data: {
|
||||
data: 'binary-data',
|
||||
mimeType: 'image/jpeg',
|
||||
fileName: 'photo.jpg',
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
executeFunctionsMock.helpers.assertBinaryData.mockReturnValue({
|
||||
data: 'binary-data',
|
||||
mimeType: 'image/jpeg',
|
||||
fileName: 'photo.jpg',
|
||||
});
|
||||
|
||||
apiRequestSpy.mockResolvedValue([{ result: { message_id: 123 } }]);
|
||||
|
||||
await node.execute.call(executeFunctionsMock);
|
||||
|
||||
expect(executeFunctionsMock.helpers.assertBinaryData).toHaveBeenCalledWith(0, 'data');
|
||||
});
|
||||
|
||||
it('should call assertBinaryData for each item with correct index', async () => {
|
||||
executeFunctionsMock.getNodeParameter.mockImplementation((paramName, index) => {
|
||||
switch (paramName) {
|
||||
case 'resource':
|
||||
return 'message';
|
||||
case 'operation':
|
||||
return 'sendPhoto';
|
||||
case 'binaryData':
|
||||
return true;
|
||||
case 'chatId':
|
||||
return `chat-id-${index}`;
|
||||
case 'binaryPropertyName':
|
||||
return `data${index}`;
|
||||
case 'additionalFields.fileName':
|
||||
return '';
|
||||
case 'additionalFields':
|
||||
return {};
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
|
||||
executeFunctionsMock.getInputData.mockReturnValue([
|
||||
{
|
||||
json: {},
|
||||
binary: {
|
||||
data0: {
|
||||
data: 'binary-data-0',
|
||||
mimeType: 'image/jpeg',
|
||||
fileName: 'photo0.jpg',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
json: {},
|
||||
binary: {
|
||||
data1: {
|
||||
data: 'binary-data-1',
|
||||
mimeType: 'image/png',
|
||||
fileName: 'photo1.png',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
json: {},
|
||||
binary: {
|
||||
data2: {
|
||||
data: 'binary-data-2',
|
||||
mimeType: 'image/gif',
|
||||
fileName: 'photo2.gif',
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
executeFunctionsMock.helpers.assertBinaryData.mockImplementation(legacyBinaryAccessHelper);
|
||||
|
||||
apiRequestSpy.mockResolvedValue([{ result: { message_id: 123 } }]);
|
||||
|
||||
await node.execute.call(executeFunctionsMock);
|
||||
|
||||
expect(executeFunctionsMock.helpers.assertBinaryData).toHaveBeenCalledTimes(3);
|
||||
expect(executeFunctionsMock.helpers.assertBinaryData).toHaveBeenNthCalledWith(1, 0, 'data0');
|
||||
expect(executeFunctionsMock.helpers.assertBinaryData).toHaveBeenNthCalledWith(2, 1, 'data1');
|
||||
expect(executeFunctionsMock.helpers.assertBinaryData).toHaveBeenNthCalledWith(3, 2, 'data2');
|
||||
});
|
||||
|
||||
it('should throw error when binary data is missing', async () => {
|
||||
executeFunctionsMock.getInputData.mockReturnValue([
|
||||
{
|
||||
json: {},
|
||||
// No binary data
|
||||
},
|
||||
]);
|
||||
|
||||
executeFunctionsMock.helpers.assertBinaryData.mockImplementation(() => {
|
||||
throw new Error('No binary data exists on item!');
|
||||
});
|
||||
|
||||
await expect(node.execute.call(executeFunctionsMock)).rejects.toThrow(
|
||||
'No binary data exists on item!',
|
||||
);
|
||||
|
||||
expect(executeFunctionsMock.helpers.assertBinaryData).toHaveBeenCalledWith(0, 'data');
|
||||
});
|
||||
|
||||
it('should throw error when specified binary property does not exist', async () => {
|
||||
executeFunctionsMock.getNodeParameter.mockImplementation((paramName) => {
|
||||
switch (paramName) {
|
||||
case 'resource':
|
||||
return 'message';
|
||||
case 'operation':
|
||||
return 'sendPhoto';
|
||||
case 'binaryData':
|
||||
return true;
|
||||
case 'chatId':
|
||||
return 'chat-id';
|
||||
case 'binaryPropertyName':
|
||||
return 'nonExistentProperty';
|
||||
case 'additionalFields.fileName':
|
||||
return '';
|
||||
case 'additionalFields':
|
||||
return {};
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
|
||||
executeFunctionsMock.getInputData.mockReturnValue([
|
||||
{
|
||||
json: {},
|
||||
binary: {
|
||||
data: {
|
||||
data: 'binary-data',
|
||||
mimeType: 'image/jpeg',
|
||||
fileName: 'photo.jpg',
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
executeFunctionsMock.helpers.assertBinaryData.mockImplementation(() => {
|
||||
throw new Error("There is no binary data property 'nonExistentProperty' on item!");
|
||||
});
|
||||
|
||||
await expect(node.execute.call(executeFunctionsMock)).rejects.toThrow(
|
||||
"There is no binary data property 'nonExistentProperty' on item!",
|
||||
);
|
||||
|
||||
expect(executeFunctionsMock.helpers.assertBinaryData).toHaveBeenCalledWith(
|
||||
0,
|
||||
'nonExistentProperty',
|
||||
);
|
||||
});
|
||||
|
||||
it('should use fileName from assertBinaryData result when additionalFields.fileName is not provided', async () => {
|
||||
const mockBinaryData = {
|
||||
data: 'binary-data',
|
||||
mimeType: 'image/jpeg',
|
||||
fileName: 'from-binary-data.jpg',
|
||||
};
|
||||
|
||||
executeFunctionsMock.getInputData.mockReturnValue([
|
||||
{
|
||||
json: {},
|
||||
binary: {
|
||||
data: mockBinaryData,
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
executeFunctionsMock.helpers.assertBinaryData.mockReturnValue(mockBinaryData);
|
||||
|
||||
apiRequestSpy.mockResolvedValue([{ result: { message_id: 123 } }]);
|
||||
|
||||
await node.execute.call(executeFunctionsMock);
|
||||
|
||||
expect(executeFunctionsMock.helpers.assertBinaryData).toHaveBeenCalledWith(0, 'data');
|
||||
expect(apiRequestSpy).toHaveBeenCalledWith(
|
||||
'POST',
|
||||
'sendPhoto',
|
||||
{},
|
||||
{},
|
||||
expect.objectContaining({
|
||||
formData: expect.objectContaining({
|
||||
photo: expect.objectContaining({
|
||||
options: expect.objectContaining({
|
||||
filename: 'from-binary-data.jpg',
|
||||
contentType: 'image/jpeg',
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('message:sendPhoto with binary data', () => {
|
||||
beforeEach(() => {
|
||||
executeFunctionsMock.helpers.assertBinaryData.mockImplementation(legacyBinaryAccessHelper);
|
||||
|
||||
executeFunctionsMock.getNodeParameter.mockImplementation((paramName, index) => {
|
||||
switch (paramName) {
|
||||
case 'resource':
|
||||
return 'message';
|
||||
case 'operation':
|
||||
return 'sendPhoto';
|
||||
case 'binaryData':
|
||||
return true;
|
||||
case 'chatId':
|
||||
return index === 0 ? 'chat-id-0' : index === 1 ? 'chat-id-1' : 'chat-id-2';
|
||||
case 'binaryPropertyName':
|
||||
return index === 0 ? 'data0' : index === 1 ? 'data1' : 'data2';
|
||||
case 'additionalFields.fileName':
|
||||
return index === 0 ? 'photo0.jpg' : index === 1 ? 'photo1.png' : 'photo2.gif';
|
||||
case 'additionalFields':
|
||||
return {};
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should use correct index for binaryPropertyName parameter', async () => {
|
||||
executeFunctionsMock.getInputData.mockReturnValue([
|
||||
{
|
||||
json: {},
|
||||
binary: {
|
||||
data0: {
|
||||
data: 'binary-data-0',
|
||||
mimeType: 'image/jpeg',
|
||||
fileName: 'original0.jpg',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
json: {},
|
||||
binary: {
|
||||
data1: {
|
||||
data: 'binary-data-1',
|
||||
mimeType: 'image/png',
|
||||
fileName: 'original1.png',
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
apiRequestSpy.mockResolvedValue([{ result: { message_id: 123 } }]);
|
||||
|
||||
await node.execute.call(executeFunctionsMock);
|
||||
|
||||
expect(executeFunctionsMock.getNodeParameter).toHaveBeenCalledWith('binaryPropertyName', 0);
|
||||
expect(executeFunctionsMock.getNodeParameter).toHaveBeenCalledWith('binaryPropertyName', 1);
|
||||
expect(executeFunctionsMock.getNodeParameter).not.toHaveBeenCalledWith(
|
||||
'binaryPropertyName',
|
||||
0,
|
||||
expect.anything(),
|
||||
);
|
||||
expect(executeFunctionsMock.getNodeParameter).not.toHaveBeenCalledWith(
|
||||
'binaryPropertyName',
|
||||
1,
|
||||
expect.anything(),
|
||||
);
|
||||
});
|
||||
|
||||
it('should use correct index for additionalFields.fileName parameter', async () => {
|
||||
executeFunctionsMock.getInputData.mockReturnValue([
|
||||
{
|
||||
json: {},
|
||||
binary: {
|
||||
data0: {
|
||||
data: 'binary-data-0',
|
||||
mimeType: 'image/jpeg',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
json: {},
|
||||
binary: {
|
||||
data1: {
|
||||
data: 'binary-data-1',
|
||||
mimeType: 'image/png',
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
apiRequestSpy.mockResolvedValue([{ result: { message_id: 123 } }]);
|
||||
|
||||
await node.execute.call(executeFunctionsMock);
|
||||
|
||||
expect(executeFunctionsMock.getNodeParameter).toHaveBeenCalledWith(
|
||||
'additionalFields.fileName',
|
||||
0,
|
||||
'',
|
||||
);
|
||||
expect(executeFunctionsMock.getNodeParameter).toHaveBeenCalledWith(
|
||||
'additionalFields.fileName',
|
||||
1,
|
||||
'',
|
||||
);
|
||||
});
|
||||
|
||||
it('should use correct binary data for each item based on binaryPropertyName index', async () => {
|
||||
executeFunctionsMock.getInputData.mockReturnValue([
|
||||
{
|
||||
json: {},
|
||||
binary: {
|
||||
data0: {
|
||||
data: 'binary-data-0',
|
||||
mimeType: 'image/jpeg',
|
||||
fileName: 'original0.jpg',
|
||||
},
|
||||
wrongData: {
|
||||
data: 'wrong-binary-data',
|
||||
mimeType: 'image/gif',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
json: {},
|
||||
binary: {
|
||||
data1: {
|
||||
data: 'binary-data-1',
|
||||
mimeType: 'image/png',
|
||||
fileName: 'original1.png',
|
||||
},
|
||||
wrongData: {
|
||||
data: 'wrong-binary-data',
|
||||
mimeType: 'image/gif',
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
apiRequestSpy.mockResolvedValue([{ result: { message_id: 123 } }]);
|
||||
|
||||
await node.execute.call(executeFunctionsMock);
|
||||
|
||||
expect(apiRequestSpy).toHaveBeenCalledTimes(2);
|
||||
|
||||
expect(apiRequestSpy).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
'POST',
|
||||
'sendPhoto',
|
||||
{},
|
||||
{},
|
||||
expect.objectContaining({
|
||||
formData: expect.objectContaining({
|
||||
chat_id: 'chat-id-0',
|
||||
photo: expect.objectContaining({
|
||||
value: expect.any(Buffer),
|
||||
options: expect.objectContaining({
|
||||
filename: 'photo0.jpg',
|
||||
contentType: 'image/jpeg',
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
expect(apiRequestSpy).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
'POST',
|
||||
'sendPhoto',
|
||||
{},
|
||||
{},
|
||||
expect.objectContaining({
|
||||
formData: expect.objectContaining({
|
||||
chat_id: 'chat-id-1',
|
||||
photo: expect.objectContaining({
|
||||
value: expect.any(Buffer),
|
||||
options: expect.objectContaining({
|
||||
filename: 'photo1.png',
|
||||
contentType: 'image/png',
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should fallback to binary fileName when additionalFields.fileName is empty', async () => {
|
||||
executeFunctionsMock.getNodeParameter.mockImplementation((paramName, index) => {
|
||||
switch (paramName) {
|
||||
case 'resource':
|
||||
return 'message';
|
||||
case 'operation':
|
||||
return 'sendPhoto';
|
||||
case 'binaryData':
|
||||
return true;
|
||||
case 'chatId':
|
||||
return index === 0 ? 'chat-id-0' : 'chat-id-1';
|
||||
case 'binaryPropertyName':
|
||||
return index === 0 ? 'data0' : 'data1';
|
||||
case 'additionalFields.fileName':
|
||||
return index === 0 ? '' : 'custom-name.jpg';
|
||||
case 'additionalFields':
|
||||
return {};
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
|
||||
executeFunctionsMock.getInputData.mockReturnValue([
|
||||
{
|
||||
json: {},
|
||||
binary: {
|
||||
data0: {
|
||||
data: 'binary-data-0',
|
||||
mimeType: 'image/jpeg',
|
||||
fileName: 'fallback-name.jpg',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
json: {},
|
||||
binary: {
|
||||
data1: {
|
||||
data: 'binary-data-1',
|
||||
mimeType: 'image/png',
|
||||
fileName: 'original-name.png',
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
apiRequestSpy.mockResolvedValue([{ result: { message_id: 123 } }]);
|
||||
|
||||
await node.execute.call(executeFunctionsMock);
|
||||
|
||||
const expectFileName = (index: number, filename: string) => {
|
||||
expect(apiRequestSpy).toHaveBeenNthCalledWith(
|
||||
index,
|
||||
'POST',
|
||||
'sendPhoto',
|
||||
{},
|
||||
{},
|
||||
{
|
||||
formData: expect.objectContaining({
|
||||
photo: expect.objectContaining({
|
||||
options: expect.objectContaining({
|
||||
filename,
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
expectFileName(1, 'fallback-name.jpg');
|
||||
expectFileName(2, 'custom-name.jpg');
|
||||
});
|
||||
|
||||
it('should process different chat IDs for multiple items correctly', async () => {
|
||||
executeFunctionsMock.getInputData.mockReturnValue([
|
||||
{
|
||||
json: {},
|
||||
binary: {
|
||||
data0: {
|
||||
data: 'binary-data-0',
|
||||
mimeType: 'image/jpeg',
|
||||
fileName: 'photo0.jpg',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
json: {},
|
||||
binary: {
|
||||
data1: {
|
||||
data: 'binary-data-1',
|
||||
mimeType: 'image/png',
|
||||
fileName: 'photo1.png',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
json: {},
|
||||
binary: {
|
||||
data2: {
|
||||
data: 'binary-data-2',
|
||||
mimeType: 'image/gif',
|
||||
fileName: 'photo2.gif',
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
apiRequestSpy.mockResolvedValue([{ result: { message_id: 123 } }]);
|
||||
|
||||
await node.execute.call(executeFunctionsMock);
|
||||
|
||||
expect(executeFunctionsMock.getNodeParameter).toHaveBeenCalledWith('chatId', 0);
|
||||
expect(executeFunctionsMock.getNodeParameter).toHaveBeenCalledWith('chatId', 1);
|
||||
expect(executeFunctionsMock.getNodeParameter).toHaveBeenCalledWith('chatId', 2);
|
||||
|
||||
expect(apiRequestSpy).toHaveBeenCalledTimes(3);
|
||||
|
||||
const expectChatId = (n: number, chatId: string) => {
|
||||
expect(apiRequestSpy).toHaveBeenNthCalledWith(
|
||||
n,
|
||||
'POST',
|
||||
'sendPhoto',
|
||||
{},
|
||||
{},
|
||||
{
|
||||
formData: expect.objectContaining({
|
||||
chat_id: chatId,
|
||||
}),
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
expectChatId(1, 'chat-id-0');
|
||||
expectChatId(2, 'chat-id-1');
|
||||
expectChatId(3, 'chat-id-2');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user