mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-22 12:19:09 +00:00
refactor(editor): Move editor-ui and design-system to frontend dir (no-changelog) (#13564)
This commit is contained in:
@@ -0,0 +1,622 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import type { INode, IRunExecutionData, NodeConnectionType } from 'n8n-workflow';
|
||||
import { useAIAssistantHelpers } from './useAIAssistantHelpers';
|
||||
import { createTestingPinia } from '@pinia/testing';
|
||||
import { setActivePinia } from 'pinia';
|
||||
import type { IWorkflowDb } from '@/Interface';
|
||||
import type { ChatRequest } from '@/types/assistant.types';
|
||||
import {
|
||||
ERROR_HELPER_TEST_PAYLOAD,
|
||||
PAYLOAD_SIZE_FOR_1_PASS,
|
||||
PAYLOAD_SIZE_FOR_2_PASSES,
|
||||
SUPPORT_CHAT_TEST_PAYLOAD,
|
||||
} from './useAIAssistantHelpers.test.constants';
|
||||
|
||||
const referencedNodesTestCases: Array<{ caseName: string; node: INode; expected: string[] }> = [
|
||||
{
|
||||
caseName: 'Should return an empty array if no referenced nodes',
|
||||
node: {
|
||||
parameters: {
|
||||
curlImport: '',
|
||||
method: 'GET',
|
||||
url: 'https://httpbin.org/get1',
|
||||
authentication: 'none',
|
||||
provideSslCertificates: false,
|
||||
sendQuery: false,
|
||||
sendHeaders: false,
|
||||
sendBody: false,
|
||||
options: {},
|
||||
infoMessage: '',
|
||||
},
|
||||
type: 'n8n-nodes-base.httpRequest',
|
||||
typeVersion: 4.2,
|
||||
position: [220, 220],
|
||||
id: 'edc36001-aee7-4052-b66e-cf127f4b6ea5',
|
||||
name: 'HTTP Request',
|
||||
},
|
||||
expected: [],
|
||||
},
|
||||
{
|
||||
caseName: 'Should return an array of references for regular node',
|
||||
node: {
|
||||
parameters: {
|
||||
authentication: 'oAuth2',
|
||||
resource: 'sheet',
|
||||
operation: 'read',
|
||||
documentId: {
|
||||
__rl: true,
|
||||
value: "={{ $('Edit Fields').item.json.document }}",
|
||||
mode: 'id',
|
||||
},
|
||||
sheetName: {
|
||||
__rl: true,
|
||||
value: "={{ $('Edit Fields 2').item.json.sheet }}",
|
||||
mode: 'id',
|
||||
},
|
||||
filtersUI: {},
|
||||
combineFilters: 'AND',
|
||||
options: {},
|
||||
},
|
||||
type: 'n8n-nodes-base.googleSheets',
|
||||
typeVersion: 4.5,
|
||||
position: [440, 0],
|
||||
id: '9a95ad27-06cf-4076-af6b-52846a109a8b',
|
||||
name: 'Google Sheets',
|
||||
credentials: {
|
||||
googleSheetsOAuth2Api: {
|
||||
id: '8QEpi028oHDLXntS',
|
||||
name: 'milorad@n8n.io',
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: ['Edit Fields', 'Edit Fields 2'],
|
||||
},
|
||||
{
|
||||
caseName: 'Should return an array of references for set node',
|
||||
node: {
|
||||
parameters: {
|
||||
mode: 'manual',
|
||||
duplicateItem: false,
|
||||
assignments: {
|
||||
assignments: [
|
||||
{
|
||||
id: '135e0eb0-f412-430d-8990-731c57cf43ae',
|
||||
name: 'document',
|
||||
value: "={{ $('Edit Fields 2').item.json.document}}",
|
||||
type: 'string',
|
||||
typeVersion: 1,
|
||||
},
|
||||
{
|
||||
parameters: {},
|
||||
id: 'b5942df6-0160-4ef7-965d-57583acdc8aa',
|
||||
name: 'Replace me with your logic',
|
||||
type: 'n8n-nodes-base.noOp',
|
||||
position: [520, 340],
|
||||
typeVersion: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
includeOtherFields: false,
|
||||
options: {},
|
||||
},
|
||||
type: 'n8n-nodes-base.set',
|
||||
typeVersion: 3.4,
|
||||
position: [560, -140],
|
||||
id: '7306745f-ba8c-451d-ae1a-c627f60fbdd3',
|
||||
name: 'Edit Fields 2',
|
||||
},
|
||||
expected: ['Edit Fields 2'],
|
||||
},
|
||||
{
|
||||
caseName: 'Should handle expressions with single quotes, double quotes and backticks',
|
||||
node: {
|
||||
parameters: {
|
||||
authentication: 'oAuth2',
|
||||
resource: 'sheet',
|
||||
operation: 'read',
|
||||
documentId: {
|
||||
__rl: true,
|
||||
value: "={{ $('Edit Fields').item.json.document }}",
|
||||
mode: 'id',
|
||||
},
|
||||
sheetName: {
|
||||
__rl: true,
|
||||
value: '={{ $("Edit Fields 2").item.json.sheet }}',
|
||||
mode: 'id',
|
||||
},
|
||||
rowName: {
|
||||
__rl: true,
|
||||
value: '={{ $(`Edit Fields 3`).item.json.row }}',
|
||||
mode: 'id',
|
||||
},
|
||||
filtersUI: {},
|
||||
combineFilters: 'AND',
|
||||
options: {},
|
||||
},
|
||||
type: 'n8n-nodes-base.googleSheets',
|
||||
typeVersion: 4.5,
|
||||
position: [440, 0],
|
||||
id: '9a95ad27-06cf-4076-af6b-52846a109a8b',
|
||||
name: 'Google Sheets',
|
||||
credentials: {
|
||||
googleSheetsOAuth2Api: {
|
||||
id: '8QEpi028oHDLXntS',
|
||||
name: 'milorad@n8n.io',
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: ['Edit Fields', 'Edit Fields 2', 'Edit Fields 3'],
|
||||
},
|
||||
{
|
||||
caseName: 'Should only add one reference for each referenced node',
|
||||
node: {
|
||||
parameters: {
|
||||
authentication: 'oAuth2',
|
||||
resource: 'sheet',
|
||||
operation: 'read',
|
||||
documentId: {
|
||||
__rl: true,
|
||||
value: "={{ $('Edit Fields').item.json.document }}",
|
||||
mode: 'id',
|
||||
},
|
||||
sheetName: {
|
||||
__rl: true,
|
||||
value: "={{ $('Edit Fields').item.json.sheet }}",
|
||||
mode: 'id',
|
||||
},
|
||||
filtersUI: {},
|
||||
combineFilters: 'AND',
|
||||
options: {},
|
||||
},
|
||||
type: 'n8n-nodes-base.googleSheets',
|
||||
typeVersion: 4.5,
|
||||
position: [440, 0],
|
||||
id: '9a95ad27-06cf-4076-af6b-52846a109a8b',
|
||||
name: 'Google Sheets',
|
||||
credentials: {
|
||||
googleSheetsOAuth2Api: {
|
||||
id: '8QEpi028oHDLXntS',
|
||||
name: 'milorad@n8n.io',
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: ['Edit Fields'],
|
||||
},
|
||||
{
|
||||
caseName: 'Should handle multiple node references in one expression',
|
||||
node: {
|
||||
parameters: {
|
||||
curlImport: '',
|
||||
method: 'GET',
|
||||
url: "={{ $('Edit Fields').item.json.one }} {{ $('Edit Fields 2').item.json.two }} {{ $('Edit Fields').item.json.three }}",
|
||||
authentication: 'none',
|
||||
provideSslCertificates: false,
|
||||
sendQuery: false,
|
||||
sendHeaders: false,
|
||||
sendBody: false,
|
||||
options: {},
|
||||
infoMessage: '',
|
||||
},
|
||||
type: 'n8n-nodes-base.httpRequest',
|
||||
typeVersion: 4.2,
|
||||
position: [220, 220],
|
||||
id: 'edc36001-aee7-4052-b66e-cf127f4b6ea5',
|
||||
name: 'HTTP Request',
|
||||
},
|
||||
expected: ['Edit Fields', 'Edit Fields 2'],
|
||||
},
|
||||
{
|
||||
caseName: 'Should respect whitespace around node references',
|
||||
node: {
|
||||
parameters: {
|
||||
curlImport: '',
|
||||
method: 'GET',
|
||||
url: "={{ $(' Edit Fields ').item.json.one }}",
|
||||
authentication: 'none',
|
||||
provideSslCertificates: false,
|
||||
sendQuery: false,
|
||||
sendHeaders: false,
|
||||
sendBody: false,
|
||||
options: {},
|
||||
infoMessage: '',
|
||||
},
|
||||
type: 'n8n-nodes-base.httpRequest',
|
||||
typeVersion: 4.2,
|
||||
position: [220, 220],
|
||||
id: 'edc36001-aee7-4052-b66e-cf127f4b6ea5',
|
||||
name: 'HTTP Request',
|
||||
},
|
||||
expected: [' Edit Fields '],
|
||||
},
|
||||
{
|
||||
caseName: 'Should ignore whitespace inside expressions',
|
||||
node: {
|
||||
parameters: {
|
||||
curlImport: '',
|
||||
method: 'GET',
|
||||
url: "={{ $( 'Edit Fields' ).item.json.one }}",
|
||||
authentication: 'none',
|
||||
provideSslCertificates: false,
|
||||
sendQuery: false,
|
||||
sendHeaders: false,
|
||||
sendBody: false,
|
||||
options: {},
|
||||
infoMessage: '',
|
||||
},
|
||||
type: 'n8n-nodes-base.httpRequest',
|
||||
typeVersion: 4.2,
|
||||
position: [220, 220],
|
||||
id: 'edc36001-aee7-4052-b66e-cf127f4b6ea5',
|
||||
name: 'HTTP Request',
|
||||
},
|
||||
expected: ['Edit Fields'],
|
||||
},
|
||||
{
|
||||
caseName: 'Should ignore special characters in node references',
|
||||
node: {
|
||||
parameters: {
|
||||
curlImport: '',
|
||||
method: 'GET',
|
||||
url: "={{ $( 'Ignore ' this' ).item.json.document }",
|
||||
authentication: 'none',
|
||||
provideSslCertificates: false,
|
||||
sendQuery: false,
|
||||
sendHeaders: false,
|
||||
sendBody: false,
|
||||
options: {},
|
||||
infoMessage: '',
|
||||
},
|
||||
type: 'n8n-nodes-base.httpRequest',
|
||||
typeVersion: 4.2,
|
||||
position: [220, 220],
|
||||
id: 'edc36001-aee7-4052-b66e-cf127f4b6ea5',
|
||||
name: 'HTTP Request',
|
||||
},
|
||||
expected: [],
|
||||
},
|
||||
{
|
||||
caseName: 'Should correctly detect node names that contain single quotes',
|
||||
node: {
|
||||
parameters: {
|
||||
curlImport: '',
|
||||
method: 'GET',
|
||||
// In order to carry over backslashes to test function, the string needs to be double escaped
|
||||
url: "={{ $('Edit \\'Fields\\' 2').item.json.name }}",
|
||||
authentication: 'none',
|
||||
provideSslCertificates: false,
|
||||
sendQuery: false,
|
||||
sendHeaders: false,
|
||||
sendBody: false,
|
||||
options: {},
|
||||
infoMessage: '',
|
||||
},
|
||||
type: 'n8n-nodes-base.httpRequest',
|
||||
typeVersion: 4.2,
|
||||
position: [220, 220],
|
||||
id: 'edc36001-aee7-4052-b66e-cf127f4b6ea5',
|
||||
name: 'HTTP Request',
|
||||
},
|
||||
expected: ["Edit 'Fields' 2"],
|
||||
},
|
||||
{
|
||||
caseName: 'Should correctly detect node names with inner backticks',
|
||||
node: {
|
||||
parameters: {
|
||||
curlImport: '',
|
||||
method: 'GET',
|
||||
url: "={{ $('Edit `Fields` 2').item.json.name }}",
|
||||
authentication: 'none',
|
||||
provideSslCertificates: false,
|
||||
sendQuery: false,
|
||||
sendHeaders: false,
|
||||
sendBody: false,
|
||||
options: {},
|
||||
infoMessage: '',
|
||||
},
|
||||
type: 'n8n-nodes-base.httpRequest',
|
||||
typeVersion: 4.2,
|
||||
position: [220, 220],
|
||||
id: 'edc36001-aee7-4052-b66e-cf127f4b6ea5',
|
||||
name: 'HTTP Request',
|
||||
},
|
||||
expected: ['Edit `Fields` 2'],
|
||||
},
|
||||
{
|
||||
caseName: 'Should correctly detect node names with inner escaped backticks',
|
||||
node: {
|
||||
parameters: {
|
||||
curlImport: '',
|
||||
method: 'GET',
|
||||
url: '={{ $(`Edit \\`Fields\\` 2`).item.json.name }}',
|
||||
authentication: 'none',
|
||||
provideSslCertificates: false,
|
||||
sendQuery: false,
|
||||
sendHeaders: false,
|
||||
sendBody: false,
|
||||
options: {},
|
||||
infoMessage: '',
|
||||
},
|
||||
type: 'n8n-nodes-base.httpRequest',
|
||||
typeVersion: 4.2,
|
||||
position: [220, 220],
|
||||
id: 'edc36001-aee7-4052-b66e-cf127f4b6ea5',
|
||||
name: 'HTTP Request',
|
||||
},
|
||||
expected: ['Edit `Fields` 2'],
|
||||
},
|
||||
{
|
||||
caseName: 'Should correctly detect node names with inner escaped double quotes',
|
||||
node: {
|
||||
parameters: {
|
||||
curlImport: '',
|
||||
method: 'GET',
|
||||
// In order to carry over backslashes to test function, the string needs to be double escaped
|
||||
url: '={{ $("Edit \\"Fields\\" 2").item.json.name }}',
|
||||
authentication: 'none',
|
||||
provideSslCertificates: false,
|
||||
sendQuery: false,
|
||||
sendHeaders: false,
|
||||
sendBody: false,
|
||||
options: {},
|
||||
infoMessage: '',
|
||||
},
|
||||
type: 'n8n-nodes-base.httpRequest',
|
||||
typeVersion: 4.2,
|
||||
position: [220, 220],
|
||||
id: 'edc36001-aee7-4052-b66e-cf127f4b6ea5',
|
||||
name: 'HTTP Request',
|
||||
},
|
||||
expected: ['Edit "Fields" 2'],
|
||||
},
|
||||
{
|
||||
caseName: 'Should not detect invalid expressions',
|
||||
node: {
|
||||
parameters: {
|
||||
curlImport: '',
|
||||
method: 'GET',
|
||||
// String not closed properly
|
||||
url: "={{ $('Edit ' fields').item.json.document }",
|
||||
// Mixed quotes
|
||||
url2: '{{ $("Edit \'Fields" 2").item.json.name }}',
|
||||
url3: '{{ $("Edit `Fields" 2").item.json.name }}',
|
||||
// Quotes not escaped
|
||||
url4: '{{ $("Edit "Fields" 2").item.json.name }}',
|
||||
url5: "{{ $('Edit 'Fields' 2').item.json.name }}",
|
||||
url6: '{{ $(`Edit `Fields` 2`).item.json.name }}',
|
||||
},
|
||||
type: 'n8n-nodes-base.httpRequest',
|
||||
typeVersion: 4.2,
|
||||
position: [220, 220],
|
||||
id: 'edc36001-aee7-4052-b66e-cf127f4b6ea5',
|
||||
name: 'HTTP Request',
|
||||
},
|
||||
expected: [],
|
||||
},
|
||||
];
|
||||
|
||||
const testWorkflow: IWorkflowDb = {
|
||||
id: 'MokOcBHON6KkPq6Y',
|
||||
name: 'My Sub-Workflow 3',
|
||||
active: false,
|
||||
createdAt: -1,
|
||||
updatedAt: -1,
|
||||
connections: {
|
||||
'Execute Workflow Trigger': {
|
||||
main: [
|
||||
[
|
||||
{
|
||||
node: 'Replace me with your logic',
|
||||
type: 'main' as NodeConnectionType,
|
||||
index: 0,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
nodes: [
|
||||
{
|
||||
parameters: {
|
||||
notice: '',
|
||||
events: 'worklfow_call',
|
||||
},
|
||||
id: 'c055762a-8fe7-4141-a639-df2372f30060',
|
||||
name: 'Execute Workflow Trigger',
|
||||
type: 'n8n-nodes-base.executeWorkflowTrigger',
|
||||
position: [260, 340],
|
||||
typeVersion: 0,
|
||||
},
|
||||
{
|
||||
parameters: {},
|
||||
id: 'b5942df6-0160-4ef7-965d-57583acdc8aa',
|
||||
name: 'Replace me with your logic',
|
||||
type: 'n8n-nodes-base.noOp',
|
||||
position: [520, 340],
|
||||
typeVersion: 1,
|
||||
},
|
||||
],
|
||||
settings: {
|
||||
executionOrder: 'v1',
|
||||
},
|
||||
tags: [],
|
||||
pinData: {},
|
||||
versionId: '9f3263e3-d23d-4cc8-bff0-0fdecfbd82bf',
|
||||
usedCredentials: [],
|
||||
scopes: [
|
||||
'workflow:create',
|
||||
'workflow:delete',
|
||||
'workflow:execute',
|
||||
'workflow:list',
|
||||
'workflow:move',
|
||||
'workflow:read',
|
||||
'workflow:share',
|
||||
'workflow:update',
|
||||
],
|
||||
sharedWithProjects: [],
|
||||
};
|
||||
|
||||
const testExecutionData: IRunExecutionData['resultData'] = {
|
||||
runData: {
|
||||
'When clicking ‘Test workflow’': [
|
||||
{
|
||||
hints: [],
|
||||
startTime: 1732882780588,
|
||||
executionTime: 4,
|
||||
source: [],
|
||||
executionStatus: 'success',
|
||||
data: {
|
||||
main: [
|
||||
[
|
||||
{
|
||||
json: {},
|
||||
pairedItem: {
|
||||
item: 0,
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
'Edit Fields': [
|
||||
{
|
||||
hints: [],
|
||||
startTime: 1732882780593,
|
||||
executionTime: 0,
|
||||
source: [
|
||||
{
|
||||
previousNode: 'When clicking ‘Test workflow’',
|
||||
},
|
||||
],
|
||||
executionStatus: 'success',
|
||||
data: {
|
||||
main: [
|
||||
[
|
||||
{
|
||||
json: {
|
||||
something: 'here',
|
||||
},
|
||||
pairedItem: {
|
||||
item: 0,
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
pinData: {},
|
||||
lastNodeExecuted: 'Edit Fields',
|
||||
};
|
||||
|
||||
describe.each(referencedNodesTestCases)('getReferencedNodes', (testCase) => {
|
||||
let aiAssistantHelpers: ReturnType<typeof useAIAssistantHelpers>;
|
||||
|
||||
beforeEach(() => {
|
||||
setActivePinia(createTestingPinia());
|
||||
aiAssistantHelpers = useAIAssistantHelpers();
|
||||
});
|
||||
|
||||
const caseName = testCase.caseName;
|
||||
it(`${caseName}`, () => {
|
||||
expect(aiAssistantHelpers.getReferencedNodes(testCase.node)).toEqual(testCase.expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Simplify assistant payloads', () => {
|
||||
let aiAssistantHelpers: ReturnType<typeof useAIAssistantHelpers>;
|
||||
|
||||
beforeEach(() => {
|
||||
setActivePinia(createTestingPinia());
|
||||
aiAssistantHelpers = useAIAssistantHelpers();
|
||||
});
|
||||
|
||||
it('simplifyWorkflowForAssistant: Should remove unnecessary properties from workflow object', () => {
|
||||
const simplifiedWorkflow = aiAssistantHelpers.simplifyWorkflowForAssistant(testWorkflow);
|
||||
const removedProperties = [
|
||||
'createdAt',
|
||||
'updatedAt',
|
||||
'settings',
|
||||
'versionId',
|
||||
'usedCredentials',
|
||||
'sharedWithProjects',
|
||||
'pinData',
|
||||
'scopes',
|
||||
'tags',
|
||||
];
|
||||
removedProperties.forEach((property) => {
|
||||
expect(simplifiedWorkflow).not.toHaveProperty(property);
|
||||
});
|
||||
});
|
||||
|
||||
it('simplifyResultData: Should remove data from nodes', () => {
|
||||
const simplifiedResultData = aiAssistantHelpers.simplifyResultData(testExecutionData);
|
||||
for (const nodeName of Object.keys(simplifiedResultData.runData)) {
|
||||
expect(simplifiedResultData.runData[nodeName][0]).not.toHaveProperty('data');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('Trim Payload Size', () => {
|
||||
let aiAssistantHelpers: ReturnType<typeof useAIAssistantHelpers>;
|
||||
|
||||
beforeEach(() => {
|
||||
setActivePinia(createTestingPinia());
|
||||
aiAssistantHelpers = useAIAssistantHelpers();
|
||||
});
|
||||
|
||||
it('Should trim active node parameters in error helper payload', () => {
|
||||
const payload = ERROR_HELPER_TEST_PAYLOAD;
|
||||
aiAssistantHelpers.trimPayloadSize(payload);
|
||||
expect((payload.payload as ChatRequest.InitErrorHelper).node.parameters).toEqual({});
|
||||
});
|
||||
|
||||
it('Should trim all node parameters in support chat', () => {
|
||||
// Testing the scenario where only one trimming pass is needed
|
||||
// (payload is under the limit after removing all node parameters and execution data)
|
||||
const payload: ChatRequest.RequestPayload = SUPPORT_CHAT_TEST_PAYLOAD;
|
||||
const supportPayload: ChatRequest.InitSupportChat =
|
||||
payload.payload as ChatRequest.InitSupportChat;
|
||||
|
||||
// Trimming to 4kb should be successful
|
||||
expect(() =>
|
||||
aiAssistantHelpers.trimPayloadSize(payload, PAYLOAD_SIZE_FOR_1_PASS),
|
||||
).not.toThrow();
|
||||
// All active node parameters should be removed
|
||||
expect(supportPayload?.context?.activeNodeInfo?.node?.parameters).toEqual({});
|
||||
// Also, all node parameters in the workflow should be removed
|
||||
supportPayload.context?.currentWorkflow?.nodes?.forEach((node) => {
|
||||
expect(node.parameters).toEqual({});
|
||||
});
|
||||
// Node parameters in the execution data should be removed
|
||||
expect(supportPayload.context?.executionData?.runData).toEqual({});
|
||||
if (
|
||||
supportPayload.context?.executionData?.error &&
|
||||
'node' in supportPayload.context.executionData.error
|
||||
) {
|
||||
expect(supportPayload.context?.executionData?.error?.node?.parameters).toEqual({});
|
||||
}
|
||||
// Context object should still be there
|
||||
expect(supportPayload.context).to.be.an('object');
|
||||
});
|
||||
|
||||
it('Should trim the whole context in support chat', () => {
|
||||
// Testing the scenario where both trimming passes are needed
|
||||
// (payload is over the limit after removing all node parameters and execution data)
|
||||
const payload: ChatRequest.RequestPayload = SUPPORT_CHAT_TEST_PAYLOAD;
|
||||
const supportPayload: ChatRequest.InitSupportChat =
|
||||
payload.payload as ChatRequest.InitSupportChat;
|
||||
|
||||
// Trimming should be successful
|
||||
expect(() =>
|
||||
aiAssistantHelpers.trimPayloadSize(payload, PAYLOAD_SIZE_FOR_2_PASSES),
|
||||
).not.toThrow();
|
||||
// The whole context object should be removed
|
||||
expect(supportPayload.context).not.toBeDefined();
|
||||
});
|
||||
|
||||
it('Should throw an error if payload is too big after trimming', () => {
|
||||
const payload = ERROR_HELPER_TEST_PAYLOAD;
|
||||
expect(() => aiAssistantHelpers.trimPayloadSize(payload, 0.2)).toThrow();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user