2025-04-22 18:55:17 -07:00
|
|
|
import { generateUUID } from '@/lib/utils';
|
|
|
|
|
import { expect, test } from '../fixtures';
|
|
|
|
|
import { TEST_PROMPTS } from '../prompts/routes';
|
|
|
|
|
|
|
|
|
|
const chatIdsCreatedByAda: Array<string> = [];
|
|
|
|
|
|
|
|
|
|
test.describe
|
|
|
|
|
.serial('/api/chat', () => {
|
|
|
|
|
test('Ada cannot invoke a chat generation with empty request body', async ({
|
|
|
|
|
adaContext,
|
|
|
|
|
}) => {
|
|
|
|
|
const response = await adaContext.request.post('/api/chat', {
|
2025-04-26 01:09:01 -07:00
|
|
|
data: JSON.stringify({}),
|
2025-04-22 18:55:17 -07:00
|
|
|
});
|
2025-04-26 01:09:01 -07:00
|
|
|
expect(response.status()).toBe(400);
|
2025-04-22 18:55:17 -07:00
|
|
|
|
|
|
|
|
const text = await response.text();
|
2025-04-26 01:09:01 -07:00
|
|
|
expect(text).toEqual('Invalid request body');
|
2025-04-22 18:55:17 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('Ada can invoke chat generation', async ({ adaContext }) => {
|
|
|
|
|
const chatId = generateUUID();
|
|
|
|
|
|
2025-04-25 23:40:15 -07:00
|
|
|
const response = await adaContext.request.post('/api/chat', {
|
2025-04-22 18:55:17 -07:00
|
|
|
data: {
|
|
|
|
|
id: chatId,
|
2025-04-26 01:09:01 -07:00
|
|
|
message: TEST_PROMPTS.SKY.MESSAGE,
|
2025-04-22 18:55:17 -07:00
|
|
|
selectedChatModel: 'chat-model',
|
2025-05-01 17:47:48 -07:00
|
|
|
selectedVisibilityType: 'private',
|
2025-04-22 18:55:17 -07:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
expect(response.status()).toBe(200);
|
|
|
|
|
|
|
|
|
|
const text = await response.text();
|
|
|
|
|
const lines = text.split('\n');
|
|
|
|
|
|
|
|
|
|
const [_, ...rest] = lines;
|
|
|
|
|
expect(rest.filter(Boolean)).toEqual(TEST_PROMPTS.SKY.OUTPUT_STREAM);
|
|
|
|
|
|
|
|
|
|
chatIdsCreatedByAda.push(chatId);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("Babbage cannot append message to Ada's chat", async ({
|
|
|
|
|
babbageContext,
|
|
|
|
|
}) => {
|
|
|
|
|
const [chatId] = chatIdsCreatedByAda;
|
|
|
|
|
|
2025-04-25 23:40:15 -07:00
|
|
|
const response = await babbageContext.request.post('/api/chat', {
|
2025-04-22 18:55:17 -07:00
|
|
|
data: {
|
|
|
|
|
id: chatId,
|
2025-04-26 01:09:01 -07:00
|
|
|
message: TEST_PROMPTS.GRASS.MESSAGE,
|
2025-04-22 18:55:17 -07:00
|
|
|
selectedChatModel: 'chat-model',
|
2025-05-01 17:47:48 -07:00
|
|
|
selectedVisibilityType: 'private',
|
2025-04-22 18:55:17 -07:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
expect(response.status()).toBe(403);
|
|
|
|
|
|
|
|
|
|
const text = await response.text();
|
|
|
|
|
expect(text).toEqual('Forbidden');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("Babbage cannot delete Ada's chat", async ({ babbageContext }) => {
|
|
|
|
|
const [chatId] = chatIdsCreatedByAda;
|
|
|
|
|
|
|
|
|
|
const response = await babbageContext.request.delete(
|
2025-04-25 23:40:15 -07:00
|
|
|
`/api/chat?id=${chatId}`,
|
2025-04-22 18:55:17 -07:00
|
|
|
);
|
|
|
|
|
expect(response.status()).toBe(403);
|
|
|
|
|
|
|
|
|
|
const text = await response.text();
|
|
|
|
|
expect(text).toEqual('Forbidden');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('Ada can delete her own chat', async ({ adaContext }) => {
|
|
|
|
|
const [chatId] = chatIdsCreatedByAda;
|
|
|
|
|
|
2025-04-25 23:40:15 -07:00
|
|
|
const response = await adaContext.request.delete(
|
|
|
|
|
`/api/chat?id=${chatId}`,
|
|
|
|
|
);
|
2025-04-22 18:55:17 -07:00
|
|
|
expect(response.status()).toBe(200);
|
|
|
|
|
|
|
|
|
|
const deletedChat = await response.json();
|
|
|
|
|
expect(deletedChat).toMatchObject({ id: chatId });
|
|
|
|
|
});
|
2025-05-01 12:36:52 -07:00
|
|
|
|
|
|
|
|
test('Ada cannot resume stream of chat that does not exist', async ({
|
|
|
|
|
adaContext,
|
|
|
|
|
}) => {
|
|
|
|
|
const response = await adaContext.request.get(
|
|
|
|
|
`/api/chat?chatId=${generateUUID()}`,
|
|
|
|
|
);
|
|
|
|
|
expect(response.status()).toBe(404);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('Ada can resume chat generation', async ({ adaContext }) => {
|
|
|
|
|
const chatId = generateUUID();
|
|
|
|
|
|
|
|
|
|
const firstRequest = adaContext.request.post('/api/chat', {
|
|
|
|
|
data: {
|
|
|
|
|
id: chatId,
|
|
|
|
|
message: {
|
|
|
|
|
id: generateUUID(),
|
|
|
|
|
role: 'user',
|
|
|
|
|
content: 'Help me write an essay about Silcon Valley',
|
|
|
|
|
parts: [
|
|
|
|
|
{
|
|
|
|
|
type: 'text',
|
|
|
|
|
text: 'Help me write an essay about Silicon Valley',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
createdAt: new Date().toISOString(),
|
|
|
|
|
},
|
|
|
|
|
selectedChatModel: 'chat-model',
|
2025-05-01 17:47:48 -07:00
|
|
|
selectedVisibilityType: 'private',
|
2025-05-01 12:36:52 -07:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
|
|
|
|
|
|
|
|
const secondRequest = adaContext.request.get(
|
|
|
|
|
`/api/chat?chatId=${chatId}`,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const [firstResponse, secondResponse] = await Promise.all([
|
|
|
|
|
firstRequest,
|
|
|
|
|
secondRequest,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
const [firstStatusCode, secondStatusCode] = await Promise.all([
|
|
|
|
|
firstResponse.status(),
|
|
|
|
|
secondResponse.status(),
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
expect(firstStatusCode).toBe(200);
|
|
|
|
|
expect(secondStatusCode).toBe(200);
|
|
|
|
|
|
|
|
|
|
const [firstResponseBody, secondResponseBody] = await Promise.all([
|
|
|
|
|
await firstResponse.body(),
|
|
|
|
|
await secondResponse.body(),
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
expect(firstResponseBody.toString()).toEqual(
|
|
|
|
|
secondResponseBody.toString(),
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
2025-05-07 16:02:53 -07:00
|
|
|
test('Ada can resume chat generation that has ended during request', async ({
|
2025-05-01 12:36:52 -07:00
|
|
|
adaContext,
|
|
|
|
|
}) => {
|
|
|
|
|
const chatId = generateUUID();
|
|
|
|
|
|
|
|
|
|
const firstRequest = await adaContext.request.post('/api/chat', {
|
|
|
|
|
data: {
|
|
|
|
|
id: chatId,
|
|
|
|
|
message: {
|
|
|
|
|
id: generateUUID(),
|
|
|
|
|
role: 'user',
|
|
|
|
|
content: 'Help me write an essay about Silcon Valley',
|
|
|
|
|
parts: [
|
|
|
|
|
{
|
|
|
|
|
type: 'text',
|
|
|
|
|
text: 'Help me write an essay about Silicon Valley',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
createdAt: new Date().toISOString(),
|
|
|
|
|
},
|
|
|
|
|
selectedChatModel: 'chat-model',
|
2025-05-01 17:47:48 -07:00
|
|
|
selectedVisibilityType: 'private',
|
2025-05-01 12:36:52 -07:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const secondRequest = adaContext.request.get(
|
|
|
|
|
`/api/chat?chatId=${chatId}`,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const [firstResponse, secondResponse] = await Promise.all([
|
|
|
|
|
firstRequest,
|
|
|
|
|
secondRequest,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
const [firstStatusCode, secondStatusCode] = await Promise.all([
|
|
|
|
|
firstResponse.status(),
|
|
|
|
|
secondResponse.status(),
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
expect(firstStatusCode).toBe(200);
|
|
|
|
|
expect(secondStatusCode).toBe(200);
|
|
|
|
|
|
|
|
|
|
const [, secondResponseContent] = await Promise.all([
|
|
|
|
|
firstResponse.text(),
|
|
|
|
|
secondResponse.text(),
|
|
|
|
|
]);
|
|
|
|
|
|
2025-05-07 16:02:53 -07:00
|
|
|
expect(secondResponseContent).toContain('append-message');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('Ada cannot resume chat generation that has ended', async ({
|
|
|
|
|
adaContext,
|
|
|
|
|
}) => {
|
|
|
|
|
const chatId = generateUUID();
|
|
|
|
|
|
|
|
|
|
const firstResponse = await adaContext.request.post('/api/chat', {
|
|
|
|
|
data: {
|
|
|
|
|
id: chatId,
|
|
|
|
|
message: {
|
|
|
|
|
id: generateUUID(),
|
|
|
|
|
role: 'user',
|
|
|
|
|
content: 'Help me write an essay about Silcon Valley',
|
|
|
|
|
parts: [
|
|
|
|
|
{
|
|
|
|
|
type: 'text',
|
|
|
|
|
text: 'Help me write an essay about Silicon Valley',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
createdAt: new Date().toISOString(),
|
|
|
|
|
},
|
|
|
|
|
selectedChatModel: 'chat-model',
|
|
|
|
|
selectedVisibilityType: 'private',
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const firstStatusCode = firstResponse.status();
|
|
|
|
|
expect(firstStatusCode).toBe(200);
|
|
|
|
|
|
|
|
|
|
await firstResponse.text();
|
|
|
|
|
await new Promise((resolve) => setTimeout(resolve, 15 * 1000));
|
|
|
|
|
await new Promise((resolve) => setTimeout(resolve, 15000));
|
|
|
|
|
const secondResponse = await adaContext.request.get(
|
|
|
|
|
`/api/chat?chatId=${chatId}`,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const secondStatusCode = secondResponse.status();
|
|
|
|
|
expect(secondStatusCode).toBe(200);
|
|
|
|
|
|
|
|
|
|
const secondResponseContent = await secondResponse.text();
|
2025-05-01 12:36:52 -07:00
|
|
|
expect(secondResponseContent).toEqual('');
|
|
|
|
|
});
|
|
|
|
|
|
2025-05-01 17:47:48 -07:00
|
|
|
test('Babbage cannot resume a private chat generation that belongs to Ada', async ({
|
2025-05-01 12:36:52 -07:00
|
|
|
adaContext,
|
|
|
|
|
babbageContext,
|
|
|
|
|
}) => {
|
|
|
|
|
const chatId = generateUUID();
|
|
|
|
|
|
|
|
|
|
const firstRequest = adaContext.request.post('/api/chat', {
|
|
|
|
|
data: {
|
|
|
|
|
id: chatId,
|
|
|
|
|
message: {
|
|
|
|
|
id: generateUUID(),
|
|
|
|
|
role: 'user',
|
|
|
|
|
content: 'Help me write an essay about Silcon Valley',
|
|
|
|
|
parts: [
|
|
|
|
|
{
|
|
|
|
|
type: 'text',
|
|
|
|
|
text: 'Help me write an essay about Silicon Valley',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
createdAt: new Date().toISOString(),
|
|
|
|
|
},
|
|
|
|
|
selectedChatModel: 'chat-model',
|
2025-05-01 17:47:48 -07:00
|
|
|
selectedVisibilityType: 'private',
|
2025-05-01 12:36:52 -07:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
|
|
|
|
|
|
|
|
const secondRequest = babbageContext.request.get(
|
|
|
|
|
`/api/chat?chatId=${chatId}`,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const [firstResponse, secondResponse] = await Promise.all([
|
|
|
|
|
firstRequest,
|
|
|
|
|
secondRequest,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
const [firstStatusCode, secondStatusCode] = await Promise.all([
|
|
|
|
|
firstResponse.status(),
|
|
|
|
|
secondResponse.status(),
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
expect(firstStatusCode).toBe(200);
|
|
|
|
|
expect(secondStatusCode).toBe(403);
|
|
|
|
|
});
|
2025-05-01 17:47:48 -07:00
|
|
|
|
|
|
|
|
test('Babbage can resume a public chat generation that belongs to Ada', async ({
|
|
|
|
|
adaContext,
|
|
|
|
|
babbageContext,
|
|
|
|
|
}) => {
|
|
|
|
|
const chatId = generateUUID();
|
|
|
|
|
|
|
|
|
|
const firstRequest = adaContext.request.post('/api/chat', {
|
|
|
|
|
data: {
|
|
|
|
|
id: chatId,
|
|
|
|
|
message: {
|
|
|
|
|
id: generateUUID(),
|
|
|
|
|
role: 'user',
|
|
|
|
|
content: 'Help me write an essay about Silicon Valley',
|
|
|
|
|
parts: [
|
|
|
|
|
{
|
|
|
|
|
type: 'text',
|
|
|
|
|
text: 'Help me write an essay about Silicon Valley',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
createdAt: new Date().toISOString(),
|
|
|
|
|
},
|
|
|
|
|
selectedChatModel: 'chat-model',
|
|
|
|
|
selectedVisibilityType: 'public',
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
2025-05-07 16:02:53 -07:00
|
|
|
await new Promise((resolve) => setTimeout(resolve, 10 * 1000));
|
2025-05-01 17:47:48 -07:00
|
|
|
|
|
|
|
|
const secondRequest = babbageContext.request.get(
|
|
|
|
|
`/api/chat?chatId=${chatId}`,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const [firstResponse, secondResponse] = await Promise.all([
|
|
|
|
|
firstRequest,
|
|
|
|
|
secondRequest,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
const [firstStatusCode, secondStatusCode] = await Promise.all([
|
|
|
|
|
firstResponse.status(),
|
|
|
|
|
secondResponse.status(),
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
expect(firstStatusCode).toBe(200);
|
|
|
|
|
expect(secondStatusCode).toBe(200);
|
|
|
|
|
|
|
|
|
|
const [firstResponseContent, secondResponseContent] = await Promise.all([
|
|
|
|
|
firstResponse.text(),
|
|
|
|
|
secondResponse.text(),
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
expect(firstResponseContent).toEqual(secondResponseContent);
|
|
|
|
|
});
|
2025-04-22 18:55:17 -07:00
|
|
|
});
|