witten
/
luminotes
Archived
1
0
Fork 0

Made send_invites() update any similar invites that have already been sent.

This commit is contained in:
Dan Helfman 2007-12-06 22:05:00 +00:00
parent 10cee7291a
commit a615f65d29
5 changed files with 100 additions and 4 deletions

3
NEWS
View File

@ -1,7 +1,8 @@
1.0.4: November ??, 2007
1.0.4: December ??, 2007
* When the web browser is resized, all notes are automatically resized as well.
* Fixed note focusing in Safari.
* Fixed note state detection (bold, italic, etc.) in Safari.
* Improved input validation.
1.0.3: November 28, 2007
* Updated logo, which is now an image and could be theoretically replaced for

View File

@ -717,7 +717,14 @@ class Users( object ):
# record the sending of this invite email
invite_id = self.__database.next_id( Invite, commit = False )
invite = Invite.create( invite_id, user_id, notebook_id, email_address, read_write, owner )
self.__database.save( invite )
self.__database.save( invite, commit = False )
# update any unredeemed invitations for this notebook already sent to the same email address
similar_invites = self.__database.select_many( Invite, invite.sql_load_similar() )
for similar in similar_invites:
similar.read_write = read_write
similar.owner = owner
self.__database.save( similar, commit = False )
# create an email message with a unique invitation link
notebook_name = notebook.name.strip().replace( "\n", " " ).replace( "\r", " " )
@ -739,6 +746,8 @@ class Users( object ):
server.sendmail( message[ u"from" ], [ email_address ], message.as_string() )
server.quit()
self.__database.commit()
if email_count == 1:
return dict( message = u"An invitation has been sent." )
else:

View File

@ -12,6 +12,7 @@ class Test_controller( object ):
from model.User import User
from model.Notebook import Notebook
from model.Note import Note
from model.Invite import Invite
# Since Stub_database isn't a real database and doesn't know SQL, replace some of the
# SQL-returning methods in User, Note, and Notebook to return functions that manipulate data in
@ -214,6 +215,21 @@ class Test_controller( object ):
Notebook.sql_count_notes = lambda self: \
lambda database: sql_count_notes( self, database )
def sql_load_similar( self, database ):
invites = []
for ( object_id, obj_list ) in database.objects.items():
obj = obj_list[ -1 ]
if isinstance( obj, Invite ) and obj.from_user_id == self.from_user_id and \
obj.notebook_id == self.notebook_id and obj.email_address == self.email_address and \
obj.redeemed_user_id is None and obj.object_id != self.object_id:
invites.append( obj )
return invites
Invite.sql_load_similar = lambda self: \
lambda database: sql_load_similar( self, database )
def setUp( self ):
from controller.Root import Root
cherrypy.lowercase_api = True

View File

@ -853,6 +853,60 @@ class Test_users( Test_controller ):
assert self.notebooks[ 0 ].name in message
assert self.INVITE_LINK_PATTERN.search( message )
def test_send_invites_similar( self ):
Stub_smtp.reset()
smtplib.SMTP = Stub_smtp
self.login()
self.user.rate_plan = 1
self.database.save( self.user )
email_addresses_list = [ u"foo@example.com" ]
email_addresses = email_addresses_list[ 0 ]
# first send an invite with read_write and owner set to False
self.http_post( "/users/send_invites", dict(
notebook_id = self.notebooks[ 0 ].object_id,
email_addresses = email_addresses,
read_write = False,
owner = False,
invite_button = u"send invites",
), session_id = self.session_id )
matches = self.INVITE_LINK_PATTERN.search( smtplib.SMTP.message )
invite_id1 = matches.group( 2 )
assert invite_id1
# then send a similar invite to the same email address with read_write and owner set to True
self.http_post( "/users/send_invites", dict(
notebook_id = self.notebooks[ 0 ].object_id,
email_addresses = email_addresses,
read_write = True,
owner = True,
invite_button = u"send invites",
), session_id = self.session_id )
matches = self.INVITE_LINK_PATTERN.search( smtplib.SMTP.message )
invite_id2 = matches.group( 2 )
assert invite_id2
# assert that both invites have the read_write / owner flags set to True now
invite1_list = self.database.objects.get( invite_id1 )
assert invite1_list
assert len( invite1_list ) >= 2
invite1 = invite1_list[ -1 ]
assert invite1
assert invite1.read_write is True
assert invite1.owner is True
invite2_list = self.database.objects.get( invite_id2 )
assert invite2_list
assert len( invite2_list ) >= 1
invite2 = invite2_list[ -1 ]
assert invite2
assert invite2.read_write is True
assert invite2.owner is True
def test_send_invites_with_generic_from_address( self ):
Stub_smtp.reset()
smtplib.SMTP = Stub_smtp

View File

@ -90,6 +90,22 @@ class Invite( Persistent ):
quote( self.__email_address ), quote( self.__read_write and "t" or "f" ), quote( self.__owner and "t" or "f" ),
quote( self.__redeemed_user_id ) )
def sql_load_similar( self ):
# select unredeemed invitations with the same from_user_id, notebook_id, and email_address as this invitation
return "select id, revision, from_user_id, notebook_id, email_address, read_write, owner, redeemed_user_id from invite " + \
"where from_user_id = %s and notebook_id = %s and email_address = %s and id != %s and redeemed_user_id is null;" % \
( quote( self.__from_user_id ), quote( self.__notebook_id ), quote( self.__email_address ), quote( self.object_id ) )
def __set_read_write( self, read_write ):
if read_write != self.__read_write:
self.update_revision()
self.__read_write = read_write
def __set_owner( self, owner ):
if owner != self.__owner:
self.update_revision()
self.__owner = owner
def __set_redeemed_user_id( self, redeemed_user_id ):
if redeemed_user_id != self.__redeemed_user_id:
self.update_revision()
@ -98,6 +114,6 @@ class Invite( Persistent ):
from_user_id = property( lambda self: self.__from_user_id )
notebook_id = property( lambda self: self.__notebook_id )
email_address = property( lambda self: self.__email_address )
read_write = property( lambda self: self.__read_write )
owner = property( lambda self: self.__owner )
read_write = property( lambda self: self.__read_write, __set_read_write )
owner = property( lambda self: self.__owner, __set_owner )
redeemed_user_id = property( lambda self: self.__redeemed_user_id, __set_redeemed_user_id )