Skip to content

Commit

Permalink
Implement and document updateThread in useThreadList
Browse files Browse the repository at this point in the history
  • Loading branch information
fjsj committed Oct 3, 2024
1 parent 714b4d8 commit d7c91ab
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 2 deletions.
2 changes: 1 addition & 1 deletion django_ai_assistant/helpers/use_cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ def get_threads(
If empty or None, all threads for the user are returned.
request (HttpRequest | None): Current request, if any
Returns:
list[Thread]: QuerySet of Thread model instances
list[Thread]: List of thread model instances
"""
threads = Thread.objects.filter(created_by=user)

Expand Down
4 changes: 3 additions & 1 deletion docs/frontend.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ Get a thread by ID.

### `aiUpdateThread`
Update a thread by ID.
**Param:** `{ threadId: string, requestBody: { name: string } }`
**Param:** `{ threadId: string, requestBody: { name: string, assistant_id: string } }`
**Return:** a `Promise` that resolves to a `Thread`.

### `aiDeleteThread`
Expand Down Expand Up @@ -198,9 +198,11 @@ export function MyComponent() {
threads,
fetchThreads,
createThread,
updateThread,
deleteThread,
loadingFetchThreads,
loadingCreateThread,
loadingUpdateThread,
loadingDeleteThread
} = useThreadList();
// ...
Expand Down
38 changes: 38 additions & 0 deletions frontend/src/hooks/useThreadList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useState } from "react";
import {
Thread,
aiCreateThread,
aiUpdateThread,
aiDeleteThread,
aiListThreads,
} from "../client";
Expand All @@ -17,6 +18,8 @@ export function useThreadList({ assistantId }: { assistantId?: string } = {}) {
useState<boolean>(false);
const [loadingCreateThread, setLoadingCreateThread] =
useState<boolean>(false);
const [loadingUpdateThread, setLoadingUpdateThread] =
useState<boolean>(false);
const [loadingDeleteThread, setLoadingDeleteThread] =
useState<boolean>(false);

Expand Down Expand Up @@ -57,6 +60,33 @@ export function useThreadList({ assistantId }: { assistantId?: string } = {}) {
[fetchThreads, assistantId]
);

/**
* Updates a thread.
*
* @param threadId The ID of the thread to update.
* @param name The new name of the thread.
* @param shouldUpdateAssistantId If true, the assistant ID will be updated.
* @returns A promise that resolves with the updated thread.
*/
const updateThread = useCallback(
async ({ threadId, name, shouldUpdateAssistantId }: { threadId: string, name: string, shouldUpdateAssistantId: boolean }): Promise<Thread> => {
try {
setLoadingUpdateThread(true);
const thread = await aiUpdateThread({
threadId, requestBody: {
name,
assistant_id: shouldUpdateAssistantId ? assistantId : undefined,
}
});
await fetchThreads();
return thread;
} finally {
setLoadingUpdateThread(false);
}
},
[fetchThreads, assistantId]
);

/**
* Deletes a thread.
*
Expand Down Expand Up @@ -84,6 +114,10 @@ export function useThreadList({ assistantId }: { assistantId?: string } = {}) {
* Function to create a new thread.
*/
createThread,
/**
* Function to update a thread.
*/
updateThread,
/**
* Function to delete a thread.
*/
Expand All @@ -100,6 +134,10 @@ export function useThreadList({ assistantId }: { assistantId?: string } = {}) {
* Loading state of the create operation.
*/
loadingCreateThread,
/**
* Loading state of the update operation.
*/
loadingUpdateThread,
/**
* Loading state of the delete operation.
*/
Expand Down
64 changes: 64 additions & 0 deletions frontend/tests/useThreadList.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { act, renderHook } from "@testing-library/react";
import { useThreadList } from "../src/hooks";
import {
aiCreateThread,
aiUpdateThread,
aiDeleteThread,
aiListThreads,
} from "../src/client";
Expand All @@ -13,6 +14,9 @@ jest.mock("../src/client", () => ({
aiListThreads: jest
.fn()
.mockImplementation(() => Promise.resolve()),
aiUpdateThread: jest
.fn()
.mockImplementation(() => Promise.resolve()),
aiDeleteThread: jest
.fn()
.mockImplementation(() => Promise.resolve()),
Expand Down Expand Up @@ -221,6 +225,66 @@ describe("useThreadList", () => {
});
});

describe("updateThread", () => {
it("should update a thread and update state correctly", async () => {
const updatedThreadId = mockThreads[0].id;
const updatedThread = {
...mockThreads[0],
name: "Updated Thread",
};
(aiListThreads as jest.Mock).mockResolvedValue([updatedThread, ...mockThreads.slice(1)]);
(aiUpdateThread as jest.Mock).mockResolvedValue(updatedThread);

const { result } = renderHook(() => useThreadList());

result.current.threads = mockThreads;

expect(result.current.threads).toEqual(mockThreads);
expect(result.current.loadingUpdateThread).toBe(false);

await act(async () => {
await result.current.updateThread({
threadId: updatedThreadId.toString(),
name: "Updated Thread",
shouldUpdateAssistantId: false,
});
});

expect(result.current.threads).toEqual([updatedThread, ...mockThreads.slice(1)]);
expect(result.current.loadingUpdateThread).toBe(false);
});

it("should update a thread with shouldUpdateAssistantId", async () => {
const assistantId = "test_assistant";
const updatedThreadId = mockThreads[0].id;
const updatedThread = {
...mockThreads[0],
name: "Updated Thread",
assistant_id: "test_assistant",
};
(aiListThreads as jest.Mock).mockResolvedValue([updatedThread, ...mockThreads.slice(1)]);
(aiUpdateThread as jest.Mock).mockResolvedValue(updatedThread);

const { result } = renderHook(() => useThreadList({ assistantId: assistantId }));

result.current.threads = mockThreads;

expect(result.current.threads).toEqual(mockThreads);
expect(result.current.loadingUpdateThread).toBe(false);

await act(async () => {
await result.current.updateThread({
threadId: updatedThreadId.toString(),
name: "Updated Thread",
shouldUpdateAssistantId: true,
});
});

expect(result.current.threads).toEqual([updatedThread, ...mockThreads.slice(1)]);
expect(result.current.loadingUpdateThread).toBe(false);
});
});

describe("deleteThread", () => {
it("should delete a thread and update state correctly", async () => {
const deletedThreadId = mockThreads[0].id;
Expand Down

0 comments on commit d7c91ab

Please sign in to comment.