Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
Hailong-am authored Mar 11, 2024
2 parents a2d1e52 + 8f0885d commit 2f3418c
Show file tree
Hide file tree
Showing 41 changed files with 1,697 additions and 72 deletions.
9 changes: 6 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
### Deprecations

### 🛡 Security
- Support dynamic CSP rules to mitigate Clickjacking https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5641

### 📈 Features/Enhancements
- [MD]Change cluster selector component name to data source selector ([#6042](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6042))
- [MD]Change cluster selector component name to data source selector ([#6042](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6042))
- [Multiple Datasource] Add interfaces to register add-on authentication method from plug-in module ([#5851](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5851))
- [Multiple Datasource] Able to Hide "Local Cluster" option from datasource DropDown ([#5827](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5827))
- [Multiple Datasource] Add api registry and allow it to be added into client config in data source plugin ([#5895](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5895))
Expand All @@ -25,7 +26,9 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- [Multiple Datasource] Handles auth methods from auth registry in DataSource SavedObjects Client Wrapper ([#6062](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6062))
- [Multiple Datasource] Expose a few properties for customize the appearance of the data source selector component ([#6057](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6057))
- [Multiple Datasource] Create data source menu component able to be mount to nav bar ([#6082](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6082))

- [Multiple Datasource] Handle form values(request payload) if the selected type is available in the authentication registry ([#6049](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6049))
- [Multiple Datasource] Add Vega support to MDS by specifying a data source name in the Vega spec ([#5975](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5975))
- [Workspace] Consume workspace id in saved object client ([#6014](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6014))

- [Workspace] Add delete saved objects by workspace functionality([#6013](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6013))

Expand All @@ -41,7 +44,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- [osd/std] Add additional recovery from false-positives in handling of long numerals ([#5956](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5956))
- [BUG][Multiple Datasource] Fix missing customApiRegistryPromise param for test connection ([#5944](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5944))
- [BUG][Multiple Datasource] Add a migration function for datasource to add migrationVersion field ([#6025](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6025))
- [BUG][MD]Expose picker using function in data source management plugin setup([#6030](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6030))
- [BUG][MD]Expose picker using function in data source management plugin setup([#6030](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6030))

### 🚞 Infrastructure

Expand Down
4 changes: 4 additions & 0 deletions config/opensearch_dashboards.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
# Set the value of this setting to true to enable plugin application config. By default it is disabled.
# application_config.enabled: false

# Set the value of this setting to true to enable plugin CSP handler. By default it is disabled.
# It requires the application config plugin as its dependency.
# csp_handler.enabled: false

# The default application to load.
#opensearchDashboards.defaultAppId: "home"

Expand Down
332 changes: 332 additions & 0 deletions src/core/public/saved_objects/saved_objects_client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,26 @@ describe('SavedObjectsClient', () => {
`);
});

test('makes HTTP call with workspaces', () => {
savedObjectsClient.create('index-pattern', attributes, {
workspaces: ['foo'],
});
expect(http.fetch.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"/api/saved_objects/index-pattern",
Object {
"body": "{\\"attributes\\":{\\"foo\\":\\"Foo\\",\\"bar\\":\\"Bar\\"},\\"workspaces\\":[\\"foo\\"]}",
"method": "POST",
"query": Object {
"overwrite": undefined,
},
},
],
]
`);
});

test('rejects when HTTP call fails', async () => {
http.fetch.mockRejectedValueOnce(new Error('Request failed'));
await expect(
Expand Down Expand Up @@ -386,6 +406,29 @@ describe('SavedObjectsClient', () => {
]
`);
});

test('makes HTTP call with workspaces', () => {
savedObjectsClient.bulkCreate([doc], {
workspaces: ['foo'],
});
expect(http.fetch.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"/api/saved_objects/_bulk_create",
Object {
"body": "[{\\"id\\":\\"AVwSwFxtcMV38qjDZoQg\\",\\"type\\":\\"config\\",\\"attributes\\":{\\"title\\":\\"Example title\\"},\\"version\\":\\"foo\\",\\"updated_at\\":\\"${updatedAt}\\"}]",
"method": "POST",
"query": Object {
"overwrite": undefined,
"workspaces": Array [
"foo",
],
},
},
],
]
`);
});
});

describe('#bulk_update', () => {
Expand Down Expand Up @@ -510,5 +553,294 @@ describe('SavedObjectsClient', () => {
]
`);
});

test('makes HTTP call correctly with workspaces', () => {
const options = {
invalid: true,
workspaces: ['foo'],
};

// @ts-expect-error
savedObjectsClient.find(options);
expect(http.fetch.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"/api/saved_objects/_find",
Object {
"body": undefined,
"method": "GET",
"query": Object {
"workspaces": Array [
"foo",
],
},
},
],
]
`);
});
});
});

describe('SavedObjectsClientWithWorkspaceSet', () => {
const updatedAt = new Date().toISOString();
const doc = {
id: 'AVwSwFxtcMV38qjDZoQg',
type: 'config',
attributes: { title: 'Example title' },
version: 'foo',
updated_at: updatedAt,
};

const http = httpServiceMock.createStartContract();
let savedObjectsClient: SavedObjectsClient;

beforeEach(() => {
savedObjectsClient = new SavedObjectsClient(http);
savedObjectsClient.setCurrentWorkspace('foo');
http.fetch.mockClear();
});

describe('#create', () => {
const attributes = { foo: 'Foo', bar: 'Bar' };

beforeEach(() => {
http.fetch.mockResolvedValue({ id: 'serverId', type: 'server-type', attributes });
});

test('makes HTTP call with ID', () => {
savedObjectsClient.create('index-pattern', attributes, { id: 'myId' });
expect(http.fetch.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"/api/saved_objects/index-pattern/myId",
Object {
"body": "{\\"attributes\\":{\\"foo\\":\\"Foo\\",\\"bar\\":\\"Bar\\"},\\"workspaces\\":[\\"foo\\"]}",
"method": "POST",
"query": Object {
"overwrite": undefined,
},
},
],
]
`);
});

test('makes HTTP call without ID', () => {
savedObjectsClient.create('index-pattern', attributes);
expect(http.fetch.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"/api/saved_objects/index-pattern",
Object {
"body": "{\\"attributes\\":{\\"foo\\":\\"Foo\\",\\"bar\\":\\"Bar\\"},\\"workspaces\\":[\\"foo\\"]}",
"method": "POST",
"query": Object {
"overwrite": undefined,
},
},
],
]
`);
});

test('makes HTTP call with workspaces', () => {
savedObjectsClient.create('index-pattern', attributes, {
workspaces: ['foo'],
});
expect(http.fetch.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"/api/saved_objects/index-pattern",
Object {
"body": "{\\"attributes\\":{\\"foo\\":\\"Foo\\",\\"bar\\":\\"Bar\\"},\\"workspaces\\":[\\"foo\\"]}",
"method": "POST",
"query": Object {
"overwrite": undefined,
},
},
],
]
`);
});
});

describe('#bulk_create', () => {
beforeEach(() => {
http.fetch.mockResolvedValue({ saved_objects: [doc] });
});

test('makes HTTP call', async () => {
await savedObjectsClient.bulkCreate([doc]);
expect(http.fetch.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"/api/saved_objects/_bulk_create",
Object {
"body": "[{\\"id\\":\\"AVwSwFxtcMV38qjDZoQg\\",\\"type\\":\\"config\\",\\"attributes\\":{\\"title\\":\\"Example title\\"},\\"version\\":\\"foo\\",\\"updated_at\\":\\"${updatedAt}\\"}]",
"method": "POST",
"query": Object {
"overwrite": false,
"workspaces": Array [
"foo",
],
},
},
],
]
`);
});

test('makes HTTP call with overwrite query paramater', async () => {
await savedObjectsClient.bulkCreate([doc], { overwrite: true });
expect(http.fetch.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"/api/saved_objects/_bulk_create",
Object {
"body": "[{\\"id\\":\\"AVwSwFxtcMV38qjDZoQg\\",\\"type\\":\\"config\\",\\"attributes\\":{\\"title\\":\\"Example title\\"},\\"version\\":\\"foo\\",\\"updated_at\\":\\"${updatedAt}\\"}]",
"method": "POST",
"query": Object {
"overwrite": true,
"workspaces": Array [
"foo",
],
},
},
],
]
`);
});

test('makes HTTP call with workspaces', () => {
savedObjectsClient.bulkCreate([doc], {
workspaces: ['bar'],
});
expect(http.fetch.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"/api/saved_objects/_bulk_create",
Object {
"body": "[{\\"id\\":\\"AVwSwFxtcMV38qjDZoQg\\",\\"type\\":\\"config\\",\\"attributes\\":{\\"title\\":\\"Example title\\"},\\"version\\":\\"foo\\",\\"updated_at\\":\\"${updatedAt}\\"}]",
"method": "POST",
"query": Object {
"overwrite": undefined,
"workspaces": Array [
"bar",
],
},
},
],
]
`);
});
});

describe('#bulk_update', () => {
const bulkUpdateDoc = {
id: 'AVwSwFxtcMV38qjDZoQg',
type: 'config',
attributes: { title: 'Example title' },
version: 'foo',
};
beforeEach(() => {
http.fetch.mockResolvedValue({ saved_objects: [bulkUpdateDoc] });
});

test('makes HTTP call', async () => {
await savedObjectsClient.bulkUpdate([bulkUpdateDoc]);
expect(http.fetch.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"/api/saved_objects/_bulk_update",
Object {
"body": "[{\\"id\\":\\"AVwSwFxtcMV38qjDZoQg\\",\\"type\\":\\"config\\",\\"attributes\\":{\\"title\\":\\"Example title\\"},\\"version\\":\\"foo\\"}]",
"method": "PUT",
"query": undefined,
},
],
]
`);
});
});

describe('#find', () => {
const object = { id: 'logstash-*', type: 'index-pattern', title: 'Test' };

beforeEach(() => {
http.fetch.mockResolvedValue({ saved_objects: [object], page: 0, per_page: 1, total: 1 });
});

test('makes HTTP call correctly mapping options into snake case query parameters', () => {
const options = {
defaultSearchOperator: 'OR' as const,
fields: ['title'],
hasReference: { id: '1', type: 'reference' },
page: 10,
perPage: 100,
search: 'what is the meaning of life?|life',
searchFields: ['title^5', 'body'],
sortField: 'sort_field',
type: 'index-pattern',
};

savedObjectsClient.find(options);
expect(http.fetch.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"/api/saved_objects/_find",
Object {
"body": undefined,
"method": "GET",
"query": Object {
"default_search_operator": "OR",
"fields": Array [
"title",
],
"has_reference": "{\\"id\\":\\"1\\",\\"type\\":\\"reference\\"}",
"page": 10,
"per_page": 100,
"search": "what is the meaning of life?|life",
"search_fields": Array [
"title^5",
"body",
],
"sort_field": "sort_field",
"type": "index-pattern",
"workspaces": Array [
"foo",
],
},
},
],
]
`);
});

test('makes HTTP call correctly with workspaces', () => {
const options = {
invalid: true,
workspaces: ['bar'],
};

// @ts-expect-error
savedObjectsClient.find(options);
expect(http.fetch.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"/api/saved_objects/_find",
Object {
"body": undefined,
"method": "GET",
"query": Object {
"workspaces": Array [
"bar",
],
},
},
],
]
`);
});
});
});
Loading

0 comments on commit 2f3418c

Please sign in to comment.