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,62 @@
|
||||
import * as create from '../../../../v2/actions/drive/create.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction, driveNode } from '../helpers';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
googleApiRequest: jest.fn(async function () {
|
||||
return {};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('uuid', () => {
|
||||
const originalModule = jest.requireActual('uuid');
|
||||
return {
|
||||
...originalModule,
|
||||
v4: jest.fn(function () {
|
||||
return '430c0ca1-2498-472c-9d43-da0163839823';
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('test GoogleDriveV2: drive create', () => {
|
||||
it('should be called with', async () => {
|
||||
const nodeParameters = {
|
||||
resource: 'drive',
|
||||
name: 'newDrive',
|
||||
options: {
|
||||
capabilities: {
|
||||
canComment: true,
|
||||
canRename: true,
|
||||
canTrashChildren: true,
|
||||
},
|
||||
colorRgb: '#451AD3',
|
||||
hidden: false,
|
||||
restrictions: {
|
||||
driveMembersOnly: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const fakeExecuteFunction = createMockExecuteFunction(nodeParameters, driveNode);
|
||||
|
||||
await create.execute.call(fakeExecuteFunction, 0);
|
||||
|
||||
expect(transport.googleApiRequest).toBeCalledTimes(1);
|
||||
expect(transport.googleApiRequest).toHaveBeenCalledWith(
|
||||
'POST',
|
||||
'/drive/v3/drives',
|
||||
{
|
||||
capabilities: { canComment: true, canRename: true, canTrashChildren: true },
|
||||
colorRgb: '#451AD3',
|
||||
hidden: false,
|
||||
name: 'newDrive',
|
||||
restrictions: { driveMembersOnly: true },
|
||||
},
|
||||
{ requestId: '430c0ca1-2498-472c-9d43-da0163839823' },
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
import * as deleteDrive from '../../../../v2/actions/drive/deleteDrive.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction, driveNode } from '../helpers';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
googleApiRequest: jest.fn(async function () {
|
||||
return {};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('test GoogleDriveV2: drive deleteDrive', () => {
|
||||
it('should be called with', async () => {
|
||||
const nodeParameters = {
|
||||
resource: 'drive',
|
||||
operation: 'deleteDrive',
|
||||
driveId: {
|
||||
__rl: true,
|
||||
value: 'driveIDxxxxxx',
|
||||
mode: 'id',
|
||||
},
|
||||
};
|
||||
|
||||
const fakeExecuteFunction = createMockExecuteFunction(nodeParameters, driveNode);
|
||||
|
||||
await deleteDrive.execute.call(fakeExecuteFunction, 0);
|
||||
|
||||
expect(transport.googleApiRequest).toBeCalledTimes(1);
|
||||
expect(transport.googleApiRequest).toHaveBeenCalledWith(
|
||||
'DELETE',
|
||||
'/drive/v3/drives/driveIDxxxxxx',
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,42 @@
|
||||
import * as get from '../../../../v2/actions/drive/get.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction, driveNode } from '../helpers';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
googleApiRequest: jest.fn(async function () {
|
||||
return {};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('test GoogleDriveV2: drive get', () => {
|
||||
it('should be called with', async () => {
|
||||
const nodeParameters = {
|
||||
resource: 'drive',
|
||||
operation: 'get',
|
||||
driveId: {
|
||||
__rl: true,
|
||||
value: 'driveIDxxxxxx',
|
||||
mode: 'id',
|
||||
},
|
||||
options: {
|
||||
useDomainAdminAccess: true,
|
||||
},
|
||||
};
|
||||
|
||||
const fakeExecuteFunction = createMockExecuteFunction(nodeParameters, driveNode);
|
||||
|
||||
await get.execute.call(fakeExecuteFunction, 0);
|
||||
|
||||
expect(transport.googleApiRequest).toBeCalledTimes(1);
|
||||
expect(transport.googleApiRequest).toHaveBeenCalledWith(
|
||||
'GET',
|
||||
'/drive/v3/drives/driveIDxxxxxx',
|
||||
{},
|
||||
{ useDomainAdminAccess: true },
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,67 @@
|
||||
import type { IHttpRequestMethods } from 'n8n-workflow';
|
||||
|
||||
import * as list from '../../../../v2/actions/drive/list.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction, driveNode } from '../helpers';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
googleApiRequest: jest.fn(async function (method: IHttpRequestMethods) {
|
||||
if (method === 'GET') {
|
||||
return {};
|
||||
}
|
||||
}),
|
||||
googleApiRequestAllItems: jest.fn(async function (method: IHttpRequestMethods) {
|
||||
if (method === 'GET') {
|
||||
return {};
|
||||
}
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('test GoogleDriveV2: drive list', () => {
|
||||
it('should be called with limit', async () => {
|
||||
const nodeParameters = {
|
||||
resource: 'drive',
|
||||
operation: 'list',
|
||||
limit: 20,
|
||||
options: {},
|
||||
};
|
||||
|
||||
const fakeExecuteFunction = createMockExecuteFunction(nodeParameters, driveNode);
|
||||
|
||||
await list.execute.call(fakeExecuteFunction, 0);
|
||||
|
||||
expect(transport.googleApiRequest).toBeCalledTimes(1);
|
||||
expect(transport.googleApiRequest).toHaveBeenCalledWith(
|
||||
'GET',
|
||||
'/drive/v3/drives',
|
||||
{},
|
||||
{ pageSize: 20 },
|
||||
);
|
||||
});
|
||||
|
||||
it('should be called with returnAll true', async () => {
|
||||
const nodeParameters = {
|
||||
resource: 'drive',
|
||||
operation: 'list',
|
||||
returnAll: true,
|
||||
options: {},
|
||||
};
|
||||
|
||||
const fakeExecuteFunction = createMockExecuteFunction(nodeParameters, driveNode);
|
||||
|
||||
await list.execute.call(fakeExecuteFunction, 0);
|
||||
|
||||
expect(transport.googleApiRequestAllItems).toBeCalledTimes(1);
|
||||
expect(transport.googleApiRequestAllItems).toHaveBeenCalledWith(
|
||||
'GET',
|
||||
'drives',
|
||||
'/drive/v3/drives',
|
||||
{},
|
||||
{},
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,45 @@
|
||||
import * as update from '../../../../v2/actions/drive/update.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction, driveNode } from '../helpers';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
googleApiRequest: jest.fn(async function () {
|
||||
return {};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('test GoogleDriveV2: drive update', () => {
|
||||
it('should be called with', async () => {
|
||||
const nodeParameters = {
|
||||
resource: 'drive',
|
||||
operation: 'update',
|
||||
driveId: {
|
||||
__rl: true,
|
||||
value: 'sharedDriveIDxxxxx',
|
||||
mode: 'id',
|
||||
},
|
||||
options: {
|
||||
colorRgb: '#F4BEBE',
|
||||
name: 'newName',
|
||||
restrictions: {
|
||||
driveMembersOnly: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const fakeExecuteFunction = createMockExecuteFunction(nodeParameters, driveNode);
|
||||
|
||||
await update.execute.call(fakeExecuteFunction, 0);
|
||||
|
||||
expect(transport.googleApiRequest).toBeCalledTimes(1);
|
||||
expect(transport.googleApiRequest).toHaveBeenCalledWith(
|
||||
'PATCH',
|
||||
'/drive/v3/drives/sharedDriveIDxxxxx',
|
||||
{ colorRgb: '#F4BEBE', name: 'newName', restrictions: { driveMembersOnly: true } },
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,63 @@
|
||||
import * as copy from '../../../../v2/actions/file/copy.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction, driveNode } from '../helpers';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
googleApiRequest: jest.fn(async function () {
|
||||
return {};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('test GoogleDriveV2: file copy', () => {
|
||||
it('should be called with', async () => {
|
||||
const nodeParameters = {
|
||||
operation: 'copy',
|
||||
fileId: {
|
||||
__rl: true,
|
||||
value: 'fileIDxxxxxx',
|
||||
mode: 'list',
|
||||
cachedResultName: 'test01.png',
|
||||
cachedResultUrl: 'https://drive.google.com/file/d/fileIDxxxxxx/view?usp=drivesdk',
|
||||
},
|
||||
name: 'copyImage.png',
|
||||
sameFolder: false,
|
||||
folderId: {
|
||||
__rl: true,
|
||||
value: 'folderIDxxxxxx',
|
||||
mode: 'list',
|
||||
cachedResultName: 'testFolder 3',
|
||||
cachedResultUrl: 'https://drive.google.com/drive/folders/folderIDxxxxxx',
|
||||
},
|
||||
options: {
|
||||
copyRequiresWriterPermission: true,
|
||||
description: 'image copy',
|
||||
},
|
||||
};
|
||||
|
||||
const fakeExecuteFunction = createMockExecuteFunction(nodeParameters, driveNode);
|
||||
|
||||
await copy.execute.call(fakeExecuteFunction, 0);
|
||||
|
||||
expect(transport.googleApiRequest).toBeCalledTimes(1);
|
||||
expect(transport.googleApiRequest).toBeCalledWith(
|
||||
'POST',
|
||||
'/drive/v3/files/fileIDxxxxxx/copy',
|
||||
{
|
||||
copyRequiresWriterPermission: true,
|
||||
description: 'image copy',
|
||||
name: 'copyImage.png',
|
||||
parents: ['folderIDxxxxxx'],
|
||||
},
|
||||
{
|
||||
supportsAllDrives: true,
|
||||
corpora: 'allDrives',
|
||||
includeItemsFromAllDrives: true,
|
||||
spaces: 'appDataFolder, drive',
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,94 @@
|
||||
import * as createFromText from '../../../../v2/actions/file/createFromText.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction, driveNode } from '../helpers';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
googleApiRequest: jest.fn(async function () {
|
||||
return { id: 42 };
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('test GoogleDriveV2: file createFromText', () => {
|
||||
it('should be called with', async () => {
|
||||
const nodeParameters = {
|
||||
operation: 'createFromText',
|
||||
content: 'hello drive!',
|
||||
name: 'helloDrive.txt',
|
||||
folderId: {
|
||||
__rl: true,
|
||||
value: 'folderIDxxxxxx',
|
||||
mode: 'list',
|
||||
cachedResultName: 'testFolder 3',
|
||||
cachedResultUrl: 'https://drive.google.com/drive/folders/folderIDxxxxxx',
|
||||
},
|
||||
options: {
|
||||
appPropertiesUi: {
|
||||
appPropertyValues: [
|
||||
{
|
||||
key: 'appKey1',
|
||||
value: 'appValue1',
|
||||
},
|
||||
],
|
||||
},
|
||||
propertiesUi: {
|
||||
propertyValues: [
|
||||
{
|
||||
key: 'prop1',
|
||||
value: 'value1',
|
||||
},
|
||||
{
|
||||
key: 'prop2',
|
||||
value: 'value2',
|
||||
},
|
||||
],
|
||||
},
|
||||
keepRevisionForever: true,
|
||||
ocrLanguage: 'en',
|
||||
useContentAsIndexableText: true,
|
||||
},
|
||||
};
|
||||
|
||||
const fakeExecuteFunction = createMockExecuteFunction(nodeParameters, driveNode);
|
||||
|
||||
await createFromText.execute.call(fakeExecuteFunction, 0);
|
||||
|
||||
expect(transport.googleApiRequest).toBeCalledTimes(2);
|
||||
expect(transport.googleApiRequest).toHaveBeenCalledWith(
|
||||
'POST',
|
||||
'/upload/drive/v3/files',
|
||||
expect.anything(), // Buffer of content goes here
|
||||
{ uploadType: 'multipart', supportsAllDrives: true },
|
||||
undefined,
|
||||
{
|
||||
headers: {
|
||||
'Content-Length': 503,
|
||||
'Content-Type': expect.stringMatching(/^multipart\/related; boundary=(\\S)*/),
|
||||
},
|
||||
},
|
||||
);
|
||||
expect(transport.googleApiRequest).toHaveBeenCalledWith(
|
||||
'PATCH',
|
||||
'/drive/v3/files/42',
|
||||
{
|
||||
appProperties: { appKey1: 'appValue1' },
|
||||
mimeType: 'text/plain',
|
||||
name: 'helloDrive.txt',
|
||||
properties: { prop1: 'value1', prop2: 'value2' },
|
||||
},
|
||||
{
|
||||
addParents: 'folderIDxxxxxx',
|
||||
corpora: 'allDrives',
|
||||
includeItemsFromAllDrives: true,
|
||||
keepRevisionForever: true,
|
||||
ocrLanguage: 'en',
|
||||
spaces: 'appDataFolder, drive',
|
||||
supportsAllDrives: true,
|
||||
useContentAsIndexableText: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
import * as deleteFile from '../../../../v2/actions/file/deleteFile.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction, driveNode } from '../helpers';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
googleApiRequest: jest.fn(async function () {
|
||||
return {};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('test GoogleDriveV2: file deleteFile', () => {
|
||||
it('should be called with', async () => {
|
||||
const nodeParameters = {
|
||||
operation: 'deleteFile',
|
||||
fileId: {
|
||||
__rl: true,
|
||||
value: 'fileIDxxxxxx',
|
||||
mode: 'list',
|
||||
cachedResultName: 'test.txt',
|
||||
cachedResultUrl: 'https://drive.google.com/file/d/fileIDxxxxxx/view?usp=drivesdk',
|
||||
},
|
||||
options: {
|
||||
deletePermanently: true,
|
||||
},
|
||||
};
|
||||
|
||||
const fakeExecuteFunction = createMockExecuteFunction(nodeParameters, driveNode);
|
||||
|
||||
await deleteFile.execute.call(fakeExecuteFunction, 0);
|
||||
|
||||
expect(transport.googleApiRequest).toBeCalledTimes(1);
|
||||
expect(transport.googleApiRequest).toHaveBeenCalledWith(
|
||||
'DELETE',
|
||||
'/drive/v3/files/fileIDxxxxxx',
|
||||
undefined,
|
||||
{ supportsAllDrives: true },
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,51 @@
|
||||
import * as download from '../../../../v2/actions/file/download.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction, driveNode } from '../helpers';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
googleApiRequest: jest.fn(async function () {
|
||||
return {};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('test GoogleDriveV2: file download', () => {
|
||||
it('should be called with', async () => {
|
||||
const nodeParameters = {
|
||||
operation: 'deleteFile',
|
||||
fileId: {
|
||||
__rl: true,
|
||||
value: 'fileIDxxxxxx',
|
||||
mode: 'list',
|
||||
cachedResultName: 'test.txt',
|
||||
cachedResultUrl: 'https://drive.google.com/file/d/fileIDxxxxxx/view?usp=drivesdk',
|
||||
},
|
||||
options: {
|
||||
deletePermanently: true,
|
||||
},
|
||||
};
|
||||
|
||||
const fakeExecuteFunction = createMockExecuteFunction(nodeParameters, driveNode);
|
||||
|
||||
await download.execute.call(fakeExecuteFunction, 0, { json: {} });
|
||||
|
||||
expect(transport.googleApiRequest).toBeCalledTimes(2);
|
||||
expect(transport.googleApiRequest).toHaveBeenCalledWith(
|
||||
'GET',
|
||||
'/drive/v3/files/fileIDxxxxxx',
|
||||
{},
|
||||
{ fields: 'mimeType,name', supportsTeamDrives: true, supportsAllDrives: true },
|
||||
);
|
||||
expect(transport.googleApiRequest).toHaveBeenCalledWith(
|
||||
'GET',
|
||||
'/drive/v3/files/fileIDxxxxxx',
|
||||
{},
|
||||
{ alt: 'media', supportsAllDrives: true },
|
||||
undefined,
|
||||
{ encoding: 'arraybuffer', json: false, returnFullResponse: true, useStream: true },
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,73 @@
|
||||
import type { IHttpRequestMethods } from 'n8n-workflow';
|
||||
|
||||
import * as move from '../../../../v2/actions/file/move.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction, driveNode } from '../helpers';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
googleApiRequest: jest.fn(async function (method: IHttpRequestMethods) {
|
||||
if (method === 'GET') {
|
||||
return {
|
||||
parents: ['parentFolderIDxxxxxx'],
|
||||
};
|
||||
}
|
||||
return {};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('test GoogleDriveV2: file move', () => {
|
||||
it('should be called with', async () => {
|
||||
const nodeParameters = {
|
||||
operation: 'move',
|
||||
fileId: {
|
||||
__rl: true,
|
||||
value: 'fileIDxxxxxx',
|
||||
mode: 'list',
|
||||
cachedResultName: 'test.txt',
|
||||
cachedResultUrl: 'https://drive.google.com/file/d/fileIDxxxxxx/view?usp=drivesdk',
|
||||
},
|
||||
folderId: {
|
||||
__rl: true,
|
||||
value: 'folderIDxxxxxx',
|
||||
mode: 'list',
|
||||
cachedResultName: 'testFolder1',
|
||||
cachedResultUrl: 'https://drive.google.com/drive/folders/folderIDxxxxxx',
|
||||
},
|
||||
};
|
||||
|
||||
const fakeExecuteFunction = createMockExecuteFunction(nodeParameters, driveNode);
|
||||
|
||||
await move.execute.call(fakeExecuteFunction, 0);
|
||||
|
||||
expect(transport.googleApiRequest).toBeCalledTimes(2);
|
||||
expect(transport.googleApiRequest).toHaveBeenCalledWith(
|
||||
'GET',
|
||||
'/drive/v3/files/fileIDxxxxxx',
|
||||
undefined,
|
||||
{
|
||||
corpora: 'allDrives',
|
||||
fields: 'parents',
|
||||
includeItemsFromAllDrives: true,
|
||||
spaces: 'appDataFolder, drive',
|
||||
supportsAllDrives: true,
|
||||
},
|
||||
);
|
||||
expect(transport.googleApiRequest).toHaveBeenCalledWith(
|
||||
'PATCH',
|
||||
'/drive/v3/files/fileIDxxxxxx',
|
||||
undefined,
|
||||
{
|
||||
addParents: 'folderIDxxxxxx',
|
||||
removeParents: 'parentFolderIDxxxxxx',
|
||||
corpora: 'allDrives',
|
||||
includeItemsFromAllDrives: true,
|
||||
spaces: 'appDataFolder, drive',
|
||||
supportsAllDrives: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,61 @@
|
||||
import * as share from '../../../../v2/actions/file/share.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction, driveNode } from '../helpers';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
googleApiRequest: jest.fn(async function () {
|
||||
return {};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('test GoogleDriveV2: file share', () => {
|
||||
it('should be called with', async () => {
|
||||
const nodeParameters = {
|
||||
operation: 'share',
|
||||
fileId: {
|
||||
__rl: true,
|
||||
value: 'fileIDxxxxxx',
|
||||
mode: 'list',
|
||||
cachedResultName: 'test.txt',
|
||||
cachedResultUrl: 'https://drive.google.com/file/d/fileIDxxxxxx/view?usp=drivesdk',
|
||||
},
|
||||
permissionsUi: {
|
||||
permissionsValues: {
|
||||
role: 'owner',
|
||||
type: 'user',
|
||||
emailAddress: 'user@gmail.com',
|
||||
},
|
||||
},
|
||||
options: {
|
||||
emailMessage: 'some message',
|
||||
moveToNewOwnersRoot: true,
|
||||
sendNotificationEmail: true,
|
||||
transferOwnership: true,
|
||||
useDomainAdminAccess: true,
|
||||
},
|
||||
};
|
||||
|
||||
const fakeExecuteFunction = createMockExecuteFunction(nodeParameters, driveNode);
|
||||
|
||||
await share.execute.call(fakeExecuteFunction, 0);
|
||||
|
||||
expect(transport.googleApiRequest).toBeCalledTimes(1);
|
||||
expect(transport.googleApiRequest).toHaveBeenCalledWith(
|
||||
'POST',
|
||||
'/drive/v3/files/fileIDxxxxxx/permissions',
|
||||
{ emailAddress: 'user@gmail.com', role: 'owner', type: 'user' },
|
||||
{
|
||||
emailMessage: 'some message',
|
||||
moveToNewOwnersRoot: true,
|
||||
sendNotificationEmail: true,
|
||||
supportsAllDrives: true,
|
||||
transferOwnership: true,
|
||||
useDomainAdminAccess: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,53 @@
|
||||
import * as update from '../../../../v2/actions/file/update.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction, driveNode } from '../helpers';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
googleApiRequest: jest.fn(async function () {
|
||||
return {};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('test GoogleDriveV2: file update', () => {
|
||||
it('should be called with', async () => {
|
||||
const nodeParameters = {
|
||||
operation: 'update',
|
||||
fileId: {
|
||||
__rl: true,
|
||||
value: 'fileIDxxxxxx',
|
||||
mode: 'list',
|
||||
cachedResultName: 'test.txt',
|
||||
cachedResultUrl: 'https://drive.google.com/file/d/fileIDxxxxxx/view?usp=drivesdk',
|
||||
},
|
||||
newUpdatedFileName: 'test2.txt',
|
||||
options: {
|
||||
keepRevisionForever: true,
|
||||
ocrLanguage: 'en',
|
||||
useContentAsIndexableText: true,
|
||||
fields: ['hasThumbnail', 'starred'],
|
||||
},
|
||||
};
|
||||
|
||||
const fakeExecuteFunction = createMockExecuteFunction(nodeParameters, driveNode);
|
||||
|
||||
await update.execute.call(fakeExecuteFunction, 0);
|
||||
|
||||
expect(transport.googleApiRequest).toBeCalledTimes(1);
|
||||
expect(transport.googleApiRequest).toHaveBeenCalledWith(
|
||||
'PATCH',
|
||||
'/drive/v3/files/fileIDxxxxxx',
|
||||
{ name: 'test2.txt' },
|
||||
{
|
||||
fields: 'hasThumbnail, starred',
|
||||
keepRevisionForever: true,
|
||||
ocrLanguage: 'en',
|
||||
supportsAllDrives: true,
|
||||
useContentAsIndexableText: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,160 @@
|
||||
import type { IHttpRequestMethods } from 'n8n-workflow';
|
||||
|
||||
import * as upload from '../../../../v2/actions/file/upload.operation';
|
||||
import * as utils from '../../../../v2/helpers/utils';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction, createTestStream, driveNode } from '../helpers';
|
||||
|
||||
const fileContent = Buffer.from('Hello Drive!');
|
||||
const originalFilename = 'original.txt';
|
||||
const contentLength = 123;
|
||||
const mimeType = 'text/plain';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
googleApiRequest: jest.fn(async function (method: IHttpRequestMethods) {
|
||||
if (method === 'POST') {
|
||||
return {
|
||||
headers: { location: 'someLocation' },
|
||||
};
|
||||
}
|
||||
return {};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('../../../../v2/helpers/utils', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/helpers/utils');
|
||||
return {
|
||||
...originalModule,
|
||||
getItemBinaryData: jest.fn(async function () {
|
||||
return {
|
||||
contentLength,
|
||||
fileContent,
|
||||
originalFilename,
|
||||
mimeType,
|
||||
};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('test GoogleDriveV2: file upload', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should upload buffers', async () => {
|
||||
const name = 'newFile.txt';
|
||||
const parent = 'folderIDxxxxxx';
|
||||
const nodeParameters = {
|
||||
name,
|
||||
folderId: {
|
||||
__rl: true,
|
||||
value: parent,
|
||||
mode: 'list',
|
||||
cachedResultName: 'testFolder 3',
|
||||
cachedResultUrl: 'https://drive.google.com/drive/folders/folderIDxxxxxx',
|
||||
},
|
||||
options: {
|
||||
simplifyOutput: true,
|
||||
},
|
||||
};
|
||||
|
||||
const fakeExecuteFunction = createMockExecuteFunction(nodeParameters, driveNode);
|
||||
|
||||
await upload.execute.call(fakeExecuteFunction, 0);
|
||||
|
||||
expect(transport.googleApiRequest).toBeCalledTimes(2);
|
||||
|
||||
expect(transport.googleApiRequest).toHaveBeenCalledWith(
|
||||
'POST',
|
||||
'/upload/drive/v3/files',
|
||||
expect.any(Buffer),
|
||||
{ uploadType: 'multipart', supportsAllDrives: true },
|
||||
undefined,
|
||||
{
|
||||
headers: {
|
||||
'Content-Length': 498,
|
||||
'Content-Type': expect.stringMatching(/^multipart\/related; boundary=(\\S)*/),
|
||||
},
|
||||
},
|
||||
);
|
||||
expect(transport.googleApiRequest).toHaveBeenCalledWith(
|
||||
'PATCH',
|
||||
'/drive/v3/files/undefined',
|
||||
{ mimeType, name, originalFilename },
|
||||
{
|
||||
addParents: parent,
|
||||
supportsAllDrives: true,
|
||||
corpora: 'allDrives',
|
||||
includeItemsFromAllDrives: true,
|
||||
spaces: 'appDataFolder, drive',
|
||||
},
|
||||
);
|
||||
|
||||
expect(utils.getItemBinaryData).toBeCalledTimes(1);
|
||||
expect(utils.getItemBinaryData).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should stream large files in 2MB chunks', async () => {
|
||||
const name = 'newFile.jpg';
|
||||
const parent = 'folderIDxxxxxx';
|
||||
const originalFilename = 'test.jpg';
|
||||
const mimeType = 'image/jpg';
|
||||
const nodeParameters = {
|
||||
name,
|
||||
folderId: {
|
||||
__rl: true,
|
||||
value: parent,
|
||||
mode: 'list',
|
||||
cachedResultName: 'testFolder 3',
|
||||
cachedResultUrl: 'https://drive.google.com/drive/folders/folderIDxxxxxx',
|
||||
},
|
||||
options: {
|
||||
simplifyOutput: true,
|
||||
},
|
||||
};
|
||||
|
||||
const fakeExecuteFunction = createMockExecuteFunction(nodeParameters, driveNode);
|
||||
const httpRequestSpy = jest.spyOn(fakeExecuteFunction.helpers, 'httpRequest');
|
||||
|
||||
const fileSize = 7 * 1024 * 1024; // 7MB
|
||||
jest.mocked(utils.getItemBinaryData).mockResolvedValue({
|
||||
mimeType,
|
||||
originalFilename,
|
||||
contentLength: fileSize,
|
||||
fileContent: createTestStream(fileSize),
|
||||
});
|
||||
|
||||
await upload.execute.call(fakeExecuteFunction, 0);
|
||||
|
||||
// 4 chunks: 7MB = 3x2MB + 1x1MB
|
||||
expect(httpRequestSpy).toHaveBeenCalledTimes(4);
|
||||
expect(httpRequestSpy).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ body: expect.any(Buffer) }),
|
||||
);
|
||||
expect(transport.googleApiRequest).toBeCalledTimes(2);
|
||||
expect(transport.googleApiRequest).toHaveBeenCalledWith(
|
||||
'POST',
|
||||
'/upload/drive/v3/files',
|
||||
{ name, parents: [parent] },
|
||||
{ uploadType: 'resumable', supportsAllDrives: true },
|
||||
undefined,
|
||||
{ returnFullResponse: true, headers: { 'X-Upload-Content-Type': 'image/jpg' } },
|
||||
);
|
||||
expect(transport.googleApiRequest).toHaveBeenCalledWith(
|
||||
'PATCH',
|
||||
'/drive/v3/files/undefined',
|
||||
{ mimeType, name, originalFilename },
|
||||
{
|
||||
addParents: parent,
|
||||
supportsAllDrives: true,
|
||||
corpora: 'allDrives',
|
||||
includeItemsFromAllDrives: true,
|
||||
spaces: 'appDataFolder, drive',
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,108 @@
|
||||
import type { IHttpRequestMethods } from 'n8n-workflow';
|
||||
|
||||
import * as search from '../../../../v2/actions/fileFolder/search.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction, driveNode } from '../helpers';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
googleApiRequest: jest.fn(async function (method: IHttpRequestMethods) {
|
||||
if (method === 'GET') {
|
||||
return {};
|
||||
}
|
||||
}),
|
||||
googleApiRequestAllItems: jest.fn(async function (method: IHttpRequestMethods) {
|
||||
if (method === 'GET') {
|
||||
return {};
|
||||
}
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('test GoogleDriveV2: fileFolder search', () => {
|
||||
it('returnAll = false', async () => {
|
||||
const nodeParameters = {
|
||||
searchMethod: 'name',
|
||||
resource: 'fileFolder',
|
||||
queryString: 'test',
|
||||
returnAll: false,
|
||||
limit: 2,
|
||||
filter: {
|
||||
whatToSearch: 'files',
|
||||
fileTypes: ['application/vnd.google-apps.document'],
|
||||
},
|
||||
options: {
|
||||
fields: ['id', 'name', 'starred', 'version'],
|
||||
},
|
||||
};
|
||||
|
||||
const fakeExecuteFunction = createMockExecuteFunction(nodeParameters, driveNode);
|
||||
|
||||
await search.execute.call(fakeExecuteFunction, 0);
|
||||
|
||||
expect(transport.googleApiRequest).toBeCalledTimes(1);
|
||||
expect(transport.googleApiRequest).toBeCalledWith('GET', '/drive/v3/files', undefined, {
|
||||
corpora: 'allDrives',
|
||||
fields: 'nextPageToken, files(id, name, starred, version)',
|
||||
includeItemsFromAllDrives: true,
|
||||
pageSize: 2,
|
||||
q: "name contains 'test' and mimeType != 'application/vnd.google-apps.folder' and trashed = false and (mimeType = 'application/vnd.google-apps.document')",
|
||||
spaces: 'appDataFolder, drive',
|
||||
supportsAllDrives: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('returnAll = true', async () => {
|
||||
const nodeParameters = {
|
||||
resource: 'fileFolder',
|
||||
searchMethod: 'query',
|
||||
queryString: 'test',
|
||||
returnAll: true,
|
||||
filter: {
|
||||
driveId: {
|
||||
__rl: true,
|
||||
value: 'driveID000000123',
|
||||
mode: 'list',
|
||||
cachedResultName: 'sharedDrive',
|
||||
cachedResultUrl: 'https://drive.google.com/drive/folders/driveID000000123',
|
||||
},
|
||||
folderId: {
|
||||
__rl: true,
|
||||
value: 'folderID000000123',
|
||||
mode: 'list',
|
||||
cachedResultName: 'testFolder 3',
|
||||
cachedResultUrl: 'https://drive.google.com/drive/folders/folderID000000123',
|
||||
},
|
||||
whatToSearch: 'all',
|
||||
fileTypes: ['*'],
|
||||
includeTrashed: true,
|
||||
},
|
||||
options: {
|
||||
fields: ['permissions', 'mimeType'],
|
||||
},
|
||||
};
|
||||
|
||||
const fakeExecuteFunction = createMockExecuteFunction(nodeParameters, driveNode);
|
||||
|
||||
await search.execute.call(fakeExecuteFunction, 0);
|
||||
|
||||
expect(transport.googleApiRequestAllItems).toBeCalledTimes(1);
|
||||
expect(transport.googleApiRequestAllItems).toBeCalledWith(
|
||||
'GET',
|
||||
'files',
|
||||
'/drive/v3/files',
|
||||
{},
|
||||
{
|
||||
corpora: 'drive',
|
||||
driveId: 'driveID000000123',
|
||||
fields: 'nextPageToken, files(permissions, mimeType)',
|
||||
includeItemsFromAllDrives: true,
|
||||
q: "test and 'folderID000000123' in parents",
|
||||
spaces: 'appDataFolder, drive',
|
||||
supportsAllDrives: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,55 @@
|
||||
import * as create from '../../../../v2/actions/folder/create.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction, driveNode } from '../helpers';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
googleApiRequest: jest.fn(async function () {
|
||||
return {};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('test GoogleDriveV2: folder create', () => {
|
||||
it('should be called with', async () => {
|
||||
const nodeParameters = {
|
||||
resource: 'folder',
|
||||
name: 'testFolder 2',
|
||||
folderId: {
|
||||
__rl: true,
|
||||
value: 'root',
|
||||
mode: 'list',
|
||||
cachedResultName: 'root',
|
||||
cachedResultUrl: 'https://drive.google.com/drive',
|
||||
},
|
||||
options: {
|
||||
folderColorRgb: '#167D08',
|
||||
},
|
||||
};
|
||||
|
||||
const fakeExecuteFunction = createMockExecuteFunction(nodeParameters, driveNode);
|
||||
|
||||
await create.execute.call(fakeExecuteFunction, 0);
|
||||
|
||||
expect(transport.googleApiRequest).toBeCalledTimes(1);
|
||||
expect(transport.googleApiRequest).toHaveBeenCalledWith(
|
||||
'POST',
|
||||
'/drive/v3/files',
|
||||
{
|
||||
folderColorRgb: '#167D08',
|
||||
mimeType: 'application/vnd.google-apps.folder',
|
||||
name: 'testFolder 2',
|
||||
parents: ['root'],
|
||||
},
|
||||
{
|
||||
fields: undefined,
|
||||
includeItemsFromAllDrives: true,
|
||||
supportsAllDrives: true,
|
||||
spaces: 'appDataFolder, drive',
|
||||
corpora: 'allDrives',
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,67 @@
|
||||
import * as deleteFolder from '../../../../v2/actions/folder/deleteFolder.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction, driveNode } from '../helpers';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
googleApiRequest: jest.fn(async function () {
|
||||
return {};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('test GoogleDriveV2: folder deleteFolder', () => {
|
||||
it('should be called with PATCH', async () => {
|
||||
const nodeParameters = {
|
||||
resource: 'folder',
|
||||
operation: 'deleteFolder',
|
||||
folderNoRootId: {
|
||||
__rl: true,
|
||||
value: 'folderIDxxxxxx',
|
||||
mode: 'list',
|
||||
cachedResultName: 'testFolder 2',
|
||||
cachedResultUrl: 'https://drive.google.com/drive/folders/folderIDxxxxxx',
|
||||
},
|
||||
options: {},
|
||||
};
|
||||
|
||||
const fakeExecuteFunction = createMockExecuteFunction(nodeParameters, driveNode);
|
||||
|
||||
await deleteFolder.execute.call(fakeExecuteFunction, 0);
|
||||
|
||||
expect(transport.googleApiRequest).toHaveBeenCalledWith(
|
||||
'PATCH',
|
||||
'/drive/v3/files/folderIDxxxxxx',
|
||||
{ trashed: true },
|
||||
{ supportsAllDrives: true },
|
||||
);
|
||||
});
|
||||
|
||||
it('should be called with DELETE', async () => {
|
||||
const nodeParameters = {
|
||||
resource: 'folder',
|
||||
operation: 'deleteFolder',
|
||||
folderNoRootId: {
|
||||
__rl: true,
|
||||
value: 'folderIDxxxxxx',
|
||||
mode: 'list',
|
||||
cachedResultName: 'testFolder 2',
|
||||
cachedResultUrl: 'https://drive.google.com/drive/folders/folderIDxxxxxx',
|
||||
},
|
||||
options: { deletePermanently: true },
|
||||
};
|
||||
|
||||
const fakeExecuteFunction = createMockExecuteFunction(nodeParameters, driveNode);
|
||||
|
||||
await deleteFolder.execute.call(fakeExecuteFunction, 0);
|
||||
|
||||
expect(transport.googleApiRequest).toHaveBeenCalledWith(
|
||||
'DELETE',
|
||||
'/drive/v3/files/folderIDxxxxxx',
|
||||
undefined,
|
||||
{ supportsAllDrives: true },
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,51 @@
|
||||
import * as share from '../../../../v2/actions/folder/share.operation';
|
||||
import * as transport from '../../../../v2/transport';
|
||||
import { createMockExecuteFunction, driveNode } from '../helpers';
|
||||
|
||||
jest.mock('../../../../v2/transport', () => {
|
||||
const originalModule = jest.requireActual('../../../../v2/transport');
|
||||
return {
|
||||
...originalModule,
|
||||
googleApiRequest: jest.fn(async function () {
|
||||
return {};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('test GoogleDriveV2: folder share', () => {
|
||||
it('should be called with', async () => {
|
||||
const nodeParameters = {
|
||||
resource: 'folder',
|
||||
operation: 'share',
|
||||
folderNoRootId: {
|
||||
__rl: true,
|
||||
value: 'folderIDxxxxxx',
|
||||
mode: 'list',
|
||||
cachedResultName: 'testFolder 2',
|
||||
cachedResultUrl: 'https://drive.google.com/drive/folders/folderIDxxxxxx',
|
||||
},
|
||||
permissionsUi: {
|
||||
permissionsValues: {
|
||||
role: 'reader',
|
||||
type: 'anyone',
|
||||
allowFileDiscovery: true,
|
||||
},
|
||||
},
|
||||
options: {
|
||||
moveToNewOwnersRoot: true,
|
||||
},
|
||||
};
|
||||
|
||||
const fakeExecuteFunction = createMockExecuteFunction(nodeParameters, driveNode);
|
||||
|
||||
await share.execute.call(fakeExecuteFunction, 0);
|
||||
|
||||
expect(transport.googleApiRequest).toBeCalledTimes(1);
|
||||
expect(transport.googleApiRequest).toHaveBeenCalledWith(
|
||||
'POST',
|
||||
'/drive/v3/files/folderIDxxxxxx/permissions',
|
||||
{ allowFileDiscovery: true, role: 'reader', type: 'anyone' },
|
||||
{ moveToNewOwnersRoot: true, supportsAllDrives: true },
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,64 @@
|
||||
import get from 'lodash/get';
|
||||
import { constructExecutionMetaData } from 'n8n-core';
|
||||
import type { IDataObject, IExecuteFunctions, IGetNodeParameterOptions, INode } from 'n8n-workflow';
|
||||
import { Readable } from 'stream';
|
||||
|
||||
export const driveNode: INode = {
|
||||
id: '11',
|
||||
name: 'Google Drive node',
|
||||
typeVersion: 3,
|
||||
type: 'n8n-nodes-base.googleDrive',
|
||||
position: [42, 42],
|
||||
parameters: {},
|
||||
};
|
||||
|
||||
export const createMockExecuteFunction = (
|
||||
nodeParameters: IDataObject,
|
||||
node: INode,
|
||||
continueOnFail = false,
|
||||
) => {
|
||||
const fakeExecuteFunction = {
|
||||
getNodeParameter(
|
||||
parameterName: string,
|
||||
_itemIndex: number,
|
||||
fallbackValue?: IDataObject,
|
||||
options?: IGetNodeParameterOptions,
|
||||
) {
|
||||
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
||||
return get(nodeParameters, parameter, fallbackValue);
|
||||
},
|
||||
getNode() {
|
||||
return node;
|
||||
},
|
||||
helpers: {
|
||||
constructExecutionMetaData,
|
||||
returnJsonArray: () => [],
|
||||
prepareBinaryData: () => {},
|
||||
httpRequest: () => {},
|
||||
},
|
||||
continueOnFail: () => continueOnFail,
|
||||
} as unknown as IExecuteFunctions;
|
||||
return fakeExecuteFunction;
|
||||
};
|
||||
|
||||
export function createTestStream(byteSize: number) {
|
||||
let bytesSent = 0;
|
||||
const CHUNK_SIZE = 64 * 1024; // 64kB chunks (default NodeJS highWaterMark)
|
||||
|
||||
return new Readable({
|
||||
read() {
|
||||
const remainingBytes = byteSize - bytesSent;
|
||||
|
||||
if (remainingBytes <= 0) {
|
||||
this.push(null);
|
||||
return;
|
||||
}
|
||||
|
||||
const chunkSize = Math.min(CHUNK_SIZE, remainingBytes);
|
||||
const chunk = Buffer.alloc(chunkSize, 'A'); // Test data just a string of "A"
|
||||
|
||||
bytesSent += chunkSize;
|
||||
this.push(chunk);
|
||||
},
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user