grafana/public/app/core/utils/fetch.test.ts

176 lines
11 KiB
TypeScript

import 'whatwg-fetch'; // fetch polyfill needed for PhantomJs rendering
import {
isContentTypeApplicationJson,
parseBody,
parseCredentials,
parseHeaders,
parseInitFromOptions,
parseResponseBody,
parseUrlFromOptions,
} from './fetch';
describe('parseUrlFromOptions', () => {
it.each`
params | url | expected
${undefined} | ${'api/dashboard'} | ${'api/dashboard'}
${{ key: 'value' }} | ${'api/dashboard'} | ${'api/dashboard?key=value'}
${{ key: undefined }} | ${'api/dashboard'} | ${'api/dashboard'}
${{ firstKey: 'first value', secondValue: 'second value' }} | ${'api/dashboard'} | ${'api/dashboard?firstKey=first%20value&secondValue=second%20value'}
${{ firstKey: 'first value', secondValue: undefined }} | ${'api/dashboard'} | ${'api/dashboard?firstKey=first%20value'}
${{ id: [1, 2, 3] }} | ${'api/dashboard'} | ${'api/dashboard?id=1&id=2&id=3'}
${{ id: [] }} | ${'api/dashboard'} | ${'api/dashboard'}
`(
"when called with params: '$params' and url: '$url' then result should be '$expected'",
({ params, url, expected }) => {
expect(parseUrlFromOptions({ params, url })).toEqual(expected);
}
);
});
describe('parseInitFromOptions', () => {
it.each`
method | data | withCredentials | credentials | expected
${undefined} | ${undefined} | ${undefined} | ${undefined} | ${{ method: undefined, headers: { map: { accept: 'application/json, text/plain, */*' } }, body: undefined, credentials: 'same-origin' }}
${'GET'} | ${undefined} | ${undefined} | ${undefined} | ${{ method: 'GET', headers: { map: { accept: 'application/json, text/plain, */*' } }, body: undefined, credentials: 'same-origin' }}
${'POST'} | ${{ id: '0' }} | ${undefined} | ${undefined} | ${{ method: 'POST', headers: { map: { 'content-type': 'application/json', accept: 'application/json, text/plain, */*' } }, body: '{"id":"0"}', credentials: 'same-origin' }}
${'PUT'} | ${{ id: '0' }} | ${undefined} | ${undefined} | ${{ method: 'PUT', headers: { map: { 'content-type': 'application/json', accept: 'application/json, text/plain, */*' } }, body: '{"id":"0"}', credentials: 'same-origin' }}
${'monkey'} | ${undefined} | ${undefined} | ${'omit'} | ${{ method: 'monkey', headers: { map: { accept: 'application/json, text/plain, */*' } }, body: undefined, credentials: 'omit' }}
${'GET'} | ${undefined} | ${true} | ${undefined} | ${{ method: 'GET', headers: { map: { accept: 'application/json, text/plain, */*' } }, body: undefined, credentials: 'include' }}
${'GET'} | ${undefined} | ${true} | ${'omit'} | ${{ method: 'GET', headers: { map: { accept: 'application/json, text/plain, */*' } }, body: undefined, credentials: 'omit' }}
`(
"when called with method: '$method', data: '$data', withCredentials: '$withCredentials' and credentials: '$credentials' then result should be '$expected'",
({ method, data, withCredentials, credentials, expected }) => {
expect(parseInitFromOptions({ method, data, withCredentials, credentials, url: '' })).toEqual(expected);
}
);
});
describe('parseHeaders', () => {
it.each`
options | expected
${undefined} | ${{ map: { accept: 'application/json, text/plain, */*' } }}
${{ propKey: 'some prop value' }} | ${{ map: { accept: 'application/json, text/plain, */*' } }}
${{ method: 'GET' }} | ${{ map: { accept: 'application/json, text/plain, */*' } }}
${{ method: 'POST' }} | ${{ map: { accept: 'application/json, text/plain, */*', 'content-type': 'application/json' } }}
${{ method: 'PUT' }} | ${{ map: { accept: 'application/json, text/plain, */*', 'content-type': 'application/json' } }}
${{ headers: { 'content-type': 'application/json' } }} | ${{ map: { accept: 'application/json, text/plain, */*', 'content-type': 'application/json' } }}
${{ method: 'GET', headers: { 'content-type': 'application/json' } }} | ${{ map: { accept: 'application/json, text/plain, */*', 'content-type': 'application/json' } }}
${{ method: 'POST', headers: { 'content-type': 'application/json' } }} | ${{ map: { accept: 'application/json, text/plain, */*', 'content-type': 'application/json' } }}
${{ method: 'PUT', headers: { 'content-type': 'application/json' } }} | ${{ map: { accept: 'application/json, text/plain, */*', 'content-type': 'application/json' } }}
${{ headers: { 'cOnTent-tYpe': 'application/json' } }} | ${{ map: { accept: 'application/json, text/plain, */*', 'content-type': 'application/json' } }}
${{ headers: { 'content-type': 'AppLiCatIon/JsOn' } }} | ${{ map: { accept: 'application/json, text/plain, */*', 'content-type': 'AppLiCatIon/JsOn' } }}
${{ headers: { 'cOnTent-tYpe': 'AppLiCatIon/JsOn' } }} | ${{ map: { accept: 'application/json, text/plain, */*', 'content-type': 'AppLiCatIon/JsOn' } }}
${{ headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }} | ${{ map: { accept: 'application/json, text/plain, */*', 'content-type': 'application/x-www-form-urlencoded' } }}
${{ method: 'GET', headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }} | ${{ map: { accept: 'application/json, text/plain, */*', 'content-type': 'application/x-www-form-urlencoded' } }}
${{ method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }} | ${{ map: { accept: 'application/json, text/plain, */*', 'content-type': 'application/x-www-form-urlencoded' } }}
${{ method: 'PUT', headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }} | ${{ map: { accept: 'application/json, text/plain, */*', 'content-type': 'application/x-www-form-urlencoded' } }}
${{ headers: { Accept: 'text/plain' } }} | ${{ map: { accept: 'text/plain' } }}
${{ headers: { Auth: 'Basic asdasdasd' } }} | ${{ map: { accept: 'application/json, text/plain, */*', auth: 'Basic asdasdasd' } }}
`("when called with options: '$options' then the result should be '$expected'", ({ options, expected }) => {
expect(parseHeaders(options)).toEqual(expected);
});
});
describe('isContentTypeApplicationJson', () => {
it.each`
headers | expected
${undefined} | ${false}
${new Headers({ 'cOnTent-tYpe': 'application/json' })} | ${true}
${new Headers({ 'content-type': 'AppLiCatIon/JsOn' })} | ${true}
${new Headers({ 'cOnTent-tYpe': 'AppLiCatIon/JsOn' })} | ${true}
${new Headers({ 'content-type': 'application/x-www-form-urlencoded' })} | ${false}
${new Headers({ auth: 'Basic akdjasdkjalksdjasd' })} | ${false}
`("when called with headers: 'headers' then the result should be '$expected'", ({ headers, expected }) => {
expect(isContentTypeApplicationJson(headers)).toEqual(expected);
});
});
describe('parseBody', () => {
it.each`
options | isAppJson | expected
${undefined} | ${false} | ${undefined}
${undefined} | ${true} | ${undefined}
${{ data: undefined }} | ${false} | ${undefined}
${{ data: undefined }} | ${true} | ${undefined}
${{ data: 'some data' }} | ${false} | ${'some data'}
${{ data: 'some data' }} | ${true} | ${'some data'}
${{ data: { id: '0' } }} | ${false} | ${new URLSearchParams({ id: '0' })}
${{ data: { id: '0' } }} | ${true} | ${'{"id":"0"}'}
`(
"when called with options: '$options' and isAppJson: '$isAppJson' then the result should be '$expected'",
({ options, isAppJson, expected }) => {
expect(parseBody(options, isAppJson)).toEqual(expected);
}
);
});
describe('parseCredentials', () => {
it.each`
options | expected
${undefined} | ${undefined}
${{}} | ${'same-origin'}
${{ credentials: undefined }} | ${'same-origin'}
${{ credentials: undefined, withCredentials: undefined }} | ${'same-origin'}
${{ credentials: undefined, withCredentials: false }} | ${'same-origin'}
${{ credentials: undefined, withCredentials: true }} | ${'include'}
${{ credentials: 'invalid' }} | ${'invalid'}
${{ credentials: 'invalid', withCredentials: undefined }} | ${'invalid'}
${{ credentials: 'invalid', withCredentials: false }} | ${'invalid'}
${{ credentials: 'invalid', withCredentials: true }} | ${'invalid'}
${{ credentials: 'omit' }} | ${'omit'}
${{ credentials: 'omit', withCredentials: undefined }} | ${'omit'}
${{ credentials: 'omit', withCredentials: false }} | ${'omit'}
${{ credentials: 'omit', withCredentials: true }} | ${'omit'}
`(
"when called with options: '$options' then the result should be '$expected'",
({ options, isAppJson, expected }) => {
expect(parseCredentials(options)).toEqual(expected);
}
);
});
describe('parseResponseBody', () => {
const rsp = ({} as unknown) as Response;
it('parses json', async () => {
const value = { hello: 'world' };
const body = await parseResponseBody(
{
...rsp,
json: jest.fn().mockImplementationOnce(() => value),
},
'json'
);
expect(body).toEqual(value);
});
it('parses text', async () => {
const value = 'RAW TEXT';
const body = await parseResponseBody(
{
...rsp,
text: jest.fn().mockImplementationOnce(() => value),
},
'text'
);
expect(body).toEqual(value);
});
it('undefined text', async () => {
const value = 'RAW TEXT';
const body = await parseResponseBody({
...rsp,
text: jest.fn().mockImplementationOnce(() => value),
});
expect(body).toEqual(value);
});
it('undefined as parsed json', async () => {
const value = { hello: 'world' };
const body = await parseResponseBody({
...rsp,
text: jest.fn().mockImplementationOnce(() => JSON.stringify(value)),
});
expect(body).toEqual(value);
});
});