Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8022171

Browse files
committedJul 24, 2024·
Adds a test
Signed-off-by: Derek Ho <dxho@amazon.com>
1 parent d0488dd commit 8022171

File tree

3 files changed

+205
-2
lines changed

3 files changed

+205
-2
lines changed
 

‎public/plugin.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ import {
6060
getDataSourceFromUrl,
6161
} from './utils/datasource-utils';
6262

63-
async function hasApiPermission(core: CoreSetup): Promise<boolean | undefined> {
63+
export async function hasApiPermission(core: CoreSetup): Promise<boolean | undefined> {
6464
try {
6565
const permissions = await core.http.get(API_ENDPOINT_PERMISSIONS_INFO);
6666
return permissions.has_api_access || false;

‎public/test/plugin.test.ts

+199
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
/*
17+
* SPDX-License-Identifier: Apache-2.0
18+
*
19+
* The OpenSearch Contributors require contributions made to
20+
* this file be licensed under the Apache-2.0 license or a
21+
* compatible open source license.
22+
*
23+
* Any modifications Copyright OpenSearch Contributors. See
24+
* GitHub history for details.
25+
*/
26+
27+
/*
28+
* Licensed to Elasticsearch B.V. under one or more contributor
29+
* license agreements. See the NOTICE file distributed with
30+
* this work for additional information regarding copyright
31+
* ownership. Elasticsearch B.V. licenses this file to you under
32+
* the Apache License, Version 2.0 (the "License"); you may
33+
* not use this file except in compliance with the License.
34+
* You may obtain a copy of the License at
35+
*
36+
* http://www.apache.org/licenses/LICENSE-2.0
37+
*
38+
* Unless required by applicable law or agreed to in writing,
39+
* software distributed under the License is distributed on an
40+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
41+
* KIND, either express or implied. See the License for the
42+
* specific language governing permissions and limitations
43+
* under the License.
44+
*/
45+
46+
import { coreMock } from '../../../../src/core/public/mocks';
47+
import { SecurityPlugin } from '../plugin.ts';
48+
import * as pluginModule from '../plugin'; // Import the entire module to mock specific functions
49+
50+
// Mock the hasApiPermission function
51+
jest.mock('../plugin', () => {
52+
const originalModule = jest.requireActual('../plugin');
53+
return {
54+
...originalModule,
55+
hasApiPermission: jest.fn(), // Mock the function here
56+
};
57+
});
58+
59+
describe('SecurityPlugin', () => {
60+
let plugin;
61+
let coreSetup;
62+
let coreStart;
63+
let initializerContext;
64+
let deps;
65+
66+
beforeEach(() => {
67+
coreSetup = coreMock.createSetup();
68+
coreStart = coreMock.createStart();
69+
initializerContext = {
70+
config: {
71+
get: jest.fn().mockReturnValue({
72+
readonly_mode: { roles: [] },
73+
multitenancy: { enabled: true, enable_aggregation_view: false },
74+
clusterPermissions: { include: [] },
75+
indexPermissions: { include: [] },
76+
disabledTransportCategories: { exclude: [] },
77+
disabledRestCategories: { exclude: [] },
78+
ui: { autologout: false },
79+
}),
80+
},
81+
};
82+
deps = {
83+
dataSource: { dataSourceEnabled: true },
84+
savedObjectsManagement: { createSetup: jest.fn() },
85+
};
86+
});
87+
88+
it('does not call register function for certain applications when getNavGroupEnabled is off', async () => {
89+
// Mock hasApiPermission to return false
90+
pluginModule.hasApiPermission.mockResolvedValue(false); // Access the mock via the imported module
91+
92+
// Instantiate the plugin after mocking
93+
plugin = new SecurityPlugin(initializerContext);
94+
95+
// Override getNavGroupEnabled to return false
96+
coreSetup.chrome.navGroup = {
97+
...coreSetup.chrome.navGroup,
98+
getNavGroupEnabled: () => false,
99+
};
100+
// Mock the core.application.register function
101+
const registerSpy = jest.spyOn(coreSetup.application, 'register');
102+
103+
// Execute the setup function
104+
await plugin.setup(coreSetup, deps);
105+
106+
// Assert that the register function was not called for specific applications
107+
const registeredApps = registerSpy.mock.calls.map((call) => call[0].id);
108+
const expectedApps = [
109+
'security-dashboards-plugin_getstarted',
110+
'security-dashboards-plugin_auth',
111+
'security-dashboards-plugin_roles',
112+
'security-dashboards-plugin_users',
113+
'security-dashboards-plugin_permissions',
114+
'security-dashboards-plugin_tenants',
115+
'security-dashboards-plugin_auditlog',
116+
];
117+
118+
expectedApps.forEach((app) => {
119+
expect(registeredApps).not.toContain(app);
120+
});
121+
});
122+
123+
it('calls register function for certain applications when getNavGroupEnabled is on', async () => {
124+
// Mock hasApiPermission to return true
125+
pluginModule.hasApiPermission.mockResolvedValue(true); // Access the mock via the imported module
126+
127+
// Instantiate the plugin after mocking
128+
plugin = new SecurityPlugin(initializerContext);
129+
130+
// Override getNavGroupEnabled to return true
131+
coreSetup.chrome.navGroup = {
132+
...coreSetup.chrome.navGroup,
133+
getNavGroupEnabled: () => true,
134+
};
135+
// Mock the core.application.register function
136+
const registerSpy = jest.spyOn(coreSetup.application, 'register');
137+
138+
// Execute the setup function
139+
await plugin.setup(coreSetup, deps);
140+
141+
// Assert that the register function was called for specific applications
142+
const registeredApps = registerSpy.mock.calls.map((call) => call[0].id);
143+
const expectedApps = [
144+
'security-dashboards-plugin_getstarted',
145+
'security-dashboards-plugin_auth',
146+
'security-dashboards-plugin_roles',
147+
'security-dashboards-plugin_users',
148+
'security-dashboards-plugin_permissions',
149+
'security-dashboards-plugin_tenants',
150+
'security-dashboards-plugin_auditlog',
151+
];
152+
153+
expectedApps.forEach((app) => {
154+
expect(registeredApps).toContain(app);
155+
});
156+
});
157+
158+
it('does not call register function for tenant app when multitenancy is off', async () => {
159+
// Mock hasApiPermission to return true
160+
pluginModule.hasApiPermission.mockResolvedValue(true);
161+
162+
// InitializerContext with multitenancy disabled
163+
initializerContext = {
164+
config: {
165+
get: jest.fn().mockReturnValue({
166+
readonly_mode: { roles: [] },
167+
multitenancy: { enabled: false, enable_aggregation_view: false },
168+
clusterPermissions: { include: [] },
169+
indexPermissions: { include: [] },
170+
disabledTransportCategories: { exclude: [] },
171+
disabledRestCategories: { exclude: [] },
172+
ui: { autologout: false },
173+
}),
174+
},
175+
};
176+
177+
// Instantiate the plugin after mocking
178+
plugin = new SecurityPlugin(initializerContext);
179+
180+
// Override getNavGroupEnabled to return true
181+
coreSetup.chrome.navGroup = {
182+
...coreSetup.chrome.navGroup,
183+
getNavGroupEnabled: () => true,
184+
};
185+
// Mock the core.application.register function
186+
const registerSpy = jest.spyOn(coreSetup.application, 'register');
187+
188+
// Execute the setup function
189+
await plugin.setup(coreSetup, deps);
190+
191+
// Assert that the register function was not called for tenancy app
192+
const registeredApps = registerSpy.mock.calls.map((call) => call[0].id);
193+
const expectedApps = ['security-dashboards-plugin_tenants'];
194+
195+
expectedApps.forEach((app) => {
196+
expect(registeredApps).not.toContain(app);
197+
});
198+
});
199+
});

‎public/types.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ import {
1919
SavedObjectsManagementPluginStart,
2020
} from '../../../src/plugins/saved_objects_management/public';
2121
import { ManagementOverViewPluginSetup } from '../../../src/plugins/management_overview/public';
22-
import { DataSourcePluginStart } from '../../../src/plugins/data_source/public/types';
22+
import {
23+
DataSourcePluginSetup,
24+
DataSourcePluginStart,
25+
} from '../../../src/plugins/data_source/public/types';
2326
import { DataSourceManagementPluginSetup } from '../../../src/plugins/data_source_management/public';
2427

2528
// eslint-disable-next-line @typescript-eslint/no-empty-interface
@@ -31,6 +34,7 @@ export interface SecurityPluginSetupDependencies {
3134
savedObjectsManagement: SavedObjectsManagementPluginSetup;
3235
managementOverview?: ManagementOverViewPluginSetup;
3336
dataSourceManagement?: DataSourceManagementPluginSetup;
37+
dataSource?: DataSourcePluginSetup;
3438
}
3539

3640
export interface Cluster {

0 commit comments

Comments
 (0)