Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions x-pack/plugins/upgrade_assistant/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
24 changes: 3 additions & 21 deletions x-pack/plugins/upgrade_assistant/public/application/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface ContextValue {
isCloudEnabled: boolean;
docLinks: DocLinksStart;
kibanaVersionInfo: KibanaVersionContext;
isReadOnlyMode: boolean;
}

export const AppContext = createContext<ContextValue>({} as any);
Expand Down
Original file line number Diff line number Diff line change
@@ -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>
);
};
Original file line number Diff line number Diff line change
@@ -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} />
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -24,5 +25,6 @@ export async function mountManagementSection(
i18n,
docLinks,
kibanaVersionInfo,
isReadOnlyMode: UA_READONLY_MODE,
});
}
Original file line number Diff line number Diff line change
@@ -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';
Original file line number Diff line number Diff line change
@@ -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';
Original file line number Diff line number Diff line change
@@ -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>
);
};
Original file line number Diff line number Diff line change
@@ -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);
});
});
});
1 change: 1 addition & 0 deletions x-pack/plugins/upgrade_assistant/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
38 changes: 24 additions & 14 deletions x-pack/test/accessibility/apps/upgrade_assistant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
});
}