Skip to content

Commit

Permalink
[1.x][Backwards Compatibility] restore URL forwarding from legacy app
Browse files Browse the repository at this point in the history
Forwarding legacy app to the current format of the application.
This enables the usage of stored URLs and other links that referenced
the format of the application URL that mentioned the application name.

Since we changed the URL forwarding we changed this value and released.
So incase forks were made and depended on this legacy formatted reference
of the application. It will still work. There are also references of the
application.

Issue resolved:
opensearch-project#1013

Backport PR:
opensearch-project#1021

Signed-off-by: Kawika Avilla <kavilla414@gmail.com>
  • Loading branch information
kavilla committed Jan 10, 2022
1 parent 14407c0 commit bd72294
Show file tree
Hide file tree
Showing 9 changed files with 1,342 additions and 1 deletion.
29 changes: 29 additions & 0 deletions src/plugins/data/common/field_formats/converters/url.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,5 +306,34 @@ describe('UrlFormat', () => {
'<span ng-non-bindable><a href="http://opensearch-dashboards.host.com/app/opensearch-dashboards#/dashboard/" target="_blank" rel="noopener noreferrer">#/dashboard/</a></span>'
);
});

test('should support multiple types of urls w/o basePath from legacy app', () => {
const parsedUrl = {
origin: 'http://opensearch-dashboards.host.com',
pathname: '/app/kibana',
};
const url = new UrlFormat({ parsedUrl });
const converter = url.getConverterFor(HTML_CONTEXT_TYPE) as Function;

expect(converter('10.22.55.66')).toBe(
'<span ng-non-bindable><a href="http://opensearch-dashboards.host.com/app/10.22.55.66" target="_blank" rel="noopener noreferrer">10.22.55.66</a></span>'
);

expect(converter('http://www.domain.name/app/kibana#/dashboard/')).toBe(
'<span ng-non-bindable><a href="http://www.domain.name/app/kibana#/dashboard/" target="_blank" rel="noopener noreferrer">http://www.domain.name/app/kibana#/dashboard/</a></span>'
);

expect(converter('/app/kibana')).toBe(
'<span ng-non-bindable><a href="http://opensearch-dashboards.host.com/app/kibana" target="_blank" rel="noopener noreferrer">/app/kibana</a></span>'
);

expect(converter('kibana#/dashboard/')).toBe(
'<span ng-non-bindable><a href="http://opensearch-dashboards.host.com/app/kibana#/dashboard/" target="_blank" rel="noopener noreferrer">kibana#/dashboard/</a></span>'
);

expect(converter('#/dashboard/')).toBe(
'<span ng-non-bindable><a href="http://opensearch-dashboards.host.com/app/kibana#/dashboard/" target="_blank" rel="noopener noreferrer">#/dashboard/</a></span>'
);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,22 @@ describe('format', () => {
`"http://localhost:5601/oxf/app/opensearch-dashboards#?test=test&test1=test1"`
);
});

it('should add hash query to url without hash with legacy app', () => {
const url = 'http://localhost:5601/oxf/app/kibana';
expect(replaceUrlHashQuery(url, () => ({ test: 'test' }))).toMatchInlineSnapshot(
`"http://localhost:5601/oxf/app/kibana#?test=test"`
);
});

it('should replace hash query with legacy app', () => {
const url = 'http://localhost:5601/oxf/app/kibana#?test=test';
expect(
replaceUrlHashQuery(url, (query) => ({
...query,
test1: 'test1',
}))
).toMatchInlineSnapshot(`"http://localhost:5601/oxf/app/kibana#?test=test&test1=test1"`);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,36 @@ describe('hash unhash url', () => {
expect(hashUrl(url)).toBe(url);
});

it('if just a path with legacy app', () => {
const url = 'https://localhost:5601/app/kibana';
expect(hashUrl(url)).toBe(url);
});

it('if just a path and query with legacy app', () => {
const url = 'https://localhost:5601/app/kibana?foo=bar';
expect(hashUrl(url)).toBe(url);
});

it('if empty hash with query with legacy app', () => {
const url = 'https://localhost:5601/app/kibana?foo=bar#';
expect(hashUrl(url)).toBe(url);
});

it('if query parameter matches and there is no hash with legacy app', () => {
const url = 'https://localhost:5601/app/kibana?testParam=(yes:!t)';
expect(hashUrl(url)).toBe(url);
});

it(`if query parameter matches and it's before the hash with legacy app`, () => {
const url = 'https://localhost:5601/app/kibana?testParam=(yes:!t)';
expect(hashUrl(url)).toBe(url);
});

it('if empty hash without query with legacy app', () => {
const url = 'https://localhost:5601/app/kibana#';
expect(hashUrl(url)).toBe(url);
});

it('if hash is just a path', () => {
const url = 'https://localhost:5601/app/discover#/';
expect(hashUrl(url)).toBe(url);
Expand Down Expand Up @@ -189,6 +219,26 @@ describe('hash unhash url', () => {
expect(unhashUrl(url)).toBe(url);
});

it('if just a path with legacy app', () => {
const url = 'https://localhost:5601/app/kibana';
expect(unhashUrl(url)).toBe(url);
});

it('if just a path and query with legacy app', () => {
const url = 'https://localhost:5601/app/kibana?foo=bar';
expect(unhashUrl(url)).toBe(url);
});

it('if empty hash with query with legacy app', () => {
const url = 'https://localhost:5601/app/kibana?foo=bar#';
expect(unhashUrl(url)).toBe(url);
});

it('if empty hash without query with legacy app', () => {
const url = 'https://localhost:5601/app/kibana#';
expect(unhashUrl(url)).toBe(url);
});

it('if hash is just a path', () => {
const url = 'https://localhost:5601/app/discover#/';
expect(unhashUrl(url)).toBe(url);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import { ScopedHistory } from '../../../../../core/public';
describe('osd_url_storage', () => {
describe('getStateFromUrl & setStateToUrl', () => {
const url = 'http://localhost:5601/oxf/app/opensearch-dashboards#/yourApp';
const legacyUrl = 'http://localhost:5601/oxf/app/kibana#/yourApp';
const state1 = {
testStr: '123',
testNumber: 0,
Expand Down Expand Up @@ -112,6 +113,59 @@ describe('osd_url_storage', () => {
`"http://localhost:5601/oxf/app/opensearch-dashboards/yourApp?_a=(tab:other)&_b=(f:test,i:'',l:'')"`
);
});

it('should set expanded state to url for legacy app', () => {
let newUrl = setStateToOsdUrl('_s', state1, { useHash: false }, legacyUrl);
expect(newUrl).toMatchInlineSnapshot(
`"http://localhost:5601/oxf/app/kibana#/yourApp?_s=(testArray:!(1,2,()),testNull:!n,testNumber:0,testObj:(test:'123'),testStr:'123')"`
);
const retrievedState1 = getStateFromOsdUrl('_s', newUrl);
expect(retrievedState1).toEqual(state1);

newUrl = setStateToOsdUrl('_s', state2, { useHash: false }, newUrl);
expect(newUrl).toMatchInlineSnapshot(
`"http://localhost:5601/oxf/app/kibana#/yourApp?_s=(test:'123')"`
);
const retrievedState2 = getStateFromOsdUrl('_s', newUrl);
expect(retrievedState2).toEqual(state2);
});

it('should set hashed state to url for legacy app', () => {
let newUrl = setStateToOsdUrl('_s', state1, { useHash: true }, legacyUrl);
expect(newUrl).toMatchInlineSnapshot(
`"http://localhost:5601/oxf/app/kibana#/yourApp?_s=h@a897fac"`
);
const retrievedState1 = getStateFromOsdUrl('_s', newUrl);
expect(retrievedState1).toEqual(state1);

newUrl = setStateToOsdUrl('_s', state2, { useHash: true }, newUrl);
expect(newUrl).toMatchInlineSnapshot(
`"http://localhost:5601/oxf/app/kibana#/yourApp?_s=h@40f94d5"`
);
const retrievedState2 = getStateFromOsdUrl('_s', newUrl);
expect(retrievedState2).toEqual(state2);
});

it('should set query to url for legacy app with storeInHashQuery: false', () => {
let newUrl = setStateToOsdUrl(
'_a',
{ tab: 'other' },
{ useHash: false, storeInHashQuery: false },
'http://localhost:5601/oxf/app/kibana/yourApp'
);
expect(newUrl).toMatchInlineSnapshot(
`"http://localhost:5601/oxf/app/kibana/yourApp?_a=(tab:other)"`
);
newUrl = setStateToOsdUrl(
'_b',
{ f: 'test', i: '', l: '' },
{ useHash: false, storeInHashQuery: false },
newUrl
);
expect(newUrl).toMatchInlineSnapshot(
`"http://localhost:5601/oxf/app/kibana/yourApp?_a=(tab:other)&_b=(f:test,i:'',l:'')"`
);
});
});

describe('urlControls', () => {
Expand Down Expand Up @@ -333,4 +387,91 @@ describe('osd_url_storage', () => {
expect(relativePath).toEqual("/yourApp?_a=(tab:indexedFields)&_b=(f:test,i:'',l:'')");
});
});

describe('urlControls - scoped history integration - legacy app', () => {
let history: History;
let urlControls: IOsdUrlControls;
beforeEach(() => {
const parentHistory = createBrowserHistory();
parentHistory.replace('/app/kibana/');
history = new ScopedHistory(parentHistory, '/app/kibana/');
urlControls = createOsdUrlControls(history);
});

const getCurrentUrl = () => history.createHref(history.location);

it('should flush async url updates', async () => {
const pr1 = urlControls.updateAsync(() => '/app/kibana/1', false);
const pr2 = urlControls.updateAsync(() => '/app/kibana/2', false);
const pr3 = urlControls.updateAsync(() => '/app/kibana/3', false);
expect(getCurrentUrl()).toBe('/app/kibana/');
expect(urlControls.flush()).toBe('/app/kibana/3');
expect(getCurrentUrl()).toBe('/app/kibana/3');
await Promise.all([pr1, pr2, pr3]);
expect(getCurrentUrl()).toBe('/app/kibana/3');
});

it('flush() should return undefined, if no url updates happened', () => {
expect(urlControls.flush()).toBeUndefined();
urlControls.updateAsync(() => '/app/kibana/1', false);
urlControls.updateAsync(() => '/app/kibana/', false);
expect(urlControls.flush()).toBeUndefined();
});
});

describe('getRelativeToHistoryPath - legacy app', () => {
it('should extract path relative to browser history without basename', () => {
const history = createBrowserHistory();
const url =
"http://localhost:5601/oxf/app/kibana#/yourApp?_a=(tab:indexedFields)&_b=(f:test,i:'',l:'')";
const relativePath = getRelativeToHistoryPath(url, history);
expect(relativePath).toEqual(
"/oxf/app/kibana#/yourApp?_a=(tab:indexedFields)&_b=(f:test,i:'',l:'')"
);
});

it('should extract path relative to browser history with basename', () => {
const url =
"http://localhost:5601/oxf/app/kibana#/yourApp?_a=(tab:indexedFields)&_b=(f:test,i:'',l:'')";
const history1 = createBrowserHistory({ basename: '/oxf/app/' });
const relativePath1 = getRelativeToHistoryPath(url, history1);
expect(relativePath1).toEqual(
"/kibana#/yourApp?_a=(tab:indexedFields)&_b=(f:test,i:'',l:'')"
);

const history2 = createBrowserHistory({ basename: '/oxf/app/kibana/' });
const relativePath2 = getRelativeToHistoryPath(url, history2);
expect(relativePath2).toEqual("#/yourApp?_a=(tab:indexedFields)&_b=(f:test,i:'',l:'')");
});

it('should extract path relative to browser history with basename from relative url', () => {
const history = createBrowserHistory({ basename: '/oxf/app/' });
const url = "/oxf/app/kibana#/yourApp?_a=(tab:indexedFields)&_b=(f:test,i:'',l:'')";
const relativePath = getRelativeToHistoryPath(url, history);
expect(relativePath).toEqual("/kibana#/yourApp?_a=(tab:indexedFields)&_b=(f:test,i:'',l:'')");
});

it('should extract path relative to hash history without basename', () => {
const history = createHashHistory();
const url =
"http://localhost:5601/oxf/app/kibana#/yourApp?_a=(tab:indexedFields)&_b=(f:test,i:'',l:'')";
const relativePath = getRelativeToHistoryPath(url, history);
expect(relativePath).toEqual("/yourApp?_a=(tab:indexedFields)&_b=(f:test,i:'',l:'')");
});

it('should extract path relative to hash history with basename', () => {
const history = createHashHistory({ basename: 'management' });
const url =
"http://localhost:5601/oxf/app/kibana#/yourApp?_a=(tab:indexedFields)&_b=(f:test,i:'',l:'')";
const relativePath = getRelativeToHistoryPath(url, history);
expect(relativePath).toEqual("/yourApp?_a=(tab:indexedFields)&_b=(f:test,i:'',l:'')");
});

it('should extract path relative to hash history with basename from relative url', () => {
const history = createHashHistory({ basename: 'management' });
const url = "/oxf/app/kibana#/yourApp?_a=(tab:indexedFields)&_b=(f:test,i:'',l:'')";
const relativePath = getRelativeToHistoryPath(url, history);
expect(relativePath).toEqual("/yourApp?_a=(tab:indexedFields)&_b=(f:test,i:'',l:'')");
});
});
});
Loading

0 comments on commit bd72294

Please sign in to comment.