Files
MAcode/tcs-iptv/internal/macode/macode_test.go
T
selfrelease a329d4906b init: AIGC-Hub/AVCC 方案文档 + TCS-IPTV 内容可信锁定系统 MVP
- 方案文档: AVCC 体系建设、IPTV TCS 需求(0-req)/PRD(1-prd)/任务(2-task)/二三四期任务
- tcs-iptv: Go 后端(哈希SDK/MA码生成/可信数据空间mock/业务编排/HTTP API+HMAC鉴权)
- web-console: React+AntD 监管大屏(角色工作台/全流程演示/监管片库)
- 一剧一码+集级哈希, 集级下架/恢复, 全栈测试通过
2026-06-14 16:50:31 +08:00

136 lines
3.8 KiB
Go

package macode
import (
"sync"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// fixedTime 固定为 2025 年,便于断言年份段。
var fixedTime = time.Date(2025, 6, 1, 0, 0, 0, 0, time.UTC)
func newGen(t *testing.T) *Generator {
t.Helper()
g := NewGenerator(NewMemoryStore())
require.NoError(t, g.RegisterSegment(Segment{
IndustryNode: "8531", OrgNode: "4401", Category: CategoryMicroDrama,
Start: 1, End: 100, SeqWidth: 7,
}))
// 固定年份便于断言
g.clock = func() time.Time { return fixedTime }
return g
}
func TestAllocate_SequentialUnique(t *testing.T) {
g := newGen(t)
seen := make(map[string]bool)
for i := 0; i < 50; i++ {
issued, err := g.Allocate(CategoryMicroDrama)
require.NoError(t, err)
assert.False(t, seen[issued.MACode], "MA 码必须唯一: %s", issued.MACode)
seen[issued.MACode] = true
assert.True(t, IsValid(issued.MACode), "应符合格式: %s", issued.MACode)
}
assert.Len(t, seen, 50)
}
func TestAllocate_FormatCorrect(t *testing.T) {
g := newGen(t)
issued, err := g.Allocate(CategoryMicroDrama)
require.NoError(t, err)
assert.Equal(t, "MA.156.8531.4401/WD/20250000001", issued.MACode)
assert.Equal(t, uint64(1), issued.Sequence)
assert.Equal(t, 2025, issued.Year)
}
func TestAllocate_UnknownCategory(t *testing.T) {
g := newGen(t)
_, err := g.Allocate("XX")
assert.ErrorIs(t, err, ErrUnknownCategory)
}
func TestAllocate_SegmentExhausted(t *testing.T) {
g := NewGenerator(NewMemoryStore())
g.clock = func() time.Time { return fixedTime }
require.NoError(t, g.RegisterSegment(Segment{
IndustryNode: "8531", OrgNode: "4401", Category: CategoryWebMovie,
Start: 1, End: 2, SeqWidth: 5,
}))
_, err := g.Allocate(CategoryWebMovie)
require.NoError(t, err)
_, err = g.Allocate(CategoryWebMovie)
require.NoError(t, err)
_, err = g.Allocate(CategoryWebMovie) // 第3个超出 [1,2]
assert.ErrorIs(t, err, ErrSegmentExhausted)
}
func TestAllocate_ConcurrentNoDuplicate(t *testing.T) {
g := NewGenerator(NewMemoryStore())
g.clock = func() time.Time { return fixedTime }
require.NoError(t, g.RegisterSegment(Segment{
IndustryNode: "8531", OrgNode: "4401", Category: CategoryWebSeries,
Start: 1, End: 1000, SeqWidth: 7,
}))
var wg sync.WaitGroup
var mu sync.Mutex
seen := make(map[string]bool)
dup := 0
for i := 0; i < 200; i++ {
wg.Add(1)
go func() {
defer wg.Done()
issued, err := g.Allocate(CategoryWebSeries)
if err != nil {
return
}
mu.Lock()
if seen[issued.MACode] {
dup++
}
seen[issued.MACode] = true
mu.Unlock()
}()
}
wg.Wait()
assert.Equal(t, 0, dup, "并发分配不得出现重号")
assert.Len(t, seen, 200)
}
func TestParse_RoundTrip(t *testing.T) {
seg := Segment{IndustryNode: "8531", OrgNode: "4401", Category: CategoryMicroDrama, SeqWidth: 7}
code := Format(seg, 2025, 123)
assert.Equal(t, "MA.156.8531.4401/WD/20250000123", code)
p, err := Parse(code)
require.NoError(t, err)
assert.Equal(t, "MA", p.Root)
assert.Equal(t, "156", p.CountryCode)
assert.Equal(t, "8531", p.IndustryNode)
assert.Equal(t, "4401", p.OrgNode)
assert.Equal(t, "WD", p.Category)
assert.Equal(t, 2025, p.Year)
assert.Equal(t, uint64(123), p.Sequence)
}
func TestParse_Invalid(t *testing.T) {
bad := []string{
"", "MA.156", "MA.156.8531.4401/WD", "(京)网微剧审字(2025)第123号",
"MA.156.8531.4401/wd/20250000123", // 类目须大写两位
}
for _, b := range bad {
_, err := Parse(b)
assert.Error(t, err, "应判为非法: %q", b)
assert.False(t, IsValid(b))
}
}
func TestSegment_Validate(t *testing.T) {
assert.Error(t, Segment{}.Validate())
assert.Error(t, Segment{IndustryNode: "1", OrgNode: "2", Category: "WD", Start: 10, End: 5}.Validate())
assert.NoError(t, Segment{IndustryNode: "1", OrgNode: "2", Category: "WD", Start: 1, End: 5, SeqWidth: 7}.Validate())
}