1
0
mirror of https://github.com/twirl/The-API-Book.git synced 2025-05-13 21:26:26 +02:00
2023-07-30 15:25:21 +03:00

159 lines
5.6 KiB
TypeScript

/**
* @jest-environment jsdom
*/
import { SearchBox } from '../src/SearchBox';
import { ISearchResult } from '../src/interfaces/ICoffeeApi';
import {
CAFEE_CHAMOMILE_LUNGO_OFFER,
DUMMY_RESPONSE,
dummyCoffeeApi
} from './fixtures/dummyCoffeeApi';
import { mockComposer } from './fixtures/mocks';
import { waitForEvents, defer } from './util';
class TestSearchBox extends SearchBox {
public buildComposer() {
return mockComposer;
}
public getInputNode() {
return this.input;
}
public getButtonNode() {
return this.searchButton;
}
}
describe('SearchBox', () => {
let searchBox: TestSearchBox;
beforeEach(() => {
jest.resetAllMocks();
document.body.innerHTML = '';
});
afterEach(() => searchBox.destroy());
test(`SearchBox doesn't react on button click if input is empty`, () => {
const searchMock = jest.spyOn(dummyCoffeeApi, 'search');
searchBox = new TestSearchBox(document.body, dummyCoffeeApi, {});
searchBox.getInputNode().value = ' ';
searchBox.getButtonNode().click();
expect(searchMock).toBeCalledTimes(0);
searchBox.destroy();
});
test('SearchBox reacts on button click', async () => {
const searchMock = jest.spyOn(dummyCoffeeApi, 'search');
searchBox = new TestSearchBox(document.body, dummyCoffeeApi, {});
searchBox.getInputNode().value = ' test\t';
const offerLists = await waitForEvents(
searchBox.events,
'offerListChange',
() => {
searchBox.getButtonNode().click();
}
);
expect(offerLists).toEqual([{ offerList: DUMMY_RESPONSE }]);
expect(searchMock).toBeCalledTimes(1);
expect(searchMock).toBeCalledWith('test');
searchBox.destroy();
});
test('SearchBox performs search if the "search" method is called', async () => {
const searchMock = jest.spyOn(dummyCoffeeApi, 'search');
searchBox = new TestSearchBox(document.body, dummyCoffeeApi, {});
searchBox.getInputNode().value = ' test\t';
const offerLists = await waitForEvents(
searchBox.events,
'offerListChange',
() => {
searchBox.search('test');
}
);
expect(searchBox.getInputNode().value).toEqual('test');
expect(offerLists).toEqual([{ offerList: DUMMY_RESPONSE }]);
expect(searchMock).toBeCalledTimes(1);
expect(searchMock).toBeCalledWith('test');
searchBox.destroy();
});
test('SearchBox displays only the latest result even if the earlier call came first', async () => {
const defer1 = defer<ISearchResult[]>();
const defer2 = defer<ISearchResult[]>();
const DUMMY_RESPONSE_2 = [
CAFEE_CHAMOMILE_LUNGO_OFFER,
CAFEE_CHAMOMILE_LUNGO_OFFER
];
const searchMock = jest
.spyOn(dummyCoffeeApi, 'search')
.mockImplementationOnce(() => defer1.promise)
.mockImplementationOnce(() => defer2.promise);
searchBox = new TestSearchBox(document.body, dummyCoffeeApi, {});
const offerList = await waitForEvents(
searchBox.events,
'offerListChange',
() => {
searchBox.search('test1');
setTimeout(() => {
searchBox.search('test2');
defer1.resolve(DUMMY_RESPONSE);
defer2.resolve(DUMMY_RESPONSE_2);
}, 50);
},
1
);
expect(offerList).toEqual([{ offerList: DUMMY_RESPONSE_2 }]);
expect(searchMock).toBeCalledTimes(2);
expect(searchMock).toBeCalledWith('test1');
expect(searchMock).toBeCalledWith('test2');
searchBox.destroy();
});
test('SearchBox resets results while waiting for a response', async () => {
searchBox = new TestSearchBox(document.body, dummyCoffeeApi, {});
await searchBox.search('test1');
const offerList = await waitForEvents(
searchBox.events,
'offerListChange',
() => {
searchBox.search('test2');
},
2
);
expect(offerList).toEqual([
{ offerList: null },
{ offerList: DUMMY_RESPONSE }
]);
searchBox.destroy();
});
test('SearchBox creates order upon receiving a "createOrder" event from the composer', () => {
const createOrderMock = jest.spyOn(dummyCoffeeApi, 'createOrder');
searchBox = new TestSearchBox(document.body, dummyCoffeeApi, {});
mockComposer.events.emit('createOrder', {
offer: CAFEE_CHAMOMILE_LUNGO_OFFER
});
expect(createOrderMock).toBeCalledWith({
offerId: CAFEE_CHAMOMILE_LUNGO_OFFER.offerId
});
searchBox.destroy();
});
test('SearchBox destroys. Destroyed SearchBox does not react to events', () => {
const searchMock = jest.spyOn(dummyCoffeeApi, 'search');
const createOrderMock = jest.spyOn(dummyCoffeeApi, 'createOrder');
const searchBox = new TestSearchBox(document.body, dummyCoffeeApi, {});
searchBox.destroy();
expect(document.body.innerHTML).toEqual('');
searchBox.getButtonNode().click();
mockComposer.events.emit('createOrder', {
offer: CAFEE_CHAMOMILE_LUNGO_OFFER
});
expect(searchMock).toBeCalledTimes(0);
expect(createOrderMock).toBeCalledTimes(0);
expect(mockComposer.destroy).toBeCalledTimes(1);
searchBox.destroy();
});
});