Skip to content

Commit

Permalink
[Lens] Simplify request to determine existing fields
Browse files Browse the repository at this point in the history
  • Loading branch information
wylieconlon committed Oct 1, 2020
1 parent 198c5d9 commit 912fe00
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 235 deletions.
127 changes: 18 additions & 109 deletions x-pack/plugins/lens/server/routes/existing_fields.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,99 +14,65 @@ describe('existingFields', () => {
return {
name,
isScript: false,
isAlias: false,
isMeta: false,
path: name.split('.'),
path: name,
...obj,
};
}

function indexPattern(_source: unknown, fields: unknown = {}) {
return { _source, fields };
function searchResults(fields: Record<string, unknown[]> = {}) {
return { fields };
}

it('should handle root level fields', () => {
const result = existingFields(
[indexPattern({ foo: 'bar' }), indexPattern({ baz: 0 })],
[searchResults({ foo: ['bar'] }), searchResults({ baz: [0] })],
[field('foo'), field('bar'), field('baz')]
);

expect(result).toEqual(['foo', 'baz']);
});

it('should handle arrays of objects', () => {
it('should handle basic arrays, ignoring empty ones', () => {
const result = existingFields(
[indexPattern({ stuff: [{ foo: 'bar' }, { baz: 0 }] })],
[field('stuff.foo'), field('stuff.bar'), field('stuff.baz')]
[searchResults({ stuff: ['heyo', 'there'], empty: [] })],
[field('stuff'), field('empty')]
);

expect(result).toEqual(['stuff.foo', 'stuff.baz']);
});

it('should handle basic arrays', () => {
const result = existingFields([indexPattern({ stuff: ['heyo', 'there'] })], [field('stuff')]);

expect(result).toEqual(['stuff']);
});

it('should handle deep object structures', () => {
const result = existingFields(
[indexPattern({ geo: { coordinates: { lat: 40, lon: -77 } } })],
[field('geo.coordinates')]
);

expect(result).toEqual(['geo.coordinates']);
});

it('should handle objects with dotted fields', () => {
const result = existingFields(
[indexPattern({ 'geo.country_name': 'US' })],
[searchResults({ 'geo.country_name': ['US'] })],
[field('geo.country_name')]
);

expect(result).toEqual(['geo.country_name']);
});

it('should handle arrays with dotted fields on both sides', () => {
const result = existingFields(
[indexPattern({ 'process.cpu': [{ 'user.pct': 50 }] })],
[field('process.cpu.user.pct')]
);

expect(result).toEqual(['process.cpu.user.pct']);
});

it('should be false if it hits a positive leaf before the end of the path', () => {
const result = existingFields(
[indexPattern({ geo: { coordinates: 32 } })],
[field('geo.coordinates.lat')]
);

expect(result).toEqual([]);
});

it('should use path, not name', () => {
const result = existingFields(
[indexPattern({ stuff: [{ foo: 'bar' }, { baz: 0 }] })],
[field({ name: 'goober', path: ['stuff', 'foo'] })]
[searchResults({ 'stuff.foo': ['bar'] })],
[field({ name: 'goober', path: 'stuff.foo' })]
);

expect(result).toEqual(['goober']);
});

it('supports scripted fields', () => {
const result = existingFields(
[indexPattern({}, { bar: 'scriptvalue' })],
[field({ name: 'baz', isScript: true, path: ['bar'] })]
[searchResults({ bar: ['scriptvalue'] })],
[field({ name: 'baz', isScript: true, path: 'bar' })]
);

expect(result).toEqual(['baz']);
});

it('supports meta fields', () => {
const result = existingFields(
[{ _mymeta: 'abc', ...indexPattern({}, { bar: 'scriptvalue' }) }],
[field({ name: '_mymeta', isMeta: true, path: ['_mymeta'] })]
[{ _mymeta: 'abc', ...searchResults({ bar: ['scriptvalue'] }) }],
[field({ name: '_mymeta', isMeta: true, path: '_mymeta' })]
);

expect(result).toEqual(['_mymeta']);
Expand All @@ -132,81 +98,24 @@ describe('buildFieldList', () => {
references: [],
};

const mappings = {
testpattern: {
mappings: {
properties: {
'@bar': {
type: 'alias',
path: 'bar',
},
},
},
},
};

const fieldDescriptors = [
{
name: 'baz',
subType: { multi: { parent: 'a.b.c' } },
},
];

it('uses field descriptors to determine the path', () => {
const fields = buildFieldList(indexPattern, mappings, fieldDescriptors, []);
expect(fields.find((f) => f.name === 'baz')).toMatchObject({
isAlias: false,
isScript: false,
name: 'baz',
path: ['a', 'b', 'c'],
});
});

it('uses aliases to determine the path', () => {
const fields = buildFieldList(indexPattern, mappings, fieldDescriptors, []);
expect(fields.find((f) => f.isAlias)).toMatchObject({
isAlias: true,
isScript: false,
name: '@bar',
path: ['bar'],
});
});

it('supports scripted fields', () => {
const fields = buildFieldList(indexPattern, mappings, fieldDescriptors, []);
const fields = buildFieldList(indexPattern, []);
expect(fields.find((f) => f.isScript)).toMatchObject({
isAlias: false,
isScript: true,
name: 'foo',
path: ['foo'],
path: 'foo',
lang: 'painless',
script: '2+2',
});
});

it('supports meta fields', () => {
const fields = buildFieldList(indexPattern, mappings, fieldDescriptors, ['_mymeta']);
const fields = buildFieldList(indexPattern, ['_mymeta']);
expect(fields.find((f) => f.isMeta)).toMatchObject({
isAlias: false,
isScript: false,
isMeta: true,
name: '_mymeta',
path: ['_mymeta'],
});
});

it('handles missing mappings', () => {
const fields = buildFieldList(indexPattern, {}, fieldDescriptors, []);
expect(fields.every((f) => f.isAlias === false)).toEqual(true);
});

it('handles empty fieldDescriptors by skipping multi-mappings', () => {
const fields = buildFieldList(indexPattern, mappings, [], []);
expect(fields.find((f) => f.name === 'baz')).toMatchObject({
isAlias: false,
isScript: false,
name: 'baz',
path: ['baz'],
path: '_mymeta',
});
});
});
Loading

0 comments on commit 912fe00

Please sign in to comment.