Browse Source

fix(email-plugin): Only call `loadData()` function after filters run

Fixes #518
Michael Bromley 5 years ago
parent
commit
e22db7e2e0

+ 8 - 0
packages/email-plugin/src/event-handler.ts

@@ -1,5 +1,6 @@
 import { LanguageCode } from '@vendure/common/lib/generated-types';
 import { Type } from '@vendure/common/lib/shared-types';
+import { Injector } from '@vendure/core';
 
 import { EmailEventListener, EmailTemplateConfig, SetTemplateVarsFn } from './event-listener';
 import { EventWithAsyncData, EventWithContext, IntermediateEmailDetails, LoadDataFn } from './types';
@@ -169,12 +170,19 @@ export class EmailEventHandler<T extends string = string, Event extends EventWit
     async handle(
         event: Event,
         globals: { [key: string]: any } = {},
+        injector: Injector,
     ): Promise<IntermediateEmailDetails | undefined> {
         for (const filterFn of this.filterFns) {
             if (!filterFn(event)) {
                 return;
             }
         }
+        if (this instanceof EmailEventHandlerWithAsyncData) {
+            (event as EventWithAsyncData<Event, any>).data = await this._loadDataFn({
+                event,
+                injector,
+            });
+        }
         if (!this.setRecipientFn) {
             throw new Error(
                 `No setRecipientFn has been defined. ` +

+ 18 - 0
packages/email-plugin/src/plugin.spec.ts

@@ -421,6 +421,24 @@ describe('EmailPlugin', () => {
             expect(onSend.mock.calls[0][0].from).toBe('"test from" <noreply@test.com>');
             expect(onSend.mock.calls[0][0].recipient).toBe('test@test.com');
         });
+
+        it('only executes for filtered events', async () => {
+            let callCount = 0;
+            const handler = new EmailEventListener('test')
+                .on(MockEvent)
+                .filter(event => event.shouldSend === true)
+                .loadData(async ({ injector }) => {
+                    callCount++;
+                });
+
+            await initPluginWithHandlers([handler]);
+
+            eventBus.publish(new MockEvent(RequestContext.empty(), false));
+            eventBus.publish(new MockEvent(RequestContext.empty(), true));
+            await pause();
+
+            expect(callCount).toBe(1);
+        });
     });
 
     describe('orderConfirmationHandler', () => {

+ 6 - 8
packages/email-plugin/src/plugin.ts

@@ -233,14 +233,12 @@ export class EmailPlugin implements OnVendureBootstrap, OnVendureClose {
         Logger.debug(`Handling event "${handler.type}"`, 'EmailPlugin');
         const { type } = handler;
         try {
-            if (handler instanceof EmailEventHandlerWithAsyncData) {
-                const injector = new Injector(this.moduleRef);
-                (event as EventWithAsyncData<EventWithContext, any>).data = await handler._loadDataFn({
-                    event,
-                    injector,
-                });
-            }
-            const result = await handler.handle(event as any, EmailPlugin.options.globalTemplateVars);
+            const injector = new Injector(this.moduleRef);
+            const result = await handler.handle(
+                event as any,
+                EmailPlugin.options.globalTemplateVars,
+                injector,
+            );
             if (!result) {
                 return;
             }