package roomtreasure import ( "errors" "testing" ) func TestNormalizeConfigDefaultsAndSortsLevels(t *testing.T) { config, err := normalizeConfig(RoomTreasureConfig{ AppCode: "lalu", OpenDelayMS: defaultOpenDelayMS, Levels: []RoomTreasureLevelConfig{ {Level: 2, EnergyThreshold: 300}, {Level: 1, EnergyThreshold: 100}, {Level: 3, EnergyThreshold: 600}, {Level: 4, EnergyThreshold: 1_000}, {Level: 5, EnergyThreshold: 1_500}, {Level: 6, EnergyThreshold: 2_100}, {Level: 7, EnergyThreshold: 2_800}, }, }) if err != nil { t.Fatalf("normalizeConfig failed: %v", err) } if config.EnergySource != defaultEnergySource || config.OpenDelayMS != defaultOpenDelayMS || config.BroadcastScope != defaultBroadcastScope { t.Fatalf("default fields mismatch: %+v", config) } if config.Levels[0].Level != 1 || config.Levels[6].Level != 7 { t.Fatalf("levels should be sorted by level: %+v", config.Levels) } } func TestDefaultConfigKeepsOperationalDefaults(t *testing.T) { config, err := normalizeConfig(defaultConfig("lalu")) if err != nil { t.Fatalf("normalizeConfig(defaultConfig) failed: %v", err) } if !config.BroadcastEnabled || config.OpenDelayMS != defaultOpenDelayMS || len(config.Levels) != roomTreasureLevelCount { t.Fatalf("default config mismatch: %+v", config) } } func TestNormalizeConfigRejectsInvalidLevels(t *testing.T) { tests := []struct { name string config RoomTreasureConfig }{ {name: "missing_level", config: RoomTreasureConfig{AppCode: "lalu", Levels: []RoomTreasureLevelConfig{{Level: 1, EnergyThreshold: 1}}}}, {name: "duplicate", config: RoomTreasureConfig{AppCode: "lalu", Levels: []RoomTreasureLevelConfig{ {Level: 1, EnergyThreshold: 1}, {Level: 1, EnergyThreshold: 2}, {Level: 3, EnergyThreshold: 3}, {Level: 4, EnergyThreshold: 4}, {Level: 5, EnergyThreshold: 5}, {Level: 6, EnergyThreshold: 6}, {Level: 7, EnergyThreshold: 7}, }}}, {name: "zero_threshold", config: RoomTreasureConfig{AppCode: "lalu", Levels: []RoomTreasureLevelConfig{ {Level: 1, EnergyThreshold: 0}, {Level: 2, EnergyThreshold: 2}, {Level: 3, EnergyThreshold: 3}, {Level: 4, EnergyThreshold: 4}, {Level: 5, EnergyThreshold: 5}, {Level: 6, EnergyThreshold: 6}, {Level: 7, EnergyThreshold: 7}, }}}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { _, err := normalizeConfig(test.config) if !errors.Is(err, ErrInvalidArgument) { t.Fatalf("normalizeConfig should reject %s with ErrInvalidArgument, got %v", test.name, err) } }) } } func TestNormalizeConfigRejectsIncompleteRewardAndEnergyRule(t *testing.T) { config := defaultConfig("lalu") config.Levels[0].InRoomRewards = []RoomTreasureRewardItem{{ResourceGroupID: 0, Weight: 100}} if _, err := normalizeConfig(config); !errors.Is(err, ErrInvalidArgument) { t.Fatalf("reward without resource group should be invalid, got %v", err) } config = defaultConfig("lalu") config.GiftEnergyRules = []GiftEnergyRuleConfig{{GiftID: "gift-1"}} if _, err := normalizeConfig(config); !errors.Is(err, ErrInvalidArgument) { t.Fatalf("energy rule without multiplier or fixed energy should be invalid, got %v", err) } }