Skip to content

Commit

Permalink
Use savedObjectsClient.resolve in saved query service (elastic#111229)
Browse files Browse the repository at this point in the history
* Use resolve instead of get for saved query service

* Update tests

* Update src/plugins/data/public/query/saved_query/saved_query_service.ts

Co-authored-by: Joe Portner <5295965+jportner@users.noreply.github.com>

* Revert step 4

* Fix test

Co-authored-by: Joe Portner <5295965+jportner@users.noreply.github.com>
  • Loading branch information
2 people authored and kibanamachine committed Sep 13, 2021
1 parent d3f231c commit 774289f
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 39 deletions.
113 changes: 76 additions & 37 deletions src/plugins/data/public/query/saved_query/saved_query_service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const mockSavedObjectsClient = {
create: jest.fn(),
error: jest.fn(),
find: jest.fn(),
get: jest.fn(),
resolve: jest.fn(),
delete: jest.fn(),
};

Expand All @@ -74,7 +74,7 @@ describe('saved query service', () => {
afterEach(() => {
mockSavedObjectsClient.create.mockReset();
mockSavedObjectsClient.find.mockReset();
mockSavedObjectsClient.get.mockReset();
mockSavedObjectsClient.resolve.mockReset();
mockSavedObjectsClient.delete.mockReset();
});

Expand Down Expand Up @@ -267,85 +267,124 @@ describe('saved query service', () => {

describe('getSavedQuery', function () {
it('should retrieve a saved query by id', async () => {
mockSavedObjectsClient.get.mockReturnValue({ id: 'foo', attributes: savedQueryAttributes });
mockSavedObjectsClient.resolve.mockReturnValue({
saved_object: {
id: 'foo',
attributes: savedQueryAttributes,
},
outcome: 'exactMatch',
});

const response = await getSavedQuery('foo');
expect(response).toEqual({ id: 'foo', attributes: savedQueryAttributes });
});
it('should only return saved queries', async () => {
mockSavedObjectsClient.get.mockReturnValue({ id: 'foo', attributes: savedQueryAttributes });
mockSavedObjectsClient.resolve.mockReturnValue({
saved_object: {
id: 'foo',
attributes: savedQueryAttributes,
},
outcome: 'exactMatch',
});

await getSavedQuery('foo');
expect(mockSavedObjectsClient.get).toHaveBeenCalledWith('query', 'foo');
expect(mockSavedObjectsClient.resolve).toHaveBeenCalledWith('query', 'foo');
});

it('should parse a json query', async () => {
mockSavedObjectsClient.get.mockReturnValue({
id: 'food',
attributes: {
title: 'food',
description: 'bar',
query: {
language: 'kuery',
query: '{"x": "y"}',
mockSavedObjectsClient.resolve.mockReturnValue({
saved_object: {
id: 'food',
attributes: {
title: 'food',
description: 'bar',
query: {
language: 'kuery',
query: '{"x": "y"}',
},
},
},
outcome: 'exactMatch',
});

const response = await getSavedQuery('food');
expect(response.attributes.query.query).toEqual({ x: 'y' });
});

it('should handle null string', async () => {
mockSavedObjectsClient.get.mockReturnValue({
id: 'food',
attributes: {
title: 'food',
description: 'bar',
query: {
language: 'kuery',
query: 'null',
mockSavedObjectsClient.resolve.mockReturnValue({
saved_object: {
id: 'food',
attributes: {
title: 'food',
description: 'bar',
query: {
language: 'kuery',
query: 'null',
},
},
},
outcome: 'exactMatch',
});

const response = await getSavedQuery('food');
expect(response.attributes.query.query).toEqual('null');
});

it('should handle null quoted string', async () => {
mockSavedObjectsClient.get.mockReturnValue({
id: 'food',
attributes: {
title: 'food',
description: 'bar',
query: {
language: 'kuery',
query: '"null"',
mockSavedObjectsClient.resolve.mockReturnValue({
saved_object: {
id: 'food',
attributes: {
title: 'food',
description: 'bar',
query: {
language: 'kuery',
query: '"null"',
},
},
},
outcome: 'exactMatch',
});

const response = await getSavedQuery('food');
expect(response.attributes.query.query).toEqual('"null"');
});

it('should not lose quotes', async () => {
mockSavedObjectsClient.get.mockReturnValue({
id: 'food',
attributes: {
title: 'food',
description: 'bar',
query: {
language: 'kuery',
query: '"Bob"',
mockSavedObjectsClient.resolve.mockReturnValue({
saved_object: {
id: 'food',
attributes: {
title: 'food',
description: 'bar',
query: {
language: 'kuery',
query: '"Bob"',
},
},
},
outcome: 'exactMatch',
});

const response = await getSavedQuery('food');
expect(response.attributes.query.query).toEqual('"Bob"');
});

it('should throw if conflict', async () => {
mockSavedObjectsClient.resolve.mockReturnValue({
saved_object: {
id: 'foo',
attributes: savedQueryAttributes,
},
outcome: 'conflict',
});

const result = getSavedQuery('food');
expect(result).rejects.toMatchInlineSnapshot(
`[Error: Multiple saved queries found with ID: food (legacy URL alias conflict)]`
);
});
});

describe('deleteSavedQuery', function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,13 @@ export const createSavedQueryService = (
};

const getSavedQuery = async (id: string): Promise<SavedQuery> => {
const savedObject = await savedObjectsClient.get<SerializedSavedQueryAttributes>('query', id);
if (savedObject.error) {
const {
saved_object: savedObject,
outcome,
} = await savedObjectsClient.resolve<SerializedSavedQueryAttributes>('query', id);
if (outcome === 'conflict') {
throw new Error(`Multiple saved queries found with ID: ${id} (legacy URL alias conflict)`);
} else if (savedObject.error) {
throw new Error(savedObject.error.message);
}
return parseSavedQueryObject(savedObject);
Expand Down

0 comments on commit 774289f

Please sign in to comment.