from twisted.trial import unittest
from axiom import store, userbase
from xmantissa import signup, offering
from xmantissa.plugins import free_signup
from xmantissa.product import Product, Installation
class SignupCreationTestCase(unittest.TestCase):
def setUp(self):
self.dbdir = self.mktemp()
self.store = store.Store(self.dbdir)
self.ls = userbase.LoginSystem(store=self.store)
self.admin = self.ls.addAccount(u'admin', u'localhost', None,
internal=True, verified=True)
self.substore = self.admin.avatars.open()
self.sc = signup.SignupConfiguration(store=self.substore)
def _installTestOffering(self):
io = offering.InstalledOffering(
store=self.store,
offeringName=u"mantissa",
application=None)
def createFreeSignup(self, itemClass, url=u'signup', prompt=u'Sign Up!'):
"""
A utility method to ensure that the same arguments are always used to
create signup mechanisms, since these are the arguments that are going
to be coming from the admin form.
"""
self.ftp = Product(store=self.store, types=[])
return self.sc.createSignup(
u'testuser@localhost',
itemClass,
{'prefixURL': url},
self.ftp,
u'Blank Email Template', prompt)
def testCreateFreeSignups(self):
self._installTestOffering()
for signupMechanismPlugin in [free_signup.freeTicket,
free_signup.userInfo]:
self.createFreeSignup(signupMechanismPlugin.itemClass)
def test_usernameAvailability(self):
"""
Test that the usernames which ought to be available are and that those
which aren't are not:
Only syntactically valid localparts are allowed. Localparts which are
already assigned are not allowed.
Only domains which are actually served by this mantissa instance are
allowed.
"""
signup = self.createFreeSignup(free_signup.userInfo.itemClass)
# Allowed: unused localpart, same domain as the administrator created
# by setUp.
self.failUnless(signup.usernameAvailable(u'alice', u'localhost')[0])
# Not allowed: unused localpart, unknown domain.
self.failIf(signup.usernameAvailable(u'alice', u'example.com')[0])
# Not allowed: used localpart, same domain as the administrator created
# by setUp.
self.failIf(signup.usernameAvailable(u'admin', u'localhost')[0])
self.assertEquals(signup.usernameAvailable(u'fjones', u'localhost'),
[True, u'Username already taken'])
signup.createUser(
firstName=u"Frank",
lastName=u"Jones",
username=u'fjones',
domain=u'localhost',
password=u'asdf',
emailAddress=u'fj@crappy.example.com')
self.assertEquals(signup.usernameAvailable(u'fjones', u'localhost'),
[False, u'Username already taken'])
ss = self.ls.accountByAddress(u"fjones", u"localhost").avatars.open()
self.assertEquals(ss.query(Installation).count(), 1)
def testUserInfoSignupValidation2(self):
"""
Ensure that invalid characters aren't allowed in usernames, that
usernames are parsable as the local part of an email address and that
usernames shorter than two characters are invalid.
"""
signup = self.createFreeSignup(free_signup.userInfo.itemClass)
self.assertEquals(signup.usernameAvailable(u'foo bar', u'localhost'),
[False, u"Username contains invalid character: ' '"])
self.assertEquals(signup.usernameAvailable(u'foo@bar', u'localhost'),
[False, u"Username contains invalid character: '@'"])
# '~' is not expressly forbidden by the validator in usernameAvailable,
# yet it is rejected by parseAddress (in xmantissa.smtp).
self.assertEquals(signup.usernameAvailable(u'fo~o', u'127.0.0.1'),
[False, u"Username fails to parse"])
self.assertEquals(signup.usernameAvailable(u'f', u'localhost'),
[False, u"Username too short"])
def test_userInfoLoginMethods(self):
"""
Check that C{createUser} creates only two L{LoginMethod}s on the
account.
"""
username, domain = u'fjones', u'divmod.com'
signup = self.createFreeSignup(free_signup.userInfo.itemClass)
signup.createUser(u'Frank', u'Jones', username, domain, u'asdf',
u'fj@example.com')
account = self.ls.accountByAddress(username, domain)
query = list(
self.store.query(userbase.LoginMethod,
userbase.LoginMethod.account == account,
sort=userbase.LoginMethod.internal.ascending))
self.assertEquals(len(query), 2)
self.assertEquals(query[0].internal, False)
self.assertEquals(query[0].verified, False)
self.assertEquals(query[0].localpart, u'fj')
self.assertEquals(query[0].domain, u'example.com')
self.assertEquals(query[1].internal, True)
self.assertEquals(query[1].verified, True)
self.assertEquals(query[1].localpart, username)
self.assertEquals(query[1].domain, domain)
def test_freeSignupsList(self):
"""
Test that if we produce 3 different publicly accessible signups, we get
information about all of them back.
"""
for i, signupMechanismPlugin in enumerate(
[free_signup.freeTicket,
free_signup.userInfo]):
self.createFreeSignup(signupMechanismPlugin.itemClass,
url=u'signup%d' % (i+1,),
prompt=u"Sign Up %d" % (i+1,))
x = list(signup._getPublicSignupInfo(self.store))
x.sort()
self.assertEquals(x, [(u'Sign Up 1', u'/signup1'),
(u'Sign Up 2', u'/signup2')])
syntax highlighted by Code2HTML, v. 0.9.1