test_conditions.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. import pytest
  2. from flagpole import EvaluationContext
  3. from flagpole.conditions import (
  4. ConditionTypeMismatchException,
  5. ContainsCondition,
  6. EqualsCondition,
  7. InCondition,
  8. NotContainsCondition,
  9. NotEqualsCondition,
  10. NotInCondition,
  11. create_case_insensitive_set_from_list,
  12. )
  13. class TestCreateCaseInsensitiveSetFromList:
  14. def test_empty_set(self):
  15. assert create_case_insensitive_set_from_list([]) == set()
  16. def test_returns_int_set(self):
  17. assert create_case_insensitive_set_from_list([1, 2, 3]) == {1, 2, 3}
  18. def test_returns_float_set(self):
  19. assert create_case_insensitive_set_from_list([1.1, 2.2, 3.3]) == {1.1, 2.2, 3.3}
  20. def test_returns_lowercase_string_set(self):
  21. assert create_case_insensitive_set_from_list(["AbC", "DEF"]) == {"abc", "def"}
  22. class TestInConditions:
  23. def test_is_in(self):
  24. values = ["bar", "baz"]
  25. condition = InCondition(property="foo", value=values)
  26. assert condition.match(context=EvaluationContext({"foo": "bar"}), segment_name="test")
  27. not_condition = NotInCondition(property="foo", value=values)
  28. assert not not_condition.match(
  29. context=EvaluationContext({"foo": "bar"}), segment_name="test"
  30. )
  31. int_values = [1, 2]
  32. condition = InCondition(property="foo", value=int_values)
  33. # Validation check to ensure no type coercion occurs
  34. assert condition.value == int_values
  35. assert condition.match(context=EvaluationContext({"foo": 2}), segment_name="test")
  36. assert not condition.match(context=EvaluationContext({"foo": 3}), segment_name="test")
  37. def test_is_in_numeric_string(self):
  38. values = ["123", "456"]
  39. condition = InCondition(property="foo", value=values, operator="in")
  40. assert condition.value == values
  41. assert not condition.match(context=EvaluationContext({"foo": 123}), segment_name="test")
  42. assert condition.match(context=EvaluationContext({"foo": "123"}), segment_name="test")
  43. def test_is_not_in(self):
  44. values = ["bar", "baz"]
  45. condition = InCondition(property="foo", value=values)
  46. assert not condition.match(context=EvaluationContext({"foo": "foo"}), segment_name="test")
  47. not_condition = NotInCondition(property="foo", value=values)
  48. assert not_condition.match(context=EvaluationContext({"foo": "foo"}), segment_name="test")
  49. def test_is_in_case_insensitivity(self):
  50. values = ["bAr", "baz"]
  51. condition = InCondition(property="foo", value=values)
  52. assert condition.match(context=EvaluationContext({"foo": "BaR"}), segment_name="test")
  53. not_condition = NotInCondition(property="foo", value=values)
  54. assert not not_condition.match(
  55. context=EvaluationContext({"foo": "BaR"}), segment_name="test"
  56. )
  57. def test_invalid_property_value(self):
  58. values = ["bar", "baz"]
  59. condition = InCondition(property="foo", value=values)
  60. bad_context = ([1], {"k": "v"})
  61. for attr_val in bad_context:
  62. with pytest.raises(ConditionTypeMismatchException):
  63. condition.match(context=EvaluationContext({"foo": attr_val}), segment_name="test")
  64. not_condition = NotInCondition(property="foo", value=values)
  65. for attr_val in bad_context:
  66. with pytest.raises(ConditionTypeMismatchException):
  67. not_condition.match(
  68. context=EvaluationContext({"foo": attr_val}), segment_name="test"
  69. )
  70. def test_missing_context_property(self):
  71. values = ["bar", "baz"]
  72. in_condition = InCondition(property="foo", value=values)
  73. assert not in_condition.match(
  74. context=EvaluationContext({"bar": "bar"}), segment_name="test"
  75. )
  76. not_on_condition = NotInCondition(property="foo", value=values)
  77. assert not_on_condition.match(
  78. context=EvaluationContext({"bar": "bar"}), segment_name="test"
  79. )
  80. class TestContainsConditions:
  81. def test_does_contain(self):
  82. condition = ContainsCondition(property="foo", value="bar")
  83. assert condition.match(
  84. context=EvaluationContext({"foo": ["foo", "bar"]}), segment_name="test"
  85. )
  86. not_condition = NotContainsCondition(property="foo", value="bar")
  87. assert not not_condition.match(
  88. context=EvaluationContext({"foo": ["foo", "bar"]}), segment_name="test"
  89. )
  90. condition = ContainsCondition(property="foo", value=1)
  91. assert condition.match(context=EvaluationContext({"foo": [1, 2]}), segment_name="test")
  92. assert not condition.match(context=EvaluationContext({"foo": [3, 4]}), segment_name="test")
  93. def test_does_not_contain(self):
  94. values = "baz"
  95. condition = ContainsCondition(property="foo", value=values, operator="contains")
  96. assert not condition.match(
  97. context=EvaluationContext({"foo": ["foo", "bar"]}), segment_name="test"
  98. )
  99. not_condition = NotContainsCondition(property="foo", value=values)
  100. assert not_condition.match(
  101. context=EvaluationContext({"foo": ["foo", "bar"]}), segment_name="test"
  102. )
  103. def test_invalid_property_provided(self):
  104. values = "baz"
  105. bad_context = ("oops", "1", 1, 3.14, None, False, True)
  106. for attr_val in bad_context:
  107. with pytest.raises(ConditionTypeMismatchException):
  108. condition = ContainsCondition(property="foo", value=values)
  109. assert not condition.match(
  110. context=EvaluationContext({"foo": attr_val}), segment_name="test"
  111. )
  112. for attr_val in bad_context:
  113. with pytest.raises(ConditionTypeMismatchException):
  114. not_condition = NotContainsCondition(property="foo", value=values)
  115. assert not_condition.match(
  116. context=EvaluationContext({"foo": attr_val}), segment_name="test"
  117. )
  118. def test_missing_context_property(self):
  119. condition = ContainsCondition(property="foo", value="bar")
  120. with pytest.raises(ConditionTypeMismatchException):
  121. condition.match(context=EvaluationContext({"bar": ["foo", "bar"]}), segment_name="test")
  122. not_condition = NotContainsCondition(property="foo", value="bar")
  123. with pytest.raises(ConditionTypeMismatchException):
  124. not_condition.match(
  125. context=EvaluationContext({"bar": ["foo", "bar"]}), segment_name="test"
  126. )
  127. class TestEqualsConditions:
  128. def test_is_equal_string(self):
  129. value = "foo"
  130. condition = EqualsCondition(property="foo", value=value)
  131. assert condition.match(context=EvaluationContext({"foo": "foo"}), segment_name="test")
  132. not_condition = NotEqualsCondition(property="foo", value=value)
  133. assert not not_condition.match(
  134. context=EvaluationContext({"foo": "foo"}), segment_name="test"
  135. )
  136. def test_is_not_equals(self):
  137. values = "bar"
  138. condition = EqualsCondition(property="foo", value=values)
  139. assert not condition.match(context=EvaluationContext({"foo": "foo"}), segment_name="test")
  140. not_condition = NotEqualsCondition(property="foo", value=values)
  141. assert not_condition.match(context=EvaluationContext({"foo": "foo"}), segment_name="test")
  142. def test_is_equal_case_insensitive(self):
  143. values = "bAr"
  144. condition = EqualsCondition(property="foo", value=values)
  145. assert condition.match(context=EvaluationContext({"foo": "BaR"}), segment_name="test")
  146. not_condition = NotEqualsCondition(property="foo", value=values)
  147. assert not not_condition.match(
  148. context=EvaluationContext({"foo": "BaR"}), segment_name="test"
  149. )
  150. def test_equality_type_mismatch_strings(self):
  151. values = ["foo", "bar"]
  152. condition = EqualsCondition(property="foo", value=values, operator="equals")
  153. with pytest.raises(ConditionTypeMismatchException):
  154. condition.match(context=EvaluationContext({"foo": "foo"}), segment_name="test")
  155. not_condition = NotEqualsCondition(property="foo", value=values)
  156. with pytest.raises(ConditionTypeMismatchException):
  157. not_condition.match(context=EvaluationContext({"foo": "foo"}), segment_name="test")