diff --git a/src/field-selection.spec.ts b/src/field-selection.spec.ts index 5bdbe3b0..0a5a2058 100644 --- a/src/field-selection.spec.ts +++ b/src/field-selection.spec.ts @@ -20,14 +20,18 @@ describe('selectFields()', () => { const instances = selectFields(req, ['foo', 'baz'], ['cookies']); expect(instances).toHaveLength(2); - expect(instances[0]).toMatchObject({ + expect(instances[0]).toEqual({ location: 'cookies', path: 'foo', + originalPath: 'foo', + pathValues: [], value: 'bar', }); - expect(instances[1]).toMatchObject({ + expect(instances[1]).toEqual({ location: 'cookies', path: 'baz', + originalPath: 'baz', + pathValues: [], value: 'qux', }); }); @@ -114,14 +118,19 @@ describe('selectFields()', () => { const req = { query: { foo: ['bar', 'baz'] }, }; - const instances = selectFields(req, ['foo[1]'], ['query']); + const instances = selectFields(req, ['foo[1]', 'foo[2]'], ['query']); - expect(instances).toHaveLength(1); + expect(instances).toHaveLength(2); expect(instances[0]).toMatchObject({ location: 'query', path: 'foo[1]', value: 'baz', }); + expect(instances[1]).toMatchObject({ + location: 'query', + path: 'foo[2]', + value: undefined, + }); }); it('selects from headers using lowercase', () => { @@ -155,7 +164,7 @@ describe('selectFields()', () => { }); it('selects inexistent properties', () => { - const instances = selectFields({}, ['foo.bar.baz'], ['cookies']); + const instances = selectFields({ cookies: {} }, ['foo.bar.baz'], ['cookies']); expect(instances).toHaveLength(1); expect(instances[0]).toEqual({ @@ -167,14 +176,24 @@ describe('selectFields()', () => { }); }); - it('does not select properties of primitives', () => { + it('selects properties of primitives', () => { const req = { body: { foo: 1 }, }; - const instances = selectFields(req, ['foo.toFixed'], ['body']); - expect(instances).toHaveLength(0); - }); + const instances = selectFields(req, ['foo.toFixed', 'foo.nop'], ['body']); + expect(instances).toHaveLength(2); + expect(instances[0]).toMatchObject({ + location: 'body', + path: 'foo.toFixed', + value: expect.any(Function), + }); + expect(instances[1]).toMatchObject({ + location: 'body', + path: 'foo.nop', + value: undefined, + }); + }); it('deduplicates field instances', () => { const req = { body: { diff --git a/src/field-selection.ts b/src/field-selection.ts index 067cf41c..0e1981e4 100644 --- a/src/field-selection.ts +++ b/src/field-selection.ts @@ -68,18 +68,29 @@ function expandPath( const rest = segments.slice(1); if (object != null && !_.isObjectLike(object)) { - if (key === '**' && !rest.length) { - // globstar leaves are always selected - return [ - { - path: reconstructFieldPath(currPath), - values: currValues, - }, - ]; + if (key === '**') { + if (!rest.length) { + // globstar leaves are always selected + return [ + { + path: reconstructFieldPath(currPath), + values: currValues, + }, + ]; + } + return []; } - - // there still are paths to traverse, but value is a primitive, stop - return []; + if (key === '*') { + // wildcard position does not exist + return []; + } + // value is a primitive, paths being traversed from here might be in their prototype, return the entire path + return [ + { + path: reconstructFieldPath([...currPath, ...segments]), + values: currValues, + }, + ]; } // Use a non-null value so that inexistent fields are still selected