def test_notify_team_invitation_to_non_registered_user_does_not_send_notification(
            self):
        invitation = MagicMock()
        inviter_id = MagicMock()
        '''Mocked outputs'''
        inviter_user = PublicUser(user_id=0,
                                  username="******",
                                  first_name="Test0",
                                  last_name="Test0")
        team = Team(team_id=0, name="Test-Team")

        def send_notification(topic_name, message_title, message_body,
                              data_message):
            from tests.test_services import test_notifications
            MockedNotificationServer.notification = Notification(
                topic_name, message_title, message_body, data_message)

        sys.modules[
            "daos.users"].UserDatabaseClient.get_user_by_id.return_value = inviter_user
        sys.modules[
            "daos.users"].UserDatabaseClient.get_user_by_email.return_value = None
        sys.modules[
            "daos.teams"].TeamDatabaseClient.get_team_by_id.return_value = team
        sys.modules["pyfcm"].FCMNotification(
        ).notify_topic_subscribers = MagicMock(side_effect=send_notification)

        NotificationService.notify_team_invitation(invitation, inviter_id)
        self.assertIsNone(MockedNotificationServer.notification)
    def test_notify_mention_to_bot_does_not_send_notification(self):
        message = Message(sender_id=0,
                          receiver_id=1,
                          team_id=0,
                          content="Sarasa",
                          send_type=SendMessageType.DIRECT.value,
                          message_type=MessageType.TEXT.value)
        mentioned_id = 1
        '''Mocked outputs'''
        bot_mentioned = Bot(bot_id=0,
                            name="Test-Bot",
                            callback=None,
                            token=None)

        def send_notification(topic_name, message_title, message_body,
                              data_message):
            from tests.test_services import test_notifications
            MockedNotificationServer.notification = Notification(
                topic_name, message_title, message_body, data_message)
            return {"failure": 0}

        sys.modules[
            "daos.bots"].BotDatabaseClient.get_bot_by_id.return_value = bot_mentioned
        sys.modules["pyfcm"].FCMNotification(
        ).notify_topic_subscribers = MagicMock(side_effect=send_notification)

        NotificationService.notify_mention(message, mentioned_id)
        self.assertIsNone(MockedNotificationServer.notification)
Пример #3
0
    def save_mentions(cls, message, mentions):
        cls.logger().debug(
            f"Saving mentions from message #{message.message_id}.")

        try:
            for mention in mentions:
                if message.send_type == SendMessageType.CHANNEL.value:
                    BotService.process_mention(mention, message)
                    new_mention = Mention(message_id=message.message_id,
                                          client_id=mention)
                    MessageDatabaseClient.add_mention(new_mention)
                    cls.logger().debug(f"Mention saved for client {mention}.")
                    NotificationService.notify_mention(message, mention)

                elif BotDatabaseClient.get_bot_by_id(mention) is None:
                    new_mention = Mention(message_id=message.message_id,
                                          client_id=mention)
                    MessageDatabaseClient.add_mention(new_mention)
                    cls.logger().debug(f"Mention saved for user {mention}.")
                    NotificationService.notify_mention(message, mention)

            DatabaseClient.commit()
            cls.logger().info(
                f"{len(mentions)} mentions saved for message #{message.message_id}."
            )
        except IntegrityError:
            DatabaseClient.rollback()
            cls.logger().error(
                f"Couldn't save mentions for message #{message.message_id}.")
    def test_notify_channel_message_from_user_sends_notification(self):
        message = Message(sender_id=0,
                          receiver_id=1,
                          team_id=0,
                          content="Sarasa",
                          send_type=SendMessageType.DIRECT.value,
                          message_type=MessageType.TEXT.value)
        is_user_receiver = False
        '''Mocked outputs'''
        user_sender = PublicUser(user_id=0,
                                 username="******",
                                 first_name="Test0",
                                 last_name="Test0")
        channel = Channel(channel_id=0,
                          team_id=0,
                          name="Test-Channel",
                          creator=ChannelCreator(0, "Tester0", "Test0",
                                                 "Test0"))
        team = Team(team_id=0, name="Test-Team")

        def send_notification(topic_name, message_title, message_body,
                              data_message):
            from tests.test_services import test_notifications
            MockedNotificationServer.notification = Notification(
                topic_name, message_title, message_body, data_message)
            return {"failure": 0}

        sys.modules[
            "daos.teams"].TeamDatabaseClient.get_team_by_id.return_value = team
        sys.modules[
            "daos.users"].UserDatabaseClient.get_user_by_id.return_value = user_sender
        sys.modules[
            "daos.channels"].ChannelDatabaseClient.get_channel_by_id.return_value = channel
        sys.modules["pyfcm"].FCMNotification(
        ).notify_topic_subscribers = MagicMock(side_effect=send_notification)

        NotificationService.notify_message(message, is_user_receiver)
        self.assertEqual(1, MockedNotificationServer.notification.topic_name)
        self.assertEqual("Hypechat",
                         MockedNotificationServer.notification.message_title)
        self.assertEqual("You receive a channel message!",
                         MockedNotificationServer.notification.message_body)
        self.assertEqual(
            "Test-Team",
            MockedNotificationServer.notification.data_message.get(
                "team_name"))
        self.assertEqual(
            "Test-Channel",
            MockedNotificationServer.notification.data_message.get(
                "channel_name"))
        self.assertEqual(
            0,
            MockedNotificationServer.notification.data_message.get(
                "sender_id"))
        self.assertEqual(
            NotificationType.MESSAGE.value,
            MockedNotificationServer.notification.data_message.get(
                "notification_type"))
    def test_notify_channel_invitation_sends_notification(self):
        user_channel = ChannelUser(user_id=1, channel_id=0)
        inviter_id = 0
        '''Mocked outputs'''
        inviter_user = PublicUser(user_id=0,
                                  username="******",
                                  first_name="Test0",
                                  last_name="Test0")
        channel = Channel(channel_id=0,
                          team_id=0,
                          name="Test-Channel",
                          creator=ChannelCreator(0, "Tester0", "Test0",
                                                 "Test0"))
        team = Team(team_id=0, name="Test-Team")

        def send_notification(topic_name, message_title, message_body,
                              data_message):
            from tests.test_services import test_notifications
            MockedNotificationServer.notification = Notification(
                topic_name, message_title, message_body, data_message)
            return {"failure": 0}

        sys.modules[
            "daos.users"].UserDatabaseClient.get_user_by_id.return_value = inviter_user
        sys.modules[
            "daos.teams"].TeamDatabaseClient.get_team_by_id.return_value = team
        sys.modules[
            "daos.channels"].ChannelDatabaseClient.get_channel_by_id.return_value = channel
        sys.modules["pyfcm"].FCMNotification(
        ).notify_topic_subscribers = MagicMock(side_effect=send_notification)

        NotificationService.notify_channel_invitation(user_channel, inviter_id)
        self.assertEqual(1, MockedNotificationServer.notification.topic_name)
        self.assertEqual("Hypechat",
                         MockedNotificationServer.notification.message_title)
        self.assertEqual(
            "You have been added to channel Test-Channel in team Test-Team!",
            MockedNotificationServer.notification.message_body)
        self.assertEqual(
            "Test-Team",
            MockedNotificationServer.notification.data_message.get(
                "team_name"))
        self.assertEqual(
            "Test-Channel",
            MockedNotificationServer.notification.data_message.get(
                "channel_name"))
        self.assertEqual(
            0,
            MockedNotificationServer.notification.data_message.get(
                "inviter_id"))
        self.assertEqual(
            NotificationType.CHANNEL_INVITATION.value,
            MockedNotificationServer.notification.data_message.get(
                "notification_type"))
Пример #6
0
    def send_message(cls, inbox_data):
        user = Authenticator.authenticate_team(inbox_data.authentication)

        if user.id == inbox_data.chat_id:
            raise WrongActionError("You cannot send a message to yourself!", MessageResponseStatus.ERROR.value)

        receiver = cls._determinate_message_receiver(inbox_data.chat_id, user.team_id)
        if receiver is None or receiver.team_id != user.team_id:
            cls.logger().info(f"Trying to send a message to client #{inbox_data.chat_id} who's not part of team "
                              f"{user.team_id}.")
            return BadRequestMessageSentResponse("The receiver it's not part of this team!",
                                                 TeamResponseStatus.USER_NOT_MEMBER.value)

        new_message = Message(
            sender_id=user.id,
            receiver_id=inbox_data.chat_id,
            team_id=user.team_id,
            content=inbox_data.content,
            send_type=SendMessageType.DIRECT.value if receiver.is_user else SendMessageType.CHANNEL.value,
            message_type=inbox_data.message_type
        )

        chat_sender, chat_receivers = cls._increase_chats_offset(user.id, inbox_data.chat_id, user.team_id, receiver.is_user)

        try:
            new_message = MessageDatabaseClient.add_message(new_message)
            if inbox_data.mentions is not None:
                MentionService.save_mentions(new_message, inbox_data.mentions)
            MessageDatabaseClient.add_or_update_chat(chat_sender)
            for chat_receiver in chat_receivers:
                MessageDatabaseClient.add_or_update_chat(chat_receiver)
            DatabaseClient.commit()
            NotificationService.notify_message(new_message, receiver.is_user)
            cls.logger().info(f"Message sent from user #{new_message.sender_id} to client #{new_message.receiver_id}.")
        except IntegrityError:
            DatabaseClient.rollback()
            if UserDatabaseClient.get_client_by_id(inbox_data.chat_id) is None:
                cls.logger().error(f"User #{new_message.sender_id} trying to sent a message to an nonexistent user.")
                raise UserNotFoundError("User not found.", UserResponseStatus.USER_NOT_FOUND.value)
            else:
                cls.logger().error(f"Failing to send message from user #{new_message.sender_id} to client"
                                   f" #{inbox_data.chat_id}.")
                return UnsuccessfulMessageSentResponse("Couldn't sent message.")
        except FlushError:
            cls.logger().error(
                f"Failing to send message from user #{new_message.sender_id} to client #{inbox_data.chat_id} "
                f"due to DB problems.")
            return UnsuccessfulMessageSentResponse("Couldn't sent message.")
        else:
            return SuccessfulMessageSentResponse("Message sent")
    def test_notify_team_invitation_to_registered_user_does_send_notification(
            self):
        invitation = MagicMock()
        inviter_id = MagicMock()
        '''Mocked outputs'''
        inviter_user = PublicUser(user_id=0,
                                  username="******",
                                  first_name="Test0",
                                  last_name="Test0")
        invited_user = PublicUser(user_id=1,
                                  username="******",
                                  first_name="Test1",
                                  last_name="Test1")
        team = Team(team_id=0, name="Test-Team")

        def send_notification(topic_name, message_title, message_body,
                              data_message):
            from tests.test_services import test_notifications
            MockedNotificationServer.notification = Notification(
                topic_name, message_title, message_body, data_message)
            return {"failure": 0}

        sys.modules[
            "daos.users"].UserDatabaseClient.get_user_by_id.return_value = inviter_user
        sys.modules[
            "daos.users"].UserDatabaseClient.get_user_by_email.return_value = invited_user
        sys.modules[
            "daos.teams"].TeamDatabaseClient.get_team_by_id.return_value = team
        sys.modules["pyfcm"].FCMNotification(
        ).notify_topic_subscribers = MagicMock(side_effect=send_notification)

        NotificationService.notify_team_invitation(invitation, inviter_id)
        self.assertEqual(1, MockedNotificationServer.notification.topic_name)
        self.assertEqual("Hypechat",
                         MockedNotificationServer.notification.message_title)
        self.assertEqual("You have been invited to join a team!",
                         MockedNotificationServer.notification.message_body)
        self.assertEqual(
            "Test-Team",
            MockedNotificationServer.notification.data_message.get(
                "team_name"))
        self.assertEqual(
            0,
            MockedNotificationServer.notification.data_message.get(
                "inviter_id"))
        self.assertEqual(
            NotificationType.TEAM_INVITATION.value,
            MockedNotificationServer.notification.data_message.get(
                "notification_type"))
    def test_notify_direct_message_from_bot_sends_notification(self):
        message = Message(sender_id=0,
                          receiver_id=1,
                          team_id=0,
                          content="Sarasa",
                          send_type=SendMessageType.DIRECT.value,
                          message_type=MessageType.TEXT.value)
        is_user_receiver = True
        '''Mocked outputs'''
        bot_sender = Bot(bot_id=0, name="Test-Bot", callback=None, token=None)
        team = Team(team_id=0, name="Test-Team")

        def send_notification(topic_name, message_title, message_body,
                              data_message):
            from tests.test_services import test_notifications
            MockedNotificationServer.notification = Notification(
                topic_name, message_title, message_body, data_message)
            return {"failure": 0}

        sys.modules[
            "daos.teams"].TeamDatabaseClient.get_team_by_id.return_value = team
        sys.modules[
            "daos.users"].UserDatabaseClient.get_user_by_id.return_value = None
        sys.modules[
            "daos.bots"].BotDatabaseClient.get_bot_by_id.return_value = bot_sender
        sys.modules[
            "daos.channels"].ChannelDatabaseClient.get_channel_by_id.return_value = None
        sys.modules["pyfcm"].FCMNotification(
        ).notify_topic_subscribers = MagicMock(side_effect=send_notification)

        NotificationService.notify_message(message, is_user_receiver)
        self.assertEqual(1, MockedNotificationServer.notification.topic_name)
        self.assertEqual("Hypechat",
                         MockedNotificationServer.notification.message_title)
        self.assertEqual("You receive a direct message!",
                         MockedNotificationServer.notification.message_body)
        self.assertEqual(
            "Test-Team",
            MockedNotificationServer.notification.data_message.get(
                "team_name"))
        self.assertEqual(
            0,
            MockedNotificationServer.notification.data_message.get(
                "sender_id"))
        self.assertEqual(
            NotificationType.MESSAGE.value,
            MockedNotificationServer.notification.data_message.get(
                "notification_type"))
    def test_notify_team_role_change_sends_notification(self):
        user_team = TeamUser(user_id=1,
                             team_id=0,
                             role=TeamRoles.MODERATOR.value)
        admin_id = 0
        '''Mocked outputs'''
        admin = PublicUser(user_id=0,
                           username="******",
                           first_name="Test0",
                           last_name="Test0")
        old_role = TeamRoles.MEMBER.value
        team = Team(team_id=0, name="Test-Team")

        def send_notification(topic_name, message_title, message_body,
                              data_message):
            from tests.test_services import test_notifications
            MockedNotificationServer.notification = Notification(
                topic_name, message_title, message_body, data_message)
            return {"failure": 0}

        sys.modules[
            "daos.users"].UserDatabaseClient.get_user_by_id.return_value = admin
        sys.modules[
            "daos.teams"].TeamDatabaseClient.get_team_by_id.return_value = team
        sys.modules["pyfcm"].FCMNotification(
        ).notify_topic_subscribers = MagicMock(side_effect=send_notification)

        NotificationService.notify_change_role(user_team, old_role, admin_id)
        self.assertEqual(1, MockedNotificationServer.notification.topic_name)
        self.assertEqual("Hypechat",
                         MockedNotificationServer.notification.message_title)
        self.assertEqual("You have been upgraded in team Test-Team!",
                         MockedNotificationServer.notification.message_body)
        self.assertEqual(
            "Test-Team",
            MockedNotificationServer.notification.data_message.get(
                "team_name"))
        self.assertEqual(
            0,
            MockedNotificationServer.notification.data_message.get("admin_id"))
        self.assertEqual(
            NotificationType.TEAM_ROLE_CHANGE.value,
            MockedNotificationServer.notification.data_message.get(
                "notification_type"))
Пример #10
0
    def change_role(cls, change_role_data):
        team_admin = Authenticator.authenticate_team(
            change_role_data.authentication, TeamRoles.is_team_creator)

        if change_role_data.new_role == TeamRoles.CREATOR.value:
            cls.logger().warning(
                f"Trying to set user as team #{team_admin.team_id} {TeamRoles.CREATOR.value}"
            )
            return BadRequestTeamMessageResponse(
                "You cannot set someone as team CREATOR.",
                TeamResponseStatus.ROLE_UNAVAILABLE.value)

        user_team = TeamDatabaseClient.get_user_in_team_by_ids(
            change_role_data.user_id, team_admin.team_id)
        if user_team is None:
            cls.logger().info(
                f"Trying to modify role from user #{change_role_data.user_id}, who's not part of team #{team_admin.team_id}"
            )
            return BadRequestTeamMessageResponse(
                "The given user is not part this team.",
                TeamResponseStatus.USER_NOT_MEMBER.value)

        old_role = user_team.role
        user_team.role = change_role_data.new_role

        try:
            TeamDatabaseClient.update_team_user(user_team)
            DatabaseClient.commit()
            NotificationService.notify_change_role(user_team, old_role,
                                                   team_admin.id)
            cls.logger().info(
                f"User #{user_team.user_id} set as team #{team_admin.team_id} {user_team.role} by user "
                f"#{team_admin.id}.")
        except IntegrityError:
            DatabaseClient.rollback()
            cls.logger().error(
                f"Failing to modifying role of #{user_team.user_id} in team #{user_team.team_id}."
            )
            return UnsuccessfulTeamMessageResponse(
                "Couldn't modify user role.")
        else:
            return SuccessfulTeamMessageResponse(
                "Role modified", TeamResponseStatus.ROLE_MODIFIED.value)
Пример #11
0
    def add_member(cls, invitation_data):
        user = Authenticator.authenticate_channel(invitation_data.authentication, TeamRoles.is_channel_creator)

        invited_user = UserDatabaseClient.get_user_by_id(invitation_data.user_invited_id)
        if invited_user is None:
            cls.logger().info(f"Trying to add user an nonexistent user to channel #{user.channel_id}.")
            return BadRequestChannelMessageResponse("Invited user not found!", UserResponseStatus.USER_NOT_FOUND.value)

        invited_user_in_team = TeamDatabaseClient.get_user_in_team_by_ids(invited_user.id, user.team_id)
        if invited_user_in_team is None:
            cls.logger().info(f"Trying to add user {invited_user.id} to channel #{user.channel_id}, but it's not part "
                              f"of the team #{user.team_id}.")
            return BadRequestChannelMessageResponse("User not part of the team!",
                                                    TeamResponseStatus.USER_NOT_MEMBER.value)

        try:
            new_channel_user = ChannelUser(user_id=invited_user.id, channel_id=user.channel_id)
            ChannelDatabaseClient.add_channel_user(new_channel_user)
            new_chat = Chat(user_id=invited_user.id, chat_id=user.channel_id, team_id=user.team_id)
            MessageDatabaseClient.add_chat(new_chat)
            DatabaseClient.commit()
            NotificationService.notify_channel_invitation(new_channel_user, user.id)
            cls.logger().info(f"User #{invited_user.id} added to channel #{user.channel_id} by {user.username}.")

        except IntegrityError:
            DatabaseClient.rollback()
            already_member = ChannelDatabaseClient.get_user_in_channel_by_ids(invited_user.id, user.channel_id)

            if already_member is not None:
                cls.logger().info(f"Failing to add user #{invited_user.id} to channel #{user.channel_id}. "
                                  f"The user is already part of it.")
                return BadRequestChannelMessageResponse(f"User already registered in channel.",
                                                        TeamResponseStatus.ALREADY_REGISTERED.value)
            else:
                cls.logger().error(f"Failing to add user #{invitation_data.user_invited_id} to channel"
                                   f"{invitation_data.authentication.channel_id}.")
                return UnsuccessfulChannelMessageResponse("Couldn't add user to channel.")
        else:
            return SuccessfulChannelMessageResponse("User added!", ChannelResponseStatus.ADDED.value)
    def test_when_connection_error_is_raised_by_pyfcm_notification_is_not_send(
            self):
        def send_notification(topic_name, message_title, message_body,
                              data_message):
            raise ConnectionError

        sys.modules["pyfcm"].FCMNotification(
        ).notify_topic_subscribers = MagicMock(side_effect=send_notification)

        NotificationService.notify_team_invitation(mock, mock)
        self.assertIsNone(MockedNotificationServer.notification)
        NotificationService.notify_channel_invitation(mock, mock)
        self.assertIsNone(MockedNotificationServer.notification)
        NotificationService.notify_message(mock, mock)
        self.assertIsNone(MockedNotificationServer.notification)
        NotificationService.notify_mention(mock, mock)
        self.assertIsNone(MockedNotificationServer.notification)
Пример #13
0
    def invite_user(cls, invite_data):
        team_mod = Authenticator.authenticate_team(invite_data.authentication,
                                                   TeamRoles.is_team_moderator)

        invited_user = UserDatabaseClient.get_user_by_email(invite_data.email)
        if invited_user is not None and invited_user.role == UserRoles.ADMIN.value:
            cls.logger().info(
                f"Mod #{team_mod.id} tried to invite admin #{invited_user.id} to team #{team_mod.team_id}."
            )
            return BadRequestTeamMessageResponse(
                "You cannot invite an admin to a team!",
                TeamResponseStatus.ROLE_UNAVAILABLE.value)

        already_member = TeamDatabaseClient.get_user_in_team_by_email(
            invite_data.email, team_mod.team_id)
        if already_member is not None:
            cls.logger().info(
                f"Mod #{team_mod.id} tried to invite user #{already_member.user_id} to team "
                f"#{team_mod.team_id}, but it already belongs to that team.")
            return BadRequestTeamMessageResponse(
                "This user already belongs to the team.",
                TeamResponseStatus.ALREADY_REGISTERED.value)

        if TeamDatabaseClient.get_team_invite(team_mod.team_id,
                                              invite_data.email) is not None:
            cls.logger().info(
                f"Mod #{team_mod.id} tried to invite an user already invited to team #{team_mod.team_id}"
            )
            return BadRequestTeamMessageResponse(
                "This user was already invited to join the team.",
                TeamResponseStatus.ALREADY_INVITED.value)

        invite_token = Authenticator.generate_team_invitation()
        new_invite = TeamInvite(team_id=team_mod.team_id,
                                email=invite_data.email,
                                token=invite_token)

        try:
            TeamDatabaseClient.add_invite(new_invite)
            team = TeamDatabaseClient.get_team_by_id(team_mod.team_id)
            DatabaseClient.commit()
            cls.logger().info(
                f"New invitation for {new_invite.email} to join team #{team_mod.team_id}, by user #"
                f"{team_mod.id}.")

            email_data = TeamInvitationEmailDTO(
                email=invite_data.email,
                team_name=team.name,
                inviter_name=team_mod.username,
                token=invite_token,
                message_template=EmailService.team_invitation_message)
            EmailService.send_email(email_data)
            NotificationService.notify_team_invitation(new_invite, team_mod.id)
            cls.logger().info(
                f"Team #{team_mod.team_id} invitation email sent to {new_invite.email}."
            )

        except IntegrityError:
            DatabaseClient.rollback()
            cls.logger().error(
                f"Couldn't invite user {new_invite.email} to team #{team_mod.team_id}."
            )
            return UnsuccessfulTeamMessageResponse(
                "Couldn't invite user to team.")
        else:
            return SuccessfulTeamMessageResponse(
                "User invited.", TeamResponseStatus.INVITED.value)