kibana/packages/kbn-rison/kbn_rison.test.ts
Maxim Palenov 4a93da0ba3
[Security Solution] Global query string functionality improvements (#147218)
Addresses: https://github.com/elastic/kibana/issues/140263

This PR was inspired by https://github.com/elastic/kibana/pull/146649 and while working on persistent rules table state https://github.com/elastic/kibana/pull/145111.

## Summary

It includes improvements for url search parameters manipulation functionality. In particular `useGetInitialUrlParamValue` and `useReplaceUrlParams` hooks.

The main idea is to isolate the encoding layer ([rison](https://github.com/Nanonid/rison)) as an implementation detail so `useGetInitialUrlParamValue` and `useReplaceUrlParams` consumers can just provide types they wish and the hooks serialize/desirealize the data into appropriate format under the hood.

On top of that after `@kbn/rison` was added in https://github.com/elastic/kibana/pull/146649 it's possible to use this package directly to encode and decode parameters whenever necessary.

The improvements include
- store unserialized url parameters state in the redux store
- encode and decode data by using functions from `@kbn/rison` directly
- let `useReplaceUrlParams` accept an updater object

### Checklist

- [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios
2023-01-05 18:02:12 +01:00

99 lines
3 KiB
TypeScript

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import * as Rison from './kbn_rison';
describe('encoding', () => {
it('encodes basic values', () => {
expect(Rison.encode(false)).toMatchInlineSnapshot(`"!f"`);
expect(Rison.encode(true)).toMatchInlineSnapshot(`"!t"`);
expect(Rison.encode(1)).toMatchInlineSnapshot(`"1"`);
expect(Rison.encode([1])).toMatchInlineSnapshot(`"!(1)"`);
expect(Rison.encode(['1'])).toMatchInlineSnapshot(`"!('1')"`);
expect(Rison.encode([null])).toMatchInlineSnapshot(`"!(!n)"`);
expect(Rison.encode([undefined])).toMatchInlineSnapshot(`"!()"`);
expect(Rison.encode(null)).toMatchInlineSnapshot(`"!n"`);
});
it('throws if it received undefined', () => {
expect(() => Rison.encode(undefined)).toThrowErrorMatchingInlineSnapshot(
`"unable to encode value into rison, expected a primitive value array or object"`
);
});
it('encodes a complex object', () => {
expect(
Rison.encode({
foo: 1,
bar: {
bax: 1,
bar: [
'x',
{
a: /foo/,
b: new Date(0),
},
],
},
})
).toMatchInlineSnapshot(`"(bar:(bar:!(x,(a:(),b:'1970-01-01T00:00:00.000Z')),bax:1),foo:1)"`);
});
it('encodes arrays directly as well', () => {
expect(Rison.encodeArray([1, 2, 3])).toMatchInlineSnapshot(`"1,2,3"`);
});
});
describe('decoding', () => {
it('decodes a simple rison string', () => {
expect(Rison.decode('!f')).toMatchInlineSnapshot(`false`);
expect(Rison.decode('!t')).toMatchInlineSnapshot(`true`);
expect(Rison.decode('1')).toMatchInlineSnapshot(`1`);
expect(Rison.decode('!(1)')).toMatchInlineSnapshot(`
Array [
1,
]
`);
expect(Rison.decode("!('1')")).toMatchInlineSnapshot(`
Array [
"1",
]
`);
expect(Rison.decode('!(!n)')).toMatchInlineSnapshot(`
Array [
null,
]
`);
expect(Rison.decode('!()')).toMatchInlineSnapshot(`Array []`);
expect(Rison.decode('!n')).toMatchInlineSnapshot(`null`);
});
it('decodes a complex rison string', () => {
expect(Rison.decode(`(bar:(bar:!(x,(a:(),b:'1970-01-01T00:00:00.000Z')),bax:1),foo:1)`))
.toMatchInlineSnapshot(`
Object {
"bar": Object {
"bar": Array [
"x",
Object {
"a": Object {},
"b": "1970-01-01T00:00:00.000Z",
},
],
"bax": 1,
},
"foo": 1,
}
`);
});
it('decodes an encoded array', () => {
expect(Rison.decodeArray('1,2,3')).toMatchInlineSnapshot(`
Array [
1,
2,
3,
]
`);
});
});