refactor(core): Refactor nodes loading (no-changelog) (#7283)
fixes PAY-605
This commit is contained in:
committed by
GitHub
parent
789e1e7ed4
commit
c5ee06cc61
@@ -1,7 +1,8 @@
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { mocked } from 'jest-mock';
|
||||
import { Container } from 'typedi';
|
||||
|
||||
import type { ICredentialTypes, INode, INodesAndCredentials } from 'n8n-workflow';
|
||||
import type { INode } from 'n8n-workflow';
|
||||
import { LoggerProxy, NodeApiError, NodeOperationError, Workflow } from 'n8n-workflow';
|
||||
|
||||
import { ActiveWorkflowRunner } from '@/ActiveWorkflowRunner';
|
||||
@@ -11,22 +12,19 @@ import { SharedWorkflow } from '@db/entities/SharedWorkflow';
|
||||
import { Role } from '@db/entities/Role';
|
||||
import { User } from '@db/entities/User';
|
||||
import { getLogger } from '@/Logger';
|
||||
import { randomEmail, randomName } from '../integration/shared/random';
|
||||
import * as Helpers from './Helpers';
|
||||
import * as WorkflowExecuteAdditionalData from '@/WorkflowExecuteAdditionalData';
|
||||
|
||||
import { WorkflowRunner } from '@/WorkflowRunner';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
import type { ExternalHooks } from '@/ExternalHooks';
|
||||
import { Container } from 'typedi';
|
||||
import { ExternalHooks } from '@/ExternalHooks';
|
||||
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
|
||||
import { mockInstance } from '../integration/shared/utils/';
|
||||
import { Push } from '@/push';
|
||||
import { ActiveExecutions } from '@/ActiveExecutions';
|
||||
import { NodeTypes } from '@/NodeTypes';
|
||||
import { SecretsHelper } from '@/SecretsHelpers';
|
||||
import { WebhookService } from '@/services/webhook.service';
|
||||
import { VariablesService } from '../../src/environments/variables/variables.service';
|
||||
import { VariablesService } from '@/environments/variables/variables.service';
|
||||
|
||||
import { mockInstance } from '../integration/shared/utils/';
|
||||
import { randomEmail, randomName } from '../integration/shared/random';
|
||||
import * as Helpers from './Helpers';
|
||||
|
||||
/**
|
||||
* TODO:
|
||||
@@ -114,13 +112,6 @@ jest.mock('@/Db', () => {
|
||||
return fakeQueryBuilder;
|
||||
}),
|
||||
},
|
||||
Webhook: {
|
||||
clear: jest.fn(),
|
||||
delete: jest.fn(),
|
||||
},
|
||||
Variables: {
|
||||
find: jest.fn(() => []),
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
@@ -140,37 +131,24 @@ const workflowExecuteAdditionalDataExecuteErrorWorkflowSpy = jest.spyOn(
|
||||
);
|
||||
|
||||
describe('ActiveWorkflowRunner', () => {
|
||||
let externalHooks: ExternalHooks;
|
||||
let activeWorkflowRunner: ActiveWorkflowRunner;
|
||||
mockInstance(ActiveExecutions);
|
||||
const externalHooks = mockInstance(ExternalHooks);
|
||||
const webhookService = mockInstance(WebhookService);
|
||||
mockInstance(Push);
|
||||
mockInstance(SecretsHelper);
|
||||
const variablesService = mockInstance(VariablesService);
|
||||
const nodesAndCredentials = mockInstance(LoadNodesAndCredentials);
|
||||
Object.assign(nodesAndCredentials, {
|
||||
loadedNodes: MOCK_NODE_TYPES_DATA,
|
||||
known: { nodes: {}, credentials: {} },
|
||||
types: { nodes: [], credentials: [] },
|
||||
});
|
||||
|
||||
const activeWorkflowRunner = Container.get(ActiveWorkflowRunner);
|
||||
|
||||
beforeAll(async () => {
|
||||
LoggerProxy.init(getLogger());
|
||||
const nodesAndCredentials: INodesAndCredentials = {
|
||||
loaded: {
|
||||
nodes: MOCK_NODE_TYPES_DATA,
|
||||
credentials: {},
|
||||
},
|
||||
known: { nodes: {}, credentials: {} },
|
||||
credentialTypes: {} as ICredentialTypes,
|
||||
};
|
||||
const mockVariablesService = {
|
||||
getAllCached: jest.fn(() => []),
|
||||
};
|
||||
Container.set(LoadNodesAndCredentials, nodesAndCredentials);
|
||||
Container.set(VariablesService, mockVariablesService);
|
||||
mockInstance(Push);
|
||||
mockInstance(SecretsHelper);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
externalHooks = mock();
|
||||
activeWorkflowRunner = new ActiveWorkflowRunner(
|
||||
new ActiveExecutions(),
|
||||
externalHooks,
|
||||
Container.get(NodeTypes),
|
||||
webhookService,
|
||||
);
|
||||
variablesService.getAllCached.mockResolvedValue([]);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
|
||||
@@ -1,36 +1,29 @@
|
||||
import type { ICredentialTypes, INodesAndCredentials } from 'n8n-workflow';
|
||||
import { CredentialTypes } from '@/CredentialTypes';
|
||||
import { Container } from 'typedi';
|
||||
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
|
||||
import { mockInstance } from '../integration/shared/utils';
|
||||
|
||||
describe('CredentialTypes', () => {
|
||||
const mockNodesAndCredentials: INodesAndCredentials = {
|
||||
loaded: {
|
||||
nodes: {},
|
||||
credentials: {
|
||||
fakeFirstCredential: {
|
||||
type: {
|
||||
name: 'fakeFirstCredential',
|
||||
displayName: 'Fake First Credential',
|
||||
properties: [],
|
||||
},
|
||||
sourcePath: '',
|
||||
const mockNodesAndCredentials = mockInstance(LoadNodesAndCredentials, {
|
||||
loadedCredentials: {
|
||||
fakeFirstCredential: {
|
||||
type: {
|
||||
name: 'fakeFirstCredential',
|
||||
displayName: 'Fake First Credential',
|
||||
properties: [],
|
||||
},
|
||||
fakeSecondCredential: {
|
||||
type: {
|
||||
name: 'fakeSecondCredential',
|
||||
displayName: 'Fake Second Credential',
|
||||
properties: [],
|
||||
},
|
||||
sourcePath: '',
|
||||
sourcePath: '',
|
||||
},
|
||||
fakeSecondCredential: {
|
||||
type: {
|
||||
name: 'fakeSecondCredential',
|
||||
displayName: 'Fake Second Credential',
|
||||
properties: [],
|
||||
},
|
||||
sourcePath: '',
|
||||
},
|
||||
},
|
||||
known: { nodes: {}, credentials: {} },
|
||||
credentialTypes: {} as ICredentialTypes,
|
||||
};
|
||||
|
||||
Container.set(LoadNodesAndCredentials, mockNodesAndCredentials);
|
||||
});
|
||||
|
||||
const credentialTypes = Container.get(CredentialTypes);
|
||||
|
||||
@@ -39,7 +32,7 @@ describe('CredentialTypes', () => {
|
||||
});
|
||||
|
||||
test('Should return correct credential type for valid name', () => {
|
||||
const mockedCredentialTypes = mockNodesAndCredentials.loaded.credentials;
|
||||
const mockedCredentialTypes = mockNodesAndCredentials.loadedCredentials;
|
||||
expect(credentialTypes.getByName('fakeFirstCredential')).toStrictEqual(
|
||||
mockedCredentialTypes.fakeFirstCredential.type,
|
||||
);
|
||||
|
||||
@@ -2,68 +2,58 @@ import type {
|
||||
IAuthenticateGeneric,
|
||||
ICredentialDataDecryptedObject,
|
||||
ICredentialType,
|
||||
ICredentialTypes,
|
||||
IHttpRequestOptions,
|
||||
INode,
|
||||
INodeProperties,
|
||||
INodesAndCredentials,
|
||||
} from 'n8n-workflow';
|
||||
import { deepCopy } from 'n8n-workflow';
|
||||
import { Workflow } from 'n8n-workflow';
|
||||
import { CredentialsHelper } from '@/CredentialsHelper';
|
||||
import { CredentialTypes } from '@/CredentialTypes';
|
||||
import { Container } from 'typedi';
|
||||
import { NodeTypes } from '@/NodeTypes';
|
||||
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
|
||||
import { mockInstance } from '../integration/shared/utils';
|
||||
|
||||
describe('CredentialsHelper', () => {
|
||||
const TEST_ENCRYPTION_KEY = 'test';
|
||||
|
||||
const mockNodesAndCredentials: INodesAndCredentials = {
|
||||
loaded: {
|
||||
nodes: {
|
||||
'test.set': {
|
||||
sourcePath: '',
|
||||
type: {
|
||||
description: {
|
||||
displayName: 'Set',
|
||||
name: 'set',
|
||||
group: ['input'],
|
||||
version: 1,
|
||||
description: 'Sets a value',
|
||||
defaults: {
|
||||
name: 'Set',
|
||||
color: '#0000FF',
|
||||
},
|
||||
inputs: ['main'],
|
||||
outputs: ['main'],
|
||||
properties: [
|
||||
{
|
||||
displayName: 'Value1',
|
||||
name: 'value1',
|
||||
type: 'string',
|
||||
default: 'default-value1',
|
||||
},
|
||||
{
|
||||
displayName: 'Value2',
|
||||
name: 'value2',
|
||||
type: 'string',
|
||||
default: 'default-value2',
|
||||
},
|
||||
],
|
||||
const mockNodesAndCredentials = mockInstance(LoadNodesAndCredentials, {
|
||||
loadedNodes: {
|
||||
'test.set': {
|
||||
sourcePath: '',
|
||||
type: {
|
||||
description: {
|
||||
displayName: 'Set',
|
||||
name: 'set',
|
||||
group: ['input'],
|
||||
version: 1,
|
||||
description: 'Sets a value',
|
||||
defaults: {
|
||||
name: 'Set',
|
||||
color: '#0000FF',
|
||||
},
|
||||
inputs: ['main'],
|
||||
outputs: ['main'],
|
||||
properties: [
|
||||
{
|
||||
displayName: 'Value1',
|
||||
name: 'value1',
|
||||
type: 'string',
|
||||
default: 'default-value1',
|
||||
},
|
||||
{
|
||||
displayName: 'Value2',
|
||||
name: 'value2',
|
||||
type: 'string',
|
||||
default: 'default-value2',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
credentials: {},
|
||||
},
|
||||
known: { nodes: {}, credentials: {} },
|
||||
credentialTypes: {} as ICredentialTypes,
|
||||
};
|
||||
});
|
||||
|
||||
Container.set(LoadNodesAndCredentials, mockNodesAndCredentials);
|
||||
|
||||
const nodeTypes = Container.get(NodeTypes);
|
||||
const nodeTypes = mockInstance(NodeTypes);
|
||||
|
||||
describe('authenticate', () => {
|
||||
const tests: Array<{
|
||||
@@ -280,20 +270,14 @@ describe('CredentialsHelper', () => {
|
||||
|
||||
for (const testData of tests) {
|
||||
test(testData.description, async () => {
|
||||
mockNodesAndCredentials.loaded.credentials = {
|
||||
mockNodesAndCredentials.loadedCredentials = {
|
||||
[testData.input.credentialType.name]: {
|
||||
type: testData.input.credentialType,
|
||||
sourcePath: '',
|
||||
},
|
||||
};
|
||||
|
||||
const credentialTypes = Container.get(CredentialTypes);
|
||||
|
||||
const credentialsHelper = new CredentialsHelper(
|
||||
TEST_ENCRYPTION_KEY,
|
||||
credentialTypes,
|
||||
nodeTypes,
|
||||
);
|
||||
const credentialsHelper = new CredentialsHelper(TEST_ENCRYPTION_KEY);
|
||||
|
||||
const result = await credentialsHelper.authenticate(
|
||||
testData.input.credentials,
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { Container } from 'typedi';
|
||||
import type { ICredentialTypes, INodeTypes } from 'n8n-workflow';
|
||||
import { SubworkflowOperationError, Workflow } from 'n8n-workflow';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
import type { ILogger, INodeTypes } from 'n8n-workflow';
|
||||
import { LoggerProxy, SubworkflowOperationError, Workflow } from 'n8n-workflow';
|
||||
|
||||
import config from '@/config';
|
||||
import * as Db from '@/Db';
|
||||
@@ -14,35 +15,26 @@ import { UserService } from '@/services/user.service';
|
||||
import { PermissionChecker } from '@/UserManagement/PermissionChecker';
|
||||
import * as UserManagementHelper from '@/UserManagement/UserManagementHelper';
|
||||
import { WorkflowsService } from '@/workflows/workflows.services';
|
||||
import { OwnershipService } from '@/services/ownership.service';
|
||||
|
||||
import { mockInstance } from '../integration/shared/utils/';
|
||||
import {
|
||||
randomCredentialPayload as randomCred,
|
||||
randomPositiveDigit,
|
||||
} from '../integration/shared/random';
|
||||
import * as testDb from '../integration/shared/testDb';
|
||||
import { mockNodeTypesData } from './Helpers';
|
||||
import type { SaveCredentialFunction } from '../integration/shared/types';
|
||||
import { mockInstance } from '../integration/shared/utils/';
|
||||
import { OwnershipService } from '@/services/ownership.service';
|
||||
import { mockNodeTypesData } from './Helpers';
|
||||
|
||||
import { LoggerProxy } from 'n8n-workflow';
|
||||
import { getLogger } from '@/Logger';
|
||||
|
||||
LoggerProxy.init(getLogger());
|
||||
LoggerProxy.init(mock<ILogger>());
|
||||
|
||||
let mockNodeTypes: INodeTypes;
|
||||
let credentialOwnerRole: Role;
|
||||
let workflowOwnerRole: Role;
|
||||
let saveCredential: SaveCredentialFunction;
|
||||
|
||||
const MOCK_NODE_TYPES_DATA = mockNodeTypesData(['start', 'actionNetwork']);
|
||||
mockInstance(LoadNodesAndCredentials, {
|
||||
loaded: {
|
||||
nodes: MOCK_NODE_TYPES_DATA,
|
||||
credentials: {},
|
||||
},
|
||||
known: { nodes: {}, credentials: {} },
|
||||
credentialTypes: {} as ICredentialTypes,
|
||||
loadedNodes: mockNodeTypesData(['start', 'actionNetwork']),
|
||||
});
|
||||
|
||||
beforeAll(async () => {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { exec } from 'child_process';
|
||||
import { access as fsAccess, mkdir as fsMkdir } from 'fs/promises';
|
||||
|
||||
import axios from 'axios';
|
||||
import { mocked } from 'jest-mock';
|
||||
import Container from 'typedi';
|
||||
import type { PublicInstalledPackage } from 'n8n-workflow';
|
||||
|
||||
import {
|
||||
NODE_PACKAGE_PREFIX,
|
||||
@@ -9,22 +11,20 @@ import {
|
||||
NPM_PACKAGE_STATUS_GOOD,
|
||||
RESPONSE_ERROR_MESSAGES,
|
||||
} from '@/constants';
|
||||
import { InstalledPackages } from '@db/entities/InstalledPackages';
|
||||
import { randomName } from '../../integration/shared/random';
|
||||
import config from '@/config';
|
||||
import { mockInstance, mockPackageName, mockPackagePair } from '../../integration/shared/utils';
|
||||
import { mocked } from 'jest-mock';
|
||||
|
||||
import { InstalledPackages } from '@db/entities/InstalledPackages';
|
||||
import type { CommunityPackages } from '@/Interfaces';
|
||||
import { CommunityPackageService } from '@/services/communityPackage.service';
|
||||
import { CommunityPackagesService } from '@/services/communityPackages.service';
|
||||
import { InstalledNodesRepository, InstalledPackagesRepository } from '@/databases/repositories';
|
||||
import Container from 'typedi';
|
||||
import { InstalledNodes } from '@/databases/entities/InstalledNodes';
|
||||
import { LoadNodesAndCredentials } from '@/LoadNodesAndCredentials';
|
||||
|
||||
import {
|
||||
COMMUNITY_NODE_VERSION,
|
||||
COMMUNITY_PACKAGE_VERSION,
|
||||
} from '../../integration/shared/constants';
|
||||
import type { PublicInstalledPackage } from 'n8n-workflow';
|
||||
import { randomName } from '../../integration/shared/random';
|
||||
import { mockInstance, mockPackageName, mockPackagePair } from '../../integration/shared/utils';
|
||||
|
||||
jest.mock('fs/promises');
|
||||
jest.mock('child_process');
|
||||
@@ -38,10 +38,8 @@ const execMock = ((...args) => {
|
||||
cb(null, 'Done', '');
|
||||
}) as typeof exec;
|
||||
|
||||
describe('CommunityPackageService', () => {
|
||||
describe('CommunityPackagesService', () => {
|
||||
const installedNodesRepository = mockInstance(InstalledNodesRepository);
|
||||
Container.set(InstalledNodesRepository, installedNodesRepository);
|
||||
|
||||
installedNodesRepository.create.mockImplementation(() => {
|
||||
const nodeName = randomName();
|
||||
|
||||
@@ -54,7 +52,6 @@ describe('CommunityPackageService', () => {
|
||||
});
|
||||
|
||||
const installedPackageRepository = mockInstance(InstalledPackagesRepository);
|
||||
|
||||
installedPackageRepository.create.mockImplementation(() => {
|
||||
return Object.assign(new InstalledPackages(), {
|
||||
packageName: mockPackageName(),
|
||||
@@ -62,7 +59,9 @@ describe('CommunityPackageService', () => {
|
||||
});
|
||||
});
|
||||
|
||||
const communityPackageService = new CommunityPackageService(installedPackageRepository);
|
||||
mockInstance(LoadNodesAndCredentials);
|
||||
|
||||
const communityPackagesService = Container.get(CommunityPackagesService);
|
||||
|
||||
beforeEach(() => {
|
||||
config.load(config.default);
|
||||
@@ -70,18 +69,18 @@ describe('CommunityPackageService', () => {
|
||||
|
||||
describe('parseNpmPackageName()', () => {
|
||||
test('should fail with empty package name', () => {
|
||||
expect(() => communityPackageService.parseNpmPackageName('')).toThrowError();
|
||||
expect(() => communityPackagesService.parseNpmPackageName('')).toThrowError();
|
||||
});
|
||||
|
||||
test('should fail with invalid package prefix name', () => {
|
||||
expect(() =>
|
||||
communityPackageService.parseNpmPackageName('INVALID_PREFIX@123'),
|
||||
communityPackagesService.parseNpmPackageName('INVALID_PREFIX@123'),
|
||||
).toThrowError();
|
||||
});
|
||||
|
||||
test('should parse valid package name', () => {
|
||||
const name = mockPackageName();
|
||||
const parsed = communityPackageService.parseNpmPackageName(name);
|
||||
const parsed = communityPackagesService.parseNpmPackageName(name);
|
||||
|
||||
expect(parsed.rawString).toBe(name);
|
||||
expect(parsed.packageName).toBe(name);
|
||||
@@ -93,7 +92,7 @@ describe('CommunityPackageService', () => {
|
||||
const name = mockPackageName();
|
||||
const version = '0.1.1';
|
||||
const fullPackageName = `${name}@${version}`;
|
||||
const parsed = communityPackageService.parseNpmPackageName(fullPackageName);
|
||||
const parsed = communityPackagesService.parseNpmPackageName(fullPackageName);
|
||||
|
||||
expect(parsed.rawString).toBe(fullPackageName);
|
||||
expect(parsed.packageName).toBe(name);
|
||||
@@ -106,7 +105,7 @@ describe('CommunityPackageService', () => {
|
||||
const name = mockPackageName();
|
||||
const version = '0.1.1';
|
||||
const fullPackageName = `${scope}/${name}@${version}`;
|
||||
const parsed = communityPackageService.parseNpmPackageName(fullPackageName);
|
||||
const parsed = communityPackagesService.parseNpmPackageName(fullPackageName);
|
||||
|
||||
expect(parsed.rawString).toBe(fullPackageName);
|
||||
expect(parsed.packageName).toBe(`${scope}/${name}`);
|
||||
@@ -134,7 +133,7 @@ describe('CommunityPackageService', () => {
|
||||
|
||||
mocked(exec).mockImplementation(execMock);
|
||||
|
||||
await communityPackageService.executeNpmCommand('ls');
|
||||
await communityPackagesService.executeNpmCommand('ls');
|
||||
|
||||
expect(fsAccess).toHaveBeenCalled();
|
||||
expect(exec).toHaveBeenCalled();
|
||||
@@ -144,7 +143,7 @@ describe('CommunityPackageService', () => {
|
||||
test('should make sure folder exists', async () => {
|
||||
mocked(exec).mockImplementation(execMock);
|
||||
|
||||
await communityPackageService.executeNpmCommand('ls');
|
||||
await communityPackagesService.executeNpmCommand('ls');
|
||||
expect(fsAccess).toHaveBeenCalled();
|
||||
expect(exec).toHaveBeenCalled();
|
||||
expect(fsMkdir).toBeCalledTimes(0);
|
||||
@@ -156,7 +155,7 @@ describe('CommunityPackageService', () => {
|
||||
throw new Error('Folder does not exist.');
|
||||
});
|
||||
|
||||
await communityPackageService.executeNpmCommand('ls');
|
||||
await communityPackagesService.executeNpmCommand('ls');
|
||||
|
||||
expect(fsAccess).toHaveBeenCalled();
|
||||
expect(exec).toHaveBeenCalled();
|
||||
@@ -172,7 +171,7 @@ describe('CommunityPackageService', () => {
|
||||
|
||||
mocked(exec).mockImplementation(erroringExecMock);
|
||||
|
||||
const call = async () => communityPackageService.executeNpmCommand('ls');
|
||||
const call = async () => communityPackagesService.executeNpmCommand('ls');
|
||||
|
||||
await expect(call).rejects.toThrowError(RESPONSE_ERROR_MESSAGES.PACKAGE_NOT_FOUND);
|
||||
|
||||
@@ -186,7 +185,7 @@ describe('CommunityPackageService', () => {
|
||||
test('should return same list if availableUpdates is undefined', () => {
|
||||
const fakePkgs = mockPackagePair();
|
||||
|
||||
const crossedPkgs = communityPackageService.matchPackagesWithUpdates(fakePkgs);
|
||||
const crossedPkgs = communityPackagesService.matchPackagesWithUpdates(fakePkgs);
|
||||
|
||||
expect(crossedPkgs).toEqual(fakePkgs);
|
||||
});
|
||||
@@ -210,7 +209,7 @@ describe('CommunityPackageService', () => {
|
||||
};
|
||||
|
||||
const [crossedPkgA, crossedPkgB]: PublicInstalledPackage[] =
|
||||
communityPackageService.matchPackagesWithUpdates([pkgA, pkgB], updates);
|
||||
communityPackagesService.matchPackagesWithUpdates([pkgA, pkgB], updates);
|
||||
|
||||
expect(crossedPkgA.updateAvailable).toBe('0.2.0');
|
||||
expect(crossedPkgB.updateAvailable).toBe('0.3.0');
|
||||
@@ -229,7 +228,7 @@ describe('CommunityPackageService', () => {
|
||||
};
|
||||
|
||||
const [crossedPkgA, crossedPkgB]: PublicInstalledPackage[] =
|
||||
communityPackageService.matchPackagesWithUpdates([pkgA, pkgB], updates);
|
||||
communityPackagesService.matchPackagesWithUpdates([pkgA, pkgB], updates);
|
||||
|
||||
expect(crossedPkgA.updateAvailable).toBeUndefined();
|
||||
expect(crossedPkgB.updateAvailable).toBe('0.3.0');
|
||||
@@ -239,12 +238,12 @@ describe('CommunityPackageService', () => {
|
||||
describe('matchMissingPackages()', () => {
|
||||
test('should not match failed packages that do not exist', () => {
|
||||
const fakePkgs = mockPackagePair();
|
||||
const notFoundPkgNames = `${NODE_PACKAGE_PREFIX}very-long-name-that-should-never-be-generated@1.0.0 ${NODE_PACKAGE_PREFIX}another-very-long-name-that-never-is-seen`;
|
||||
setMissingPackages([
|
||||
`${NODE_PACKAGE_PREFIX}very-long-name-that-should-never-be-generated@1.0.0`,
|
||||
`${NODE_PACKAGE_PREFIX}another-very-long-name-that-never-is-seen`,
|
||||
]);
|
||||
|
||||
const matchedPackages = communityPackageService.matchMissingPackages(
|
||||
fakePkgs,
|
||||
notFoundPkgNames,
|
||||
);
|
||||
const matchedPackages = communityPackagesService.matchMissingPackages(fakePkgs);
|
||||
|
||||
expect(matchedPackages).toEqual(fakePkgs);
|
||||
|
||||
@@ -256,12 +255,15 @@ describe('CommunityPackageService', () => {
|
||||
|
||||
test('should match failed packages that should be present', () => {
|
||||
const [pkgA, pkgB] = mockPackagePair();
|
||||
const notFoundPkgNames = `${NODE_PACKAGE_PREFIX}very-long-name-that-should-never-be-generated@1.0.0 ${pkgA.packageName}@${pkgA.installedVersion}`;
|
||||
setMissingPackages([
|
||||
`${NODE_PACKAGE_PREFIX}very-long-name-that-should-never-be-generated@1.0.0`,
|
||||
`${pkgA.packageName}@${pkgA.installedVersion}`,
|
||||
]);
|
||||
|
||||
const [matchedPkgA, matchedPkgB] = communityPackageService.matchMissingPackages(
|
||||
[pkgA, pkgB],
|
||||
notFoundPkgNames,
|
||||
);
|
||||
const [matchedPkgA, matchedPkgB] = communityPackagesService.matchMissingPackages([
|
||||
pkgA,
|
||||
pkgB,
|
||||
]);
|
||||
|
||||
expect(matchedPkgA.failedLoading).toBe(true);
|
||||
expect(matchedPkgB.failedLoading).toBeUndefined();
|
||||
@@ -269,11 +271,14 @@ describe('CommunityPackageService', () => {
|
||||
|
||||
test('should match failed packages even if version is wrong', () => {
|
||||
const [pkgA, pkgB] = mockPackagePair();
|
||||
const notFoundPackageList = `${NODE_PACKAGE_PREFIX}very-long-name-that-should-never-be-generated@1.0.0 ${pkgA.packageName}@123.456.789`;
|
||||
const [matchedPkgA, matchedPkgB] = communityPackageService.matchMissingPackages(
|
||||
[pkgA, pkgB],
|
||||
notFoundPackageList,
|
||||
);
|
||||
setMissingPackages([
|
||||
`${NODE_PACKAGE_PREFIX}very-long-name-that-should-never-be-generated@1.0.0`,
|
||||
`${pkgA.packageName}@123.456.789`,
|
||||
]);
|
||||
const [matchedPkgA, matchedPkgB] = communityPackagesService.matchMissingPackages([
|
||||
pkgA,
|
||||
pkgB,
|
||||
]);
|
||||
|
||||
expect(matchedPkgA.failedLoading).toBe(true);
|
||||
expect(matchedPkgB.failedLoading).toBeUndefined();
|
||||
@@ -282,7 +287,7 @@ describe('CommunityPackageService', () => {
|
||||
|
||||
describe('checkNpmPackageStatus()', () => {
|
||||
test('should call axios.post', async () => {
|
||||
await communityPackageService.checkNpmPackageStatus(mockPackageName());
|
||||
await communityPackagesService.checkNpmPackageStatus(mockPackageName());
|
||||
|
||||
expect(axios.post).toHaveBeenCalled();
|
||||
});
|
||||
@@ -292,7 +297,7 @@ describe('CommunityPackageService', () => {
|
||||
throw new Error('Something went wrong');
|
||||
});
|
||||
|
||||
const result = await communityPackageService.checkNpmPackageStatus(mockPackageName());
|
||||
const result = await communityPackagesService.checkNpmPackageStatus(mockPackageName());
|
||||
|
||||
expect(result.status).toBe(NPM_PACKAGE_STATUS_GOOD);
|
||||
});
|
||||
@@ -300,7 +305,7 @@ describe('CommunityPackageService', () => {
|
||||
test('should warn if package is banned', async () => {
|
||||
mocked(axios.post).mockResolvedValue({ data: { status: 'Banned', reason: 'Not good' } });
|
||||
|
||||
const result = (await communityPackageService.checkNpmPackageStatus(
|
||||
const result = (await communityPackagesService.checkNpmPackageStatus(
|
||||
mockPackageName(),
|
||||
)) as CommunityPackages.PackageStatusCheck;
|
||||
|
||||
@@ -311,47 +316,50 @@ describe('CommunityPackageService', () => {
|
||||
|
||||
describe('hasPackageLoadedSuccessfully()', () => {
|
||||
test('should return true when failed package list does not exist', () => {
|
||||
config.set<string>('nodes.packagesMissing', undefined);
|
||||
|
||||
expect(communityPackageService.hasPackageLoaded('package')).toBe(true);
|
||||
setMissingPackages([]);
|
||||
expect(communityPackagesService.hasPackageLoaded('package')).toBe(true);
|
||||
});
|
||||
|
||||
test('should return true when package is not in the list of missing packages', () => {
|
||||
config.set('nodes.packagesMissing', 'packageA@0.1.0 packageB@0.1.0');
|
||||
|
||||
expect(communityPackageService.hasPackageLoaded('packageC')).toBe(true);
|
||||
setMissingPackages(['packageA@0.1.0', 'packageB@0.1.0']);
|
||||
expect(communityPackagesService.hasPackageLoaded('packageC')).toBe(true);
|
||||
});
|
||||
|
||||
test('should return false when package is in the list of missing packages', () => {
|
||||
config.set('nodes.packagesMissing', 'packageA@0.1.0 packageB@0.1.0');
|
||||
|
||||
expect(communityPackageService.hasPackageLoaded('packageA')).toBe(false);
|
||||
setMissingPackages(['packageA@0.1.0', 'packageB@0.1.0']);
|
||||
expect(communityPackagesService.hasPackageLoaded('packageA')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('removePackageFromMissingList()', () => {
|
||||
test('should do nothing if key does not exist', () => {
|
||||
config.set<string>('nodes.packagesMissing', undefined);
|
||||
setMissingPackages([]);
|
||||
communityPackagesService.removePackageFromMissingList('packageA');
|
||||
|
||||
communityPackageService.removePackageFromMissingList('packageA');
|
||||
|
||||
expect(config.get('nodes.packagesMissing')).toBeUndefined();
|
||||
expect(communityPackagesService.missingPackages).toBeEmptyArray();
|
||||
});
|
||||
|
||||
test('should remove only correct package from list', () => {
|
||||
config.set('nodes.packagesMissing', 'packageA@0.1.0 packageB@0.2.0 packageC@0.2.0');
|
||||
setMissingPackages(['packageA@0.1.0', 'packageB@0.2.0', 'packageC@0.2.0']);
|
||||
|
||||
communityPackageService.removePackageFromMissingList('packageB');
|
||||
communityPackagesService.removePackageFromMissingList('packageB');
|
||||
|
||||
expect(config.get('nodes.packagesMissing')).toBe('packageA@0.1.0 packageC@0.2.0');
|
||||
expect(communityPackagesService.missingPackages).toEqual([
|
||||
'packageA@0.1.0',
|
||||
'packageC@0.2.0',
|
||||
]);
|
||||
});
|
||||
|
||||
test('should not remove if package is not in the list', () => {
|
||||
const failedToLoadList = 'packageA@0.1.0 packageB@0.2.0 packageB@0.2.0';
|
||||
config.set('nodes.packagesMissing', failedToLoadList);
|
||||
communityPackageService.removePackageFromMissingList('packageC');
|
||||
const failedToLoadList = ['packageA@0.1.0', 'packageB@0.2.0', 'packageB@0.2.0'];
|
||||
setMissingPackages(failedToLoadList);
|
||||
communityPackagesService.removePackageFromMissingList('packageC');
|
||||
|
||||
expect(config.get('nodes.packagesMissing')).toBe(failedToLoadList);
|
||||
expect(communityPackagesService.missingPackages).toEqual(failedToLoadList);
|
||||
});
|
||||
});
|
||||
|
||||
const setMissingPackages = (missingPackages: string[]) => {
|
||||
Object.assign(communityPackagesService, { missingPackages });
|
||||
};
|
||||
});
|
||||
Reference in New Issue
Block a user