refactor(core): Move license endpoints to a decorated controller class (no-changelog) (#8074)

This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2023-12-19 12:13:19 +01:00
committed by GitHub
parent 63a6e7e034
commit a63d94f28c
13 changed files with 224 additions and 193 deletions

View File

@@ -60,7 +60,7 @@ describe('POST /license/activate', () => {
await authMemberAgent
.post('/license/activate')
.send({ activationKey: 'abcde' })
.expect(403, { code: 403, message: NON_OWNER_ACTIVATE_RENEW_MESSAGE });
.expect(403, UNAUTHORIZED_RESPONSE);
});
test('errors out properly', async () => {
@@ -82,19 +82,17 @@ describe('POST /license/renew', () => {
});
test('does not work for regular users', async () => {
await authMemberAgent
.post('/license/renew')
.expect(403, { code: 403, message: NON_OWNER_ACTIVATE_RENEW_MESSAGE });
await authMemberAgent.post('/license/renew').expect(403, UNAUTHORIZED_RESPONSE);
});
test('errors out properly', async () => {
License.prototype.renew = jest.fn().mockImplementation(() => {
throw new Error(RENEW_ERROR_MESSAGE);
throw new Error(GENERIC_ERROR_MESSAGE);
});
await authOwnerAgent
.post('/license/renew')
.expect(400, { code: 400, message: RENEW_ERROR_MESSAGE });
.expect(400, { code: 400, message: `Failed to renew license: ${GENERIC_ERROR_MESSAGE}` });
});
});
@@ -131,6 +129,6 @@ const DEFAULT_POST_RESPONSE: { data: ILicensePostResponse } = {
},
};
const NON_OWNER_ACTIVATE_RENEW_MESSAGE = 'Only an instance owner may activate or renew a license';
const UNAUTHORIZED_RESPONSE = { status: 'error', message: 'Unauthorized' };
const ACTIVATION_FAILED_MESSAGE = 'Failed to activate license';
const RENEW_ERROR_MESSAGE = 'Something went wrong when trying to renew license';
const GENERIC_ERROR_MESSAGE = 'Something went wrong';

View File

@@ -144,8 +144,8 @@ export const setupTestServer = ({
break;
case 'license':
const { licenseController } = await import('@/license/license.controller');
app.use(`/${REST_PATH_SEGMENT}/license`, licenseController);
const { LicenseController } = await import('@/license/license.controller');
registerController(app, config, Container.get(LicenseController));
break;
case 'metrics':

View File

@@ -28,7 +28,7 @@ describe('License', () => {
let license: License;
const logger = mockInstance(Logger);
const instanceSettings = mockInstance(InstanceSettings, { instanceId: MOCK_INSTANCE_ID });
const multiMainSetup = mockInstance(MultiMainSetup);
mockInstance(MultiMainSetup);
beforeEach(async () => {
license = new License(logger, instanceSettings, mock(), mock(), mock());
@@ -85,20 +85,20 @@ describe('License', () => {
expect(LicenseManager.prototype.renew).toHaveBeenCalled();
});
test('check if feature is enabled', async () => {
await license.isFeatureEnabled(MOCK_FEATURE_FLAG);
test('check if feature is enabled', () => {
license.isFeatureEnabled(MOCK_FEATURE_FLAG);
expect(LicenseManager.prototype.hasFeatureEnabled).toHaveBeenCalledWith(MOCK_FEATURE_FLAG);
});
test('check if sharing feature is enabled', async () => {
await license.isFeatureEnabled(MOCK_FEATURE_FLAG);
test('check if sharing feature is enabled', () => {
license.isFeatureEnabled(MOCK_FEATURE_FLAG);
expect(LicenseManager.prototype.hasFeatureEnabled).toHaveBeenCalledWith(MOCK_FEATURE_FLAG);
});
test('check fetching entitlements', async () => {
await license.getCurrentEntitlements();
test('check fetching entitlements', () => {
license.getCurrentEntitlements();
expect(LicenseManager.prototype.getCurrentEntitlements).toHaveBeenCalled();
});
@@ -110,7 +110,7 @@ describe('License', () => {
});
test('check management jwt', async () => {
await license.getManagementJwt();
license.getManagementJwt();
expect(LicenseManager.prototype.getManagementJwt).toHaveBeenCalled();
});

View File

@@ -8,13 +8,6 @@ import { InstanceSettings } from 'n8n-core';
import { mockInstance } from '../shared/mocking';
jest.unmock('@/telemetry');
jest.mock('@/license/License.service', () => {
return {
LicenseService: {
getActiveTriggerCount: async () => 0,
},
};
});
jest.mock('@/posthog');
describe('Telemetry', () => {

View File

@@ -0,0 +1,76 @@
import { LicenseErrors, LicenseService } from '@/license/license.service';
import type { License } from '@/License';
import type { InternalHooks } from '@/InternalHooks';
import type { WorkflowRepository } from '@db/repositories/workflow.repository';
import type { TEntitlement } from '@n8n_io/license-sdk';
import { mock } from 'jest-mock-extended';
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
describe('LicenseService', () => {
const license = mock<License>();
const internalHooks = mock<InternalHooks>();
const workflowRepository = mock<WorkflowRepository>();
const entitlement = mock<TEntitlement>({ productId: '123' });
const licenseService = new LicenseService(mock(), license, internalHooks, workflowRepository);
license.getMainPlan.mockReturnValue(entitlement);
license.getTriggerLimit.mockReturnValue(400);
license.getPlanName.mockReturnValue('Test Plan');
workflowRepository.getActiveTriggerCount.mockResolvedValue(7);
beforeEach(() => jest.clearAllMocks());
class LicenseError extends Error {
constructor(readonly errorId: string) {
super(`License error: ${errorId}`);
}
}
describe('getLicenseData', () => {
it('should return usage and license data', async () => {
const data = await licenseService.getLicenseData();
expect(data).toEqual({
usage: {
executions: {
limit: 400,
value: 7,
warningThreshold: 0.8,
},
},
license: {
planId: '123',
planName: 'Test Plan',
},
});
});
});
describe('activateLicense', () => {
Object.entries(LicenseErrors).forEach(([errorId, message]) =>
it(`should handle ${errorId} error`, async () => {
license.activate.mockRejectedValueOnce(new LicenseError(errorId));
await expect(licenseService.activateLicense('')).rejects.toThrowError(
new BadRequestError(message),
);
}),
);
});
describe('renewLicense', () => {
test('on success', async () => {
license.renew.mockResolvedValueOnce();
await licenseService.renewLicense();
expect(internalHooks.onLicenseRenewAttempt).toHaveBeenCalledWith({ success: true });
});
test('on failure', async () => {
license.renew.mockRejectedValueOnce(new LicenseError('RESERVATION_EXPIRED'));
await expect(licenseService.renewLicense()).rejects.toThrowError(
new BadRequestError('Activation key has expired'),
);
expect(internalHooks.onLicenseRenewAttempt).toHaveBeenCalledWith({ success: false });
});
});
});