@flusys/nestjs-email 6.0.2 → 6.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/cjs/controllers/email-config.controller.spec.js +85 -0
  2. package/cjs/controllers/email-send.controller.spec.js +139 -0
  3. package/cjs/controllers/email-template.controller.spec.js +89 -0
  4. package/cjs/docs/email-swagger.config.spec.js +62 -0
  5. package/cjs/entities/index.spec.js +18 -0
  6. package/cjs/modules/email.module.spec.js +142 -0
  7. package/cjs/providers/email-factory.service.spec.js +242 -0
  8. package/cjs/providers/email-provider.registry.spec.js +58 -0
  9. package/cjs/providers/mailgun-provider.spec.js +244 -0
  10. package/cjs/providers/sendgrid-provider.spec.js +346 -0
  11. package/cjs/providers/smtp-provider.js +12 -5
  12. package/cjs/providers/smtp-provider.spec.js +327 -0
  13. package/cjs/services/email-config.service.spec.js +69 -0
  14. package/cjs/services/email-datasource.provider.spec.js +135 -0
  15. package/cjs/services/email-provider-config.service.spec.js +247 -0
  16. package/cjs/services/email-send.service.spec.js +546 -0
  17. package/cjs/services/email-template.service.spec.js +257 -0
  18. package/cjs/utils/email-templates.util.spec.js +61 -0
  19. package/fesm/controllers/email-config.controller.spec.js +81 -0
  20. package/fesm/controllers/email-send.controller.spec.js +135 -0
  21. package/fesm/controllers/email-template.controller.spec.js +85 -0
  22. package/fesm/docs/email-swagger.config.spec.js +58 -0
  23. package/fesm/entities/index.spec.js +14 -0
  24. package/fesm/modules/email.module.spec.js +138 -0
  25. package/fesm/providers/email-factory.service.spec.js +238 -0
  26. package/fesm/providers/email-provider.registry.spec.js +54 -0
  27. package/fesm/providers/mailgun-provider.spec.js +240 -0
  28. package/fesm/providers/sendgrid-provider.spec.js +342 -0
  29. package/fesm/providers/smtp-provider.js +12 -5
  30. package/fesm/providers/smtp-provider.spec.js +282 -0
  31. package/fesm/services/email-config.service.spec.js +65 -0
  32. package/fesm/services/email-datasource.provider.spec.js +131 -0
  33. package/fesm/services/email-provider-config.service.spec.js +243 -0
  34. package/fesm/services/email-send.service.spec.js +542 -0
  35. package/fesm/services/email-template.service.spec.js +253 -0
  36. package/fesm/utils/email-templates.util.spec.js +57 -0
  37. package/package.json +3 -3
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ const _loggedusermock = require("@test-utils/mocks/logged-user.mock");
6
+ const _emailconfigcontroller = require("./email-config.controller");
7
+ function buildEmailConfig(overrides = {}) {
8
+ return {
9
+ id: 'email-config-1',
10
+ provider: 'smtp',
11
+ isActive: true,
12
+ isDefault: true,
13
+ readOnly: false,
14
+ createdAt: new Date(),
15
+ updatedAt: new Date(),
16
+ ...overrides
17
+ };
18
+ }
19
+ describe('EmailConfigController', ()=>{
20
+ let controller;
21
+ let mockEmailConfigService;
22
+ beforeEach(()=>{
23
+ mockEmailConfigService = {
24
+ insert: jest.fn(),
25
+ findById: jest.fn(),
26
+ getAll: jest.fn(),
27
+ update: jest.fn(),
28
+ delete: jest.fn()
29
+ };
30
+ controller = new _emailconfigcontroller.EmailConfigController(mockEmailConfigService);
31
+ });
32
+ it('wires the injected service onto the generated controller base', ()=>{
33
+ expect(controller.emailConfigService).toBe(mockEmailConfigService);
34
+ expect(controller.service).toBe(mockEmailConfigService);
35
+ });
36
+ describe('insert', ()=>{
37
+ it('creates an email config and returns the mapped response', async ()=>{
38
+ const user = (0, _loggedusermock.buildMockUser)();
39
+ mockEmailConfigService.insert.mockResolvedValue(buildEmailConfig());
40
+ const result = await controller.insert({
41
+ provider: 'smtp'
42
+ }, user);
43
+ expect(mockEmailConfigService.insert).toHaveBeenCalledWith({
44
+ provider: 'smtp'
45
+ }, user);
46
+ expect(result.success).toBe(true);
47
+ expect(result.data).toEqual(expect.objectContaining({
48
+ id: 'email-config-1'
49
+ }));
50
+ });
51
+ });
52
+ describe('getAll', ()=>{
53
+ it('paginates email configs and maps the response list', async ()=>{
54
+ mockEmailConfigService.getAll.mockResolvedValue({
55
+ data: [
56
+ buildEmailConfig()
57
+ ],
58
+ total: 1
59
+ });
60
+ const result = await controller.getAll({}, (0, _loggedusermock.buildMockUser)(), '');
61
+ expect(mockEmailConfigService.getAll).toHaveBeenCalledWith('', {}, (0, _loggedusermock.buildMockUser)());
62
+ expect(result.data).toHaveLength(1);
63
+ });
64
+ });
65
+ describe('delete', ()=>{
66
+ it('delegates soft-delete to the service', async ()=>{
67
+ mockEmailConfigService.delete.mockResolvedValue({
68
+ count: 1
69
+ });
70
+ const result = await controller.delete({
71
+ id: [
72
+ 'email-config-1'
73
+ ],
74
+ type: 'delete'
75
+ }, (0, _loggedusermock.buildMockUser)());
76
+ expect(mockEmailConfigService.delete).toHaveBeenCalledWith({
77
+ id: [
78
+ 'email-config-1'
79
+ ],
80
+ type: 'delete'
81
+ }, (0, _loggedusermock.buildMockUser)());
82
+ expect(result.success).toBe(true);
83
+ });
84
+ });
85
+ });
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ const _testing = require("@nestjs/testing");
6
+ const _loggedusermock = require("@test-utils/mocks/logged-user.mock");
7
+ const _emailsendcontroller = require("./email-send.controller");
8
+ const _services = require("../services");
9
+ describe('EmailSendController', ()=>{
10
+ let controller;
11
+ let mockService;
12
+ beforeEach(async ()=>{
13
+ mockService = {
14
+ sendEmail: jest.fn(),
15
+ sendTemplateEmail: jest.fn(),
16
+ sendTestEmail: jest.fn()
17
+ };
18
+ const module = await _testing.Test.createTestingModule({
19
+ controllers: [
20
+ _emailsendcontroller.EmailSendController
21
+ ],
22
+ providers: [
23
+ {
24
+ provide: _services.EmailSendService,
25
+ useValue: mockService
26
+ }
27
+ ]
28
+ }).compile();
29
+ controller = module.get(_emailsendcontroller.EmailSendController);
30
+ });
31
+ describe('sendEmail', ()=>{
32
+ it('delegates to the service and returns a success response', async ()=>{
33
+ mockService.sendEmail.mockResolvedValue({
34
+ success: true,
35
+ messageId: 'msg-1'
36
+ });
37
+ const dto = {
38
+ to: 'a@example.com',
39
+ subject: 'Hi',
40
+ html: '<p/>'
41
+ };
42
+ const user = (0, _loggedusermock.buildMockUser)();
43
+ const result = await controller.sendEmail(dto, user);
44
+ expect(mockService.sendEmail).toHaveBeenCalledWith(dto, user);
45
+ expect(result).toEqual({
46
+ success: true,
47
+ message: 'Email sent successfully',
48
+ messageKey: 'email.send.success',
49
+ data: {
50
+ success: true,
51
+ messageId: 'msg-1',
52
+ error: undefined
53
+ }
54
+ });
55
+ });
56
+ it('returns a failure response with the FAILED messageKey when the send fails', async ()=>{
57
+ mockService.sendEmail.mockResolvedValue({
58
+ success: false,
59
+ error: 'SMTP down'
60
+ });
61
+ const result = await controller.sendEmail({
62
+ to: 'a@example.com',
63
+ subject: 'Hi',
64
+ html: '<p/>'
65
+ }, (0, _loggedusermock.buildMockUser)());
66
+ expect(result).toEqual({
67
+ success: false,
68
+ message: 'Failed to send email',
69
+ messageKey: 'email.send.failed',
70
+ data: {
71
+ success: false,
72
+ messageId: undefined,
73
+ error: 'SMTP down'
74
+ }
75
+ });
76
+ });
77
+ });
78
+ describe('sendTemplateEmail', ()=>{
79
+ it('delegates to the service and returns a success response', async ()=>{
80
+ mockService.sendTemplateEmail.mockResolvedValue({
81
+ success: true,
82
+ messageId: 'msg-2'
83
+ });
84
+ const dto = {
85
+ to: 'a@example.com',
86
+ templateSlug: 'welcome'
87
+ };
88
+ const user = (0, _loggedusermock.buildMockUser)();
89
+ const result = await controller.sendTemplateEmail(dto, user);
90
+ expect(mockService.sendTemplateEmail).toHaveBeenCalledWith(dto, user);
91
+ expect(result.success).toBe(true);
92
+ expect(result.messageKey).toBe('email.send.success');
93
+ expect(result.message).toBe('Template email sent successfully');
94
+ });
95
+ it('returns a failure response when the template send fails', async ()=>{
96
+ mockService.sendTemplateEmail.mockResolvedValue({
97
+ success: false,
98
+ error: 'Template error'
99
+ });
100
+ const result = await controller.sendTemplateEmail({
101
+ to: 'a@example.com',
102
+ templateSlug: 'welcome'
103
+ }, (0, _loggedusermock.buildMockUser)());
104
+ expect(result.success).toBe(false);
105
+ expect(result.messageKey).toBe('email.send.failed');
106
+ expect(result.message).toBe('Failed to send template email');
107
+ });
108
+ });
109
+ describe('sendTestEmail', ()=>{
110
+ it('delegates to the service with the emailConfigId and recipient from the dto', async ()=>{
111
+ mockService.sendTestEmail.mockResolvedValue({
112
+ success: true,
113
+ messageId: 'msg-3'
114
+ });
115
+ const dto = {
116
+ emailConfigId: 'config-1',
117
+ recipient: 'a@example.com'
118
+ };
119
+ const user = (0, _loggedusermock.buildMockUser)();
120
+ const result = await controller.sendTestEmail(dto, user);
121
+ expect(mockService.sendTestEmail).toHaveBeenCalledWith('config-1', 'a@example.com', user);
122
+ expect(result.success).toBe(true);
123
+ expect(result.message).toBe('Test email sent successfully');
124
+ });
125
+ it('returns a failure response when the test send fails', async ()=>{
126
+ mockService.sendTestEmail.mockResolvedValue({
127
+ success: false,
128
+ error: 'Bad config'
129
+ });
130
+ const result = await controller.sendTestEmail({
131
+ emailConfigId: 'config-1',
132
+ recipient: 'a@example.com'
133
+ }, (0, _loggedusermock.buildMockUser)());
134
+ expect(result.success).toBe(false);
135
+ expect(result.message).toBe('Failed to send test email');
136
+ expect(result.messageKey).toBe('email.send.failed');
137
+ });
138
+ });
139
+ });
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ const _common = require("@nestjs/common");
6
+ const _loggedusermock = require("@test-utils/mocks/logged-user.mock");
7
+ const _emailtemplatecontroller = require("./email-template.controller");
8
+ function buildTemplate(overrides = {}) {
9
+ return {
10
+ id: 'template-1',
11
+ slug: 'password-reset',
12
+ subject: 'Reset your password',
13
+ body: '<p>Hello {{name}}</p>',
14
+ isActive: true,
15
+ readOnly: false,
16
+ createdAt: new Date(),
17
+ updatedAt: new Date(),
18
+ ...overrides
19
+ };
20
+ }
21
+ describe('EmailTemplateController', ()=>{
22
+ let controller;
23
+ let mockEmailTemplateService;
24
+ beforeEach(()=>{
25
+ mockEmailTemplateService = {
26
+ insert: jest.fn(),
27
+ findById: jest.fn(),
28
+ getAll: jest.fn(),
29
+ update: jest.fn(),
30
+ delete: jest.fn(),
31
+ findBySlug: jest.fn()
32
+ };
33
+ controller = new _emailtemplatecontroller.EmailTemplateController(mockEmailTemplateService);
34
+ });
35
+ it('wires the injected service onto the generated controller base', ()=>{
36
+ expect(controller.emailTemplateService).toBe(mockEmailTemplateService);
37
+ expect(controller.service).toBe(mockEmailTemplateService);
38
+ });
39
+ describe('insert', ()=>{
40
+ it('creates an email template and returns the mapped response', async ()=>{
41
+ const user = (0, _loggedusermock.buildMockUser)();
42
+ mockEmailTemplateService.insert.mockResolvedValue(buildTemplate());
43
+ const result = await controller.insert({
44
+ slug: 'password-reset'
45
+ }, user);
46
+ expect(mockEmailTemplateService.insert).toHaveBeenCalledWith({
47
+ slug: 'password-reset'
48
+ }, user);
49
+ expect(result.success).toBe(true);
50
+ expect(result.data).toEqual(expect.objectContaining({
51
+ id: 'template-1'
52
+ }));
53
+ });
54
+ });
55
+ describe('getAll', ()=>{
56
+ it('paginates templates and maps the response list', async ()=>{
57
+ mockEmailTemplateService.getAll.mockResolvedValue({
58
+ data: [
59
+ buildTemplate()
60
+ ],
61
+ total: 1
62
+ });
63
+ const result = await controller.getAll({}, (0, _loggedusermock.buildMockUser)(), '');
64
+ expect(mockEmailTemplateService.getAll).toHaveBeenCalledWith('', {}, (0, _loggedusermock.buildMockUser)());
65
+ expect(result.data).toHaveLength(1);
66
+ });
67
+ });
68
+ describe('getBySlug', ()=>{
69
+ it('returns the template matching the given slug', async ()=>{
70
+ const user = (0, _loggedusermock.buildMockUser)();
71
+ mockEmailTemplateService.findBySlug.mockResolvedValue(buildTemplate());
72
+ const result = await controller.getBySlug({
73
+ slug: 'password-reset'
74
+ }, user);
75
+ expect(mockEmailTemplateService.findBySlug).toHaveBeenCalledWith('password-reset', user);
76
+ expect(result.success).toBe(true);
77
+ expect(result.data).toEqual(expect.objectContaining({
78
+ slug: 'password-reset'
79
+ }));
80
+ });
81
+ it('throws NotFoundException when no template matches the slug', async ()=>{
82
+ const user = (0, _loggedusermock.buildMockUser)();
83
+ mockEmailTemplateService.findBySlug.mockResolvedValue(null);
84
+ await expect(controller.getBySlug({
85
+ slug: 'missing'
86
+ }, user)).rejects.toThrow(_common.NotFoundException);
87
+ });
88
+ });
89
+ });
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ const _emailswaggerconfig = require("./email-swagger.config");
6
+ describe('emailSwaggerConfig', ()=>{
7
+ it('should default to company feature enabled and single-database mode when no config is given', ()=>{
8
+ const config = (0, _emailswaggerconfig.emailSwaggerConfig)();
9
+ expect(config.title).toBe('Email API');
10
+ expect(config.bearerAuth).toBe(true);
11
+ expect(config.excludeSchemaProperties).toBeUndefined();
12
+ expect(config.description).not.toContain('Multi-Tenant Mode');
13
+ });
14
+ it('should exclude companyId schema properties when the company feature is disabled', ()=>{
15
+ const config = (0, _emailswaggerconfig.emailSwaggerConfig)({
16
+ enableCompanyFeature: false
17
+ });
18
+ expect(config.excludeSchemaProperties).toEqual([
19
+ {
20
+ schemaName: 'EmailConfigResponseDto',
21
+ properties: [
22
+ 'companyId'
23
+ ]
24
+ },
25
+ {
26
+ schemaName: 'EmailTemplateResponseDto',
27
+ properties: [
28
+ 'companyId'
29
+ ]
30
+ }
31
+ ]);
32
+ });
33
+ it('should not exclude any schema properties when the company feature is enabled', ()=>{
34
+ const config = (0, _emailswaggerconfig.emailSwaggerConfig)({
35
+ enableCompanyFeature: true
36
+ });
37
+ expect(config.excludeSchemaProperties).toBeUndefined();
38
+ });
39
+ it('should describe company isolation and multi-tenant support only when the company feature is enabled', ()=>{
40
+ const withCompany = (0, _emailswaggerconfig.emailSwaggerConfig)({
41
+ enableCompanyFeature: true
42
+ });
43
+ const withoutCompany = (0, _emailswaggerconfig.emailSwaggerConfig)({
44
+ enableCompanyFeature: false
45
+ });
46
+ expect(withCompany.description).toContain('Company isolation');
47
+ expect(withCompany.description).toContain('## Multi-Tenant Support');
48
+ expect(withCompany.description).toContain('with multi-tenant and company support');
49
+ expect(withoutCompany.description).not.toContain('Company isolation');
50
+ expect(withoutCompany.description).not.toContain('## Multi-Tenant Support');
51
+ });
52
+ it('should mention multi-tenant mode in the description only for multi-tenant database mode', ()=>{
53
+ const multiTenant = (0, _emailswaggerconfig.emailSwaggerConfig)({
54
+ databaseMode: 'multi-tenant'
55
+ });
56
+ const single = (0, _emailswaggerconfig.emailSwaggerConfig)({
57
+ databaseMode: 'single'
58
+ });
59
+ expect(multiTenant.description).toContain('Multi-Tenant Mode');
60
+ expect(single.description).not.toContain('Multi-Tenant Mode');
61
+ });
62
+ });
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ const _index = require("./index");
6
+ describe('getEmailEntitiesByConfig', ()=>{
7
+ it('returns the core entities when the company feature is disabled', ()=>{
8
+ expect((0, _index.getEmailEntitiesByConfig)(false)).toBe(_index.EmailCoreEntities);
9
+ });
10
+ it('returns the company-scoped entities when the company feature is enabled', ()=>{
11
+ expect((0, _index.getEmailEntitiesByConfig)(true)).toBe(_index.EmailCompanyEntities);
12
+ });
13
+ it('core and company entity sets are disjoint (never mixed)', ()=>{
14
+ const core = (0, _index.getEmailEntitiesByConfig)(false);
15
+ const company = (0, _index.getEmailEntitiesByConfig)(true);
16
+ expect(core.some((e)=>company.includes(e))).toBe(false);
17
+ });
18
+ });
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ const _emailmodule = require("./email.module");
6
+ const _emailconstants = require("../config/email.constants");
7
+ const _controllers = require("../controllers");
8
+ function _define_property(obj, key, value) {
9
+ if (key in obj) {
10
+ Object.defineProperty(obj, key, {
11
+ value: value,
12
+ enumerable: true,
13
+ configurable: true,
14
+ writable: true
15
+ });
16
+ } else {
17
+ obj[key] = value;
18
+ }
19
+ return obj;
20
+ }
21
+ function providerTokens(providers) {
22
+ return providers.map((p)=>typeof p === 'function' ? p : p.provide);
23
+ }
24
+ describe('EmailModule', ()=>{
25
+ describe('forRoot', ()=>{
26
+ it('should default to a non-global module with all controllers registered', ()=>{
27
+ const dynamicModule = _emailmodule.EmailModule.forRoot({});
28
+ expect(dynamicModule.module).toBe(_emailmodule.EmailModule);
29
+ expect(dynamicModule.global).toBe(false);
30
+ expect(dynamicModule.controllers).toEqual([
31
+ _controllers.EmailConfigController,
32
+ _controllers.EmailTemplateController,
33
+ _controllers.EmailSendController
34
+ ]);
35
+ });
36
+ it('should respect global: true', ()=>{
37
+ expect(_emailmodule.EmailModule.forRoot({
38
+ global: true
39
+ }).global).toBe(true);
40
+ });
41
+ it('should register no controllers when includeController is false', ()=>{
42
+ expect(_emailmodule.EmailModule.forRoot({
43
+ includeController: false
44
+ }).controllers).toEqual([]);
45
+ });
46
+ it('should register a EMAIL_MODULE_OPTIONS provider carrying the given options', ()=>{
47
+ const options = {
48
+ bootstrapAppConfig: {
49
+ enableCompanyFeature: true
50
+ }
51
+ };
52
+ const dynamicModule = _emailmodule.EmailModule.forRoot(options);
53
+ const provider = dynamicModule.providers.find((p)=>p.provide === _emailconstants.EMAIL_MODULE_OPTIONS);
54
+ expect(provider.useValue).toBe(options);
55
+ });
56
+ it('should always export the same fixed set of services', ()=>{
57
+ expect(_emailmodule.EmailModule.forRoot({}).exports).toHaveLength(6);
58
+ });
59
+ });
60
+ describe('forRootAsync', ()=>{
61
+ it('should forward external imports alongside CacheModule/UtilsModule', ()=>{
62
+ let FakeImportedModule = class FakeImportedModule {
63
+ };
64
+ const dynamicModule = _emailmodule.EmailModule.forRootAsync({
65
+ bootstrapAppConfig: {},
66
+ imports: [
67
+ FakeImportedModule
68
+ ]
69
+ });
70
+ expect(dynamicModule.imports).toEqual(expect.arrayContaining([
71
+ FakeImportedModule
72
+ ]));
73
+ });
74
+ it('useFactory: builds an EMAIL_MODULE_OPTIONS provider that merges resolved config into the static options', async ()=>{
75
+ const useFactory = jest.fn().mockResolvedValue({
76
+ defaultFrom: 'noreply@flusys.io'
77
+ });
78
+ const dynamicModule = _emailmodule.EmailModule.forRootAsync({
79
+ bootstrapAppConfig: {},
80
+ useFactory,
81
+ inject: [
82
+ 'SOME_TOKEN'
83
+ ]
84
+ });
85
+ const provider = dynamicModule.providers.find((p)=>p.provide === _emailconstants.EMAIL_MODULE_OPTIONS);
86
+ expect(provider.inject).toEqual([
87
+ 'SOME_TOKEN'
88
+ ]);
89
+ const resolved = await provider.useFactory('injected');
90
+ expect(useFactory).toHaveBeenCalledWith('injected');
91
+ expect(resolved.config).toEqual({
92
+ defaultFrom: 'noreply@flusys.io'
93
+ });
94
+ });
95
+ it('useClass: registers both the class provider and an options provider calling createEmailOptions()', async ()=>{
96
+ let MyOptionsFactory = class MyOptionsFactory {
97
+ constructor(){
98
+ _define_property(this, "createEmailOptions", jest.fn().mockResolvedValue({
99
+ defaultFrom: 'from-class@flusys.io'
100
+ }));
101
+ }
102
+ };
103
+ const dynamicModule = _emailmodule.EmailModule.forRootAsync({
104
+ bootstrapAppConfig: {},
105
+ useClass: MyOptionsFactory
106
+ });
107
+ const classProvider = dynamicModule.providers.find((p)=>p.provide === MyOptionsFactory);
108
+ expect(classProvider.useClass).toBe(MyOptionsFactory);
109
+ const optionsProvider = dynamicModule.providers.find((p)=>p.provide === _emailconstants.EMAIL_MODULE_OPTIONS);
110
+ const instance = new MyOptionsFactory();
111
+ const resolved = await optionsProvider.useFactory(instance);
112
+ expect(instance.createEmailOptions).toHaveBeenCalled();
113
+ expect(resolved.config).toEqual({
114
+ defaultFrom: 'from-class@flusys.io'
115
+ });
116
+ });
117
+ it('useExisting: registers a single options provider without a duplicate class registration', async ()=>{
118
+ let MyOptionsFactory = class MyOptionsFactory {
119
+ constructor(){
120
+ _define_property(this, "createEmailOptions", jest.fn().mockResolvedValue({
121
+ defaultFrom: 'from-existing@flusys.io'
122
+ }));
123
+ }
124
+ };
125
+ const dynamicModule = _emailmodule.EmailModule.forRootAsync({
126
+ bootstrapAppConfig: {},
127
+ useExisting: MyOptionsFactory
128
+ });
129
+ expect(dynamicModule.providers.filter((p)=>p.provide === MyOptionsFactory)).toHaveLength(0);
130
+ const optionsProvider = dynamicModule.providers.find((p)=>p.provide === _emailconstants.EMAIL_MODULE_OPTIONS);
131
+ expect(optionsProvider.inject).toEqual([
132
+ MyOptionsFactory
133
+ ]);
134
+ });
135
+ it('should register no EMAIL_MODULE_OPTIONS provider when neither useFactory, useClass, nor useExisting is given', ()=>{
136
+ const dynamicModule = _emailmodule.EmailModule.forRootAsync({
137
+ bootstrapAppConfig: {}
138
+ });
139
+ expect(providerTokens(dynamicModule.providers)).not.toContain(_emailconstants.EMAIL_MODULE_OPTIONS);
140
+ });
141
+ });
142
+ });