import React from 'react'; import { waitForElementToBeRemoved } from '@testing-library/dom'; import { act, cleanup, fireEvent, render, RenderResult, } from '@testing-library/react'; import { JestDOM } from '@leafygreen-ui/testing-lib'; import { constructOrganizationURL, dataFixtures, urlFixtures, } from '../../data'; import { OnChangeInterface } from '../../types'; import OrgSelect from './OrgSelect'; // data const { currentOrganization, organizations } = dataFixtures; const mongoSelectUrls = urlFixtures.mongoSelect; describe('packages/mongo-select/OrgSelect', () => { let getByTestId: RenderResult['getByTestId']; let queryByTestId: RenderResult['queryByTestId']; let queryAllByTestId: RenderResult['queryAllByTestId']; afterEach(() => { jest.restoreAllMocks(); cleanup(); }); describe('OrgSelect', () => { const renderComponent = (props = {}) => { ({ getByTestId, queryByTestId, queryAllByTestId } = render( , )); }; describe('when rendered with default props', () => { beforeEach(renderComponent); it('displays the org select trigger with the current org name', () => { const orgTriggerText = getByTestId('org-select-active-org'); expect(orgTriggerText).toBeVisible(); expect(orgTriggerText.textContent).toEqual('Demo Organization'); }); it('sets "aria-expanded" to false when organization dropdown is closed', () => { expect(getByTestId('org-trigger').getAttribute('aria-expanded')).toBe( 'false', ); }); describe('when clicking the current organization trigger', () => { beforeEach(() => { fireEvent.click(getByTestId('org-trigger')); }); it('sets "aria-expanded" to true', () => { expect(getByTestId('org-trigger').getAttribute('aria-expanded')).toBe( 'true', ); }); it('displays a search input with a placeholder', () => { expect( getByTestId('org-filter-input').getAttribute('placeholder'), ).toContain('Search for an Organization...'); }); it('displays two organization results', () => { expect(queryAllByTestId('org-option').length).toEqual(2); }); it('displays the correct names of each result', () => { const orgResults = queryAllByTestId('org-option'); expect(orgResults[0].textContent).toContain('Demo Organization'); expect(orgResults[1].textContent).toContain('Demo Organization 2'); }); it('displays the correct org type of each result', () => { const orgResults = queryAllByTestId('org-option'); expect(orgResults[0].textContent).toContain('Atlas'); expect(orgResults[1].textContent).toContain('Cloud Manager'); }); it('displays the correct link to projects of each result', () => { const orgResults = queryAllByTestId('org-option'); expect((orgResults[0] as HTMLAnchorElement).href).toBe( 'https://cloud.mongodb.com/v2#/org/fakeOrgId1/projects', ); expect((orgResults[1] as HTMLAnchorElement).href).toBe( 'https://cloud.mongodb.com/v2#/org/fakeOrgId2/projects', ); }); it('indicates the current organization', () => { const orgResults = queryAllByTestId('org-option'); const currentResult = orgResults.find( result => result.getAttribute('aria-current') === 'true', ); expect(currentResult).toBeInTheDocument(); }); describe('when clicking an org', () => { beforeEach(async () => { const orgResults = queryAllByTestId('org-option'); await JestDOM.silenceNavigationErrors(async waitForNavigation => { fireEvent.click(orgResults[0]); await waitForNavigation(); }); }); // eslint-disable-next-line jest/expect-expect it('closes the menu', async () => { await waitForElementToBeRemoved(() => queryByTestId('org-filter-input'), ); }); }); }); }); describe('when rendered in a disabled state', () => { beforeEach(() => renderComponent({ disabled: true })); it('displays the current org as "All Organizations"', () => { const orgTrigger = getByTestId('org-trigger'); expect(orgTrigger.textContent).toContain('All Organizations'); }); it('does not display an org settings icon', () => { expect(queryByTestId('org-trigger-settings')).toBeNull(); }); }); describe('when a user filters organizations', () => { beforeEach(renderComponent); beforeEach(() => { fireEvent.click(getByTestId('org-trigger')); }); it('displays one organization when only one matches the search', () => { const input = getByTestId('org-filter-input'); expect(input.innerHTML).toEqual(''); fireEvent.change(input, { target: { value: '2' }, }); expect(queryAllByTestId('org-option').length).toBe(1); }); it('displays no organizations when none matches the search', () => { const input = getByTestId('org-filter-input'); fireEvent.change(input, { target: { value: 'xx' }, }); expect(queryAllByTestId('org-option').length).toBe(0); }); it('when closing the menu the filter value is reset', async () => { // Close menu act(() => { // For some reason this causes a navigation and a console error. // I can't figure out how or why yet document.body.dispatchEvent( new MouseEvent('click', { bubbles: true }), ); }); // Need to wait for the UI to update as clicking on the orgTrigger so rapidly causes // React to coalesce the events await waitForElementToBeRemoved(() => queryByTestId('org-filter-input'), ); fireEvent.click(getByTestId('org-trigger')); expect(getByTestId('org-filter-input').innerHTML).toEqual(''); }); }); describe('when all organizations have the same planType', () => { beforeEach(() => renderComponent({ data: [ { orgId: 'fakeOrgId1', orgName: 'Demo Organization', planType: 'atlas', }, { orgId: 'fakeOrgId2', orgName: 'Demo Organization 2', planType: 'atlas', }, ], }), ); beforeEach(() => { fireEvent.click(getByTestId('org-trigger')); }); it('does not render the logo associated with the planType', () => { const orgResults = queryAllByTestId('org-option'); expect(orgResults[0].innerHTML).not.toContain('svg'); }); }); describe('when the onChange prop is set', () => { function onChange({ setData }: OnChangeInterface) { return setData([ { orgId: 'testOrgId', orgName: 'Test SetData', planType: 'atlas', }, ]); } beforeEach(() => renderComponent({ onChange })); it('filters the organizations based on the onChange callback', () => { fireEvent.click(getByTestId('org-trigger')); const input = getByTestId('org-filter-input'); fireEvent.change(input, { target: { value: '2' }, }); const orgResult = getByTestId('org-option'); expect(orgResult.innerHTML.includes('Test SetData')).toBe(true); }); }); }); // eslint-disable-next-line jest/no-disabled-tests describe.skip('types work as expected', () => { // eslint-disable-next-line jest/expect-expect test('does not error when only ProjectSelect values are passed to url prop', () => { 'string'} urls={{ viewAllOrganizations: 'string', orgSettings: 'string' }} />; }); }); });