Skip to content

Commit

Permalink
add API unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
pgayvallet committed May 19, 2021
1 parent 464d824 commit 442c480
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/plugins/newsfeed/public/lib/api.test.mocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { storageMock } from './storage.mock';
import { driverMock } from './driver.mock';

export const storageInstanceMock = storageMock.create();
jest.doMock('./storage', () => ({
NewsfeedStorage: jest.fn().mockImplementation(() => storageInstanceMock),
}));

export const driverInstanceMock = driverMock.create();
jest.doMock('./driver', () => ({
NewsfeedApiDriver: jest.fn().mockImplementation(() => driverInstanceMock),
}));
130 changes: 130 additions & 0 deletions src/plugins/newsfeed/public/lib/api.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { driverInstanceMock, storageInstanceMock } from './api.test.mocks';
import moment from 'moment';
import { httpServiceMock } from '../../../../core/public/mocks';
import { getApi } from './api';
import { TestScheduler } from 'rxjs/testing';
import { FetchResult, NewsfeedPluginBrowserConfig } from '../types';
import { take } from 'rxjs/operators';

const kibanaVersion = '8.0.0';
const newsfeedId = 'test';

const getTestScheduler = () =>
new TestScheduler((actual, expected) => {
expect(actual).toEqual(expected);
});

const createConfig = (mainInternal: number): NewsfeedPluginBrowserConfig => ({
mainInterval: moment.duration(mainInternal, 'ms'),
fetchInterval: moment.duration(mainInternal, 'ms'),
service: {
urlRoot: 'urlRoot',
pathTemplate: 'pathTemplate',
},
});

const createFetchResult = (parts: Partial<FetchResult>): FetchResult => ({
feedItems: [],
hasNew: false,
error: null,
kibanaVersion,
...parts,
});

describe('getApi', () => {
let http: ReturnType<typeof httpServiceMock.createSetupContract>;

beforeEach(() => {
http = httpServiceMock.createSetupContract();
driverInstanceMock.shouldFetch.mockReturnValue(true);
});

afterEach(() => {
storageInstanceMock.isAnyUnread$.mockReset();
driverInstanceMock.fetchNewsfeedItems.mockReset();
});

it('merges the newsfeed and unread observables', () => {
getTestScheduler().run(({ expectObservable, cold }) => {
storageInstanceMock.isAnyUnread$.mockImplementation(() => {
return cold<boolean>('a|', {
a: true,
});
});
driverInstanceMock.fetchNewsfeedItems.mockReturnValue(
cold<FetchResult>('a|', {
a: createFetchResult({ feedItems: ['item' as any] }),
})
);
const api = getApi(http, createConfig(1000), kibanaVersion, newsfeedId);

expectObservable(api.fetchResults$.pipe(take(1))).toBe('(a|)', {
a: createFetchResult({
feedItems: ['item' as any],
hasNew: true,
}),
});
});
});

it('emits based on the predefined interval', () => {
getTestScheduler().run(({ expectObservable, cold }) => {
storageInstanceMock.isAnyUnread$.mockImplementation(() => {
return cold<boolean>('a|', {
a: true,
});
});
driverInstanceMock.fetchNewsfeedItems.mockReturnValue(
cold<FetchResult>('a|', {
a: createFetchResult({ feedItems: ['item' as any] }),
})
);
const api = getApi(http, createConfig(2), kibanaVersion, newsfeedId);

expectObservable(api.fetchResults$.pipe(take(2))).toBe('a-(b|)', {
a: createFetchResult({
feedItems: ['item' as any],
hasNew: true,
}),
b: createFetchResult({
feedItems: ['item' as any],
hasNew: true,
}),
});
});
});

it('re-emits when the unread status changes', () => {
getTestScheduler().run(({ expectObservable, cold }) => {
storageInstanceMock.isAnyUnread$.mockImplementation(() => {
return cold<boolean>('a--b', {
a: true,
b: false,
});
});
driverInstanceMock.fetchNewsfeedItems.mockReturnValue(
cold<FetchResult>('(a|)', {
a: createFetchResult({}),
})
);
const api = getApi(http, createConfig(10), kibanaVersion, newsfeedId);

expectObservable(api.fetchResults$.pipe(take(2))).toBe('a--(b|)', {
a: createFetchResult({
hasNew: true,
}),
b: createFetchResult({
hasNew: false,
}),
});
});
});
});
22 changes: 22 additions & 0 deletions src/plugins/newsfeed/public/lib/driver.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { PublicMethodsOf } from '@kbn/utility-types';
import type { NewsfeedApiDriver } from './driver';

const createDriverMock = () => {
const mock: jest.Mocked<PublicMethodsOf<NewsfeedApiDriver>> = {
shouldFetch: jest.fn(),
fetchNewsfeedItems: jest.fn(),
};
return mock as jest.Mocked<NewsfeedApiDriver>;
};

export const driverMock = {
create: createDriverMock,
};

0 comments on commit 442c480

Please sign in to comment.