backend/pkg/notification/usecase/template_test.go

256 lines
5.9 KiB
Go
Raw Normal View History

2025-10-22 13:40:31 +00:00
package usecase
import (
"backend/pkg/notification/domain/entity"
"backend/pkg/notification/domain/template"
"backend/pkg/notification/domain/usecase"
"context"
"testing"
"github.com/stretchr/testify/assert"
)
func TestTemplateUseCase_RenderEmailTemplate(t *testing.T) {
uc := MustTemplateUseCase(TemplateUseCaseParam{
TemplateRepo: nil,
})
ctx := context.Background()
tests := []struct {
name string
tmpl template.EmailTemplate
params entity.TemplateParams
expectedSubj string
expectedBody string
shouldContain []string
shouldNotError bool
}{
{
name: "渲染基本參數",
tmpl: template.EmailTemplate{
Title: "Hello {{.Username}}",
Body: "<p>Your code is: {{.VerifyCode}}</p>",
},
params: entity.TemplateParams{
Username: "張三",
VerifyCode: "123456",
},
expectedSubj: "Hello 張三",
shouldContain: []string{"123456"},
shouldNotError: true,
},
{
name: "渲染額外參數",
tmpl: template.EmailTemplate{
Title: "Welcome",
Body: "<p>Hello {{.Username}}, your link: {{.Link}}</p>",
},
params: entity.TemplateParams{
Username: "John",
Extra: map[string]string{
"Link": "https://example.com",
},
},
shouldContain: []string{"John", "https://example.com"},
shouldNotError: true,
},
{
name: "特殊字符不轉義(簡單字符串替換)",
tmpl: template.EmailTemplate{
Title: "Test",
Body: "<p>Name: {{.Username}}</p>",
},
params: entity.TemplateParams{
Username: "<script>alert('xss')</script>",
},
shouldContain: []string{"<script>alert('xss')</script>"}, // 使用簡單字符串替換,不轉義
shouldNotError: true,
},
{
name: "空模板",
tmpl: template.EmailTemplate{
Title: "",
Body: "",
},
params: entity.TemplateParams{
Username: "Test",
},
expectedSubj: "",
expectedBody: "",
shouldNotError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := uc.RenderEmailTemplate(ctx, tt.tmpl, tt.params)
if tt.shouldNotError {
assert.NoError(t, err)
if tt.expectedSubj != "" {
assert.Equal(t, tt.expectedSubj, result.Subject)
}
if tt.expectedBody != "" {
assert.Equal(t, tt.expectedBody, result.Body)
}
for _, contain := range tt.shouldContain {
assert.Contains(t, result.Body, contain)
}
} else {
assert.Error(t, err)
}
})
}
}
func TestTemplateUseCase_RenderSMSTemplate(t *testing.T) {
uc := MustTemplateUseCase(TemplateUseCaseParam{
TemplateRepo: nil,
})
ctx := context.Background()
tests := []struct {
name string
tmpl usecase.SMSTemplateResp
params entity.TemplateParams
expectedBody string
shouldContain []string
shouldNotError bool
}{
{
name: "渲染 SMS 驗證碼",
tmpl: usecase.SMSTemplateResp{
Body: "您的驗證碼是:{{.VerifyCode}}請在5分鐘內使用。",
},
params: entity.TemplateParams{
VerifyCode: "654321",
},
shouldContain: []string{"654321", "5分鐘"},
shouldNotError: true,
},
{
name: "SMS 純文本替換",
tmpl: usecase.SMSTemplateResp{
Body: "Hi {{.Username}}, your code: {{.VerifyCode}}",
},
params: entity.TemplateParams{
Username: "<test>",
VerifyCode: "111111",
},
shouldContain: []string{"<test>", "111111"}, // 使用簡單字符串替換
shouldNotError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := uc.RenderSMSTemplate(ctx, tt.tmpl, tt.params)
if tt.shouldNotError {
assert.NoError(t, err)
if tt.expectedBody != "" {
assert.Equal(t, tt.expectedBody, result.Body)
}
for _, contain := range tt.shouldContain {
assert.Contains(t, result.Body, contain)
}
} else {
assert.Error(t, err)
}
})
}
}
func TestTemplateUseCase_GetEmailTemplateByStatic(t *testing.T) {
uc := MustTemplateUseCase(TemplateUseCaseParam{
TemplateRepo: nil,
})
ctx := context.Background()
tests := []struct {
name string
language template.Language
templateID template.Type
wantErr bool
}{
{
name: "獲取忘記密碼模板 (zh-tw)",
language: template.LanguageZhTW,
templateID: template.ForgetPasswordVerify,
wantErr: false,
},
{
name: "獲取綁定郵箱模板 (zh-tw)",
language: template.LanguageZhTW,
templateID: template.BindingEmail,
wantErr: false,
},
{
name: "不存在的語言",
language: template.Language("xx-xx"),
templateID: template.ForgetPasswordVerify,
wantErr: true,
},
{
name: "不存在的模板類型",
language: template.LanguageZhTW,
templateID: template.Type("non_existent"),
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := uc.GetEmailTemplateByStatic(ctx, tt.language, tt.templateID)
if tt.wantErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.NotEmpty(t, result.Title)
assert.NotEmpty(t, result.Body)
}
})
}
}
func TestTemplateUseCase_GetDefaultSMSTemplate(t *testing.T) {
uc := &TemplateUseCase{}
tests := []struct {
name string
templateID template.Type
shouldContain []string
}{
{
name: "忘記密碼模板",
templateID: template.ForgetPasswordVerify,
shouldContain: []string{"密碼重設", "驗證碼"},
},
{
name: "綁定郵箱模板",
templateID: template.BindingEmail,
shouldContain: []string{"綁定", "驗證碼"},
},
{
name: "默認模板",
templateID: template.Type("unknown"),
shouldContain: []string{"驗證碼"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := uc.getDefaultSMSTemplate(tt.templateID)
assert.NotEmpty(t, result.Body)
for _, contain := range tt.shouldContain {
assert.Contains(t, result.Body, contain)
}
})
}
}