Skip to content

Commit

Permalink
add support for sorting benchmark page
Browse files Browse the repository at this point in the history
  • Loading branch information
CohenIdo committed Mar 9, 2022
1 parent b76370d commit 453cab5
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,48 @@ describe('benchmarks API', () => {
});
});

it('should throw when sort_field is not string', async () => {
expect(() => {
benchmarksInputSchema.validate({ sort_field: true });
}).toThrow();
});

it('should not throw when sort_field is a string', async () => {
expect(() => {
benchmarksInputSchema.validate({ sort_field: 'field1' });
}).not.toThrow();
});

it('should throw when sort_order is not `asc` or `desc`', async () => {
expect(() => {
benchmarksInputSchema.validate({ sort_order: 'Other Direction' });
}).toThrow();
});

it('should not throw when `asc` is input for sort_order field', async () => {
expect(() => {
benchmarksInputSchema.validate({ sort_order: 'asc' });
}).not.toThrow();
});

it('should not throw when `desc` is input for sort_order field', async () => {
expect(() => {
benchmarksInputSchema.validate({ sort_order: 'desc' });
}).not.toThrow();
});

it('should throw when fields is not string', async () => {
expect(() => {
benchmarksInputSchema.validate({ fields: ['field1', 'field2'] });
}).toThrow();
});

it('should not throw when fields is a string', async () => {
expect(() => {
benchmarksInputSchema.validate({ sort_field: 'field1, field2' });
}).not.toThrow();
});

describe('test benchmarks utils', () => {
let mockSoClient: jest.Mocked<SavedObjectsClientContract>;

Expand All @@ -109,19 +151,73 @@ describe('benchmarks API', () => {
});

describe('test getPackagePolicies', () => {
it('should throw when agentPolicyService is undefined', async () => {
const mockAgentPolicyService = undefined;
expect(
getPackagePolicies(mockSoClient, mockAgentPolicyService, 'myPackage', {
page: 1,
per_page: 100,
sort_order: 'desc',
})
).rejects.toThrow();
});

it('should format request by package name', async () => {
const mockPackagePolicyService = createPackagePolicyServiceMock();

await getPackagePolicies(mockSoClient, mockPackagePolicyService, 'myPackage', {
page: 1,
per_page: 100,
sort_order: 'desc',
});

expect(mockAgentPolicyService.list.mock.calls[0][1]).toMatchObject(
expect.objectContaining({
kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:myPackage`,
page: 1,
perPage: 100,
})
);
});

it('should build sort request by `sort_field` and default `sort_order`', async () => {
const mockAgentPolicyService = createPackagePolicyServiceMock();

await getPackagePolicies(mockSoClient, mockAgentPolicyService, 'myPackage', {
page: 1,
per_page: 100,
sort_field: 'name',
sort_order: 'desc',
});

expect(mockAgentPolicyService.list.mock.calls[0][1]).toMatchObject(
expect.objectContaining({
kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:myPackage`,
page: 1,
perPage: 100,
sortField: 'name',
sortOrder: 'desc',
})
);
});

it('should build sort request by `sort_field` and asc `sort_order`', async () => {
const mockAgentPolicyService = createPackagePolicyServiceMock();

await getPackagePolicies(mockSoClient, mockAgentPolicyService, 'myPackage', {
page: 1,
per_page: 100,
sort_field: 'name',
sort_order: 'asc',
});

expect(mockPackagePolicyService.list.mock.calls[0][1]).toMatchObject(
expect.objectContaining({
kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:myPackage`,
page: 1,
perPage: 100,
sortField: 'name',
sortOrder: 'asc',
})
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@ import {
AgentPolicyServiceInterface,
AgentService,
} from '../../../../fleet/server';
import { GetAgentPoliciesResponseItem, PackagePolicy, AgentPolicy } from '../../../../fleet/common';
import {
GetAgentPoliciesResponseItem,
PackagePolicy,
AgentPolicy,
ListWithKuery,
} from '../../../../fleet/common';
import { BENCHMARKS_ROUTE_PATH, CIS_KUBERNETES_PACKAGE_NAME } from '../../../common/constants';
import { CspAppContext } from '../../plugin';

// TODO: use the same method from common/ once PR 106 is merged
export const isNonNullable = <T extends unknown>(v: T): v is NonNullable<T> =>
v !== null && v !== undefined;

Expand Down Expand Up @@ -52,6 +56,18 @@ const getPackageNameQuery = (packageName: string, benchmarkFilter?: string): str
return kquery;
};

const addSortToQuery = (
baseQuery: ListWithKuery,
queryParams: BenchmarksQuerySchema
): ListWithKuery =>
queryParams.sort_field
? {
...baseQuery,
sortField: queryParams.sort_field,
sortOrder: queryParams.sort_order,
}
: baseQuery;

export const getPackagePolicies = async (
soClient: SavedObjectsClientContract,
packagePolicyService: PackagePolicyServiceInterface,
Expand All @@ -64,11 +80,17 @@ export const getPackagePolicies = async (

const packageNameQuery = getPackageNameQuery(packageName, queryParams.benchmark_name);

const { items: packagePolicies } = (await packagePolicyService?.list(soClient, {
const baseQuery = {
kuery: packageNameQuery,
page: queryParams.page,
perPage: queryParams.per_page,
})) ?? { items: [] as PackagePolicy[] };
};

const query = addSortToQuery(baseQuery, queryParams);

const { items: packagePolicies } = (await packagePolicyService?.list(soClient, query)) ?? {
items: [] as PackagePolicy[],
};

return packagePolicies;
};
Expand Down Expand Up @@ -197,6 +219,14 @@ export const benchmarksInputSchema = rt.object({
* The number of objects to include in each page
*/
per_page: rt.number({ defaultValue: DEFAULT_BENCHMARKS_PER_PAGE, min: 0 }),
/**
* The field to use for sorting the found objects.
*/
sort_field: rt.maybe(rt.string()),
/**
* The order to sort by
*/
sort_order: rt.oneOf([rt.literal('asc'), rt.literal('desc')], { defaultValue: 'desc' }),
/**
* Benchmark filter
*/
Expand Down

0 comments on commit 453cab5

Please sign in to comment.