mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
* Convert saved object routes to TS * Convert some attributes to optional * Cleanup * Add comments as to why we added ts-ignore * Fix lint issues * Apply PR feedback
This commit is contained in:
parent
07fbe6bf2b
commit
80b8d568aa
18 changed files with 569 additions and 256 deletions
|
@ -21,23 +21,23 @@ import Hapi from 'hapi';
|
|||
import { defaultValidationErrorHandler } from '../../../../core/server/http/http_tools';
|
||||
|
||||
const defaultConfig = {
|
||||
'kibana.index': '.kibana'
|
||||
'kibana.index': '.kibana',
|
||||
};
|
||||
|
||||
export function MockServer(config = defaultConfig) {
|
||||
export function createMockServer(config: { [key: string]: any } = defaultConfig) {
|
||||
const server = new Hapi.Server({
|
||||
port: 0,
|
||||
routes: {
|
||||
validate: {
|
||||
failAction: defaultValidationErrorHandler
|
||||
}
|
||||
}
|
||||
failAction: defaultValidationErrorHandler,
|
||||
},
|
||||
},
|
||||
});
|
||||
server.config = function () {
|
||||
server.config = () => {
|
||||
return {
|
||||
get: (key) => {
|
||||
get(key: string) {
|
||||
return config[key];
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
@ -17,23 +17,33 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import Hapi from 'hapi';
|
||||
import { createMockServer } from './_mock_server';
|
||||
import { createBulkCreateRoute } from './bulk_create';
|
||||
import { MockServer } from './_mock_server';
|
||||
|
||||
describe('POST /api/saved_objects/_bulk_create', () => {
|
||||
const savedObjectsClient = { bulkCreate: jest.fn() };
|
||||
let server;
|
||||
let server: Hapi.Server;
|
||||
const savedObjectsClient = {
|
||||
errors: {} as any,
|
||||
bulkCreate: jest.fn(),
|
||||
bulkGet: jest.fn(),
|
||||
create: jest.fn(),
|
||||
delete: jest.fn(),
|
||||
find: jest.fn(),
|
||||
get: jest.fn(),
|
||||
update: jest.fn(),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
savedObjectsClient.bulkCreate.mockImplementation(() => Promise.resolve(''));
|
||||
server = new MockServer();
|
||||
server = createMockServer();
|
||||
|
||||
const prereqs = {
|
||||
getSavedObjectsClient: {
|
||||
assign: 'savedObjectsClient',
|
||||
method() {
|
||||
return savedObjectsClient;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -48,23 +58,27 @@ describe('POST /api/saved_objects/_bulk_create', () => {
|
|||
const request = {
|
||||
method: 'POST',
|
||||
url: '/api/saved_objects/_bulk_create',
|
||||
payload: [{
|
||||
id: 'abc123',
|
||||
type: 'index-pattern',
|
||||
attributes: {
|
||||
title: 'my_title',
|
||||
payload: [
|
||||
{
|
||||
id: 'abc123',
|
||||
type: 'index-pattern',
|
||||
attributes: {
|
||||
title: 'my_title',
|
||||
},
|
||||
},
|
||||
}]
|
||||
],
|
||||
};
|
||||
|
||||
const clientResponse = {
|
||||
saved_objects: [{
|
||||
id: 'abc123',
|
||||
type: 'index-pattern',
|
||||
title: 'logstash-*',
|
||||
version: 2,
|
||||
references: [],
|
||||
}]
|
||||
saved_objects: [
|
||||
{
|
||||
id: 'abc123',
|
||||
type: 'index-pattern',
|
||||
title: 'logstash-*',
|
||||
version: 2,
|
||||
references: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
savedObjectsClient.bulkCreate.mockImplementation(() => Promise.resolve(clientResponse));
|
||||
|
@ -77,21 +91,24 @@ describe('POST /api/saved_objects/_bulk_create', () => {
|
|||
});
|
||||
|
||||
it('calls upon savedObjectClient.bulkCreate', async () => {
|
||||
const docs = [{
|
||||
id: 'abc123',
|
||||
type: 'index-pattern',
|
||||
attributes: {
|
||||
title: 'foo',
|
||||
const docs = [
|
||||
{
|
||||
id: 'abc123',
|
||||
type: 'index-pattern',
|
||||
attributes: {
|
||||
title: 'foo',
|
||||
},
|
||||
references: [],
|
||||
},
|
||||
references: [],
|
||||
}, {
|
||||
id: 'abc1234',
|
||||
type: 'index-pattern',
|
||||
attributes: {
|
||||
title: 'bar',
|
||||
{
|
||||
id: 'abc1234',
|
||||
type: 'index-pattern',
|
||||
attributes: {
|
||||
title: 'bar',
|
||||
},
|
||||
references: [],
|
||||
},
|
||||
references: [],
|
||||
}];
|
||||
];
|
||||
|
||||
const request = {
|
||||
method: 'POST',
|
||||
|
@ -110,14 +127,16 @@ describe('POST /api/saved_objects/_bulk_create', () => {
|
|||
await server.inject({
|
||||
method: 'POST',
|
||||
url: '/api/saved_objects/_bulk_create?overwrite=true',
|
||||
payload: [{
|
||||
id: 'abc1234',
|
||||
type: 'index-pattern',
|
||||
attributes: {
|
||||
title: 'foo',
|
||||
payload: [
|
||||
{
|
||||
id: 'abc1234',
|
||||
type: 'index-pattern',
|
||||
attributes: {
|
||||
title: 'foo',
|
||||
},
|
||||
references: [],
|
||||
},
|
||||
references: [],
|
||||
}]
|
||||
],
|
||||
});
|
||||
|
||||
expect(savedObjectsClient.bulkCreate).toHaveBeenCalled();
|
|
@ -17,9 +17,31 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import Hapi from 'hapi';
|
||||
import Joi from 'joi';
|
||||
import { SavedObjectAttributes, SavedObjectsClient } from '../';
|
||||
import { Prerequisites, SavedObjectReference, WithoutQueryAndParams } from './types';
|
||||
|
||||
export const createBulkCreateRoute = prereqs => ({
|
||||
interface SavedObject {
|
||||
type: string;
|
||||
id?: string;
|
||||
attributes: SavedObjectAttributes;
|
||||
version?: string;
|
||||
migrationVersion?: { [key: string]: string };
|
||||
references: SavedObjectReference[];
|
||||
}
|
||||
|
||||
interface BulkCreateRequest extends WithoutQueryAndParams<Hapi.Request> {
|
||||
pre: {
|
||||
savedObjectsClient: SavedObjectsClient;
|
||||
};
|
||||
query: {
|
||||
overwrite: boolean;
|
||||
};
|
||||
payload: SavedObject[];
|
||||
}
|
||||
|
||||
export const createBulkCreateRoute = (prereqs: Prerequisites) => ({
|
||||
path: '/api/saved_objects/_bulk_create',
|
||||
method: 'POST',
|
||||
config: {
|
||||
|
@ -37,18 +59,19 @@ export const createBulkCreateRoute = prereqs => ({
|
|||
attributes: Joi.object().required(),
|
||||
version: Joi.string(),
|
||||
migrationVersion: Joi.object().optional(),
|
||||
references: Joi.array().items(
|
||||
Joi.object()
|
||||
.keys({
|
||||
references: Joi.array()
|
||||
.items(
|
||||
Joi.object().keys({
|
||||
name: Joi.string().required(),
|
||||
type: Joi.string().required(),
|
||||
id: Joi.string().required(),
|
||||
}),
|
||||
).default([]),
|
||||
})
|
||||
)
|
||||
.default([]),
|
||||
}).required()
|
||||
),
|
||||
},
|
||||
handler(request) {
|
||||
handler(request: BulkCreateRequest) {
|
||||
const { overwrite } = request.query;
|
||||
const { savedObjectsClient } = request.pre;
|
||||
|
|
@ -17,22 +17,32 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import Hapi from 'hapi';
|
||||
import { createMockServer } from './_mock_server';
|
||||
import { createBulkGetRoute } from './bulk_get';
|
||||
import { MockServer } from './_mock_server';
|
||||
|
||||
describe('POST /api/saved_objects/_bulk_get', () => {
|
||||
const savedObjectsClient = { bulkGet: jest.fn() };
|
||||
let server;
|
||||
let server: Hapi.Server;
|
||||
const savedObjectsClient = {
|
||||
errors: {} as any,
|
||||
bulkCreate: jest.fn(),
|
||||
bulkGet: jest.fn(),
|
||||
create: jest.fn(),
|
||||
delete: jest.fn(),
|
||||
find: jest.fn(),
|
||||
get: jest.fn(),
|
||||
update: jest.fn(),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
savedObjectsClient.bulkGet.mockImplementation(() => Promise.resolve(''));
|
||||
server = new MockServer();
|
||||
server = createMockServer();
|
||||
const prereqs = {
|
||||
getSavedObjectsClient: {
|
||||
assign: 'savedObjectsClient',
|
||||
method() {
|
||||
return savedObjectsClient;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -47,20 +57,24 @@ describe('POST /api/saved_objects/_bulk_get', () => {
|
|||
const request = {
|
||||
method: 'POST',
|
||||
url: '/api/saved_objects/_bulk_get',
|
||||
payload: [{
|
||||
id: 'abc123',
|
||||
type: 'index-pattern'
|
||||
}]
|
||||
payload: [
|
||||
{
|
||||
id: 'abc123',
|
||||
type: 'index-pattern',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const clientResponse = {
|
||||
saved_objects: [{
|
||||
id: 'abc123',
|
||||
type: 'index-pattern',
|
||||
title: 'logstash-*',
|
||||
version: 'foo',
|
||||
references: [],
|
||||
}]
|
||||
saved_objects: [
|
||||
{
|
||||
id: 'abc123',
|
||||
type: 'index-pattern',
|
||||
title: 'logstash-*',
|
||||
version: 'foo',
|
||||
references: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
savedObjectsClient.bulkGet.mockImplementation(() => Promise.resolve(clientResponse));
|
||||
|
@ -73,15 +87,17 @@ describe('POST /api/saved_objects/_bulk_get', () => {
|
|||
});
|
||||
|
||||
it('calls upon savedObjectClient.bulkGet', async () => {
|
||||
const docs = [{
|
||||
id: 'abc123',
|
||||
type: 'index-pattern'
|
||||
}];
|
||||
const docs = [
|
||||
{
|
||||
id: 'abc123',
|
||||
type: 'index-pattern',
|
||||
},
|
||||
];
|
||||
|
||||
const request = {
|
||||
method: 'POST',
|
||||
url: '/api/saved_objects/_bulk_get',
|
||||
payload: docs
|
||||
payload: docs,
|
||||
};
|
||||
|
||||
await server.inject(request);
|
|
@ -17,23 +17,38 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import Hapi from 'hapi';
|
||||
import Joi from 'joi';
|
||||
import { SavedObjectsClient } from '../';
|
||||
import { Prerequisites } from './types';
|
||||
|
||||
export const createBulkGetRoute = (prereqs) => ({
|
||||
interface BulkGetRequest extends Hapi.Request {
|
||||
pre: {
|
||||
savedObjectsClient: SavedObjectsClient;
|
||||
};
|
||||
payload: Array<{
|
||||
type: string;
|
||||
id: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
export const createBulkGetRoute = (prereqs: Prerequisites) => ({
|
||||
path: '/api/saved_objects/_bulk_get',
|
||||
method: 'POST',
|
||||
config: {
|
||||
pre: [prereqs.getSavedObjectsClient],
|
||||
validate: {
|
||||
payload: Joi.array().items(Joi.object({
|
||||
type: Joi.string().required(),
|
||||
id: Joi.string().required(),
|
||||
}).required())
|
||||
payload: Joi.array().items(
|
||||
Joi.object({
|
||||
type: Joi.string().required(),
|
||||
id: Joi.string().required(),
|
||||
}).required()
|
||||
),
|
||||
},
|
||||
handler(request) {
|
||||
handler(request: BulkGetRequest) {
|
||||
const { savedObjectsClient } = request.pre;
|
||||
|
||||
return savedObjectsClient.bulkGet(request.payload);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
|
@ -17,23 +17,33 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import Hapi from 'hapi';
|
||||
import { createMockServer } from './_mock_server';
|
||||
import { createCreateRoute } from './create';
|
||||
import { MockServer } from './_mock_server';
|
||||
|
||||
describe('POST /api/saved_objects/{type}', () => {
|
||||
const savedObjectsClient = { create: jest.fn() };
|
||||
let server;
|
||||
let server: Hapi.Server;
|
||||
const savedObjectsClient = {
|
||||
errors: {} as any,
|
||||
bulkCreate: jest.fn(),
|
||||
bulkGet: jest.fn(),
|
||||
create: jest.fn(),
|
||||
delete: jest.fn(),
|
||||
find: jest.fn(),
|
||||
get: jest.fn(),
|
||||
update: jest.fn(),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
savedObjectsClient.create.mockImplementation(() => Promise.resolve(''));
|
||||
server = new MockServer();
|
||||
server = createMockServer();
|
||||
|
||||
const prereqs = {
|
||||
getSavedObjectsClient: {
|
||||
assign: 'savedObjectsClient',
|
||||
method() {
|
||||
return savedObjectsClient;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -50,9 +60,9 @@ describe('POST /api/saved_objects/{type}', () => {
|
|||
url: '/api/saved_objects/index-pattern',
|
||||
payload: {
|
||||
attributes: {
|
||||
title: 'Testing'
|
||||
}
|
||||
}
|
||||
title: 'Testing',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const clientResponse = {
|
||||
|
@ -75,7 +85,7 @@ describe('POST /api/saved_objects/{type}', () => {
|
|||
const request = {
|
||||
method: 'POST',
|
||||
url: '/api/saved_objects/index-pattern',
|
||||
payload: {}
|
||||
payload: {},
|
||||
};
|
||||
|
||||
const { statusCode, payload } = await server.inject(request);
|
||||
|
@ -93,9 +103,9 @@ describe('POST /api/saved_objects/{type}', () => {
|
|||
url: '/api/saved_objects/index-pattern',
|
||||
payload: {
|
||||
attributes: {
|
||||
title: 'Testing'
|
||||
}
|
||||
}
|
||||
title: 'Testing',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
await server.inject(request);
|
||||
|
@ -114,9 +124,9 @@ describe('POST /api/saved_objects/{type}', () => {
|
|||
url: '/api/saved_objects/index-pattern/logstash-*',
|
||||
payload: {
|
||||
attributes: {
|
||||
title: 'Testing'
|
||||
}
|
||||
}
|
||||
title: 'Testing',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
await server.inject(request);
|
|
@ -17,9 +17,30 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import Hapi from 'hapi';
|
||||
import Joi from 'joi';
|
||||
import { SavedObjectAttributes, SavedObjectsClient } from '../';
|
||||
import { Prerequisites, SavedObjectReference, WithoutQueryAndParams } from './types';
|
||||
|
||||
export const createCreateRoute = prereqs => {
|
||||
interface CreateRequest extends WithoutQueryAndParams<Hapi.Request> {
|
||||
pre: {
|
||||
savedObjectsClient: SavedObjectsClient;
|
||||
};
|
||||
query: {
|
||||
overwrite: boolean;
|
||||
};
|
||||
params: {
|
||||
type: string;
|
||||
id?: string;
|
||||
};
|
||||
payload: {
|
||||
attributes: SavedObjectAttributes;
|
||||
migrationVersion?: { [key: string]: string };
|
||||
references: SavedObjectReference[];
|
||||
};
|
||||
}
|
||||
|
||||
export const createCreateRoute = (prereqs: Prerequisites) => {
|
||||
return {
|
||||
path: '/api/saved_objects/{type}/{id?}',
|
||||
method: 'POST',
|
||||
|
@ -40,17 +61,18 @@ export const createCreateRoute = prereqs => {
|
|||
payload: Joi.object({
|
||||
attributes: Joi.object().required(),
|
||||
migrationVersion: Joi.object().optional(),
|
||||
references: Joi.array().items(
|
||||
Joi.object()
|
||||
.keys({
|
||||
references: Joi.array()
|
||||
.items(
|
||||
Joi.object().keys({
|
||||
name: Joi.string().required(),
|
||||
type: Joi.string().required(),
|
||||
id: Joi.string().required(),
|
||||
}),
|
||||
).default([]),
|
||||
})
|
||||
)
|
||||
.default([]),
|
||||
}).required(),
|
||||
},
|
||||
handler(request) {
|
||||
handler(request: CreateRequest) {
|
||||
const { savedObjectsClient } = request.pre;
|
||||
const { type, id } = request.params;
|
||||
const { overwrite } = request.query;
|
|
@ -17,23 +17,33 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import Hapi from 'hapi';
|
||||
import { createMockServer } from './_mock_server';
|
||||
import { createDeleteRoute } from './delete';
|
||||
import { MockServer } from './_mock_server';
|
||||
|
||||
describe('DELETE /api/saved_objects/{type}/{id}', () => {
|
||||
const savedObjectsClient = { delete: jest.fn() };
|
||||
let server;
|
||||
let server: Hapi.Server;
|
||||
const savedObjectsClient = {
|
||||
errors: {} as any,
|
||||
bulkCreate: jest.fn(),
|
||||
bulkGet: jest.fn(),
|
||||
create: jest.fn(),
|
||||
delete: jest.fn(),
|
||||
find: jest.fn(),
|
||||
get: jest.fn(),
|
||||
update: jest.fn(),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
savedObjectsClient.delete.mockImplementation(() => Promise.resolve('{}'));
|
||||
server = new MockServer();
|
||||
server = createMockServer();
|
||||
|
||||
const prereqs = {
|
||||
getSavedObjectsClient: {
|
||||
assign: 'savedObjectsClient',
|
||||
method() {
|
||||
return savedObjectsClient;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -47,7 +57,7 @@ describe('DELETE /api/saved_objects/{type}/{id}', () => {
|
|||
it('formats successful response', async () => {
|
||||
const request = {
|
||||
method: 'DELETE',
|
||||
url: '/api/saved_objects/index-pattern/logstash-*'
|
||||
url: '/api/saved_objects/index-pattern/logstash-*',
|
||||
};
|
||||
|
||||
const { payload, statusCode } = await server.inject(request);
|
||||
|
@ -60,7 +70,7 @@ describe('DELETE /api/saved_objects/{type}/{id}', () => {
|
|||
it('calls upon savedObjectClient.delete', async () => {
|
||||
const request = {
|
||||
method: 'DELETE',
|
||||
url: '/api/saved_objects/index-pattern/logstash-*'
|
||||
url: '/api/saved_objects/index-pattern/logstash-*',
|
||||
};
|
||||
|
||||
await server.inject(request);
|
|
@ -17,24 +17,39 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import Hapi from 'hapi';
|
||||
import Joi from 'joi';
|
||||
import { SavedObjectsClient } from '../';
|
||||
import { Prerequisites } from './types';
|
||||
|
||||
export const createDeleteRoute = (prereqs) => ({
|
||||
interface DeleteRequest extends Hapi.Request {
|
||||
pre: {
|
||||
savedObjectsClient: SavedObjectsClient;
|
||||
};
|
||||
params: {
|
||||
type: string;
|
||||
id: string;
|
||||
};
|
||||
}
|
||||
|
||||
export const createDeleteRoute = (prereqs: Prerequisites) => ({
|
||||
path: '/api/saved_objects/{type}/{id}',
|
||||
method: 'DELETE',
|
||||
config: {
|
||||
pre: [prereqs.getSavedObjectsClient],
|
||||
validate: {
|
||||
params: Joi.object().keys({
|
||||
type: Joi.string().required(),
|
||||
id: Joi.string().required(),
|
||||
}).required()
|
||||
params: Joi.object()
|
||||
.keys({
|
||||
type: Joi.string().required(),
|
||||
id: Joi.string().required(),
|
||||
})
|
||||
.required(),
|
||||
},
|
||||
handler(request) {
|
||||
handler(request: DeleteRequest) {
|
||||
const { savedObjectsClient } = request.pre;
|
||||
const { type, id } = request.params;
|
||||
|
||||
return savedObjectsClient.delete(type, id);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import Joi from 'joi';
|
||||
import { keysToCamelCaseShallow } from '../../../utils/case_conversion';
|
||||
|
||||
export const createFindRoute = (prereqs) => ({
|
||||
path: '/api/saved_objects/_find',
|
||||
method: 'GET',
|
||||
config: {
|
||||
pre: [prereqs.getSavedObjectsClient],
|
||||
validate: {
|
||||
query: Joi.object().keys({
|
||||
per_page: Joi.number().min(0).default(20),
|
||||
page: Joi.number().min(0).default(1),
|
||||
type: Joi.array().items(Joi.string()).single().required(),
|
||||
search: Joi.string().allow('').optional(),
|
||||
default_search_operator: Joi.string().valid('OR', 'AND').default('OR'),
|
||||
search_fields: Joi.array().items(Joi.string()).single(),
|
||||
sort_field: Joi.array().items(Joi.string()).single(),
|
||||
has_reference: Joi.object()
|
||||
.keys({
|
||||
type: Joi.string().required(),
|
||||
id: Joi.string().required(),
|
||||
}).optional(),
|
||||
fields: Joi.array().items(Joi.string()).single()
|
||||
}).default()
|
||||
},
|
||||
handler(request) {
|
||||
const options = keysToCamelCaseShallow(request.query);
|
||||
return request.pre.savedObjectsClient.find(options);
|
||||
}
|
||||
}
|
||||
});
|
|
@ -17,23 +17,33 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import Hapi from 'hapi';
|
||||
import { createMockServer } from './_mock_server';
|
||||
import { createFindRoute } from './find';
|
||||
import { MockServer } from './_mock_server';
|
||||
|
||||
describe('GET /api/saved_objects/_find', () => {
|
||||
const savedObjectsClient = { find: jest.fn() };
|
||||
let server;
|
||||
let server: Hapi.Server;
|
||||
const savedObjectsClient = {
|
||||
errors: {} as any,
|
||||
bulkCreate: jest.fn(),
|
||||
bulkGet: jest.fn(),
|
||||
create: jest.fn(),
|
||||
delete: jest.fn(),
|
||||
find: jest.fn(),
|
||||
get: jest.fn(),
|
||||
update: jest.fn(),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
savedObjectsClient.find.mockImplementation(() => Promise.resolve(''));
|
||||
server = new MockServer();
|
||||
server = createMockServer();
|
||||
|
||||
const prereqs = {
|
||||
getSavedObjectsClient: {
|
||||
assign: 'savedObjectsClient',
|
||||
method() {
|
||||
return savedObjectsClient;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -47,7 +57,7 @@ describe('GET /api/saved_objects/_find', () => {
|
|||
it('returns with status 400 when type is missing', async () => {
|
||||
const request = {
|
||||
method: 'GET',
|
||||
url: '/api/saved_objects/_find'
|
||||
url: '/api/saved_objects/_find',
|
||||
};
|
||||
|
||||
const { payload, statusCode } = await server.inject(request);
|
||||
|
@ -63,7 +73,7 @@ describe('GET /api/saved_objects/_find', () => {
|
|||
it('formats successful response', async () => {
|
||||
const request = {
|
||||
method: 'GET',
|
||||
url: '/api/saved_objects/_find?type=index-pattern'
|
||||
url: '/api/saved_objects/_find?type=index-pattern',
|
||||
};
|
||||
|
||||
const clientResponse = {
|
||||
|
@ -76,15 +86,16 @@ describe('GET /api/saved_objects/_find', () => {
|
|||
timeFieldName: '@timestamp',
|
||||
notExpandable: true,
|
||||
references: [],
|
||||
}, {
|
||||
},
|
||||
{
|
||||
type: 'index-pattern',
|
||||
id: 'stocks-*',
|
||||
title: 'stocks-*',
|
||||
timeFieldName: '@timestamp',
|
||||
notExpandable: true,
|
||||
references: [],
|
||||
}
|
||||
]
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
savedObjectsClient.find.mockImplementation(() => Promise.resolve(clientResponse));
|
||||
|
@ -99,7 +110,7 @@ describe('GET /api/saved_objects/_find', () => {
|
|||
it('calls upon savedObjectClient.find with defaults', async () => {
|
||||
const request = {
|
||||
method: 'GET',
|
||||
url: '/api/saved_objects/_find?type=foo&type=bar'
|
||||
url: '/api/saved_objects/_find?type=foo&type=bar',
|
||||
};
|
||||
|
||||
await server.inject(request);
|
||||
|
@ -107,13 +118,18 @@ describe('GET /api/saved_objects/_find', () => {
|
|||
expect(savedObjectsClient.find).toHaveBeenCalledTimes(1);
|
||||
|
||||
const options = savedObjectsClient.find.mock.calls[0][0];
|
||||
expect(options).toEqual({ perPage: 20, page: 1, type: ['foo', 'bar'], defaultSearchOperator: 'OR' });
|
||||
expect(options).toEqual({
|
||||
perPage: 20,
|
||||
page: 1,
|
||||
type: ['foo', 'bar'],
|
||||
defaultSearchOperator: 'OR',
|
||||
});
|
||||
});
|
||||
|
||||
it('accepts the query parameter page/per_page', async () => {
|
||||
const request = {
|
||||
method: 'GET',
|
||||
url: '/api/saved_objects/_find?type=foo&per_page=10&page=50'
|
||||
url: '/api/saved_objects/_find?type=foo&per_page=10&page=50',
|
||||
};
|
||||
|
||||
await server.inject(request);
|
||||
|
@ -127,35 +143,7 @@ describe('GET /api/saved_objects/_find', () => {
|
|||
it('accepts the query parameter search_fields', async () => {
|
||||
const request = {
|
||||
method: 'GET',
|
||||
url: '/api/saved_objects/_find?type=foo&search_fields=title'
|
||||
};
|
||||
|
||||
await server.inject(request);
|
||||
|
||||
expect(savedObjectsClient.find).toHaveBeenCalledTimes(1);
|
||||
|
||||
const options = savedObjectsClient.find.mock.calls[0][0];
|
||||
expect(options).toEqual({ perPage: 20, page: 1, searchFields: ['title'], type: ['foo'], defaultSearchOperator: 'OR' });
|
||||
});
|
||||
|
||||
it('accepts the query parameter fields as a string', async () => {
|
||||
const request = {
|
||||
method: 'GET',
|
||||
url: '/api/saved_objects/_find?type=foo&fields=title'
|
||||
};
|
||||
|
||||
await server.inject(request);
|
||||
|
||||
expect(savedObjectsClient.find).toHaveBeenCalledTimes(1);
|
||||
|
||||
const options = savedObjectsClient.find.mock.calls[0][0];
|
||||
expect(options).toEqual({ perPage: 20, page: 1, fields: ['title'], type: ['foo'], defaultSearchOperator: 'OR' });
|
||||
});
|
||||
|
||||
it('accepts the query parameter fields as an array', async () => {
|
||||
const request = {
|
||||
method: 'GET',
|
||||
url: '/api/saved_objects/_find?type=foo&fields=title&fields=description'
|
||||
url: '/api/saved_objects/_find?type=foo&search_fields=title',
|
||||
};
|
||||
|
||||
await server.inject(request);
|
||||
|
@ -164,14 +152,58 @@ describe('GET /api/saved_objects/_find', () => {
|
|||
|
||||
const options = savedObjectsClient.find.mock.calls[0][0];
|
||||
expect(options).toEqual({
|
||||
perPage: 20, page: 1, fields: ['title', 'description'], type: ['foo'], defaultSearchOperator: 'OR'
|
||||
perPage: 20,
|
||||
page: 1,
|
||||
searchFields: ['title'],
|
||||
type: ['foo'],
|
||||
defaultSearchOperator: 'OR',
|
||||
});
|
||||
});
|
||||
|
||||
it('accepts the query parameter fields as a string', async () => {
|
||||
const request = {
|
||||
method: 'GET',
|
||||
url: '/api/saved_objects/_find?type=foo&fields=title',
|
||||
};
|
||||
|
||||
await server.inject(request);
|
||||
|
||||
expect(savedObjectsClient.find).toHaveBeenCalledTimes(1);
|
||||
|
||||
const options = savedObjectsClient.find.mock.calls[0][0];
|
||||
expect(options).toEqual({
|
||||
perPage: 20,
|
||||
page: 1,
|
||||
fields: ['title'],
|
||||
type: ['foo'],
|
||||
defaultSearchOperator: 'OR',
|
||||
});
|
||||
});
|
||||
|
||||
it('accepts the query parameter fields as an array', async () => {
|
||||
const request = {
|
||||
method: 'GET',
|
||||
url: '/api/saved_objects/_find?type=foo&fields=title&fields=description',
|
||||
};
|
||||
|
||||
await server.inject(request);
|
||||
|
||||
expect(savedObjectsClient.find).toHaveBeenCalledTimes(1);
|
||||
|
||||
const options = savedObjectsClient.find.mock.calls[0][0];
|
||||
expect(options).toEqual({
|
||||
perPage: 20,
|
||||
page: 1,
|
||||
fields: ['title', 'description'],
|
||||
type: ['foo'],
|
||||
defaultSearchOperator: 'OR',
|
||||
});
|
||||
});
|
||||
|
||||
it('accepts the query parameter type as a string', async () => {
|
||||
const request = {
|
||||
method: 'GET',
|
||||
url: '/api/saved_objects/_find?type=index-pattern'
|
||||
url: '/api/saved_objects/_find?type=index-pattern',
|
||||
};
|
||||
|
||||
await server.inject(request);
|
||||
|
@ -179,13 +211,18 @@ describe('GET /api/saved_objects/_find', () => {
|
|||
expect(savedObjectsClient.find).toHaveBeenCalledTimes(1);
|
||||
|
||||
const options = savedObjectsClient.find.mock.calls[0][0];
|
||||
expect(options).toEqual({ perPage: 20, page: 1, type: ['index-pattern'], defaultSearchOperator: 'OR' });
|
||||
expect(options).toEqual({
|
||||
perPage: 20,
|
||||
page: 1,
|
||||
type: ['index-pattern'],
|
||||
defaultSearchOperator: 'OR',
|
||||
});
|
||||
});
|
||||
|
||||
it('accepts the query parameter type as an array', async () => {
|
||||
const request = {
|
||||
method: 'GET',
|
||||
url: '/api/saved_objects/_find?type=index-pattern&type=visualization'
|
||||
url: '/api/saved_objects/_find?type=index-pattern&type=visualization',
|
||||
};
|
||||
|
||||
await server.inject(request);
|
||||
|
@ -193,6 +230,11 @@ describe('GET /api/saved_objects/_find', () => {
|
|||
expect(savedObjectsClient.find).toHaveBeenCalledTimes(1);
|
||||
|
||||
const options = savedObjectsClient.find.mock.calls[0][0];
|
||||
expect(options).toEqual({ perPage: 20, page: 1, type: ['index-pattern', 'visualization'], defaultSearchOperator: 'OR' });
|
||||
expect(options).toEqual({
|
||||
perPage: 20,
|
||||
page: 1,
|
||||
type: ['index-pattern', 'visualization'],
|
||||
defaultSearchOperator: 'OR',
|
||||
});
|
||||
});
|
||||
});
|
100
src/legacy/server/saved_objects/routes/find.ts
Normal file
100
src/legacy/server/saved_objects/routes/find.ts
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import Hapi from 'hapi';
|
||||
import Joi from 'joi';
|
||||
import { SavedObjectsClient } from '../';
|
||||
import { Prerequisites, WithoutQueryAndParams } from './types';
|
||||
|
||||
interface FindRequest extends WithoutQueryAndParams<Hapi.Request> {
|
||||
pre: {
|
||||
savedObjectsClient: SavedObjectsClient;
|
||||
};
|
||||
query: {
|
||||
per_page: number;
|
||||
page: number;
|
||||
type: string[];
|
||||
search?: string;
|
||||
default_search_operator: 'AND' | 'OR';
|
||||
search_fields?: string[];
|
||||
sort_field?: string;
|
||||
has_reference?: {
|
||||
type: string;
|
||||
id: string;
|
||||
};
|
||||
fields?: string[];
|
||||
};
|
||||
}
|
||||
|
||||
export const createFindRoute = (prereqs: Prerequisites) => ({
|
||||
path: '/api/saved_objects/_find',
|
||||
method: 'GET',
|
||||
config: {
|
||||
pre: [prereqs.getSavedObjectsClient],
|
||||
validate: {
|
||||
query: Joi.object()
|
||||
.keys({
|
||||
per_page: Joi.number()
|
||||
.min(0)
|
||||
.default(20),
|
||||
page: Joi.number()
|
||||
.min(0)
|
||||
.default(1),
|
||||
type: Joi.array()
|
||||
.items(Joi.string())
|
||||
.single()
|
||||
.required(),
|
||||
search: Joi.string()
|
||||
.allow('')
|
||||
.optional(),
|
||||
default_search_operator: Joi.string()
|
||||
.valid('OR', 'AND')
|
||||
.default('OR'),
|
||||
search_fields: Joi.array()
|
||||
.items(Joi.string())
|
||||
.single(),
|
||||
sort_field: Joi.string(),
|
||||
has_reference: Joi.object()
|
||||
.keys({
|
||||
type: Joi.string().required(),
|
||||
id: Joi.string().required(),
|
||||
})
|
||||
.optional(),
|
||||
fields: Joi.array()
|
||||
.items(Joi.string())
|
||||
.single(),
|
||||
})
|
||||
.default(),
|
||||
},
|
||||
handler(request: FindRequest) {
|
||||
const query = request.query;
|
||||
return request.pre.savedObjectsClient.find({
|
||||
perPage: query.per_page,
|
||||
page: query.page,
|
||||
type: query.type,
|
||||
search: query.search,
|
||||
defaultSearchOperator: query.default_search_operator,
|
||||
searchFields: query.search_fields,
|
||||
sortField: query.sort_field,
|
||||
hasReference: query.has_reference,
|
||||
fields: query.fields,
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
|
@ -17,23 +17,33 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import Hapi from 'hapi';
|
||||
import { createMockServer } from './_mock_server';
|
||||
import { createGetRoute } from './get';
|
||||
import { MockServer } from './_mock_server';
|
||||
|
||||
describe('GET /api/saved_objects/{type}/{id}', () => {
|
||||
const savedObjectsClient = { get: jest.fn() };
|
||||
let server;
|
||||
let server: Hapi.Server;
|
||||
const savedObjectsClient = {
|
||||
errors: {} as any,
|
||||
bulkCreate: jest.fn(),
|
||||
bulkGet: jest.fn(),
|
||||
create: jest.fn(),
|
||||
delete: jest.fn(),
|
||||
find: jest.fn(),
|
||||
get: jest.fn(),
|
||||
update: jest.fn(),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
savedObjectsClient.get.mockImplementation(() => Promise.resolve(true));
|
||||
server = new MockServer();
|
||||
savedObjectsClient.get.mockImplementation(() => Promise.resolve(''));
|
||||
server = createMockServer();
|
||||
|
||||
const prereqs = {
|
||||
getSavedObjectsClient: {
|
||||
assign: 'savedObjectsClient',
|
||||
method() {
|
||||
return savedObjectsClient;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -47,7 +57,7 @@ describe('GET /api/saved_objects/{type}/{id}', () => {
|
|||
it('formats successful response', async () => {
|
||||
const request = {
|
||||
method: 'GET',
|
||||
url: '/api/saved_objects/index-pattern/logstash-*'
|
||||
url: '/api/saved_objects/index-pattern/logstash-*',
|
||||
};
|
||||
const clientResponse = {
|
||||
id: 'logstash-*',
|
||||
|
@ -69,7 +79,7 @@ describe('GET /api/saved_objects/{type}/{id}', () => {
|
|||
it('calls upon savedObjectClient.get', async () => {
|
||||
const request = {
|
||||
method: 'GET',
|
||||
url: '/api/saved_objects/index-pattern/logstash-*'
|
||||
url: '/api/saved_objects/index-pattern/logstash-*',
|
||||
};
|
||||
|
||||
await server.inject(request);
|
|
@ -17,24 +17,39 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import Hapi from 'hapi';
|
||||
import Joi from 'joi';
|
||||
import { SavedObjectsClient } from '../';
|
||||
import { Prerequisites } from './types';
|
||||
|
||||
export const createGetRoute = (prereqs) => ({
|
||||
interface GetRequest extends Hapi.Request {
|
||||
pre: {
|
||||
savedObjectsClient: SavedObjectsClient;
|
||||
};
|
||||
params: {
|
||||
type: string;
|
||||
id: string;
|
||||
};
|
||||
}
|
||||
|
||||
export const createGetRoute = (prereqs: Prerequisites) => ({
|
||||
path: '/api/saved_objects/{type}/{id}',
|
||||
method: 'GET',
|
||||
config: {
|
||||
pre: [prereqs.getSavedObjectsClient],
|
||||
validate: {
|
||||
params: Joi.object().keys({
|
||||
type: Joi.string().required(),
|
||||
id: Joi.string().required(),
|
||||
}).required()
|
||||
params: Joi.object()
|
||||
.keys({
|
||||
type: Joi.string().required(),
|
||||
id: Joi.string().required(),
|
||||
})
|
||||
.required(),
|
||||
},
|
||||
handler(request) {
|
||||
handler(request: GetRequest) {
|
||||
const { savedObjectsClient } = request.pre;
|
||||
const { type, id } = request.params;
|
||||
|
||||
return savedObjectsClient.get(type, id);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
36
src/legacy/server/saved_objects/routes/types.ts
Normal file
36
src/legacy/server/saved_objects/routes/types.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import Hapi from 'hapi';
|
||||
import { SavedObjectsClient } from '../';
|
||||
|
||||
export interface SavedObjectReference {
|
||||
name: string;
|
||||
type: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface Prerequisites {
|
||||
getSavedObjectsClient: {
|
||||
assign: string;
|
||||
method: (req: Hapi.Request) => SavedObjectsClient;
|
||||
};
|
||||
}
|
||||
|
||||
export type WithoutQueryAndParams<T> = Pick<T, Exclude<keyof T, 'query' | 'params'>>;
|
|
@ -17,24 +17,33 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import Hapi from 'hapi';
|
||||
import { createMockServer } from './_mock_server';
|
||||
import { createUpdateRoute } from './update';
|
||||
import { MockServer } from './_mock_server';
|
||||
|
||||
describe('PUT /api/saved_objects/{type}/{id?}', () => {
|
||||
|
||||
const savedObjectsClient = { update: jest.fn() };
|
||||
let server;
|
||||
let server: Hapi.Server;
|
||||
const savedObjectsClient = {
|
||||
errors: {} as any,
|
||||
bulkCreate: jest.fn(),
|
||||
bulkGet: jest.fn(),
|
||||
create: jest.fn(),
|
||||
delete: jest.fn(),
|
||||
find: jest.fn(),
|
||||
get: jest.fn(),
|
||||
update: jest.fn(),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
server = new MockServer();
|
||||
savedObjectsClient.update.mockImplementation(() => Promise.resolve(true));
|
||||
savedObjectsClient.update.mockImplementation(() => Promise.resolve(''));
|
||||
server = createMockServer();
|
||||
|
||||
const prereqs = {
|
||||
getSavedObjectsClient: {
|
||||
assign: 'savedObjectsClient',
|
||||
method() {
|
||||
return savedObjectsClient;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -51,10 +60,10 @@ describe('PUT /api/saved_objects/{type}/{id?}', () => {
|
|||
url: '/api/saved_objects/index-pattern/logstash-*',
|
||||
payload: {
|
||||
attributes: {
|
||||
title: 'Testing'
|
||||
title: 'Testing',
|
||||
},
|
||||
references: [],
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const clientResponse = {
|
||||
|
@ -81,7 +90,7 @@ describe('PUT /api/saved_objects/{type}/{id?}', () => {
|
|||
payload: {
|
||||
attributes: { title: 'Testing' },
|
||||
version: 'foo',
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
await server.inject(request);
|
|
@ -17,40 +17,61 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import Hapi from 'hapi';
|
||||
import Joi from 'joi';
|
||||
import { SavedObjectAttributes, SavedObjectsClient } from '../';
|
||||
import { Prerequisites, SavedObjectReference } from './types';
|
||||
|
||||
export const createUpdateRoute = (prereqs) => {
|
||||
interface UpdateRequest extends Hapi.Request {
|
||||
pre: {
|
||||
savedObjectsClient: SavedObjectsClient;
|
||||
};
|
||||
params: {
|
||||
type: string;
|
||||
id: string;
|
||||
};
|
||||
payload: {
|
||||
attributes: SavedObjectAttributes;
|
||||
version?: string;
|
||||
references: SavedObjectReference[];
|
||||
};
|
||||
}
|
||||
|
||||
export const createUpdateRoute = (prereqs: Prerequisites) => {
|
||||
return {
|
||||
path: '/api/saved_objects/{type}/{id}',
|
||||
method: 'PUT',
|
||||
config: {
|
||||
pre: [prereqs.getSavedObjectsClient],
|
||||
validate: {
|
||||
params: Joi.object().keys({
|
||||
type: Joi.string().required(),
|
||||
id: Joi.string().required(),
|
||||
}).required(),
|
||||
params: Joi.object()
|
||||
.keys({
|
||||
type: Joi.string().required(),
|
||||
id: Joi.string().required(),
|
||||
})
|
||||
.required(),
|
||||
payload: Joi.object({
|
||||
attributes: Joi.object().required(),
|
||||
version: Joi.string(),
|
||||
references: Joi.array().items(
|
||||
Joi.object()
|
||||
.keys({
|
||||
references: Joi.array()
|
||||
.items(
|
||||
Joi.object().keys({
|
||||
name: Joi.string().required(),
|
||||
type: Joi.string().required(),
|
||||
id: Joi.string().required(),
|
||||
}),
|
||||
).default([]),
|
||||
}).required()
|
||||
})
|
||||
)
|
||||
.default([]),
|
||||
}).required(),
|
||||
},
|
||||
handler(request) {
|
||||
handler(request: UpdateRequest) {
|
||||
const { savedObjectsClient } = request.pre;
|
||||
const { type, id } = request.params;
|
||||
const { attributes, version, references } = request.payload;
|
||||
const options = { version, references };
|
||||
|
||||
return savedObjectsClient.update(type, id, attributes, options);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue