def sieve_is(self, content): filtersset = FiltersSet("Testfilterset") filtersset.from_parser_result(self.parser) target = six.StringIO() filtersset.tosieve(target) repr_ = target.getvalue() target.close() self.assertEqual(repr_, content)
class FactoryTestCase(unittest.TestCase): def setUp(self): self.fs = FiltersSet("test") def test_get_filter_conditions(self): """Test get_filter_conditions method.""" orig_conditions = [('Sender', ":is", '*****@*****.**')] self.fs.addfilter("ruleX", orig_conditions, [ ("fileinto", ":copy", "Toto"), ]) conditions = self.fs.get_filter_conditions("ruleX") self.assertEqual(orig_conditions, conditions) orig_conditions = [("exists", "list-help", "list-unsubscribe", "list-subscribe", "list-owner")] self.fs.addfilter("ruleY", orig_conditions, [("fileinto", 'List')]) conditions = self.fs.get_filter_conditions("ruleY") self.assertEqual(orig_conditions, conditions) orig_conditions = [('Sender', ":notis", '*****@*****.**')] self.fs.addfilter("ruleZ", orig_conditions, [ ("fileinto", ":copy", "Toto"), ]) conditions = self.fs.get_filter_conditions("ruleZ") self.assertEqual(orig_conditions, conditions) orig_conditions = [("notexists", "list-help", "list-unsubscribe", "list-subscribe", "list-owner")] self.fs.addfilter("ruleA", orig_conditions, [("fileinto", 'List')]) conditions = self.fs.get_filter_conditions("ruleA") self.assertEqual(orig_conditions, conditions) def test_get_filter_matchtype(self): """Test get_filter_matchtype method.""" self.fs.addfilter("ruleX", [ ('Sender', ":is", '*****@*****.**'), ], [ ("fileinto", ":copy", "Toto"), ]) match_type = self.fs.get_filter_matchtype("ruleX") self.assertEqual(match_type, "anyof") def test_get_filter_actions(self): """Test get_filter_actions method.""" self.fs.addfilter("ruleX", [ ('Sender', ":is", '*****@*****.**'), ], [ ("fileinto", ":copy", "Toto"), ]) actions = self.fs.get_filter_actions("ruleX") self.assertIn("fileinto", actions[0]) self.assertIn(":copy", actions[0]) self.assertIn("Toto", actions[0]) def test_add_header_filter(self): output = six.StringIO() self.fs.addfilter("rule1", [ ('Sender', ":is", '*****@*****.**'), ], [ ("fileinto", ":copy", "Toto"), ]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.fs.tosieve(output) self.assertEqual( output.getvalue(), """require ["fileinto", "copy"]; # Filter: rule1 if anyof (header :is "Sender" "*****@*****.**") { fileinto :copy "Toto"; } """) output.close() def test_use_action_with_tag(self): output = six.StringIO() self.fs.addfilter("rule1", [ ('Sender', ":is", '*****@*****.**'), ], [ ("redirect", ":copy", "*****@*****.**"), ]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.fs.tosieve(output) self.assertEqual( output.getvalue(), """require ["copy"]; # Filter: rule1 if anyof (header :is "Sender" "*****@*****.**") { redirect :copy "*****@*****.**"; } """) output.close() def test_add_header_filter_with_not(self): output = six.StringIO() self.fs.addfilter("rule1", [('Sender', ":notcontains", '*****@*****.**')], [("fileinto", 'Toto')]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.fs.tosieve(output) self.assertEqual( output.getvalue(), """require ["fileinto"]; # Filter: rule1 if anyof (not header :contains "Sender" "*****@*****.**") { fileinto "Toto"; } """) def test_add_exists_filter(self): output = six.StringIO() self.fs.addfilter("rule1", [('exists', "list-help", "list-unsubscribe", "list-subscribe", "list-owner")], [("fileinto", 'Toto')]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.fs.tosieve(output) self.assertEqual( output.getvalue(), """require ["fileinto"]; # Filter: rule1 if anyof (exists ["list-help","list-unsubscribe","list-subscribe","list-owner"]) { fileinto "Toto"; } """) def test_add_exists_filter_with_not(self): output = six.StringIO() self.fs.addfilter("rule1", [('notexists', "list-help", "list-unsubscribe", "list-subscribe", "list-owner")], [("fileinto", 'Toto')]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.fs.tosieve(output) self.assertEqual( output.getvalue(), """require ["fileinto"]; # Filter: rule1 if anyof (not exists ["list-help","list-unsubscribe","list-subscribe","list-owner"]) { fileinto "Toto"; } """) def test_add_size_filter(self): output = six.StringIO() self.fs.addfilter("rule1", [('size', ":over", "100k")], [("fileinto", 'Totoéé')]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.fs.tosieve(output) self.assertEqual( output.getvalue(), """require ["fileinto"]; # Filter: rule1 if anyof (size :over 100k) { fileinto "Totoéé"; } """) def test_remove_filter(self): self.fs.addfilter("rule1", [('Sender', ":is", '*****@*****.**')], [("fileinto", 'Toto')]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.assertEqual(self.fs.removefilter("rule1"), True) self.assertIs(self.fs.getfilter("rule1"), None) def test_disablefilter(self): """ FIXME: Extra spaces are written between if and anyof, why?! """ self.fs.addfilter("rule1", [('Sender', ":is", '*****@*****.**')], [("fileinto", 'Toto')]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.assertEqual(self.fs.disablefilter("rule1"), True) output = six.StringIO() self.fs.tosieve(output) self.assertEqual( output.getvalue(), """require ["fileinto"]; # Filter: rule1 if false { if anyof (header :is "Sender" "*****@*****.**") { fileinto "Toto"; } } """) output.close() self.assertEqual(self.fs.is_filter_disabled("rule1"), True) def test_add_filter_unicode(self): """Add a filter containing unicode data.""" name = u"Test\xe9".encode("utf-8") self.fs.addfilter(name, [ ('Sender', ":is", '*****@*****.**'), ], [ ("fileinto", 'Toto'), ]) self.assertIsNot(self.fs.getfilter("Testé"), None) self.assertEqual( "{}".format(self.fs), """require ["fileinto"]; # Filter: Testé if anyof (header :is "Sender" "*****@*****.**") { fileinto "Toto"; } """)
def get_filter_vars(data): filter_match_types = { "match_any_flowing_rules": "anyof", "match_all_flowing_rules": "allof", "match_all": "all", } filter_sections = { "subject": "subject", "from": "from", "to": "to", "cc": "cc", "to_or_cc": "to_or_cc", "size": "size", "header": "header", "body": "body" } filter_conditions = { "is": ":is", "contains": ":contains", "matches": ":matches", "matches_regex": ":regex", "is_under": ":over", "is_over": ":under", } filter_negative_conditions = { "is_not": ":is", "does_not_contain": ":contains", "does_not_match": ":matches", "does_not_match_regex": ":regex" } filter_section_conditions = { "subject": lambda x: [x], "from": lambda x: [x], "to": lambda x: [x], "cc": lambda x: [x], "to_or_cc": lambda x: [x], "size": lambda x: [x], "header": lambda x: [x], "body": lambda x: [":text", x] } filter_actions = { "discard_message": "discard", "keep_message": "keep", "stop_processing_filter": "stop", "forward_message_to": "redirect", "send_reject_message": "reject", "file_message_in": "fileinto" } action_value_map = { "forward_message_to": "to_email", "send_reject_message": "message", "file_message_in": "folder" } filters = data.value raw_filter = "" fs = FiltersSet("cow") filters = sorted(filters, key=lambda f: f['order']) for s_filter in filters: # range(len(filters.keys())): # filter= filters[i] filter_name = s_filter.get("name") enabled = True # s_filter.get("enabled") TODO :: rules = s_filter.get("conditions") actions = s_filter.get("actions") matchtype = filter_match_types[s_filter.get("incoming_message")] builded_conditions = [] for rule in rules: # range(len(rules.keys())): # rule = rules[rule_number] negated = False section = filter_sections[rule["selector"]] if "not" in rule["condition"]: negated = True condition = filter_negative_conditions[rule["condition"]] else: condition = filter_conditions[rule["condition"]] condition = filter_section_conditions[section](condition) if negated: section = "not{}".format(section) value = rule["value"] builded_conditions.append((section, *condition, value)) builded_actions = [] actions = sorted(actions, key=lambda f: f['order']) for action in actions: # range(len(actions.keys())): # action = actions[action_number] param = "" if action["type"] in action_value_map.keys(): param = action[action_value_map[action["type"]]] # if value_map=[] builded_actions.append((filter_actions[action["type"]], param)) if matchtype == "all": p = Parser() raw = 'require ["reject","fileinto","imap4flags"];' for builded_action in builded_actions: name = builded_action[0] param = builded_action[1] if param: raw += "\n{} \"{}\";".format(name, param) else: raw += "\n{};".format(name) p.parse(raw) fs.from_parser_result(p) else: fs.addfilter(name=filter_name, conditions=builded_conditions, actions=builded_actions, matchtype=matchtype) requirements = fs.requires io = StringIO() fs.tosieve(io) raw_sieve = io.getvalue() if requirements: raw_sieve = '\n'.join(raw_sieve.splitlines()[2:]) if "not" in raw_sieve: for key in filter_sections.keys(): raw_sieve = raw_sieve.replace("not" + key, key) return [raw_sieve, requirements]
class FactoryTestCase(unittest.TestCase): def setUp(self): self.fs = FiltersSet("test") def test_add_header_filter(self): output = six.StringIO() self.fs.addfilter( "rule1", [('Sender', ":is", '*****@*****.**'), ], [("fileinto", 'Toto'), ]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.fs.tosieve(output) self.assertEqual(output.getvalue(), """require ["fileinto"]; # Filter: rule1 if anyof (header :is "Sender" "*****@*****.**") { fileinto "Toto"; } """) output.close() def test_add_header_filter_with_not(self): output = six.StringIO() self.fs.addfilter("rule1", [('Sender', ":notcontains", '*****@*****.**'),], [("fileinto", 'Toto'),]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.fs.tosieve(output) self.assertEqual(output.getvalue(), """require ["fileinto"]; # Filter: rule1 if anyof (not header :contains "Sender" "*****@*****.**") { fileinto "Toto"; } """) def test_add_exists_filter(self): output = six.StringIO() self.fs.addfilter( "rule1", [('exists', "list-help", "list-unsubscribe", "list-subscribe", "list-owner")], [("fileinto", 'Toto'),] ) self.assertIsNot(self.fs.getfilter("rule1"), None) self.fs.tosieve(output) self.assertEqual(output.getvalue(), """require ["fileinto"]; # Filter: rule1 if anyof (exists ["list-help","list-unsubscribe","list-subscribe","list-owner"]) { fileinto "Toto"; } """) def test_add_exists_filter_with_not(self): output = six.StringIO() self.fs.addfilter( "rule1", [('notexists', "list-help", "list-unsubscribe", "list-subscribe", "list-owner")], [("fileinto", 'Toto'),] ) self.assertIsNot(self.fs.getfilter("rule1"), None) self.fs.tosieve(output) self.assertEqual(output.getvalue(), """require ["fileinto"]; # Filter: rule1 if anyof (not exists ["list-help","list-unsubscribe","list-subscribe","list-owner"]) { fileinto "Toto"; } """) def test_add_size_filter(self): output = six.StringIO() self.fs.addfilter( "rule1", [('size', ":over", "100k")], [("fileinto", 'Totoéé'),] ) self.assertIsNot(self.fs.getfilter("rule1"), None) self.fs.tosieve(output) self.assertEqual(output.getvalue(), """require ["fileinto"]; # Filter: rule1 if anyof (size :over 100k) { fileinto "Totoéé"; } """) def test_remove_filter(self): self.fs.addfilter("rule1", [('Sender', ":is", '*****@*****.**'),], [("fileinto", 'Toto'),]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.assertEqual(self.fs.removefilter("rule1"), True) self.assertIs(self.fs.getfilter("rule1"), None) def test_disablefilter(self): """ FIXME: Extra spaces are written between if and anyof, why?! """ self.fs.addfilter("rule1", [('Sender', ":is", '*****@*****.**'),], [("fileinto", 'Toto'),]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.assertEqual(self.fs.disablefilter("rule1"), True) output = six.StringIO() self.fs.tosieve(output) self.assertEqual(output.getvalue(), """require ["fileinto"]; # Filter: rule1 if false { if anyof (header :is "Sender" "*****@*****.**") { fileinto "Toto"; } } """) output.close() self.assertEqual(self.fs.is_filter_disabled("rule1"), True) def test_add_filter_unicode(self): """Add a filter containing unicode data.""" name = u"Test\xe9".encode("utf-8") self.fs.addfilter( name, [('Sender', ":is", '*****@*****.**'), ], [("fileinto", 'Toto'), ]) self.assertIsNot(self.fs.getfilter("Testé"), None) self.assertEqual("{}".format(self.fs), """require ["fileinto"]; # Filter: Testé if anyof (header :is "Sender" "*****@*****.**") { fileinto "Toto"; } """)
class FactoryTestCase(unittest.TestCase): def setUp(self): self.fs = FiltersSet("test") def test_add_header_filter(self): output = six.StringIO() self.fs.addfilter("rule1", [ ('Sender', ":is", '*****@*****.**'), ], [ ("fileinto", 'Toto'), ]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.fs.tosieve(output) self.assertEqual( output.getvalue(), """require ["fileinto"]; # Filter: rule1 if anyof (header :is "Sender" "*****@*****.**") { fileinto "Toto"; } """) output.close() def test_add_header_filter_with_not(self): output = six.StringIO() self.fs.addfilter("rule1", [ ('Sender', ":notcontains", '*****@*****.**'), ], [ ("fileinto", 'Toto'), ]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.fs.tosieve(output) self.assertEqual( output.getvalue(), """require ["fileinto"]; # Filter: rule1 if anyof (not header :contains "Sender" "*****@*****.**") { fileinto "Toto"; } """) def test_add_exists_filter(self): output = six.StringIO() self.fs.addfilter("rule1", [('exists', "list-help", "list-unsubscribe", "list-subscribe", "list-owner")], [ ("fileinto", 'Toto'), ]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.fs.tosieve(output) self.assertEqual( output.getvalue(), """require ["fileinto"]; # Filter: rule1 if anyof (exists ["list-help","list-unsubscribe","list-subscribe","list-owner"]) { fileinto "Toto"; } """) def test_add_exists_filter_with_not(self): output = six.StringIO() self.fs.addfilter("rule1", [('notexists', "list-help", "list-unsubscribe", "list-subscribe", "list-owner")], [ ("fileinto", 'Toto'), ]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.fs.tosieve(output) self.assertEqual( output.getvalue(), """require ["fileinto"]; # Filter: rule1 if anyof (not exists ["list-help","list-unsubscribe","list-subscribe","list-owner"]) { fileinto "Toto"; } """) def test_add_size_filter(self): output = six.StringIO() self.fs.addfilter("rule1", [('size', ":over", "100k")], [ ("fileinto", 'Totoéé'), ]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.fs.tosieve(output) self.assertEqual( output.getvalue(), """require ["fileinto"]; # Filter: rule1 if anyof (size :over 100k) { fileinto "Totoéé"; } """) def test_remove_filter(self): self.fs.addfilter("rule1", [ ('Sender', ":is", '*****@*****.**'), ], [ ("fileinto", 'Toto'), ]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.assertEqual(self.fs.removefilter("rule1"), True) self.assertIs(self.fs.getfilter("rule1"), None) def test_disablefilter(self): """ FIXME: Extra spaces are written between if and anyof, why?! """ self.fs.addfilter("rule1", [ ('Sender', ":is", '*****@*****.**'), ], [ ("fileinto", 'Toto'), ]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.assertEqual(self.fs.disablefilter("rule1"), True) output = six.StringIO() self.fs.tosieve(output) self.assertEqual( output.getvalue(), """require ["fileinto"]; # Filter: rule1 if false { if anyof (header :is "Sender" "*****@*****.**") { fileinto "Toto"; } } """) output.close() self.assertEqual(self.fs.is_filter_disabled("rule1"), True) def test_add_filter_unicode(self): """Add a filter containing unicode data.""" name = u"Test\xe9".encode("utf-8") self.fs.addfilter(name, [ ('Sender', ":is", '*****@*****.**'), ], [ ("fileinto", 'Toto'), ]) self.assertIsNot(self.fs.getfilter("Testé"), None) self.assertEqual( "{}".format(self.fs), """require ["fileinto"]; # Filter: Testé if anyof (header :is "Sender" "*****@*****.**") { fileinto "Toto"; } """)
class FactoryTestCase(unittest.TestCase): def setUp(self): self.fs = FiltersSet("test") def test_get_filter_conditions(self): """Test get_filter_conditions method.""" orig_conditions = [('Sender', ":is", '*****@*****.**')] self.fs.addfilter("ruleX", orig_conditions, [ ("fileinto", ":copy", "Toto"), ]) conditions = self.fs.get_filter_conditions("ruleX") self.assertEqual(orig_conditions, conditions) orig_conditions = [("exists", "list-help", "list-unsubscribe", "list-subscribe", "list-owner")] self.fs.addfilter("ruleY", orig_conditions, [("fileinto", 'List')]) conditions = self.fs.get_filter_conditions("ruleY") self.assertEqual(orig_conditions, conditions) orig_conditions = [('Sender', ":notis", '*****@*****.**')] self.fs.addfilter("ruleZ", orig_conditions, [ ("fileinto", ":copy", "Toto"), ]) conditions = self.fs.get_filter_conditions("ruleZ") self.assertEqual(orig_conditions, conditions) orig_conditions = [("notexists", "list-help", "list-unsubscribe", "list-subscribe", "list-owner")] self.fs.addfilter("ruleA", orig_conditions, [("fileinto", 'List')]) conditions = self.fs.get_filter_conditions("ruleA") self.assertEqual(orig_conditions, conditions) orig_conditions = [("envelope", ":is", ["From"], ["hello"])] self.fs.addfilter("ruleB", orig_conditions, [("fileinto", "INBOX")]) conditions = self.fs.get_filter_conditions("ruleB") self.assertEqual(orig_conditions, conditions) orig_conditions = [("body", ":raw", ":notcontains", "matteo")] self.fs.addfilter("ruleC", orig_conditions, [("fileinto", "INBOX")]) conditions = self.fs.get_filter_conditions("ruleC") self.assertEqual(orig_conditions, conditions) orig_conditions = [("currentdate", ":zone", "+0100", ":notis", "date", "2019-02-26")] self.fs.addfilter("ruleD", orig_conditions, [("fileinto", "INBOX")]) conditions = self.fs.get_filter_conditions("ruleD") self.assertEqual(orig_conditions, conditions) orig_conditions = [("currentdate", ":zone", "+0100", ":value", "gt", "date", "2019-02-26")] self.fs.addfilter("ruleE", orig_conditions, [("fileinto", "INBOX")]) conditions = self.fs.get_filter_conditions("ruleE") self.assertEqual(orig_conditions, conditions) def test_get_filter_conditions_from_parser_result(self): res = """require ["fileinto"]; # rule:[test] if anyof (exists ["Subject"]) { fileinto "INBOX"; } """ p = parser.Parser() p.parse(res) fs = FiltersSet("test", '# rule:') fs.from_parser_result(p) c = fs.get_filter_conditions('[test]') self.assertEqual(c, [("exists", "Subject")]) res = """require ["date", "fileinto"]; # rule:aaa if anyof (currentdate :zone "+0100" :is "date" ["2019-03-27"]) { fileinto "INBOX"; } """ p = parser.Parser() p.parse(res) fs = FiltersSet("aaa", "# rule:") fs.from_parser_result(p) c = fs.get_filter_conditions('aaa') self.assertEqual( c, [('currentdate', ':zone', '+0100', ':is', 'date', '2019-03-27')]) res = """require ["envelope", "fileinto"]; # rule:[aaa] if anyof (envelope :contains ["To"] ["*****@*****.**"]) { fileinto "INBOX"; } """ p = parser.Parser() p.parse(res) fs = FiltersSet("aaa", "# rule:") fs.from_parser_result(p) c = fs.get_filter_conditions('[aaa]') self.assertEqual( c, [('envelope', ':contains', ['To'], ['*****@*****.**'])]) def test_get_filter_matchtype(self): """Test get_filter_matchtype method.""" self.fs.addfilter("ruleX", [ ('Sender', ":is", '*****@*****.**'), ], [ ("fileinto", ":copy", "Toto"), ]) match_type = self.fs.get_filter_matchtype("ruleX") self.assertEqual(match_type, "anyof") def test_get_filter_actions(self): """Test get_filter_actions method.""" self.fs.addfilter("ruleX", [ ('Sender', ":is", '*****@*****.**'), ], [ ("fileinto", ":copy", "Toto"), ]) actions = self.fs.get_filter_actions("ruleX") self.assertIn("fileinto", actions[0]) self.assertIn(":copy", actions[0]) self.assertIn("Toto", actions[0]) self.fs.addfilter("ruleY", [("Subject", ":contains", "aaa")], [("stop", )]) actions = self.fs.get_filter_actions("ruleY") self.assertIn("stop", actions[0]) def test_add_header_filter(self): output = io.StringIO() self.fs.addfilter("rule1", [ ('Sender', ":is", '*****@*****.**'), ], [ ("fileinto", ":copy", "Toto"), ]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.fs.tosieve(output) self.assertEqual( output.getvalue(), """require ["fileinto", "copy"]; # Filter: rule1 if anyof (header :is "Sender" "*****@*****.**") { fileinto :copy "Toto"; } """) output.close() def test_use_action_with_tag(self): output = io.StringIO() self.fs.addfilter("rule1", [ ('Sender', ":is", '*****@*****.**'), ], [ ("redirect", ":copy", "*****@*****.**"), ]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.fs.tosieve(output) self.assertEqual( output.getvalue(), """require ["copy"]; # Filter: rule1 if anyof (header :is "Sender" "*****@*****.**") { redirect :copy "*****@*****.**"; } """) output.close() def test_add_header_filter_with_not(self): output = io.StringIO() self.fs.addfilter("rule1", [('Sender', ":notcontains", '*****@*****.**')], [("fileinto", 'Toto')]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.fs.tosieve(output) self.assertEqual( output.getvalue(), """require ["fileinto"]; # Filter: rule1 if anyof (not header :contains "Sender" "*****@*****.**") { fileinto "Toto"; } """) def test_add_exists_filter(self): output = io.StringIO() self.fs.addfilter("rule1", [('exists', "list-help", "list-unsubscribe", "list-subscribe", "list-owner")], [("fileinto", 'Toto')]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.fs.tosieve(output) self.assertEqual( output.getvalue(), """require ["fileinto"]; # Filter: rule1 if anyof (exists ["list-help","list-unsubscribe","list-subscribe","list-owner"]) { fileinto "Toto"; } """) def test_add_exists_filter_with_not(self): output = io.StringIO() self.fs.addfilter("rule1", [('notexists', "list-help", "list-unsubscribe", "list-subscribe", "list-owner")], [("fileinto", 'Toto')]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.fs.tosieve(output) self.assertEqual( output.getvalue(), """require ["fileinto"]; # Filter: rule1 if anyof (not exists ["list-help","list-unsubscribe","list-subscribe","list-owner"]) { fileinto "Toto"; } """) def test_add_size_filter(self): output = io.StringIO() self.fs.addfilter("rule1", [('size', ":over", "100k")], [("fileinto", 'Totoéé')]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.fs.tosieve(output) self.assertEqual( output.getvalue(), """require ["fileinto"]; # Filter: rule1 if anyof (size :over 100k) { fileinto "Totoéé"; } """) def test_remove_filter(self): self.fs.addfilter("rule1", [('Sender', ":is", '*****@*****.**')], [("fileinto", 'Toto')]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.assertEqual(self.fs.removefilter("rule1"), True) self.assertIs(self.fs.getfilter("rule1"), None) def test_disablefilter(self): """ FIXME: Extra spaces are written between if and anyof, why?! """ self.fs.addfilter("rule1", [('Sender', ":is", '*****@*****.**')], [("fileinto", 'Toto')]) self.assertIsNot(self.fs.getfilter("rule1"), None) self.assertEqual(self.fs.disablefilter("rule1"), True) output = io.StringIO() self.fs.tosieve(output) self.assertEqual( output.getvalue(), """require ["fileinto"]; # Filter: rule1 if false { if anyof (header :is "Sender" "*****@*****.**") { fileinto "Toto"; } } """) output.close() self.assertEqual(self.fs.is_filter_disabled("rule1"), True) def test_add_filter_unicode(self): """Add a filter containing unicode data.""" name = u"Test\xe9".encode("utf-8") self.fs.addfilter(name, [ ('Sender', ":is", '*****@*****.**'), ], [ ("fileinto", 'Toto'), ]) self.assertIsNot(self.fs.getfilter("Testé"), None) self.assertEqual( "{}".format(self.fs), """require ["fileinto"]; # Filter: Testé if anyof (header :is "Sender" "*****@*****.**") { fileinto "Toto"; } """) def test_add_body_filter(self): """Add a body filter.""" self.fs.addfilter("test", [("body", ":raw", ":contains", "matteo")], [("fileinto", "Toto")]) self.assertEqual( "{}".format(self.fs), """require ["body", "fileinto"]; # Filter: test if anyof (body :contains :raw ["matteo"]) { fileinto "Toto"; } """) def test_add_notbody_filter(self): """Add a not body filter.""" self.fs.addfilter("test", [("body", ":raw", ":notcontains", "matteo")], [("fileinto", "Toto")]) self.assertEqual( "{}".format(self.fs), """require ["body", "fileinto"]; # Filter: test if anyof (not body :contains :raw ["matteo"]) { fileinto "Toto"; } """) def test_add_envelope_filter(self): """Add a envelope filter.""" self.fs.addfilter("test", [("envelope", ":is", ["From"], ["hello"])], [("fileinto", "INBOX")]) self.assertEqual( "{}".format(self.fs), """require ["envelope", "fileinto"]; # Filter: test if anyof (envelope :is ["From"] ["hello"]) { fileinto "INBOX"; } """) def test_add_notenvelope_filter(self): """Add a not envelope filter.""" self.fs.addfilter("test", [("envelope", ":notis", ["From"], ["hello"])], [("fileinto", "INBOX")]) self.assertEqual( "{}".format(self.fs), """require ["envelope", "fileinto"]; # Filter: test if anyof (not envelope :is ["From"] ["hello"]) { fileinto "INBOX"; } """) def test_add_currentdate_filter(self): """Add a currentdate filter.""" self.fs.addfilter( "test", [("currentdate", ":zone", "+0100", ":is", "date", "2019-02-26")], [("fileinto", "INBOX")]) self.assertEqual( "{}".format(self.fs), """require ["date", "fileinto"]; # Filter: test if anyof (currentdate :zone "+0100" :is "date" ["2019-02-26"]) { fileinto "INBOX"; } """) self.fs.removefilter("test") self.fs.addfilter("test", [("currentdate", ":zone", "+0100", ":value", "gt", "date", "2019-02-26")], [("fileinto", "INBOX")]) self.assertEqual( "{}".format(self.fs), """require ["date", "fileinto", "relational"]; # Filter: test if anyof (currentdate :zone "+0100" :value "gt" "date" ["2019-02-26"]) { fileinto "INBOX"; } """)