Limnoria/plugins/Config/test.py
Valentin Lorentz 63eb6672ea Revert generic 'The Limnoria Contributors' in copyright notices
This commit reverts db7ef3f025
(though it keeps the year updates)

After discussion with several people, it seems better to mention
copyright owners explicitly. eg. https://reuse.software/faq/#vcs-copyright
explains the issue of using VCSs to track copyright.

As db7ef3f025 only replaced mentions
of my name with 'The Limnoria Contributors', this commit only needs
to undo that + add one person who contributed to setup.py.
2021-10-17 09:57:55 +02:00

515 lines
23 KiB
Python

###
# Copyright (c) 2002-2005, Jeremiah Fincher
# Copyright (c) 2009, James McCoy
# Copyright (c) 2010-2021, Valentin Lorentz
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions, and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions, and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the author of this software nor the name of
# contributors to this software may be used to endorse or promote products
# derived from this software without specific prior written consent.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
###
import random
from supybot.test import *
import supybot.conf as conf
_letters = 'abcdefghijklmnopqrstuvwxyz'
def random_string():
return ''.join(random.choice(_letters) for _ in range(16))
class ConfigTestCase(ChannelPluginTestCase):
# We add utilities so there's something in supybot.plugins.
plugins = ('Config', 'User', 'Utilities', 'Web')
prefix1 = 'somethingElse!user@host1.tld'
prefix2 = 'EvensomethingElse!user@host2.tld'
prefix3 = 'Completely!Different@host3.tld__no_testcap__'
def testGet(self):
self.assertNotRegexp('config get supybot.reply', r'registry\.Group')
self.assertResponse('config supybot.protocols.irc.throttleTime', '0.0')
def testList(self):
self.assertError('config list asldfkj')
self.assertError('config list supybot.asdfkjsldf')
self.assertNotError('config list supybot')
self.assertRegexp('config list supybot.replies', ', #:errorOwner, ')
self.assertRegexp('config list supybot', r'@plugins.*@replies.*@reply')
def testListExcludes(self):
"""Checks that 'config list' excludes pseudo-children of
network-specific and channel-specific variables."""
self.assertNotError(
'config channel #zpojfejf supybot.replies.error foo')
self.assertRegexp('config list supybot.replies.error',
"There don't seem to be any values")
def testHelp(self):
self.assertError('config help alsdkfj')
self.assertError('config help supybot.alsdkfj')
self.assertNotError('config help supybot') # We tell the user to list.
self.assertNotError('config help supybot.plugins')
self.assertNotError('config help supybot.replies.success')
self.assertNotError('config help replies.success')
def testHelpDoesNotAssertionError(self):
self.assertNotRegexp('config help ' # Cont'd.
'supybot.commands.defaultPlugins.help',
'AssertionError')
def testHelpExhaustively(self):
L = conf.supybot.getValues(getChildren=True)
for (name, v) in L:
self.assertNotError('config help %s' % name)
def testSearch(self):
self.assertRegexp(
'config search chars', 'supybot.reply.whenAddressedBy.chars')
self.assertNotError('config channel reply.whenAddressedBy.chars @')
self.assertNotRegexp('config search chars', self.channel)
def testSearchHelp(self):
self.assertRegexp(
'config searchhelp "what prefix characters"',
'supybot.reply.whenAddressedBy.chars')
self.assertNotError('config channel reply.whenAddressedBy.chars @')
self.assertNotRegexp(
'config searchhelp "what prefix characters"', self.channel)
def testSearchValues(self):
self.assertResponse(
'config searchvalues @@@',
'There were no matching configuration variables.')
self.assertNotError('config channel reply.whenAddressedBy.strings @@@')
self.assertResponse(
'config searchvalues @@@',
r'supybot.reply.whenAddressedBy.strings.#test and '
r'supybot.reply.whenAddressedBy.strings.\:test.#test')
def testDefault(self):
self.assertNotError('config default '
'supybot.replies.genericNoCapability')
def testConfigErrors(self):
self.assertRegexp('config supybot.replies.', 'not a valid')
self.assertRegexp('config supybot.repl', 'not a valid')
self.assertRegexp('config supybot.reply.withNickPrefix 123',
'True or False.*, not \'123\'.')
self.assertRegexp('config supybot.replies foo', 'settable')
def testReadOnly(self):
old_plugins_dirs = conf.supybot.directories.plugins()
try:
self.assertResponse('config supybot.commands.allowShell', 'True')
self.assertNotError('config supybot.directories.plugins dir1')
self.assertNotError('config supybot.commands.allowShell True')
self.assertResponse('config supybot.commands.allowShell', 'True')
self.assertResponse('config supybot.directories.plugins', 'dir1')
self.assertNotError('config supybot.commands.allowShell False')
self.assertResponse('config supybot.commands.allowShell', 'False')
self.assertRegexp('config supybot.directories.plugins dir2',
'Error.*not writeable')
self.assertResponse('config supybot.directories.plugins', 'dir1')
self.assertRegexp('config supybot.commands.allowShell True',
'Error.*not writeable')
self.assertResponse('config supybot.commands.allowShell', 'False')
self.assertRegexp('config commands.allowShell True',
'Error.*not writeable')
self.assertResponse('config supybot.commands.allowShell', 'False')
self.assertRegexp('config COMMANDS.ALLOWSHELL True',
'Error.*not writeable')
self.assertResponse('config supybot.commands.allowShell', 'False')
finally:
conf.supybot.commands.allowShell.setValue(True)
conf.supybot.directories.plugins.setValue(old_plugins_dirs)
def testOpEditable(self):
var_name = 'testOpEditable' + random_string()
conf.registerChannelValue(conf.supybot.plugins.Config, var_name,
registry.Integer(0, 'help'))
self.assertNotError('register bar passwd', frm=self.prefix3,
private=True)
self.assertRegexp('whoami', 'bar', frm=self.prefix3)
ircdb.users.getUser('bar').addCapability(self.channel + ',op')
self.assertRegexp('config plugins.Config.%s 1' % var_name,
'^Completely: Error: ',
frm=self.prefix3)
self.assertResponse('config plugins.Config.%s' % var_name,
'Global: 0; #test @ test: 0')
self.assertNotRegexp('config channel plugins.Config.%s 1' % var_name,
'^Completely: Error: ',
frm=self.prefix3)
self.assertResponse('config plugins.Config.%s' % var_name,
'Global: 0; #test @ test: 1')
def testOpNonEditable(self):
var_name = 'testOpNonEditable' + random_string()
conf.registerChannelValue(conf.supybot.plugins.Config, var_name,
registry.Integer(0, 'help'), opSettable=False)
self.assertNotError('register bar passwd', frm=self.prefix3,
private=True)
self.assertRegexp('whoami', 'bar', frm=self.prefix3)
ircdb.users.getUser('bar').addCapability(self.channel + ',op')
self.assertRegexp('config plugins.Config.%s 1' % var_name,
'^Completely: Error: ',
frm=self.prefix3)
self.assertResponse('config plugins.Config.%s' % var_name,
'Global: 0; #test @ test: 0')
self.assertRegexp('config channel plugins.Config.%s 1' % var_name,
'^Completely: Error: ',
frm=self.prefix3)
self.assertResponse('config plugins.Config.%s' % var_name,
'Global: 0; #test @ test: 0')
self.assertNotRegexp('config channel plugins.Config.%s 1' % var_name,
'^Completely: Error: ')
self.assertResponse('config plugins.Config.%s' % var_name,
'Global: 0; #test @ test: 1')
def testChannel(self):
try:
conf.supybot.reply.whenAddressedBy.strings.get(':test').unregister(self.channel)
conf.supybot.reply.whenAddressedBy.strings.unregister(':test')
conf.supybot.reply.whenAddressedBy.strings.unregister(self.channel)
except:
pass
self.assertResponse('config reply.whenAddressedBy.strings ^',
'The operation succeeded.')
self.assertResponse('config channel reply.whenAddressedBy.strings @',
'The operation succeeded.')
self.assertResponse('config channel reply.whenAddressedBy.strings', '@')
self.assertNotError('config channel reply.whenAddressedBy.strings $')
self.assertResponse('config channel #testchan1 reply.whenAddressedBy.strings', '^')
self.assertResponse('config channel #testchan2 reply.whenAddressedBy.strings', '^')
self.assertNotError('config channel #testchan1,#testchan2 reply.whenAddressedBy.strings .')
self.assertResponse('config channel reply.whenAddressedBy.strings', '$')
self.assertResponse('config channel #testchan1 reply.whenAddressedBy.strings', '.')
self.assertResponse('config channel #testchan2 reply.whenAddressedBy.strings', '.')
def testNetwork(self):
getTestIrc('testnet1')
getTestIrc('testnet2')
self.assertResponse('config reply.whenAddressedBy.strings ^',
'The operation succeeded.')
self.assertResponse('config network reply.whenAddressedBy.strings @',
'The operation succeeded.')
self.assertResponse('config network reply.whenAddressedBy.strings', '@')
self.assertNotError('config network reply.whenAddressedBy.strings $')
self.assertResponse('config network testnet1 reply.whenAddressedBy.strings', '^')
self.assertResponse('config network testnet2 reply.whenAddressedBy.strings', '^')
self.assertResponse('config network reply.whenAddressedBy.strings', '$')
self.assertResponse('config network testnet1 reply.whenAddressedBy.strings', '^')
self.assertResponse('config network testnet2 reply.whenAddressedBy.strings', '^')
self.assertNotError('config network testnet1 reply.whenAddressedBy.strings =')
self.assertResponse('config network testnet1 reply.whenAddressedBy.strings', '=')
self.assertResponse('config network testnet2 reply.whenAddressedBy.strings', '^')
def testChannelNetwork(self):
irc = self.irc
irc1 = getTestIrc('testnet1')
irc2 = getTestIrc('testnet2')
irc3 = getTestIrc('testnet3')
conf.supybot.reply.whenAddressedBy.strings.get('#test')._wasSet = False
# 1. Set global
self.assertResponse('config reply.whenAddressedBy.strings ^',
'The operation succeeded.')
# 2. Set for current net + #testchan1
self.assertResponse('config channel #testchan1 reply.whenAddressedBy.strings @',
'The operation succeeded.')
# Exact match for #2:
self.assertResponse('config channel #testchan1 reply.whenAddressedBy.strings', '@')
# 3: Set for #testchan1 for all nets:
self.assertNotError('config channel * #testchan1 reply.whenAddressedBy.strings $')
# Still exact match for #2:
self.assertResponse('config channel #testchan1 reply.whenAddressedBy.strings', '@')
# Inherit from *:
self.assertResponse('config channel testnet1 #testchan1 reply.whenAddressedBy.strings', '$')
self.assertResponse('config channel testnet2 #testchan1 reply.whenAddressedBy.strings', '$')
# 4: Set for testnet1 for #testchan1 and #testchan2:
self.assertNotError('config channel testnet1 #testchan1,#testchan2 reply.whenAddressedBy.strings .')
# 5: Set for testnet2 for #testchan1:
self.assertNotError('config channel testnet2 #testchan1 reply.whenAddressedBy.strings :')
# Inherit from global value (nothing was set of current net or current
# chan):
(old_channel, self.channel) = (self.channel, '#iejofjfozifk')
try:
self.assertResponse('config channel reply.whenAddressedBy.strings', '^')
finally:
self.channel = old_channel
# Still exact match for #2:
self.assertResponse('config channel #testchan1 reply.whenAddressedBy.strings', '@')
self.assertResponse('config channel %s #testchan1 reply.whenAddressedBy.strings' % irc.network, '@')
# Exact match for #4:
self.assertResponse('config channel testnet1 #testchan1 reply.whenAddressedBy.strings', '.')
self.assertResponse('config channel testnet1 #testchan2 reply.whenAddressedBy.strings', '.')
# Inherit from #5, which set for #testchan1 on all nets
self.assertResponse('config channel testnet3 #testchan1 reply.whenAddressedBy.strings', ':')
def testChannelInheritance(self):
try:
conf.supybot.reply.whenAddressedBy.strings.get(':test').unregister(self.channel)
conf.supybot.reply.whenAddressedBy.strings.unregister(':test')
conf.supybot.reply.whenAddressedBy.strings.unregister(self.channel)
except:
pass
self.assertResponse('config reply.whenAddressedBy.strings ^',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: ^; #test @ test: ^')
self.assertResponse('config channel reply.whenAddressedBy.strings', '^')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertFalse(
conf.supybot.reply.whenAddressedBy.strings.get(self.channel)._wasSet)
# Parent changes, child follows
self.assertResponse('config reply.whenAddressedBy.strings @',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: @; #test @ test: @')
self.assertResponse('config channel reply.whenAddressedBy.strings', '@')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertFalse(
conf.supybot.reply.whenAddressedBy.strings.get(self.channel)._wasSet)
# Child changes, parent keeps its value
self.assertResponse('config channel reply.whenAddressedBy.strings $',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: @; #test @ test: $')
self.assertResponse('config channel reply.whenAddressedBy.strings', '$')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings.get(self.channel)._wasSet)
# Parent changes, child keeps its value
self.assertResponse('config reply.whenAddressedBy.strings .',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: .; #test @ test: $')
self.assertResponse('config channel reply.whenAddressedBy.strings', '$')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings.get(self.channel)._wasSet)
def testResetChannel(self):
try:
conf.supybot.reply.whenAddressedBy.strings.get(':test').unregister(self.channel)
conf.supybot.reply.whenAddressedBy.strings.unregister(':test')
conf.supybot.reply.whenAddressedBy.strings.unregister(self.channel)
except:
pass
self.assertResponse('config reply.whenAddressedBy.strings ^',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: ^; #test @ test: ^')
self.assertResponse('config channel reply.whenAddressedBy.strings', '^')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertFalse(
conf.supybot.reply.whenAddressedBy.strings.get(self.channel)._wasSet)
# Child changes, parent keeps its value
self.assertResponse('config channel reply.whenAddressedBy.strings $',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: ^; #test @ test: $')
self.assertResponse('config channel reply.whenAddressedBy.strings', '$')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings.get(self.channel)._wasSet)
# Reset child
self.assertResponse('config reset channel reply.whenAddressedBy.strings',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: ^; #test @ test: ^')
self.assertResponse('config channel reply.whenAddressedBy.strings', '^')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertFalse(
conf.supybot.reply.whenAddressedBy.strings.get(self.channel)._wasSet)
# Parent changes, child follows
self.assertResponse('config reply.whenAddressedBy.strings .',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: .; #test @ test: .')
self.assertResponse('config channel reply.whenAddressedBy.strings', '.')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertFalse(
conf.supybot.reply.whenAddressedBy.strings.get(self.channel)._wasSet)
def testResetNetwork(self):
try:
conf.supybot.reply.whenAddressedBy.strings.unregister(':test')
except:
pass
self.assertResponse('config reply.whenAddressedBy.strings ^',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: ^; #test @ test: ^')
self.assertResponse('config network reply.whenAddressedBy.strings', '^')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertFalse(
conf.supybot.reply.whenAddressedBy.strings.get(':test')._wasSet)
# Child changes, parent keeps its value
self.assertResponse('config network reply.whenAddressedBy.strings $',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: ^; #test @ test: $')
self.assertResponse('config network reply.whenAddressedBy.strings', '$')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings.get(':test')._wasSet)
# Reset child
self.assertResponse('config reset network reply.whenAddressedBy.strings',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: ^; #test @ test: ^')
self.assertResponse('config network reply.whenAddressedBy.strings', '^')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertFalse(
conf.supybot.reply.whenAddressedBy.strings.get(':test')._wasSet)
# Parent changes, child follows
self.assertResponse('config reply.whenAddressedBy.strings .',
'The operation succeeded.')
self.assertResponse('config reply.whenAddressedBy.strings',
'Global: .; #test @ test: .')
self.assertResponse('config network reply.whenAddressedBy.strings', '.')
self.assertTrue(
conf.supybot.reply.whenAddressedBy.strings._wasSet)
self.assertFalse(
conf.supybot.reply.whenAddressedBy.strings.get(':test')._wasSet)
def testResetRegexpChannel(self):
"""Specifically tests resetting a Regexp value, as they have an extra
internal state that needs to be reset; see the comment in plugin.py"""
self.assertResponse(
'config plugins.Web.nonSnarfingRegexp',
'Global: ; #test @ test: '
)
self.assertResponse(
'config plugins.Web.nonSnarfingRegexp m/foo/',
'The operation succeeded.'
)
self.assertResponse(
'config channel plugins.Web.nonSnarfingRegexp m/bar/',
'The operation succeeded.'
)
self.assertResponse(
'config plugins.Web.nonSnarfingRegexp',
'Global: m/foo/; #test @ test: m/bar/'
)
self.assertResponse(
'config reset channel plugins.Web.nonSnarfingRegexp',
'The operation succeeded.'
)
self.assertResponse('config plugins.Web.nonSnarfingRegexp',
'Global: m/foo/; #test @ test: m/foo/'
)
self.assertResponse(
'config plugins.Web.nonSnarfingRegexp ""',
'The operation succeeded.'
)
self.assertResponse(
'config plugins.Web.nonSnarfingRegexp',
'Global: ; #test @ test: '
)
def testResetRegexpNetwork(self):
"""Specifically tests resetting a Regexp value, as they have an extra
internal state that needs to be reset; see the comment in plugin.py"""
self.assertResponse(
'config plugins.Web.nonSnarfingRegexp',
'Global: ; #test @ test: '
)
self.assertResponse(
'config plugins.Web.nonSnarfingRegexp m/foo/',
'The operation succeeded.'
)
self.assertResponse(
'config network plugins.Web.nonSnarfingRegexp m/bar/',
'The operation succeeded.'
)
self.assertResponse(
'config plugins.Web.nonSnarfingRegexp',
'Global: m/foo/; #test @ test: m/bar/'
)
self.assertResponse(
'config reset network plugins.Web.nonSnarfingRegexp',
'The operation succeeded.'
)
self.assertResponse('config plugins.Web.nonSnarfingRegexp',
'Global: m/foo/; #test @ test: m/foo/'
)
self.assertResponse(
'config plugins.Web.nonSnarfingRegexp ""',
'The operation succeeded.'
)
self.assertResponse(
'config plugins.Web.nonSnarfingRegexp',
'Global: ; #test @ test: '
)
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: