256 lines
5.9 KiB
Go
256 lines
5.9 KiB
Go
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)
|
||
}
|
||
})
|
||
}
|
||
}
|