[Upgrade Assistant] Disable UA and add prompt (#92834)

This commit is contained in:
Alison Goryachev 2021-03-04 13:03:14 -05:00 committed by GitHub
parent 67ca801c3f
commit ebe1f1f6d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 263 additions and 35 deletions

View file

@ -13,3 +13,10 @@ import SemVer from 'semver/classes/semver';
*/
export const mockKibanaVersion = '8.0.0';
export const mockKibanaSemverVersion = new SemVer(mockKibanaVersion);
/*
* This will be set to true up until the last minor before the next major.
* In readonly mode, the user will not be able to perform any actions in the UI
* and will be presented with a message indicating as such.
*/
export const UA_READONLY_MODE = true;

View file

@ -7,37 +7,19 @@
import React from 'react';
import { I18nStart } from 'src/core/public';
import { EuiPageHeader, EuiPageHeaderSection, EuiTitle } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { UpgradeAssistantTabs } from './components/tabs';
import { AppContextProvider, ContextValue, AppContext } from './app_context';
import { AppContextProvider, ContextValue } from './app_context';
import { PageContent } from './components/page_content';
export interface AppDependencies extends ContextValue {
i18n: I18nStart;
}
export const RootComponent = ({ i18n, ...contextValue }: AppDependencies) => {
const { nextMajor } = contextValue.kibanaVersionInfo;
return (
<i18n.Context>
<AppContextProvider value={contextValue}>
<div data-test-subj="upgradeAssistantRoot">
<EuiPageHeader>
<EuiPageHeaderSection>
<EuiTitle size="l">
<h1>
<FormattedMessage
id="xpack.upgradeAssistant.appTitle"
defaultMessage="{version} Upgrade Assistant"
values={{ version: `${nextMajor}.0` }}
/>
</h1>
</EuiTitle>
</EuiPageHeaderSection>
</EuiPageHeader>
<AppContext.Consumer>
{({ http }) => <UpgradeAssistantTabs http={http} />}
</AppContext.Consumer>
<PageContent />
</div>
</AppContextProvider>
</i18n.Context>

View file

@ -19,6 +19,7 @@ export interface ContextValue {
isCloudEnabled: boolean;
docLinks: DocLinksStart;
kibanaVersionInfo: KibanaVersionContext;
isReadOnlyMode: boolean;
}
export const AppContext = createContext<ContextValue>({} as any);

View file

@ -0,0 +1,65 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import { EuiEmptyPrompt, EuiPageContent, EuiLink } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { useAppContext } from '../app_context';
export const ComingSoonPrompt: React.FunctionComponent = () => {
const { kibanaVersionInfo, docLinks } = useAppContext();
const { nextMajor, currentMajor } = kibanaVersionInfo;
const { ELASTIC_WEBSITE_URL } = docLinks;
return (
<EuiPageContent>
<EuiEmptyPrompt
iconType="wrench"
data-test-subj="comingSoonPrompt"
title={
<h2>
<FormattedMessage
id="xpack.upgradeAssistant.emptyPrompt.title"
defaultMessage="{uaVersion} Upgrade Assistant"
values={{ uaVersion: `${nextMajor}.0` }}
/>
</h2>
}
body={
<>
<p>
<FormattedMessage
id="xpack.upgradeAssistant.emptyPrompt.upgradeAssistantDescription"
defaultMessage="The Upgrade Assistant identifies deprecated settings in your cluster and helps you
resolve issues before you upgrade. Check back here when it's time to upgrade to Elastic {nextMajor}."
values={{ nextMajor: `${nextMajor}.0` }}
/>
</p>
{currentMajor === 7 && (
<p>
<EuiLink
external
target="_blank"
href={`${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/master/migrating-8.0.html`}
>
<FormattedMessage
id="xpack.upgradeAssistant.emptyPrompt.learnMoreDescription"
defaultMessage="Learn more about migrating to {nextMajor}."
values={{
nextMajor: `${nextMajor}.0`,
}}
/>
</EuiLink>
</p>
)}
</>
}
/>
</EuiPageContent>
);
};

View file

@ -0,0 +1,44 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import { EuiPageHeader, EuiPageHeaderSection, EuiTitle } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { useAppContext } from '../app_context';
import { ComingSoonPrompt } from './coming_soon_prompt';
import { UpgradeAssistantTabs } from './tabs';
export const PageContent: React.FunctionComponent = () => {
const { kibanaVersionInfo, isReadOnlyMode, http } = useAppContext();
const { nextMajor } = kibanaVersionInfo;
// Read-only mode will be enabled up until the last minor before the next major release
if (isReadOnlyMode) {
return <ComingSoonPrompt />;
}
return (
<>
<EuiPageHeader data-test-subj="upgradeAssistantPageContent">
<EuiPageHeaderSection>
<EuiTitle size="l">
<h1>
<FormattedMessage
id="xpack.upgradeAssistant.appTitle"
defaultMessage="{version} Upgrade Assistant"
values={{ version: `${nextMajor}.0` }}
/>
</h1>
</EuiTitle>
</EuiPageHeaderSection>
</EuiPageHeader>
<UpgradeAssistantTabs http={http} />
</>
);
};

View file

@ -7,6 +7,7 @@
import { CoreSetup } from 'src/core/public';
import { ManagementAppMountParams } from '../../../../../src/plugins/management/public';
import { UA_READONLY_MODE } from '../../common/constants';
import { renderApp } from './render_app';
import { KibanaVersionContext } from './app_context';
@ -24,5 +25,6 @@ export async function mountManagementSection(
i18n,
docLinks,
kibanaVersionInfo,
isReadOnlyMode: UA_READONLY_MODE,
});
}

View file

@ -0,0 +1,8 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
export { setup, OverviewTestBed } from './overview.helpers';

View file

@ -0,0 +1,25 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { registerTestBed, TestBed, TestBedConfig } from '@kbn/test/jest';
import { PageContent } from '../../public/application/components/page_content';
import { WithAppDependencies } from './setup_environment';
const testBedConfig: TestBedConfig = {
doMountAsync: true,
};
export type OverviewTestBed = TestBed<OverviewTestSubjects>;
export const setup = async (overrides?: any): Promise<OverviewTestBed> => {
const initTestBed = registerTestBed(WithAppDependencies(PageContent, overrides), testBedConfig);
const testBed = await initTestBed();
return testBed;
};
export type OverviewTestSubjects = 'comingSoonPrompt' | 'upgradeAssistantPageContent';

View file

@ -0,0 +1,37 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import axios from 'axios';
import { docLinksServiceMock } from '../../../../../src/core/public/mocks';
import { HttpSetup } from '../../../../../src/core/public';
import { mockKibanaSemverVersion, UA_READONLY_MODE } from '../../common/constants';
import { AppContextProvider } from '../../public/application/app_context';
const mockHttpClient = axios.create();
const contextValue = {
http: (mockHttpClient as unknown) as HttpSetup,
isCloudEnabled: false,
docLinks: docLinksServiceMock.createStartContract(),
kibanaVersionInfo: {
currentMajor: mockKibanaSemverVersion.major,
prevMajor: mockKibanaSemverVersion.major - 1,
nextMajor: mockKibanaSemverVersion.major + 1,
},
isReadOnlyMode: UA_READONLY_MODE,
};
export const WithAppDependencies = (Comp: any, overrides: any = {}) => (props: any) => {
return (
<AppContextProvider value={{ ...contextValue, ...overrides }}>
<Comp {...props} />
</AppContextProvider>
);
};

View file

@ -0,0 +1,46 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { act } from 'react-dom/test-utils';
import { OverviewTestBed, setup } from './helpers';
describe('<PageContent />', () => {
let testBed: OverviewTestBed;
beforeEach(async () => {
await act(async () => {
testBed = await setup();
});
});
describe('Coming soon prompt', () => {
// Default behavior up until the last minor before the next major release
test('renders the coming soon prompt by default', () => {
const { exists } = testBed;
expect(exists('comingSoonPrompt')).toBe(true);
});
});
describe('Tabs', () => {
beforeEach(async () => {
await act(async () => {
// Override the default context value to verify tab content renders as expected
// This will be the default behavior on the last minor before the next major release (e.g., v7.15)
testBed = await setup({ isReadOnlyMode: false });
});
});
test('renders the coming soon prompt by default', () => {
const { exists } = testBed;
expect(exists('comingSoonPrompt')).toBe(false);
expect(exists('upgradeAssistantPageContent')).toBe(true);
});
});
});

View file

@ -11,6 +11,7 @@
"common/**/*",
"public/**/*",
"server/**/*",
"tests_client_integration/**/*",
// have to declare *.json explicitly due to https://github.com/microsoft/TypeScript/issues/25636
"public/**/*.json",
"server/**/*.json"

View file

@ -18,27 +18,37 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.upgradeAssistant.navigateToPage();
});
it('Overview Tab', async () => {
await retry.waitFor('Upgrade Assistant overview tab to be visible', async () => {
return testSubjects.exists('upgradeAssistantOverviewTabDetail');
it('Overview page', async () => {
await retry.waitFor('Upgrade Assistant overview page to be visible', async () => {
return testSubjects.exists('comingSoonPrompt');
});
await a11y.testAppSnapshot();
});
it('Cluster Tab', async () => {
await testSubjects.click('upgradeAssistantClusterTab');
await retry.waitFor('Upgrade Assistant Cluster tab to be visible', async () => {
return testSubjects.exists('upgradeAssistantClusterTabDetail');
// These tests will be skipped until the last minor of the next major release
describe.skip('tabs', () => {
it('Overview Tab', async () => {
await retry.waitFor('Upgrade Assistant overview tab to be visible', async () => {
return testSubjects.exists('upgradeAssistantOverviewTabDetail');
});
await a11y.testAppSnapshot();
});
await a11y.testAppSnapshot();
});
it('Indices Tab', async () => {
await testSubjects.click('upgradeAssistantIndicesTab');
await retry.waitFor('Upgrade Assistant Cluster tab to be visible', async () => {
return testSubjects.exists('upgradeAssistantIndexTabDetail');
it('Cluster Tab', async () => {
await testSubjects.click('upgradeAssistantClusterTab');
await retry.waitFor('Upgrade Assistant Cluster tab to be visible', async () => {
return testSubjects.exists('upgradeAssistantClusterTabDetail');
});
await a11y.testAppSnapshot();
});
it('Indices Tab', async () => {
await testSubjects.click('upgradeAssistantIndicesTab');
await retry.waitFor('Upgrade Assistant Cluster tab to be visible', async () => {
return testSubjects.exists('upgradeAssistantIndexTabDetail');
});
await a11y.testAppSnapshot();
});
await a11y.testAppSnapshot();
});
});
}