Skip to content

Commit

Permalink
Add view
Browse files Browse the repository at this point in the history
  • Loading branch information
scottybollinger committed Dec 1, 2021
1 parent fbc4c8d commit b04b6df
Show file tree
Hide file tree
Showing 3 changed files with 219 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* 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 { setMockValues, setMockActions } from '../../../__mocks__/kea_logic';
import { unmountHandler } from '../../../__mocks__/shallow_useeffect.mock';

import React from 'react';

import { shallow } from 'enzyme';

import { EuiEmptyPrompt, EuiCopy } from '@elastic/eui';

import { DEFAULT_META } from '../../../shared/constants';
import { externalUrl } from '../../../shared/enterprise_search_url';

import { ApiKeys } from './api_keys';
import { ApiKeyFlyout } from './components/api_key_flyout';
import { ApiKeysList } from './components/api_keys_list';

describe('ApiKeys', () => {
const fetchApiKeys = jest.fn();
const resetApiKeys = jest.fn();
const showApiKeysForm = jest.fn();
const apiToken = {
id: '1',
name: 'test',
key: 'foo',
};

const values = {
apiKeyFormVisible: false,
meta: DEFAULT_META,
dataLoading: false,
apiTokens: [apiToken],
};

beforeEach(() => {
jest.clearAllMocks();
setMockValues(values);
setMockActions({
fetchApiKeys,
resetApiKeys,
showApiKeysForm,
});
});

it('renders', () => {
const wrapper = shallow(<ApiKeys />);

expect(wrapper.find(ApiKeysList)).toHaveLength(1);
});

it('renders EuiEmptyPrompt when no api keys present', () => {
setMockValues({ ...values, apiTokens: [] });
const wrapper = shallow(<ApiKeys />);

expect(wrapper.find(ApiKeysList)).toHaveLength(0);
expect(wrapper.find(EuiEmptyPrompt)).toHaveLength(1);
});

it('fetches data on mount', () => {
shallow(<ApiKeys />);

expect(fetchApiKeys).toHaveBeenCalledTimes(1);
});

it('calls resetApiKeys on unmount', () => {
shallow(<ApiKeys />);
unmountHandler();

expect(resetApiKeys).toHaveBeenCalledTimes(1);
});

it('renders the API endpoint and a button to copy it', () => {
externalUrl.enterpriseSearchUrl = 'http://localhost:3002';
const copyMock = jest.fn();
const wrapper = shallow(<ApiKeys />);
// We wrap children in a div so that `shallow` can render it.
const copyEl = shallow(<div>{wrapper.find(EuiCopy).props().children(copyMock)}</div>);

expect(copyEl.find('EuiButtonIcon').props().onClick).toEqual(copyMock);
expect(copyEl.text().replace('<EuiButtonIcon />', '')).toEqual('http://localhost:3002');
});

it('will render ApiKeyFlyout if apiKeyFormVisible is true', () => {
setMockValues({ ...values, apiKeyFormVisible: true });
const wrapper = shallow(<ApiKeys />);

expect(wrapper.find(ApiKeyFlyout)).toHaveLength(1);
});

it('will NOT render ApiKeyFlyout if apiKeyFormVisible is false', () => {
setMockValues({ ...values, apiKeyFormVisible: false });
const wrapper = shallow(<ApiKeys />);

expect(wrapper.find(ApiKeyFlyout)).toHaveLength(0);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* 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, { useEffect } from 'react';

import { useActions, useValues } from 'kea';

import {
EuiButton,
EuiTitle,
EuiPanel,
EuiCopy,
EuiButtonIcon,
EuiSpacer,
EuiEmptyPrompt,
} from '@elastic/eui';

import { docLinks } from '../../../shared/doc_links';
import { externalUrl } from '../../../shared/enterprise_search_url/external_url';

import { WorkplaceSearchPageTemplate } from '../../components/layout';
import { NAV, API_KEYS_TITLE } from '../../constants';

import { ApiKeysLogic } from './api_keys_logic';
import { ApiKeyFlyout } from './components/api_key_flyout';
import { ApiKeysList } from './components/api_keys_list';
import {
API_KEYS_EMPTY_TITLE,
API_KEYS_EMPTY_BODY,
API_KEYS_EMPTY_BUTTON_LABEL,
CREATE_KEY_BUTTON_LABEL,
ENDPOINT_TITLE,
COPIED_TOOLTIP,
COPY_API_ENDPOINT_BUTTON_LABEL,
} from './constants';

export const ApiKeys: React.FC = () => {
const { fetchApiKeys, resetApiKeys, showApiKeyForm } = useActions(ApiKeysLogic);

const { meta, dataLoading, apiKeyFormVisible, apiTokens } = useValues(ApiKeysLogic);

useEffect(() => {
fetchApiKeys();
return resetApiKeys;
}, [meta.page.current]);

const hasApiKeys = apiTokens.length > 0;

const addKeyButton = (
<EuiButton fill onClick={showApiKeyForm}>
{CREATE_KEY_BUTTON_LABEL}
</EuiButton>
);

const emptyPrompt = (
<EuiEmptyPrompt
iconType="editorStrike"
title={<h2>{API_KEYS_EMPTY_TITLE}</h2>}
body={API_KEYS_EMPTY_BODY}
actions={
<EuiButton
size="s"
target="_blank"
iconType="popout"
href={docLinks.workplaceSearchApiKeys}
>
{API_KEYS_EMPTY_BUTTON_LABEL}
</EuiButton>
}
/>
);

return (
<WorkplaceSearchPageTemplate
pageChrome={[NAV.API_KEYS]}
pageHeader={{
pageTitle: API_KEYS_TITLE,
rightSideItems: [addKeyButton],
}}
isLoading={dataLoading}
emptyState={!hasApiKeys && emptyPrompt}
>
{apiKeyFormVisible && <ApiKeyFlyout />}
<EuiPanel color="subdued" className="eui-textCenter">
<EuiTitle size="s">
<h2>{ENDPOINT_TITLE}</h2>
</EuiTitle>
<EuiCopy textToCopy={externalUrl.enterpriseSearchUrl} afterMessage={COPIED_TOOLTIP}>
{(copy) => (
<>
<EuiButtonIcon
onClick={copy}
iconType="copyClipboard"
aria-label={COPY_API_ENDPOINT_BUTTON_LABEL}
/>
{externalUrl.enterpriseSearchUrl}
</>
)}
</EuiCopy>
</EuiPanel>
<EuiSpacer size="xxl" />
<EuiPanel hasBorder>{hasApiKeys ? <ApiKeysList /> : emptyPrompt}</EuiPanel>
</WorkplaceSearchPageTemplate>
);
};
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 { ApiKeys } from './api_keys';

0 comments on commit b04b6df

Please sign in to comment.