[Synthetics] Perform params API HTTP migration (#160575)

Co-authored-by: shahzad31 <shahzad31comp@gmail.com>
This commit is contained in:
Justin Kambic 2023-07-04 13:55:05 -04:00 committed by GitHub
parent cd04cd305a
commit 6731eb3008
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 222 additions and 157 deletions

View file

@ -7,10 +7,10 @@
import * as t from 'io-ts';
export const SyntheticsParamSOCodec = t.intersection([
export const SyntheticsParamsReadonlyCodec = t.intersection([
t.interface({
id: t.string,
key: t.string,
value: t.string,
}),
t.partial({
description: t.string,
@ -19,7 +19,23 @@ export const SyntheticsParamSOCodec = t.intersection([
}),
]);
export type SyntheticsParamSO = t.TypeOf<typeof SyntheticsParamSOCodec>;
export type SyntheticsParamsReadonly = t.TypeOf<typeof SyntheticsParamsReadonlyCodec>;
export const SyntheticsParamsCodec = t.intersection([
SyntheticsParamsReadonlyCodec,
t.interface({ value: t.string }),
]);
export type SyntheticsParams = t.TypeOf<typeof SyntheticsParamsCodec>;
export type SyntheticsParamSOAttributes = t.TypeOf<typeof SyntheticsParamsCodec>;
export const DeleteParamsResponseCodec = t.interface({
id: t.string,
deleted: t.boolean,
});
export type DeleteParamsResponse = t.TypeOf<typeof DeleteParamsResponseCodec>;
export const SyntheticsParamRequestCodec = t.intersection([
t.interface({

View file

@ -31,7 +31,7 @@ import {
} from '../../../state/global_params';
import { ClientPluginsStart } from '../../../../../plugin';
import { ListParamItem } from './params_list';
import { SyntheticsParamSO } from '../../../../../../common/runtime_types';
import { SyntheticsParams } from '../../../../../../common/runtime_types';
import { useFormWrapped } from '../../../../../hooks/use_form_wrapped';
import { AddParamForm } from './add_param_form';
import { syncGlobalParamsAction } from '../../../state/settings';
@ -49,7 +49,7 @@ export const AddParamFlyout = ({
const { id, ...dataToSave } = isEditingItem ?? {};
const form = useFormWrapped<SyntheticsParamSO>({
const form = useFormWrapped<SyntheticsParams>({
mode: 'onSubmit',
reValidateMode: 'onChange',
shouldFocusError: true,
@ -77,7 +77,7 @@ export const AddParamFlyout = ({
const { isSaving, savedData } = useSelector(selectGlobalParamState);
const onSubmit = (formData: SyntheticsParamSO) => {
const onSubmit = (formData: SyntheticsParams) => {
const { namespaces, ...paramRequest } = formData;
const shareAcrossSpaces = namespaces?.includes(ALL_SPACES_ID);

View file

@ -16,7 +16,7 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { Controller, useFormContext, useFormState } from 'react-hook-form';
import { SyntheticsParamSO } from '../../../../../../common/runtime_types';
import { SyntheticsParams } from '../../../../../../common/runtime_types';
import { ListParamItem } from './params_list';
export const AddParamForm = ({
@ -26,8 +26,8 @@ export const AddParamForm = ({
items: ListParamItem[];
isEditingItem: ListParamItem | null;
}) => {
const { register, control } = useFormContext<SyntheticsParamSO>();
const { errors } = useFormState<SyntheticsParamSO>();
const { register, control } = useFormContext<SyntheticsParams>();
const { errors } = useFormState<SyntheticsParams>();
const tagsList = items.reduce((acc, item) => {
const tags = item.tags || [];

View file

@ -35,14 +35,14 @@ export const DeleteParam = ({
const { status } = useFetcher(() => {
if (isDeleting) {
return deleteGlobalParams({ ids: items.map(({ id }) => id) });
return deleteGlobalParams(items.map(({ id }) => id));
}
}, [items, isDeleting]);
const name = items
.map(({ key }) => key)
.join(', ')
.substr(0, 50);
.slice(0, 50);
useEffect(() => {
if (!isDeleting) {

View file

@ -24,12 +24,12 @@ import { EuiBasicTableColumn } from '@elastic/eui/src/components/basic_table/bas
import { useDebounce } from 'react-use';
import { TableTitle } from '../../common/components/table_title';
import { ParamsText } from './params_text';
import { SyntheticsParamSO } from '../../../../../../common/runtime_types';
import { SyntheticsParams } from '../../../../../../common/runtime_types';
import { useParamsList } from '../hooks/use_params_list';
import { AddParamFlyout } from './add_param_flyout';
import { DeleteParam } from './delete_param';
export interface ListParamItem extends SyntheticsParamSO {
export interface ListParamItem extends SyntheticsParams {
id: string;
}

View file

@ -20,12 +20,7 @@ export const useParamsList = () => {
return useMemo(() => {
return {
items:
listOfParams?.map((item) => ({
id: item.id,
...item.attributes,
namespaces: item.namespaces,
})) ?? [],
items: listOfParams ?? [],
isLoading,
};
}, [listOfParams, isLoading]);

View file

@ -6,7 +6,7 @@
*/
import { createReducer } from '@reduxjs/toolkit';
import { CertResult, SyntheticsParamSO } from '../../../../../common/runtime_types';
import { CertResult, SyntheticsParams } from '../../../../../common/runtime_types';
import { IHttpSerializedFetchError } from '..';
import { getCertsListAction } from './actions';
@ -15,7 +15,7 @@ export interface CertsListState {
data?: CertResult;
error: IHttpSerializedFetchError | null;
isSaving?: boolean;
savedData?: SyntheticsParamSO;
savedData?: SyntheticsParams;
}
const initialState: CertsListState = {

View file

@ -5,15 +5,14 @@
* 2.0.
*/
import { SavedObject } from '@kbn/core-saved-objects-common';
import { SyntheticsParamRequest, SyntheticsParamSO } from '../../../../../common/runtime_types';
import { SyntheticsParamRequest, SyntheticsParams } from '../../../../../common/runtime_types';
import { createAsyncAction } from '../utils/actions';
export const getGlobalParamAction = createAsyncAction<void, Array<SavedObject<SyntheticsParamSO>>>(
export const getGlobalParamAction = createAsyncAction<void, SyntheticsParams[]>(
'GET GLOBAL PARAMS'
);
export const addNewGlobalParamAction = createAsyncAction<SyntheticsParamRequest, SyntheticsParamSO>(
export const addNewGlobalParamAction = createAsyncAction<SyntheticsParamRequest, SyntheticsParams>(
'ADD NEW GLOBAL PARAM'
);
@ -22,5 +21,5 @@ export const editGlobalParamAction = createAsyncAction<
id: string;
paramRequest: SyntheticsParamRequest;
},
SyntheticsParamSO
SyntheticsParams
>('EDIT GLOBAL PARAM');

View file

@ -5,23 +5,28 @@
* 2.0.
*/
import { SavedObject } from '@kbn/core-saved-objects-common';
import { SYNTHETICS_API_URLS } from '../../../../../common/constants';
import { SyntheticsParamRequest, SyntheticsParamSO } from '../../../../../common/runtime_types';
import {
DeleteParamsResponse,
SyntheticsParamRequest,
SyntheticsParams,
SyntheticsParamsCodec,
SyntheticsParamsReadonlyCodec,
} from '../../../../../common/runtime_types';
import { apiService } from '../../../../utils/api_service/api_service';
export const getGlobalParams = async (): Promise<Array<SavedObject<SyntheticsParamSO>>> => {
const result = (await apiService.get(SYNTHETICS_API_URLS.PARAMS)) as {
data: Array<SavedObject<SyntheticsParamSO>>;
};
return result.data;
export const getGlobalParams = async (): Promise<SyntheticsParams[]> => {
return apiService.get<SyntheticsParams[]>(
SYNTHETICS_API_URLS.PARAMS,
undefined,
SyntheticsParamsReadonlyCodec
);
};
export const addGlobalParam = async (
paramRequest: SyntheticsParamRequest
): Promise<SyntheticsParamSO> => {
return apiService.post(SYNTHETICS_API_URLS.PARAMS, paramRequest);
};
): Promise<SyntheticsParams> =>
apiService.post(SYNTHETICS_API_URLS.PARAMS, paramRequest, SyntheticsParamsCodec);
export const editGlobalParam = async ({
paramRequest,
@ -29,19 +34,17 @@ export const editGlobalParam = async ({
}: {
id: string;
paramRequest: SyntheticsParamRequest;
}): Promise<SyntheticsParamSO> => {
return apiService.put(SYNTHETICS_API_URLS.PARAMS, {
id,
...paramRequest,
});
};
}): Promise<SyntheticsParams> =>
apiService.put<SyntheticsParams>(
SYNTHETICS_API_URLS.PARAMS,
{
id,
...paramRequest,
},
SyntheticsParamsCodec
);
export const deleteGlobalParams = async ({
ids,
}: {
ids: string[];
}): Promise<SyntheticsParamSO> => {
return apiService.delete(SYNTHETICS_API_URLS.PARAMS, {
export const deleteGlobalParams = async (ids: string[]): Promise<DeleteParamsResponse[]> =>
apiService.delete(SYNTHETICS_API_URLS.PARAMS, {
ids: JSON.stringify(ids),
});
};

View file

@ -6,18 +6,17 @@
*/
import { createReducer } from '@reduxjs/toolkit';
import { SavedObject } from '@kbn/core-saved-objects-common';
import { SyntheticsParamSO } from '../../../../../common/runtime_types';
import { SyntheticsParams } from '../../../../../common/runtime_types';
import { IHttpSerializedFetchError } from '..';
import { addNewGlobalParamAction, editGlobalParamAction, getGlobalParamAction } from './actions';
export interface GlobalParamsState {
isLoading?: boolean;
listOfParams?: Array<SavedObject<SyntheticsParamSO>>;
listOfParams?: SyntheticsParams[];
addError: IHttpSerializedFetchError | null;
editError: IHttpSerializedFetchError | null;
isSaving?: boolean;
savedData?: SyntheticsParamSO;
savedData?: SyntheticsParams;
}
const initialState: GlobalParamsState = {

View file

@ -41,20 +41,7 @@ class ApiService {
return ApiService.instance;
}
public async get<T>(
apiUrl: string,
params?: HttpFetchQuery,
decodeType?: any,
asResponse = false
) {
const response = await this._http!.fetch<T>({
path: apiUrl,
query: params,
asResponse,
});
this.addInspectorRequest?.({ data: response, status: FETCH_STATUS.SUCCESS, loading: false });
private parseResponse<T>(response: Awaited<T>, apiUrl: string, decodeType?: any): T {
if (decodeType) {
const decoded = decodeType.decode(response);
if (isRight(decoded)) {
@ -69,10 +56,26 @@ class ApiService {
);
}
}
return response;
}
public async get<T>(
apiUrl: string,
params?: HttpFetchQuery,
decodeType?: any,
asResponse = false
) {
const response = await this._http!.fetch<T>({
path: apiUrl,
query: params,
asResponse,
});
this.addInspectorRequest?.({ data: response, status: FETCH_STATUS.SUCCESS, loading: false });
return this.parseResponse(response, apiUrl, decodeType);
}
public async post<T>(apiUrl: string, data?: any, decodeType?: any, params?: HttpFetchQuery) {
const response = await this._http!.post<T>(apiUrl, {
method: 'POST',
@ -82,18 +85,7 @@ class ApiService {
this.addInspectorRequest?.({ data: response, status: FETCH_STATUS.SUCCESS, loading: false });
if (decodeType) {
const decoded = decodeType.decode(response);
if (isRight(decoded)) {
return decoded.right as T;
} else {
// eslint-disable-next-line no-console
console.warn(
`API ${apiUrl} is not returning expected response, ${formatErrors(decoded.left)}`
);
}
}
return response;
return this.parseResponse(response, apiUrl, decodeType);
}
public async put<T>(apiUrl: string, data?: any, decodeType?: any) {
@ -102,18 +94,7 @@ class ApiService {
body: JSON.stringify(data),
});
if (decodeType) {
const decoded = decodeType.decode(response);
if (isRight(decoded)) {
return decoded.right as T;
} else {
// eslint-disable-next-line no-console
console.warn(
`API ${apiUrl} is not returning expected response, ${formatErrors(decoded.left)}`
);
}
}
return response;
return this.parseResponse(response, apiUrl, decodeType);
}
public async delete<T>(apiUrl: string, params?: HttpFetchQuery) {

View file

@ -8,8 +8,13 @@
import { schema } from '@kbn/config-schema';
import { ALL_SPACES_ID } from '@kbn/security-plugin/common/constants';
import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common';
import { IKibanaResponse } from '@kbn/core/server';
import { SyntheticsRestApiRouteFactory } from '../types';
import { SyntheticsParamRequest, SyntheticsParamSO } from '../../../common/runtime_types';
import {
SyntheticsParamRequest,
SyntheticsParams,
SyntheticsParamSOAttributes,
} from '../../../common/runtime_types';
import { syntheticsParamType } from '../../../common/types/saved_objects';
import { SYNTHETICS_API_URLS } from '../../../common/constants';
@ -26,7 +31,12 @@ export const addSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({
}),
},
writeAccess: true,
handler: async ({ request, response, server, savedObjectsClient }): Promise<any> => {
handler: async ({
request,
response,
server,
savedObjectsClient,
}): Promise<IKibanaResponse<SyntheticsParams>> => {
try {
const { id: spaceId } = (await server.spaces?.spacesService.getActiveSpace(request)) ?? {
id: DEFAULT_SPACE_ID,
@ -34,14 +44,33 @@ export const addSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({
const { share_across_spaces: shareAcrossSpaces, ...data } =
request.body as SyntheticsParamRequest;
const result = await savedObjectsClient.create<SyntheticsParamSO>(syntheticsParamType, data, {
initialNamespaces: shareAcrossSpaces ? [ALL_SPACES_ID] : [spaceId],
const {
attributes: { key, tags, description },
id,
namespaces,
} = await savedObjectsClient.create<Omit<SyntheticsParamSOAttributes, 'id'>>(
syntheticsParamType,
data,
{
initialNamespaces: shareAcrossSpaces ? [ALL_SPACES_ID] : [spaceId],
}
);
return response.ok({
body: {
id,
description,
key,
namespaces,
tags,
value: data.value,
},
});
return { data: result };
} catch (error) {
if (error.output?.statusCode === 404) {
const spaceId = server.spaces?.spacesService.getSpaceId(request) ?? DEFAULT_SPACE_ID;
return response.notFound({ body: { message: `Kibana space '${spaceId}' does not exist` } });
return response.notFound({
body: { message: `Kibana space '${spaceId}' does not exist` },
});
}
throw error;

View file

@ -5,10 +5,12 @@
* 2.0.
*/
import { IKibanaResponse } from '@kbn/core/server';
import { schema } from '@kbn/config-schema';
import { SyntheticsRestApiRouteFactory } from '../types';
import { syntheticsParamType } from '../../../common/types/saved_objects';
import { SYNTHETICS_API_URLS } from '../../../common/constants';
import { DeleteParamsResponse } from '../../../common/runtime_types';
export const deleteSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({
method: 'DELETE',
@ -19,7 +21,11 @@ export const deleteSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () =>
}),
},
writeAccess: true,
handler: async ({ savedObjectsClient, request }): Promise<any> => {
handler: async ({
savedObjectsClient,
request,
response,
}): Promise<IKibanaResponse<DeleteParamsResponse[]>> => {
const { ids } = request.query as { ids: string };
const parsedIds = JSON.parse(ids) as string[];
@ -27,7 +33,8 @@ export const deleteSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () =>
parsedIds.map((id) => ({ type: syntheticsParamType, id })),
{ force: true }
);
return { data: result };
return response.ok({
body: result.statuses.map(({ id, success }) => ({ id, deleted: success })),
});
},
});

View file

@ -6,9 +6,10 @@
*/
import { schema } from '@kbn/config-schema';
import { IKibanaResponse, SavedObject } from '@kbn/core/server';
import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common';
import { SyntheticsRestApiRouteFactory } from '../types';
import { SyntheticsParamRequest } from '../../../common/runtime_types';
import { SyntheticsParamRequest, SyntheticsParams } from '../../../common/runtime_types';
import { syntheticsParamType } from '../../../common/types/saved_objects';
import { SYNTHETICS_API_URLS } from '../../../common/constants';
@ -26,7 +27,12 @@ export const editSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({
}),
},
writeAccess: true,
handler: async ({ savedObjectsClient, request, response, server }): Promise<any> => {
handler: async ({
savedObjectsClient,
request,
response,
server,
}): Promise<IKibanaResponse<SyntheticsParams>> => {
try {
const { id: _spaceId } = (await server.spaces?.spacesService.getActiveSpace(request)) ?? {
id: DEFAULT_SPACE_ID,
@ -39,9 +45,18 @@ export const editSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({
id: string;
};
const result = await savedObjectsClient.update(syntheticsParamType, id, data);
const { value } = data;
const {
id: responseId,
attributes: { key, tags, description },
namespaces,
} = (await savedObjectsClient.update(
syntheticsParamType,
id,
data
)) as SavedObject<SyntheticsParams>;
return { data: result };
return response.ok({ body: { id: responseId, key, tags, description, namespaces, value } });
} catch (error) {
if (error.output?.statusCode === 404) {
const spaceId = server.spaces?.spacesService.getSpaceId(request) ?? DEFAULT_SPACE_ID;

View file

@ -5,52 +5,66 @@
* 2.0.
*/
import { IKibanaResponse } from '@kbn/core/server';
import { SavedObjectsFindResult } from '@kbn/core-saved-objects-api-server';
import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common';
import { SyntheticsRestApiRouteFactory } from '../types';
import { syntheticsParamType } from '../../../common/types/saved_objects';
import { SYNTHETICS_API_URLS } from '../../../common/constants';
import { SyntheticsParams, SyntheticsParamsReadonly } from '../../../common/runtime_types';
export const getSyntheticsParamsRoute: SyntheticsRestApiRouteFactory = () => ({
type SyntheticsParamsResponse =
| IKibanaResponse<SyntheticsParams[]>
| IKibanaResponse<SyntheticsParamsReadonly[]>;
export const getSyntheticsParamsRoute: SyntheticsRestApiRouteFactory<
SyntheticsParamsResponse
> = () => ({
method: 'GET',
path: SYNTHETICS_API_URLS.PARAMS,
validate: {},
handler: async ({ savedObjectsClient, request, response, server }): Promise<any> => {
handler: async ({ savedObjectsClient, request, response, server, spaceId }) => {
try {
const encryptedSavedObjectsClient = server.encryptedSavedObjects.getClient();
const { id: spaceId } = (await server.spaces?.spacesService.getActiveSpace(request)) ?? {
id: DEFAULT_SPACE_ID,
};
const canSave =
(await server.coreStart?.capabilities.resolveCapabilities(request)).uptime.save ?? false;
if (canSave) {
const finder =
await encryptedSavedObjectsClient.createPointInTimeFinderDecryptedAsInternalUser({
type: syntheticsParamType,
perPage: 1000,
namespaces: [spaceId],
});
await encryptedSavedObjectsClient.createPointInTimeFinderDecryptedAsInternalUser<SyntheticsParams>(
{
type: syntheticsParamType,
perPage: 1000,
namespaces: [spaceId],
}
);
const hits: SavedObjectsFindResult[] = [];
const hits: Array<SavedObjectsFindResult<SyntheticsParams>> = [];
for await (const result of finder.find()) {
hits.push(...result.saved_objects);
}
return { data: hits };
return response.ok({
body: hits.map(({ id, attributes, namespaces }) => ({
...attributes,
id,
namespaces,
})),
});
} else {
const data = await savedObjectsClient.find({
const data = await savedObjectsClient.find<SyntheticsParamsReadonly>({
type: syntheticsParamType,
perPage: 10000,
});
return { data: data.saved_objects };
return response.ok({
body: data.saved_objects.map(({ id, attributes, namespaces }) => ({
...attributes,
namespaces,
id,
})),
});
}
} catch (error) {
if (error.output?.statusCode === 404) {
const spaceId = server.spaces?.spacesService.getSpaceId(request) ?? DEFAULT_SPACE_ID;
return response.notFound({ body: { message: `Kibana space '${spaceId}' does not exist` } });
}

View file

@ -36,7 +36,7 @@ import {
ServiceLocations,
SyntheticsMonitorWithId,
SyntheticsMonitorWithSecrets,
SyntheticsParamSO,
SyntheticsParams,
ThrottlingOptions,
} from '../../common/runtime_types';
import { getServiceLocations } from './get_service_locations';
@ -599,7 +599,7 @@ export class SyntheticsService {
const paramsBySpace: Record<string, Record<string, string>> = Object.create(null);
const finder =
await encryptedClient.createPointInTimeFinderDecryptedAsInternalUser<SyntheticsParamSO>({
await encryptedClient.createPointInTimeFinderDecryptedAsInternalUser<SyntheticsParams>({
type: syntheticsParamType,
perPage: 1000,
namespaces: spaceId ? [spaceId] : undefined,

View file

@ -4,13 +4,19 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { v4 as uuidv4 } from 'uuid';
import { pick } from 'lodash';
import { SYNTHETICS_API_URLS } from '@kbn/synthetics-plugin/common/constants';
import expect from '@kbn/expect';
import { syntheticsParamType } from '@kbn/synthetics-plugin/common/types/saved_objects';
import { FtrProviderContext } from '../../ftr_provider_context';
import { PrivateLocationTestService } from './services/private_location_test_service';
function assertHas(actual: unknown, expected: object) {
expect(pick(actual, Object.keys(expected))).eql(expected);
}
export default function ({ getService }: FtrProviderContext) {
describe('AddEditParams', function () {
this.tags('skipCloud');
@ -40,7 +46,7 @@ export default function ({ getService }: FtrProviderContext) {
.set('kbn-xsrf', 'true')
.expect(200);
expect(getResponse.body.data[0].attributes).eql(testParam);
assertHas(getResponse.body[0], testParam);
});
it('handles tags and description', async () => {
@ -63,11 +69,11 @@ export default function ({ getService }: FtrProviderContext) {
.set('kbn-xsrf', 'true')
.expect(200);
expect(getResponse.body.data[0].attributes).eql(testParam2);
assertHas(getResponse.body[0], testParam2);
});
it('handles editing a param', async () => {
const updatedParam = {
const expectedUpdatedParam = {
key: 'testUpdated',
value: 'testUpdated',
tags: ['a tag'],
@ -84,21 +90,21 @@ export default function ({ getService }: FtrProviderContext) {
.get(SYNTHETICS_API_URLS.PARAMS)
.set('kbn-xsrf', 'true')
.expect(200);
const param = getResponse.body.data[0];
expect(param.attributes).eql(testParam);
const param = getResponse.body[0];
assertHas(param, testParam);
await supertestAPI
.put(SYNTHETICS_API_URLS.PARAMS)
.set('kbn-xsrf', 'true')
.send({ ...updatedParam, id: param.id })
.send({ ...expectedUpdatedParam, id: param.id })
.expect(200);
const updatedGetResponse = await supertestAPI
.get(SYNTHETICS_API_URLS.PARAMS)
.set('kbn-xsrf', 'true')
.expect(200);
const updatedParamSO = updatedGetResponse.body.data[0];
expect(updatedParamSO.attributes).eql(updatedParam);
const actualUpdatedParam = updatedGetResponse.body[0];
assertHas(actualUpdatedParam, expectedUpdatedParam);
});
it('handles spaces', async () => {
@ -118,8 +124,8 @@ export default function ({ getService }: FtrProviderContext) {
.set('kbn-xsrf', 'true')
.expect(200);
expect(getResponse.body.data[0].namespaces).eql([SPACE_ID]);
expect(getResponse.body.data[0].attributes).eql(testParam);
expect(getResponse.body[0].namespaces).eql([SPACE_ID]);
assertHas(getResponse.body[0], testParam);
});
it('handles editing a param in spaces', async () => {
@ -128,7 +134,7 @@ export default function ({ getService }: FtrProviderContext) {
await kServer.spaces.create({ id: SPACE_ID, name: SPACE_NAME });
const updatedParam = {
const expectedUpdatedParam = {
key: 'testUpdated',
value: 'testUpdated',
tags: ['a tag'],
@ -145,21 +151,21 @@ export default function ({ getService }: FtrProviderContext) {
.get(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`)
.set('kbn-xsrf', 'true')
.expect(200);
const param = getResponse.body.data[0];
expect(param.attributes).eql(testParam);
const param = getResponse.body[0];
assertHas(param, testParam);
await supertestAPI
.put(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`)
.set('kbn-xsrf', 'true')
.send({ ...updatedParam, id: param.id })
.send({ ...expectedUpdatedParam, id: param.id })
.expect(200);
const updatedGetResponse = await supertestAPI
.get(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`)
.set('kbn-xsrf', 'true')
.expect(200);
const updatedParamSO = updatedGetResponse.body.data[0];
expect(updatedParamSO.attributes).eql(updatedParam);
const actualUpdatedParam = updatedGetResponse.body[0];
assertHas(actualUpdatedParam, expectedUpdatedParam);
});
it('does not allow editing a param in created in one space in a different space', async () => {
@ -188,8 +194,8 @@ export default function ({ getService }: FtrProviderContext) {
.get(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`)
.set('kbn-xsrf', 'true')
.expect(200);
const param = getResponse.body.data[0];
expect(param.attributes).eql(testParam);
const param = getResponse.body[0];
assertHas(param, testParam);
// space does exist so get request should be 200
await supertestAPI
@ -207,8 +213,8 @@ export default function ({ getService }: FtrProviderContext) {
.get(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.PARAMS}`)
.set('kbn-xsrf', 'true')
.expect(200);
const updatedParamSO = updatedGetResponse.body.data[0];
expect(updatedParamSO.attributes).eql(testParam);
const actualUpdatedParam = updatedGetResponse.body[0];
assertHas(actualUpdatedParam, testParam);
});
it('handles invalid spaces', async () => {
@ -241,8 +247,8 @@ export default function ({ getService }: FtrProviderContext) {
.get(SYNTHETICS_API_URLS.PARAMS)
.set('kbn-xsrf', 'true')
.expect(200);
const param = getResponse.body.data[0];
expect(param.attributes).eql(testParam);
const param = getResponse.body[0];
assertHas(param, testParam);
await supertestAPI
.put(`/s/doesnotexist${SYNTHETICS_API_URLS.PARAMS}`)
@ -268,8 +274,8 @@ export default function ({ getService }: FtrProviderContext) {
.set('kbn-xsrf', 'true')
.expect(200);
expect(getResponse.body.data[0].namespaces).eql(['*']);
expect(getResponse.body.data[0].attributes).eql(testParam);
expect(getResponse.body[0].namespaces).eql(['*']);
assertHas(getResponse.body[0], testParam);
});
});
}

View file

@ -7,7 +7,7 @@
import {
ConfigKey,
HTTPFields,
SyntheticsParamSO,
SyntheticsParams,
} from '@kbn/synthetics-plugin/common/runtime_types';
import { SYNTHETICS_API_URLS } from '@kbn/synthetics-plugin/common/constants';
import { omit } from 'lodash';
@ -15,7 +15,6 @@ import { secretKeys } from '@kbn/synthetics-plugin/common/constants/monitor_mana
import { PackagePolicy } from '@kbn/fleet-plugin/common';
import expect from '@kbn/expect';
import { syntheticsParamType } from '@kbn/synthetics-plugin/common/types/saved_objects';
import { SavedObject } from '@kbn/core-saved-objects-server';
import { FtrProviderContext } from '../../ftr_provider_context';
import { getFixtureJson } from './helper/get_fixture_json';
import { PrivateLocationTestService } from './services/private_location_test_service';
@ -157,8 +156,8 @@ export default function ({ getService }: FtrProviderContext) {
expect(apiResponse.status).eql(200);
apiResponse.body.data.forEach(({ attributes }: SavedObject<SyntheticsParamSO>) => {
params[attributes.key] = attributes.value;
apiResponse.body.forEach(({ key, value }: SyntheticsParams) => {
params[key] = value;
});
});
@ -257,23 +256,25 @@ export default function ({ getService }: FtrProviderContext) {
.set('kbn-xsrf', 'true')
.expect(200);
expect(getResponse.body.data.length).eql(2);
expect(getResponse.body.length).eql(2);
const paramsResponse = getResponse.body.data || [];
const paramsResponse = getResponse.body || [];
const ids = paramsResponse.map((param: any) => param.id);
await supertestAPI
const deleteResponse = await supertestAPI
.delete(SYNTHETICS_API_URLS.PARAMS)
.query({ ids: JSON.stringify(ids) })
.set('kbn-xsrf', 'true')
.expect(200);
expect(deleteResponse.body).to.have.length(2);
const getResponseAfterDelete = await supertestAPI
.get(SYNTHETICS_API_URLS.PARAMS)
.set('kbn-xsrf', 'true')
.expect(200);
expect(getResponseAfterDelete.body.data.length).eql(0);
expect(getResponseAfterDelete.body.length).eql(0);
await supertestAPI
.get(SYNTHETICS_API_URLS.SYNC_GLOBAL_PARAMS)