Skip to content

Commit

Permalink
[Workspace][Bug] Check if workspaces exists when creating saved objec…
Browse files Browse the repository at this point in the history
…ts (#8739)

* Check if workspaces exists when creating saved objects

Signed-off-by: yubonluo <[email protected]>

* Changeset file for PR #8739 created/updated

* optimize the code

Signed-off-by: yubonluo <[email protected]>

* fix test error

Signed-off-by: yubonluo <[email protected]>

* optimize the code

Signed-off-by: yubonluo <[email protected]>

* fix test errors

Signed-off-by: yubonluo <[email protected]>

* add integration tests

Signed-off-by: yubonluo <[email protected]>

---------

Signed-off-by: yubonluo <[email protected]>
Co-authored-by: opensearch-changeset-bot[bot] <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com>
  • Loading branch information
yubonluo and opensearch-changeset-bot[bot] authored Dec 3, 2024
1 parent 080b0db commit 340326f
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 80 deletions.
2 changes: 2 additions & 0 deletions changelogs/fragments/8739.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fix:
- [Workspace] [Bug] Check if workspaces exists when creating saved objects. ([#8739](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/8739))
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,35 @@ describe('workspace_id_consumer integration test', () => {
`/api/saved_objects/${config.type}/${packageInfo.version}`
);

// workspaces arrtibutes should not be append
// workspaces attributes should not be append
expect(!getConfigResult.body.workspaces).toEqual(true);
});

it('should return error when create with a not existing workspace', async () => {
await clearFooAndBar();
const createResultWithNonExistRequestWorkspace = await osdTestServer.request
.post(root, `/w/not_exist_workspace_id/api/saved_objects/${dashboard.type}`)
.send({
attributes: dashboard.attributes,
})
.expect(400);

expect(createResultWithNonExistRequestWorkspace.body.message).toEqual(
'Exist invalid workspaces'
);

const createResultWithNonExistOptionsWorkspace = await osdTestServer.request
.post(root, `/api/saved_objects/${dashboard.type}`)
.send({
attributes: dashboard.attributes,
workspaces: ['not_exist_workspace_id'],
})
.expect(400);
expect(createResultWithNonExistOptionsWorkspace.body.message).toEqual(
'Exist invalid workspaces'
);
});

it('bulk create', async () => {
await clearFooAndBar();
const createResultFoo = await osdTestServer.request
Expand Down Expand Up @@ -184,6 +209,37 @@ describe('workspace_id_consumer integration test', () => {
);
});

it('should return error when bulk create with a not existing workspace', async () => {
await clearFooAndBar();
const bulkCreateResultWithNonExistRequestWorkspace = await osdTestServer.request
.post(root, `/w/not_exist_workspace_id/api/saved_objects/_bulk_create`)
.send([
{
...dashboard,
id: 'foo',
},
])
.expect(400);

expect(bulkCreateResultWithNonExistRequestWorkspace.body.message).toEqual(
'Exist invalid workspaces'
);

const bulkCreateResultWithNonExistOptionsWorkspace = await osdTestServer.request
.post(root, `/api/saved_objects/_bulk_create?workspaces=not_exist_workspace_id`)
.send([
{
...dashboard,
id: 'foo',
},
])
.expect(400);

expect(bulkCreateResultWithNonExistOptionsWorkspace.body.message).toEqual(
'Exist invalid workspaces'
);
});

it('checkConflicts when importing ndjson', async () => {
await clearFooAndBar();
const createResultFoo = await osdTestServer.request
Expand Down Expand Up @@ -288,7 +344,7 @@ describe('workspace_id_consumer integration test', () => {
.get(root, `/w/not_exist_workspace_id/api/saved_objects/_find?type=${dashboard.type}`)
.expect(400);

expect(findResult.body.message).toEqual('Invalid workspaces');
expect(findResult.body.message).toEqual('Exist invalid workspaces');
});

it('import within workspace', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ describe('WorkspaceSavedObjectsClientWrapper', () => {
perPage: 999,
page: 1,
})
).rejects.toMatchInlineSnapshot(`[Error: Invalid workspaces]`);
).rejects.toMatchInlineSnapshot(`[Error: Exist invalid workspaces]`);
});

it('should return consistent inner workspace data when user permitted', async () => {
Expand Down Expand Up @@ -349,21 +349,16 @@ describe('WorkspaceSavedObjectsClientWrapper', () => {
});

describe('create', () => {
it('should throw forbidden error when workspace not permitted and create called', async () => {
let error;
try {
await notPermittedSavedObjectedClient.create(
it('should throw bad request error when workspace is invalid and create called', async () => {
await expect(
notPermittedSavedObjectedClient.create(
'dashboard',
{},
{
workspaces: ['workspace-1'],
}
);
} catch (e) {
error = e;
}

expect(SavedObjectsErrorHelpers.isForbiddenError(error)).toBe(true);
)
).rejects.toMatchInlineSnapshot(`[Error: Exist invalid workspaces]`);
});

it('should able to create saved objects into permitted workspaces after create called', async () => {
Expand Down Expand Up @@ -427,7 +422,7 @@ describe('WorkspaceSavedObjectsClientWrapper', () => {
expect(createResult.error).toBeUndefined();
});

it('should throw forbidden error when user create a workspce and is not OSD admin', async () => {
it('should throw forbidden error when user create a workspace and is not OSD admin', async () => {
let error;
try {
await permittedSavedObjectedClient.create('workspace', {}, {});
Expand Down Expand Up @@ -468,17 +463,12 @@ describe('WorkspaceSavedObjectsClientWrapper', () => {
});

describe('bulkCreate', () => {
it('should throw forbidden error when workspace not permitted and bulkCreate called', async () => {
let error;
try {
await notPermittedSavedObjectedClient.bulkCreate([{ type: 'dashboard', attributes: {} }], {
it('should throw bad request error when workspace is invalid and bulkCreate called', async () => {
await expect(
notPermittedSavedObjectedClient.bulkCreate([{ type: 'dashboard', attributes: {} }], {
workspaces: ['workspace-1'],
});
} catch (e) {
error = e;
}

expect(SavedObjectsErrorHelpers.isForbiddenError(error)).toBe(true);
})
).rejects.toMatchInlineSnapshot(`[Error: Exist invalid workspaces]`);
});

it('should able to create saved objects into permitted workspaces after bulkCreate called', async () => {
Expand Down Expand Up @@ -506,7 +496,6 @@ describe('WorkspaceSavedObjectsClientWrapper', () => {
],
{
overwrite: true,
workspaces: ['workspace-1'],
}
);
} catch (e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,15 @@ describe('WorkspaceIdConsumerWrapper', () => {
describe('create', () => {
beforeEach(() => {
mockedClient.create.mockClear();
mockedWorkspaceClient.get.mockClear();
mockedWorkspaceClient.list.mockClear();
});
it(`Should add workspaces parameters when create`, async () => {
mockedWorkspaceClient.get.mockImplementationOnce((requestContext, id) => {
return {
success: true,
};
});
await wrapperClient.create('dashboard', {
name: 'foo',
});
Expand Down Expand Up @@ -68,13 +75,54 @@ describe('WorkspaceIdConsumerWrapper', () => {

expect(mockedClient.create.mock.calls[0][2]?.hasOwnProperty('workspaces')).toEqual(false);
});

it(`Should throw error when passing in invalid workspaces`, async () => {
const workspaceIdConsumerWrapper = new WorkspaceIdConsumerWrapper(mockedWorkspaceClient);
const mockRequest = httpServerMock.createOpenSearchDashboardsRequest();
updateWorkspaceState(mockRequest, {});
const mockedWrapperClient = workspaceIdConsumerWrapper.wrapperFactory({
client: mockedClient,
typeRegistry: requestHandlerContext.savedObjects.typeRegistry,
request: mockRequest,
});

mockedWorkspaceClient.list.mockResolvedValueOnce({
success: true,
result: {
workspaces: [
{
id: 'foo',
},
],
},
});

expect(
mockedWrapperClient.create(
'dashboard',
{
name: 'foo',
},
{ workspaces: ['zoo', 'noo'] }
)
).rejects.toMatchInlineSnapshot(`[Error: Exist invalid workspaces]`);
expect(mockedWorkspaceClient.get).toBeCalledTimes(0);
expect(mockedWorkspaceClient.list).toBeCalledTimes(1);
});
});

describe('bulkCreate', () => {
beforeEach(() => {
mockedClient.bulkCreate.mockClear();
mockedWorkspaceClient.get.mockClear();
mockedWorkspaceClient.list.mockClear();
});
it(`Should add workspaces parameters when bulk create`, async () => {
mockedWorkspaceClient.get.mockImplementationOnce((requestContext, id) => {
return {
success: true,
};
});
await wrapperClient.bulkCreate([
getSavedObject({
id: 'foo',
Expand All @@ -88,6 +136,23 @@ describe('WorkspaceIdConsumerWrapper', () => {
}
);
});

it(`Should throw error when passing in invalid workspaces`, async () => {
mockedWorkspaceClient.get.mockImplementationOnce((requestContext, id) => {
return {
success: false,
};
});
expect(
wrapperClient.bulkCreate([
getSavedObject({
id: 'foo',
}),
])
).rejects.toMatchInlineSnapshot(`[Error: Exist invalid workspaces]`);
expect(mockedWorkspaceClient.get).toBeCalledTimes(1);
expect(mockedWorkspaceClient.list).toBeCalledTimes(0);
});
});

describe('checkConflict', () => {
Expand Down Expand Up @@ -174,7 +239,7 @@ describe('WorkspaceIdConsumerWrapper', () => {
type: ['dashboard', 'visualization'],
workspaces: ['foo', 'not-exist'],
})
).rejects.toMatchInlineSnapshot(`[Error: Invalid workspaces]`);
).rejects.toMatchInlineSnapshot(`[Error: Exist invalid workspaces]`);
expect(mockedWorkspaceClient.get).toBeCalledTimes(0);
expect(mockedWorkspaceClient.list).toBeCalledTimes(1);
});
Expand Down
Loading

0 comments on commit 340326f

Please sign in to comment.