diff --git a/src/Models/Conversation.php b/src/Models/Conversation.php index e2774db..f198e0f 100644 --- a/src/Models/Conversation.php +++ b/src/Models/Conversation.php @@ -47,4 +47,17 @@ public static function createManyFromArray(array $data): array } return $conversations; } + + public function unreadBy(): ?array + { + if ($this->lastMessage === null) { + return null; + } + + $readBy = $this->lastMessage->readBy; + $readBy[] = $this->lastMessage->senderId; + $participants = array_keys($this->participants); + + return array_diff($participants, $readBy); + } } diff --git a/src/Models/Message.php b/src/Models/Message.php index df327b2..2d5c372 100644 --- a/src/Models/Message.php +++ b/src/Models/Message.php @@ -53,4 +53,20 @@ public function isSystemMessage(): bool { return $this->type == MessageType::SYSTEM; } + + public function isReadBy(string $userId): bool + { + if ($userId === $this->senderId) { + return true; + } + + return in_array($userId, $this->readBy, true); + } + + public function isRead(): bool + { + $unread = array_diff($this->readBy, [$this->senderId]); + + return !empty($unread); + } } diff --git a/tests/Feature/ConversationTest.php b/tests/Feature/ConversationTest.php index c845756..bb3df7f 100644 --- a/tests/Feature/ConversationTest.php +++ b/tests/Feature/ConversationTest.php @@ -14,12 +14,12 @@ use CarAndClassic\TalkJS\Events\ParticipationUpdated; use CarAndClassic\TalkJS\Models\Conversation; use CarAndClassic\TalkJS\Models\Message; +use CarAndClassic\TalkJS\Tests\TestCase; use Symfony\Component\HttpClient\Response\MockResponse; final class ConversationTest extends TestCase { private array $userIds; - private array $conversations; public function setUp(): void @@ -54,7 +54,7 @@ public function setUp(): void 'createdAt' => $createdAt, ]), 'participants' => [ - $this->userIds[0] => [ + $this->userIds[0] => [ 'access' => 'ReadWrite', 'notify' => true ], @@ -84,6 +84,38 @@ public function setUp(): void ] ], 'createdAt' => $createdAt + ], + [ + 'id' => 'testConversationId3', + 'subject' => 'Test Conversation 3', + 'topicId' => 'Test Topic 3', + 'photoUrl' => null, + 'welcomeMessages' => ['Test Welcome Message'], + 'custom' => ['test' => 'test'], + 'lastMessage' => new Message([ + 'id' => "test", + 'type' => "UserMessage", + 'conversationId' => "dev_test", + 'senderId' => $this->userIds[1], + 'text' => "This is the message copy", + 'readBy' => [], + 'origin' => "rest", + 'location' => null, + 'custom' => [], + 'attachment' => null, + 'createdAt' => $createdAt, + ]), + 'participants' => [ + $this->userIds[0] => [ + 'access' => 'ReadWrite', + 'notify' => true + ], + $this->userIds[1] => [ + 'access' => 'Read', + 'notify' => false + ] + ], + 'createdAt' => $createdAt ] ]; } diff --git a/tests/Feature/MessageTest.php b/tests/Feature/MessageTest.php index 60eacea..06d604b 100644 --- a/tests/Feature/MessageTest.php +++ b/tests/Feature/MessageTest.php @@ -10,14 +10,13 @@ use CarAndClassic\TalkJS\Events\MessageDeleted; use CarAndClassic\TalkJS\Events\MessageEdited; use CarAndClassic\TalkJS\Models\Message; +use CarAndClassic\TalkJS\Tests\TestCase; use Symfony\Component\HttpClient\Response\MockResponse; final class MessageTest extends TestCase { private string $conversationId; - private string $senderId; - private array $messages; protected function setUp(): void diff --git a/tests/Feature/UserTest.php b/tests/Feature/UserTest.php index db14918..8525083 100644 --- a/tests/Feature/UserTest.php +++ b/tests/Feature/UserTest.php @@ -8,14 +8,13 @@ use CarAndClassic\TalkJS\Events\UserCreatedOrUpdated; use CarAndClassic\TalkJS\Models\Conversation; use CarAndClassic\TalkJS\Models\User; +use CarAndClassic\TalkJS\Tests\TestCase; use Symfony\Component\HttpClient\Response\MockResponse; final class UserTest extends TestCase { private string $userId; - private array $userDetails; - private array $userConversations; protected function setUp(): void diff --git a/tests/Feature/TestCase.php b/tests/TestCase.php similarity index 96% rename from tests/Feature/TestCase.php rename to tests/TestCase.php index 998bcb7..01de248 100644 --- a/tests/Feature/TestCase.php +++ b/tests/TestCase.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace CarAndClassic\TalkJS\Tests\Feature; +namespace CarAndClassic\TalkJS\Tests; use CarAndClassic\TalkJS\Api\TalkJSApi; use PHPUnit\Framework\TestCase as BaseTestCase; @@ -12,7 +12,6 @@ abstract class TestCase extends BaseTestCase { protected array $defaultMockResponseHeaders; - protected array $defaultFilters; protected function setUp(): void diff --git a/tests/Unit/ConversationTest.php b/tests/Unit/ConversationTest.php new file mode 100644 index 0000000..7835d6a --- /dev/null +++ b/tests/Unit/ConversationTest.php @@ -0,0 +1,133 @@ +conversations = [ + [ + 'id' => 'testConversationId1', + 'subject' => 'Test Conversation 1', + 'topicId' => 'Test Topic 1', + 'photoUrl' => null, + 'welcomeMessages' => ['Test Welcome Message'], + 'custom' => ['test' => 'test'], + 'lastMessage' => [ + 'id' => "test", + 'type' => "UserMessage", + 'conversationId' => "dev_test", + 'senderId' => $userIds[1], + 'text' => "This is the message copy", + 'readBy' => [ + $userIds[0], + ], + 'origin' => "rest", + 'location' => null, + 'custom' => [], + 'attachment' => null, + 'createdAt' => $createdAt, + ], + 'participants' => [ + $userIds[0] => [ + 'access' => 'ReadWrite', + 'notify' => true + ], + $userIds[1] => [ + 'access' => 'Read', + 'notify' => false + ] + ], + 'createdAt' => $createdAt + ], + [ + 'id' => 'testConversationId2', + 'subject' => 'Test Conversation 2', + 'topicId' => 'Test Topic 2', + 'photoUrl' => null, + 'welcomeMessages' => ['Test Welcome Message'], + 'custom' => ['test' => 'test'], + 'lastMessage' => null, + 'participants' => [ + $userIds[0] => [ + 'access' => 'ReadWrite', + 'notify' => true + ], + $userIds[1] => [ + 'access' => 'Read', + 'notify' => false + ] + ], + 'createdAt' => $createdAt + ], + [ + 'id' => 'testConversationId3', + 'subject' => 'Test Conversation 3', + 'topicId' => 'Test Topic 3', + 'photoUrl' => null, + 'welcomeMessages' => ['Test Welcome Message'], + 'custom' => ['test' => 'test'], + 'lastMessage' => [ + 'id' => "test", + 'type' => "UserMessage", + 'conversationId' => "dev_test", + 'senderId' => $userIds[1], + 'text' => "This is the message copy", + 'readBy' => [], + 'origin' => "rest", + 'location' => null, + 'custom' => [], + 'attachment' => null, + 'createdAt' => $createdAt, + ], + 'participants' => [ + $userIds[0] => [ + 'access' => 'ReadWrite', + 'notify' => true + ], + $userIds[1] => [ + 'access' => 'Read', + 'notify' => false + ] + ], + 'createdAt' => $createdAt + ] + ]; + } + + public function testCreateManyFromArray(): void + { + $conversations = Conversation::createManyFromArray($this->conversations); + + $this->assertIsArray($conversations); + + foreach ($conversations as $conversation) { + $this->assertInstanceOf(Conversation::class, $conversation); + } + } + + public function testUnreadBy(): void + { + $conversation1 = new Conversation($this->conversations[0]); + $conversation2 = new Conversation($this->conversations[1]); + $conversation3 = new Conversation($this->conversations[2]); + + $this->assertEmpty($conversation1->unreadBy()); + $this->assertNull($conversation2->unreadBy()); + $this->assertEquals($conversation3->unreadBy(), ['TestConversationUserId1']); + } +} diff --git a/tests/Unit/MessageTest.php b/tests/Unit/MessageTest.php new file mode 100644 index 0000000..a40253c --- /dev/null +++ b/tests/Unit/MessageTest.php @@ -0,0 +1,98 @@ +senderId = 'testSenderId'; + $this->userIds = [ + 'TestConversationUserId1', + 'TestConversationUserId2' + ]; + $this->messages = [ + [ + 'id' => '1', // At time of writing results are returned descending + 'type' => MessageType::USER, + 'conversationId' => $conversationId, + 'senderId' => $this->senderId, + 'text' => 'Test User Message', + 'readBy' => [ + $this->userIds[0] + ], + 'origin' => 'rest', + 'location' => null, + 'custom' => ['test' => 'test'], + 'createdAt' => (time() + 1) * 1000, // At time of writing TalkJS returns timestamp in milliseconds + 'attachment' => null + ], + [ + 'id' => '2', + 'type' => MessageType::SYSTEM, + 'conversationId' => $conversationId, + 'senderId' => null, + 'text' => 'Test System Message', + 'readBy' => [], + 'origin' => 'rest', + 'location' => null, + 'custom' => ['test' => 'test'], + 'createdAt' => time() * 1000, + 'attachment' => null + ] + ]; + $this->message1 = new Message($this->messages[0]); + $this->message2 = new Message($this->messages[1]); + } + + public function testCreateManyFromArray(): void + { + $messages = Message::createManyFromArray($this->messages); + + $this->assertIsArray($messages); + + foreach ($messages as $message) { + $this->assertInstanceOf(Message::class, $message); + } + } + + public function testIsUserMessage(): void + { + $this->assertSame($this->message1->isUserMessage(), true); + $this->assertSame($this->message2->isUserMessage(), false); + } + + public function testIsSystemMessage(): void + { + $this->assertSame($this->message1->isSystemMessage(), false); + $this->assertSame($this->message2->isSystemMessage(), true); + } + + public function testIsReadBy(): void + { + $this->assertSame($this->message1->isReadBy($this->userIds[0]), true); + $this->assertSame($this->message1->isReadBy($this->userIds[1]), false); + $this->assertSame($this->message1->isReadBy($this->senderId), true); + $this->assertSame($this->message2->isReadBy($this->userIds[0]), false); + } + + public function testIsRead(): void + { + $this->assertSame($this->message1->isRead(), true); + $this->assertSame($this->message2->isRead(), false); + } +}