@flusys/nestjs-email 7.1.0 → 8.0.0-beta.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 (159) hide show
  1. package/config/index.d.ts +3 -3
  2. package/controllers/email-config.controller.d.ts +2 -2
  3. package/controllers/email-send.controller.d.ts +3 -3
  4. package/controllers/email-template.controller.d.ts +4 -4
  5. package/controllers/index.d.ts +3 -3
  6. package/docs/email-swagger.config.d.ts +2 -2
  7. package/docs/index.d.ts +1 -1
  8. package/dtos/email-config.dto.d.ts +1 -1
  9. package/dtos/email-send.dto.d.ts +1 -1
  10. package/dtos/index.d.ts +3 -3
  11. package/entities/email-config-with-company.entity.d.ts +1 -1
  12. package/entities/email-template-with-company.entity.d.ts +1 -1
  13. package/entities/index.d.ts +10 -10
  14. package/enums/index.d.ts +1 -1
  15. package/fesm/261.js +799 -0
  16. package/fesm/493.js +1723 -0
  17. package/fesm/chunks/99.js +12 -0
  18. package/fesm/config/index.js +104 -3
  19. package/fesm/controllers/index.js +396 -3
  20. package/fesm/docs/index.js +134 -1
  21. package/fesm/dtos/index.js +22 -3
  22. package/fesm/entities/index.js +409 -13
  23. package/fesm/enums/index.js +37 -1
  24. package/fesm/index.js +762 -10
  25. package/fesm/interfaces/index.js +18 -4
  26. package/fesm/modules/index.js +541 -1
  27. package/fesm/providers/index.js +523 -5
  28. package/fesm/runtime.js +134 -0
  29. package/fesm/services/index.js +17 -5
  30. package/index.d.ts +10 -10
  31. package/interfaces/email-config.interface.d.ts +2 -2
  32. package/interfaces/email-module-options.interface.d.ts +3 -3
  33. package/interfaces/email-template.interface.d.ts +1 -1
  34. package/interfaces/index.d.ts +4 -4
  35. package/modules/email.module.d.ts +2 -2
  36. package/modules/index.d.ts +1 -1
  37. package/package.json +27 -38
  38. package/providers/email-factory.service.d.ts +2 -2
  39. package/providers/email-provider.registry.d.ts +2 -2
  40. package/providers/index.d.ts +5 -5
  41. package/providers/mailgun-provider.d.ts +1 -1
  42. package/providers/sendgrid-provider.d.ts +1 -1
  43. package/providers/smtp-provider.d.ts +1 -1
  44. package/services/email-config.service.d.ts +3 -3
  45. package/services/email-datasource.provider.d.ts +3 -3
  46. package/services/email-provider-config.service.d.ts +7 -7
  47. package/services/email-send.service.d.ts +7 -7
  48. package/services/email-template.service.d.ts +6 -6
  49. package/services/index.d.ts +5 -5
  50. package/utils/index.d.ts +1 -1
  51. package/cjs/config/email.constants.js +0 -22
  52. package/cjs/config/event-actions.js +0 -34
  53. package/cjs/config/index.js +0 -20
  54. package/cjs/config/message-keys.js +0 -39
  55. package/cjs/controllers/email-config.controller.js +0 -111
  56. package/cjs/controllers/email-config.controller.spec.js +0 -85
  57. package/cjs/controllers/email-send.controller.js +0 -128
  58. package/cjs/controllers/email-send.controller.spec.js +0 -139
  59. package/cjs/controllers/email-template.controller.js +0 -142
  60. package/cjs/controllers/email-template.controller.spec.js +0 -89
  61. package/cjs/controllers/index.js +0 -20
  62. package/cjs/docs/email-swagger.config.js +0 -116
  63. package/cjs/docs/email-swagger.config.spec.js +0 -62
  64. package/cjs/docs/index.js +0 -11
  65. package/cjs/dtos/email-config.dto.js +0 -212
  66. package/cjs/dtos/email-send.dto.js +0 -354
  67. package/cjs/dtos/email-template.dto.js +0 -252
  68. package/cjs/dtos/index.js +0 -20
  69. package/cjs/entities/email-config-with-company.entity.js +0 -63
  70. package/cjs/entities/email-config.entity.js +0 -114
  71. package/cjs/entities/email-template-with-company.entity.js +0 -65
  72. package/cjs/entities/email-template.entity.js +0 -136
  73. package/cjs/entities/index.js +0 -56
  74. package/cjs/entities/index.spec.js +0 -18
  75. package/cjs/enums/email-provider-type.enum.js +0 -18
  76. package/cjs/enums/index.js +0 -18
  77. package/cjs/index.js +0 -28
  78. package/cjs/interfaces/email-config.interface.js +0 -4
  79. package/cjs/interfaces/email-module-options.interface.js +0 -4
  80. package/cjs/interfaces/email-provider.interface.js +0 -4
  81. package/cjs/interfaces/email-template.interface.js +0 -4
  82. package/cjs/interfaces/index.js +0 -21
  83. package/cjs/modules/email.module.js +0 -122
  84. package/cjs/modules/email.module.spec.js +0 -142
  85. package/cjs/modules/index.js +0 -18
  86. package/cjs/providers/email-factory.service.js +0 -113
  87. package/cjs/providers/email-factory.service.spec.js +0 -242
  88. package/cjs/providers/email-provider.registry.js +0 -41
  89. package/cjs/providers/email-provider.registry.spec.js +0 -58
  90. package/cjs/providers/index.js +0 -22
  91. package/cjs/providers/mailgun-provider.js +0 -119
  92. package/cjs/providers/mailgun-provider.spec.js +0 -244
  93. package/cjs/providers/sendgrid-provider.js +0 -129
  94. package/cjs/providers/sendgrid-provider.spec.js +0 -346
  95. package/cjs/providers/smtp-provider.js +0 -164
  96. package/cjs/providers/smtp-provider.spec.js +0 -327
  97. package/cjs/services/email-config.service.js +0 -71
  98. package/cjs/services/email-config.service.spec.js +0 -69
  99. package/cjs/services/email-datasource.provider.js +0 -84
  100. package/cjs/services/email-datasource.provider.spec.js +0 -135
  101. package/cjs/services/email-provider-config.service.js +0 -159
  102. package/cjs/services/email-provider-config.service.spec.js +0 -269
  103. package/cjs/services/email-send.service.js +0 -315
  104. package/cjs/services/email-send.service.spec.js +0 -614
  105. package/cjs/services/email-template.service.js +0 -144
  106. package/cjs/services/email-template.service.spec.js +0 -261
  107. package/cjs/services/index.js +0 -22
  108. package/cjs/utils/email-templates.util.js +0 -64
  109. package/cjs/utils/email-templates.util.spec.js +0 -61
  110. package/cjs/utils/index.js +0 -18
  111. package/fesm/config/email.constants.js +0 -4
  112. package/fesm/config/event-actions.js +0 -13
  113. package/fesm/config/message-keys.js +0 -18
  114. package/fesm/controllers/email-config.controller.js +0 -101
  115. package/fesm/controllers/email-config.controller.spec.js +0 -81
  116. package/fesm/controllers/email-send.controller.js +0 -118
  117. package/fesm/controllers/email-send.controller.spec.js +0 -135
  118. package/fesm/controllers/email-template.controller.js +0 -132
  119. package/fesm/controllers/email-template.controller.spec.js +0 -85
  120. package/fesm/docs/email-swagger.config.js +0 -109
  121. package/fesm/docs/email-swagger.config.spec.js +0 -58
  122. package/fesm/dtos/email-config.dto.js +0 -191
  123. package/fesm/dtos/email-send.dto.js +0 -324
  124. package/fesm/dtos/email-template.dto.js +0 -231
  125. package/fesm/entities/email-config-with-company.entity.js +0 -53
  126. package/fesm/entities/email-config.entity.js +0 -104
  127. package/fesm/entities/email-template-with-company.entity.js +0 -55
  128. package/fesm/entities/email-template.entity.js +0 -126
  129. package/fesm/entities/index.spec.js +0 -14
  130. package/fesm/enums/email-provider-type.enum.js +0 -8
  131. package/fesm/interfaces/email-config.interface.js +0 -1
  132. package/fesm/interfaces/email-module-options.interface.js +0 -1
  133. package/fesm/interfaces/email-provider.interface.js +0 -1
  134. package/fesm/interfaces/email-template.interface.js +0 -1
  135. package/fesm/modules/email.module.js +0 -112
  136. package/fesm/modules/email.module.spec.js +0 -138
  137. package/fesm/providers/email-factory.service.js +0 -103
  138. package/fesm/providers/email-factory.service.spec.js +0 -238
  139. package/fesm/providers/email-provider.registry.js +0 -31
  140. package/fesm/providers/email-provider.registry.spec.js +0 -54
  141. package/fesm/providers/mailgun-provider.js +0 -109
  142. package/fesm/providers/mailgun-provider.spec.js +0 -240
  143. package/fesm/providers/sendgrid-provider.js +0 -119
  144. package/fesm/providers/sendgrid-provider.spec.js +0 -342
  145. package/fesm/providers/smtp-provider.js +0 -113
  146. package/fesm/providers/smtp-provider.spec.js +0 -282
  147. package/fesm/services/email-config.service.js +0 -61
  148. package/fesm/services/email-config.service.spec.js +0 -65
  149. package/fesm/services/email-datasource.provider.js +0 -74
  150. package/fesm/services/email-datasource.provider.spec.js +0 -131
  151. package/fesm/services/email-provider-config.service.js +0 -149
  152. package/fesm/services/email-provider-config.service.spec.js +0 -265
  153. package/fesm/services/email-send.service.js +0 -305
  154. package/fesm/services/email-send.service.spec.js +0 -610
  155. package/fesm/services/email-template.service.js +0 -134
  156. package/fesm/services/email-template.service.spec.js +0 -257
  157. package/fesm/utils/email-templates.util.js +0 -47
  158. package/fesm/utils/email-templates.util.spec.js +0 -57
  159. package/fesm/utils/index.js +0 -1
@@ -1,159 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, "EmailProviderConfigService", {
6
- enumerable: true,
7
- get: function() {
8
- return EmailProviderConfigService;
9
- }
10
- });
11
- const _classes = require("@flusys/nestjs-shared/classes");
12
- const _modules = require("@flusys/nestjs-shared/modules");
13
- const _utils = require("@flusys/nestjs-shared/utils");
14
- const _common = require("@nestjs/common");
15
- const _typeorm = require("typeorm");
16
- const _config = require("../config");
17
- const _entities = require("../entities");
18
- const _emailconfigservice = require("./email-config.service");
19
- const _emaildatasourceprovider = require("./email-datasource.provider");
20
- function _define_property(obj, key, value) {
21
- if (key in obj) {
22
- Object.defineProperty(obj, key, {
23
- value: value,
24
- enumerable: true,
25
- configurable: true,
26
- writable: true
27
- });
28
- } else {
29
- obj[key] = value;
30
- }
31
- return obj;
32
- }
33
- function _ts_decorate(decorators, target, key, desc) {
34
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
35
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
36
- else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
37
- return c > 3 && r && Object.defineProperty(target, key, r), r;
38
- }
39
- function _ts_metadata(k, v) {
40
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
41
- }
42
- function _ts_param(paramIndex, decorator) {
43
- return function(target, key) {
44
- decorator(target, key, paramIndex);
45
- };
46
- }
47
- let EmailProviderConfigService = class EmailProviderConfigService extends _classes.ApiService {
48
- async beforeDeleteOperation(dto, _user, _queryRunner) {
49
- const ids = Array.isArray(dto.id) ? dto.id : [
50
- dto.id
51
- ];
52
- await this.ensureDataSourceRepository();
53
- const defaultConfigs = await this.repository.find({
54
- where: {
55
- id: (0, _typeorm.In)(ids),
56
- isDefault: true,
57
- deletedAt: (0, _typeorm.IsNull)()
58
- }
59
- });
60
- if (defaultConfigs.length > 0) {
61
- const names = defaultConfigs.map((c)=>c.name).join(', ');
62
- throw new _common.ForbiddenException({
63
- message: `Cannot delete the default email config(s): ${names}. Set another config as default first.`,
64
- messageKey: _config.EMAIL_CONFIG_MESSAGES.DEFAULT_DELETE_FORBIDDEN,
65
- messageVariables: {
66
- names
67
- }
68
- });
69
- }
70
- }
71
- async convertSingleDtoToEntity(dto, user) {
72
- const entity = {
73
- ...dto
74
- };
75
- if (this.emailConfig.isCompanyFeatureEnabled()) {
76
- entity.companyId = user?.companyId ?? null;
77
- }
78
- return entity;
79
- }
80
- async getSelectQuery(query, _user, select) {
81
- if (!select?.length) {
82
- select = [
83
- 'id',
84
- 'name',
85
- 'provider',
86
- 'config',
87
- 'fromEmail',
88
- 'fromName',
89
- 'isActive',
90
- 'isDefault',
91
- 'createdAt',
92
- 'updatedAt'
93
- ];
94
- if (this.emailConfig.isCompanyFeatureEnabled()) select.push('companyId');
95
- }
96
- query.select(select.map((field)=>`${this.entityName}.${field}`));
97
- return {
98
- query,
99
- isRaw: false
100
- };
101
- }
102
- async getExtraManipulateQuery(query, filterDto, user) {
103
- const result = await super.getExtraManipulateQuery(query, filterDto, user);
104
- (0, _utils.applyCompanyFilter)(query, {
105
- isCompanyFeatureEnabled: this.emailConfig.isCompanyFeatureEnabled(),
106
- entityAlias: 'emailConfig'
107
- }, user);
108
- query.orderBy(`${this.entityName}.createdAt`, 'DESC');
109
- return result;
110
- }
111
- async findByIdDirect(id) {
112
- await this.ensureDataSourceRepository();
113
- return this.repository.findOne({
114
- where: {
115
- id
116
- }
117
- });
118
- }
119
- async getDefaultConfig(user) {
120
- await this.ensureDataSourceRepository();
121
- const baseWhere = (0, _utils.buildCompanyWhereCondition)({
122
- isActive: true
123
- }, this.emailConfig.isCompanyFeatureEnabled(), user);
124
- const defaultConfig = await this.repository.findOne({
125
- where: {
126
- ...baseWhere,
127
- isDefault: true
128
- },
129
- order: {
130
- createdAt: 'ASC'
131
- }
132
- });
133
- return defaultConfig || this.repository.findOne({
134
- where: baseWhere,
135
- order: {
136
- createdAt: 'ASC'
137
- }
138
- });
139
- }
140
- constructor(cacheManager, utilsService, emailConfig, dataSourceProvider){
141
- super(_config.EMAIL_EVENT_ENTITIES.CONFIG, cacheManager, utilsService, EmailProviderConfigService.name, true, _config.EMAIL_EVENT_MODULE, dataSourceProvider, emailConfig.isCompanyFeatureEnabled() ? _entities.EmailConfigWithCompany : _entities.EmailConfig), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "emailConfig", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.emailConfig = emailConfig;
142
- }
143
- };
144
- EmailProviderConfigService = _ts_decorate([
145
- (0, _common.Injectable)({
146
- scope: _common.Scope.REQUEST
147
- }),
148
- _ts_param(0, (0, _common.Inject)('CACHE_INSTANCE')),
149
- _ts_param(1, (0, _common.Inject)(_modules.UtilsService)),
150
- _ts_param(2, (0, _common.Inject)(_emailconfigservice.EmailConfigService)),
151
- _ts_param(3, (0, _common.Inject)(_emaildatasourceprovider.EmailDataSourceProvider)),
152
- _ts_metadata("design:type", Function),
153
- _ts_metadata("design:paramtypes", [
154
- typeof _classes.HybridCache === "undefined" ? Object : _classes.HybridCache,
155
- typeof _modules.UtilsService === "undefined" ? Object : _modules.UtilsService,
156
- typeof _emailconfigservice.EmailConfigService === "undefined" ? Object : _emailconfigservice.EmailConfigService,
157
- typeof _emaildatasourceprovider.EmailDataSourceProvider === "undefined" ? Object : _emaildatasourceprovider.EmailDataSourceProvider
158
- ])
159
- ], EmailProviderConfigService);
@@ -1,269 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- const _testing = require("@nestjs/testing");
6
- const _modules = require("@flusys/nestjs-shared/modules");
7
- const _repositorymock = require("@test-utils/mocks/repository.mock");
8
- const _loggedusermock = require("@test-utils/mocks/logged-user.mock");
9
- const _entities = require("../entities");
10
- const _emailconfigservice = require("./email-config.service");
11
- const _emaildatasourceprovider = require("./email-datasource.provider");
12
- const _emailproviderconfigservice = require("./email-provider-config.service");
13
- function buildEmailConfig(overrides = {}) {
14
- return {
15
- id: 'config-uuid-1',
16
- name: 'Primary SMTP',
17
- provider: 'smtp',
18
- config: {
19
- host: 'smtp.example.com'
20
- },
21
- fromEmail: 'noreply@example.com',
22
- fromName: 'FLUSYS',
23
- isActive: true,
24
- isDefault: false,
25
- createdAt: new Date(),
26
- updatedAt: new Date(),
27
- deletedAt: null,
28
- createdById: null,
29
- updatedById: null,
30
- deletedById: null,
31
- ...overrides
32
- };
33
- }
34
- function buildQuery() {
35
- return {
36
- select: jest.fn().mockReturnThis(),
37
- andWhere: jest.fn().mockReturnThis(),
38
- orderBy: jest.fn().mockReturnThis()
39
- };
40
- }
41
- describe('EmailProviderConfigService', ()=>{
42
- let service;
43
- let module;
44
- let mockRepo;
45
- let mockEmailConfig;
46
- beforeEach(async ()=>{
47
- mockRepo = (0, _repositorymock.createMockRepository)();
48
- const mockDataSourceProvider = (0, _repositorymock.createMockDataSourceProvider)(mockRepo);
49
- mockEmailConfig = {
50
- isCompanyFeatureEnabled: jest.fn().mockReturnValue(false)
51
- };
52
- module = await _testing.Test.createTestingModule({
53
- providers: [
54
- _emailproviderconfigservice.EmailProviderConfigService,
55
- {
56
- provide: 'CACHE_INSTANCE',
57
- useValue: {}
58
- },
59
- {
60
- provide: _modules.UtilsService,
61
- useValue: {}
62
- },
63
- {
64
- provide: _emailconfigservice.EmailConfigService,
65
- useValue: mockEmailConfig
66
- },
67
- {
68
- provide: _emaildatasourceprovider.EmailDataSourceProvider,
69
- useValue: mockDataSourceProvider
70
- }
71
- ]
72
- }).compile();
73
- service = await module.resolve(_emailproviderconfigservice.EmailProviderConfigService);
74
- });
75
- describe('entity selection', ()=>{
76
- it('uses EmailConfig when the company feature is disabled', async ()=>{
77
- mockEmailConfig.isCompanyFeatureEnabled.mockReturnValue(false);
78
- const built = await module.resolve(_emailproviderconfigservice.EmailProviderConfigService);
79
- expect(built['_entity']).toBe(_entities.EmailConfig);
80
- });
81
- it('uses EmailConfigWithCompany when the company feature is enabled', async ()=>{
82
- mockEmailConfig.isCompanyFeatureEnabled.mockReturnValue(true);
83
- const built = await module.resolve(_emailproviderconfigservice.EmailProviderConfigService);
84
- expect(built['_entity']).toBe(_entities.EmailConfigWithCompany);
85
- });
86
- });
87
- describe('convertSingleDtoToEntity', ()=>{
88
- it('does not attach companyId when the company feature is disabled', async ()=>{
89
- const entity = await service.convertSingleDtoToEntity({
90
- name: 'X',
91
- provider: 'smtp',
92
- config: {}
93
- }, (0, _loggedusermock.buildMockUser)());
94
- expect(entity.companyId).toBeUndefined();
95
- });
96
- it('attaches the current user companyId when the company feature is enabled', async ()=>{
97
- mockEmailConfig.isCompanyFeatureEnabled.mockReturnValue(true);
98
- const entity = await service.convertSingleDtoToEntity({
99
- name: 'X',
100
- provider: 'smtp',
101
- config: {}
102
- }, (0, _loggedusermock.buildMockUser)({
103
- companyId: 'company-uuid-42'
104
- }));
105
- expect(entity.companyId).toBe('company-uuid-42');
106
- });
107
- it('sets companyId to null when the company feature is enabled but no user is provided', async ()=>{
108
- mockEmailConfig.isCompanyFeatureEnabled.mockReturnValue(true);
109
- const entity = await service.convertSingleDtoToEntity({
110
- name: 'X',
111
- provider: 'smtp',
112
- config: {}
113
- }, null);
114
- expect(entity.companyId).toBeNull();
115
- });
116
- });
117
- describe('getSelectQuery', ()=>{
118
- it('selects the default whitelisted fields (without companyId) when company feature is disabled', async ()=>{
119
- const query = buildQuery();
120
- const { isRaw } = await service.getSelectQuery(query, (0, _loggedusermock.buildMockUser)());
121
- expect(isRaw).toBe(false);
122
- const [selected] = query.select.mock.calls[0];
123
- expect(selected).toEqual(expect.arrayContaining([
124
- 'emailConfig.id',
125
- 'emailConfig.name',
126
- 'emailConfig.provider',
127
- 'emailConfig.config',
128
- 'emailConfig.fromEmail',
129
- 'emailConfig.fromName',
130
- 'emailConfig.isActive',
131
- 'emailConfig.isDefault',
132
- 'emailConfig.createdAt',
133
- 'emailConfig.updatedAt'
134
- ]));
135
- expect(selected).not.toContain('emailConfig.companyId');
136
- });
137
- it('appends companyId to the default field list when company feature is enabled', async ()=>{
138
- mockEmailConfig.isCompanyFeatureEnabled.mockReturnValue(true);
139
- const query = buildQuery();
140
- await service.getSelectQuery(query, (0, _loggedusermock.buildMockUser)());
141
- const [selected] = query.select.mock.calls[0];
142
- expect(selected).toContain('emailConfig.companyId');
143
- });
144
- it('respects an explicit select list instead of the defaults', async ()=>{
145
- const query = buildQuery();
146
- await service.getSelectQuery(query, (0, _loggedusermock.buildMockUser)(), [
147
- 'name'
148
- ]);
149
- expect(query.select).toHaveBeenCalledWith([
150
- 'emailConfig.name'
151
- ]);
152
- });
153
- });
154
- describe('getExtraManipulateQuery', ()=>{
155
- it('applies the company filter and orders by createdAt DESC when company feature is enabled', async ()=>{
156
- mockEmailConfig.isCompanyFeatureEnabled.mockReturnValue(true);
157
- const query = buildQuery();
158
- await service.getExtraManipulateQuery(query, {}, (0, _loggedusermock.buildMockUser)({
159
- companyId: 'c-1'
160
- }));
161
- expect(query.andWhere).toHaveBeenCalledWith('emailConfig.companyId = :companyId', {
162
- companyId: 'c-1'
163
- });
164
- expect(query.orderBy).toHaveBeenCalledWith('emailConfig.createdAt', 'DESC');
165
- });
166
- it('skips the company filter when the company feature is disabled', async ()=>{
167
- const query = buildQuery();
168
- await service.getExtraManipulateQuery(query, {}, (0, _loggedusermock.buildMockUser)());
169
- expect(query.andWhere).not.toHaveBeenCalled();
170
- expect(query.orderBy).toHaveBeenCalledWith('emailConfig.createdAt', 'DESC');
171
- });
172
- });
173
- describe('findByIdDirect', ()=>{
174
- it('returns the matching config from the repository', async ()=>{
175
- const config = buildEmailConfig();
176
- mockRepo.findOne.mockResolvedValue(config);
177
- const result = await service.findByIdDirect('config-uuid-1');
178
- expect(result).toBe(config);
179
- expect(mockRepo.findOne).toHaveBeenCalledWith({
180
- where: {
181
- id: 'config-uuid-1'
182
- }
183
- });
184
- });
185
- it('returns null when no config matches', async ()=>{
186
- mockRepo.findOne.mockResolvedValue(null);
187
- await expect(service.findByIdDirect('missing')).resolves.toBeNull();
188
- });
189
- });
190
- describe('getDefaultConfig', ()=>{
191
- it('returns the active default config when one is marked isDefault', async ()=>{
192
- const defaultConfig = buildEmailConfig({
193
- isDefault: true
194
- });
195
- mockRepo.findOne.mockResolvedValueOnce(defaultConfig);
196
- const result = await service.getDefaultConfig((0, _loggedusermock.buildMockUser)());
197
- expect(result).toBe(defaultConfig);
198
- expect(mockRepo.findOne).toHaveBeenCalledTimes(1);
199
- expect(mockRepo.findOne).toHaveBeenCalledWith({
200
- where: {
201
- isActive: true,
202
- isDefault: true
203
- },
204
- order: {
205
- createdAt: 'ASC'
206
- }
207
- });
208
- });
209
- it('falls back to the oldest active config when no default is marked', async ()=>{
210
- const fallbackConfig = buildEmailConfig({
211
- isDefault: false
212
- });
213
- mockRepo.findOne.mockResolvedValueOnce(null).mockResolvedValueOnce(fallbackConfig);
214
- const result = await service.getDefaultConfig((0, _loggedusermock.buildMockUser)());
215
- expect(result).toBe(fallbackConfig);
216
- expect(mockRepo.findOne).toHaveBeenCalledTimes(2);
217
- expect(mockRepo.findOne).toHaveBeenNthCalledWith(2, {
218
- where: {
219
- isActive: true
220
- },
221
- order: {
222
- createdAt: 'ASC'
223
- }
224
- });
225
- });
226
- it('returns null when there is no active config at all', async ()=>{
227
- mockRepo.findOne.mockResolvedValue(null);
228
- await expect(service.getDefaultConfig((0, _loggedusermock.buildMockUser)())).resolves.toBeNull();
229
- });
230
- it('scopes the lookup to the current company when the company feature is enabled', async ()=>{
231
- mockEmailConfig.isCompanyFeatureEnabled.mockReturnValue(true);
232
- const defaultConfig = buildEmailConfig({
233
- isDefault: true
234
- });
235
- mockRepo.findOne.mockResolvedValueOnce(defaultConfig);
236
- await service.getDefaultConfig((0, _loggedusermock.buildMockUser)({
237
- companyId: 'company-uuid-9'
238
- }));
239
- expect(mockRepo.findOne).toHaveBeenCalledWith({
240
- where: {
241
- isActive: true,
242
- companyId: 'company-uuid-9',
243
- isDefault: true
244
- },
245
- order: {
246
- createdAt: 'ASC'
247
- }
248
- });
249
- });
250
- });
251
- describe('beforeDeleteOperation', ()=>{
252
- it('rejects deleting the default email config', async ()=>{
253
- mockRepo.find.mockResolvedValue([
254
- buildEmailConfig({
255
- isDefault: true
256
- })
257
- ]);
258
- await expect(service.beforeDeleteOperation({
259
- id: 'config-uuid-1'
260
- }, null, {})).rejects.toThrow('Cannot delete the default email config');
261
- });
262
- it('allows deleting a non-default email config', async ()=>{
263
- mockRepo.find.mockResolvedValue([]);
264
- await expect(service.beforeDeleteOperation({
265
- id: 'config-uuid-1'
266
- }, null, {})).resolves.toBeUndefined();
267
- });
268
- });
269
- });