mirror of
https://github.com/n8n-io/n8n.git
synced 2026-06-04 02:37:46 +02:00
fix(Zulip Node): Normalize multiOptions recipients when expression returns a string (#31492)
Co-authored-by: Dawid Myslak <dawid.myslak@gmail.com>
This commit is contained in:
parent
60c8517004
commit
01cc906ebd
|
|
@ -56,6 +56,28 @@ export async function zulipApiRequest(
|
|||
}
|
||||
}
|
||||
|
||||
// A multiOptions parameter normally resolves to an array. When its value comes
|
||||
// from an expression that is wrapped in surrounding text/whitespace, n8n
|
||||
// switches to string interpolation and the array is coerced to a comma-joined
|
||||
// string. Accept both shapes so the node degrades gracefully instead of
|
||||
// throwing a low-level "join is not a function" TypeError.
|
||||
export function toMultiOptionsCsv(value: unknown): string {
|
||||
if (Array.isArray(value)) {
|
||||
return value
|
||||
.map((entry) => String(entry).trim())
|
||||
.filter((entry) => entry.length > 0)
|
||||
.join(',');
|
||||
}
|
||||
if (typeof value === 'string') {
|
||||
return value
|
||||
.split(',')
|
||||
.map((entry) => entry.trim())
|
||||
.filter((entry) => entry.length > 0)
|
||||
.join(',');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
export function validateJSON(json: string | undefined): any {
|
||||
let result;
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import type {
|
|||
} from 'n8n-workflow';
|
||||
import { NodeConnectionTypes, NodeOperationError } from 'n8n-workflow';
|
||||
|
||||
import { validateJSON, zulipApiRequest } from './GenericFunctions';
|
||||
import { toMultiOptionsCsv, validateJSON, zulipApiRequest } from './GenericFunctions';
|
||||
import { messageFields, messageOperations } from './MessageDescription';
|
||||
import type { IMessage } from './MessageInterface';
|
||||
import { streamFields, streamOperations } from './StreamDescription';
|
||||
|
|
@ -138,7 +138,7 @@ export class Zulip implements INodeType {
|
|||
if (resource === 'message') {
|
||||
//https://zulipchat.com/api/send-message
|
||||
if (operation === 'sendPrivate') {
|
||||
const to = (this.getNodeParameter('to', i) as string[]).join(',');
|
||||
const to = toMultiOptionsCsv(this.getNodeParameter('to', i));
|
||||
const content = this.getNodeParameter('content', i) as string;
|
||||
const body: IMessage = {
|
||||
type: 'private',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
import { toMultiOptionsCsv } from '../GenericFunctions';
|
||||
|
||||
describe('Zulip > GenericFunctions', () => {
|
||||
describe('toMultiOptionsCsv', () => {
|
||||
it('joins array values', () => {
|
||||
expect(toMultiOptionsCsv(['user1@example.com', 'user2@example.com'])).toBe(
|
||||
'user1@example.com,user2@example.com',
|
||||
);
|
||||
});
|
||||
|
||||
it('trims entries inside an array (interpolated array elements)', () => {
|
||||
expect(toMultiOptionsCsv(['user1@example.com ', ' user2@example.com'])).toBe(
|
||||
'user1@example.com,user2@example.com',
|
||||
);
|
||||
});
|
||||
|
||||
it('coerces non-string array entries via String()', () => {
|
||||
expect(toMultiOptionsCsv([1, 2, 3])).toBe('1,2,3');
|
||||
});
|
||||
|
||||
it('accepts a comma-joined string (the whitespace-expression coercion case)', () => {
|
||||
expect(toMultiOptionsCsv('user1@example.com,user2@example.com ')).toBe(
|
||||
'user1@example.com,user2@example.com',
|
||||
);
|
||||
});
|
||||
|
||||
it('trims whitespace around each entry in a comma-string', () => {
|
||||
expect(toMultiOptionsCsv(' user1@example.com , user2@example.com ')).toBe(
|
||||
'user1@example.com,user2@example.com',
|
||||
);
|
||||
});
|
||||
|
||||
it('drops empty entries', () => {
|
||||
expect(toMultiOptionsCsv(['user1@example.com', '', ' ', 'user2@example.com'])).toBe(
|
||||
'user1@example.com,user2@example.com',
|
||||
);
|
||||
});
|
||||
|
||||
it('returns an empty string for undefined/null/empty values', () => {
|
||||
expect(toMultiOptionsCsv(undefined)).toBe('');
|
||||
expect(toMultiOptionsCsv(null)).toBe('');
|
||||
expect(toMultiOptionsCsv('')).toBe('');
|
||||
expect(toMultiOptionsCsv([])).toBe('');
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user