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

add per space configuration to custom header banner #94449

Merged
merged 30 commits into from
Mar 31, 2021
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
7faf18e
restore the banners ui settings
pgayvallet Mar 11, 2021
14739df
fix banner init logic
pgayvallet Mar 11, 2021
50b4dc1
Merge remote-tracking branch 'upstream/master' into kbn-17298-banner-…
pgayvallet Mar 16, 2021
eedff07
fix unit tests
pgayvallet Mar 16, 2021
4afec76
update telemetry schema
pgayvallet Mar 16, 2021
28b08a5
add basic server-side plugin tests
pgayvallet Mar 16, 2021
559509f
add FTR tests for banners plugin
pgayvallet Mar 16, 2021
42ad72e
use keyword for sensitive setting
pgayvallet Mar 16, 2021
574f8e4
update snapshots
pgayvallet Mar 16, 2021
0c5172f
Merge remote-tracking branch 'upstream/master' into kbn-17298-banner-…
pgayvallet Mar 17, 2021
9313585
setting name consistency with configuration properties
pgayvallet Mar 17, 2021
fda3ffc
fix setting names in telemetry files
pgayvallet Mar 17, 2021
26f8272
Merge remote-tracking branch 'upstream/master' into kbn-17298-banner-…
pgayvallet Mar 22, 2021
847e0f2
open banner links in new tab
pgayvallet Mar 22, 2021
a7b6abf
Merge remote-tracking branch 'upstream/master' into kbn-17298-banner-…
pgayvallet Mar 25, 2021
085d401
add config.disableSpaceBanners property
pgayvallet Mar 25, 2021
506a9e3
fix types
pgayvallet Mar 25, 2021
2745d03
Merge remote-tracking branch 'upstream/master' into kbn-17298-banner-…
pgayvallet Mar 26, 2021
707ea3b
add descriptions to banner settings
pgayvallet Mar 26, 2021
4b6a76e
Merge remote-tracking branch 'upstream/master' into kbn-17298-banner-…
pgayvallet Mar 29, 2021
0570ea1
change label and value header->top
pgayvallet Mar 29, 2021
2ac2bea
finishing header->top replacement
pgayvallet Mar 29, 2021
2ce561a
Merge remote-tracking branch 'upstream/master' into kbn-17298-banner-…
pgayvallet Mar 29, 2021
f43168b
doc nits
pgayvallet Mar 29, 2021
14c33b6
add banners section to advanced options doc
pgayvallet Mar 29, 2021
3f90c42
Merge remote-tracking branch 'upstream/master' into kbn-17298-banner-…
pgayvallet Mar 30, 2021
0c8b881
feedback on advanced options doc
pgayvallet Mar 30, 2021
ceea04a
Merge remote-tracking branch 'upstream/master' into kbn-17298-banner-…
pgayvallet Mar 30, 2021
07206ea
Merge remote-tracking branch 'upstream/master' into kbn-17298-banner-…
pgayvallet Mar 31, 2021
f39965b
adapt deprecation to new format
pgayvallet Mar 31, 2021
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
10 changes: 8 additions & 2 deletions src/core/server/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ export { capabilitiesServiceMock } from './capabilities/capabilities_service.moc
export { coreUsageDataServiceMock } from './core_usage_data/core_usage_data_service.mock';
export { i18nServiceMock } from './i18n/i18n_service.mock';

type MockedPluginInitializerConfig<T> = jest.Mocked<PluginInitializerContext<T>['config']>;

export function pluginInitializerContextConfigMock<T>(config: T) {
const globalConfig: SharedGlobalConfig = {
kibana: {
Expand All @@ -68,7 +70,7 @@ export function pluginInitializerContextConfigMock<T>(config: T) {
},
};

const mock: jest.Mocked<PluginInitializerContext<T>['config']> = {
const mock: MockedPluginInitializerConfig<T> = {
legacy: {
globalConfig$: of(globalConfig),
get: () => globalConfig,
Expand All @@ -80,8 +82,12 @@ export function pluginInitializerContextConfigMock<T>(config: T) {
return mock;
}

type PluginInitializerContextMock<T> = Omit<PluginInitializerContext<T>, 'config'> & {
config: MockedPluginInitializerConfig<T>;
};

function pluginInitializerContextMock<T>(config: T = {} as T) {
const mock: PluginInitializerContext<T> = {
const mock: PluginInitializerContextMock<T> = {
opaqueId: Symbol(),
logger: loggingSystemMock.create(),
env: {
Expand Down

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

Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ export class Field extends PureComponent<FieldProps> {
<div data-test-subj={`advancedSetting-editField-${name}`}>
<EuiCodeEditor
{...a11yProps}
name={`advancedSetting-editField-${name}-editor`}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was required for the addition of SettingsPage.setAdvancedSettingsTextArea (see test/functional/page_objects/settings_page.ts)

mode={type}
theme="textmate"
value={currentValue}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ export const stackManagementSchema: MakeSchemaFrom<UsageStats> = {
type: 'keyword',
_meta: { description: 'Default value of the setting was changed.' },
},
'banners:textContent': {
type: 'keyword',
_meta: { description: 'Default value of the setting was changed.' },
},
// non-sensitive
'visualize:enableLabs': {
type: 'boolean',
Expand Down Expand Up @@ -412,4 +416,16 @@ export const stackManagementSchema: MakeSchemaFrom<UsageStats> = {
type: 'boolean',
_meta: { description: 'Non-default value of setting.' },
},
'banners:placement': {
type: 'keyword',
_meta: { description: 'Non-default value of setting.' },
},
'banners:textColor': {
type: 'text',
_meta: { description: 'Non-default value of setting.' },
},
'banners:backgroundColor': {
type: 'text',
_meta: { description: 'Non-default value of setting.' },
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface UsageStats {
'timelion:graphite.url': string;
'xpackDashboardMode:roles': string;
'securitySolution:ipReputationLinks': string;
'banners:textContent': string;
/**
* non-sensitive settings
*/
Expand Down Expand Up @@ -113,4 +114,7 @@ export interface UsageStats {
'csv:quoteValues': boolean;
'dateFormat:dow': string;
dateFormat: string;
'banners:placement': string;
'banners:textColor': string;
'banners:backgroundColor': string;
}
24 changes: 24 additions & 0 deletions src/plugins/telemetry/schema/oss_plugins.json
Original file line number Diff line number Diff line change
Expand Up @@ -7478,6 +7478,12 @@
"description": "Default value of the setting was changed."
}
},
"banners:textContent": {
"type": "keyword",
"_meta": {
"description": "Default value of the setting was changed."
}
},
"visualize:enableLabs": {
"type": "boolean",
"_meta": {
Expand Down Expand Up @@ -8032,6 +8038,24 @@
"_meta": {
"description": "Non-default value of setting."
}
},
"banners:placement": {
"type": "keyword",
"_meta": {
"description": "Non-default value of setting."
}
},
"banners:textColor": {
"type": "text",
"_meta": {
"description": "Non-default value of setting."
}
},
"banners:backgroundColor": {
"type": "text",
"_meta": {
"description": "Non-default value of setting."
}
}
}
},
Expand Down
19 changes: 19 additions & 0 deletions test/functional/page_objects/settings_page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export function SettingsPageProvider({ getService, getPageObjects }: FtrProvider
async clickLinkText(text: string) {
await find.clickByDisplayedLinkText(text);
}

async clickKibanaSettings() {
await testSubjects.click('settings');
await PageObjects.header.waitUntilLoadingHasFinished();
Expand Down Expand Up @@ -89,6 +90,22 @@ export function SettingsPageProvider({ getService, getPageObjects }: FtrProvider
await PageObjects.header.waitUntilLoadingHasFinished();
}

async setAdvancedSettingsTextArea(propertyName: string, propertyValue: string) {
const wrapper = await testSubjects.find(`advancedSetting-editField-${propertyName}`);
const textarea = await wrapper.findByTagName('textarea');
await textarea.focus();
// only way to properly replace the value of the ace editor is via the JS api
await browser.execute(
(editor: string, value: string) => {
return (window as any).ace.edit(editor).setValue(value);
},
`advancedSetting-editField-${propertyName}-editor`,
propertyValue
);
await testSubjects.click(`advancedSetting-saveButton`);
await PageObjects.header.waitUntilLoadingHasFinished();
}

async toggleAdvancedSettingCheckbox(propertyName: string) {
await testSubjects.click(`advancedSetting-editField-${propertyName}`);
await PageObjects.header.waitUntilLoadingHasFinished();
Expand Down Expand Up @@ -162,13 +179,15 @@ export function SettingsPageProvider({ getService, getPageObjects }: FtrProvider

async sortBy(columnName: string) {
const chartTypes = await find.allByCssSelector('table.euiTable thead tr th button');

async function getChartType(chart: Record<string, any>) {
const chartString = await chart.getVisibleText();
if (chartString === columnName) {
await chart.click();
await PageObjects.header.waitUntilLoadingHasFinished();
}
}

const getChartTypesPromises = chartTypes.map(getChartType);
return Promise.all(getChartTypesPromises);
}
Expand Down
89 changes: 57 additions & 32 deletions x-pack/plugins/banners/public/plugin.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,19 @@

import { getBannerInfoMock } from './plugin.test.mocks';
import { coreMock } from '../../../../src/core/public/mocks';
import { BannerConfiguration } from '../common/types';
import { BannersPlugin } from './plugin';
import { BannerClientConfig } from './types';

const nextTick = async () => await new Promise<void>((resolve) => resolve());

const createBannerConfig = (parts: Partial<BannerConfiguration> = {}): BannerConfiguration => ({
placement: 'disabled',
textContent: 'foo',
textColor: '#FFFFFF',
backgroundColor: '#000000',
...parts,
});

describe('BannersPlugin', () => {
let plugin: BannersPlugin;
let pluginInitContext: ReturnType<typeof coreMock.createPluginInitializerContext>;
Expand All @@ -25,11 +33,12 @@ describe('BannersPlugin', () => {

getBannerInfoMock.mockResolvedValue({
allowed: false,
banner: createBannerConfig(),
});
});

const startPlugin = async (config: BannerClientConfig) => {
pluginInitContext = coreMock.createPluginInitializerContext(config);
const startPlugin = async () => {
pluginInitContext = coreMock.createPluginInitializerContext();
plugin = new BannersPlugin(pluginInitContext);
plugin.setup(coreSetup);
plugin.start(coreStart);
Expand All @@ -41,46 +50,62 @@ describe('BannersPlugin', () => {
getBannerInfoMock.mockReset();
});

it('calls `getBannerInfo` if `config.placement !== disabled`', async () => {
await startPlugin({
placement: 'header',
describe('when banner is allowed', () => {
it('registers the header banner if `banner.placement` is `header`', async () => {
getBannerInfoMock.mockResolvedValue({
allowed: true,
banner: createBannerConfig({
placement: 'header',
}),
});

await startPlugin();

expect(coreStart.chrome.setHeaderBanner).toHaveBeenCalledTimes(1);
expect(coreStart.chrome.setHeaderBanner).toHaveBeenCalledWith({
content: expect.any(Function),
});
});

expect(getBannerInfoMock).toHaveBeenCalledTimes(1);
});
it('does not register the header banner if `banner.placement` is `disabled`', async () => {
getBannerInfoMock.mockResolvedValue({
allowed: true,
banner: createBannerConfig({
placement: 'disabled',
}),
});

it('does not call `getBannerInfo` if `config.placement === disabled`', async () => {
await startPlugin({
placement: 'disabled',
});
await startPlugin();

expect(getBannerInfoMock).not.toHaveBeenCalled();
expect(coreStart.chrome.setHeaderBanner).toHaveBeenCalledTimes(0);
});
});

it('registers the header banner if `getBannerInfo` return `allowed=true`', async () => {
getBannerInfoMock.mockResolvedValue({
allowed: true,
});
describe('when banner is not allowed', () => {
it('does not register the header banner if `banner.placement` is `header`', async () => {
getBannerInfoMock.mockResolvedValue({
allowed: false,
banner: createBannerConfig({
placement: 'header',
}),
});

await startPlugin({
placement: 'header',
});
await startPlugin();

expect(coreStart.chrome.setHeaderBanner).toHaveBeenCalledTimes(1);
expect(coreStart.chrome.setHeaderBanner).toHaveBeenCalledWith({
content: expect.any(Function),
expect(coreStart.chrome.setHeaderBanner).toHaveBeenCalledTimes(0);
});
});

it('does not register the header banner if `getBannerInfo` return `allowed=false`', async () => {
getBannerInfoMock.mockResolvedValue({
allowed: false,
});
it('does not register the header banner if `banner.placement` is `disabled`', async () => {
getBannerInfoMock.mockResolvedValue({
allowed: false,
banner: createBannerConfig({
placement: 'disabled',
}),
});

await startPlugin({
placement: 'header',
});
await startPlugin();

expect(coreStart.chrome.setHeaderBanner).not.toHaveBeenCalled();
expect(coreStart.chrome.setHeaderBanner).toHaveBeenCalledTimes(0);
});
});
});
Loading