Skip to content

Commit

Permalink
API tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ashokaditya committed Nov 6, 2024
1 parent 486ad91 commit 31465b1
Show file tree
Hide file tree
Showing 5 changed files with 393 additions and 24 deletions.
79 changes: 79 additions & 0 deletions x-pack/plugins/data_usage/server/mocks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { loggingSystemMock, coreMock } from '@kbn/core/server/mocks';
import type { RouterMock } from '@kbn/core-http-router-server-mocks';
import type { AddVersionOpts, VersionedRouteConfig } from '@kbn/core-http-server';
import { DeepReadonly } from 'utility-types';
import {
PluginInitializerContext,
type RequestHandler,
type IRouter,
type RouteMethod,
} from '@kbn/core/server';
import { Observable } from 'rxjs';
import { DataUsageContext } from '../types';
import { DataUsageConfigType } from '../config';

export interface MockedDataUsageContext extends DataUsageContext {
logFactory: ReturnType<ReturnType<typeof loggingSystemMock.create>['get']>;
config$?: Observable<DataUsageConfigType>;
configInitialValue: DataUsageConfigType;
serverConfig: DeepReadonly<DataUsageConfigType>;
kibanaInstanceId: PluginInitializerContext['env']['instanceUuid'];
kibanaVersion: PluginInitializerContext['env']['packageInfo']['version'];
kibanaBranch: PluginInitializerContext['env']['packageInfo']['branch'];
}

export const createMockedDataUsageContext = (
context: PluginInitializerContext<DataUsageConfigType>
): MockedDataUsageContext => {
return {
logFactory: loggingSystemMock.create().get(),
config$: context.config.create<DataUsageConfigType>(),
configInitialValue: context.config.get(),
serverConfig: context.config.get(),
kibanaInstanceId: context.env.instanceUuid,
kibanaVersion: context.env.packageInfo.version,
kibanaBranch: context.env.packageInfo.branch,
};
};

export const createMockClients = () => {
const core = coreMock.createRequestHandlerContext();

return {
core,
};
};

type RouterMethod = Extract<keyof IRouter, RouteMethod>;

interface RegisteredVersionedRoute {
routeConfig: VersionedRouteConfig<RouterMethod>;
versionConfig: AddVersionOpts<any, any, any>;
routeHandler: RequestHandler<any, any, any, any, any>;
}
export const getRegisteredVersionedRouteMock = (
routerMock: RouterMock,
method: RouterMethod,
path: string,
version: string
): RegisteredVersionedRoute => {
const route = routerMock.versioned.getRoute(method, path);
const routeVersion = route.versions[version];

if (!routeVersion) {
throw new Error(`Handler for [${method}][${path}] with version [${version}] no found!`);
}

return {
routeConfig: route.config,
versionConfig: routeVersion.config,
routeHandler: routeVersion.handler,
};
};
105 changes: 105 additions & 0 deletions x-pack/plugins/data_usage/server/routes/internal/data_streams.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import type { MockedKeys } from '@kbn/utility-types-jest';
import type { CoreSetup } from '@kbn/core/server';
import { registerDataStreamsRoute } from './data_streams';
import { coreMock } from '@kbn/core/server/mocks';
import { httpServerMock } from '@kbn/core/server/mocks';
import { DataUsageService } from '../../services';
import type {
DataUsageRequestHandlerContext,
DataUsageRouter,
DataUsageServerStart,
} from '../../types';
import { DATA_USAGE_DATA_STREAMS_API_ROUTE } from '../../../common';
import { createMockedDataUsageContext } from '../../mocks';
import { getMeteringStats } from '../../utils/get_metering_stats';

jest.mock('../../utils/get_metering_stats');
const mockGetMeteringStats = getMeteringStats as jest.Mock;

describe('registerDataStreamsRoute', () => {
let mockCore: MockedKeys<CoreSetup<{}, DataUsageServerStart>>;
let router: DataUsageRouter;
let dataUsageService: DataUsageService;
let context: DataUsageRequestHandlerContext;

beforeEach(() => {
mockCore = coreMock.createSetup();
router = mockCore.http.createRouter();
context = coreMock.createCustomRequestHandlerContext(
coreMock.createRequestHandlerContext()
) as unknown as DataUsageRequestHandlerContext;

const mockedDataUsageContext = createMockedDataUsageContext(
coreMock.createPluginInitializerContext()
);
dataUsageService = new DataUsageService(mockedDataUsageContext);
registerDataStreamsRoute(router, dataUsageService);
});

it('should request correct API', () => {
expect(router.versioned.get).toHaveBeenCalledTimes(1);
expect(router.versioned.get).toHaveBeenCalledWith({
access: 'internal',
path: DATA_USAGE_DATA_STREAMS_API_ROUTE,
});
});

it('should correctly sort response', async () => {
mockGetMeteringStats.mockResolvedValue({
datastreams: [
{
name: 'datastream1',
size_in_bytes: 100,
},
{
name: 'datastream2',
size_in_bytes: 200,
},
],
});
const mockRequest = httpServerMock.createKibanaRequest({ body: {} });
const mockResponse = httpServerMock.createResponseFactory();
const mockRouter = mockCore.http.createRouter.mock.results[0].value;
const [[, handler]] = mockRouter.versioned.get.mock.results[0].value.addVersion.mock.calls;
await handler(context, mockRequest, mockResponse);

expect(mockResponse.ok).toHaveBeenCalledTimes(1);
expect(mockResponse.ok.mock.calls[0][0]).toEqual({
body: [
{
name: 'datastream2',
storageSizeBytes: 200,
},
{
name: 'datastream1',
storageSizeBytes: 100,
},
],
});
});

it.each([
['no datastreams', {}, []],
['empty array', { datastreams: [] }, []],
['an empty element', { datastreams: [{}] }, [{ name: undefined, storageSizeBytes: 0 }]],
])('should return empty array when no stats data with %s', async (_, stats, res) => {
mockGetMeteringStats.mockResolvedValue(stats);
const mockRequest = httpServerMock.createKibanaRequest({ body: {} });
const mockResponse = httpServerMock.createResponseFactory();
const mockRouter = mockCore.http.createRouter.mock.results[0].value;
const [[, handler]] = mockRouter.versioned.get.mock.results[0].value.addVersion.mock.calls;
await handler(context, mockRequest, mockResponse);

expect(mockResponse.ok).toHaveBeenCalledTimes(1);
expect(mockResponse.ok.mock.calls[0][0]).toEqual({
body: res,
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,11 @@
* 2.0.
*/

import { type ElasticsearchClient, RequestHandler } from '@kbn/core/server';
import { RequestHandler } from '@kbn/core/server';
import { DataUsageRequestHandlerContext } from '../../types';
import { errorHandler } from '../error_handler';
import { DataUsageService } from '../../services';

export interface MeteringStats {
name: string;
num_docs: number;
size_in_bytes: number;
}

interface MeteringStatsResponse {
datastreams: MeteringStats[];
}

const getMeteringStats = (client: ElasticsearchClient) => {
return client.transport.request<MeteringStatsResponse>({
method: 'GET',
path: '/_metering/stats',
});
};
import { getMeteringStats } from '../../utils/get_metering_stats';

export const getDataStreamsHandler = (
dataUsageService: DataUsageService
Expand All @@ -41,12 +25,15 @@ export const getDataStreamsHandler = (
core.elasticsearch.client.asSecondaryAuthUser
);

const body = meteringStats
.sort((a, b) => b.size_in_bytes - a.size_in_bytes)
.map((stat) => ({
name: stat.name,
storageSizeBytes: stat.size_in_bytes ?? 0,
}));
const body =
meteringStats && !!meteringStats.length
? meteringStats
.sort((a, b) => b.size_in_bytes - a.size_in_bytes)
.map((stat) => ({
name: stat.name,
storageSizeBytes: stat.size_in_bytes ?? 0,
}))
: [];

return response.ok({
body,
Expand Down
Loading

0 comments on commit 31465b1

Please sign in to comment.