YetiForceCompany/YetiForceCRM

View on GitHub
tests/Base/Z_Chat.php

Summary

Maintainability
A
3 hrs
Test Coverage
A
100%
<?php

/**
 * Chat test class.
 *
 * @package   Tests
 *
 * @copyright YetiForce S.A.
 * @license   YetiForce Public License 6.5 (licenses/LicenseEN.txt or yetiforce.com)
 * @author    Arkadiusz Adach <a.adach@yetiforce.com>
 */

namespace Tests\Base;

/**
 * Class Chat.
 */
class Z_Chat extends \Tests\Base
{
    /**
     * ID list.
     *
     * @var int[]
     */
    private static $listId;

    /**
     * Is chat active.
     *
     * @var bool
     */
    private static $chatActive = false;

    /**
     * Global room.
     *
     * @var bool|array
     */
    private static $globalRoom = false;

    /**
     * List of user IDs.
     *
     * @var int[]
     */
    private static $users = [];

    /**
     * Get key of chat room.
     *
     * @codeCoverageIgnore
     *
     * @param array  $userRooms
     * @param string $roomType
     * @param int    $recordId
     *
     * @return bool|int
     */
    private static function getKeyRoom($userRooms, string $roomType, int $recordId)
    {
        if (isset($userRooms[$roomType]) && \is_array($userRooms[$roomType])) {
            foreach ($userRooms[$roomType] as $key => $val) {
                if ($val['recordid'] === $recordId) {
                    return $key;
                }
            }
        }
        return false;
    }

    /**
     * Get key of message.
     *
     * @codeCoverageIgnore
     *
     * @param array $entries
     * @param int   $id
     *
     * @return int|false
     */
    private static function getKeyMessage($entries, int $id)
    {
        foreach ($entries as $key => $val) {
            if ($val['id'] === $id) {
                return $key;
            }
        }
        return false;
    }

    /**
     * Get user from participants.
     *
     * @codeCoverageIgnore
     *
     * @param array $participants
     * @param int   $userId
     *
     * @return bool|int|string
     */
    private static function getUserFromParticipants($participants, int $userId)
    {
        foreach ($participants as $key => $val) {
            if ($val['user_id'] === $userId) {
                return $key;
            }
        }
        return false;
    }

    /**
     * Setting of tests.
     */
    public static function setUpBeforeClass(): void
    {
        self::$chatActive = \App\Module::isModuleActive('Chat');
        \App\User::setCurrentUserId(\App\User::getActiveAdminId());
        $recordModel = C_RecordActions::createContactRecord(false);
        self::$listId[] = $recordModel->getId();
        self::$users[] = A_User::createUsersRecord('test_1')->getId();
        self::$users[] = A_User::createUsersRecord('test_2')->getId();
    }

    /**
     * Configuration testing.
     */
    public function testConfiguration()
    {
        $this->assertTrue(\App\Module::isModuleActive('Chat'), 'The chat module is inactive');
    }

    /**
     * Check if the general chat room exists.
     */
    public function testGeneralRoom()
    {
        self::$globalRoom = (new \App\Db\Query())->from('u_#__chat_global')->where(['name' => 'LBL_GENERAL'])->one();
        $this->assertNotFalse(self::$globalRoom, 'The general chat room not exists.');
        //$currentRoom = \App\Chat::getCurrentRoom();  ???
        //$this->assertSame($currentRoom['roomType'], 'global');  ???
        //$this->assertSame($currentRoom['recordId'], self::$globalRoom['global_room_id']);  ???
        // $chat = \App\Chat::getInstance();  ???
        //$this->assertSame($chat->getRoomType(), 'global');  ???
        //$this->assertSame($chat->getRecordId(), self::$globalRoom['global_room_id']);  ???
    }

    /**
     * Chat testing for groups.
     */
    public function testGroup()
    {
        \App\User::setCurrentUserId(\App\User::getActiveAdminId());
        $groups = \App\User::getCurrentUserModel()->getGroupNames();
        $this->assertGreaterThanOrEqual(1, \count($groups), 'No defined groups');
        $groupId = \key($groups);
        $chat = \App\Chat::getInstance('group', $groupId);
        $this->assertTrue($chat->isRoomExists(), "The chat room does not exist '{$groups[$groupId]}'");
        $this->assertFalse($chat->isAssigned(), "The user should not be assigned '{$groups[$groupId]}'");
        $cntEntries = \count($chat->getEntries());
        $id = $chat->addMessage('Test MSG');
        $this->assertIsInt($id);
        $rowMsg = (new \App\Db\Query())
            ->from(\App\Chat::TABLE_NAME['message'][$chat->getRoomType()])
            ->where(['id' => $id])->one();
        $this->assertNotFalse($rowMsg, "The message {$id} does not exist");
        $this->assertSame('Test MSG', $rowMsg['messages']);
        $this->assertSame(\App\User::getCurrentUserId(), $rowMsg['userid']);
        $entries = $chat->getEntries();
        $this->assertCount($cntEntries + 1, $entries, 'Too many messages in the chat room');
        $key = self::getKeyMessage($entries, $id);
        $this->assertNotFalse($key, 'Problem with the method "getEntries"');
        $this->assertSame($rowMsg['messages'], $entries[$key]['messages']);
        $this->assertSame(\App\User::getCurrentUserModel()->getName(), $entries[$key]['user_name']);
    }

    /**
     * Test assigning a user to a group room.
     *
     * @throws \App\Exceptions\IllegalValue
     */
    public function testAssigningToGroup()
    {
        \App\User::setCurrentUserId(\App\User::getActiveAdminId());
        $groups = \App\User::getCurrentUserModel()->getGroupNames();
        $groupId = \key($groups);
        $chat = \App\Chat::getInstance('group', $groupId);
        $this->assertTrue($chat->isRoomExists(), "The chat room does not exist '{$groups[$groupId]}'");
        $this->assertFalse($chat->isAssigned(), "The user should not be assigned '{$groups[$groupId]}'");
        $chat->addToFavorites();
        $this->assertTrue($chat->isRoomExists(), "The chat room does not exist '{$groups[$groupId]}'");
        $this->assertTrue($chat->isAssigned(), "The user should be assigned '{$groups[$groupId]}'");
        $row = (new \App\Db\Query())
            ->from(\App\Chat::TABLE_NAME['room'][$chat->getRoomType()])
            ->where(['userid' => \App\User::getCurrentUserId()])
            ->andWhere([\App\Chat::COLUMN_NAME['room'][$chat->getRoomType()] => $groupId])
            ->one();
        $this->assertNotFalse($row, 'Problem with methods "addToFavorites"');
        $this->assertIsInt($row['last_message'], 'Problem with methods "addToFavorites"');
    }

    /**
     * Remove test from favorites.
     *
     * @throws \App\Exceptions\IllegalValue
     * @throws \yii\db\Exception
     */
    public function testRemoveFromFavorites()
    {
        $groups = \App\User::getCurrentUserModel()->getGroupNames();
        $groupId = \key($groups);
        $chat = \App\Chat::getInstance('group', $groupId);
        $this->assertTrue($chat->isRoomExists(), "The chat room does not exist '{$groups[$groupId]}'");
        $this->assertTrue($chat->isAssigned(), "The user should be assigned '{$groups[$groupId]}'");
        $chat->removeFromFavorites();
        $this->assertTrue($chat->isRoomExists(), "The chat room does not exist '{$groups[$groupId]}'");
        $this->assertFalse($chat->isAssigned(), "The user should not be assigned '{$groups[$groupId]}'");
        $this->assertFalse((new \App\Db\Query())
            ->from(\App\Chat::TABLE_NAME['room'][$chat->getRoomType()])
            ->where(['userid' => \App\User::getCurrentUserId()])
            ->andWhere([\App\Chat::COLUMN_NAME['room'][$chat->getRoomType()] => $groupId])
            ->exists(),
            'Problem with methods "removeFromFavorites"'
        );
    }

    /**
     * Testing the method of the current chat room.
     */
    public function testCurrentRoom()
    {
        unset($_SESSION);
        \App\Chat::setCurrentRoom('global', self::$globalRoom['global_room_id']);
        $this->assertSame($_SESSION['chat']['roomType'], 'global');
        $this->assertSame($_SESSION['chat']['recordId'], self::$globalRoom['global_room_id']);
    }

    /**
     * Testing adding messages.
     */
    public function testAddNewMessage()
    {
        $chat = \App\Chat::getInstance();
        $id = $chat->addMessage('test');
        $this->assertIsInt($id);
        $rowMsg = (new \App\Db\Query())
            ->from(\App\Chat::TABLE_NAME['message'][$chat->getRoomType()])
            ->where(['id' => $id])->one();
        $this->assertNotFalse($rowMsg, "The message {$id} does not exist");
        $this->assertSame('test', $rowMsg['messages']);
        $this->assertSame(\App\User::getCurrentUserId(), $rowMsg['userid']);
        $entries = $chat->getEntries();
        $key = self::getKeyMessage($entries, $id);
        $this->assertNotFalse($key, 'Problem with the method "getEntries"');
        $this->assertSame($rowMsg['messages'], $entries[$key]['messages']);
        $this->assertSame(\App\User::getCurrentUserModel()->getName(), $entries[$key]['user_name']);
    }

    /**
     * Testing the method for checking new messages.
     */
    public function testNewMessage()
    {
        $chat = \App\Chat::getInstance();
        $this->assertFalse(\App\Chat::isNewMessages(), 'Problem with the method "isNewMessages"');
        $chat->addMessage('test 2');
        $this->assertTrue(\App\Chat::isNewMessages(), 'Problem with the method "isNewMessages"');
        //Switch user
        \App\User::setCurrentUserId(self::$users[0]);
        $chat = \App\Chat::getInstance();
        $this->assertTrue(\App\Chat::isNewMessages(), 'Problem with the method "isNewMessages"');
        $chat->getEntries();
        $this->assertFalse(\App\Chat::isNewMessages(), 'Problem with the method "isNewMessages"');
        //Switch user
        \App\User::setCurrentUserId(self::$users[1]);
        $chat = \App\Chat::getInstance();
        $this->assertTrue(\App\Chat::isNewMessages(), 'Problem with the method "isNewMessages"');
        $chat->getEntries();
        $this->assertFalse(\App\Chat::isNewMessages(), 'Problem with the method "isNewMessages"');
    }

    /**
     * Testing creating a chat room.
     */
    public function testCreatingChatRoomCrm()
    {
        $recordModel = \Vtiger_Record_Model::getInstanceById(self::$listId[0]);
        $chat = \App\Chat::createRoom('crm', $recordModel->getId());
        $rowRoom = (new \App\Db\Query())
            ->from(\App\Chat::TABLE_NAME['room']['crm'])
            ->where([\App\Chat::COLUMN_NAME['room']['crm'] => $recordModel->getId()])->one();
        $this->assertNotFalse($rowRoom, "The chat room {$recordModel->getId()} does not exist");
        $this->assertSame($recordModel->getId(), $rowRoom[\App\Chat::COLUMN_NAME['room']['crm']]);
        $this->assertSame($recordModel->getId(), $chat->getRecordId());
        $rooms = \App\Chat::getRoomsByUser();
        $key = self::getKeyRoom($rooms, 'crm', (int) $recordModel->getId());
        $this->assertNotFalse($key, 'Problem with the method "getRoomsByUser". Crm id=' . $recordModel->getId());
        $this->assertSame($recordModel->getModuleName(), $rooms['crm'][$key]['moduleName']);
        $this->assertSame($recordModel->getId(), $rooms['crm'][$key]['recordid']);
    }

    /**
     * Testing adding messages to Crm chat room.
     */
    public function testAddMessageCrm()
    {
        $recordModel = \Vtiger_Record_Model::getInstanceById(self::$listId[0]);
        $chat = \App\Chat::getInstance('crm', $recordModel->getId());
        $id = $chat->addMessage('test2');
        $this->assertIsInt($id);
        $rowMsg = (new \App\Db\Query())
            ->from(\App\Chat::TABLE_NAME['message'][$chat->getRoomType()])
            ->where(['id' => $id])->one();
        $this->assertNotFalse($rowMsg, "The message {$id} does not exist");
        $this->assertSame('test2', $rowMsg['messages']);
        $this->assertSame(\App\User::getCurrentUserId(), $rowMsg['userid']);
        $entries = $chat->getEntries();
        $key = self::getKeyMessage($entries, $id);
        $this->assertNotFalse($key, 'Problem with the method "getEntries"');
        $this->assertSame($rowMsg['messages'], $entries[$key]['messages']);
        $this->assertSame(\App\User::getCurrentUserModel()->getName(), $entries[$key]['user_name']);
    }

    /**
     * Testing a CRM chat room.
     */
    public function testRoomCrm()
    {
        $userId = \App\User::getActiveAdminId();
        \App\User::setCurrentUserId($userId);
        $this->assertFalse(\App\Chat::isNewMessagesForCrm($userId), 'Problem with the method "isNewMessagesForCrm"');
        $chat = \App\Chat::getInstance('crm', self::$listId[0]);
        $chat->addToFavorites();
        $this->assertFalse(\App\Chat::isNewMessagesForCrm($userId), 'Problem with the method "isNewMessagesForCrm"');
        $id = $chat->addMessage('testRoomCrm');
        $this->assertIsInt($id);
        $rowMsg = (new \App\Db\Query())
            ->from(\App\Chat::TABLE_NAME['message'][$chat->getRoomType()])
            ->where(['id' => $id])->one();
        $this->assertNotFalse($rowMsg, "The message {$id} does not exist");
        $this->assertSame('testRoomCrm', $rowMsg['messages']);
        $this->assertSame(\App\User::getCurrentUserId(), $rowMsg['userid']);
    }

    /**
     * Chat room switching test.
     *
     * @throws \App\Exceptions\IllegalValue
     */
    public function testSwitchRoom()
    {
        \App\Chat::setCurrentRoom('crm', self::$listId[0]);
        $this->assertSame($_SESSION['chat']['roomType'], 'crm');
        $this->assertSame($_SESSION['chat']['recordId'], self::$listId[0]);
        $currentRoom = \App\Chat::getCurrentRoom();
        $this->assertSame($currentRoom['roomType'], 'crm');
        $this->assertSame($currentRoom['recordId'], self::$listId[0]);
    }

    /**
     * Message history test.
     *
     * @throws \App\Exceptions\IllegalValue
     */
    public function testHistory()
    {
        $userId = \App\User::getCurrentUserId();
        $userName = \App\User::getCurrentUserModel()->getName();
        $chat = \App\Chat::getInstance('global', self::$globalRoom['global_room_id']);
        $globalHistory = $chat->getHistoryByType('global');
        $this->assertIsArray($globalHistory);
        foreach ($globalHistory as $message) {
            $this->assertSame($userId, $message['userid']);
            $this->assertSame($userName, $message['user_name']);
            $this->assertNotNull($message['messages']);
        }
        $globalCrm = $chat->getHistoryByType('crm');
        $this->assertIsArray($globalCrm);
        foreach ($globalCrm as $message) {
            $this->assertSame($userId, $message['userid']);
            $this->assertSame($userName, $message['user_name']);
            $this->assertNotNull($message['messages']);
        }
        $globalGroup = $chat->getHistoryByType('group');
        $this->assertIsArray($globalGroup);
        foreach ($globalGroup as $message) {
            $this->assertSame($userId, $message['userid']);
            $this->assertSame($userName, $message['user_name']);
            $this->assertNotNull($message['messages']);
        }
    }

    /**
     * Testing the removal of Crm chat room.
     *
     * @throws \Exception
     */
    public function testRemoveRecordCrm(): void
    {
        $recordModel = \Vtiger_Record_Model::getInstanceById(self::$listId[0]);
        $recordId = $recordModel->getId();
        $recordModel->delete();
        $this->assertFalse(
            (new \App\Db\Query())
                ->from(\App\Chat::TABLE_NAME['room']['crm'])
                ->where([\App\Chat::COLUMN_NAME['room']['crm'] => $recordId])->exists(),
            "The chat room {$recordId} does exist"
        );
        $this->assertFalse(
            (new \App\Db\Query())
                ->from(\App\Chat::TABLE_NAME['message']['crm'])
                ->where([\App\Chat::COLUMN_NAME['message']['crm'] => $recordId])->exists(),
            "Messages {$recordId} exist"
        );
    }

    /**
     * Test the current chat room after deleting the record.
     */
    public function testCurrentRoomAfterDeletingRecord(): void
    {
        $this->assertSame($_SESSION['chat']['roomType'], 'crm');
        $this->assertSame($_SESSION['chat']['recordId'], self::$listId[0]);
        \vtlib\Functions::clearCacheMetaDataRecord(self::$listId[0]);
        $this->assertFalse(\App\Record::isExists(self::$listId[0]), 'The record should not exist');
        $currentRoom = \App\Chat::getCurrentRoom();
        //$this->assertSame($currentRoom['roomType'], 'global'); ???
        //$this->assertSame($currentRoom['recordId'], self::$globalRoom['global_room_id']); ???
    }

    /**
     * Cleaning after tests.
     *
     * @codeCoverageIgnore
     */
    public static function tearDownAfterClass(): void
    {
        unset(self::$listId[0]);
        \App\User::setCurrentUserId(\App\User::getActiveAdminId());
        if (!self::$chatActive) {
            (new \Settings_ModuleManager_Module_Model())->disableModule('Chat');
        }
        foreach (self::$listId as $id) {
            $recordModel = \Vtiger_Record_Model::getInstanceById($id);
            $recordModel->delete();
        }
    }
}