Commit aec978d0 authored by Marko Lalic's avatar Marko Lalic

Add leave-team email control command.

Users can now leave teams using the email interface. The command
requires a confirmation by the email being removed from the team.
parent 6142b7f9
......@@ -81,3 +81,59 @@ class JoinTeam(Command):
team, email_user = packed
team.add_members([email_user])
self.reply('You have successfully joined the team "{}"'.format(team))
@needs_confirmation
class LeaveTeam(Command):
"""
Command which lets users leave a team they are already a member of.
"""
META = {
'description': """leave-team <team-slug> [<email>]
Removes <email> from the team with the slug given by <team-slug>. If
<email> is not given, it uses the From address email.
If the user is not a member of the team, a warning is returned.""",
'name': 'leave-team',
}
REGEX_LIST = (
r'\s+(?P<team_slug>\S+)(?:\s+(?P<email>\S+))?$',
)
def __init__(self, team_slug, email):
super(LeaveTeam, self).__init__()
self.user_email = email
self.team_slug = team_slug
def get_team_and_user(self):
team = get_or_none(Team, slug=self.team_slug)
if not team:
self.error('Team with the slug "{}" does not exist.'.format(
self.team_slug))
return
email_user, _ = EmailUser.objects.get_or_create(email=self.user_email)
if email_user not in team.members.all():
self.warn("You are not a member of the team.")
return
return team, email_user
def pre_confirm(self):
packed = self.get_team_and_user()
if packed is None:
return False
self.reply('A confirmation mail has been sent to ' + self.user_email)
return True
def get_command_text(self):
return super(LeaveTeam, self).get_command_text(
self.team_slug, self.user_email)
def handle(self):
packed = self.get_team_and_user()
if packed is None:
return
team, email_user = packed
team.remove_members([email_user])
self.reply('You have successfully left the team "{}" (slug: {})'.format(
team, team.slug))
......@@ -2334,3 +2334,93 @@ class JoinTeamCommandsTests(TeamCommandsMixin, EmailControlTest):
self.control_process()
self.assert_warning_in_response(self.get_is_member_warning())
class LeaveTeamCommandTests(TeamCommandsMixin, EmailControlTest):
def setUp(self):
super(LeaveTeamCommandTests, self).setUp()
self.email_user = EmailUser.objects.create(email='other@domain.com')
self.team.add_members([self.email_user])
self.set_header('From', self.email_user.email)
def get_leave_command(self, team, email=''):
return 'leave-team {} {}'.format(team, email)
def get_left_team_message(self, team):
return 'You have successfully left the team "{}" (slug: {})'.format(
team,
team.slug)
def get_is_not_member_warning(self):
return 'You are not a member of the team.'
def get_no_exist_error(self, team):
return 'Team with the slug "{}" does not exist.'.format(team)
def test_leave_team(self):
"""
Tests the normal situation where the user leaves a team he is a
member of.
"""
self.set_input_lines([self.get_leave_command(self.team.slug)])
self.control_process()
# A confirmation sent to the user
self.assert_confirmation_sent_to(self.email_user.email)
# Which is displayed in the response to the original message
self.assert_in_response(self.get_confirmation_text(self.email_user.email))
# The user is still a member of the team
self.assertIn(self.email_user, self.team.members.all())
# A confirmation is created
self.assertEqual(1, CommandConfirmation.objects.count())
confirmation = CommandConfirmation.objects.all()[0]
# Now confirm the email
self.reset_outbox()
self.set_input_lines(['CONFIRM ' + confirmation.confirmation_key])
self.control_process()
# The user notified that he has left the team
self.assert_in_response(self.get_left_team_message(self.team))
# The user is no longer a member of the team
self.assertNotIn(self.email_user, self.team.members.all())
def test_leave_team_different_from(self):
"""
Tests that a confirmation message is sent to the user being removed
from the team, not the one that sent the control message.
"""
self.set_input_lines(
[self.get_leave_command(self.team.slug, self.email_user.email)])
self.set_header('From', 'some-other-user@domain.com')
self.control_process()
# Confirmation sent to the user being removed from the team
self.assert_confirmation_sent_to(self.email_user.email)
def test_leave_team_not_member(self):
"""
Tests that a warning is returned when the user tries to leave a team
that he is not a member of.
"""
self.team.remove_members([self.email_user])
self.set_input_lines([self.get_leave_command(self.team.slug)])
self.control_process()
self.assert_warning_in_response(self.get_is_not_member_warning())
def test_leave_team_does_not_exist(self):
"""
Tests that an error is returned when the user tries to leave a team
that does not even exist.
"""
team_slug = 'this-does-not-exist'
self.set_input_lines([self.get_leave_command(team_slug)])
self.control_process()
self.assert_error_in_response(self.get_no_exist_error(team_slug))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment