class TestBasicProcessor(unittest.TestCase): """ Tests for `BasicProcessor`. """ def setUp(self): self.cookie_jar = InMemoryCookieJar() self.rules = [Rule(lambda *args: False, MagicMock(), RULE_IDENTIFIER) for _ in range(10)] self.cookie_jar.enrich_cookie( COOKIE_IDENTIFIER, Enrichment("first", datetime(year=1, month=1, day=1, tzinfo=timezone.utc), Metadata())) self.cookie = self.cookie_jar.fetch_cookie(COOKIE_IDENTIFIER) self.processor = BasicProcessor(self.cookie_jar, [], []) def test_evaluate_rules_with_cookie_when_no_rules(self): halt = self.processor.evaluate_rules_with_cookie(self.cookie) self.assertFalse(halt) def test_evaluate_rules_with_cookie_when_no_matched_rules(self): self.processor.rules = self.rules halt = self.processor.evaluate_rules_with_cookie(self.cookie) for rule in self.rules: rule._action.assert_not_called() self.assertFalse(halt) def test_evaluate_rules_with_cookie_when_matched_rules_and_no_termination(self): extra_rules = [ Rule(lambda *args: True, MagicMock(return_value=False), RULE_IDENTIFIER), Rule(lambda *args: True, MagicMock(return_value=False), RULE_IDENTIFIER) ] self.processor.rules = self.rules + extra_rules halt = self.processor.evaluate_rules_with_cookie(self.cookie) for rule in self.rules: rule._action.assert_not_called() for rule in extra_rules: self.assertEqual(rule._action.call_count, 1) self.assertEqual(rule._action.call_args[0][0].identifier, self.cookie.identifier) self.assertFalse(halt) def test_evaluate_rules_with_cookie_when_matched_rules_and_termination(self): production_to_be_called = MagicMock(return_value=True) extra_rules = [ Rule(lambda *args: True, lambda *args: False, Priority.MIN_PRIORITY), Rule(lambda *args: True, production_to_be_called, Priority.get_lower_priority_value(Priority.MAX_PRIORITY)), Rule(lambda *args: False, lambda *args: False, Priority.MAX_PRIORITY) ] self.processor.rules = self.rules + extra_rules halt = self.processor.evaluate_rules_with_cookie(self.cookie) total_call_count = 0 for rule in self.rules: total_call_count += rule._action.call_count self.assertEqual(total_call_count, 0) self.assertEqual(production_to_be_called.call_count, 1) self.assertTrue(halt) def test_evaluate_rules_with_cookie_does_not_allow_rule_to_change_cookie_for_subsequent_rules(self): source = "my_enrichment" change_detected_in_next_rule = False def cookie_changer(cookie: Cookie) -> bool: enrichment = Enrichment(source, datetime(year=2000, month=1, day=1), Metadata()) cookie.enrich(enrichment) return False def record_fail_if_changed(cookie: Cookie) -> bool: nonlocal change_detected_in_next_rule if source in cookie.get_enrichment_sources(): change_detected_in_next_rule = True self.processor.rules = [ Rule(cookie_changer, self.rules[0]._action, RULE_IDENTIFIER, priority=Priority.MAX_PRIORITY), Rule(record_fail_if_changed, self.rules[0]._action, RULE_IDENTIFIER, priority=Priority.MIN_PRIORITY) ] self.processor.process_cookie(self.cookie) self.assertFalse(change_detected_in_next_rule) def test_evaluate_rules_with_cookie_when_no_matched__does_not_enrich_with_rule_application_log(self): self.processor.rules = self.rules _ = self.processor.evaluate_rules_with_cookie(self.cookie) cookie = self.cookie_jar.fetch_cookie(self.cookie.identifier) self.assertEqual(len(cookie.enrichments), 1) def test_evaluate_rules_with_cookie_when_matched_enriches_with_rule_application_log(self): matched_rule_identifier = "matched_rule" terminates = False self.processor.rules = self.rules \ + [Rule(lambda *args: True, MagicMock(return_value=terminates), matched_rule_identifier)] _ = self.processor.evaluate_rules_with_cookie(self.cookie) cookie = self.cookie_jar.fetch_cookie(self.cookie.identifier) self.assertGreater(len(cookie.enrichments), 1) last_enrichment = cookie.enrichments[-1] self.assertEqual(last_enrichment.source, RULE_APPLICATION) rule_application_log = RuleApplicationLogJSONDecoder().decode_parsed(last_enrichment.metadata) # type: RuleApplicationLog self.assertEqual(rule_application_log.rule_id, matched_rule_identifier) self.assertEqual(rule_application_log.terminated_processing, terminates) def test_handle_cookie_enrichment_when_matching_enrichments(self): self.processor.notification_receivers = [MagicMock()] self.processor.enrichment_loaders = [EnrichmentLoader( lambda *args: True, lambda *args: SAMPLE_ENRICHMENT, RULE_IDENTIFIER)] self.processor.handle_cookie_enrichment(self.cookie) self.processor.notification_receivers[0].receive.assert_not_called() cookie = self.cookie_jar.get_next_for_processing() self.assertIn(SAMPLE_ENRICHMENT, cookie.enrichments)
class TestBasicProcessor(unittest.TestCase): """ Tests for `BasicProcessor`. """ def setUp(self): self.cookie_jar = InMemoryCookieJar() self.rules = [Rule(lambda *args: False, MagicMock()) for _ in range(10)] self.cookie = Cookie(COOKIE_IDENTIFIER) self.processor = BasicProcessor(self.cookie_jar, [], []) def test_evaluate_rules_with_cookie_when_no_rules(self): halt = self.processor.evaluate_rules_with_cookie(self.cookie) self.assertFalse(halt) def test_evaluate_rules_with_cookie_when_no_matched_rules(self): self.processor.rules = self.rules halt = self.processor.evaluate_rules_with_cookie(self.cookie) for rule in self.rules: rule._action.assert_not_called() self.assertFalse(halt) def test_evaluate_rules_with_cookie_when_matched_rules_and_no_termination(self): extra_rules = [ Rule(lambda *args: True, MagicMock(return_value=False)), Rule(lambda *args: True, MagicMock(return_value=False)) ] self.processor.rules = self.rules + extra_rules halt = self.processor.evaluate_rules_with_cookie(self.cookie) for rule in self.rules: rule._action.assert_not_called() self.assertFalse(halt) def test_evaluate_rules_with_cookie_when_matched_rules_and_termination(self): production_to_be_called = MagicMock(return_value=True) extra_rules = [ Rule(lambda *args: True, lambda *args: False, Priority.MIN_PRIORITY), Rule(lambda *args: True, production_to_be_called, Priority.get_lower_priority_value(Priority.MAX_PRIORITY)), Rule(lambda *args: False, lambda *args: False, Priority.MAX_PRIORITY) ] self.processor.rules = self.rules + extra_rules halt = self.processor.evaluate_rules_with_cookie(self.cookie) total_call_count = 0 for rule in self.rules: total_call_count += rule._action.call_count self.assertEqual(total_call_count, 0) self.assertEqual(production_to_be_called.call_count, 1) self.assertTrue(halt) def test_evaluate_rules_with_cookie_does_not_allow_rule_to_change_cookie_for_subsequent_rules(self): source = "my_enrichment" change_detected_in_next_rule = False def cookie_changer(cookie: Cookie) -> bool: enrichment = Enrichment(source, datetime(year=2000, month=1, day=1), Metadata()) cookie.enrich(enrichment) return False def record_fail_if_changed(cookie: Cookie) -> bool: nonlocal change_detected_in_next_rule if source in cookie.get_enrichment_sources(): change_detected_in_next_rule = True self.processor.rules = [ Rule(cookie_changer, self.rules[0]._action, priority=Priority.MAX_PRIORITY), Rule(record_fail_if_changed, self.rules[0]._action, priority=Priority.MIN_PRIORITY) ] self.processor.process_cookie(self.cookie) self.assertFalse(change_detected_in_next_rule) def test_handle_cookie_enrichment_when_matching_enrichments(self): self.processor.notification_receivers = [MagicMock()] self.processor.enrichment_loaders = [EnrichmentLoader(lambda *args: True, lambda *args: SAMPLE_ENRICHMENT)] self.processor.handle_cookie_enrichment(self.cookie) self.processor.notification_receivers[0].receive.assert_not_called() cookie = self.cookie_jar.get_next_for_processing() self.assertIn(SAMPLE_ENRICHMENT, cookie.enrichments)