Skip to content

Commit

Permalink
feat: add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mutdmour committed Aug 15, 2024
1 parent 5fc20e1 commit f0d98b9
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 1 deletion.
112 changes: 112 additions & 0 deletions packages/editor-ui/src/utils/__tests__/apiUtils.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { STREAM_SEPERATOR, streamRequest } from '../apiUtils';

describe('streamRequest', () => {
it('should stream data from the API endpoint', async () => {
const encoder = new TextEncoder();
const mockResponse = new ReadableStream({
start(controller) {
controller.enqueue(encoder.encode(`${JSON.stringify({ chunk: 1 })}${STREAM_SEPERATOR}`));
controller.enqueue(encoder.encode(`${JSON.stringify({ chunk: 2 })}${STREAM_SEPERATOR}`));
controller.enqueue(encoder.encode(`${JSON.stringify({ chunk: 3 })}${STREAM_SEPERATOR}`));
controller.close();
},
});

const mockFetch = vi.fn().mockResolvedValue({
ok: true,
body: mockResponse,
});

global.fetch = mockFetch;

const onChunkMock = vi.fn();
const onDoneMock = vi.fn();
const onErrorMock = vi.fn();

await streamRequest(
{
baseUrl: 'https://api.example.com',
pushRef: '',
},
'/data',
{ key: 'value' },
onChunkMock,
onDoneMock,
onErrorMock,
);

expect(mockFetch).toHaveBeenCalledWith('https://api.example.com/data', {
method: 'POST',
body: JSON.stringify({ key: 'value' }),
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'browser-id': expect.stringContaining('-'),
},
});

expect(onChunkMock).toHaveBeenCalledTimes(3);
expect(onChunkMock).toHaveBeenNthCalledWith(1, { chunk: 1 });
expect(onChunkMock).toHaveBeenNthCalledWith(2, { chunk: 2 });
expect(onChunkMock).toHaveBeenNthCalledWith(3, { chunk: 3 });

expect(onDoneMock).toHaveBeenCalledTimes(1);
expect(onErrorMock).not.toHaveBeenCalled();
});

it('should handle broken stream data', async () => {
const encoder = new TextEncoder();
const mockResponse = new ReadableStream({
start(controller) {
controller.enqueue(
encoder.encode(`${JSON.stringify({ chunk: 1 })}${STREAM_SEPERATOR}{"chunk": `),
);
controller.enqueue(encoder.encode(`2}${STREAM_SEPERATOR}{"ch`));
controller.enqueue(encoder.encode('unk":'));
controller.enqueue(encoder.encode(`3}${STREAM_SEPERATOR}`));
controller.close();
},
});

const mockFetch = vi.fn().mockResolvedValue({
ok: true,
body: mockResponse,
});

global.fetch = mockFetch;

const onChunkMock = vi.fn();
const onDoneMock = vi.fn();
const onErrorMock = vi.fn();

await streamRequest(
{
baseUrl: 'https://api.example.com',
pushRef: '',
},
'/data',
{ key: 'value' },
onChunkMock,
onDoneMock,
onErrorMock,
);

expect(mockFetch).toHaveBeenCalledWith('https://api.example.com/data', {
method: 'POST',
body: JSON.stringify({ key: 'value' }),
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'browser-id': expect.stringContaining('-'),
},
});

expect(onChunkMock).toHaveBeenCalledTimes(3);
expect(onChunkMock).toHaveBeenNthCalledWith(1, { chunk: 1 });
expect(onChunkMock).toHaveBeenNthCalledWith(2, { chunk: 2 });
expect(onChunkMock).toHaveBeenNthCalledWith(3, { chunk: 3 });

expect(onDoneMock).toHaveBeenCalledTimes(1);
expect(onErrorMock).not.toHaveBeenCalled();
});
});
3 changes: 2 additions & 1 deletion packages/editor-ui/src/utils/apiUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ if (!browserId && 'randomUUID' in crypto) {
}

export const NO_NETWORK_ERROR_CODE = 999;
export const STREAM_SEPERATOR = '⧉⇋⇋➽⌑⧉§§\n';

export class ResponseError extends ApplicationError {
// The HTTP status code of response
Expand Down Expand Up @@ -200,7 +201,7 @@ export async function streamRequest<T>(
onChunk?: (chunk: T) => void,
onDone?: () => void,
onError?: (e: Error) => void,
separator = '⧉⇋⇋➽⌑⧉§§\n',
separator = STREAM_SEPERATOR,
): Promise<void> {
const headers: Record<string, string> = {
'Content-Type': 'application/json',
Expand Down

0 comments on commit f0d98b9

Please sign in to comment.