import {reactHooks} from 'sentry-test/reactTestingLibrary'; import OrganizationStore from 'sentry/stores/organizationStore'; import ProjectsStore from 'sentry/stores/projectsStore'; import useProjects from 'sentry/utils/useProjects'; describe('useProjects', function () { const org = TestStubs.Organization(); const mockProjects = [TestStubs.Project()]; it('provides projects from the team store', function () { reactHooks.act(() => void ProjectsStore.loadInitialData(mockProjects)); const {result} = reactHooks.renderHook(() => useProjects()); const {projects} = result.current; expect(projects).toEqual(mockProjects); }); it('loads more projects when using onSearch', async function () { reactHooks.act(() => void ProjectsStore.loadInitialData(mockProjects)); reactHooks.act(() => void OrganizationStore.onUpdate(org, {replace: true})); const newProject3 = TestStubs.Project({id: '3', slug: 'test-project3'}); const newProject4 = TestStubs.Project({id: '4', slug: 'test-project4'}); const mockRequest = MockApiClient.addMockResponse({ url: `/organizations/${org.slug}/projects/`, method: 'GET', body: [newProject3, newProject4], }); const {result, waitFor} = reactHooks.renderHook(() => useProjects()); const {onSearch} = result.current; // Works with append const onSearchPromise = reactHooks.act(() => onSearch('test')); expect(result.current.fetching).toBe(true); await onSearchPromise; expect(result.current.fetching).toBe(false); // Wait for state to be reflected from the store await waitFor(() => result.current.projects.length === 3); expect(mockRequest).toHaveBeenCalled(); expect(result.current.projects).toEqual([...mockProjects, newProject3, newProject4]); // de-duplicates items in the query results mockRequest.mockClear(); await reactHooks.act(() => onSearch('test')); // No new items have been added expect(mockRequest).toHaveBeenCalled(); expect(result.current.projects).toEqual([...mockProjects, newProject3, newProject4]); }); it('provides only the specified slugs', async function () { reactHooks.act(() => void ProjectsStore.loadInitialData(mockProjects)); reactHooks.act(() => void OrganizationStore.onUpdate(org, {replace: true})); const projectFoo = TestStubs.Project({id: 3, slug: 'foo'}); const mockRequest = MockApiClient.addMockResponse({ url: `/organizations/${org.slug}/projects/`, method: 'GET', body: [projectFoo], }); const {result, waitFor} = reactHooks.renderHook(props => useProjects(props), { initialProps: {slugs: ['foo']}, }); expect(result.current.initiallyLoaded).toBe(false); expect(mockRequest).toHaveBeenCalled(); await waitFor(() => expect(result.current.projects.length).toBe(1)); const {projects} = result.current; expect(projects).toEqual(expect.arrayContaining([projectFoo])); }); it('only loads slugs when needed', function () { reactHooks.act(() => void ProjectsStore.loadInitialData(mockProjects)); const {result} = reactHooks.renderHook(props => useProjects(props), { initialProps: {slugs: [mockProjects[0].slug]}, }); const {projects, initiallyLoaded} = result.current; expect(initiallyLoaded).toBe(true); expect(projects).toEqual(expect.arrayContaining(mockProjects)); }); });