123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- import styled from '@emotion/styled';
- import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
- import {makeCloseButton} from 'sentry/components/globalModal/components';
- import ExternalIssueForm from 'sentry/components/group/externalIssueForm';
- jest.mock('lodash/debounce', () => {
- const debounceMap = new Map();
- const mockDebounce =
- (fn, timeout) =>
- (...args) => {
- if (debounceMap.has(fn)) {
- clearTimeout(debounceMap.get(fn));
- }
- debounceMap.set(
- fn,
- setTimeout(() => {
- fn.apply(fn, args);
- debounceMap.delete(fn);
- }, timeout)
- );
- };
- return mockDebounce;
- });
- describe('ExternalIssueForm', () => {
- let group, integration, formConfig;
- const onChange = jest.fn();
- beforeEach(() => {
- MockApiClient.clearMockResponses();
- group = TestStubs.Group();
- integration = TestStubs.GitHubIntegration({externalIssues: []});
- });
- afterEach(() => {
- jest.useRealTimers();
- jest.clearAllMocks();
- });
- const renderComponent = async (action = 'Create') => {
- MockApiClient.addMockResponse({
- url: `/organizations/org-slug/issues/${group.id}/integrations/${integration.id}/`,
- body: formConfig,
- match: [MockApiClient.matchQuery({action: 'create'})],
- });
- const styledWrapper = styled(c => c.children);
- const wrapper = render(
- <ExternalIssueForm
- Body={styledWrapper()}
- Footer={styledWrapper()}
- organization={TestStubs.Organization()}
- Header={c => <span>{c.children}</span>}
- group={group}
- integration={integration}
- onChange={onChange}
- CloseButton={makeCloseButton(() => {})}
- closeModal={() => {}}
- />
- );
- await userEvent.click(screen.getByText(action));
- return wrapper;
- };
- describe('create', () => {
- // TODO: expand tests
- beforeEach(() => {
- formConfig = {
- createIssueConfig: [],
- };
- MockApiClient.addMockResponse({
- url: `/organizations/org-slug/issues/${group.id}/integrations/${integration.id}/`,
- body: formConfig,
- });
- });
- it('renders', async () => {
- await renderComponent();
- });
- });
- describe('link', () => {
- let externalIssueField, getFormConfigRequest;
- beforeEach(() => {
- externalIssueField = {
- name: 'externalIssue',
- default: '',
- required: true,
- choices: [],
- url: '/search',
- label: 'Issue',
- type: 'select',
- };
- formConfig = {
- status: 'active',
- name: 'scefali',
- domainName: 'github.com/scefali',
- linkIssueConfig: [
- {
- url: '/search',
- required: true,
- name: 'repo',
- default: 'scefali/test',
- updatesForm: true,
- choices: [
- ['scefali/test', 'test'],
- ['scefali/ZeldaBazaar', 'ZeldaBazaar'],
- ],
- type: 'select',
- label: 'GitHub Repository',
- },
- externalIssueField,
- {
- help: "Leave blank if you don't want to add a comment to the GitHub issue.",
- default: 'Default Value',
- required: false,
- label: 'Comment',
- type: 'textarea',
- name: 'comment',
- },
- ],
- accountType: 'User',
- provider: {
- canAdd: true,
- aspects: {
- disable_dialog: {
- body: 'Before deleting this integration, you must uninstall this integration from GitHub. After uninstalling, your integration will be disabled at which point you can choose to delete this integration.',
- actionText: 'Visit GitHub',
- },
- removal_dialog: {
- body: 'Deleting this integration will delete all associated repositories and commit data. This action cannot be undone. Are you sure you want to delete your integration?',
- actionText: 'Delete',
- },
- },
- features: ['commits', 'issue-basic'],
- canDisable: true,
- key: 'github',
- name: 'GitHub',
- },
- id: '5',
- };
- getFormConfigRequest = MockApiClient.addMockResponse({
- url: `/organizations/org-slug/issues/${group.id}/integrations/${integration.id}/`,
- body: formConfig,
- match: [MockApiClient.matchQuery({action: 'link'})],
- });
- });
- it('renders and loads options', async () => {
- await renderComponent('Link');
- expect(getFormConfigRequest).toHaveBeenCalled();
- });
- describe('options loaded', () => {
- beforeEach(() => {
- MockApiClient.addMockResponse({
- url: `/organizations/org-slug/issues/${group.id}/integrations/${integration.id}/?action=link`,
- body: formConfig,
- });
- });
- it('fast typing is debounced and uses trailing call when fetching data', async () => {
- const searchResponse = MockApiClient.addMockResponse({
- url: '/search?field=externalIssue&query=faster&repo=scefali%2Ftest',
- body: [
- {
- label: '#1337 ref(js): Convert Form to a FC',
- value: 1337,
- },
- {
- label: '#2345 perf: Make it faster',
- value: 2345,
- },
- ],
- });
- await renderComponent('Link');
- jest.useFakeTimers();
- const textbox = screen.getByRole('textbox', {name: 'Issue'});
- await userEvent.click(textbox, {delay: null});
- await userEvent.type(textbox, 'faster', {delay: null});
- expect(searchResponse).not.toHaveBeenCalled();
- jest.advanceTimersByTime(300);
- expect(searchResponse).toHaveBeenCalledTimes(1);
- expect(await screen.findByText('#2345 perf: Make it faster')).toBeInTheDocument();
- });
- });
- });
- });
|