mirror of
https://github.com/directus/directus.git
synced 2026-01-14 08:37:57 -05:00
* feat(sdk): add a message entry on api error to be catchable normally * feat(sdk): FetchInterface MUST return unknown to support alternative fetch implementations * feat(sdk): empty default error message to match js Error spec * Improve DirectusError type * add tests * account for non object reason in message * add non object reason test * simplify error message check * add changeset * Error result is not necessarily a directus error * Remove unnecessary errors existence check --------- Co-authored-by: daedalus <44623501+ComfortablyCoding@users.noreply.github.com>
106 lines
3.0 KiB
TypeScript
106 lines
3.0 KiB
TypeScript
import { afterEach, describe, expect, it, test, vi } from 'vitest';
|
|
import { request } from '../src/utils/request.js';
|
|
|
|
const fetchMock = vi.fn(async () => ({}));
|
|
|
|
afterEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe('Request', () => {
|
|
describe('headers', () => {
|
|
it('should default to empty headers object if no header provided', async () => {
|
|
await request('https://example.com', {}, fetchMock);
|
|
|
|
expect(fetchMock).toBeCalledWith('https://example.com', { headers: {} });
|
|
});
|
|
|
|
it('should default to empty headers object if non object header provided', async () => {
|
|
await request('https://example.com', { headers: [] }, fetchMock);
|
|
|
|
expect(fetchMock).toBeCalledWith('https://example.com', { headers: {} });
|
|
});
|
|
|
|
it('should leave headers as is if they are object', async () => {
|
|
const options = { headers: { 'Content-Type': 'application/json' } };
|
|
|
|
await request('https://example.com', options, fetchMock);
|
|
|
|
expect(fetchMock).toBeCalledWith('https://example.com', options);
|
|
});
|
|
});
|
|
|
|
describe('error handling', () => {
|
|
it('should handle non object reason', async () => {
|
|
vi.mocked(fetchMock).mockResolvedValue({
|
|
headers: new Headers([['Content-Type', 'application/json']]),
|
|
json: async () => 'Error',
|
|
text: () => {},
|
|
ok: false,
|
|
});
|
|
|
|
await expect(async () => await request('https://example.com', {}, fetchMock)).rejects.toStrictEqual({
|
|
errors: 'Error',
|
|
message: '',
|
|
response: expect.objectContaining({
|
|
ok: false,
|
|
}),
|
|
});
|
|
});
|
|
|
|
it('should handle reason with errors array', async () => {
|
|
vi.mocked(fetchMock).mockResolvedValue({ errors: [] });
|
|
|
|
await expect(async () => await request('https://example.com', {}, fetchMock)).rejects.toStrictEqual({
|
|
errors: [],
|
|
message: '',
|
|
response: {
|
|
errors: [],
|
|
},
|
|
});
|
|
});
|
|
|
|
describe('should handle reason with errors array and data property', () => {
|
|
const types = [{}, [], false, 1, '1', null];
|
|
|
|
test.each(types)('Check %o', async (type) => {
|
|
vi.mocked(fetchMock).mockResolvedValue({ errors: [], data: type });
|
|
|
|
await expect(async () => await request('https://example.com', {}, fetchMock)).rejects.toStrictEqual({
|
|
errors: [],
|
|
message: '',
|
|
response: {
|
|
data: type,
|
|
errors: [],
|
|
},
|
|
data: type,
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should handle reason with non array errors', async () => {
|
|
vi.mocked(fetchMock).mockResolvedValue({ errors: 'Error' });
|
|
|
|
await expect(async () => await request('https://example.com', {}, fetchMock)).rejects.toStrictEqual({
|
|
errors: 'Error',
|
|
message: '',
|
|
response: {
|
|
errors: 'Error',
|
|
},
|
|
});
|
|
});
|
|
|
|
it('should handle reason with message property in errors array', async () => {
|
|
vi.mocked(fetchMock).mockResolvedValue({ errors: [{ message: 'Error' }] });
|
|
|
|
await expect(async () => await request('https://example.com', {}, fetchMock)).rejects.toStrictEqual({
|
|
errors: [{ message: 'Error' }],
|
|
message: 'Error',
|
|
response: {
|
|
errors: [{ message: 'Error' }],
|
|
},
|
|
});
|
|
});
|
|
});
|
|
});
|