-
Notifications
You must be signed in to change notification settings - Fork 20
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
Adds views tests for Threads #93
Merged
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
df723f0
Adds tests for list threads and also a helper to create threads
amandasavluchinske 7e65ccd
Adds baker
amandasavluchinske 6c6ed3c
Merges with base branch
amandasavluchinske 95fe7ee
Merge branch 'td/add-tests-to-views-assistant' into td/add-tests-to-v…
amandasavluchinske 4e68248
Updates threads tests to use pytest standards
amandasavluchinske b06a23f
Removes helpers file
amandasavluchinske 8721e1d
Adds tests for threads
amandasavluchinske 3e25840
Removes useless json.dumps
amandasavluchinske 1e91885
Merge branch 'main' into td/add-tests-to-views-threads
amandasavluchinske edfe7d0
Favors reverse as opposed to hardcoded URLs
amandasavluchinske 1fdee92
Adds test for getting a specific thread and improves list thread test
amandasavluchinske 2d2e0a1
Update tests/test_views.py
fjsj 0bc09ff
Drop unused description field
fjsj eb43ab5
Adds additional assertions to update and delete tests
amandasavluchinske File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,15 @@ | ||
from http import HTTPStatus | ||
|
||
from django.contrib.auth.models import User | ||
from django.urls import reverse | ||
|
||
import pytest | ||
from model_bakery import baker | ||
|
||
from django_ai_assistant.exceptions import AIAssistantNotDefinedError | ||
from django_ai_assistant.helpers.assistants import AIAssistant, register_assistant | ||
from django_ai_assistant.langchain.tools import BaseModel, Field, method_tool | ||
from django_ai_assistant.models import Thread | ||
|
||
|
||
# Set up | ||
|
@@ -14,7 +19,6 @@ | |
class TemperatureAssistant(AIAssistant): | ||
id = "temperature_assistant" # noqa: A003 | ||
name = "Temperature Assistant" | ||
description = "A temperature assistant that provides temperature information." | ||
instructions = "You are a temperature bot." | ||
model = "gpt-4o" | ||
|
||
|
@@ -36,11 +40,18 @@ def fetch_forecast_temperature(self, location: str, dt_str: str) -> str: | |
return "35 degrees Celsius" | ||
|
||
|
||
@pytest.fixture | ||
def authenticated_client(client): | ||
User.objects.create_user(username="testuser", password="password") | ||
client.login(username="testuser", password="password") | ||
return client | ||
|
||
|
||
# Assistant Views | ||
|
||
|
||
def test_list_assistants_with_results(client): | ||
response = client.get("/assistants/") | ||
response = client.get(reverse("django_ai_assistant:assistants_list")) | ||
|
||
assert response.status_code == HTTPStatus.OK | ||
assert response.json() == [{"id": "temperature_assistant", "name": "Temperature Assistant"}] | ||
|
@@ -52,15 +63,23 @@ def test_does_not_list_assistants_if_unauthorized(): | |
|
||
|
||
def test_get_assistant_that_exists(client): | ||
response = client.get("/assistants/temperature_assistant/") | ||
response = client.get( | ||
reverse( | ||
"django_ai_assistant:assistant_detail", kwargs={"assistant_id": "temperature_assistant"} | ||
) | ||
) | ||
|
||
assert response.status_code == HTTPStatus.OK | ||
assert response.json() == {"id": "temperature_assistant", "name": "Temperature Assistant"} | ||
|
||
|
||
def test_get_assistant_that_does_not_exist(client): | ||
with pytest.raises(AIAssistantNotDefinedError): | ||
client.get("/assistants/fake_assistant/") | ||
client.get( | ||
reverse( | ||
"django_ai_assistant:assistant_detail", kwargs={"assistant_id": "fake_assistant"} | ||
) | ||
) | ||
|
||
|
||
def test_does_not_return_assistant_if_unauthorized(): | ||
|
@@ -70,4 +89,136 @@ def test_does_not_return_assistant_if_unauthorized(): | |
|
||
# Threads Views | ||
|
||
# Up next | ||
# GET | ||
|
||
|
||
@pytest.mark.django_db(transaction=True) | ||
def test_list_threads_without_results(authenticated_client): | ||
response = authenticated_client.get(reverse("django_ai_assistant:threads_list_create")) | ||
|
||
assert response.status_code == HTTPStatus.OK | ||
assert response.json() == [] | ||
|
||
|
||
@pytest.mark.django_db(transaction=True) | ||
def test_list_threads_with_results(authenticated_client): | ||
user = User.objects.first() | ||
baker.make(Thread, created_by=user, _quantity=2) | ||
response = authenticated_client.get(reverse("django_ai_assistant:threads_list_create")) | ||
|
||
assert response.status_code == HTTPStatus.OK | ||
assert len(response.json()) == 2 | ||
|
||
|
||
@pytest.mark.django_db(transaction=True) | ||
def test_does_not_list_other_users_threads(authenticated_client): | ||
baker.make(Thread) | ||
response = authenticated_client.get(reverse("django_ai_assistant:threads_list_create")) | ||
|
||
assert response.status_code == HTTPStatus.OK | ||
assert response.json() == [] | ||
|
||
|
||
@pytest.mark.django_db(transaction=True) | ||
def test_gets_specific_thread(authenticated_client): | ||
thread = baker.make(Thread, created_by=User.objects.first()) | ||
response = authenticated_client.get( | ||
reverse("django_ai_assistant:thread_detail_update_delete", kwargs={"thread_id": thread.id}) | ||
) | ||
|
||
assert response.status_code == HTTPStatus.OK | ||
assert response.json().get("id") == thread.id | ||
|
||
|
||
def test_does_not_list_threads_if_unauthorized(): | ||
# TODO: Implement this test once permissions are in place | ||
pass | ||
|
||
|
||
# POST | ||
|
||
|
||
@pytest.mark.django_db(transaction=True) | ||
def test_create_thread(authenticated_client): | ||
response = authenticated_client.post( | ||
reverse("django_ai_assistant:threads_list_create"), data={}, content_type="application/json" | ||
) | ||
|
||
thread = Thread.objects.first() | ||
|
||
assert response.status_code == HTTPStatus.OK | ||
assert response.json().get("id") == thread.id | ||
|
||
|
||
def test_cannot_create_thread_if_unauthorized(): | ||
# TODO: Implement this test once permissions are in place | ||
pass | ||
|
||
|
||
# PATCH | ||
|
||
|
||
@pytest.mark.django_db(transaction=True) | ||
def test_update_thread(authenticated_client): | ||
thread = baker.make(Thread, created_by=User.objects.first()) | ||
response = authenticated_client.patch( | ||
reverse("django_ai_assistant:thread_detail_update_delete", kwargs={"thread_id": thread.id}), | ||
data={"name": "New name"}, | ||
content_type="application/json", | ||
) | ||
|
||
assert response.status_code == HTTPStatus.OK | ||
assert Thread.objects.filter(id=thread.id).first().name == "New name" | ||
|
||
|
||
@pytest.mark.django_db(transaction=True) | ||
def test_cannot_update_other_users_threads(authenticated_client): | ||
thread = baker.make(Thread) | ||
response = authenticated_client.patch( | ||
reverse("django_ai_assistant:thread_detail_update_delete", kwargs={"thread_id": thread.id}), | ||
data={"name": "New name"}, | ||
content_type="application/json", | ||
) | ||
|
||
assert response.status_code == HTTPStatus.FORBIDDEN | ||
assert Thread.objects.filter(id=thread.id).first().name != "New name" | ||
|
||
|
||
def test_cannot_update_thread_if_unauthorized(): | ||
# TODO: Implement this test once permissions are in place | ||
pass | ||
|
||
|
||
# DELETE | ||
|
||
|
||
@pytest.mark.django_db(transaction=True) | ||
def test_delete_thread(authenticated_client): | ||
thread = baker.make(Thread, created_by=User.objects.first()) | ||
response = authenticated_client.delete( | ||
reverse("django_ai_assistant:thread_detail_update_delete", kwargs={"thread_id": thread.id}) | ||
) | ||
|
||
assert response.status_code == HTTPStatus.NO_CONTENT | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you please assert the deletion really happened by checking if the thread is gone? |
||
assert not Thread.objects.filter(id=thread.id).exists() | ||
|
||
|
||
@pytest.mark.django_db(transaction=True) | ||
def test_cannot_delete_other_users_threads(authenticated_client): | ||
thread = baker.make(Thread) | ||
response = authenticated_client.delete( | ||
reverse("django_ai_assistant:thread_detail_update_delete", kwargs={"thread_id": thread.id}) | ||
) | ||
|
||
assert response.status_code == HTTPStatus.FORBIDDEN | ||
assert Thread.objects.filter(id=thread.id).exists() | ||
|
||
|
||
def test_cannot_delete_thread_if_unauthorized(): | ||
# TODO: Implement this test once permissions are in place | ||
pass | ||
|
||
|
||
# Threads Messages Views (will need VCR) | ||
|
||
# TBD |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please assert the update really happened by checking the new name?