@ackplus/nest-dynamic-templates 1.1.1 → 1.1.5
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.
- package/package.json +2 -2
- package/src/{index.ts → index.d.ts} +2 -14
- package/src/index.d.ts.map +1 -0
- package/src/index.js +25 -0
- package/src/lib/constant.d.ts +3 -0
- package/src/lib/constant.d.ts.map +1 -0
- package/src/lib/constant.js +5 -0
- package/src/lib/dto/create-template-layout.dto.d.ts +16 -0
- package/src/lib/dto/create-template-layout.dto.d.ts.map +1 -0
- package/src/lib/dto/create-template-layout.dto.js +86 -0
- package/src/lib/dto/create-template.dto.d.ts +18 -0
- package/src/lib/dto/create-template.dto.d.ts.map +1 -0
- package/src/lib/dto/create-template.dto.js +103 -0
- package/src/lib/dto/render-content-template-layout.dto.d.ts +8 -0
- package/src/lib/dto/render-content-template-layout.dto.d.ts.map +1 -0
- package/src/lib/dto/render-content-template-layout.dto.js +40 -0
- package/src/lib/dto/render-content-template.dto.d.ts +9 -0
- package/src/lib/dto/render-content-template.dto.d.ts.map +1 -0
- package/src/lib/dto/render-content-template.dto.js +46 -0
- package/src/lib/dto/render-template-layout.dto.d.ts +11 -0
- package/src/lib/dto/render-template-layout.dto.d.ts.map +1 -0
- package/src/lib/dto/render-template-layout.dto.js +66 -0
- package/src/lib/dto/render-template.dto.d.ts +15 -0
- package/src/lib/dto/render-template.dto.d.ts.map +1 -0
- package/src/lib/dto/render-template.dto.js +90 -0
- package/src/lib/dto/template-filter.dto.d.ts +9 -0
- package/src/lib/dto/template-filter.dto.d.ts.map +1 -0
- package/src/lib/dto/template-filter.dto.js +61 -0
- package/src/lib/dto/template-layout-filter.dto.d.ts +8 -0
- package/src/lib/dto/template-layout-filter.dto.d.ts.map +1 -0
- package/src/lib/dto/template-layout-filter.dto.js +60 -0
- package/src/lib/engines/language/html.engine.d.ts +10 -0
- package/src/lib/engines/language/html.engine.d.ts.map +1 -0
- package/src/lib/engines/language/html.engine.js +80 -0
- package/src/lib/engines/language/{index.ts → index.d.ts} +1 -0
- package/src/lib/engines/language/index.d.ts.map +1 -0
- package/src/lib/engines/language/index.js +11 -0
- package/src/lib/engines/language/markdown.engine.d.ts +10 -0
- package/src/lib/engines/language/markdown.engine.d.ts.map +1 -0
- package/src/lib/engines/language/markdown.engine.js +39 -0
- package/src/lib/engines/language/mjml.engine.d.ts +10 -0
- package/src/lib/engines/language/mjml.engine.d.ts.map +1 -0
- package/src/lib/engines/language/mjml.engine.js +75 -0
- package/src/lib/engines/language/text.engine.d.ts +8 -0
- package/src/lib/engines/language/text.engine.d.ts.map +1 -0
- package/src/lib/engines/language/text.engine.js +15 -0
- package/src/lib/engines/{language-engine.ts → language-engine.d.ts} +2 -7
- package/src/lib/engines/language-engine.d.ts.map +1 -0
- package/src/lib/engines/language-engine.js +6 -0
- package/src/lib/engines/template/ejs.engine.d.ts +11 -0
- package/src/lib/engines/template/ejs.engine.d.ts.map +1 -0
- package/src/lib/engines/template/ejs.engine.js +65 -0
- package/src/lib/engines/template/handlebars.engine.d.ts +11 -0
- package/src/lib/engines/template/handlebars.engine.d.ts.map +1 -0
- package/src/lib/engines/template/handlebars.engine.js +66 -0
- package/src/lib/engines/template/{index.ts → index.d.ts} +1 -0
- package/src/lib/engines/template/index.d.ts.map +1 -0
- package/src/lib/engines/template/index.js +11 -0
- package/src/lib/engines/template/nunjucks.engine.d.ts +17 -0
- package/src/lib/engines/template/nunjucks.engine.d.ts.map +1 -0
- package/src/lib/engines/template/{nunjucks.engine.ts → nunjucks.engine.js} +24 -30
- package/src/lib/engines/template/pug.engine.d.ts +13 -0
- package/src/lib/engines/template/pug.engine.d.ts.map +1 -0
- package/src/lib/engines/template/pug.engine.js +74 -0
- package/src/lib/engines/{template-engine.ts → template-engine.d.ts} +2 -6
- package/src/lib/engines/template-engine.d.ts.map +1 -0
- package/src/lib/engines/template-engine.js +6 -0
- package/src/lib/entities/template-layout.entity.d.ts +21 -0
- package/src/lib/entities/template-layout.entity.d.ts.map +1 -0
- package/src/lib/entities/template-layout.entity.js +120 -0
- package/src/lib/entities/template.entity.d.ts +22 -0
- package/src/lib/entities/template.entity.d.ts.map +1 -0
- package/src/lib/entities/template.entity.js +127 -0
- package/src/lib/errors/template.errors.d.ts +20 -0
- package/src/lib/errors/template.errors.d.ts.map +1 -0
- package/src/lib/errors/{template.errors.ts → template.errors.js} +22 -20
- package/src/lib/interfaces/{module-config.interface.ts → module-config.interface.d.ts} +2 -10
- package/src/lib/interfaces/module-config.interface.d.ts.map +1 -0
- package/src/lib/interfaces/module-config.interface.js +2 -0
- package/src/lib/interfaces/template.types.d.ts +23 -0
- package/src/lib/interfaces/template.types.d.ts.map +1 -0
- package/src/lib/interfaces/template.types.js +24 -0
- package/src/lib/nest-dynamic-templates.module.d.ts +11 -0
- package/src/lib/nest-dynamic-templates.module.d.ts.map +1 -0
- package/src/lib/nest-dynamic-templates.module.js +131 -0
- package/src/lib/services/template-config.service.d.ts +55 -0
- package/src/lib/services/template-config.service.d.ts.map +1 -0
- package/src/lib/services/{template-config.service.ts → template-config.service.js} +32 -43
- package/src/lib/services/template-engine.registry.d.ts +22 -0
- package/src/lib/services/template-engine.registry.d.ts.map +1 -0
- package/src/lib/services/template-engine.registry.js +93 -0
- package/src/lib/services/template-layout.service.d.ts +37 -0
- package/src/lib/services/template-layout.service.d.ts.map +1 -0
- package/src/lib/services/{template-layout.service.ts → template-layout.service.js} +101 -165
- package/src/lib/services/template.service.d.ts +39 -0
- package/src/lib/services/template.service.d.ts.map +1 -0
- package/src/lib/services/{template.service.ts → template.service.js} +137 -199
- package/src/test/helpers.d.ts +5 -0
- package/src/test/helpers.d.ts.map +1 -0
- package/src/test/{helpers.ts → helpers.js} +7 -5
- package/src/test/test-database.config.d.ts +5 -0
- package/src/test/test-database.config.d.ts.map +1 -0
- package/src/test/test-database.config.js +23 -0
- package/src/test/test.setup.d.ts +4 -0
- package/src/test/test.setup.d.ts.map +1 -0
- package/src/test/test.setup.js +30 -0
- package/eslint.config.mjs +0 -22
- package/jest.config.ts +0 -10
- package/project.json +0 -38
- package/src/lib/constant.ts +0 -2
- package/src/lib/dto/create-template-layout.dto.ts +0 -65
- package/src/lib/dto/create-template.dto.ts +0 -80
- package/src/lib/dto/render-content-template-layout.dto.ts +0 -32
- package/src/lib/dto/render-content-template.dto.ts +0 -37
- package/src/lib/dto/render-template-layout.dto.ts +0 -55
- package/src/lib/dto/render-template.dto.ts +0 -74
- package/src/lib/dto/template-filter.dto.ts +0 -52
- package/src/lib/dto/template-layout-filter.dto.ts +0 -51
- package/src/lib/engines/language/html.engine.ts +0 -49
- package/src/lib/engines/language/markdown.engine.ts +0 -37
- package/src/lib/engines/language/mjml.engine.ts +0 -44
- package/src/lib/engines/language/text.engine.ts +0 -15
- package/src/lib/engines/template/ejs.engine.ts +0 -33
- package/src/lib/engines/template/handlebars.engine.ts +0 -35
- package/src/lib/engines/template/pug.engine.ts +0 -43
- package/src/lib/entities/template-layout.entity.ts +0 -99
- package/src/lib/entities/template.entity.ts +0 -105
- package/src/lib/interfaces/template.types.ts +0 -25
- package/src/lib/nest-dynamic-templates.module.ts +0 -143
- package/src/lib/services/template-engine.registry.ts +0 -109
- package/src/test/nunjucks.service.spec.ts +0 -157
- package/src/test/pug.service.spec-temp +0 -254
- package/src/test/template-layout.service.spec.ts +0 -422
- package/src/test/template.service.spec.ts +0 -862
- package/src/test/test-database.config.ts +0 -24
- package/src/test/test-database.d.ts +0 -6
- package/src/test/test.setup.ts +0 -34
- package/src/types/ioredis.d.ts +0 -6
- package/src/types/mjml.d.ts +0 -5
- package/tsconfig.json +0 -17
- package/tsconfig.lib.json +0 -14
- package/tsconfig.spec.json +0 -15
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
import { DataSource, Repository } from 'typeorm';
|
|
2
|
-
import { createTestModule } from './test.setup';
|
|
3
|
-
import { TemplateService } from '../lib/services/template.service';
|
|
4
|
-
import { NestDynamicTemplate } from '../lib/entities/template.entity';
|
|
5
|
-
import { TemplateTypeEnum, TemplateEngineEnum, TemplateLanguageEnum } from '../lib/interfaces/template.types';
|
|
6
|
-
import { CreateTemplateDto } from '../lib/dto/create-template.dto';
|
|
7
|
-
import { engineFilters } from './helpers';
|
|
8
|
-
|
|
9
|
-
describe('Nunjucks Engine', () => {
|
|
10
|
-
let service: TemplateService;
|
|
11
|
-
let dataSource: DataSource;
|
|
12
|
-
let templateRepository: Repository<NestDynamicTemplate>;
|
|
13
|
-
|
|
14
|
-
const testTemplate: CreateTemplateDto = {
|
|
15
|
-
name: 'test-template',
|
|
16
|
-
displayName: 'Test Template',
|
|
17
|
-
content: 'Hello {{name}}!',
|
|
18
|
-
type: TemplateTypeEnum.EMAIL,
|
|
19
|
-
engine: TemplateEngineEnum.NUNJUCKS,
|
|
20
|
-
language: TemplateLanguageEnum.HTML,
|
|
21
|
-
scope: 'system',
|
|
22
|
-
scopeId: null,
|
|
23
|
-
locale: 'en',
|
|
24
|
-
isActive: true
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
beforeEach(async () => {
|
|
28
|
-
const moduleRef = await createTestModule({
|
|
29
|
-
enginesOptions: {
|
|
30
|
-
filters: engineFilters
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
service = moduleRef.get<TemplateService>(TemplateService);
|
|
35
|
-
dataSource = moduleRef.get<DataSource>(DataSource);
|
|
36
|
-
templateRepository = dataSource.getRepository(NestDynamicTemplate);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
afterEach(async () => {
|
|
40
|
-
// Clean up templates
|
|
41
|
-
await templateRepository.delete('1 = 1');
|
|
42
|
-
|
|
43
|
-
// Clean up database after each test
|
|
44
|
-
await dataSource.synchronize(true);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
afterAll(async () => {
|
|
48
|
-
// Close the connection after all tests
|
|
49
|
-
await dataSource.destroy();
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
describe('Nunjucks Custom Filters', () => {
|
|
53
|
-
it('should format date using custom date filter', async () => {
|
|
54
|
-
// Create template with date filter
|
|
55
|
-
const template = await service.createTemplate({
|
|
56
|
-
...testTemplate,
|
|
57
|
-
name: 'date-template',
|
|
58
|
-
content: 'Today is {{ date | formatDate("YYYY-MM-DD") }}',
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
const today = new Date();
|
|
62
|
-
const expectedDate = today.toISOString().split('T')[0]; // YYYY-MM-DD format
|
|
63
|
-
|
|
64
|
-
const result = await service.render({
|
|
65
|
-
name: 'date-template',
|
|
66
|
-
scope: 'system',
|
|
67
|
-
context: {
|
|
68
|
-
date: today
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
expect(result.content).toBe(`Today is ${expectedDate}`);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it('should format currency using custom currency filter', async () => {
|
|
76
|
-
// Create template with currency filter
|
|
77
|
-
const template = await service.createTemplate({
|
|
78
|
-
...testTemplate,
|
|
79
|
-
name: 'currency-template',
|
|
80
|
-
content: 'Price: {{ amount | formatCurrency("USD") }}',
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
const result = await service.render({
|
|
84
|
-
name: 'currency-template',
|
|
85
|
-
scope: 'system',
|
|
86
|
-
context: {
|
|
87
|
-
amount: 1234.56
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
expect(result.content).toBe('Price: $1,234.56');
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('should handle multiple filters in the same template', async () => {
|
|
95
|
-
// Create template with multiple filters
|
|
96
|
-
const template = await service.createTemplate({
|
|
97
|
-
...testTemplate,
|
|
98
|
-
name: 'multi-filter-template',
|
|
99
|
-
content: 'Order placed on {{ date | formatDate("YYYY-MM-DD") }} for {{ amount | formatCurrency("USD") }}',
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
const today = new Date();
|
|
103
|
-
const expectedDate = today.toISOString().split('T')[0];
|
|
104
|
-
|
|
105
|
-
const result = await service.render({
|
|
106
|
-
name: 'multi-filter-template',
|
|
107
|
-
scope: 'system',
|
|
108
|
-
context: {
|
|
109
|
-
date: today,
|
|
110
|
-
amount: 1234.56
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
expect(result.content).toBe(`Order placed on ${expectedDate} for $1,234.56`);
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
it('should handle different currency formats', async () => {
|
|
118
|
-
// Create template with different currency formats
|
|
119
|
-
const template = await service.createTemplate({
|
|
120
|
-
...testTemplate,
|
|
121
|
-
name: 'currency-formats-template',
|
|
122
|
-
content: 'USD: {{ usd | formatCurrency("USD") }}, EUR: {{ eur | formatCurrency("EUR") }}',
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
const result = await service.render({
|
|
126
|
-
name: 'currency-formats-template',
|
|
127
|
-
scope: 'system',
|
|
128
|
-
context: {
|
|
129
|
-
usd: 1234.56,
|
|
130
|
-
eur: 1234.56,
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
expect(result.content).toBe('USD: $1,234.56, EUR: €1,234.56');
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
it('should handle different date formats', async () => {
|
|
138
|
-
// Create template with different date formats
|
|
139
|
-
const template = await service.createTemplate({
|
|
140
|
-
...testTemplate,
|
|
141
|
-
name: 'date-formats-template',
|
|
142
|
-
content: 'Short: {{ date | formatDate("MM/DD/YY") }}, Long: {{ date | formatDate("MMMM D, YYYY") }}, ISO: {{ date | formatDate("YYYY-MM-DD") }}',
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
const date = new Date('2024-03-15');
|
|
146
|
-
const result = await service.render({
|
|
147
|
-
name: 'date-formats-template',
|
|
148
|
-
scope: 'system',
|
|
149
|
-
context: {
|
|
150
|
-
date: date
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
expect(result.content).toBe('Short: 03/15/24, Long: March 15, 2024, ISO: 2024-03-15');
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
});
|
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
import { DataSource, Repository } from 'typeorm';
|
|
2
|
-
import { createTestModule } from './test.setup';
|
|
3
|
-
import { TemplateService } from '../lib/services/template.service';
|
|
4
|
-
import { NestDynamicTemplate } from '../lib/entities/template.entity';
|
|
5
|
-
import { TemplateTypeEnum, TemplateEngineEnum, TemplateLanguageEnum } from '../lib/interfaces/template.types';
|
|
6
|
-
import { CreateTemplateDto } from '../lib/dto/create-template.dto';
|
|
7
|
-
import { engineFilters } from './helpers';
|
|
8
|
-
|
|
9
|
-
describe('Pug Engine', () => {
|
|
10
|
-
let service: TemplateService;
|
|
11
|
-
let dataSource: DataSource;
|
|
12
|
-
let templateRepository: Repository<NestDynamicTemplate>;
|
|
13
|
-
|
|
14
|
-
const testTemplate: CreateTemplateDto = {
|
|
15
|
-
name: 'test-template',
|
|
16
|
-
displayName: 'Test Template',
|
|
17
|
-
content: 'p Hello #{name}!',
|
|
18
|
-
type: TemplateTypeEnum.EMAIL,
|
|
19
|
-
engine: TemplateEngineEnum.PUG,
|
|
20
|
-
language: TemplateLanguageEnum.HTML,
|
|
21
|
-
scope: 'system',
|
|
22
|
-
scopeId: null,
|
|
23
|
-
locale: 'en',
|
|
24
|
-
isActive: true
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
beforeEach(async () => {
|
|
28
|
-
const moduleRef = await createTestModule({
|
|
29
|
-
engines: {
|
|
30
|
-
template: [TemplateEngineEnum.PUG],
|
|
31
|
-
},
|
|
32
|
-
enginesOptions: {
|
|
33
|
-
filters: engineFilters,
|
|
34
|
-
template: {
|
|
35
|
-
[TemplateEngineEnum.PUG]: {
|
|
36
|
-
pretty: true,
|
|
37
|
-
compileDebug: true
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
service = moduleRef.get<TemplateService>(TemplateService);
|
|
44
|
-
dataSource = moduleRef.get<DataSource>(DataSource);
|
|
45
|
-
templateRepository = dataSource.getRepository(NestDynamicTemplate);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
afterEach(async () => {
|
|
49
|
-
// Clean up templates
|
|
50
|
-
await templateRepository.delete('1 = 1');
|
|
51
|
-
|
|
52
|
-
// Clean up database after each test
|
|
53
|
-
await dataSource.synchronize(true);
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
afterAll(async () => {
|
|
57
|
-
// Close the connection after all tests
|
|
58
|
-
await dataSource.destroy();
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
describe('Pug Custom Filters', () => {
|
|
62
|
-
it('should format date using custom date filter', async () => {
|
|
63
|
-
const template = await service.createTemplate({
|
|
64
|
-
...testTemplate,
|
|
65
|
-
name: 'date-template',
|
|
66
|
-
content: 'p Today is #{formatDate(date, "YYYY-MM-DD")}',
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
const today = new Date();
|
|
70
|
-
const expectedDate = today.toISOString().split('T')[0];
|
|
71
|
-
|
|
72
|
-
const result = await service.render({
|
|
73
|
-
type: TemplateTypeEnum.EMAIL,
|
|
74
|
-
name: 'date-template',
|
|
75
|
-
scope: 'system',
|
|
76
|
-
context: {
|
|
77
|
-
date: today
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
expect(result.content).toBe(`<p>Today is ${expectedDate}</p>`);
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it('should format currency using custom currency filter', async () => {
|
|
85
|
-
const template = await service.createTemplate({
|
|
86
|
-
...testTemplate,
|
|
87
|
-
name: 'currency-template',
|
|
88
|
-
content: 'p Price: #{formatCurrency(amount, "USD")}',
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
const result = await service.render({
|
|
92
|
-
type: TemplateTypeEnum.EMAIL,
|
|
93
|
-
name: 'currency-template',
|
|
94
|
-
scope: 'system',
|
|
95
|
-
context: {
|
|
96
|
-
amount: 1234.56
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
expect(result.content).toBe('<p>Price: $1,234.56</p>');
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it('should handle multiple filters in the same template', async () => {
|
|
104
|
-
const template = await service.createTemplate({
|
|
105
|
-
...testTemplate,
|
|
106
|
-
name: 'multi-filter-template',
|
|
107
|
-
content: 'p Order placed on #{formatDate(date, "YYYY-MM-DD")} for #{formatCurrency(amount, "USD")}',
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
const today = new Date();
|
|
111
|
-
const expectedDate = today.toISOString().split('T')[0];
|
|
112
|
-
|
|
113
|
-
const result = await service.render({
|
|
114
|
-
type: TemplateTypeEnum.EMAIL,
|
|
115
|
-
name: 'multi-filter-template',
|
|
116
|
-
scope: 'system',
|
|
117
|
-
context: {
|
|
118
|
-
date: today,
|
|
119
|
-
amount: 1234.56
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
expect(result.content).toBe(`<p>Order placed on ${expectedDate} for $1,234.56</p>`);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
it('should handle different currency formats', async () => {
|
|
127
|
-
const template = await service.createTemplate({
|
|
128
|
-
...testTemplate,
|
|
129
|
-
name: 'currency-formats-template',
|
|
130
|
-
content: 'p USD: #{formatCurrency(usd, "USD")}, EUR: #{formatCurrency(eur, "EUR")}',
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
const result = await service.render({
|
|
134
|
-
type: TemplateTypeEnum.EMAIL,
|
|
135
|
-
name: 'currency-formats-template',
|
|
136
|
-
scope: 'system',
|
|
137
|
-
context: {
|
|
138
|
-
usd: 1234.56,
|
|
139
|
-
eur: 1234.56
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
expect(result.content).toBe('<p>USD: $1,234.56, EUR: €1,234.56</p>');
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
it('should handle different date formats', async () => {
|
|
147
|
-
const template = await service.createTemplate({
|
|
148
|
-
...testTemplate,
|
|
149
|
-
name: 'date-formats-template',
|
|
150
|
-
content: 'p Short: #{formatDate(date, "MM/DD/YY")}, Long: #{formatDate(date, "MMMM D, YYYY")}, ISO: #{formatDate(date, "YYYY-MM-DD")}',
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
const date = new Date('2024-03-15');
|
|
154
|
-
const result = await service.render({
|
|
155
|
-
type: TemplateTypeEnum.EMAIL,
|
|
156
|
-
name: 'date-formats-template',
|
|
157
|
-
scope: 'system',
|
|
158
|
-
context: {
|
|
159
|
-
date: date
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
expect(result.content).toBe('<p>Short: 03/15/24, Long: March 15, 2024, ISO: 2024-03-15</p>');
|
|
164
|
-
});
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
describe('Pug HTML Features', () => {
|
|
168
|
-
// Custom matcher to check HTML structure
|
|
169
|
-
const expectHtmlStructure = (received: string, expected: string) => {
|
|
170
|
-
const normalizeHtml = (html: string) => {
|
|
171
|
-
return html
|
|
172
|
-
.replace(/\s+/g, ' ')
|
|
173
|
-
.replace(/>\s+</g, '><')
|
|
174
|
-
.trim();
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
const receivedNormalized = normalizeHtml(received);
|
|
178
|
-
const expectedNormalized = normalizeHtml(expected);
|
|
179
|
-
|
|
180
|
-
// Extract attributes and compare them regardless of order
|
|
181
|
-
const getAttributes = (html: string) => {
|
|
182
|
-
const match = html.match(/<[^>]+>/);
|
|
183
|
-
if (!match) return [];
|
|
184
|
-
return match[0]
|
|
185
|
-
.replace(/<[^\s>]+/, '')
|
|
186
|
-
.replace(/>$/, '')
|
|
187
|
-
.trim()
|
|
188
|
-
.split(/\s+/)
|
|
189
|
-
.sort();
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
const receivedAttrs = getAttributes(receivedNormalized);
|
|
193
|
-
const expectedAttrs = getAttributes(expectedNormalized);
|
|
194
|
-
|
|
195
|
-
expect(receivedAttrs).toEqual(expectedAttrs);
|
|
196
|
-
expect(receivedNormalized.replace(/<[^>]+>/, '')).toBe(expectedNormalized.replace(/<[^>]+>/, ''));
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
it('should render nested HTML tags', async () => {
|
|
200
|
-
const template = await service.createTemplate({
|
|
201
|
-
...testTemplate,
|
|
202
|
-
name: 'nested-html-template',
|
|
203
|
-
content: 'div\n h1 Title\n p This is a paragraph.'
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
const result = await service.render({
|
|
207
|
-
type: TemplateTypeEnum.EMAIL,
|
|
208
|
-
name: 'nested-html-template',
|
|
209
|
-
scope: 'system',
|
|
210
|
-
context: {}
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
expect(result.content.replace(/\n/g, ''))
|
|
214
|
-
.toBe('<div><h1>Title</h1><p>This is a paragraph.</p></div>');
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
it('should render HTML with attributes', async () => {
|
|
218
|
-
const template = await service.createTemplate({
|
|
219
|
-
...testTemplate,
|
|
220
|
-
name: 'attributes-html-template',
|
|
221
|
-
content: 'a(href="https://example.com" target="_blank") Example Link'
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
const result = await service.render({
|
|
225
|
-
type: TemplateTypeEnum.EMAIL,
|
|
226
|
-
name: 'attributes-html-template',
|
|
227
|
-
scope: 'system',
|
|
228
|
-
context: {}
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
expect(result.content).toBe('<a href="https://example.com" target="_blank">Example Link</a>');
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
it('should render HTML with classes and ids', async () => {
|
|
235
|
-
const template = await service.createTemplate({
|
|
236
|
-
...testTemplate,
|
|
237
|
-
name: 'class-id-html-template',
|
|
238
|
-
content: 'div#main.container Main content'
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
const result = await service.render({
|
|
242
|
-
type: TemplateTypeEnum.EMAIL,
|
|
243
|
-
name: 'class-id-html-template',
|
|
244
|
-
scope: 'system',
|
|
245
|
-
context: {}
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
expectHtmlStructure(
|
|
249
|
-
result.content,
|
|
250
|
-
'<div class="container" id="main">Main content</div>'
|
|
251
|
-
);
|
|
252
|
-
});
|
|
253
|
-
});
|
|
254
|
-
});
|