announcement_targeting_test.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package service
  2. import (
  3. "testing"
  4. "github.com/stretchr/testify/require"
  5. )
  6. func TestAnnouncementTargeting_Matches_EmptyMatchesAll(t *testing.T) {
  7. var targeting AnnouncementTargeting
  8. require.True(t, targeting.Matches(0, nil))
  9. require.True(t, targeting.Matches(123.45, map[int64]struct{}{1: {}}))
  10. }
  11. func TestAnnouncementTargeting_NormalizeAndValidate_RejectsEmptyGroup(t *testing.T) {
  12. targeting := AnnouncementTargeting{
  13. AnyOf: []AnnouncementConditionGroup{
  14. {AllOf: nil},
  15. },
  16. }
  17. _, err := targeting.NormalizeAndValidate()
  18. require.Error(t, err)
  19. require.ErrorIs(t, err, ErrAnnouncementInvalidTarget)
  20. }
  21. func TestAnnouncementTargeting_NormalizeAndValidate_RejectsInvalidCondition(t *testing.T) {
  22. targeting := AnnouncementTargeting{
  23. AnyOf: []AnnouncementConditionGroup{
  24. {
  25. AllOf: []AnnouncementCondition{
  26. {Type: "balance", Operator: "between", Value: 10},
  27. },
  28. },
  29. },
  30. }
  31. _, err := targeting.NormalizeAndValidate()
  32. require.Error(t, err)
  33. require.ErrorIs(t, err, ErrAnnouncementInvalidTarget)
  34. }
  35. func TestAnnouncementTargeting_Matches_AndOrSemantics(t *testing.T) {
  36. targeting := AnnouncementTargeting{
  37. AnyOf: []AnnouncementConditionGroup{
  38. {
  39. AllOf: []AnnouncementCondition{
  40. {Type: AnnouncementConditionTypeBalance, Operator: AnnouncementOperatorGTE, Value: 100},
  41. {Type: AnnouncementConditionTypeSubscription, Operator: AnnouncementOperatorIn, GroupIDs: []int64{10}},
  42. },
  43. },
  44. {
  45. AllOf: []AnnouncementCondition{
  46. {Type: AnnouncementConditionTypeBalance, Operator: AnnouncementOperatorLT, Value: 5},
  47. },
  48. },
  49. },
  50. }
  51. // 命中第 2 组(balance < 5)
  52. require.True(t, targeting.Matches(4.99, nil))
  53. require.False(t, targeting.Matches(5, nil))
  54. // 命中第 1 组(balance >= 100 AND 订阅 in [10])
  55. require.False(t, targeting.Matches(100, map[int64]struct{}{}))
  56. require.False(t, targeting.Matches(99.9, map[int64]struct{}{10: {}}))
  57. require.True(t, targeting.Matches(100, map[int64]struct{}{10: {}}))
  58. }