n8n/packages/cli/test/unit/services/test-webhook-registrations.service.test.ts
Iván Ovejero f53c482939
perf(core): Improve caching service (#8213)
Story: https://linear.app/n8n/issue/PAY-1188

- Implement Redis hashes on the caching service, based on Micha's work
in #7747, adapted from `node-cache-manager-ioredis-yet`. Optimize
workflow ownership lookups and manual webhook lookups with Redis hashes.
- Simplify the caching service by removing all currently unused methods
and options: `enable`, `disable`, `getCache`, `keys`, `keyValues`,
`refreshFunctionEach`, `refreshFunctionMany`, `refreshTtl`, etc.
- Remove the flag `N8N_CACHE_ENABLED`. Currently some features on
`master` are broken with caching disabled, and test webhooks now rely
entirely on caching, for multi-main setup support. We originally
introduced this flag to protect against excessive memory usage, but
total cache usage is low enough that we decided to drop this setting.
Apparently this flag was also never documented.
- Overall caching service refactor: use generics, reduce branching, add
discriminants for cache kinds for better type safety, type caching
events, improve readability, remove outdated docs, etc. Also refactor
and expand caching service tests.

Follow-up to: https://github.com/n8n-io/n8n/pull/8176

---------

Co-authored-by: Michael Auerswald <michael.auerswald@gmail.com>
2024-01-05 11:52:44 +01:00

89 lines
2.8 KiB
TypeScript

import type { CacheService } from '@/services/cache/cache.service';
import type { TestWebhookRegistration } from '@/services/test-webhook-registrations.service';
import { TestWebhookRegistrationsService } from '@/services/test-webhook-registrations.service';
import { mock } from 'jest-mock-extended';
describe('TestWebhookRegistrationsService', () => {
const cacheService = mock<CacheService>();
const registrations = new TestWebhookRegistrationsService(cacheService);
const registration = mock<TestWebhookRegistration>({
webhook: { httpMethod: 'GET', path: 'hello', webhookId: undefined },
});
const webhookKey = 'GET|hello';
const cacheKey = 'test-webhooks';
describe('register()', () => {
test('should register a test webhook registration', async () => {
await registrations.register(registration);
expect(cacheService.setHash).toHaveBeenCalledWith(cacheKey, { [webhookKey]: registration });
});
});
describe('deregister()', () => {
test('should deregister a test webhook registration', async () => {
await registrations.register(registration);
await registrations.deregister(webhookKey);
expect(cacheService.deleteFromHash).toHaveBeenCalledWith(cacheKey, webhookKey);
});
});
describe('get()', () => {
test('should retrieve a test webhook registration', async () => {
cacheService.getHashValue.mockResolvedValueOnce(registration);
const promise = registrations.get(webhookKey);
await expect(promise).resolves.toBe(registration);
});
test('should return undefined if no such test webhook registration was found', async () => {
cacheService.getHashValue.mockResolvedValueOnce(undefined);
const promise = registrations.get(webhookKey);
await expect(promise).resolves.toBeUndefined();
});
});
describe('getAllKeys()', () => {
test('should retrieve all test webhook registration keys', async () => {
cacheService.getHash.mockResolvedValueOnce({ [webhookKey]: registration });
const result = await registrations.getAllKeys();
expect(result).toEqual([webhookKey]);
});
});
describe('getAllRegistrations()', () => {
test('should retrieve all test webhook registrations', async () => {
cacheService.getHash.mockResolvedValueOnce({ [webhookKey]: registration });
const result = await registrations.getAllRegistrations();
expect(result).toEqual([registration]);
});
});
describe('deregisterAll()', () => {
test('should deregister all test webhook registrations', async () => {
await registrations.deregisterAll();
expect(cacheService.delete).toHaveBeenCalledWith(cacheKey);
});
});
describe('toKey()', () => {
test('should convert a test webhook registration to a key', () => {
const result = registrations.toKey(registration.webhook);
expect(result).toBe(webhookKey);
});
});
});