Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[APM] Typescript fixes for rrr (WIP) #6

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,25 @@ import { createInitialDataSelector } from '../helpers';

describe('createInitialDataSelector', () => {
it('should use initialData when data is missing from state', () => {
const state = {};
const state = {} as any;
const initialData = { foo: 'bar' };
const withInitialData = createInitialDataSelector(initialData);

expect(withInitialData(state)).toBe(withInitialData(state));
expect(withInitialData(state, initialData)).toEqual({
expect(withInitialData(state)).toEqual({
args: [],
data: { foo: 'bar' }
});
});

it('should use data when available', () => {
const state = { data: 'hello' };
const state = { data: 'hello' } as any;
const initialData = { foo: 'bar' };
const withInitialData = createInitialDataSelector(initialData);

expect(withInitialData(state)).toBe(withInitialData(state));
expect(withInitialData(state, initialData)).toEqual({
expect(withInitialData(state)).toEqual({
args: [],
data: 'hello'
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,33 @@

import React from 'react';
import * as rest from '../../../services/rest/apm';
import { getServiceList, ServiceListRequest } from '../serviceList';
// @ts-ignore
import { mountWithStore } from '../../../utils/testHelpers';
import { getServiceList, ServiceListRequest } from '../serviceList';

describe('serviceList', () => {
describe('getServiceList', () => {
it('should return default value when empty', () => {
const state = { reactReduxRequest: {}, sorting: { service: {} } };
expect(getServiceList(state)).toEqual({ data: [] });
const state = { reactReduxRequest: {}, sorting: { service: {} } } as any;
expect(getServiceList(state)).toEqual({ args: [], data: [] });
});

it('should return serviceList when not empty', () => {
const state = {
reactReduxRequest: { serviceList: { data: [{ foo: 'bar' }] } },
sorting: { service: {} }
};
expect(getServiceList(state)).toEqual({ data: [{ foo: 'bar' }] });
} as any;
expect(getServiceList(state)).toEqual({
args: [],
data: [{ foo: 'bar' }]
});
});
});

describe('ServiceListRequest', () => {
let loadSpy;
let renderSpy;
let wrapper;
let loadSpy: jest.Mock;
let renderSpy: jest.Mock;
let wrapper: any;

beforeEach(() => {
const state = {
Expand All @@ -38,12 +42,12 @@ describe('serviceList', () => {
sorting: { service: {} }
};

loadSpy = jest.spyOn(rest, 'loadServiceList').mockReturnValue();
loadSpy = jest.spyOn(rest, 'loadServiceList').mockReturnValue(undefined);
renderSpy = jest.fn().mockReturnValue(<div>rendered</div>);

wrapper = mountWithStore(
<ServiceListRequest
urlParams={{ start: 'myStart', end: 'myEnd' }}
urlParams={{ start: 10, end: 1337 }}
render={renderSpy}
/>,
state
Expand All @@ -52,15 +56,16 @@ describe('serviceList', () => {

it('should call render method', () => {
expect(renderSpy).toHaveBeenCalledWith({
args: [],
data: [{ foo: 'bar' }],
status: 'my-status'
});
});

it('should call "loadServiceList"', () => {
expect(loadSpy).toHaveBeenCalledWith({
start: 'myStart',
end: 'myEnd'
start: 10,
end: 1337
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { RRRRenderResponse } from 'react-redux-request';
import { createSelector } from 'reselect';
import { get } from 'lodash';

export const createInitialDataSelector = initialData => {
export const createInitialDataSelector = <U>(initialData: U) => {
return createSelector(
state => state,
(state?: RRRRenderResponse<U>) => state,
state => {
return {
...state,
data: get(state, 'data') || initialData
status: state && state.status,
args: state && state.args ? state.args : [],
data: state && state.data ? state.data : initialData
};
}
);
Expand Down
21 changes: 13 additions & 8 deletions x-pack/plugins/apm/public/store/reactReduxRequest/serviceList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,27 @@
*/

import React from 'react';
import { Request, RRRRender, RRRRenderResponse } from 'react-redux-request';
import { IServiceListItem } from 'x-pack/plugins/apm/server/lib/services/get_services';
import {
Request,
RRRRender,
RRRRenderResponse,
RRRState
} from 'react-redux-request';
import {
IServiceListItem,
ServiceListAPIResponse
} from 'x-pack/plugins/apm/server/lib/services/get_services';
import { loadServiceList } from '../../services/rest/apm';
import { IReduxState } from '../rootReducer';
import { IUrlParams } from '../urlParams';
// @ts-ignore
import { createInitialDataSelector } from './helpers';

const ID = 'serviceList';
const INITIAL_DATA: IServiceListItem[] = [];
const withInitialData = createInitialDataSelector(INITIAL_DATA);

export function getServiceList(
state: IReduxState
state: RRRState<'serviceList', ServiceListAPIResponse>
): RRRRenderResponse<IServiceListItem[]> {
return withInitialData(state.reactReduxRequest[ID]);
return withInitialData(state.reactReduxRequest.serviceList);
}

export function ServiceListRequest({
Expand All @@ -38,7 +43,7 @@ export function ServiceListRequest({

return (
<Request
id={ID}
id="serviceList"
fn={loadServiceList}
args={[{ start, end, kuery }]}
selector={getServiceList}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,18 @@
*/

import React from 'react';
import { Request, RRRRender } from 'react-redux-request';
import { Transaction } from 'x-pack/plugins/apm/typings/Transaction';
import { Request, RRRRender, RRRState } from 'react-redux-request';
import { TransactionAPIResponse } from 'x-pack/plugins/apm/server/lib/transactions/get_transaction';
import { loadTransaction } from '../../services/rest/apm';
import { IReduxState } from '../rootReducer';
import { IUrlParams } from '../urlParams';
// @ts-ignore
import { createInitialDataSelector } from './helpers';

const ID = 'transactionDetails';
export function getTransactionDetails(state: IReduxState) {
return state.reactReduxRequest[ID];
}

const defaultResponse = { data: undefined };
export function TransactionDetailsRequest({
urlParams,
render
}: {
urlParams: IUrlParams;
render: RRRRender<Transaction | null>;
render: RRRRender<TransactionAPIResponse | undefined>;
}) {
const { serviceName, start, end, transactionId, traceId, kuery } = urlParams;

Expand All @@ -33,9 +26,11 @@ export function TransactionDetailsRequest({

return (
<Request
id={ID}
id="transactionDetails"
fn={loadTransaction}
selector={getTransactionDetails}
selector={(
state: RRRState<'transactionDetails', TransactionAPIResponse>
) => state.reactReduxRequest.transactionDetails || defaultResponse}
args={[{ serviceName, start, end, transactionId, traceId, kuery }]}
render={render}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,28 @@
*/

import React from 'react';
import { Request, RRRRender } from 'react-redux-request';
import { Request, RRRRender, RRRState } from 'react-redux-request';
import { createSelector } from 'reselect';
import { TimeSeriesAPIResponse } from 'x-pack/plugins/apm/server/lib/transactions/charts';
import { loadCharts } from '../../services/rest/apm';
import { IReduxState } from '../rootReducer';
import { getCharts } from '../selectors/chartSelectors';
import { getCharts, ICharts } from '../selectors/chartSelectors';
import { getUrlParams, IUrlParams } from '../urlParams';

const ID = 'transactionDetailsCharts';
const INITIAL_DATA: TimeSeriesAPIResponse = {
apmTimeseries: {
totalHits: 0,
responseTimes: {
avg: [],
p95: [],
p99: []
},
tpmBuckets: [],
overallAvgDuration: undefined
},
anomalyTimeseries: undefined
};

export const getTransactionDetailsCharts = createSelector(
getUrlParams,
(state: IReduxState) => state.reactReduxRequest[ID],
(urlParams, detailCharts = {}) => {
getUrlParams as any,
(state: RRRState<'transactionDetailsCharts', TimeSeriesAPIResponse>) =>
state.reactReduxRequest.transactionDetailsCharts,
(urlParams: IUrlParams, detailCharts = {} as any) => {
return {
...detailCharts,
data: getCharts(urlParams, detailCharts.data || INITIAL_DATA)
data: getCharts(urlParams, detailCharts.data)
};
}
);

interface Props {
urlParams: IUrlParams;
render: RRRRender<TimeSeriesAPIResponse>;
render: RRRRender<ICharts>;
}

export function TransactionDetailsChartsRequest({ urlParams, render }: Props) {
Expand All @@ -60,7 +45,7 @@ export function TransactionDetailsChartsRequest({ urlParams, render }: Props) {

return (
<Request
id={ID}
id="transactionDetailsCharts"
fn={loadCharts}
args={[
{ serviceName, start, end, transactionType, transactionName, kuery }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,43 @@
*/

import React from 'react';
import { Request, RRRRender, RRRRenderResponse } from 'react-redux-request';
import {
Request,
RRRRender,
RRRRenderResponse,
RRRState
} from 'react-redux-request';
import { ITransactionDistributionAPIResponse } from 'x-pack/plugins/apm/server/lib/transactions/distribution';
import { loadTransactionDistribution } from '../../services/rest/apm';
import { IReduxState } from '../rootReducer';
import { IUrlParams } from '../urlParams';
// @ts-ignore
import { createInitialDataSelector } from './helpers';

const ID = 'transactionDistribution';
const INITIAL_DATA = { buckets: [], totalHits: 0 };
const withInitialData = createInitialDataSelector(INITIAL_DATA);
type IState = RRRState<
'transactionDistribution',
ITransactionDistributionAPIResponse
>;

const INITIAL_DATA: ITransactionDistributionAPIResponse = {
buckets: [],
bucketSize: 0,
totalHits: 0
};

const withInitialData = createInitialDataSelector(INITIAL_DATA);
export function getTransactionDistribution(
state: IReduxState
state: IState
): RRRRenderResponse<ITransactionDistributionAPIResponse> {
return withInitialData(state.reactReduxRequest[ID]);
return withInitialData(state.reactReduxRequest.transactionDistribution);
}

export function getDefaultDistributionSample(state: IReduxState) {
export function getDefaultDistributionSample(state: IState) {
const distribution = getTransactionDistribution(state);
const { defaultSample = {} } = distribution.data;
return {
traceId: defaultSample.traceId,
transactionId: defaultSample.transactionId
};
if (distribution.data.defaultSample !== undefined) {
const { traceId, transactionId } = distribution.data.defaultSample;
return { traceId, transactionId };
}

return {};
}

export function TransactionDistributionRequest({
Expand All @@ -47,7 +59,7 @@ export function TransactionDistributionRequest({

return (
<Request
id={ID}
id="transactionDistribution"
fn={loadTransactionDistribution}
args={[{ serviceName, start, end, transactionName, kuery }]}
selector={getTransactionDistribution}
Expand Down
Loading