mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 17:46:45 +00:00
fix(Telegram Node): Use parameter index instead of 0 for binaryData (#19236)
This commit is contained in:
@@ -2146,10 +2146,10 @@ export class Telegram implements INodeType {
|
|||||||
let responseData;
|
let responseData;
|
||||||
|
|
||||||
if (binaryData) {
|
if (binaryData) {
|
||||||
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0);
|
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i);
|
||||||
const itemBinaryData = items[i].binary![binaryPropertyName];
|
const itemBinaryData = items[i].binary![binaryPropertyName];
|
||||||
const propertyName = getPropertyName(operation);
|
const propertyName = getPropertyName(operation);
|
||||||
const fileName = this.getNodeParameter('additionalFields.fileName', 0, '') as string;
|
const fileName = this.getNodeParameter('additionalFields.fileName', i, '') as string;
|
||||||
|
|
||||||
const filename = fileName || itemBinaryData.fileName?.toString();
|
const filename = fileName || itemBinaryData.fileName?.toString();
|
||||||
|
|
||||||
@@ -2214,7 +2214,7 @@ export class Telegram implements INodeType {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const fileName = filePath.split('/').pop() as string;
|
const fileName = filePath.split('/').pop() as string;
|
||||||
const additionalFields = this.getNodeParameter('additionalFields', 0);
|
const additionalFields = this.getNodeParameter('additionalFields', i);
|
||||||
const providedMimeType = additionalFields?.mimeType as string | undefined;
|
const providedMimeType = additionalFields?.mimeType as string | undefined;
|
||||||
const mimeType = providedMimeType ?? (lookup(fileName) || 'application/octet-stream');
|
const mimeType = providedMimeType ?? (lookup(fileName) || 'application/octet-stream');
|
||||||
|
|
||||||
@@ -2239,7 +2239,6 @@ export class Telegram implements INodeType {
|
|||||||
returnData.push(...executionData);
|
returnData.push(...executionData);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const executionData = this.helpers.constructExecutionMetaData(
|
const executionData = this.helpers.constructExecutionMetaData(
|
||||||
this.helpers.returnJsonArray(responseData as IDataObject[]),
|
this.helpers.returnJsonArray(responseData as IDataObject[]),
|
||||||
{ itemData: { item: i } },
|
{ itemData: { item: i } },
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import { mockDeep } from 'jest-mock-extended';
|
import { mockDeep } from 'jest-mock-extended';
|
||||||
import type { IExecuteFunctions, INode } from 'n8n-workflow';
|
import type {
|
||||||
|
IExecuteFunctions,
|
||||||
|
INode,
|
||||||
|
INodeExecutionData,
|
||||||
|
NodeExecutionWithMetadata,
|
||||||
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import * as GenericFunctions from '../GenericFunctions';
|
import * as GenericFunctions from '../GenericFunctions';
|
||||||
import { Telegram } from '../Telegram.node';
|
import { Telegram } from '../Telegram.node';
|
||||||
@@ -19,6 +24,12 @@ describe('Telegram node', () => {
|
|||||||
typeVersion: 1.2,
|
typeVersion: 1.2,
|
||||||
} as INode);
|
} as INode);
|
||||||
executeFunctionsMock.getInputData.mockReturnValue([{ json: {} }]);
|
executeFunctionsMock.getInputData.mockReturnValue([{ json: {} }]);
|
||||||
|
executeFunctionsMock.helpers.returnJsonArray.mockImplementation(
|
||||||
|
(input) => input as INodeExecutionData[],
|
||||||
|
);
|
||||||
|
executeFunctionsMock.helpers.constructExecutionMetaData.mockImplementation(
|
||||||
|
(input) => input as NodeExecutionWithMetadata[],
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('file:get', () => {
|
describe('file:get', () => {
|
||||||
@@ -184,4 +195,324 @@ describe('Telegram node', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('message:sendPhoto with binary data', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
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