useProjects.spec.tsx 3.3 KB

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