112 lines
3.7 KiB
Go
112 lines
3.7 KiB
Go
package service
|
||
|
||
import (
|
||
"strings"
|
||
"testing"
|
||
|
||
"github.com/stretchr/testify/assert"
|
||
"github.com/stretchr/testify/require"
|
||
"github.com/tcs-iptv/tcs/internal/chain"
|
||
"github.com/tcs-iptv/tcs/internal/cccode"
|
||
)
|
||
|
||
func newService(t *testing.T) *Service {
|
||
t.Helper()
|
||
gen := cccode.NewGenerator(cccode.NewMemoryStore())
|
||
require.NoError(t, gen.RegisterSegment(cccode.Segment{
|
||
IndustryNode: "8531", OrgNode: "4401",
|
||
Category: cccode.CategoryMicroDrama, Start: 1, End: 100, SeqWidth: 7,
|
||
}))
|
||
return New(chain.NewMemoryChain(), gen)
|
||
}
|
||
|
||
func sampleSub() Submission {
|
||
return Submission{
|
||
Title: "示例微短剧", EpisodeCount: 24, Category: cccode.CategoryMicroDrama,
|
||
FileHash: "filehash-abc", MerkleRoot: "merkle-abc", Perceptual: "phash-abc",
|
||
CPMediaID: "FS-MEDIA-77821", CPName: "飞翮信息",
|
||
}
|
||
}
|
||
|
||
func TestSubmit_IncompleteHashRejected(t *testing.T) {
|
||
s := newService(t)
|
||
_, err := s.SubmitForReview(Submission{Title: "无哈希", Category: cccode.CategoryMicroDrama})
|
||
assert.ErrorIs(t, err, ErrIncompleteHashPkg)
|
||
}
|
||
|
||
func TestSubmit_Success(t *testing.T) {
|
||
s := newService(t)
|
||
res, err := s.SubmitForReview(sampleSub())
|
||
require.NoError(t, err)
|
||
assert.NotEmpty(t, res.ReviewID)
|
||
assert.NotEmpty(t, res.ContentTwinID)
|
||
assert.Equal(t, "pending", res.Status)
|
||
}
|
||
|
||
func TestApproveAndIssue_GeneratesCCCode(t *testing.T) {
|
||
s := newService(t)
|
||
sub, err := s.SubmitForReview(sampleSub())
|
||
require.NoError(t, err)
|
||
require.NoError(t, s.ReviewCSPS(sub.ReviewID, true, "rv-1"))
|
||
|
||
issued, err := s.ApproveAndIssue(chain.RoleRegulator, sub.ReviewID, "北京市广播电视局")
|
||
require.NoError(t, err)
|
||
// 模式B:MA 码由系统按号段生成
|
||
assert.True(t, cccode.IsValid(issued.CCCode), "应生成合法 MA 码: %s", issued.CCCode)
|
||
assert.True(t, strings.HasPrefix(issued.CCCode, "MA.156.8531.4401/WD/"), "前缀应匹配号段: %s", issued.CCCode)
|
||
assert.NotEmpty(t, issued.TxID)
|
||
assert.Contains(t, issued.Certificate, issued.CCCode)
|
||
}
|
||
|
||
func TestApproveAndIssue_OnlyRegulator(t *testing.T) {
|
||
s := newService(t)
|
||
sub, _ := s.SubmitForReview(sampleSub())
|
||
require.NoError(t, s.ReviewCSPS(sub.ReviewID, true, "rv-1")) // 先过审,才轮到校验角色
|
||
_, err := s.ApproveAndIssue(chain.RoleCP, sub.ReviewID, "x")
|
||
assert.ErrorIs(t, err, chain.ErrPermissionDenied)
|
||
}
|
||
|
||
func TestSubmit_DuplicateRejectedAfterIssue(t *testing.T) {
|
||
s := newService(t)
|
||
sub, _ := s.SubmitForReview(sampleSub())
|
||
require.NoError(t, s.ReviewCSPS(sub.ReviewID, true, "rv-1"))
|
||
_, err := s.ApproveAndIssue(chain.RoleRegulator, sub.ReviewID, "issuer")
|
||
require.NoError(t, err)
|
||
|
||
// 同哈希再次送审 → 换壳重发拦截
|
||
_, err = s.SubmitForReview(sampleSub())
|
||
assert.ErrorIs(t, err, ErrDuplicateContent)
|
||
}
|
||
|
||
func TestVerify_MatchAndMismatch(t *testing.T) {
|
||
s := newService(t)
|
||
sub, _ := s.SubmitForReview(sampleSub())
|
||
require.NoError(t, s.ReviewCSPS(sub.ReviewID, true, "rv-1"))
|
||
issued, _ := s.ApproveAndIssue(chain.RoleRegulator, sub.ReviewID, "issuer")
|
||
|
||
res, err := s.Verify(issued.CCCode, "filehash-abc")
|
||
require.NoError(t, err)
|
||
assert.True(t, res.Match)
|
||
|
||
_, err = s.Verify(issued.CCCode, "tampered")
|
||
assert.ErrorIs(t, err, ErrHashMismatch)
|
||
}
|
||
|
||
func TestApproveAndIssue_TwoContentsUniqueCodes(t *testing.T) {
|
||
s := newService(t)
|
||
sub1, _ := s.SubmitForReview(sampleSub())
|
||
require.NoError(t, s.ReviewCSPS(sub1.ReviewID, true, "rv-1"))
|
||
i1, err := s.ApproveAndIssue(chain.RoleRegulator, sub1.ReviewID, "issuer")
|
||
require.NoError(t, err)
|
||
|
||
sub2v := sampleSub()
|
||
sub2v.FileHash = "filehash-def"
|
||
sub2v.MerkleRoot = "merkle-def"
|
||
sub2, _ := s.SubmitForReview(sub2v)
|
||
require.NoError(t, s.ReviewCSPS(sub2.ReviewID, true, "rv-1"))
|
||
i2, err := s.ApproveAndIssue(chain.RoleRegulator, sub2.ReviewID, "issuer")
|
||
require.NoError(t, err)
|
||
|
||
assert.NotEqual(t, i1.CCCode, i2.CCCode, "两条内容应分配不同 MA 码")
|
||
}
|