Преглед изворни кода

test(core): Add e2e tests for ErrorHandlerStrategy

Michael Bromley пре 2 година
родитељ
комит
c32b854a93

+ 147 - 0
packages/core/e2e/error-handler-strategy.e2e-spec.ts

@@ -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',
+        });
+    });
+});

+ 1 - 1
packages/core/src/config/system/error-handler-strategy.ts

@@ -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