useProjects.spec.tsx 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import {reactHooks} from 'sentry-test/reactTestingLibrary';
  2. import OrganizationStore from 'sentry/stores/organizationStore';
  3. import ProjectsStore from 'sentry/stores/projectsStore';
  4. import useProjects from 'sentry/utils/useProjects';
  5. describe('useProjects', function () {
  6. const org = TestStubs.Organization();
  7. const mockProjects = [TestStubs.Project()];
  8. it('provides projects from the team store', function () {
  9. reactHooks.act(() => void ProjectsStore.loadInitialData(mockProjects));
  10. const {result} = reactHooks.renderHook(() => useProjects());
  11. const {projects} = result.current;
  12. expect(projects).toEqual(mockProjects);
  13. });
  14. it('loads more projects when using onSearch', async function () {
  15. reactHooks.act(() => void ProjectsStore.loadInitialData(mockProjects));
  16. reactHooks.act(() => void OrganizationStore.onUpdate(org, {replace: true}));
  17. const newProject3 = TestStubs.Project({id: '3', slug: 'test-project3'});
  18. const newProject4 = TestStubs.Project({id: '4', slug: 'test-project4'});
  19. const mockRequest = MockApiClient.addMockResponse({
  20. url: `/organizations/${org.slug}/projects/`,
  21. method: 'GET',
  22. body: [newProject3, newProject4],
  23. });
  24. const {result, waitFor} = reactHooks.renderHook(() => useProjects());
  25. const {onSearch} = result.current;
  26. // Works with append
  27. const onSearchPromise = reactHooks.act(() => onSearch('test'));
  28. expect(result.current.fetching).toBe(true);
  29. await onSearchPromise;
  30. expect(result.current.fetching).toBe(false);
  31. // Wait for state to be reflected from the store
  32. await waitFor(() => result.current.projects.length === 3);
  33. expect(mockRequest).toHaveBeenCalled();
  34. expect(result.current.projects).toEqual([...mockProjects, newProject3, newProject4]);
  35. // de-duplicates items in the query results
  36. mockRequest.mockClear();
  37. await reactHooks.act(() => onSearch('test'));
  38. // No new items have been added
  39. expect(mockRequest).toHaveBeenCalled();
  40. expect(result.current.projects).toEqual([...mockProjects, newProject3, newProject4]);
  41. });
  42. it('provides only the specified slugs', async function () {
  43. reactHooks.act(() => void ProjectsStore.loadInitialData(mockProjects));
  44. reactHooks.act(() => void OrganizationStore.onUpdate(org, {replace: true}));
  45. const projectFoo = TestStubs.Project({id: 3, slug: 'foo'});
  46. const mockRequest = MockApiClient.addMockResponse({
  47. url: `/organizations/${org.slug}/projects/`,
  48. method: 'GET',
  49. body: [projectFoo],
  50. });
  51. const {result, waitFor} = reactHooks.renderHook(props => useProjects(props), {
  52. initialProps: {slugs: ['foo']},
  53. });
  54. expect(result.current.initiallyLoaded).toBe(false);
  55. expect(mockRequest).toHaveBeenCalled();
  56. await waitFor(() => expect(result.current.projects.length).toBe(1));
  57. const {projects} = result.current;
  58. expect(projects).toEqual(expect.arrayContaining([projectFoo]));
  59. });
  60. it('only loads slugs when needed', function () {
  61. reactHooks.act(() => void ProjectsStore.loadInitialData(mockProjects));
  62. const {result} = reactHooks.renderHook(props => useProjects(props), {
  63. initialProps: {slugs: [mockProjects[0].slug]},
  64. });
  65. const {projects, initiallyLoaded} = result.current;
  66. expect(initiallyLoaded).toBe(true);
  67. expect(projects).toEqual(expect.arrayContaining(mockProjects));
  68. });
  69. });