Skip to content

Commit

Permalink
test(core): Add e2e tests for ErrorHandlerStrategy
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelbromley committed Jan 18, 2024
1 parent 82ddf94 commit c32b854
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 1 deletion.
147 changes: 147 additions & 0 deletions packages/core/e2e/error-handler-strategy.e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import { ArgumentsHost, OnApplicationBootstrap } from '@nestjs/common';
import { Mutation, Resolver } from '@nestjs/graphql';
import {
mergeConfig,
Job,
ErrorHandlerStrategy,
VendurePlugin,
PluginCommonModule,
JobQueueService,
JobQueue,
} from '@vendure/core';
import { createTestEnvironment } from '@vendure/testing';
import gql from 'graphql-tag';
import path from 'path';
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';

import { initialData } from '../../../e2e-common/e2e-initial-data';
import { TEST_SETUP_TIMEOUT_MS, testConfig } from '../../../e2e-common/test-config';

import { awaitRunningJobs } from './utils/await-running-jobs';

class TestErrorHandlerStrategy implements ErrorHandlerStrategy {
static serverErrorSpy = vi.fn();
static workerErrorSpy = vi.fn();

handleServerError(exception: Error, context: { host: ArgumentsHost }) {
TestErrorHandlerStrategy.serverErrorSpy(exception, context);
}

handleWorkerError(exception: Error, context: { job: Job }) {
TestErrorHandlerStrategy.workerErrorSpy(exception, context);
}
}

@Resolver()
class TestResolver implements OnApplicationBootstrap {
private queue: JobQueue<any>;
constructor(private jobQueueService: JobQueueService) {}

async onApplicationBootstrap() {
this.queue = await this.jobQueueService.createQueue({
name: 'test-queue',
process: async () => {
throw new Error('worker error');
},
});
}

@Mutation()
createServerError() {
throw new Error('server error');
}

@Mutation()
createWorkerError() {
return this.queue.add({});
}
}

@VendurePlugin({
imports: [PluginCommonModule],
adminApiExtensions: {
schema: gql`
extend type Mutation {
createServerError: Boolean!
createWorkerError: Job!
}
`,
resolvers: [TestResolver],
},
})
class TestErrorMakingPlugin {}

describe('ErrorHandlerStrategy', () => {
const { server, adminClient, shopClient } = createTestEnvironment(
mergeConfig(testConfig(), {
systemOptions: {
errorHandlers: [new TestErrorHandlerStrategy()],
},
plugins: [TestErrorMakingPlugin],
}),
);

beforeAll(async () => {
await server.init({
initialData,
productsCsvPath: path.join(__dirname, 'fixtures/e2e-products-minimal.csv'),
customerCount: 1,
});
await adminClient.asSuperAdmin();
}, TEST_SETUP_TIMEOUT_MS);

beforeEach(() => {
TestErrorHandlerStrategy.serverErrorSpy.mockClear();
TestErrorHandlerStrategy.workerErrorSpy.mockClear();
});

afterAll(async () => {
await server.destroy();
});

it('no error handlers have initially been called', async () => {
expect(TestErrorHandlerStrategy.serverErrorSpy).toHaveBeenCalledTimes(0);
expect(TestErrorHandlerStrategy.workerErrorSpy).toHaveBeenCalledTimes(0);
});

it('invokes the server handler', async () => {
try {
await adminClient.query(
gql`
mutation {
createServerError
}
`,
);
} catch (e: any) {
expect(e.message).toBe('server error');
}
expect(TestErrorHandlerStrategy.serverErrorSpy).toHaveBeenCalledTimes(1);
expect(TestErrorHandlerStrategy.workerErrorSpy).toHaveBeenCalledTimes(0);

expect(TestErrorHandlerStrategy.serverErrorSpy.mock.calls[0][0]).toBeInstanceOf(Error);
expect(TestErrorHandlerStrategy.serverErrorSpy.mock.calls[0][0].message).toBe('server error');
expect(TestErrorHandlerStrategy.serverErrorSpy.mock.calls[0][1].host).toBeDefined();
});

it('invokes the worker handler', async () => {
await adminClient.query(
gql`
mutation {
createWorkerError {
id
}
}
`,
);
await awaitRunningJobs(adminClient);
expect(TestErrorHandlerStrategy.serverErrorSpy).toHaveBeenCalledTimes(0);
expect(TestErrorHandlerStrategy.workerErrorSpy).toHaveBeenCalledTimes(1);

expect(TestErrorHandlerStrategy.workerErrorSpy.mock.calls[0][0]).toBeInstanceOf(Error);
expect(TestErrorHandlerStrategy.workerErrorSpy.mock.calls[0][0].message).toBe('worker error');
expect(TestErrorHandlerStrategy.workerErrorSpy.mock.calls[0][1].job).toContain({
queueName: 'test-queue',
});
});
});
2 changes: 1 addition & 1 deletion packages/core/src/config/system/error-handler-strategy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ArgumentsHost } from '@nestjs/common';

import { InjectableStrategy } from '../../common/index';
import { Job } from '../../job-queue/index';
import { Job } from '../../job-queue/job';

/**
* @description
Expand Down

0 comments on commit c32b854

Please sign in to comment.