~ubuntu-ru-irc/+junk/irckit

« back to all changes in this revision

Viewing changes to ubuntuhelp/ubuntubot/plugins/Bantracker/test.py

  • Committer: rmPIC30 at gmail
  • Date: 2010-07-13 09:08:58 UTC
  • Revision ID: rmpic30@gmail.com-20100713090858-w5kkmk093hx38cen
Добавляю бота

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- Encoding: utf-8 -*-
 
2
###
 
3
# Copyright (c) 2008-2010 Terence Simpson
 
4
# Copyright (c) 2010 Elián Hanisch
 
5
#
 
6
# This program is free software; you can redistribute it and/or modify
 
7
# it under the terms of version 2 of the GNU General Public License as
 
8
# published by the Free Software Foundation.
 
9
#
 
10
# This program is distributed in the hope that it will be useful,
 
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
# GNU General Public License for more details.
 
14
#
 
15
###
 
16
 
 
17
from supybot.test import *
 
18
 
 
19
import supybot.conf as conf
 
20
import supybot.ircmsgs as ircmsgs
 
21
import supybot.world as world
 
22
 
 
23
import time
 
24
 
 
25
 
 
26
pluginConf = conf.supybot.plugins.Bantracker
 
27
pluginConf.enabled.setValue(True)
 
28
pluginConf.bansite.setValue('http://foo.bar.com')
 
29
pluginConf.database.setValue('bantracker-test.db')
 
30
 
 
31
def quiet(channel, hostmask, prefix='', msg=None):
 
32
    """Returns a MODE to quiet nick on channel."""
 
33
    return ircmsgs.mode(channel, ('+q', hostmask), prefix, msg)
 
34
 
 
35
class BantrackerTestCase(ChannelPluginTestCase):
 
36
    plugins = ('Bantracker',)
 
37
 
 
38
    def setUp(self):
 
39
        self.setDb()
 
40
        super(BantrackerTestCase, self).setUp()
 
41
        pluginConf.request.setValue(False) # disable comments
 
42
        pluginConf.request.ignore.set('')
 
43
        pluginConf.request.forward.set('')
 
44
        pluginConf.request.review.setValue(1.0/86400) # one second
 
45
        # Bantracker for some reason doesn't use Supybot's own methods for check capabilities,
 
46
        # so it doesn't have a clue about testing and screws my tests by default.
 
47
        # This would fix it until I bring myself to take a look
 
48
        cb = self.getCallback()
 
49
        f = cb.check_auth
 
50
        def test_check_auth(*args, **kwargs):
 
51
            if world.testing:
 
52
                return True
 
53
            else:
 
54
                return f(*args, **kwargs)
 
55
        cb.check_auth = test_check_auth
 
56
 
 
57
    def setDb(self):
 
58
        import sqlite, os
 
59
        dbfile = os.path.join(os.curdir, pluginConf.database())
 
60
        try:
 
61
            os.remove(dbfile)
 
62
        except:
 
63
            pass
 
64
        db = sqlite.connect(dbfile)
 
65
        cursor = db.cursor()
 
66
        cursor.execute('CREATE TABLE bans ('
 
67
                'id INTEGER PRIMARY KEY,'
 
68
                'channel VARCHAR(30) NOT NULL,'
 
69
                'mask VARCHAR(100) NOT NULL,'
 
70
                'operator VARCHAR(30) NOT NULL,'
 
71
                'time VARCHAR(300) NOT NULL,'
 
72
                'removal DATETIME,'
 
73
                'removal_op VARCHAR(30),'
 
74
                'log TEXT)')
 
75
        cursor.execute('CREATE TABLE comments ('
 
76
                'ban_id INTEGER,'
 
77
                'who VARCHAR(100) NOT NULL,'
 
78
                'comment MEDIUMTEXT NOT NULL,'
 
79
                'time VARCHAR(300) NOT NULL)')
 
80
        cursor.execute('CREATE TABLE sessions ('
 
81
                'session_id VARCHAR(50) PRIMARY KEY,'
 
82
                'user MEDIUMTEXT NOT NULL,'
 
83
                'time INT NOT NULL)')
 
84
        cursor.execute('CREATE TABLE users ('
 
85
                'username VARCHAR(50) PRIMARY KEY,'
 
86
                'salt VARCHAR(8),'
 
87
                'password VARCHAR(50))')
 
88
        db.commit()
 
89
        cursor.close()
 
90
        db.close()
 
91
 
 
92
    def getCallback(self):
 
93
        for cb in self.irc.callbacks:
 
94
            if cb.name() == 'Bantracker':
 
95
                break
 
96
        return cb
 
97
 
 
98
    def getDb(self):
 
99
        return self.getCallback().db
 
100
 
 
101
    def query(self, query, parms=()):
 
102
        cursor = self.getDb().cursor()
 
103
        cursor.execute(query, parms)
 
104
        return cursor.fetchall()
 
105
 
 
106
    def feedBan(self, hostmask, prefix='', channel=None, mode='b'):
 
107
        if not channel:
 
108
            channel = self.channel
 
109
        if not prefix:
 
110
            prefix = 'op!user@host.net'
 
111
        if mode == 'b':
 
112
            ban = ircmsgs.ban(channel, hostmask, prefix=prefix)
 
113
        elif mode == 'q':
 
114
            ban = quiet(channel, hostmask, prefix=prefix)
 
115
        elif mode == 'k':
 
116
            ban = ircmsgs.kick(channel, hostmask, s='kthxbye!', prefix=prefix)
 
117
        elif mode == 'p':
 
118
            ban = ircmsgs.part(channel, prefix=hostmask,
 
119
                    s='requested by %s (kthxbye!)' %prefix[:prefix.find('!')])
 
120
        self.irc.feedMsg(ban)
 
121
        return ban
 
122
 
 
123
    def testComment(self):
 
124
        pluginConf.request.setValue(True)
 
125
        # test bans
 
126
        self.feedBan('asd!*@*')
 
127
        msg = self.irc.takeMsg()
 
128
        self.assertEqual(str(msg).strip(), 
 
129
            "PRIVMSG op :Please comment on the ban of asd!*@* in #test, use: @comment 1"
 
130
            " <comment>")
 
131
        # test quiets
 
132
        self.feedBan('dude!*@*', mode='q')
 
133
        msg = self.irc.takeMsg()
 
134
        self.assertEqual(str(msg).strip(), 
 
135
            "PRIVMSG op :Please comment on the quiet of dude!*@* in #test, use: @comment 2"
 
136
            " <comment>")
 
137
        # test kick/part
 
138
        self.feedBan('dude', mode='k')
 
139
        msg = self.irc.takeMsg()
 
140
        self.assertEqual(str(msg).strip(), 
 
141
            "PRIVMSG op :Please comment on the removal of dude in #test, use: @comment 3"
 
142
            " <comment>")
 
143
        self.feedBan('dude!dude@trollpit.com', mode='p')
 
144
        msg = self.irc.takeMsg()
 
145
        self.assertEqual(str(msg).strip(), 
 
146
            "PRIVMSG op :Please comment on the removal of dude in #test, use: @comment 4"
 
147
            " <comment>")
 
148
 
 
149
    def testCommentIgnore(self):
 
150
        pluginConf.request.setValue(True)
 
151
        pluginConf.request.ignore.set('FloodBot? FloodBotK?')
 
152
        self.feedBan('asd!*@*', prefix='floodbotk1!bot@botpit.com')
 
153
        msg = self.irc.takeMsg()
 
154
        self.assertEqual(msg, None)
 
155
        self.feedBan('dude!*@*', mode='q', prefix='FloodBot1!bot@botpit.com')
 
156
        msg = self.irc.takeMsg()
 
157
        self.assertEqual(msg, None)
 
158
        self.feedBan('dude', mode='k', prefix='FloodBot2!bot@botbag.com')
 
159
        msg = self.irc.takeMsg()
 
160
        self.assertEqual(msg, None)
 
161
        self.feedBan('dude!dude@trollpit.com', mode='p', prefix='FloodBotK2!bot@botbag.com')
 
162
        msg = self.irc.takeMsg()
 
163
        self.assertEqual(msg, None)
 
164
        self.feedBan('asd!*@*')
 
165
        msg = self.irc.takeMsg()
 
166
        self.assertEqual(str(msg).strip(), 
 
167
            "PRIVMSG op :Please comment on the ban of asd!*@* in #test, use: @comment 5"
 
168
            " <comment>")
 
169
 
 
170
    def testCommentForward(self):
 
171
        pluginConf.request.setValue(True)
 
172
        pluginConf.request.forward.set('bot')
 
173
        pluginConf.request.forward.channels.set('#channel')
 
174
        self.feedBan('qwe!*@*')
 
175
        msg = self.irc.takeMsg()
 
176
        self.assertEqual(str(msg).strip(), 
 
177
            "PRIVMSG op :Please comment on the ban of qwe!*@* in #test, use: @comment 1"
 
178
            " <comment>")
 
179
        self.feedBan('zxc!*@*', prefix='bot!user@host.com')
 
180
        msg = self.irc.takeMsg()
 
181
        self.assertEqual(str(msg).strip(), 
 
182
            "NOTICE #channel :Please somebody comment on the ban of zxc!*@* in #test done by bot,"
 
183
            " use: @comment 2 <comment>")
 
184
 
 
185
    def testReview(self):
 
186
        pluginConf.request.setValue(True)
 
187
        cb = self.getCallback()
 
188
        self.feedBan('asd!*@*')
 
189
        self.irc.takeMsg() # ignore comment request comment
 
190
        cb.reviewBans()
 
191
        self.assertFalse(cb.pendingReviews)
 
192
        print 'waiting 4 secs..'
 
193
        time.sleep(2)
 
194
        cb.reviewBans()
 
195
        # check is pending
 
196
        self.assertTrue(cb.pendingReviews)
 
197
        # send msg if a user with a matching host says something
 
198
        self.feedMsg('Hi!', frm='op!user@fakehost.net') 
 
199
        msg = self.irc.takeMsg()
 
200
        self.assertEqual(msg, None)
 
201
        self.feedMsg('Hi!', frm='op_!user@host.net') 
 
202
        msg = self.irc.takeMsg()
 
203
        self.assertEqual(str(msg).strip(),
 
204
            "PRIVMSG op_ :Hi, please review the ban 'asd!*@*' that you set on %s in #test, link: "\
 
205
            "%s/bans.cgi?log=1" %(cb.bans['#test'][0].ascwhen, pluginConf.bansite()))
 
206
        # don't ask again
 
207
        cb.reviewBans()
 
208
        self.assertFalse(cb.pendingReviews)
 
209
        # test again with two ops
 
210
        self.feedBan('asd2!*@*')
 
211
        self.irc.takeMsg()
 
212
        self.feedBan('qwe!*@*', prefix='otherop!user@home.net')
 
213
        self.irc.takeMsg()
 
214
        time.sleep(2)
 
215
        cb.reviewBans()
 
216
        self.assertTrue(len(cb.pendingReviews) == 2)
 
217
        self.feedMsg('Hi!', frm='op!user@fakehost.net') 
 
218
        msg = self.irc.takeMsg()
 
219
        self.assertEqual(msg, None)
 
220
        self.assertResponse('banreview', 'Pending ban reviews (2): otherop:1 op:1')
 
221
        self.feedMsg('Hi!', frm='mynickissocreative!user@home.net') 
 
222
        msg = self.irc.takeMsg()
 
223
        self.assertEqual(str(msg).strip(),
 
224
            "PRIVMSG mynickissocreative :Hi, please review the ban 'qwe!*@*' that you set on %s in #test, link: "\
 
225
            "%s/bans.cgi?log=3" %(cb.bans['#test'][2].ascwhen, pluginConf.bansite()))
 
226
        self.feedMsg('ping', to='test', frm='op!user@host.net') # in a query
 
227
        self.irc.takeMsg() # drop pong reply
 
228
        msg = self.irc.takeMsg()
 
229
        self.assertEqual(str(msg).strip(),
 
230
            "PRIVMSG op :Hi, please review the ban 'asd2!*@*' that you set on %s in #test, link: "\
 
231
            "%s/bans.cgi?log=2" %(cb.bans['#test'][1].ascwhen, pluginConf.bansite()))
 
232
 
 
233
    def testReviewForward(self):
 
234
        pluginConf.request.setValue(True)
 
235
        pluginConf.request.forward.set('bot')
 
236
        pluginConf.request.forward.channels.set('#channel')
 
237
        cb = self.getCallback()
 
238
        self.feedBan('asd!*@*', prefix='bot!user@host.net')
 
239
        self.irc.takeMsg() # ignore comment request comment
 
240
        cb.reviewBans(self.irc)
 
241
        self.assertFalse(cb.pendingReviews)
 
242
        print 'waiting 2 secs..'
 
243
        time.sleep(2)
 
244
        cb.reviewBans(self.irc)
 
245
        # since it's a forward, it was sent already
 
246
        self.assertFalse(cb.pendingReviews)
 
247
        msg = self.irc.takeMsg()
 
248
        self.assertEqual(str(msg).strip(),
 
249
            "NOTICE #channel :Hi, please somebody review the ban 'asd!*@*' set by bot on %s in #test, link: "\
 
250
            "%s/bans.cgi?log=1" %(cb.bans['#test'][0].ascwhen, pluginConf.bansite()))
 
251
 
 
252
    def testReviewIgnore(self):
 
253
        pluginConf.request.setValue(True)
 
254
        pluginConf.request.ignore.set('FloodBot? FloodBotK?')
 
255
        cb = self.getCallback()
 
256
        self.feedBan('asd!*@*', prefix='floodbotk1!bot@botpit.com')
 
257
        cb.reviewBans(self.irc)
 
258
        self.assertFalse(cb.pendingReviews)
 
259
        print 'waiting 2 secs..'
 
260
        time.sleep(2)
 
261
        cb.reviewBans(self.irc)
 
262
        # since it's was ignored, it should not be queued
 
263
        self.assertFalse(cb.pendingReviews)
 
264
 
 
265
    def testReviewNickFallback(self):
 
266
        """If for some reason we don't have ops full hostmask, revert to nick match. This may be
 
267
        needed in the future as hostmasks aren't stored in the db."""
 
268
        pluginConf.request.setValue(True)
 
269
        cb = self.getCallback()
 
270
        self.feedBan('asd!*@*')
 
271
        self.irc.takeMsg() # ignore comment request comment
 
272
        cb.bans['#test'][0].who = 'op' # replace hostmask by nick
 
273
        print 'waiting 2 secs..'
 
274
        time.sleep(2)
 
275
        cb.reviewBans()
 
276
        # check is pending
 
277
        self.assertTrue(cb.pendingReviews)
 
278
        self.assertResponse('banreview', 'Pending ban reviews (1): op:1')
 
279
        # send msg if a user with a matching nick says something
 
280
        self.feedMsg('Hi!', frm='op_!user@host.net') 
 
281
        msg = self.irc.takeMsg()
 
282
        self.assertEqual(msg, None)
 
283
        self.feedMsg('Hi!', frm='op!user@host.net') 
 
284
        msg = self.irc.takeMsg()
 
285
        self.assertEqual(str(msg).strip(),
 
286
            "PRIVMSG op :Hi, please review the ban 'asd!*@*' that you set on %s in #test, link: "\
 
287
            "%s/bans.cgi?log=1" %(cb.bans['#test'][0].ascwhen, pluginConf.bansite()))
 
288
        # check not pending anymore
 
289
        self.assertFalse(cb.pendingReviews)
 
290
 
 
291
    def testPersistentCache(self):
 
292
        """Save pending reviews and when bans were last checked. This is needed for plugin
 
293
        reloads"""
 
294
        msg1 = ircmsgs.privmsg('nick', 'Hello World')
 
295
        msg2 = ircmsgs.privmsg('nick', 'Hello World') # duplicate msg, should be ignored
 
296
        msg2 = ircmsgs.privmsg('nick', 'Hello World2')
 
297
        msg3 = ircmsgs.notice('#chan', 'Hello World')
 
298
        msg4 = ircmsgs.privmsg('nick_', 'Hello World')
 
299
        pr = self.getCallback().pendingReviews
 
300
        pr['host.net'] = [('op', msg1), ('op', msg2), ('op_', msg3)]
 
301
        pr['home.net'] = [('dude', msg4)]
 
302
        self.assertResponse('banreview', 'Pending ban reviews (4): op_:1 dude:1 op:2')
 
303
        pr.close()
 
304
        pr.clear()
 
305
        pr.open()
 
306
        self.assertResponse('banreview', 'Pending ban reviews (4): op_:1 dude:1 op:2')
 
307
        items = pr['host.net']
 
308
        self.assertTrue(items[0][0] == 'op' and items[0][1] == msg1)
 
309
        self.assertTrue(items[1][0] == 'op' and items[1][1] == msg2)
 
310
        self.assertTrue(items[2][0] == 'op_' and items[2][1] == msg3)
 
311
        items = pr['home.net']
 
312
        self.assertTrue(items[0][0] == 'dude' and items[0][1] == msg4)
 
313
 
 
314
    def testReviewBanreview(self):
 
315
        pr = self.getCallback().pendingReviews
 
316
        m = ircmsgs.privmsg('#test', 'asd')
 
317
        pr['host.net'] = [('op', m), ('op_', m), ('op', m)]
 
318
        pr['home.net'] = [('dude', m)]
 
319
        self.assertResponse('banreview', 'Pending ban reviews (4): op_:1 dude:1 op:2')
 
320
 
 
321
    def testBan(self):
 
322
        self.feedBan('asd!*@*')
 
323
        fetch = self.query("SELECT id,channel,mask,operator FROM bans")
 
324
        self.assertEqual((1, '#test', 'asd!*@*', 'op'), fetch[0])
 
325
 
 
326
    def testQuiet(self):
 
327
        self.feedBan('asd!*@*', mode='q')
 
328
        fetch = self.query("SELECT id,channel,mask,operator FROM bans")
 
329
        self.assertEqual((1, '#test', '%asd!*@*', 'op'), fetch[0])
 
330
 
 
331
    def testKick(self):
 
332
        self.feedBan('troll', mode='k')
 
333
        fetch = self.query("SELECT id,channel,mask,operator FROM bans")
 
334
        self.assertEqual((1, '#test', 'troll', 'op'), fetch[0])
 
335
 
 
336
    def testPart(self):
 
337
        self.feedBan('troll!user@trollpit.net', mode='p')
 
338
        fetch = self.query("SELECT id,channel,mask,operator FROM bans")
 
339
        self.assertEqual((1, '#test', 'troll', 'op'), fetch[0])
 
340
 
 
341
 
 
342