Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport workspace-pr-integr] Add workspace id in base path #295

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 29 additions & 14 deletions src/core/public/http/base_path.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,35 +111,50 @@ describe('BasePath', () => {
});
});

describe('workspaceBasePath', () => {
it('get path with workspace', () => {
expect(new BasePath('/foo/bar', '/foo/bar', '/workspace').get()).toEqual(
'/foo/bar/workspace'
describe('clientBasePath', () => {
it('get with clientBasePath provided when construct', () => {
expect(new BasePath('/foo/bar', '/foo/bar', '/client_base_path').get()).toEqual(
'/foo/bar/client_base_path'
);
});

it('getBasePath with workspace provided', () => {
expect(new BasePath('/foo/bar', '/foo/bar', '/workspace').getBasePath()).toEqual('/foo/bar');
it('getBasePath with clientBasePath provided when construct', () => {
expect(new BasePath('/foo/bar', '/foo/bar', '/client_base_path').getBasePath()).toEqual(
'/foo/bar'
);
});

it('prepend with workspace provided', () => {
expect(new BasePath('/foo/bar', '/foo/bar', '/workspace').prepend('/prepend')).toEqual(
'/foo/bar/workspace/prepend'
it('prepend with clientBasePath provided when construct', () => {
expect(new BasePath('/foo/bar', '/foo/bar', '/client_base_path').prepend('/prepend')).toEqual(
'/foo/bar/client_base_path/prepend'
);
});

it('prepend with workspace provided but calls without workspace', () => {
it('construct with clientBasePath provided but calls prepend with withoutClientBasePath is true', () => {
expect(
new BasePath('/foo/bar', '/foo/bar', '/workspace').prepend('/prepend', {
withoutWorkspace: true,
new BasePath('/foo/bar', '/foo/bar', '/client_base_path').prepend('/prepend', {
withoutClientBasePath: true,
})
).toEqual('/foo/bar/prepend');
});

it('remove with workspace provided', () => {
it('remove with clientBasePath provided when construct', () => {
expect(
new BasePath('/foo/bar', '/foo/bar', '/workspace').remove('/foo/bar/workspace/remove')
new BasePath('/foo/bar', '/foo/bar', '/client_base_path').remove(
'/foo/bar/client_base_path/remove'
)
).toEqual('/remove');
});

it('construct with clientBasePath provided but calls remove with withoutClientBasePath is true', () => {
expect(
new BasePath('/foo/bar', '/foo/bar', '/client_base_path').remove(
'/foo/bar/client_base_path/remove',
{
withoutClientBasePath: true,
}
)
).toEqual('/client_base_path/remove');
});
});
});
12 changes: 6 additions & 6 deletions src/core/public/http/base_path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,20 @@ export class BasePath {
constructor(
private readonly basePath: string = '',
public readonly serverBasePath: string = basePath,
private readonly workspaceBasePath: string = ''
private readonly clientBasePath: string = ''
) {}

public get = () => {
return `${this.basePath}${this.workspaceBasePath}`;
return `${this.basePath}${this.clientBasePath}`;
};

public getBasePath = () => {
return this.basePath;
};

public prepend = (path: string, prependOptions?: PrependOptions): string => {
const { withoutWorkspace } = prependOptions || {};
const basePath = withoutWorkspace ? this.basePath : this.get();
const { withoutClientBasePath } = prependOptions || {};
const basePath = withoutClientBasePath ? this.basePath : this.get();
if (!basePath) return path;
return modifyUrl(path, (parts) => {
if (!parts.hostname && parts.pathname && parts.pathname.startsWith('/')) {
Expand All @@ -58,8 +58,8 @@ export class BasePath {
};

public remove = (path: string, prependOptions?: PrependOptions): string => {
const { withoutWorkspace } = prependOptions || {};
const basePath = withoutWorkspace ? this.basePath : this.get();
const { withoutClientBasePath } = prependOptions || {};
const basePath = withoutClientBasePath ? this.basePath : this.get();
if (!basePath) {
return path;
}
Expand Down
10 changes: 5 additions & 5 deletions src/core/public/http/http_service.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export type HttpSetupMock = jest.Mocked<HttpSetup> & {
anonymousPaths: jest.Mocked<HttpSetup['anonymousPaths']>;
};

const createServiceMock = ({ basePath = '', workspaceBasePath = '' } = {}): HttpSetupMock => ({
const createServiceMock = ({ basePath = '', clientBasePath = '' } = {}): HttpSetupMock => ({
fetch: jest.fn(),
get: jest.fn(),
head: jest.fn(),
Expand All @@ -48,7 +48,7 @@ const createServiceMock = ({ basePath = '', workspaceBasePath = '' } = {}): Http
patch: jest.fn(),
delete: jest.fn(),
options: jest.fn(),
basePath: new BasePath(basePath, undefined, workspaceBasePath),
basePath: new BasePath(basePath, undefined, clientBasePath),
anonymousPaths: {
register: jest.fn(),
isAnonymous: jest.fn(),
Expand All @@ -58,14 +58,14 @@ const createServiceMock = ({ basePath = '', workspaceBasePath = '' } = {}): Http
intercept: jest.fn(),
});

const createMock = ({ basePath = '', workspaceBasePath = '' } = {}) => {
const createMock = ({ basePath = '', clientBasePath = '' } = {}) => {
const mocked: jest.Mocked<PublicMethodsOf<HttpService>> = {
setup: jest.fn(),
start: jest.fn(),
stop: jest.fn(),
};
mocked.setup.mockReturnValue(createServiceMock({ basePath, workspaceBasePath }));
mocked.start.mockReturnValue(createServiceMock({ basePath, workspaceBasePath }));
mocked.setup.mockReturnValue(createServiceMock({ basePath, clientBasePath }));
mocked.start.mockReturnValue(createServiceMock({ basePath, clientBasePath }));
return mocked;
};

Expand Down
6 changes: 3 additions & 3 deletions src/core/public/http/http_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,15 @@ export class HttpService implements CoreService<HttpSetup, HttpStart> {

public setup({ injectedMetadata, fatalErrors }: HttpDeps): HttpSetup {
const opensearchDashboardsVersion = injectedMetadata.getOpenSearchDashboardsVersion();
let workspaceBasePath = '';
let clientBasePath = '';
const workspaceId = getWorkspaceIdFromUrl(window.location.href);
if (workspaceId) {
workspaceBasePath = `${WORKSPACE_PATH_PREFIX}/${workspaceId}`;
clientBasePath = `${WORKSPACE_PATH_PREFIX}/${workspaceId}`;
}
const basePath = new BasePath(
injectedMetadata.getBasePath(),
injectedMetadata.getServerBasePath(),
workspaceBasePath
clientBasePath
);
const fetchService = new Fetch({ basePath, opensearchDashboardsVersion });
const loadingCount = this.loadingCount.setup({ fatalErrors });
Expand Down
17 changes: 10 additions & 7 deletions src/core/public/http/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,14 @@ export type HttpStart = HttpSetup;
/**
* prepend options
*
* withoutWorkspace option will prepend a relative url with only basePath
* workspaceId will rewrite the /w/{workspaceId} part, if workspace id is an empty string, prepend will remove the workspaceId part
* withoutClientBasePath option will prepend a relative url with serverBasePath only.
* For now, clientBasePath is consist of:
* workspacePath, which has the pattern of /w/{workspaceId}.
*
* In the future, clientBasePath may have other parts but keep `withoutClientBasePath` for now to not over-design the interface,
*/
export interface PrependOptions {
withoutWorkspace?: boolean;
withoutClientBasePath?: boolean;
}

/**
Expand All @@ -103,22 +106,22 @@ export interface PrependOptions {
*/
export interface IBasePath {
/**
* Gets the `basePath + workspace` string.
* Gets the `basePath + clientBasePath` string.
*/
get: () => string;

/**
* Gets the `basePath
* Gets the `basePath` string
*/
getBasePath: () => string;

/**
* Prepends `path` with the basePath + workspace.
* Prepends `path` with the basePath + clientBasePath.
*/
prepend: (url: string, prependOptions?: PrependOptions) => string;

/**
* Removes the prepended basePath + workspace from the `path`.
* Removes the prepended basePath + clientBasePath from the `path`.
*/
remove: (url: string, prependOptions?: PrependOptions) => string;

Expand Down
14 changes: 11 additions & 3 deletions src/core/utils/workspace.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,27 @@ describe('#getWorkspaceIdFromUrl', () => {
it('return empty when there is not a match', () => {
expect(getWorkspaceIdFromUrl('http://localhost/w2/foo')).toEqual('');
});

it('return workspace when there is a match with basePath provided', () => {
expect(getWorkspaceIdFromUrl('http://localhost/basepath/w/foo', '/basepath')).toEqual('foo');
});

it('return empty when there is a match without basePath but basePath provided', () => {
expect(getWorkspaceIdFromUrl('http://localhost/w/foo', '/w')).toEqual('');
});
});

describe('#formatUrlWithWorkspaceId', () => {
const basePathWithoutWorkspaceBasePath = httpServiceMock.createSetupContract().basePath;
const basePathWithoutClientBasePath = httpServiceMock.createSetupContract().basePath;
it('return url with workspace prefix when format with a id provided', () => {
expect(
formatUrlWithWorkspaceId('/app/dashboard', 'foo', basePathWithoutWorkspaceBasePath)
formatUrlWithWorkspaceId('/app/dashboard', 'foo', basePathWithoutClientBasePath)
).toEqual('http://localhost/w/foo/app/dashboard');
});

it('return url without workspace prefix when format without a id', () => {
expect(
formatUrlWithWorkspaceId('/w/foo/app/dashboard', '', basePathWithoutWorkspaceBasePath)
formatUrlWithWorkspaceId('/w/foo/app/dashboard', '', basePathWithoutClientBasePath)
).toEqual('http://localhost/app/dashboard');
});
});
Loading
Loading