persistedStore.spec.tsx 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import {act} from 'react-test-renderer';
  2. import {QueryClientProvider} from '@tanstack/react-query';
  3. import {makeTestQueryClient} from 'sentry-test/queryClient';
  4. import {reactHooks} from 'sentry-test/reactTestingLibrary';
  5. import OrganizationStore from 'sentry/stores/organizationStore';
  6. import {
  7. DefaultLoadedPersistedStore,
  8. DefaultPersistedStore,
  9. PersistedStoreProvider,
  10. usePersistedStoreCategory,
  11. } from 'sentry/stores/persistedStore';
  12. import {OrganizationContext} from 'sentry/views/organizationContext';
  13. describe('PersistedStore', function () {
  14. let org, wrapper;
  15. beforeEach(() => {
  16. org = TestStubs.Organization();
  17. MockApiClient.addMockResponse({
  18. url: `/organizations/${org.slug}/client-state/`,
  19. body: {
  20. onboarding: {
  21. test: 1,
  22. },
  23. },
  24. });
  25. OrganizationStore.onUpdate(org, {replace: true});
  26. wrapper = ({children}) => (
  27. <QueryClientProvider client={makeTestQueryClient()}>
  28. <PersistedStoreProvider>
  29. <OrganizationContext.Provider value={org}>
  30. {children}
  31. </OrganizationContext.Provider>
  32. </PersistedStoreProvider>
  33. </QueryClientProvider>
  34. );
  35. });
  36. afterEach(() => {
  37. MockApiClient.clearMockResponses();
  38. });
  39. it('provides the persisted data category from client-state API', async function () {
  40. const {result, waitForNextUpdate} = reactHooks.renderHook(usePersistedStoreCategory, {
  41. initialProps: 'onboarding' as const,
  42. wrapper,
  43. });
  44. await waitForNextUpdate();
  45. const [state] = result.current;
  46. expect(state).toMatchObject({
  47. test: 1,
  48. });
  49. });
  50. it('sets the persisted data category from client-state API', async function () {
  51. const {result, waitForNextUpdate} = reactHooks.renderHook(usePersistedStoreCategory, {
  52. initialProps: 'onboarding' as const,
  53. wrapper,
  54. });
  55. await waitForNextUpdate();
  56. const [_, setState] = result.current;
  57. const clientStateUpdate = MockApiClient.addMockResponse({
  58. url: `/organizations/${org.slug}/client-state/onboarding/`,
  59. method: 'PUT',
  60. });
  61. act(() => {
  62. setState({test: 2} as any);
  63. });
  64. const [state2] = result.current;
  65. expect(state2).toMatchObject({
  66. test: 2,
  67. });
  68. await waitForNextUpdate();
  69. expect(clientStateUpdate).toHaveBeenCalledWith(
  70. `/organizations/${org.slug}/client-state/onboarding/`,
  71. expect.objectContaining({
  72. method: 'PUT',
  73. data: {
  74. test: 2,
  75. },
  76. })
  77. );
  78. });
  79. it('deletes the persisted data category on set to null', async function () {
  80. const {result, waitForNextUpdate} = reactHooks.renderHook(usePersistedStoreCategory, {
  81. initialProps: 'onboarding' as const,
  82. wrapper,
  83. });
  84. await waitForNextUpdate();
  85. const [_, setState] = result.current;
  86. const clientStateDelete = MockApiClient.addMockResponse({
  87. url: `/organizations/${org.slug}/client-state/onboarding/`,
  88. method: 'DELETE',
  89. });
  90. act(() => {
  91. setState(null);
  92. });
  93. const [state2] = result.current;
  94. expect(state2).toBe(DefaultPersistedStore.onboarding);
  95. await waitForNextUpdate();
  96. expect(clientStateDelete).toHaveBeenCalledWith(
  97. `/organizations/${org.slug}/client-state/onboarding/`,
  98. expect.objectContaining({
  99. method: 'DELETE',
  100. })
  101. );
  102. });
  103. it('returns default when state is empty', async function () {
  104. MockApiClient.addMockResponse({
  105. url: `/organizations/${org.slug}/client-state/`,
  106. body: {},
  107. });
  108. const {result, waitForNextUpdate} = reactHooks.renderHook(usePersistedStoreCategory, {
  109. initialProps: 'onboarding' as const,
  110. wrapper,
  111. });
  112. const [state] = result.current;
  113. expect(state).toBe(DefaultPersistedStore.onboarding);
  114. await waitForNextUpdate();
  115. const [state2] = result.current;
  116. expect(state2).toBe(DefaultLoadedPersistedStore.onboarding);
  117. });
  118. it('returns default when state fails to load', function () {
  119. MockApiClient.addMockResponse({
  120. url: `/organizations/${org.slug}/client-state/`,
  121. statusCode: 500,
  122. });
  123. const {result} = reactHooks.renderHook(usePersistedStoreCategory, {
  124. initialProps: 'onboarding' as const,
  125. wrapper,
  126. });
  127. const [state] = result.current;
  128. expect(state).toBe(DefaultPersistedStore.onboarding);
  129. });
  130. });