forked from elastic/kibana
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds an API for managing saved objects (elastic#11632)
POST /api/saved_objects/{type} GET /api/saved_objects/{type}/{id} PUT /api/saved_objects/{type}/{id} DELETE /api/saved_objects/{type}/{id} GET /api/saved_objects/{type?}
- Loading branch information
1 parent
a06d51f
commit 9fbf197
Showing
28 changed files
with
1,669 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
248 changes: 248 additions & 0 deletions
248
src/server/saved_objects/client/__tests__/saved_objects_client.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,248 @@ | ||
import expect from 'expect.js'; | ||
import sinon from 'sinon'; | ||
import { SavedObjectsClient } from '../saved_objects_client'; | ||
|
||
describe('SavedObjectsClient', () => { | ||
let callAdminCluster; | ||
let savedObjectsClient; | ||
const docs = { | ||
hits: { | ||
total: 3, | ||
hits: [{ | ||
_index: '.kibana', | ||
_type: 'index-pattern', | ||
_id: 'logstash-*', | ||
_score: 1, | ||
_source: { | ||
title: 'logstash-*', | ||
timeFieldName: '@timestamp', | ||
notExpandable: true | ||
} | ||
}, { | ||
_index: '.kibana', | ||
_type: 'config', | ||
_id: '6.0.0-alpha1', | ||
_score: 1, | ||
_source: { | ||
buildNum: 8467, | ||
defaultIndex: 'logstash-*' | ||
} | ||
}, { | ||
_index: '.kibana', | ||
_type: 'index-pattern', | ||
_id: 'stocks-*', | ||
_score: 1, | ||
_source: { | ||
title: 'stocks-*', | ||
timeFieldName: '@timestamp', | ||
notExpandable: true | ||
} | ||
}] | ||
} | ||
}; | ||
|
||
beforeEach(() => { | ||
callAdminCluster = sinon.mock(); | ||
savedObjectsClient = new SavedObjectsClient('.kibana-test', callAdminCluster); | ||
}); | ||
|
||
afterEach(() => { | ||
callAdminCluster.reset(); | ||
}); | ||
|
||
|
||
describe('#create', () => { | ||
it('formats Elasticsearch response', async () => { | ||
callAdminCluster.returns({ _type: 'index-pattern', _id: 'logstash-*', _version: 2 }); | ||
|
||
const response = await savedObjectsClient.create('index-pattern', { | ||
title: 'Logstash' | ||
}); | ||
|
||
expect(response).to.eql({ | ||
type: 'index-pattern', | ||
id: 'logstash-*', | ||
version: 2, | ||
attributes: { | ||
title: 'Logstash', | ||
} | ||
}); | ||
}); | ||
|
||
it('should use ES create action', async () => { | ||
callAdminCluster.returns({ _type: 'index-pattern', _id: 'logstash-*', _version: 2 }); | ||
|
||
await savedObjectsClient.create('index-pattern', { | ||
id: 'logstash-*', | ||
title: 'Logstash' | ||
}); | ||
|
||
expect(callAdminCluster.calledOnce).to.be(true); | ||
|
||
const args = callAdminCluster.getCall(0).args; | ||
expect(args[0]).to.be('index'); | ||
}); | ||
}); | ||
|
||
describe('#delete', () => { | ||
it('throws notFound when ES is unable to find the document', (done) => { | ||
callAdminCluster.returns(Promise.resolve({ found: false })); | ||
|
||
savedObjectsClient.delete('index-pattern', 'logstash-*').then(() => { | ||
done('failed'); | ||
}).catch(e => { | ||
expect(e.output.statusCode).to.be(404); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('passes the parameters to callAdminCluster', async () => { | ||
await savedObjectsClient.delete('index-pattern', 'logstash-*'); | ||
|
||
expect(callAdminCluster.calledOnce).to.be(true); | ||
|
||
const args = callAdminCluster.getCall(0).args; | ||
expect(args[0]).to.be('delete'); | ||
expect(args[1]).to.eql({ | ||
type: 'index-pattern', | ||
id: 'logstash-*', | ||
refresh: 'wait_for', | ||
index: '.kibana-test' | ||
}); | ||
}); | ||
}); | ||
|
||
describe('#find', () => { | ||
it('formats Elasticsearch response', async () => { | ||
const count = docs.hits.hits.length; | ||
|
||
callAdminCluster.returns(Promise.resolve(docs)); | ||
const response = await savedObjectsClient.find(); | ||
|
||
expect(response.total).to.be(count); | ||
expect(response.saved_objects).to.have.length(count); | ||
docs.hits.hits.forEach((doc, i) => { | ||
expect(response.saved_objects[i]).to.eql({ | ||
id: doc._id, | ||
type: doc._type, | ||
version: doc._version, | ||
attributes: doc._source | ||
}); | ||
}); | ||
}); | ||
|
||
it('accepts per_page/page', async () => { | ||
await savedObjectsClient.find({ perPage: 10, page: 6 }); | ||
|
||
expect(callAdminCluster.calledOnce).to.be(true); | ||
|
||
const options = callAdminCluster.getCall(0).args[1]; | ||
expect(options.size).to.be(10); | ||
expect(options.from).to.be(50); | ||
}); | ||
|
||
it('accepts type', async () => { | ||
await savedObjectsClient.find({ type: 'index-pattern' }); | ||
|
||
expect(callAdminCluster.calledOnce).to.be(true); | ||
|
||
const options = callAdminCluster.getCall(0).args[1]; | ||
const expectedQuery = { | ||
bool: { | ||
must: [{ match_all: {} }], | ||
filter: [{ term: { _type: 'index-pattern' } }] | ||
} | ||
}; | ||
|
||
expect(options.body).to.eql({ | ||
query: expectedQuery, version: true | ||
}); | ||
}); | ||
|
||
it('can filter by fields', async () => { | ||
await savedObjectsClient.find({ fields: 'title' }); | ||
|
||
expect(callAdminCluster.calledOnce).to.be(true); | ||
|
||
const options = callAdminCluster.getCall(0).args[1]; | ||
expect(options._source).to.eql('title'); | ||
}); | ||
}); | ||
|
||
describe('#get', () => { | ||
it('formats Elasticsearch response', async () => { | ||
callAdminCluster.returns(Promise.resolve({ | ||
_id: 'logstash-*', | ||
_type: 'index-pattern', | ||
_version: 2, | ||
_source: { | ||
title: 'Testing' | ||
} | ||
})); | ||
|
||
const response = await savedObjectsClient.get('index-pattern', 'logstash-*'); | ||
expect(response).to.eql({ | ||
id: 'logstash-*', | ||
type: 'index-pattern', | ||
version: 2, | ||
attributes: { | ||
title: 'Testing' | ||
} | ||
}); | ||
}); | ||
}); | ||
|
||
describe('#update', () => { | ||
it('returns current ES document version', async () => { | ||
const id = 'logstash-*'; | ||
const type = 'index-pattern'; | ||
const version = 2; | ||
const attributes = { title: 'Testing' }; | ||
|
||
callAdminCluster.returns(Promise.resolve({ | ||
_id: id, | ||
_type: type, | ||
_version: version, | ||
result: 'updated' | ||
})); | ||
|
||
const response = await savedObjectsClient.update('index-pattern', 'logstash-*', attributes); | ||
expect(response).to.eql({ | ||
id, | ||
type, | ||
version, | ||
attributes | ||
}); | ||
}); | ||
|
||
it('accepts version', async () => { | ||
await savedObjectsClient.update( | ||
'index-pattern', | ||
'logstash-*', | ||
{ title: 'Testing' }, | ||
{ version: 1 } | ||
); | ||
|
||
const esParams = callAdminCluster.getCall(0).args[1]; | ||
expect(esParams.version).to.be(1); | ||
}); | ||
|
||
it('passes the parameters to callAdminCluster', async () => { | ||
await savedObjectsClient.update('index-pattern', 'logstash-*', { title: 'Testing' }); | ||
|
||
expect(callAdminCluster.calledOnce).to.be(true); | ||
|
||
const args = callAdminCluster.getCall(0).args; | ||
|
||
expect(args[0]).to.be('update'); | ||
expect(args[1]).to.eql({ | ||
type: 'index-pattern', | ||
id: 'logstash-*', | ||
version: undefined, | ||
body: { doc: { title: 'Testing' } }, | ||
refresh: 'wait_for', | ||
index: '.kibana-test' | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { SavedObjectsClient } from './saved_objects_client'; |
82 changes: 82 additions & 0 deletions
82
src/server/saved_objects/client/lib/__tests__/create_find_query.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import expect from 'expect.js'; | ||
import { createFindQuery } from '../create_find_query'; | ||
|
||
describe('createFindQuery', () => { | ||
it('matches all when there is no type or filter', () => { | ||
const query = createFindQuery(); | ||
expect(query).to.eql({ query: { match_all: {} }, version: true }); | ||
}); | ||
|
||
it('adds bool filter for type', () => { | ||
const query = createFindQuery({ type: 'index-pattern' }); | ||
expect(query).to.eql({ | ||
query: { | ||
bool: { | ||
filter: [{ | ||
term: { | ||
_type: 'index-pattern' | ||
} | ||
}], | ||
must: [{ | ||
match_all: {} | ||
}] | ||
} | ||
}, | ||
version: true | ||
}); | ||
}); | ||
|
||
it('can search across all fields', () => { | ||
const query = createFindQuery({ search: 'foo' }); | ||
expect(query).to.eql({ | ||
query: { | ||
bool: { | ||
filter: [], | ||
must: [{ | ||
simple_query_string: { | ||
query: 'foo', | ||
all_fields: true | ||
} | ||
}] | ||
} | ||
}, | ||
version: true | ||
}); | ||
}); | ||
|
||
it('can search a single field', () => { | ||
const query = createFindQuery({ search: 'foo', searchFields: 'title' }); | ||
expect(query).to.eql({ | ||
query: { | ||
bool: { | ||
filter: [], | ||
must: [{ | ||
simple_query_string: { | ||
query: 'foo', | ||
fields: ['title'] | ||
} | ||
}] | ||
} | ||
}, | ||
version: true | ||
}); | ||
}); | ||
|
||
it('can search across multiple fields', () => { | ||
const query = createFindQuery({ search: 'foo', searchFields: ['title', 'description'] }); | ||
expect(query).to.eql({ | ||
query: { | ||
bool: { | ||
filter: [], | ||
must: [{ | ||
simple_query_string: { | ||
query: 'foo', | ||
fields: ['title', 'description'] | ||
} | ||
}] | ||
} | ||
}, | ||
version: true | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.