Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ychat update messages #81

Merged
merged 4 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,27 @@ jobs:
set -eux
jlpm run test

test_extensions:
runs-on: ubuntu-latest
needs: build_jupyter-chat
name: Python test on extensions

steps:
- name: Checkout
uses: actions/checkout@v3

- name: Base Setup
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1

- name: Install dependencies
run: python -m pip install -U "jupyterlab>=4.0.0,<5"

- name: Build the extensions
run: |
set -eux
./scripts/install.sh
pytest -vv -r ap --cov

build_extensions:
runs-on: ubuntu-latest
needs: build_jupyter-chat
Expand All @@ -57,7 +78,7 @@ jobs:
- name: Install dependencies
run: python -m pip install -U "jupyterlab>=4.0.0,<5"

- name: Build package
- name: Package the extensions
run: |
jlpm install
jlpm build:${{ matrix.extension }}
Expand Down
1 change: 0 additions & 1 deletion conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

import pytest

pytest_plugins = ("pytest_jupyter.jupyter_server", )
11 changes: 0 additions & 11 deletions python/jupyterlab-collaborative-chat/conftest.py

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

# import jupyter_ydoc before YChat to avoid circular error
import jupyter_ydoc

import pytest
import time
from copy import deepcopy
from uuid import uuid4
from ..ychat import YChat

USER = {
"username": str(uuid4()),
"name": "Test user",
"display_name": "Test user"
}

USER2 = {
"username": str(uuid4()),
"name": "Test user 2",
"display_name": "Test user 2"
}


def create_message():
return {
"type": "msg",
"id": str(uuid4()),
"body": "This is a test message",
"time": time.time(),
"sender": USER["username"]
}


def test_initialize_ychat():
chat = YChat()
assert chat.get_messages() == []
assert chat.get_users() == {}
assert chat.get_metadata() == {}


def test_add_user():
chat = YChat()
chat.set_user(USER)
assert USER["username"] in chat.get_users().keys()
assert chat.get_users()[USER["username"]] == USER


def test_get_user_by_name():
chat = YChat()
chat.set_user(USER)
chat.set_user(USER2)
assert chat.get_user_by_name(USER["name"]) == USER
assert chat.get_user_by_name(USER2["name"]) == USER2
assert chat.get_user_by_name(str(uuid4())) == None


def test_add_message():
chat = YChat()
msg = create_message()
chat.add_message(msg)
assert len(chat.get_messages()) == 1
assert chat.get_messages()[0] == msg


def test_set_message_should_add():
chat = YChat()
msg = create_message()
chat.set_message(msg)
assert len(chat.get_messages()) == 1
assert chat.get_messages()[0] == msg


def test_set_message_should_update():
chat = YChat()
msg = create_message()
index = chat.add_message(msg)
msg["body"] = "Updated content"
chat.set_message(msg, index)
assert len(chat.get_messages()) == 1
assert chat.get_messages()[0] == msg


def test_set_message_should_add_with_new_id():
chat = YChat()
msg = create_message()
index = chat.add_message(msg)
new_msg = deepcopy(msg)
new_msg["id"] = str(uuid4())
new_msg["body"] = "Updated content"
chat.set_message(new_msg, index)
assert len(chat.get_messages()) == 2
assert chat.get_messages()[0] == msg
assert chat.get_messages()[1] == new_msg


def test_set_message_should_update_with_wrong_index():
chat = YChat()
msg = create_message()
chat.add_message(msg)
new_msg = create_message()
new_msg["body"] = "New content"
index = chat.add_message(new_msg)
assert index == 1
new_msg["body"] = "Updated content"
chat.set_message(new_msg, 0)
assert len(chat.get_messages()) == 2
assert chat.get_messages()[0] == msg
assert chat.get_messages()[1] == new_msg

Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,13 @@ def set_user(self, user: dict[str, str]) -> None:
with self._ydoc.transaction():
self._yusers.update({user["username"]: user})

def get_message(self, id: str) -> dict | None:
def get_message(self, id: str) -> tuple[dict | None, int | None]:
"""
Returns a message from its id, or None
Returns a message and its index from its id, or None
"""
return next(
(msg for msg in self.get_messages() if msg["id"] == id),
None
((msg, i) for i, msg in enumerate(self.get_messages()) if msg["id"] == id),
(None, None)
)

def get_messages(self) -> list[dict]:
Expand All @@ -97,12 +97,45 @@ def get_messages(self) -> list[dict]:
"""
return self._ymessages.to_py()

def add_message(self, message: dict) -> None:
def add_message(self, message: dict) -> int:
"""
Append a message to the document.
"""
timestamp: float = time.time()
message["time"] = timestamp
with self._ydoc.transaction():
index = len(self._ymessages) - next((i for i, v in enumerate(self.get_messages()[::-1]) if v["time"] < timestamp), len(self._ymessages))
self._ymessages.insert(index, message)
return index

def update_message(self, message: dict, index: int, append: bool = False):
"""
Appends a message to the document.
Update a message of the document.
If append is True, the content will be append to the previous content.
"""
with self._ydoc.transaction():
self._ymessages.append(message)
initial_message = self._ymessages.pop(index)
if append:
message["body"] = initial_message["body"] + message["body"]
self._ymessages.insert(index, message)

def set_message(self, message: dict, index: int | None = None, append: bool = False):
"""
Update or append a message.
"""

if index is not None and 0 <= index < len(self._ymessages):
initial_message = self._ymessages[index]
else:
return self.add_message(message)

if not initial_message["id"] == message["id"]:
initial_message, index = self.get_message(message["id"])
if initial_message is None:
return self.add_message(message)

self.update_message(message, index, append)
return index

def get_single_metadata(self, name) -> dict:
"""
Expand Down
Loading