package dnfbridge import ( "testing" "time" dnfdungeonadmission "longheng.io/server/internal/modules/dnf/dungeonadmission" ) // 验证周常五图的准入策略生成与开放日开关。 func TestAbisEntryPolicies(t *testing.T) { for _, spec := range abisDungeonSpecs { policies, err := abisEntryPolicies(spec, 0) if err != nil { t.Fatalf("dungeon %d: %v", spec.id, err) } if len(policies) != 2 { t.Fatalf("dungeon %d: want 2 policies, got %d", spec.id, len(policies)) } account, character := policies[0], policies[1] if account.Scope == character.Scope { t.Fatalf("dungeon %d: both policies share scope %d", spec.id, account.Scope) } t.Logf("dungeon %d %s: account key=%s limit=%d section=%q | character key=%s limit=%d section=%q", spec.id, spec.name, account.Key, account.Limit, account.SourceSection, character.Key, character.Limit, character.SourceSection) if account.Key != abisSharedAccountPolicyKey { t.Fatalf("dungeon %d: account policy key=%q want=%q (must be shared across all five)", spec.id, account.Key, abisSharedAccountPolicyKey) } if len(account.DungeonIDs) != 5 { t.Fatalf("dungeon %d: shared account policy must cover 5 dungeons, got %v", spec.id, account.DungeonIDs) } if account.Limit != abisAccountDailyBase { t.Fatalf("dungeon %d: account limit=%d want=%d", spec.id, account.Limit, abisAccountDailyBase) } if character.Limit != spec.limit { t.Fatalf("dungeon %d: character limit=%d want=%d", spec.id, character.Limit, spec.limit) } } } // 冒险团分档加成必须落在 PVF 声明的区间上。 func TestAbisAdventureGroupAddition(t *testing.T) { cases := []struct { level uint32 want uint32 }{ {0, 0}, {1, 0}, {5, 0}, {6, 1}, {10, 1}, {11, 2}, {15, 2}, {16, 3}, {20, 3}, {21, 4}, {25, 4}, {26, 5}, {30, 5}, {31, 0}, } for _, c := range cases { if got := abisAdventureGroupAddition(c.level); got != c.want { t.Errorf("manage level %d: bonus=%d want=%d", c.level, got, c.want) } } } // 06:00 服务日边界:北京 05:59 属于前一天,06:00 属于新一天。 func TestAbisServiceWindowSixAMBoundary(t *testing.T) { beijing := time.FixedZone("CST", 8*3600) before := time.Date(2026, 10, 12, 5, 59, 0, 0, beijing) after := time.Date(2026, 10, 12, 6, 0, 0, 0, beijing) policy := abisEntryPoliciesForWindowProbe() w1, err := abisPolicyWindow(policy, before) if err != nil { t.Fatal(err) } w2, err := abisPolicyWindow(policy, after) if err != nil { t.Fatal(err) } if w1.Start.Equal(w2.Start) { t.Fatalf("05:59 and 06:00 must be different service days, both start=%v", w1.Start) } t.Logf("05:59 -> window %v ; 06:00 -> window %v", w1.Start, w2.Start) if w1.Start.Hour() != 6 || w2.Start.Hour() != 6 { t.Fatalf("service day must start at 06:00, got %d and %d", w1.Start.Hour(), w2.Start.Hour()) } } func abisEntryPoliciesForWindowProbe() dnfdungeonadmission.Policy { policies, _ := abisEntryPolicies(abisDungeonSpecs[0], 0) return policies[0] } // 冒险团分档加成必须计入账号策略上限:账号额度 = 5 + 分档加成。 func TestAbisAccountPolicyIncludesAdventureGroupBonus(t *testing.T) { cases := []struct { manageLevel uint32 wantLimit uint32 }{ {0, 5}, {1, 5}, {5, 5}, {6, 6}, {10, 6}, {11, 7}, {16, 8}, {21, 9}, {26, 10}, {30, 10}, {31, 5}, } for _, c := range cases { policies, err := abisEntryPolicies(abisDungeonSpecs[0], c.manageLevel) if err != nil { t.Fatalf("manage level %d: %v", c.manageLevel, err) } if got := policies[0].Limit; got != c.wantLimit { t.Errorf("manage level %d: account limit=%d want=%d", c.manageLevel, got, c.wantLimit) } // 共享键必须与等级无关,否则同一账号不同角色会各生成一条账号策略。 if policies[0].Key != abisSharedAccountPolicyKey { t.Errorf("manage level %d: account key=%q want shared", c.manageLevel, policies[0].Key) } // 角色上限不受冒险团等级影响。 if got := policies[1].Limit; got != abisDungeonSpecs[0].limit { t.Errorf("manage level %d: character limit=%d want=%d", c.manageLevel, got, abisDungeonSpecs[0].limit) } } }