Ejemplo n.º 1
0
    def test_author_flair_template_id(self):
        post = helpers.post()
        rule = Rule({
            'author': {
                'flair_template_id': 'test'
            },
            'action': 'remove'
        })
        mod = Moderator(post)

        flair_mock = MagicMock(
            return_value={'current': {
                'flair_template_id': 'test'
            }})
        old_post = reddit.post
        reddit.post = flair_mock

        assert mod.moderate(rule), "Author flair_template_id not matching"

        flair_mock.return_value = {'current': {'flair_template_id': 'nomatch'}}
        self.assertFalse(
            mod.moderate(rule),
            "Author flair_template_id matching as a false positive")

        reddit.post = old_post
Ejemplo n.º 2
0
    def test_spam(self):
        post = helpers.post()
        rule = Rule({'id': post.id, 'action': 'spam'})
        mod = Moderator(post)

        post.mod.remove.reset_mock()
        mod.moderate(rule)
        post.mod.remove.assert_called_with(spam=True)
Ejemplo n.º 3
0
    def test_starts_with(self):
        comment = helpers.comment()
        mod = Moderator(comment)

        rule = Rule({'body (starts-with)': 'Hello', 'action': 'remove'})
        assert mod.moderate(rule), "starts-with match failing to match"

        comment.body = 'Wassup, buddy?'
        self.assertFalse(mod.moderate(rule),
                         "starts-with match matching as false positive")
Ejemplo n.º 4
0
    def test_author_checks(self):
        comment = helpers.comment()
        mod = Moderator(comment)

        rule = Rule({'author': {'post_karma': '> 5'}, 'action': 'remove'})
        assert mod.moderate(rule), "basic author checks are failing"

        rule = Rule({'author': {'post_karma': '> 15'}, 'action': 'remove'})
        self.assertFalse(mod.moderate(rule),
                         "basic author checks are throwing false positive")
Ejemplo n.º 5
0
    def test_full_exact_regex(self):
        comment = helpers.comment()
        mod = Moderator(comment)

        rule = Rule({
            'body (full-exact, regex)': 'Hello,? world!?',
            'action': 'remove'
        })
        assert mod.moderate(
            rule), "full_exact match with regex failing to match"
Ejemplo n.º 6
0
    def test_negation(self):
        comment = helpers.comment()
        mod = Moderator(comment)

        rule = Rule({'id': 'abcde', 'action': 'remove'})
        assert mod.moderate(rule), "Doesn't match when validity is default"

        rule = Rule({'id': ['abcde', 'fghij'], 'action': 'remove'})
        assert mod.moderate(
            rule), "Doesn't match lists when validity is default"

        rule = Rule({'~id': 'abcde', 'action': 'remove'})
        self.assertFalse(mod.moderate(rule), "Matches when validity is false")

        rule = Rule({'id': 'test', 'action': 'remove'})
        self.assertFalse(
            mod.moderate(rule),
            "Matches when validity is default and there's no actual match")

        rule = Rule({'~id': 'test', 'action': 'remove'})
        assert mod.moderate(
            rule
        ), "Doesn't match when validity is false, but there's no actual match"

        rule = Rule({'~id': ['fghij', 'klmno'], 'action': 'remove'})
        assert mod.moderate(
            rule), "Matches when a list of values is given but none match"

        rule = Rule({'~id': ['abcde', 'fghij'], 'action': 'remove'})
        self.assertFalse(
            mod.moderate(rule),
            "Matches when a list of values is given and one matches")
Ejemplo n.º 7
0
    def test_is_edited(self):
        comment = helpers.comment()
        rule = Rule({'is_edited': True, 'action': 'approve'})

        comment.edited = 1595932445.0
        mod = Moderator(comment)
        assert mod.moderate(rule), "is_edited not matching"

        comment.edited = False
        self.assertFalse(mod.moderate(rule),
                         "is_edited matching as false positive")
Ejemplo n.º 8
0
    def test_multiple_values(self):
        comment = helpers.comment()
        mod = Moderator(comment)

        rule = Rule({'id': ['abcde', 'fghij'], 'action': 'remove'})
        assert mod.moderate(rule), "Matches fail with multiple values"

        rule = Rule({'id': ['fghij', 'abcde'], 'action': 'remove'})
        assert mod.moderate(
            rule
        ), "Matches fail with multiple values, when correct value is not first"
Ejemplo n.º 9
0
    def test_author_flair_text(self):
        post = helpers.post()
        rule = Rule({'author': {'flair_text': 'test'}, 'action': 'remove'})
        mod = Moderator(post)

        flair_mock = MagicMock(return_value=iter([{'flair_text': 'test'}]))
        post.subreddit.flair = flair_mock

        assert mod.moderate(rule), "Author flair_text not matching"

        flair_mock.return_value = iter([{'flair_text': 'nomatch'}])
        self.assertFalse(mod.moderate(rule),
                         "Author flair_text matching as a false positive")
Ejemplo n.º 10
0
    def test_include(self):
        comment = helpers.comment()
        mod = Moderator(comment)

        rule = Rule({'body (includes)': 'Ell', 'action': 'remove'})
        assert mod.moderate(rule), "include match failing to match"

        rule = Rule({'body (includes)': 'lo, ', 'action': 'remove'})
        assert mod.moderate(
            rule), "include match failing to match with word boundaries"

        comment.body = "Hello world"
        self.assertFalse(mod.moderate(rule),
                         "include match matching as a false positive")
Ejemplo n.º 11
0
    def test_regex_match(self):
        comment = helpers.comment()
        comment.body = 'Hello, foo! How are you?'
        mod = Moderator(comment)

        rule = Rule({
            'body (full-exact, regex)': 'Hello, [A-za-z]+! How are you\\?',
            'action': 'remove'
        })
        assert mod.moderate(rule), "Regex match failing to match"

        comment.body = 'Hello, Foo Bar! How are you?'
        self.assertFalse(mod.moderate(rule),
                         "Regex match matching as false positive")
Ejemplo n.º 12
0
    def test_moderators_exempt_default(self):
        comment = helpers.comment()
        mod = Moderator(comment)
        rule = Rule({'id': 'abcde', 'action': 'remove'})

        # Default, non-mod
        comment.author.moderated = MagicMock(return_value=[])
        assert mod.moderate(
            rule), "Default moderators_exempt is exempting normal redditors"

        # Default, mod
        comment.author.moderated = MagicMock(return_value=[comment.subreddit])
        self.assertFalse(mod.moderate(rule),
                         "Default moderators_exempt is not exempting mods")
Ejemplo n.º 13
0
    def test_match(self):
        comment = helpers.comment()
        comment.body = "comment with id %s" % comment.id
        rule = Rule({
            'id': comment.id,
            'body (full-exact)': 'comment with id {{match-id}}',
            'action': 'approve'
        })
        mod = Moderator(comment)

        assert mod.moderate(rule), 'Match not injecting itself'

        comment.id = 'fghij'
        self.assertFalse(mod.moderate(rule), 'Match injecting incorrectly')
Ejemplo n.º 14
0
    def test_is_banned(self):
        comment = helpers.comment()
        mod = Moderator(comment)
        rule = Rule({'author': {'is_banned': True}, 'action': 'approve'})
        banned_mock = MagicMock(return_value=[
            1
        ])  #is_banned just checks for any items in the array
        comment.subreddit.banned = banned_mock
        assert mod.moderate(
            rule), "is_banned not matching when one value is returned for bans"
        banned_mock.assert_called_with(redditor=comment.author.name)

        banned_mock.return_value = []
        self.assertFalse(mod.moderate(rule),
                         "is_banned matching as false positive")
Ejemplo n.º 15
0
    def test_multiple_checks(self):
        comment = helpers.comment()
        mod = Moderator(comment)

        rule = Rule({'id+body (full-exact)': 'abcde', 'action': 'remove'})
        assert mod.moderate(rule), "Matches fail when checks are combined"

        rule = Rule({
            'id+body (full-exact)': 'Hello, world!',
            'action': 'remove'
        })
        assert mod.moderate(rule), "Matches fail when checks are combined"

        rule = Rule({'id+body (full-exact)': 'not there', 'action': 'remove'})
        self.assertFalse(mod.moderate(rule),
                         "Matches when checks are combined")
Ejemplo n.º 16
0
    def test_lowercase_checks(self):
        comment = helpers.comment()
        mod = Moderator(comment)

        rule = Rule({'id (full-text)': 'AbCdE', 'action': 'remove'})
        assert mod.moderate(
            rule), "full-text doesn't match when some letters are uppercase"

        rule = Rule({
            'id (full-text, case-sensitive)': 'AbCdE',
            'action': 'remove'
        })
        self.assertFalse(
            mod.moderate(rule),
            "full-text matches even when some letters are uppercase and case-sensitive is on"
        )
Ejemplo n.º 17
0
    def test_body_shorter_than(self):
        comment = helpers.comment()
        rule = Rule({
            'body_shorter_than': len(comment.body) + 1,
            'action': 'approve'
        })

        mod = Moderator(comment)
        assert mod.moderate(rule), "body_shorter_than not matching"

        comment.body = comment.body + 'a'
        self.assertFalse(mod.moderate(rule),
                         'body_shorter_than matching when lengths are equal')

        comment.body = comment.body + 'a'
        self.assertFalse(
            mod.moderate(rule),
            'body_shorter_than matching when the body is too long')
Ejemplo n.º 18
0
    def test_satisfy_any_threshold(self):
        comment = helpers.comment()
        type(comment.author).comment_karma = PropertyMock(return_value=150)
        type(comment.author).link_karma = PropertyMock(return_value=100)
        mod = Moderator(comment)

        rule = Rule({
            'author': {
                'comment_karma': '> 50',
                'post_karma': '< 50'
            },
            'action': 'approve'
        })
        self.assertFalse(
            mod.moderate(rule),
            'Karma rules are passing when false, regardless of satisfy_any_threshold'
        )

        rule = Rule({
            'author': {
                'comment_karma': '> 50',
                'post_karma': '< 50',
                'satisfy_any_threshold': True
            },
            'action': 'approve'
        })
        assert mod.moderate(
            rule
        ), 'Karma rules are not passing when satisfy_any_threshold is True'

        rule = Rule({
            'author': {
                'comment_karma': '< 50',
                'post_karma': '< 50',
                'satisfy_any_threshold': True
            },
            'action': 'approve'
        })
        self.assertFalse(
            mod.moderate(rule),
            'Karma rules matching as false positive when satisfy_any_threshold is True'
        )
Ejemplo n.º 19
0
    def test_body_longer_than(self):
        comment = helpers.comment()
        comment.body = "Hello, world"
        rule = Rule({
            'body_longer_than': len(comment.body) -
            1,  # Removing 2 because the "!" will be removed
            'action': 'approve'
        })

        mod = Moderator(comment)
        assert mod.moderate(rule), "body_longer_than not matching"

        comment.body = comment.body[:-1]
        self.assertFalse(mod.moderate(rule),
                         'body_longer_than matching when lengths are equal')

        comment.body = comment.body[:-1]
        self.assertFalse(
            mod.moderate(rule),
            'body_longer_than matching when the body is too short')
Ejemplo n.º 20
0
    def test_placeholders(self):
        comment = helpers.comment()
        comment.body = "Hello, %s" % comment.author.name
        mod = Moderator(comment)

        rule = Rule({
            'body (full-exact)': 'Hello, {{author}}',
            'action': 'remove'
        })
        assert mod.moderate(rule), "Author placeholder is not replaced"

        comment.body = "Hello, %s, how are you %s?" % (comment.author.name,
                                                       comment.author.name)

        rule = Rule({
            'body (full-exact)': 'Hello, {{author}}, how are you {{author}}?',
            'action': 'remove'
        })
        assert mod.moderate(
            rule
        ), "Author placeholder is not replaced when there are multiple matches"
Ejemplo n.º 21
0
    def test_ignore_blockquotes(self):
        rule = Rule({'ignore_blockquotes': True})
        comment = helpers.comment()
        mod = Moderator(comment)

        # test
        #     test <-- removed
        #          <-- removed
        #     test <-- removed
        # test
        comment.body = "test\n    test\n    \n    test\ntest"
        self.assertEqual(len(mod.checks.body.__wrapped__(mod, rule, [])), 9)

        comment.body = "test ```test\ntest\n    test\n  test\ntest``` test"
        self.assertEqual(len(mod.checks.body.__wrapped__(mod, rule, [])), 10)
Ejemplo n.º 22
0
    def test_moderators_exempt_set(self):
        comment = helpers.comment()
        comment.author.moderated = MagicMock(return_value=[comment.subreddit])
        mod = Moderator(comment)

        # exempt True, mod
        rule = Rule({
            'id': 'abcde',
            'moderators_exempt': True,
            'action': 'remove'
        })
        self.assertFalse(
            mod.moderate(rule),
            "Moderators are not exempted when moderators_exempt is true")

        # exempt False, mod
        rule = Rule({
            'id': 'abcde',
            'moderators_exempt': False,
            'action': 'remove'
        })
        assert mod.moderate(
            rule
        ), "Moderators are exempted even when moderators_exempt is false"
Ejemplo n.º 23
0
    def test_set_sticky(self):
        post = helpers.post()
        mod = Moderator(post)
        sticky_mock = MagicMock()
        post.mod.distinguish = sticky_mock

        # Sets text
        mod.moderate(Rule({'id': post.id, 'set_sticky': True}))
        sticky_mock.assert_called_with('yes', sticky=True)

        sticky_mock.reset_mock()
        mod.moderate(Rule({'id': post.id, 'set_sticky': 1}))
        sticky_mock.assert_called_with('yes', sticky=True)

        sticky_mock.reset_mock()
        mod.moderate(Rule({'id': post.id, 'set_sticky': False}))
        sticky_mock.assert_called_with('no', sticky=False)
Ejemplo n.º 24
0
    def test_reports(self):
        rule = Rule({'reports': 2, 'action': 'approve'})

        comment = helpers.comment()
        comment.user_reports = [['abcde', 1], ['edcba', 1]]
        comment.mod_reports = []
        mod = Moderator(comment)
        assert mod.moderate(
            rule
        ), "Reports (count) not passing when the list contains same number of values"

        comment = helpers.comment()
        comment.user_reports = [['fghij', 1]]
        comment.mod_reports = [['edcba', 1]]
        mod = Moderator(comment)
        assert mod.moderate(
            rule
        ), "Reports (count) are not passing when the list contains the appropriate value between user and mod reports"

        comment.mod_reports = []
        mod = Moderator(comment)
        self.assertFalse(mod.moderate(rule),
                         "Reports (count) matching as false positive")
Ejemplo n.º 25
0
    def test_set_locked(self):
        post = helpers.post()
        mod = Moderator(post)
        lock_mock = MagicMock()
        unlock_mock = MagicMock()
        post.mod.lock = lock_mock
        post.mod.unlock = unlock_mock

        mod.moderate(Rule({'id': post.id, 'set_locked': True}))
        lock_mock.assert_called()
        unlock_mock.assert_not_called()

        lock_mock.reset_mock()
        mod.moderate(Rule({'id': post.id, 'set_locked': False}))
        lock_mock.assert_not_called()
        unlock_mock.assert_called()
Ejemplo n.º 26
0
    def test_report(self):
        post = helpers.post()
        rule = Rule({'id': post.id, 'action': 'report'})
        mod = Moderator(post)

        post.report.reset_mock()
        mod.moderate(rule)
        post.report.assert_called_with(None)

        rule = Rule({
            'id': post.id,
            'action': 'report',
            'action_reason': 'Just cuz'
        })
        post.report.reset_mock()
        mod.moderate(rule)
        post.report.assert_called_with('Just cuz')
Ejemplo n.º 27
0
    def test_full_text(self):
        comment = helpers.comment()
        comment.body = ' .# Hello, world! # ..'
        mod = Moderator(comment)

        rule = Rule({'body (full-text)': 'Hello, world', 'action': 'remove'})
        assert mod.moderate(rule), "full-text match failing to match"

        comment.body = ' .# Hello, world'
        assert mod.moderate(
            rule), "full-text match failing with just leading symbols"

        comment.body = ' Hello, world! # ..'
        assert mod.moderate(
            rule), "full-text match failing with just following symbols"

        comment.body = ' .# Hello, world! # Cya! ..'
        self.assertFalse(mod.moderate(rule),
                         "full-text match matching as false positive")
Ejemplo n.º 28
0
    def test_includes_regex(self):
        comment = helpers.comment()
        mod = Moderator(comment)

        rule = Rule({'body (includes, regex)': 'Hello!?', 'action': 'remove'})
        assert mod.moderate(rule), "include match with regex failing to match"
Ejemplo n.º 29
0
    def test_account_age(self):
        post = helpers.post()
        mod = Moderator(post)

        rule = Rule({
            'author': {
                'account_age': '> 10 minutes'
            },
            'action': 'approve'
        })
        post.author.created_utc = (datetime.today() +
                                   relativedelta(minutes=-11)).timestamp()
        assert mod.moderate(rule), "account_age not matching for minutes"
        post.author.created_utc = (datetime.today() +
                                   relativedelta(minutes=-9)).timestamp()
        self.assertFalse(mod.moderate(rule),
                         "account_age matching as false positive for minutes")

        rule = Rule({
            'author': {
                'account_age': '> 10 hours'
            },
            'action': 'approve'
        })
        post.author.created_utc = (datetime.today() +
                                   relativedelta(hours=-11)).timestamp()
        assert mod.moderate(rule), "account_age not matching for hours"
        post.author.created_utc = (datetime.today() +
                                   relativedelta(hours=-9)).timestamp()
        self.assertFalse(mod.moderate(rule),
                         "account_age matching as false positive for hours")

        rule = Rule({
            'author': {
                'account_age': '> 10 days'
            },
            'action': 'approve'
        })
        post.author.created_utc = (datetime.today() +
                                   relativedelta(days=-11)).timestamp()
        assert mod.moderate(rule), "account_age not matching for days"
        post.author.created_utc = (datetime.today() +
                                   relativedelta(days=-9)).timestamp()
        self.assertFalse(mod.moderate(rule),
                         "account_age matching as false positive for days")

        rule = Rule({
            'author': {
                'account_age': '> 10 weeks'
            },
            'action': 'approve'
        })
        post.author.created_utc = (datetime.today() +
                                   relativedelta(weeks=-11)).timestamp()
        assert mod.moderate(rule), "account_age not matching for weeks"
        post.author.created_utc = (datetime.today() +
                                   relativedelta(weeks=-9)).timestamp()
        self.assertFalse(mod.moderate(rule),
                         "account_age matching as false positive for weeks")

        rule = Rule({
            'author': {
                'account_age': '> 10 years'
            },
            'action': 'approve'
        })
        post.author.created_utc = (datetime.today() +
                                   relativedelta(years=-11)).timestamp()
        assert mod.moderate(rule), "account_age not matching for years"
        post.author.created_utc = (datetime.today() +
                                   relativedelta(years=-9)).timestamp()
        self.assertFalse(mod.moderate(rule),
                         "account_age matching as false positive for years")
Ejemplo n.º 30
0
    def test_set_author_flair(self):
        post = helpers.post()
        mod = Moderator(post)
        flair_mock = MagicMock()
        post.subreddit.flair.set = flair_mock
        old_get_flair = ModeratorAuthorChecks.flair_text.__wrapped__
        get_flair_mock = MagicMock(return_value=None)
        ModeratorAuthorChecks.flair_text.__wrapped__ = get_flair_mock

        # Sets text
        mod.moderate(Rule({'id': post.id, 'author': {'set_flair': 'test'}}))
        flair_mock.assert_called_with(text='test')

        # Sets both text and css
        flair_mock.reset_mock()
        mod.moderate(
            Rule({
                'id': post.id,
                'author': {
                    'set_flair': ['test', 'csstest']
                }
            }))
        flair_mock.assert_called_with(text='test', css_class='csstest')

        # Raises an exception if a dictionary is passed with no template_id
        with self.assertRaises(Exception):
            mod.moderate(
                Rule({
                    'id': post.id,
                    'author': {
                        'set_flair': {
                            'text': 'test'
                        }
                    }
                }))

        # Sets template_id, text, and css
        flair_mock.reset_mock()
        mod.moderate(
            Rule({
                'id': post.id,
                'author': {
                    'set_flair': {
                        'template_id': 'idtest',
                        'text': 'test',
                        'css_class': 'csstest'
                    }
                }
            }))
        flair_mock.assert_called_with(text='test',
                                      css_class='csstest',
                                      template_id='idtest')

        # Does not set new flair, because overwrite_flair is not set
        flair_mock.reset_mock()
        get_flair_mock.return_value = 'before'
        mod.moderate(Rule({'id': post.id, 'author': {'set_flair': 'test'}}))
        flair_mock.assert_not_called()

        mod.moderate(
            Rule({
                'id': post.id,
                'author': {
                    'set_flair': 'test',
                    'overwrite_flair': True
                }
            }))
        flair_mock.assert_called_with(text='test')

        ModeratorAuthorChecks.flair_text.__wrapped__ = old_get_flair