All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m38s
83 lines
3.4 KiB
Go
83 lines
3.4 KiB
Go
package audit
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"testing"
|
|
|
|
"gorm.io/gorm"
|
|
|
|
accessauditapp "github.com/break/junhong_cmp_fiber/internal/application/accessaudit"
|
|
"github.com/break/junhong_cmp_fiber/internal/model"
|
|
"github.com/break/junhong_cmp_fiber/pkg/auditfailure"
|
|
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
|
)
|
|
|
|
func TestAppendFailureDoesNotReturnToBusiness(t *testing.T) {
|
|
writer := NewWriter(nil, nil)
|
|
input := AppendInput{ActionCode: "missing_action"}
|
|
before := auditfailure.SecondaryWriteFailureCount()
|
|
if err := writer.Append(context.Background(), nil, input); err != nil {
|
|
t.Fatalf("Append 返回审计失败: %v", err)
|
|
}
|
|
if err := writer.WriteAccessChange(context.Background(), nil, accessauditapp.ChangeAudit{
|
|
ActionCode: constants.AuditActionPersonalCustomerAssetBound,
|
|
OperatorID: 1,
|
|
}); err != nil {
|
|
t.Fatalf("资源构造失败返回业务: %v", err)
|
|
}
|
|
if got := auditfailure.SecondaryWriteFailureCount(); got != before+2 {
|
|
t.Fatalf("二次失败记录次数 = %d, want %d", got, before+2)
|
|
}
|
|
if _, err := writer.AppendAndGet(context.Background(), nil, input); err == nil {
|
|
t.Fatal("AppendAndGet 未保留错误语义")
|
|
}
|
|
}
|
|
|
|
func TestPersonalCustomerAssetBoundProjectsOnlyPersonalResources(t *testing.T) {
|
|
action, ok := NewRegistry().Action(constants.AuditActionPersonalCustomerAssetBound)
|
|
if !ok {
|
|
t.Fatal("未注册个人客户资产绑定审计动作")
|
|
}
|
|
resources, err := accessResources(accessauditapp.ChangeAudit{
|
|
ActionCode: constants.AuditActionPersonalCustomerAssetBound,
|
|
PersonalCustomer: &model.PersonalCustomer{Model: gorm.Model{ID: 1}, Nickname: "客户"},
|
|
PersonalDevices: []accessauditapp.PersonalCustomerDeviceChange{{
|
|
Binding: &model.PersonalCustomerDevice{Model: gorm.Model{ID: 2}, CustomerID: 1, VirtualNo: "DEVICE-1"},
|
|
}},
|
|
PersonalICCIDs: []accessauditapp.PersonalCustomerICCIDChange{{
|
|
Binding: &model.PersonalCustomerICCID{Model: gorm.Model{ID: 3}, CustomerID: 1, ICCID: "ICCID-1"},
|
|
}},
|
|
SubjectVisibility: constants.AuditSubjectDetail,
|
|
SubjectSummary: "绑定个人客户资产",
|
|
SubjectData: map[string]any{"asset_type": constants.AuditResourceIotCard, "asset_id": uint(9)},
|
|
}, action.PrimaryResource)
|
|
if err != nil {
|
|
t.Fatalf("构造绑定审计资源失败: %v", err)
|
|
}
|
|
projected, err := NewWriter(nil, nil).buildResources(resources, action)
|
|
if err != nil {
|
|
t.Fatalf("构造绑定审计投影失败: %v", err)
|
|
}
|
|
want := map[string]bool{
|
|
constants.AuditResourcePersonalCustomer: true,
|
|
constants.AuditResourcePersonalCustomerDevice: true,
|
|
constants.AuditResourcePersonalCustomerICCID: true,
|
|
}
|
|
for _, resource := range projected {
|
|
if resource.ResourceType == constants.AuditResourceIotCard || resource.ResourceType == constants.AuditResourceDevice {
|
|
t.Fatalf("绑定审计投影包含内部资源: %s", resource.ResourceType)
|
|
}
|
|
delete(want, resource.ResourceType)
|
|
if resource.ResourceType == constants.AuditResourcePersonalCustomer {
|
|
var subjectData map[string]any
|
|
if err := json.Unmarshal(resource.SubjectData, &subjectData); err != nil || resource.SubjectVisibility != constants.AuditSubjectDetail || subjectData["asset_type"] != constants.AuditResourceIotCard || subjectData["asset_id"] != float64(9) {
|
|
t.Fatalf("主个人客户主体投影不完整: %#v", resource)
|
|
}
|
|
}
|
|
}
|
|
for resourceType := range want {
|
|
t.Fatalf("绑定审计投影缺少合法资源: %s", resourceType)
|
|
}
|
|
}
|